This page documents CLI 2.x behavior for users who haven't yet migrated to V3. For the current format, see the Hooks documentation.
In CLI 2.x, hooks were embedded directly in the agent configuration file rather than in standalone files.
{ "hooks": { "agentSpawn": [{ "command": "echo 'starting'" }], "preToolUse": [{ "command": "npm run lint", "matcher": "fs_write" }] } }
Each trigger name maps to an array of Hook definitions. Each definition has:
| Field | Description |
|---|---|
command | Shell command to execute |
matcher | Tool-name selector for preToolUse and postToolUse; exact names, aliases, and supported wildcard patterns |
| Trigger | Fires when | matcher matches |
|---|---|---|
agentSpawn | Agent is activated | Not evaluated |
userPromptSubmit | User submits a prompt | Not evaluated |
preToolUse | Before a tool executes | Tool name |
postToolUse | After a tool executes | Tool name |
stop | The assistant finishes responding | Not evaluated |
Hooks receive context as JSON via STDIN and communicate results through exit codes:
.kiro/hooks/*.json files for profile-independent automationagentSpawn → SessionStart)SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, and Stop, plus file triggers for agent-made changes and task triggers around spec executionv1 schema and support command or agent actionsStop command Hooks can return {"decision": "block"} to continue the sessionFor the full migration guide, see Hooks migration.
In CLI 2.x, tool permissions were managed through CLI flags, slash commands, and per-tool settings in agent config. In V3, per-tool settings are replaced by structured permissions.yaml files; the flags and slash commands remain as session-scoped overrides.
kiro-cli --trust-all-tools kiro-cli --trust-tools shell,write
| Command | Description |
|---|---|
/tools | Show current permission status for all tools |
/tools trust <tool> | Trust a specific tool for the session |
/tools untrust <tool> | Revert a tool to per-request confirmation |
/tools trust-all | Trust all tools (equivalent to /acceptall) |
/tools reset | Reset all runtime permissions to defaults |
{ "toolsSettings": { "shell": { "allowedCommands": ["git *", "npm *"], "deniedCommands": ["rm -rf *", "sudo *"] }, "read": { "allowedPaths": ["src/**"], "deniedPaths": ["*.env"] } } }
| Setting | Description |
|---|---|
allowedCommands | Regex patterns for auto-approved shell commands |
deniedCommands | Regex patterns for blocked shell commands |
allowedPaths | Gitignore-style glob patterns for auto-approved file paths |
deniedPaths | Gitignore-style glob patterns for blocked file paths |
autoAllowReadonly | Auto-approve read-only shell commands (e.g., git status) |
denyByDefault | Block all tools unless explicitly allowed |
When the agent requested a shell command, a tiered picker appeared:
Press (↑↓) to navigate (⏎) to select scope > Full command → git pull --rebase Partial command → git pull * Base command → git * Entire Tool → *
Trusted patterns persisted for the session and were stored as regex in allowedCommands.
When the agent needed to access a file outside the working directory:
Press (↑↓) to navigate (⏎) to select scope > Specific paths → ~/.config/app/settings.json Complete directory → ~/.config/app Entire Tool → *
toolsSettings replaced by permissions.yaml with capability/match/effect rules--trust-all-tools still works as a session-scope override but permissions.yaml is preferredautoAllowReadonly converts through /upgrade-agent to a read-only-shell policy unless denyByDefault also applies; review the generated rulesdenyByDefault removed — use exclude patterns instead/tools panel, /tools trust-all, and the approval picker remain available for session-level managementFor the full migration guide, see Permissions migration.
CLI 2.x compaction forks a new session that contains the compacted context:
/compact manually, or let compaction trigger when the context window overflows./chat resume when needed.compaction.excludeMessages and compaction.excludeContextWindowPercent.CLI V3 instead records the compaction summary as a checkpoint marker within the same session. On reload, V3 loads that summary rather than replaying the full earlier history or creating a separate session. See Manual compaction.
In CLI 2.x, agent configs were JSON-only with embedded toolsSettings and hooks.
CLI 2.x custom agent configs can use built-in names such as kiro_default or kiro_planner. The V2 loader does not reject these configs as reserved-name conflicts. For current built-in agents and their roles, see Built-in agents.
.kiro/agents/my-agent.json:
{ "name": "my-agent", "description": "A development agent", "prompt": "file://resources/MY_PROMPT.md", "model": "claude-sonnet-4.6", "tools": ["fs_read", "fs_write", "execute_bash", "grep", "glob", "code"], "toolsSettings": { "execute_bash": { "allowedCommands": ["^git status$", "^cargo build[^&;]*$"], "deniedCommands": ["^rm -rf"], "denyByDefault": false }, "fs_read": { "allowedPaths": ["src/**", "docs/**"], "deniedPaths": [".env", "secrets/**"] }, "fs_write": { "allowedPaths": ["src/**"], "deniedPaths": ["*.lock"] } }, "resources": ["file://AGENTS.md"], "hooks": { "agentSpawn": [{ "command": "git status", "description": "Add git context" }] }, "welcomeMessage": "Hello! How can I help?" }
.md files with YAML frontmatter + body as system prompt)toolsSettings removed — replaced by permissions field with capability-based ruleshooks shape changed — /upgrade-agent converts the object form to a profile-scoped array. Use standalone .kiro/hooks/*.json files for profile-independent or cross-surface automation.excludedTools, includeMcpJson, includePowers, permissions, welcomeMessageread, write, shell, web, @mcp, @builtin, *)resources field now supports skill:// URIs in addition to file://For the current format reference, see Custom agents.
CLI 2.x reference