Skip to content

Add native Kiro CLI hook integration - #4831

Merged
austinywang merged 14 commits into
mainfrom
issue-2312-feature-native-kiro-cli-hook
Jun 1, 2026
Merged

austinywang merged 14 commits into
mainfrom
issue-2312-feature-native-kiro-cli-hook

Conversation

@austinywang

@austinywang austinywang commented May 26, 2026 •

Copy link
Copy Markdown
Contributor

Closes #2312.

Summary

  • add cmux hooks kiro installation using Kiro agent config JSON at ~/.kiro/agents/cmux.json or $KIRO_HOME/agents/cmux.json
  • bridge Kiro lifecycle/tool events into cmux status, session restore, and Feed approval cards with deny mapped to Kiro's blocking hook exit path
  • add Settings/config/schema support for automation.kiroIntegration and automation.kiroNotificationLevel (minimal, standard, verbose)
  • add sanitizer/resume support for kiro-cli chat --resume-id <session> and preserve safe Kiro launch environment

References

Validation

  • python3 -m json.tool Resources/Localizable.xcstrings >/dev/null
  • python3 -m json.tool web/data/cmux.schema.json >/dev/null
  • git diff --check
  • Local builds/tests not run per workspace instruction; CI is the source of truth.

No cloud-mac repro/video: this is a new feature, not a crash or visual bug.


Note

Medium Risk
Introduces Feed permission gating and exit-2 deny semantics for a new agent; behavior is well-tested and scoped to Kiro, but it touches approval paths and hook install defaults (tools: ["*"]).

Overview
Adds native Kiro CLI as a first-class cmux agent: cmux hooks kiro install writes ~/.kiro/agents/cmux.json (or $KIRO_HOME/agents/) using a new Kiro agent JSON hook shape (timeout_ms, flat commands). Fresh installs default tools: ["*"] so pre/post tool hooks can run, and a post-install note tells users to use kiro-cli chat --agent cmux.

Feed & permissions: Kiro’s camelCase events are registered in FeedEventClassifier; mutating Kiro tool names escalate to actionable approvals via source-scoped aliases (other agents’ lowercase tools are unchanged). Feed hooks use a shell wrapper that propagates exit 2 for denies; resolved Feed permission modes map to allow ({}) or fail-closed deny (exit 2). CMUX_KIRO_NOTIFICATION_LEVEL / Settings minimal · standard · verbose filter non-actionable Kiro tool telemetry.

App integration: Session restore and launch sanitization for kiro-cli chat --resume-id, CMUX_KIRO_PID, resume bindings, task manager / hibernation / restorable agent typing, Automation settings + schema + localization, and preserved launch env (KIRO_HOME, log vars).

Reviewed by Cursor Bugbot for commit 6588760. Bugbot is set up for automated code reviews on this repo. Configure here.


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag @codesmith with what you need. Autofix is disabled.


Summary by cubic

Adds native Kiro CLI integration with session resume, Feed approvals, and a cleaner notification flow. The installer and Settings show a localized hint to run Kiro with --agent cmux, and the generated Kiro agent config now enables tools so hooks actually fire.

  • New Features

    • cmux hooks kiro install writes hooks to ~/.kiro/agents/cmux.json or $KIRO_HOME/agents/cmux.json with timeout_ms, grants tools: ["*"] on fresh install, and prints a localized tip to start with kiro-cli chat --agent cmux (Settings note shows this too).
    • Bridges Kiro events to cmux (agentSpawn, userPromptSubmit, preToolUse/postToolUse, stop) with a Feed wrapper that preserves exit 2 on deny; tracks PID via CMUX_KIRO_PID; improves shell/fs tool summaries (e.g., execute_bash, fs_read/fs_write).
    • Classifier registers Kiro’s camelCase events and source‑scoped, case‑insensitive tool aliases so only Kiro escalates approvals; minimal shows approvals only, standard suppresses read‑only tools, verbose shows all (also via CMUX_KIRO_NOTIFICATION_LEVEL).
    • Permission gate allows only once/always/all/bypass; deny or missing/unknown mode fails closed with exit 2.
    • Session restore uses kiro-cli chat --resume-id <id> with argument sanitization; preserves KIRO_HOME, KIRO_LOG_LEVEL, KIRO_LOG_NO_COLOR; publishes a surface resume binding.
  • Migration

    • Run cmux hooks kiro install, then start Kiro with kiro-cli chat --agent cmux (or set it as default).
    • Optionally set automation.kiroNotificationLevel (or CMUX_KIRO_NOTIFICATION_LEVEL) to tune Feed.
    • To disable, toggle automation.kiroIntegration or set CMUX_KIRO_HOOKS_DISABLED=1.

Written for commit 6588760. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Kiro CLI integration: installable hooks, resume support, post-install note, settings toggle, and notification level (minimal/standard/verbose).
  • Bug Fixes

    • Safer resume/launch argument and environment handling; clearer allow/deny behavior for Kiro hooks with propagated exit semantics; selective suppression of Kiro feed events.
  • Tests

    • Added Kiro-focused tests for feed classification, persistence, resume commands, and settings parsing.
  • Documentation

    • Agent-hooks docs updated with Kiro integration and notification guidance.

@vercel

vercel Bot commented May 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 1, 2026 2:11am
cmux-staging Building Building Preview, Comment Jun 1, 2026 2:11am

@coderabbitai

coderabbitai Bot commented May 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds first-class Kiro-CLI integration: agent kind and hook format, source-scoped feed-event classification and suppression, kiro-specific hook command/decision handling, launch sanitization and resume support, settings/UI/schema and environment wiring, localization, and tests.

Changes

Kiro-CLI Native Integration

Layer / File(s) Summary
Agent type registration and hook schema
Sources/RestorableAgentTypes.swift, Sources/TaskManagerTypes.swift, CLI/CMUXCLI+AgentHookDefinitions.swift, docs/agent-hooks.md
RestorableAgentKind adds .kiro; task manager built-ins include kiro. HookFormat adds .kiroAgentJSON(timeoutMs:). New AgentHookDef for kiro added with config paths, event mappings, and postInstallNote.
Feed event classification by source
CLI/FeedEventClassifier.swift, cmuxTests/FeedEventClassificationTests.swift
FeedEventClassifier passes source into wire mapping; explicit kiro registry maps camelCase hook names; isSideEffectingTool(toolName:source:) enforces source-scoped case-insensitive kiro aliases; tests added.
Hook command generation and feed processing
CLI/CMUXCLI+AgentHookDefinitions.swift, CLI/cmux.swift
Feed-hook commands use kiro-specific shell snippet that propagates exit code 2 for denials and maps other failures to {}. .kiroAgentJSON hooks include timeout_ms and follow cmux rewrite/merge/prune flows. Added feed suppression (shouldSuppressKiroFeedEvent) and decision handling (emitKiroDecisionIfHandled); tool-summary extraction broadened and PID mapping adds CMUX_KIRO_PID.
Agent launch environment, sanitization, and resume
Packages/CMUXAgentLaunch/..., Sources/RestorableAgentSession.swift
Allowlist extends with KIRO_HOME, KIRO_LOG_LEVEL, KIRO_LOG_NO_COLOR. kiroPolicy sanitizes launch args, optionally strips leading chat, rejects unexpected positional commands, and preserves allowed flags. Resume args support .kiro via kiro-cli chat --resume-id.
Settings model, defaults, and persistence
Sources/cmuxApp.swift, Packages/CmuxSettings/..., Sources/CmuxSettingsJSONPathSupport.swift, Sources/KeyboardShortcutSettingsFileStore.swift, web/data/cmux.schema.json
Introduces KiroIntegrationSettings with NotificationLevel (minimal/standard/verbose) and accessors. Adds automation/integrations DefaultsKeys for kiro and JSON-path support; parser validates notification-level strings and schema adds automation.kiroIntegration and automation.kiroNotificationLevel.
Settings UI and navigation
Packages/CmuxSettingsUI/..., Sources/cmuxApp.swift, Sources/CommandPalette/CommandPaletteSettingsToggle.swift, Sources/SettingsNavigation.swift, Sources/SettingsSearchAliases.swift
Adds Kiro integration card with toggle and picker, legacy AppStorage bindings, command-palette toggle descriptor, search indices/aliases, and reset defaults wiring.
Terminal surface integration
Sources/GhosttyTerminalView.swift
Injects CMUX_KIRO_NOTIFICATION_LEVEL into terminal environment and sets CMUX_KIRO_HOOKS_DISABLED=1 when hooks are disabled.
Localization and documentation
Resources/Localizable.xcstrings, docs/agent-hooks.md, Sources/AgentHibernation/AgentHibernationLifecycleState.swift
Adds localized strings (en/ja/ko) for Kiro UI and search aliases; updates docs with Kiro integration, env overrides, and hook behavior. Adds "kiro" to allowed hibernation status keys.
Comprehensive test coverage
cmuxTests/CLIGenericHookPersistenceTests.swift, cmuxTests/FeedEventClassificationTests.swift, cmuxTests/GhosttyConfigTests.swift, cmuxTests/RestorableAgentHookProviderResumeTests.swift, cmuxTests/SessionPersistenceTests.swift, cmuxTests/WorkspaceUnitTests.swift
Adds tests for kiro hook persistence and resume-binding, hook install shape and deny-exit preservation, feed deny/allow modes, event classification regressions, resume command generation and sanitizer behavior, session persistence, and settings-file parsing resilience.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • manaflow-ai/cmux#4225: Both PRs extend the shared agent hook/Feed-bridge infrastructure by adding a new agent definition (main: kiro via .kiroAgentJSON with special feed-hook exit-2 propagation; retrieved: grok with special hook shell command + owned-hook detection).

"🐰 I hopped into cmux with a grin,
Kiro hooks and feeds tucked in,
Toggles set, notifications sing,
Resume, sanitize — ready to spring! 🎉"


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Cmux Full Internationalization ❌ Error All 12 new Kiro entries have only 3 locales (en, ja, ko), violating the requirement for complete translations across all 20 supported locales in the catalog. Add translations for all 20 locales to Kiro entries in Resources/Localizable.xcstrings, or match Cursor/Gemini's 19-locale pattern (ar, bs, da, de, es, fr, it, km, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant).
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Cmux Swift Actor Isolation ❓ Inconclusive No result was produced after verification. Marking as INCONCLUSIVE. Re-run the check or adjust instructions to produce a final result.
✅ Passed checks (15 passed)
Check name Status Explanation
Title check ✅ Passed The PR title 'Add native Kiro CLI hook integration' clearly summarizes the main change, accurately reflecting the primary objective of adding native Kiro CLI support.
Linked Issues check ✅ Passed All primary objectives from issue #2312 are met: Settings toggle/configuration, hook event bridging, native notification rendering, and customizable verbosity levels (minimal/standard/verbose) are fully implemented with comprehensive code changes.
Out of Scope Changes check ✅ Passed All changes are scoped to Kiro CLI integration objectives. Settings infrastructure, localization, schema extensions, session resume support, Feed classification, and test coverage are all directly aligned with issue #2312 requirements.
Cmux Swift Blocking Runtime ✅ Passed No blocking synchronization primitives found in production Swift code; all async operations use callbacks and test code uses proper XCTestWaiter patterns.
Cmux No Hacky Sleeps ✅ Passed PR contains no modifications to TypeScript, JavaScript, or shell runtime scripts. All changes are to Swift files (covered by separate rule) and configuration/documentation files.
Cmux Algorithmic Complexity ✅ Passed Static collections ≤25 items with O(1) set lookups. Feed hot path: single environment capture, string comparisons in bounded sets, no nested loops or rescans.
Cmux Swift Concurrency ✅ Passed Kiro PR introduces no legacy async patterns: 0 DispatchQueue.global, fire-and-forget Tasks, new Combine, or completion handlers in new code.
Cmux Swift @Concurrent ✅ Passed All 7 new Swift functions are synchronous and lightweight (string ops, set lookups, env reads). No async work, file I/O, network ops, or @concurrent violations found.
Cmux Swift File And Package Boundaries ✅ Passed No oversized new files; CLI/cmux.swift +124 below 250-line threshold; logic distributed to CMUXAgentLaunch, CmuxSettings, CmuxSettingsUI packages; no responsibility mixing.
Cmux Swift Logging ✅ Passed All Kiro integration code passes swift-logging.md rules: no NSLog/debugPrint/dump found; all print() statements are legitimate CLI JSON output for hook agents, not diagnostic logging.
Cmux User-Facing Error Privacy ✅ Passed All user-facing error messages comply with privacy rules. The message mentioning "Kiro" is allowed per the exception for user-configured vendors explicitly in the Settings UI.
Cmux Swiftui State Layout ✅ Passed AutomationSection uses @Observable DefaultsValueModel. Legacy @AppStorage acceptable. No @ObservableObject/@published, GeometryReader changes, lazy store refs, or render mutations.
Cmux Architecture Rethink ✅ Passed No architectural violations found: no timing repairs, locks, mutable state, or lifecycle splits. Uses immutable registries, fail-closed semantics, and consistent DefaultsValueModel patterns.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR adds Kiro CLI integration via configuration, settings UI components, and CLI logic—no new NSWindow, NSPanel, NSWindowController, SwiftUI Window, or WindowGroup instances created.
Description check ✅ Passed The PR description follows the required template structure with Summary, Testing, Checklist sections and includes references, validation details, and comprehensive feature documentation.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue-2312-feature-native-kiro-cli-hook

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Comment thread CLI/cmux.swift
Comment thread Sources/KeyboardShortcutSettingsFileStore.swift
@greptile-apps

greptile-apps Bot commented May 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds native Kiro CLI hook integration alongside existing agent hooks: a new kiroAgentJSON format, a cmux Kiro agent config at ~/.kiro/agents/cmux.json, session restore via kiro-cli chat --resume-id, Feed approval bridging with fail-closed exit-2 semantics, and a three-level notification filter (minimal/standard/verbose) exposed through Settings and CMUX_KIRO_NOTIFICATION_LEVEL.

  • Hook install & format: AgentHookDef gains .kiroAgentJSON(timeoutMs:), exitTwoPropagatingAgentHookShellCommand propagates exactly exit 2 for user-deny and falls back to {} for unexpected failures (addressing previous review concerns); fresh installs default tools: [\"*\"] so preToolUse/postToolUse hooks actually fire.
  • Feed classification: Kiro's camelCase events are registered in a source-keyed table; isSideEffectingTool is source-scoped with case-insensitive Kiro-internal aliases (execute_bash, fs_write, etc.) so only the kiro source escalates those names to approval prompts.
  • Session restore & settings: RestorableAgentKind.kiro is wired end-to-end through sanitizer, resume-command builder, task manager, hibernation, and Settings (toggle + notification-level picker) with KiroIntegrationSettings mirroring the Gemini pattern."

Confidence Score: 5/5

Safe to merge; the new Kiro path is additive and isolated behind its own hook format, disable env var, and source checks.

All core logic — exit-2 propagation, fail-closed permission decisions, source-scoped side-effecting tool dispatch, and session-restore sanitization — is sound and follows established patterns for existing agents. The only gap is missing locale translations for 17 of the 20 supported languages, which does not affect runtime correctness.

Resources/Localizable.xcstrings — the 12 new Kiro string keys need translations for the 17 locales beyond en/ja/ko, particularly the two search-alias keys where the analogous gemini key already has 19 translations.

Important Files Changed

Filename Overview
CLI/CMUXCLI+AgentHookDefinitions.swift Adds .kiroAgentJSON HookFormat and the Kiro AgentHookDef; the feed hook dispatch now switches on format (post-fix from previous review); exitTwoPropagatingAgentHookShellCommand correctly propagates only exit 2 and falls back to {} for other errors.
CLI/FeedEventClassifier.swift Registers Kiro's camelCase events in a dedicated source entry; adds source-scoped isSideEffectingTool with case-insensitive Kiro aliases so only Kiro escalates approvals; logic is clear and correctly avoids broadening other agents' lowercase names into approvals.
CLI/cmux.swift Adds Kiro session-resume builder, kiroAgentJSON hook-merge/uninstall branches, shouldSuppressKiroFeedEvent filtering, and emitKiroDecisionIfHandled with fail-closed exit-2 on unknown/missing mode; all branches align with the established pattern for other agents.
Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerAdditionalPolicies.swift Adds kiroPolicy with correct value/dropped/reject option sets; --resume and -r are correctly in droppedOptions-only (boolean flags), --resume-id is in both valueOptions and droppedOptions so its argument is consumed, and non-restorable subcommands are enumerated.
Resources/Localizable.xcstrings Adds 12 new Kiro string keys, all translated into only en/ja/ko; 17 of the 20 supported locales are missing entries. The comparable gemini search-alias key has 19 locale translations, making the gap visible for kiro-specific search aliases especially.
Sources/cmuxApp.swift Adds KiroIntegrationSettings enum and wires @AppStorage bindings into the legacy SettingsView with an explicit comment acknowledging the dual-settings-view pattern; logic mirrors the existing Gemini integration.
Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/AutomationSection.swift Adds kiroCard with toggle, notification-level picker, and install note using DefaultsValueModel bindings; structure mirrors the existing Cursor/Gemini cards exactly.

Sequence Diagram

sequenceDiagram
    participant K as kiro-cli
    participant H as Kiro hook (shell)
    participant C as cmux CLI
    participant F as Feed/cmuxApp

    K->>H: "preToolUse {tool, input}"
    H->>C: cmux hooks feed --source kiro --event preToolUse
    C->>C: FeedEventClassifier.classify(source:"kiro", event:"preToolUse")
    alt side-effecting tool
        C->>F: PermissionRequest card (actionable)
        F-->>C: "decision {kind:"permission", mode:"once"|"deny"}"
        alt "mode == allow"
            C->>H: "print("{}")  exit 0"
            H-->>K: "{} (allow)"
        else "mode == deny / unknown"
            C->>H: exit(2)
            H-->>K: exit 2 (block tool)
        end
    else read-only tool (standard/verbose level)
        C->>F: PreToolUse card (non-actionable)
        C->>H: "print("{}")  exit 0"
        H-->>K: "{} (allow)"
    else "notification level == minimal"
        C->>H: "print("{}") without Feed card"
        H-->>K: "{} (allow)"
    end
Loading

Reviews (8): Last reviewed commit: "Increase Kiro suppression-test feed.push..." | Re-trigger Greptile

Comment thread CLI/CMUXCLI+AgentHookDefinitions.swift
Comment thread CLI/cmux.swift Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 4 potential issues.

There are 5 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 88229db. Configure here.

Comment thread CLI/cmux.swift Outdated
Comment thread CLI/cmux.swift
Comment thread CLI/cmux.swift Outdated
Comment thread CLI/cmux.swift Outdated
Catch up 215 commits. Two main-side refactors needed semantic conflict
resolution rather than picking a side:

* Feed-event classification (typed FeedEventClassifier registry): register
  "kiro" with its camelCase events (preToolUse/postToolUse/userPromptSubmit/
  agentSpawn/stop) and move Kiro's source-scoped side-effecting tool aliases
  + isSideEffectingTool into the classifier. Without this, Kiro's lowercase
  events fell through to .unknown and stopped escalating Feed approvals. Kept
  shouldSuppressKiroFeedEvent / emitKiroDecisionIfHandled in cmux.swift.

* Settings SPM migration (CmuxSettings/CmuxSettingsUI): the in-app SettingsView
  is now dead code, so wire the Kiro toggle + notification-level picker into the
  live AutomationSection, with kiro catalog keys in the Integrations/Automation
  catalog sections.

Also sync vendor/bonsplit to main's pointer (9166c36, forkConversation API) and
add the requested `--agent cmux` activation hint to `cmux hooks kiro install`
via a new AgentHookDef.postInstallNote. Regression coverage added in
FeedEventClassificationTests plus an install-hint assertion.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
coderabbitai[bot]
coderabbitai Bot previously requested changes May 31, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 30247-30262: emitKiroDecisionIfHandled currently treats any
non-"deny" non-empty mode as allowed; change it to a fail-closed policy by only
permitting when mode == "allow": inside emitKiroDecisionIfHandled, after
normalizing mode, check if mode == "allow" and in that case print the success
payload and return true; for all other cases (mode == "deny", mode == nil/empty,
or any other unexpected string) write a clear stderr message and exit with a
non-zero code (e.g., exit(2)) so unknown/typo modes are denied rather than
implicitly allowed.

In
`@Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerAdditionalPolicies.swift`:
- Around line 350-397: The kiroPolicy declaration lacks optionalValueOptions and
variadicOptions—either add the missing entries to Policy(…) on the kiroPolicy
symbol if kiro-cli actually exposes flags with optional values or variadic
(space-separated list) arguments, or document in a short comment above
kiroPolicy why those fields are intentionally omitted (e.g., "kiro has no
optional-value or variadic flags"); check other policies like copilotPolicy for
the expected keys and semantics of optionalValueOptions and variadicOptions to
mirror the correct shape.
- Around line 377-383: The kiroPolicy currently lists "--resume" and "-r" only
in droppedOptions so AgentLaunchSanitizer's index increment via optionWidth(...)
treats them as flags (width 1) and leaves the following session-id token; update
kiroPolicy to include "--resume" and "-r" in the correct value-carrying set
(either valueOptions or optionalValueOptions) consistent with kiro-cli semantics
so optionWidth(...) returns the proper width and both the flag and its argument
are dropped; adjust whichever of valueOptions/optionalValueOptions in kiroPolicy
is appropriate for the CLI (or add a runtime-only width mapping used by
optionWidth) and keep droppedOptions entries as-is.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 355d8652-f49e-44a5-8c7a-eb4798cd6733

📥 Commits

Reviewing files that changed from the base of the PR and between ca73d65 and 4cb99a1.

📒 Files selected for processing (30)
  • CLI/CMUXCLI+AgentHookDefinitions.swift
  • CLI/FeedEventClassifier.swift
  • CLI/cmux.swift
  • Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchEnvironmentPolicy.swift
  • Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerAdditionalPolicies.swift
  • Packages/CmuxSettings/Sources/CmuxSettings/Keys/AutomationCatalogSection.swift
  • Packages/CmuxSettings/Sources/CmuxSettings/Keys/IntegrationsCatalogSection.swift
  • Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/AutomationSection.swift
  • Resources/Localizable.xcstrings
  • Sources/AgentHibernation/AgentHibernationLifecycleState.swift
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/CommandPalette/CommandPaletteSettingsToggle.swift
  • Sources/GhosttyTerminalView.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/RestorableAgentSession.swift
  • Sources/RestorableAgentTypes.swift
  • Sources/SettingsNavigation.swift
  • Sources/SettingsSearchAliases.swift
  • Sources/TaskManagerTypes.swift
  • Sources/cmuxApp.swift
  • cmuxTests/CLIGenericHookPersistenceTests.swift
  • cmuxTests/FeedEventClassificationTests.swift
  • cmuxTests/GhosttyConfigTests.swift
  • cmuxTests/RestorableAgentHookProviderResumeTests.swift
  • cmuxTests/SessionPersistenceTests.swift
  • cmuxTests/WorkspaceUnitTests.swift
  • docs/agent-hooks.md
  • web/data/cmux.schema.json

Comment thread CLI/cmux.swift
Address CodeRabbit merge review:
- emitKiroDecisionIfHandled now allows only the WorkstreamPermissionMode
  allow values (once/always/all/bypass) and fails closed (exit 2) on deny,
  missing, empty, or any unrecognized mode. Previously any non-deny, non-empty
  mode was implicitly allowed. (CodeRabbit's suggested `mode != "allow"` was
  incorrect — there is no `allow` mode in WorkstreamPermissionMode.)
- Document why kiroPolicy omits optionalValueOptions/variadicOptions, and that
  --resume/-r are boolean (droppedOptions only) while --resume-id takes a value.
- Add testKiroFeedAllowModesProceedAndUnknownModeDenies (all four allow modes
  exit 0; an unknown mode fails closed with exit 2).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@austinywang

Copy link
Copy Markdown
Contributor Author

@coderabbitai All three findings from your review have been addressed and you confirmed each in-thread (the fail-closed allowlist fix, the boolean --resume/-r clarification, and the doc comment), and all threads are resolved. Could you re-review and clear the stale changes-requested state? Thanks!

@coderabbitai

coderabbitai Bot commented Jun 1, 2026

Copy link
Copy Markdown

@austinywang Sure! I'll kick off a fresh review now to reflect the addressed findings and update the review state.

(ノ◕ヮ◕)ノ*:・゚✧

✅ Actions performed

Full review triggered.

coderabbitai[bot]
coderabbitai Bot previously requested changes Jun 1, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CLI/cmux.swift`:
- Around line 30219-30245: Normalize the incoming Kiro hook event name in
shouldSuppressKiroFeedEvent by lowercasing/trimming hookEventName (or mapping
camelCase variants) before comparisons so checks against
"PreToolUse"/"PostToolUse" match real Kiro events like
"preToolUse"/"postToolUse"; update the switch and guard conditions that
reference hookEventName in shouldSuppressKiroFeedEvent to use the normalized
value and then apply the existing "minimal"/"standard"/"verbose" logic and
FeedEventClassifier.isSideEffectingTool(toolName, source: source) checks
unchanged.

In `@Sources/cmuxApp.swift`:
- Around line 5350-5353: The persisted kiroNotificationLevel string from
`@AppStorage` can contain unsupported raw values and bypass
KiroIntegrationSettings.notificationLevel(defaults:) normalization, causing the
picker to show no selection; create a Binding<String> (e.g.,
kiroNotificationLevelBinding) that in its getter converts the stored string to
the normalized enum via KiroIntegrationSettings.notificationLevel(defaults:),
returning that enum.rawValue, and in its setter writes the new rawValue back
into the `@AppStorage-backed` kiroNotificationLevel; then use selection:
kiroNotificationLevelBinding in the legacy Picker so the UI always reflects the
effective (normalized) setting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 8adcc4b9-6f1e-4f1d-9a77-2d1c6f6ee8bd

📥 Commits

Reviewing files that changed from the base of the PR and between ca73d65 and 1d578dd.

📒 Files selected for processing (30)
  • CLI/CMUXCLI+AgentHookDefinitions.swift
  • CLI/FeedEventClassifier.swift
  • CLI/cmux.swift
  • Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchEnvironmentPolicy.swift
  • Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizer.swift
  • Packages/CMUXAgentLaunch/Sources/CMUXAgentLaunch/AgentLaunchSanitizerAdditionalPolicies.swift
  • Packages/CmuxSettings/Sources/CmuxSettings/Keys/AutomationCatalogSection.swift
  • Packages/CmuxSettings/Sources/CmuxSettings/Keys/IntegrationsCatalogSection.swift
  • Packages/CmuxSettingsUI/Sources/CmuxSettingsUI/Sections/AutomationSection.swift
  • Resources/Localizable.xcstrings
  • Sources/AgentHibernation/AgentHibernationLifecycleState.swift
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/CommandPalette/CommandPaletteSettingsToggle.swift
  • Sources/GhosttyTerminalView.swift
  • Sources/KeyboardShortcutSettingsFileStore+Template.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/RestorableAgentSession.swift
  • Sources/RestorableAgentTypes.swift
  • Sources/SettingsNavigation.swift
  • Sources/SettingsSearchAliases.swift
  • Sources/TaskManagerTypes.swift
  • Sources/cmuxApp.swift
  • cmuxTests/CLIGenericHookPersistenceTests.swift
  • cmuxTests/FeedEventClassificationTests.swift
  • cmuxTests/GhosttyConfigTests.swift
  • cmuxTests/RestorableAgentHookProviderResumeTests.swift
  • cmuxTests/SessionPersistenceTests.swift
  • cmuxTests/WorkspaceUnitTests.swift
  • docs/agent-hooks.md
  • web/data/cmux.schema.json
👮 Files not reviewed due to content moderation or server errors (1)
  • Sources/GhosttyTerminalView.swift

Comment thread CLI/cmux.swift
Comment thread Sources/cmuxApp.swift
The CmuxSettingsUI Kiro card resolves `settings.automation.kiro.note` against
the app bundle, where the existing xcstrings entry shadowed the package
`defaultValue`, so the note rendered without the activation hint. Update the
en/ja/ko note text to include the `kiro-cli chat --agent cmux` guidance,
matching the `cmux hooks kiro install` output and the AutomationSection
defaultValue. Verified live: the Settings > Automation > Kiro note now shows it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 issues found across 30 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread cmuxTests/RestorableAgentHookProviderResumeTests.swift
Comment thread CLI/CMUXCLI+AgentHookDefinitions.swift Outdated
Comment thread CLI/CMUXCLI+AgentHookDefinitions.swift
Comment thread cmuxTests/CLIGenericHookPersistenceTests.swift
- Localize the `cmux hooks kiro install` activation note via String(localized:)
  plus an en/ja/ko Localizable.xcstrings entry (cubic P2).
- Add testKiroStandardLevelSuppressesReadOnlyToolFeedEvents: proves the
  standard-level Feed suppression triggers for real Kiro events (read-only
  fs_read suppressed, mutating fs_write emitted). This refutes the "event names
  never match" finding -- shouldSuppressKiroFeedEvent keys off the classified
  wire name (PostToolUse), not the raw camelCase event.

Remaining round-2 findings verified as false positives / consistent-with-existing
and answered on-thread: the resume bare-cd prefix is uniform across all agents,
and the hook CLI fallback + XCTest integration harness match the established
cross-agent pattern.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 3 files (changes from recent commits).

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread cmuxTests/CLIGenericHookPersistenceTests.swift Outdated
austinywang and others added 2 commits May 31, 2026 18:32
…tive-kiro-cli-hook

# Conflicts:
#	Resources/Localizable.xcstrings
`kiro-cli chat --agent cmux` was effectively unusable: a Kiro custom agent
config with no `tools` field is restricted to no tools, so the model could not
run anything and the preToolUse/postToolUse Feed-approval hooks never fired.

Add `tools: ["*"]` to the generated `~/.kiro/agents/cmux.json` (guarded by
`== nil` so an existing user `tools` list is preserved). Verified end-to-end
against real kiro-cli 2.5.0: with the fix, `kiro-cli chat --agent cmux` runs
shell tools and fires preToolUse with tool_name=execute_bash (which
kiroSideEffectingToolAliases escalates to a Feed approval). Added a regression
assertion for the tools field to the install-shape test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
web/data/cmux.schema.json (1)

884-898: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Add i18n support for Kiro integration setting descriptions

automation.kiroIntegration and automation.kiroNotificationLevel define user-facing description strings directly (no descriptionKey). There are no corresponding localized web/messages/* / schemaDescriptions.*kiro* entries, so the UI copy will not be localized for all locales in web/i18n/routing.ts. Update the schema to use descriptionKey values and add complete translations for every locale.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/data/cmux.schema.json` around lines 884 - 898, The schema currently
embeds English-only descriptions for automation.kiroIntegration and
automation.kiroNotificationLevel; replace those description fields with
descriptionKey entries (e.g., schemaDescriptions.automation.kiroIntegration and
schemaDescriptions.automation.kiroNotificationLevel) in the cmux.schema.json and
then add matching translation keys under web/messages/* (create
schemaDescriptions.*kiro* entries) for every locale used by web/i18n/routing.ts
so the UI can localize these strings across locales.
CLI/CMUXCLI+AgentHookDefinitions.swift (2)

382-385: 🧹 Nitpick | 🔵 Trivial | ⚖️ Poor tradeoff

Exit code handling converts non-deny errors to success (fail-open).

The shell command correctly propagates exit code 2 (deny), but non-2 errors print {} and implicitly exit 0 (from the echo command's success). This means communication errors or other failures will allow the tool to proceed rather than failing closed.

This is consistent with the existing || echo '{}' pattern used in agentHookShellCommand (line 379), and it's actually more secure than the generic wrapper since it preserves deny decisions rather than converting them to success. The fail-open behavior for non-deny errors appears to be an intentional design choice to maintain usability when cmux is unavailable.

Consider whether fail-closed behavior (exit 2 for all errors) would be more appropriate for security-sensitive Kiro tool permissions, or document the current fail-open design decision.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLI/CMUXCLI`+AgentHookDefinitions.swift around lines 382 - 385, The
exitTwoPropagatingAgentHookShellCommand currently prints '{}' on any non-2 error
which returns a zero exit and causes fail-open; update the shell wrapper in
exitTwoPropagatingAgentHookShellCommand to return a non-zero/deny exit for any
cmux invocation failure (i.e., when status != 0 and status != 2) instead of
echoing '{}', so that non-deny errors propagate as a failing/deny exit (preserve
the existing behavior for status==2), and ensure the conditional logic still
uses def.disableEnvVar and CMUX_* checks as currently referenced.

243-246: ⚠️ Potential issue | 🟠 Major

Fix incomplete localization for cli.hooks.kiro.postInstallNote
Resources/Localizable.xcstrings defines "cli.hooks.kiro.postInstallNote" only for locales en, ja, and ko; it’s missing for: ar, bs, da, de, es, fr, it, km, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CLI/CMUXCLI`+AgentHookDefinitions.swift around lines 243 - 246, The localized
string for postInstallNote (localized key "cli.hooks.kiro.postInstallNote",
defined via postInstallNote: String(localized: ...)) is only present for
en/ja/ko; add entries for the missing locales (ar, bs, da, de, es, fr, it, km,
nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant) in
Resources/Localizable.xcstrings, providing either proper translations or a
fallback (e.g., copy the English defaultValue) for each locale so the key exists
for all listed languages and the app uses localized text instead of falling back
unexpectedly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@CLI/CMUXCLI`+AgentHookDefinitions.swift:
- Around line 382-385: The exitTwoPropagatingAgentHookShellCommand currently
prints '{}' on any non-2 error which returns a zero exit and causes fail-open;
update the shell wrapper in exitTwoPropagatingAgentHookShellCommand to return a
non-zero/deny exit for any cmux invocation failure (i.e., when status != 0 and
status != 2) instead of echoing '{}', so that non-deny errors propagate as a
failing/deny exit (preserve the existing behavior for status==2), and ensure the
conditional logic still uses def.disableEnvVar and CMUX_* checks as currently
referenced.
- Around line 243-246: The localized string for postInstallNote (localized key
"cli.hooks.kiro.postInstallNote", defined via postInstallNote: String(localized:
...)) is only present for en/ja/ko; add entries for the missing locales (ar, bs,
da, de, es, fr, it, km, nb, pl, pt-BR, ru, th, tr, uk, zh-Hans, zh-Hant) in
Resources/Localizable.xcstrings, providing either proper translations or a
fallback (e.g., copy the English defaultValue) for each locale so the key exists
for all listed languages and the app uses localized text instead of falling back
unexpectedly.

In `@web/data/cmux.schema.json`:
- Around line 884-898: The schema currently embeds English-only descriptions for
automation.kiroIntegration and automation.kiroNotificationLevel; replace those
description fields with descriptionKey entries (e.g.,
schemaDescriptions.automation.kiroIntegration and
schemaDescriptions.automation.kiroNotificationLevel) in the cmux.schema.json and
then add matching translation keys under web/messages/* (create
schemaDescriptions.*kiro* entries) for every locale used by web/i18n/routing.ts
so the UI can localize these strings across locales.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 0a52c0ef-cd8b-475b-86a0-3cb079d3a14e

📥 Commits

Reviewing files that changed from the base of the PR and between fdca10f and 3c020fc.

📒 Files selected for processing (11)
  • CLI/CMUXCLI+AgentHookDefinitions.swift
  • CLI/cmux.swift
  • Resources/Localizable.xcstrings
  • Sources/CmuxSettingsJSONPathSupport.swift
  • Sources/GhosttyTerminalView.swift
  • Sources/KeyboardShortcutSettingsFileStore.swift
  • Sources/cmuxApp.swift
  • cmuxTests/CLIGenericHookPersistenceTests.swift
  • cmuxTests/GhosttyConfigTests.swift
  • cmuxTests/WorkspaceUnitTests.swift
  • web/data/cmux.schema.json

The 1.5s XCTWaiter on the non-suppressed (fs_write) branch could count
state.commands before the mock-server callback ran under CI load, flaking the
assertion. Bump to 5s (the suppressed branch still times out silently).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@austinywang
austinywang dismissed stale reviews from coderabbitai[bot] and coderabbitai[bot] June 1, 2026 02:05

All findings from this review have been addressed and the threads resolved (fixes + verified false-positive explanations replied on-thread; CodeRabbit acknowledged each). Dismissing the stale changes-requested state.

@austinywang
austinywang merged commit 4aaee69 into main Jun 1, 2026
28 of 29 checks passed

This branch was successfully deployed

1 active deployment
Preview – cmux — 65887603 Deployed Jun 1, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Native Kiro-CLI Hook/Notification Integration for CMUX

1 participant