@songsid/agend 2.1.12 → 2.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -2
- package/README.zh-TW.md +4 -2
- package/dist/agent-cli.js +6 -1
- package/dist/agent-cli.js.map +1 -1
- package/dist/agent-endpoint.js +68 -12
- package/dist/agent-endpoint.js.map +1 -1
- package/dist/agent-token-header.d.ts +13 -0
- package/dist/agent-token-header.js +16 -0
- package/dist/agent-token-header.js.map +1 -0
- package/dist/auth/one-time-code.d.ts +19 -0
- package/dist/auth/one-time-code.js +49 -0
- package/dist/auth/one-time-code.js.map +1 -0
- package/dist/auth-api.d.ts +52 -0
- package/dist/auth-api.js +346 -0
- package/dist/auth-api.js.map +1 -0
- package/dist/backend/antigravity.js +4 -3
- package/dist/backend/antigravity.js.map +1 -1
- package/dist/backend/claude-code.d.ts +4 -0
- package/dist/backend/claude-code.js +97 -0
- package/dist/backend/claude-code.js.map +1 -1
- package/dist/backend/codex.js +59 -30
- package/dist/backend/codex.js.map +1 -1
- package/dist/backend/grok.js +1 -1
- package/dist/backend/grok.js.map +1 -1
- package/dist/backend/kiro-agent.d.ts +66 -0
- package/dist/backend/kiro-agent.js +302 -0
- package/dist/backend/kiro-agent.js.map +1 -0
- package/dist/backend/kiro-identity.d.ts +80 -0
- package/dist/backend/kiro-identity.js +537 -0
- package/dist/backend/kiro-identity.js.map +1 -0
- package/dist/backend/kiro-v2-store-worker.d.ts +1 -0
- package/dist/backend/kiro-v2-store-worker.js +87 -0
- package/dist/backend/kiro-v2-store-worker.js.map +1 -0
- package/dist/backend/kiro-v2-store.d.ts +54 -0
- package/dist/backend/kiro-v2-store.js +131 -0
- package/dist/backend/kiro-v2-store.js.map +1 -0
- package/dist/backend/kiro-v3-identity.d.ts +5 -0
- package/dist/backend/kiro-v3-identity.js +22 -0
- package/dist/backend/kiro-v3-identity.js.map +1 -1
- package/dist/backend/kiro.d.ts +90 -7
- package/dist/backend/kiro.js +500 -124
- package/dist/backend/kiro.js.map +1 -1
- package/dist/backend/muse.js +1 -1
- package/dist/backend/muse.js.map +1 -1
- package/dist/backend/types.d.ts +51 -3
- package/dist/backend/types.js.map +1 -1
- package/dist/cache-analysis.d.ts +92 -0
- package/dist/cache-analysis.js +147 -0
- package/dist/cache-analysis.js.map +1 -0
- package/dist/cache-ledger.d.ts +108 -0
- package/dist/cache-ledger.js +230 -0
- package/dist/cache-ledger.js.map +1 -0
- package/dist/cache-prices.d.ts +32 -0
- package/dist/cache-prices.js +73 -0
- package/dist/cache-prices.js.map +1 -0
- package/dist/cache-scan.d.ts +39 -0
- package/dist/cache-scan.js +115 -0
- package/dist/cache-scan.js.map +1 -0
- package/dist/cache-service.d.ts +115 -0
- package/dist/cache-service.js +417 -0
- package/dist/cache-service.js.map +1 -0
- package/dist/channel/adapters/discord.d.ts +1 -0
- package/dist/channel/adapters/discord.js +29 -10
- package/dist/channel/adapters/discord.js.map +1 -1
- package/dist/channel/adapters/telegram.d.ts +1 -0
- package/dist/channel/adapters/telegram.js +13 -1
- package/dist/channel/adapters/telegram.js.map +1 -1
- package/dist/channel/types.d.ts +9 -1
- package/dist/classic-channel-manager.d.ts +18 -10
- package/dist/classic-channel-manager.js +45 -18
- package/dist/classic-channel-manager.js.map +1 -1
- package/dist/cli-entry.d.ts +19 -0
- package/dist/cli-entry.js +36 -0
- package/dist/cli-entry.js.map +1 -0
- package/dist/cli.js +471 -146
- package/dist/cli.js.map +1 -1
- package/dist/command-table.d.ts +5 -3
- package/dist/command-table.js +29 -27
- package/dist/command-table.js.map +1 -1
- package/dist/config-validator.js +46 -0
- package/dist/config-validator.js.map +1 -1
- package/dist/config.js +12 -0
- package/dist/config.js.map +1 -1
- package/dist/connection-secrets.d.ts +6 -0
- package/dist/connection-secrets.js +4 -0
- package/dist/connection-secrets.js.map +1 -1
- package/dist/daemon.d.ts +95 -4
- package/dist/daemon.js +748 -111
- package/dist/daemon.js.map +1 -1
- package/dist/darwin-memory.d.ts +6 -1
- package/dist/darwin-memory.js +17 -6
- package/dist/darwin-memory.js.map +1 -1
- package/dist/delivery-consumed-watch.d.ts +85 -0
- package/dist/delivery-consumed-watch.js +244 -0
- package/dist/delivery-consumed-watch.js.map +1 -0
- package/dist/delivery-outbox.d.ts +61 -0
- package/dist/delivery-outbox.js +120 -2
- package/dist/delivery-outbox.js.map +1 -1
- package/dist/delivery-reconciliation.d.ts +14 -5
- package/dist/delivery-reconciliation.js +27 -4
- package/dist/delivery-reconciliation.js.map +1 -1
- package/dist/delivery-reconciliation.test.js +35 -1
- package/dist/delivery-reconciliation.test.js.map +1 -1
- package/dist/event-log.d.ts +4 -1
- package/dist/event-log.js +6 -3
- package/dist/event-log.js.map +1 -1
- package/dist/event-loop-watch.d.ts +28 -0
- package/dist/event-loop-watch.js +75 -3
- package/dist/event-loop-watch.js.map +1 -1
- package/dist/fleet-context.d.ts +22 -2
- package/dist/fleet-control-audit.d.ts +5 -0
- package/dist/fleet-control-audit.js +7 -0
- package/dist/fleet-control-audit.js.map +1 -1
- package/dist/fleet-level-config.d.ts +2 -2
- package/dist/fleet-level-config.js +28 -1
- package/dist/fleet-level-config.js.map +1 -1
- package/dist/fleet-manager.d.ts +339 -12
- package/dist/fleet-manager.js +2623 -461
- package/dist/fleet-manager.js.map +1 -1
- package/dist/full-restart.js +2 -3
- package/dist/full-restart.js.map +1 -1
- package/dist/general-knowledge/skills/persona-emoji/SKILL.md +3 -1
- package/dist/host-memory.d.ts +4 -0
- package/dist/host-memory.js.map +1 -1
- package/dist/install-lock.d.ts +49 -0
- package/dist/install-lock.js +200 -0
- package/dist/install-lock.js.map +1 -0
- package/dist/instance-config-impact.js +8 -2
- package/dist/instance-config-impact.js.map +1 -1
- package/dist/instance-lifecycle.d.ts +10 -5
- package/dist/instance-lifecycle.js +162 -53
- package/dist/instance-lifecycle.js.map +1 -1
- package/dist/locale.js +164 -16
- package/dist/locale.js.map +1 -1
- package/dist/login-controller.d.ts +2 -0
- package/dist/login-controller.js +17 -5
- package/dist/login-controller.js.map +1 -1
- package/dist/memory-pressure.d.ts +7 -8
- package/dist/memory-pressure.js +76 -15
- package/dist/memory-pressure.js.map +1 -1
- package/dist/monotonic-budget.d.ts +2 -0
- package/dist/monotonic-budget.js +28 -0
- package/dist/monotonic-budget.js.map +1 -0
- package/dist/needs-you-hub.d.ts +114 -0
- package/dist/needs-you-hub.js +370 -0
- package/dist/needs-you-hub.js.map +1 -0
- package/dist/needs-you-live.d.ts +116 -0
- package/dist/needs-you-live.js +228 -0
- package/dist/needs-you-live.js.map +1 -0
- package/dist/needs-you.d.ts +132 -0
- package/dist/needs-you.js +164 -0
- package/dist/needs-you.js.map +1 -0
- package/dist/node-version-guard.d.ts +30 -0
- package/dist/node-version-guard.js +50 -0
- package/dist/node-version-guard.js.map +1 -0
- package/dist/operator-control-paths.d.ts +4 -0
- package/dist/operator-control-paths.js +24 -0
- package/dist/operator-control-paths.js.map +1 -0
- package/dist/outbound-handlers.d.ts +2 -0
- package/dist/outbound-handlers.js +9 -2
- package/dist/outbound-handlers.js.map +1 -1
- package/dist/outbound-schemas.d.ts +5 -5
- package/dist/outbound-schemas.js +1 -1
- package/dist/outbound-schemas.js.map +1 -1
- package/dist/package-preimage.d.ts +26 -0
- package/dist/package-preimage.js +96 -0
- package/dist/package-preimage.js.map +1 -0
- package/dist/profile-control.js +4 -20
- package/dist/profile-control.js.map +1 -1
- package/dist/public-web-gateway.d.ts +18 -0
- package/dist/public-web-gateway.js +141 -0
- package/dist/public-web-gateway.js.map +1 -0
- package/dist/public-web-link.d.ts +53 -0
- package/dist/public-web-link.js +175 -0
- package/dist/public-web-link.js.map +1 -0
- package/dist/quickstart-api.d.ts +8 -1
- package/dist/quickstart-api.js +86 -48
- package/dist/quickstart-api.js.map +1 -1
- package/dist/quickstart.d.ts +1 -0
- package/dist/quickstart.js +16 -6
- package/dist/quickstart.js.map +1 -1
- package/dist/restart-guard.d.ts +52 -0
- package/dist/restart-guard.js +109 -0
- package/dist/restart-guard.js.map +1 -0
- package/dist/scheduler/db.d.ts +7 -1
- package/dist/scheduler/db.js +44 -2
- package/dist/scheduler/db.js.map +1 -1
- package/dist/scheduler/index.d.ts +1 -1
- package/dist/scheduler/retry-label.d.ts +11 -0
- package/dist/scheduler/retry-label.js +24 -0
- package/dist/scheduler/retry-label.js.map +1 -0
- package/dist/scheduler/scheduler.d.ts +55 -2
- package/dist/scheduler/scheduler.js +220 -8
- package/dist/scheduler/scheduler.js.map +1 -1
- package/dist/scheduler/types.d.ts +22 -0
- package/dist/scheduler/types.js.map +1 -1
- package/dist/secret-store.d.ts +5 -0
- package/dist/secret-store.js +20 -0
- package/dist/secret-store.js.map +1 -1
- package/dist/service-activation.d.ts +152 -0
- package/dist/service-activation.js +407 -0
- package/dist/service-activation.js.map +1 -0
- package/dist/service-installer.d.ts +63 -1
- package/dist/service-installer.js +141 -16
- package/dist/service-installer.js.map +1 -1
- package/dist/service-plan.d.ts +65 -0
- package/dist/service-plan.js +108 -0
- package/dist/service-plan.js.map +1 -0
- package/dist/service-restart-selection.d.ts +6 -5
- package/dist/service-restart-selection.js +6 -5
- package/dist/service-restart-selection.js.map +1 -1
- package/dist/settings-api.d.ts +10 -2
- package/dist/settings-api.js +216 -72
- package/dist/settings-api.js.map +1 -1
- package/dist/settings-baseline.d.ts +20 -0
- package/dist/settings-baseline.js +104 -0
- package/dist/settings-baseline.js.map +1 -0
- package/dist/settings-change.d.ts +21 -0
- package/dist/settings-change.js +161 -0
- package/dist/settings-change.js.map +1 -0
- package/dist/settings-confirmation.d.ts +105 -0
- package/dist/settings-confirmation.js +232 -0
- package/dist/settings-confirmation.js.map +1 -0
- package/dist/settings-control.d.ts +41 -0
- package/dist/settings-control.js +294 -0
- package/dist/settings-control.js.map +1 -0
- package/dist/settings-effect.d.ts +24 -0
- package/dist/settings-effect.js +169 -0
- package/dist/settings-effect.js.map +1 -0
- package/dist/settings-http-confirmation.d.ts +29 -0
- package/dist/settings-http-confirmation.js +123 -0
- package/dist/settings-http-confirmation.js.map +1 -0
- package/dist/settings-instance-patch.d.ts +4 -0
- package/dist/settings-instance-patch.js +26 -0
- package/dist/settings-instance-patch.js.map +1 -0
- package/dist/settings-request-capability.d.ts +16 -0
- package/dist/settings-request-capability.js +32 -0
- package/dist/settings-request-capability.js.map +1 -0
- package/dist/settings-transaction.d.ts +65 -0
- package/dist/settings-transaction.js +223 -0
- package/dist/settings-transaction.js.map +1 -0
- package/dist/setup-auth.d.ts +10 -18
- package/dist/setup-auth.js +14 -38
- package/dist/setup-auth.js.map +1 -1
- package/dist/setup-form.d.ts +1 -1
- package/dist/setup-form.js +75 -18
- package/dist/setup-form.js.map +1 -1
- package/dist/setup-guide.d.ts +13 -0
- package/dist/setup-guide.js +25 -0
- package/dist/setup-guide.js.map +1 -0
- package/dist/setup-host.d.ts +16 -0
- package/dist/setup-host.js +199 -35
- package/dist/setup-host.js.map +1 -1
- package/dist/setup-wizard.js +5 -1
- package/dist/setup-wizard.js.map +1 -1
- package/dist/slash-authz.d.ts +17 -3
- package/dist/slash-authz.js +5 -0
- package/dist/slash-authz.js.map +1 -1
- package/dist/spawn-gate.js +3 -3
- package/dist/spawn-gate.js.map +1 -1
- package/dist/sqlite-open-errors.d.ts +12 -0
- package/dist/sqlite-open-errors.js +13 -0
- package/dist/sqlite-open-errors.js.map +1 -0
- package/dist/statusline-watcher.d.ts +5 -0
- package/dist/statusline-watcher.js +2 -0
- package/dist/statusline-watcher.js.map +1 -1
- package/dist/steer-capability.d.ts +6 -0
- package/dist/steer-capability.js +8 -0
- package/dist/steer-capability.js.map +1 -1
- package/dist/sync-work-attribution.d.ts +14 -0
- package/dist/sync-work-attribution.js +43 -8
- package/dist/sync-work-attribution.js.map +1 -1
- package/dist/tips.js +10 -5
- package/dist/tips.js.map +1 -1
- package/dist/tmux-control.d.ts +57 -5
- package/dist/tmux-control.js +379 -61
- package/dist/tmux-control.js.map +1 -1
- package/dist/tmux-manager.d.ts +20 -6
- package/dist/tmux-manager.js +90 -47
- package/dist/tmux-manager.js.map +1 -1
- package/dist/tmux-read.d.ts +59 -0
- package/dist/tmux-read.js +213 -0
- package/dist/tmux-read.js.map +1 -0
- package/dist/topic-commands.d.ts +21 -10
- package/dist/topic-commands.js +205 -63
- package/dist/topic-commands.js.map +1 -1
- package/dist/transcript-delta-reader.js +2 -1
- package/dist/transcript-delta-reader.js.map +1 -1
- package/dist/tunnel/cloudflared-install.d.ts +2 -0
- package/dist/tunnel/cloudflared-install.js +1 -1
- package/dist/tunnel/cloudflared-install.js.map +1 -1
- package/dist/tunnel/purpose-lane.d.ts +14 -0
- package/dist/tunnel/purpose-lane.js +43 -0
- package/dist/tunnel/purpose-lane.js.map +1 -0
- package/dist/turn-reply-guard.d.ts +2 -0
- package/dist/turn-reply-guard.js +10 -1
- package/dist/turn-reply-guard.js.map +1 -1
- package/dist/types.d.ts +33 -0
- package/dist/ui/app.html +18 -0
- package/dist/ui/chat-commands.js +43 -0
- package/dist/ui/chat-render.js +478 -0
- package/dist/ui/chat-store.js +318 -0
- package/dist/ui/chat-strings.js +89 -0
- package/dist/ui/chat-thread.js +246 -0
- package/dist/ui/chat-tour.js +116 -0
- package/dist/ui/fleet-cache.js +168 -0
- package/dist/ui/fleet-org.js +142 -0
- package/dist/ui/panel-chat.js +504 -0
- package/dist/ui/panel-fleet.js +427 -0
- package/dist/ui/panel-needs.js +202 -0
- package/dist/ui/panel-settings.js +754 -0
- package/dist/ui/preview-panel.js +202 -0
- package/dist/ui/preview.js +270 -0
- package/dist/ui/settings-apply.js +239 -0
- package/dist/ui/settings-confirm.js +186 -0
- package/dist/ui/settings-dialogs.js +546 -0
- package/dist/ui/settings-model.js +277 -0
- package/dist/ui/settings-strings.js +654 -0
- package/dist/ui/settings-wizard.js +140 -0
- package/dist/ui/shared/agend-auth.js +93 -0
- package/dist/ui/shared/app-ctx.js +80 -0
- package/dist/ui/shared/app-html.js +9 -0
- package/dist/ui/shared/app-i18n.js +95 -0
- package/dist/ui/shared/app-nav.js +73 -0
- package/dist/ui/shared/app-needs.js +114 -0
- package/dist/ui/shared/app-route.js +73 -0
- package/dist/ui/shared/app-session.js +66 -0
- package/dist/ui/shared/app-shell.js +346 -0
- package/dist/ui/shared/app-store.js +51 -0
- package/dist/ui/shared/app-stream.js +201 -0
- package/dist/ui/shared/app.css +820 -0
- package/dist/ui/shared/app.js +88 -0
- package/dist/ui/shared/fonts/OFL.txt +92 -0
- package/dist/ui/shared/fonts/README.md +21 -0
- package/dist/ui/shared/fonts/inter.woff2 +0 -0
- package/dist/ui/shared/htm.module.js +1 -0
- package/dist/ui/shared/panel-view.js +655 -0
- package/dist/ui/shared/preact-hooks.module.js +2 -0
- package/dist/ui/shared/preact.module.js +2 -0
- package/dist/ui/shared/signin.js +142 -0
- package/dist/ui/shared/theme.js +29 -0
- package/dist/ui/shared/tokens.css +153 -0
- package/dist/ui/shared/ui-confirm.js +43 -0
- package/dist/ui/shared/ui-dialog.js +45 -0
- package/dist/ui/shared/ui-icons.js +63 -0
- package/dist/ui/shared/ui-menu.js +39 -0
- package/dist/ui/shared/ui-states.js +20 -0
- package/dist/ui/shared/ui-toast.js +18 -0
- package/dist/ui/shared/vendor/htm.LICENSE +202 -0
- package/dist/ui/shared/vendor/preact.LICENSE +21 -0
- package/dist/ui/shared/vendor/vendor.json +39 -0
- package/dist/ui/shared/view-strings.js +309 -0
- package/dist/ui/signin.html +52 -0
- package/dist/update-check.d.ts +6 -2
- package/dist/update-check.js +12 -3
- package/dist/update-check.js.map +1 -1
- package/dist/update-dispatch.d.ts +28 -0
- package/dist/update-dispatch.js +73 -0
- package/dist/update-dispatch.js.map +1 -0
- package/dist/update-install.d.ts +129 -0
- package/dist/update-install.js +262 -0
- package/dist/update-install.js.map +1 -0
- package/dist/upgrade-notices.d.ts +17 -0
- package/dist/upgrade-notices.js +93 -0
- package/dist/upgrade-notices.js.map +1 -0
- package/dist/usage/statusline-usage.d.ts +2 -0
- package/dist/usage/statusline-usage.js +14 -10
- package/dist/usage/statusline-usage.js.map +1 -1
- package/dist/view-api.d.ts +6 -1
- package/dist/view-api.js +62 -51
- package/dist/view-api.js.map +1 -1
- package/dist/web-api.d.ts +85 -14
- package/dist/web-api.js +557 -77
- package/dist/web-api.js.map +1 -1
- package/dist/web-auth.d.ts +71 -27
- package/dist/web-auth.js +169 -69
- package/dist/web-auth.js.map +1 -1
- package/dist/web-body.d.ts +3 -0
- package/dist/web-body.js +55 -0
- package/dist/web-body.js.map +1 -0
- package/dist/web-channel-echo.d.ts +9 -0
- package/dist/web-channel-echo.js +55 -0
- package/dist/web-channel-echo.js.map +1 -0
- package/dist/web-chat-history.d.ts +125 -0
- package/dist/web-chat-history.js +184 -0
- package/dist/web-chat-history.js.map +1 -0
- package/dist/web-commands.d.ts +77 -0
- package/dist/web-commands.js +81 -0
- package/dist/web-commands.js.map +1 -0
- package/dist/web-continuation.d.ts +7 -0
- package/dist/web-continuation.js +22 -0
- package/dist/web-continuation.js.map +1 -0
- package/dist/web-host-guard.d.ts +34 -0
- package/dist/web-host-guard.js +57 -1
- package/dist/web-host-guard.js.map +1 -1
- package/dist/web-login.d.ts +72 -0
- package/dist/web-login.js +132 -0
- package/dist/web-login.js.map +1 -0
- package/dist/web-org.d.ts +55 -0
- package/dist/web-org.js +67 -0
- package/dist/web-org.js.map +1 -0
- package/dist/web-preview.d.ts +77 -0
- package/dist/web-preview.js +240 -0
- package/dist/web-preview.js.map +1 -0
- package/dist/web-request-context.d.ts +10 -0
- package/dist/web-request-context.js +13 -0
- package/dist/web-request-context.js.map +1 -0
- package/dist/web-session.d.ts +167 -0
- package/dist/web-session.js +389 -0
- package/dist/web-session.js.map +1 -0
- package/dist/web-shell-routes.d.ts +59 -0
- package/dist/web-shell-routes.js +96 -0
- package/dist/web-shell-routes.js.map +1 -0
- package/dist/web-upload.d.ts +183 -0
- package/dist/web-upload.js +468 -0
- package/dist/web-upload.js.map +1 -0
- package/dist/website-tips-renderer.d.ts +2 -2
- package/dist/website-tips-renderer.js +3 -3
- package/dist/website-tips-renderer.js.map +1 -1
- package/launcher/agend +110 -0
- package/launcher/agend-agent +110 -0
- package/launcher/agend-agent.cjs +4 -0
- package/launcher/agend.cjs +4 -0
- package/launcher/install-admission.cjs +105 -0
- package/launcher/launch.cjs +64 -0
- package/launcher/postinstall.cjs +114 -0
- package/launcher/run-in-process.cjs +13 -0
- package/launcher/runtime-platform.cjs +86 -0
- package/launcher/runtime-select.cjs +217 -0
- package/package.json +18 -7
- package/scripts/preinstall-guard.cjs +55 -0
- package/templates/launchd.plist.ejs +2 -2
- package/templates/systemd.service.ejs +1 -1
- package/dist/ui/dashboard.html +0 -774
- package/dist/ui/settings.html +0 -2165
- package/dist/ui/view.html +0 -1139
package/dist/backend/kiro.js
CHANGED
|
@@ -1,16 +1,20 @@
|
|
|
1
1
|
import { measureSyncWork } from "../sync-work-attribution.js";
|
|
2
2
|
import { EFFORT_CAPABILITIES } from "./effort-metadata.js";
|
|
3
|
-
import { join } from "node:path";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
4
5
|
import { getAgendHome } from "../paths.js";
|
|
5
|
-
import { credentialHomeSpec, credentialProfileHome, prepareCredentialProfileHome, resolveCredentialProfile, } from "./credential-profile.js";
|
|
6
|
+
import { credentialHomeSpec, credentialProfileHome, credentialProfileStoreHome, prepareCredentialProfileHome, resolveCredentialProfile, } from "./credential-profile.js";
|
|
7
|
+
import { kiroAgentName, kiroFleetTag, writeKiroAgent, removeKiroAgent, writeSharedKiroMcpEntries, removeSharedKiroMcpEntries, writeTaggedKiroSteering, removeTaggedKiroSteering, } from "./kiro-agent.js";
|
|
8
|
+
import { resolveKiroIdentity, listKiroV1Sessions, listKiroV2Sessions, confirmKiroAgentSwitch, kiroAgentConfirmed, forgetKiroIdentity, kiroIdentityNeedsStore, kiroCanonicalDirectory, KiroIdentityError, } from "./kiro-identity.js";
|
|
9
|
+
import { readKiroLedger } from "./kiro-engine-ledger.js";
|
|
6
10
|
import { execFileSync } from "node:child_process";
|
|
7
|
-
import {
|
|
11
|
+
import { writeFileSync, chmodSync, statSync } from "node:fs";
|
|
8
12
|
import { UnsupportedCliError, resolveBinary, shellQuote, validateEffort, validateModel, warnIfModelMismatch } from "./types.js";
|
|
9
13
|
import { PIE_CLASS } from "../tui-glyphs.js";
|
|
10
14
|
import { KIRO_EXPIRED_LOGIN_SCREEN } from "../login-flows.js";
|
|
11
15
|
import { t } from "../locale.js";
|
|
12
16
|
import { recordKiroLaunch } from "./kiro-engine-ledger.js";
|
|
13
|
-
import { resolveKiroV3Resume } from "./kiro-v3-identity.js";
|
|
17
|
+
import { forgetKiroV3Identity, resolveKiroV3Resume } from "./kiro-v3-identity.js";
|
|
14
18
|
// Kiro CLI feature gates. These are deliberately separate: the flags shipped
|
|
15
19
|
// in different releases, so one broad "old Kiro" check would still crash some
|
|
16
20
|
// supported versions with an unknown argument. Every row below was read from
|
|
@@ -26,18 +30,98 @@ export const KIRO_LEGACY_UI_MIN = "1.27.0";
|
|
|
26
30
|
export const KIRO_EFFORT_FLAG_MIN = "2.6.0";
|
|
27
31
|
/** Oldest kiro-cli AgEnD claims: older ones still launch, with a warning. */
|
|
28
32
|
export const KIRO_SUPPORTED_MIN = "2.21.0";
|
|
33
|
+
/**
|
|
34
|
+
* Lowest version whose `--agent` and `--resume-id` the per-instance agent and conversation (#906) were verified on
|
|
35
|
+
* (2.21.0 and 2.28.0, docs/design/kiro-per-instance-agent.md). Below it an instance launches as before.
|
|
36
|
+
*/
|
|
37
|
+
export const KIRO_INSTANCE_AGENT_MIN = "2.21.0";
|
|
29
38
|
/**
|
|
30
39
|
* Newest kiro-cli run live under AgEnD. Above it the launch flags come from
|
|
31
40
|
* the binary's own --help instead of the version table, and the operator is
|
|
32
41
|
* told the version is unverified.
|
|
33
42
|
*/
|
|
34
43
|
export const KIRO_TESTED_MAX = "2.27.0";
|
|
44
|
+
/**
|
|
45
|
+
* kiro-cli versions, per TUI front-end, whose mid-turn steering AgEnD drives (#1405). Only kiro's TUI steers — typed
|
|
46
|
+
* input while a turn runs is injected into it ("steer", the default) or held for its end ("queue", Ctrl+S toggles); the
|
|
47
|
+
* legacy UI swallows it. A version/front-end is listed once a live run of it — a real account, a steer and a
|
|
48
|
+
* queued message mid-tool — has been captured (tests/fixtures/kiro-steer-1405, 2026-10-08: 2.27.1 `--tui
|
|
49
|
+
* --agent-engine=v2` and `--v3`, 2.28.0 `--tui --agent-engine=v2`; identical rows on all three). Any other version,
|
|
50
|
+
* 2.28.0's v3, the legacy UI and an undetected version all deliver a steer as an ordinary message after the turn.
|
|
51
|
+
*/
|
|
52
|
+
export const KIRO_STEER_VERIFIED = {
|
|
53
|
+
"2.27.1": ["tui", "v3"],
|
|
54
|
+
"2.28.0": ["tui"],
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* The TUI composer's interrupt mode, read off its own row: the LAST row starting at column 0 with `›` (transcript user
|
|
58
|
+
* rows are indented), below which only blank rows or right-aligned hints (`/copy to clipboard`) may follow. Its text is
|
|
59
|
+
* the empty composer's placeholder (tui.js, identical in 2.21.0, 2.27.1 and 2.28.0; 2.21.0 shows no elapsed time):
|
|
60
|
+
*
|
|
61
|
+
* `› Kiro is working · 12s · Type to steer · Ctrl+S to queue` → "steer"
|
|
62
|
+
* `› Kiro is working · 12s · Type to queue · Ctrl+S to steer` → "queue" (also `· Type to queue` alone: a spec task run)
|
|
63
|
+
* `› ask a question or describe a task ↵` → "idle" (exactly; also plan mode's and tangent's
|
|
64
|
+
* complete forms — never a prefix of typed text)
|
|
65
|
+
*
|
|
66
|
+
* Any other text on the composer's row is typed text: "text" — positive evidence the box holds something. The goal,
|
|
67
|
+
* editing, initializing, spec-description and shell placeholders are other modes, and the ASCII glyph set (`.`/`enter`,
|
|
68
|
+
* never seen on a real pane of ours) is not read: null, like a screen with no composer row (a dialog) — null is never
|
|
69
|
+
* evidence of either an empty or a full box. The toggle key's label is whatever the user bound; it is read past, never
|
|
70
|
+
* pressed.
|
|
71
|
+
*/
|
|
72
|
+
function readKiroComposer(pane) {
|
|
73
|
+
const rows = pane.split("\n").map(row => row.replace(/\s+$/, ""));
|
|
74
|
+
let i = rows.length - 1;
|
|
75
|
+
while (i >= 0 && (rows[i] === "" || /^[ \t]{20,}\S/.test(rows[i])))
|
|
76
|
+
i--;
|
|
77
|
+
// Typed text of more than one line continues below the `›` row, each row indented two spaces (live, 2.27.1 and
|
|
78
|
+
// 2.28.0, TUI v2 and v3): the composer starts at the `›` row above them.
|
|
79
|
+
let continued = 0;
|
|
80
|
+
while (i >= 0 && /^ {2,19}\S/.test(rows[i])) {
|
|
81
|
+
i--;
|
|
82
|
+
continued++;
|
|
83
|
+
}
|
|
84
|
+
const row = rows[i];
|
|
85
|
+
if (row === undefined || !/^›[ \t]+\S/.test(row))
|
|
86
|
+
return null;
|
|
87
|
+
// A placeholder is one row: with continuation rows below it, this is typed text — unless its first row is another
|
|
88
|
+
// mode's placeholder, which is then not ours to read.
|
|
89
|
+
if (continued > 0) {
|
|
90
|
+
if (/^›[ \t]+(?:Kiro is working\b|ask a question or describe a task\b|Goal (?:Active|Paused):|Editing queued message \d|Initializing\b|describe what "|running shell command\b)/.test(row))
|
|
91
|
+
return null;
|
|
92
|
+
return { mode: "text", text: row.replace(/^›[ \t]+/, "") };
|
|
93
|
+
}
|
|
94
|
+
const working = String.raw `^›[ \t]+Kiro is working(?:[ \t]+·[ \t]+[^·]+?)?[ \t]+·[ \t]+`;
|
|
95
|
+
const text = row.replace(/^›[ \t]+/, "");
|
|
96
|
+
if (new RegExp(`${working}Type to steer[ \\t]+·[ \\t]+[^·]+?[ \\t]+to queue$`).test(row))
|
|
97
|
+
return { mode: "steer", text };
|
|
98
|
+
if (new RegExp(`${working}Type to queue(?:[ \\t]+·[ \\t]+[^·]+?[ \\t]+to steer)?$`).test(row))
|
|
99
|
+
return { mode: "queue", text };
|
|
100
|
+
const idle = String.raw `^›[ \t]+ask a question or describe a task`;
|
|
101
|
+
if (new RegExp(`${idle}[ \\t]+↵$`).test(row)
|
|
102
|
+
|| new RegExp(`${idle}[ \\t]+↵[ \\t]+·[ \\t]+exit plan mode: shift\\+tab$`).test(row)
|
|
103
|
+
|| new RegExp(`${idle}[ \\t]+·[ \\t]+/tangent to go back[ \\t]+·[ \\t]+/tangent ls to view$`).test(row))
|
|
104
|
+
return { mode: "idle", text };
|
|
105
|
+
// Other placeholders (and anything the ASCII glyph set paints) are not typed text.
|
|
106
|
+
if (/^›[ \t]+(?:Kiro is working\b|Goal (?:Active|Paused):|Editing queued message \d|Initializing\b|describe what "|running shell command\b|ask a question or describe a task (?:\.|enter\b))/.test(row))
|
|
107
|
+
return null;
|
|
108
|
+
return { mode: "text", text };
|
|
109
|
+
}
|
|
110
|
+
export function readKiroSteerComposer(pane) {
|
|
111
|
+
return readKiroComposer(pane)?.mode ?? null;
|
|
112
|
+
}
|
|
113
|
+
/** The typed text on the composer's row when it reads "text" (its first row, as kiro paints it); else null. */
|
|
114
|
+
export function readKiroComposerText(pane) {
|
|
115
|
+
const c = readKiroComposer(pane);
|
|
116
|
+
return c?.mode === "text" ? c.text : null;
|
|
117
|
+
}
|
|
35
118
|
const UNKNOWN_KIRO_COMPATIBILITY = {
|
|
36
119
|
supportsLegacyUi: false,
|
|
37
120
|
supportsTui: false,
|
|
38
121
|
supportsV3: false,
|
|
39
122
|
agentEngines: null,
|
|
40
123
|
supportsEffortFlag: false,
|
|
124
|
+
supportsInstanceAgent: false,
|
|
41
125
|
source: "unknown",
|
|
42
126
|
};
|
|
43
127
|
const compatibilityCache = new Map();
|
|
@@ -65,26 +149,87 @@ function kiroModelPickerAtTail(pane) {
|
|
|
65
149
|
return false;
|
|
66
150
|
return tail.some(line => /^\s*[>❯›]\s*\*?\s*\S/.test(line));
|
|
67
151
|
}
|
|
68
|
-
|
|
69
|
-
|
|
152
|
+
const KIRO_TRUST_HEADER = "Warning: Kiro is running in trust all tools mode";
|
|
153
|
+
const KIRO_TRUST_PATTERN = /^\s*(?:Warning: Kiro is running in trust all tools mode|Do you trust the files\?)\s*$/m;
|
|
154
|
+
const KIRO_TRUST_OPTIONS = ["No, exit", "Yes, I accept", "Yes, and don't ask again"];
|
|
155
|
+
/**
|
|
156
|
+
* #849A: only the captured 2.27.1 TUI trust-all-tools layout can receive a
|
|
157
|
+
* key. Unknown layouts remain held. A live composer or model picker below
|
|
158
|
+
* the header makes it history, not a consent request. The old synthetic
|
|
159
|
+
* workspace-trust shape is observable but never auto-accepted.
|
|
160
|
+
*/
|
|
161
|
+
export function kiroTrustPromptState(pane) {
|
|
162
|
+
const none = { active: false, cursor: null };
|
|
70
163
|
if (kiroModelPickerAtTail(pane))
|
|
71
|
-
return
|
|
72
|
-
const
|
|
73
|
-
let
|
|
74
|
-
for (let index =
|
|
75
|
-
if (
|
|
76
|
-
|
|
164
|
+
return none;
|
|
165
|
+
const rows = pane.replace(/\r/g, "").split("\n").map(row => row.trimEnd());
|
|
166
|
+
let header = -1;
|
|
167
|
+
for (let index = rows.length - 1; index >= 0; index--) {
|
|
168
|
+
if (KIRO_TRUST_PATTERN.test(rows[index])) {
|
|
169
|
+
header = index;
|
|
77
170
|
break;
|
|
78
171
|
}
|
|
79
172
|
}
|
|
80
|
-
if (
|
|
81
|
-
return
|
|
82
|
-
const
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
173
|
+
if (header < 0)
|
|
174
|
+
return none;
|
|
175
|
+
const body = rows.slice(header + 1);
|
|
176
|
+
if (body.some(row => KIRO_COMPOSER_ROW.test(row)))
|
|
177
|
+
return none;
|
|
178
|
+
const choice = (row, label) => {
|
|
179
|
+
if (row.trim() === label)
|
|
180
|
+
return { glyph: null };
|
|
181
|
+
const hit = /^\s*(\S)\s+(.+)$/.exec(row);
|
|
182
|
+
return hit?.[2] === label ? { glyph: hit[1] } : null;
|
|
183
|
+
};
|
|
184
|
+
const held = { active: true, cursor: null };
|
|
185
|
+
if (rows[header].trim() !== KIRO_TRUST_HEADER) {
|
|
186
|
+
// A question alone is not permission evidence. A structurally selected
|
|
187
|
+
// two-choice workspace prompt is held for a human, not navigated.
|
|
188
|
+
return body.some(row => choice(row, KIRO_TRUST_OPTIONS[0]))
|
|
189
|
+
&& body.some(row => choice(row, KIRO_TRUST_OPTIONS[1])) ? held : none;
|
|
190
|
+
}
|
|
191
|
+
const first = body.findIndex(row => choice(row, KIRO_TRUST_OPTIONS[0]) !== null);
|
|
192
|
+
if (first < 0)
|
|
193
|
+
return held;
|
|
194
|
+
if (body.slice(0, first).some(row => KIRO_TRUST_OPTIONS.some(label => choice(row, label))))
|
|
195
|
+
return held;
|
|
196
|
+
const options = body.slice(first).filter(row => row.trim());
|
|
197
|
+
// Exact labels/order, divider and key-hint tail from the native fixture.
|
|
198
|
+
// No inferred two-option layout, added option, or arbitrary output suffix.
|
|
199
|
+
if (options.length !== 5 || !/^─{3,}$/.test(options[3].trim())
|
|
200
|
+
|| !/^esc to cancel\s*·\s*↑↓ to navigate\s*·\s*↵ to select$/.test(options[4].trim()))
|
|
201
|
+
return held;
|
|
202
|
+
const hits = KIRO_TRUST_OPTIONS.map((label, index) => choice(options[index], label));
|
|
203
|
+
if (hits.some(hit => !hit))
|
|
204
|
+
return held;
|
|
205
|
+
const marked = hits.flatMap((hit, index) => hit.glyph === null ? [] : [index]);
|
|
206
|
+
if (marked.length !== 1 || !KIRO_PROMPT_CURSOR.test(hits[marked[0]].glyph))
|
|
207
|
+
return held;
|
|
208
|
+
return { active: true, cursor: marked[0] };
|
|
209
|
+
}
|
|
210
|
+
function kiroTrustPromptDialogs(trustAll) {
|
|
211
|
+
const guarded = { pattern: KIRO_TRUST_PATTERN, blocksDelivery: true, inputBlocked: true, verifyAfterKeys: true, oncePerLaunch: true };
|
|
212
|
+
const at = (pane, cursor) => {
|
|
213
|
+
const state = kiroTrustPromptState(pane);
|
|
214
|
+
return trustAll && state.active && state.cursor === cursor;
|
|
215
|
+
};
|
|
216
|
+
return [
|
|
217
|
+
{
|
|
218
|
+
...guarded, keys: ["Down"], autoResolutionKey: "kiro-trust-all-tools-step",
|
|
219
|
+
description: "Kiro trust confirmation — one step off 'No, exit'",
|
|
220
|
+
isActive: pane => at(pane, 0),
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
...guarded, keys: ["Enter"], autoResolutionKey: "kiro-trust-all-tools-confirm",
|
|
224
|
+
description: "Kiro trust confirmation — confirm per-session 'Yes, I accept'",
|
|
225
|
+
isActive: pane => at(pane, 1),
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
pattern: KIRO_TRUST_PATTERN, keys: [], holdOnly: true, blocksDelivery: true, inputBlocked: true,
|
|
229
|
+
description: "Kiro trust confirmation — unsafe or unverified choice; holding for a human",
|
|
230
|
+
isActive: pane => kiroTrustPromptState(pane).active,
|
|
231
|
+
},
|
|
232
|
+
];
|
|
88
233
|
}
|
|
89
234
|
/**
|
|
90
235
|
* Kiro's service-unavailable path opens the same picker as `/model`, but only
|
|
@@ -207,8 +352,8 @@ export function kiroLaunchPromptState(pane, spec) {
|
|
|
207
352
|
return { active: true, cursor: null };
|
|
208
353
|
return { active: true, cursor: marked[0] };
|
|
209
354
|
}
|
|
210
|
-
/**
|
|
211
|
-
const KIRO_COMPOSER_ROW = /^\s*(?:\[[^\]]*\]\s*)?\d+%\s*\S{0,2}\s*!?\s*[❯>]|^\s*[!❯>]\s
|
|
355
|
+
/** Kiro's legacy input row, or the archived TUI's column-zero `›` composer (including typed text). */
|
|
356
|
+
const KIRO_COMPOSER_ROW = /^\s*(?:\[[^\]]*\]\s*)?\d+%\s*\S{0,2}\s*!?\s*[❯>]|^\s*[!❯>]\s*$|^›(?:[ \t]|$)/;
|
|
212
357
|
/**
|
|
213
358
|
* Launch prompts that would move an instance off its engine (#1109). Text
|
|
214
359
|
* from the kiro-cli 2.27.0 binary (crates/chat-cli/src/launch/v3_ease_in.rs,
|
|
@@ -346,6 +491,7 @@ function compatibilityFromVersion(version, parsed) {
|
|
|
346
491
|
: has("2.3.0") ? ["rust", "kas"]
|
|
347
492
|
: null,
|
|
348
493
|
supportsEffortFlag: has(KIRO_EFFORT_FLAG_MIN),
|
|
494
|
+
supportsInstanceAgent: has(KIRO_INSTANCE_AGENT_MIN),
|
|
349
495
|
source: "version",
|
|
350
496
|
};
|
|
351
497
|
}
|
|
@@ -359,6 +505,10 @@ function compatibilityFromHelp(version, help) {
|
|
|
359
505
|
supportsV3: helpAdvertisesFlag(help, "--v3"),
|
|
360
506
|
agentEngines: parseKiroAgentEngines(help),
|
|
361
507
|
supportsEffortFlag: helpAdvertisesFlag(help, "--effort"),
|
|
508
|
+
// The flags are listed long before 2.21, but the behaviour #906 relies on was verified from 2.21 on: an unknown or
|
|
509
|
+
// older version keeps today's command.
|
|
510
|
+
supportsInstanceAgent: helpAdvertisesFlag(help, "--agent") && helpAdvertisesFlag(help, "--resume-id")
|
|
511
|
+
&& (() => { const v = parseSemver(version); return !!v && versionAtLeast(v, KIRO_INSTANCE_AGENT_MIN); })(),
|
|
362
512
|
source: "help",
|
|
363
513
|
};
|
|
364
514
|
}
|
|
@@ -401,14 +551,78 @@ function nextPatch(version) {
|
|
|
401
551
|
const [major, minor, patch] = parseSemver(version);
|
|
402
552
|
return `${major}.${minor}.${patch + 1}`;
|
|
403
553
|
}
|
|
554
|
+
/** Binary generations already told they cannot isolate (once each). */
|
|
555
|
+
const warnedNoInstanceAgentKeys = new Set();
|
|
556
|
+
/** Instances already told about an untagged steering file (once each). */
|
|
557
|
+
const warnedUntaggedSteering = new Set();
|
|
558
|
+
/** The classic (v1) conversation store an instance launches with: its credential profile's, else the shared one. */
|
|
559
|
+
export function kiroV1DbPath(credentialProfile) {
|
|
560
|
+
const home = credentialProfile
|
|
561
|
+
? credentialProfileStoreHome(getAgendHome(), "kiro-cli", credentialProfile)
|
|
562
|
+
: join(process.env.XDG_DATA_HOME || join(homedir(), ".local", "share"), "kiro-cli");
|
|
563
|
+
return join(home, "data.sqlite3");
|
|
564
|
+
}
|
|
565
|
+
/** The TUI (v2) session files: `<KIRO_HOME or ~/.kiro>/sessions/cli` — not per credential profile. */
|
|
566
|
+
export function kiroV2SessionsDir() {
|
|
567
|
+
return join(process.env.KIRO_HOME?.trim() || join(homedir(), ".kiro"), "sessions", "cli");
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* Adoption evidence (#906 §2): the engine ledger shows this instance launched here — same directory, credential
|
|
571
|
+
* profile and engine — before #906 (no "--agent" in that launch). A new instance has no such record and starts fresh
|
|
572
|
+
* instead of taking a sibling's conversation.
|
|
573
|
+
*/
|
|
574
|
+
export function kiroLaunchedHereBefore(instance, workingDirectory, credentialProfile, engine, ledgerPath) {
|
|
575
|
+
const entry = readKiroLedger(ledgerPath)[instance];
|
|
576
|
+
if (!entry || resolve(entry.workingDirectory) !== resolve(workingDirectory) || entry.credentialProfile !== credentialProfile)
|
|
577
|
+
return false;
|
|
578
|
+
return entry.lastLaunch.ui === (engine === "v1" ? "legacy" : "tui") && !entry.lastLaunch.flags.includes("--agent");
|
|
579
|
+
}
|
|
580
|
+
/** The legacy UI's prompt row: an optional `[agent]`, the context percentage, an optional mode glyph, the marker. */
|
|
581
|
+
const LEGACY_PROMPT_ROW = /^\s*(?:\[([^\]]+)\]\s*)?\d+%\s*(?:[^\s\d%!❯>]{1,2}\s+)?(?:!\s?[❯>]|❯|>)/;
|
|
582
|
+
/** A TUI status row: `<agent> · <model> · …`. */
|
|
583
|
+
const TUI_STATUS_ROW = /^\s*(\S+) · /;
|
|
584
|
+
const RULE_ROW = /^[\s─━│┃╭╮╰╯┌┐└┘]*$/;
|
|
585
|
+
/** The right-aligned hint under the TUI input row: far right, a slash command or two. */
|
|
586
|
+
const TUI_HINT_ROW = /^\s{20,}\/[\w-]+(?: [\w-]+)*(?: · \/[\w-]+(?: [\w-]+)*)*$/;
|
|
404
587
|
/**
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
*
|
|
410
|
-
* the instance's own engine is refused, never run on whatever kiro defaults to.
|
|
588
|
+
* The agent the live layout shows (#906 §3) — never a name quoted in the conversation above it:
|
|
589
|
+
* - legacy: the pane's last non-empty row, only when it is the prompt row; `[name]` on it, or the default agent;
|
|
590
|
+
* - TUI / v3: the status row directly above the input row (the last `›` row; earlier `›` rows are the user's past
|
|
591
|
+
* messages, which sit above it), skipping rule rows.
|
|
592
|
+
* Null when the layout cannot be read.
|
|
411
593
|
*/
|
|
594
|
+
export function readActiveKiroAgent(pane, ui) {
|
|
595
|
+
const rows = pane.split("\n").map(r => r.replace(/\s+$/, ""));
|
|
596
|
+
if (ui === "legacy") {
|
|
597
|
+
const last = [...rows].reverse().find(r => r.trim() !== "");
|
|
598
|
+
const m = last ? LEGACY_PROMPT_ROW.exec(last) : null;
|
|
599
|
+
return m ? (m[1] ?? "kiro_default") : null;
|
|
600
|
+
}
|
|
601
|
+
let input = -1;
|
|
602
|
+
for (let i = rows.length - 1; i >= 0; i--)
|
|
603
|
+
if (/^\s*›/.test(rows[i])) {
|
|
604
|
+
input = i;
|
|
605
|
+
break;
|
|
606
|
+
}
|
|
607
|
+
if (input < 0)
|
|
608
|
+
return null;
|
|
609
|
+
// The live bottom layout ends with the input row: below it only blank or rule rows and the right-aligned hint
|
|
610
|
+
// (`/copy to clipboard`, `/sessions to resume · …`). Anything else — a modal, a panel, output — means the pair
|
|
611
|
+
// above it is not the live one (#1416 review).
|
|
612
|
+
for (let i = input + 1; i < rows.length; i++) {
|
|
613
|
+
const row = rows[i];
|
|
614
|
+
if (row.trim() === "" || RULE_ROW.test(row) || TUI_HINT_ROW.test(row))
|
|
615
|
+
continue;
|
|
616
|
+
return null;
|
|
617
|
+
}
|
|
618
|
+
for (let i = input - 1; i >= 0; i--) {
|
|
619
|
+
if (RULE_ROW.test(rows[i]))
|
|
620
|
+
continue;
|
|
621
|
+
const m = TUI_STATUS_ROW.exec(rows[i]);
|
|
622
|
+
return m ? m[1] : null;
|
|
623
|
+
}
|
|
624
|
+
return null;
|
|
625
|
+
}
|
|
412
626
|
export function planKiroLaunch(ui, compat) {
|
|
413
627
|
const version = compat.version ?? "of unknown version";
|
|
414
628
|
if (ui === "v3")
|
|
@@ -539,6 +753,46 @@ export class KiroBackend {
|
|
|
539
753
|
activeTrustAll = true;
|
|
540
754
|
/** Version-gate notice for the launch just built (consumeLaunchWarning). */
|
|
541
755
|
launchWarning = null;
|
|
756
|
+
/**
|
|
757
|
+
* What this launch attempt resumes and as which agent (#906), resolved once per attempt in writeConfig — it claims
|
|
758
|
+
* conversations and records fresh starts — and read by the buildCommand that follows it.
|
|
759
|
+
*/
|
|
760
|
+
launchPlan = null;
|
|
761
|
+
/** The plan of the command last built: what agentSwitch() works from. */
|
|
762
|
+
activePlan = null;
|
|
763
|
+
preparedV2Store = null;
|
|
764
|
+
storePreparation = 0;
|
|
765
|
+
storeKey(config) {
|
|
766
|
+
return JSON.stringify([config.instanceName, config.workingDirectory, kiroCanonicalDirectory(config.workingDirectory), config.kiroUi,
|
|
767
|
+
resolveCredentialProfile(config.backendOptions), !!config.skipResume, getAgendHome(), kiroV2SessionsDir(), kiroCanonicalDirectory(kiroV2SessionsDir())]);
|
|
768
|
+
}
|
|
769
|
+
readPreparedV2Store(config) {
|
|
770
|
+
if (this.preparedV2Store?.key !== this.storeKey(config)) {
|
|
771
|
+
throw new KiroIdentityError("v2 session discovery was not prepared for this launch");
|
|
772
|
+
}
|
|
773
|
+
return this.preparedV2Store.store;
|
|
774
|
+
}
|
|
775
|
+
/** Metadata only: identity claims/config writes remain synchronous, after
|
|
776
|
+
* the daemon rechecks its launch admission following this await. */
|
|
777
|
+
async prepareLaunch(config) {
|
|
778
|
+
const preparation = ++this.storePreparation;
|
|
779
|
+
this.preparedV2Store = null;
|
|
780
|
+
if (!config || config.kiroUi !== "tui")
|
|
781
|
+
return;
|
|
782
|
+
if (!this.fixedCompatibility)
|
|
783
|
+
this.compatibility = cachedKiroCliCompatibility(this.binaryPath).compatibility;
|
|
784
|
+
const key = this.storeKey(config);
|
|
785
|
+
const plan = planKiroLaunch("tui", this.compatibility);
|
|
786
|
+
if (plan.kind !== "launch" || !plan.flags.includes("--agent-engine=v2") || !this.compatibility.supportsInstanceAgent)
|
|
787
|
+
return;
|
|
788
|
+
const opts = { instance: config.instanceName, engine: "v2", workingDirectory: config.workingDirectory,
|
|
789
|
+
credentialProfile: resolveCredentialProfile(config.backendOptions), skipResume: config.skipResume, agendHome: getAgendHome() };
|
|
790
|
+
if (kiroIdentityNeedsStore(opts)) {
|
|
791
|
+
const store = await listKiroV2Sessions(config.workingDirectory, kiroV2SessionsDir());
|
|
792
|
+
if (preparation === this.storePreparation && key === this.storeKey(config))
|
|
793
|
+
this.preparedV2Store = { key, store };
|
|
794
|
+
}
|
|
795
|
+
}
|
|
542
796
|
constructor(instanceDir, compatibility) {
|
|
543
797
|
this.instanceDir = instanceDir;
|
|
544
798
|
this.binaryPath = resolveBinary("kiro-cli");
|
|
@@ -577,6 +831,22 @@ export class KiroBackend {
|
|
|
577
831
|
// their ready marker is verified.
|
|
578
832
|
return this.activeUi === "legacy" && this.activeTrustAll;
|
|
579
833
|
}
|
|
834
|
+
/** #1405: the TUI front-end this instance was launched with, on a version listed in KIRO_STEER_VERIFIED. */
|
|
835
|
+
supportsSteer() {
|
|
836
|
+
if (this.activeUi === "legacy")
|
|
837
|
+
return false;
|
|
838
|
+
// compatibility.version is kiro-cli's own `--version` line ("kiro-cli 2.27.1").
|
|
839
|
+
const version = parseSemver(this.compatibility.version)?.join(".");
|
|
840
|
+
return version !== undefined && Object.hasOwn(KIRO_STEER_VERIFIED, version)
|
|
841
|
+
&& KIRO_STEER_VERIFIED[version].includes(this.activeUi);
|
|
842
|
+
}
|
|
843
|
+
/** #1405: the TUI composer's mode; never read on the legacy UI, whose prompt row has no such mode. */
|
|
844
|
+
readSteerComposer(pane) {
|
|
845
|
+
return this.activeUi === "legacy" ? null : readKiroSteerComposer(pane);
|
|
846
|
+
}
|
|
847
|
+
readSteerComposerText(pane) {
|
|
848
|
+
return this.activeUi === "legacy" ? null : readKiroComposerText(pane);
|
|
849
|
+
}
|
|
580
850
|
/**
|
|
581
851
|
* Live evidence (kiro-cli 2.21.0, 2026-09-03): `--resume` prints nothing
|
|
582
852
|
* until the conversation comes back from the backend ("Picking up where we
|
|
@@ -647,13 +917,21 @@ export class KiroBackend {
|
|
|
647
917
|
cmd += ` ${flag}`;
|
|
648
918
|
this.noteVersionGate();
|
|
649
919
|
const credentialProfile = resolveCredentialProfile(config.backendOptions);
|
|
920
|
+
// #906: the plan writeConfig resolved for this attempt (a direct buildCommand, as in tests, resolves its own).
|
|
921
|
+
const lp = this.launchPlan && this.launchPlan.cwd === config.workingDirectory && this.launchPlan.skipResume === !!config.skipResume
|
|
922
|
+
? this.launchPlan : this.planInstanceLaunch(config);
|
|
923
|
+
this.launchPlan = null;
|
|
924
|
+
this.activePlan = lp;
|
|
925
|
+
this.activeSpec = lp.mode === "legacy" ? null : this.agentSpec(config);
|
|
926
|
+
this.activeInstance = config.instanceName;
|
|
650
927
|
recordKiroLaunch({
|
|
651
928
|
instance: config.instanceName,
|
|
652
929
|
workingDirectory: config.workingDirectory,
|
|
653
930
|
credentialProfile,
|
|
654
931
|
kiroVersion: this.compatibility.version ?? null,
|
|
655
932
|
ui,
|
|
656
|
-
|
|
933
|
+
// "--agent" marks a launch made after #906: such an instance is never adopted again (kiroLaunchedHereBefore).
|
|
934
|
+
flags: lp.mode !== "legacy" ? [...plan.flags, "--agent"] : plan.flags,
|
|
657
935
|
});
|
|
658
936
|
// Record what is actually being launched for the delivery gate (see
|
|
659
937
|
// dropsEnterWhileBusy): the legacy prompt row exists only under
|
|
@@ -662,30 +940,24 @@ export class KiroBackend {
|
|
|
662
940
|
this.activeTrustAll = config.skipPermissions !== false;
|
|
663
941
|
if (config.skipPermissions !== false)
|
|
664
942
|
cmd += " --trust-all-tools";
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
// launch. Switching profiles also skips resume outright (crash-state
|
|
676
|
-
// resumeDisabled), so this never fires against a store that just changed.
|
|
677
|
-
//
|
|
678
|
-
// V3 is the exception, and resumes only the session it owns, by id: its
|
|
679
|
-
// `--resume` takes the newest conversation in the directory from ANY
|
|
680
|
-
// engine and converts a classic one into a new V3 copy — on every launch.
|
|
681
|
-
// A skipped resume is recorded there too, so the session given up is not
|
|
682
|
-
// taken back on the next launch. See kiro-v3-identity.ts.
|
|
683
|
-
if (ui === "v3") {
|
|
943
|
+
if (lp.mode !== "legacy") {
|
|
944
|
+
// Its own agent: on a fresh start it takes effect at once; on a resume kiro brings back the conversation's saved
|
|
945
|
+
// agent instead (E6), and the daemon switches it on screen (agentSwitch).
|
|
946
|
+
cmd += ` --agent ${shellQuote(lp.agent)}`;
|
|
947
|
+
if (lp.mode === "resume")
|
|
948
|
+
cmd += ` --resume-id ${shellQuote(lp.id)}`;
|
|
949
|
+
}
|
|
950
|
+
else if (ui === "v3") {
|
|
951
|
+
// Legacy mode, V3: it resumes only the session it owns, by id (kiro-v3-identity.ts) — its `--resume` would take
|
|
952
|
+
// the newest conversation in the directory from ANY engine and convert a classic one into a new V3 copy.
|
|
684
953
|
const id = resolveKiroV3Resume(config.instanceName, config.workingDirectory, credentialProfile, { skipResume: config.skipResume });
|
|
685
954
|
if (id)
|
|
686
955
|
cmd += ` --resume-id ${shellQuote(id)}`;
|
|
687
956
|
}
|
|
688
957
|
else if (!config.skipResume) {
|
|
958
|
+
// Legacy mode, classic/TUI: the boolean form — kiro resumes the directory's newest conversation. Not isolated
|
|
959
|
+
// between instances sharing the directory (#1410); an instance launches like this only without the
|
|
960
|
+
// per-instance plan (an old kiro-cli, or a conversation store AgEnD could not read on adoption).
|
|
689
961
|
cmd += " --resume";
|
|
690
962
|
}
|
|
691
963
|
if (config.model) {
|
|
@@ -756,7 +1028,8 @@ export class KiroBackend {
|
|
|
756
1028
|
if (!warning)
|
|
757
1029
|
return;
|
|
758
1030
|
warnedVersionGateCacheKeys.add(key);
|
|
759
|
-
this.
|
|
1031
|
+
// Appended: the launch's isolation warnings (#906, recorded by writeConfig) must not be overwritten by this one.
|
|
1032
|
+
this.addLaunchWarning(warning);
|
|
760
1033
|
}
|
|
761
1034
|
consumeLaunchWarning() {
|
|
762
1035
|
const warning = this.launchWarning;
|
|
@@ -776,36 +1049,11 @@ export class KiroBackend {
|
|
|
776
1049
|
return true;
|
|
777
1050
|
}
|
|
778
1051
|
writeConfig(config) {
|
|
779
|
-
//
|
|
780
|
-
//
|
|
781
|
-
//
|
|
782
|
-
// WORKAROUND: kiro-cli ignores the "env" block in mcp.json — the MCP server
|
|
783
|
-
// subprocess inherits the fleet manager's process env, which has a stale
|
|
784
|
-
// AGEND_SOCKET_PATH from whichever daemon wrote to it last.
|
|
785
|
-
// Fix: generate a wrapper script that exports the correct env vars before
|
|
786
|
-
// exec-ing the real MCP server.
|
|
787
|
-
const mcpDir = join(config.workingDirectory, ".kiro", "settings");
|
|
788
|
-
mkdirSync(mcpDir, { recursive: true });
|
|
789
|
-
const mcpConfigPath = join(mcpDir, "mcp.json");
|
|
790
|
-
let mcpConfig = {};
|
|
791
|
-
try {
|
|
792
|
-
mcpConfig = JSON.parse(readFileSync(mcpConfigPath, "utf-8"));
|
|
793
|
-
}
|
|
794
|
-
catch { /* new file */ }
|
|
795
|
-
const servers = (mcpConfig.mcpServers ?? {});
|
|
796
|
-
// Remove stale agend entries whose wrapper scripts no longer exist
|
|
797
|
-
for (const [key, val] of Object.entries(servers)) {
|
|
798
|
-
if (key.startsWith("agend-")) {
|
|
799
|
-
const cmd = val?.command;
|
|
800
|
-
if (typeof cmd === "string" && !existsSync(cmd)) {
|
|
801
|
-
delete servers[key];
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
}
|
|
1052
|
+
// WORKAROUND: kiro-cli ignores the "env" block of an MCP server entry — the server subprocess inherits the fleet
|
|
1053
|
+
// manager's env, with a stale AGEND_SOCKET_PATH from whichever daemon wrote last. Each server therefore runs
|
|
1054
|
+
// through a wrapper script that exports this instance's env and execs the real server.
|
|
805
1055
|
for (const [name, entry] of Object.entries(config.mcpServers)) {
|
|
806
|
-
const instanceKey = `${name}-${config.instanceName}`;
|
|
807
1056
|
const allEnv = { ...entry.env, AGEND_INSTANCE_NAME: config.instanceName };
|
|
808
|
-
// Write a wrapper script that sets env vars explicitly
|
|
809
1057
|
const wrapperPath = join(this.instanceDir, `mcp-wrapper-${name}.sh`);
|
|
810
1058
|
const envExports = Object.entries(allEnv)
|
|
811
1059
|
.map(([k, v]) => `export ${k}='${String(v).replace(/'/g, "'\\''")}'`)
|
|
@@ -813,29 +1061,170 @@ export class KiroBackend {
|
|
|
813
1061
|
// 0o700 (owner-only rwx): wrapper inlines sensitive env (tokens, socket paths).
|
|
814
1062
|
// Other users on the host must not be able to read it. Set mode at creation
|
|
815
1063
|
// to avoid a world-readable window between writeFileSync and chmodSync.
|
|
816
|
-
writeFileSync(wrapperPath, `#!/bin/bash\n${envExports}\n# Wait for IPC socket to be ready (up to 10s)\nfor i in $(seq 1 20); do [ -S "$AGEND_SOCKET_PATH" ] && break; sleep 0.5; done\nexec ${entry.command
|
|
1064
|
+
writeFileSync(wrapperPath, `#!/bin/bash\n${envExports}\n# Wait for IPC socket to be ready (up to 10s)\nfor i in $(seq 1 20); do [ -S "$AGEND_SOCKET_PATH" ] && break; sleep 0.5; done\nexec ${[entry.command, ...entry.args].map(shellQuote).join(" ")}\n`, { mode: 0o700 });
|
|
817
1065
|
// Re-chmod in case the file already existed with looser permissions (writeFileSync's
|
|
818
1066
|
// mode only applies on create).
|
|
819
1067
|
chmodSync(wrapperPath, 0o700);
|
|
820
|
-
servers[instanceKey] = {
|
|
821
|
-
command: wrapperPath,
|
|
822
|
-
args: [],
|
|
823
|
-
};
|
|
824
1068
|
}
|
|
825
|
-
//
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
1069
|
+
// #906: which conversation this attempt resumes, and as which agent — resolved once, here.
|
|
1070
|
+
const plan = this.planInstanceLaunch(config);
|
|
1071
|
+
this.preparedV2Store = null;
|
|
1072
|
+
this.launchPlan = plan;
|
|
1073
|
+
const spec = this.agentSpec(config);
|
|
1074
|
+
const root = dirname(this.instanceDir);
|
|
1075
|
+
if (plan.mode === "legacy") {
|
|
1076
|
+
// Not isolated (an old kiro-cli, or adoption with an unreadable store): the shared files as before, each
|
|
1077
|
+
// written only where it is free, and removed only by provenance.
|
|
1078
|
+
if (plan.reason)
|
|
1079
|
+
this.addLaunchWarning(plan.reason);
|
|
1080
|
+
this.noteShared("mcp.json", writeSharedKiroMcpEntries(spec));
|
|
1081
|
+
if (config.instructions)
|
|
1082
|
+
this.noteShared("steering", writeTaggedKiroSteering(spec, config.instructions));
|
|
1083
|
+
this.noteShared("mcp.json", removeSharedKiroMcpEntries(spec, root, false));
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
// Throws when a file that is not this instance's agent is in the way: never overwritten, launch refused.
|
|
1087
|
+
writeKiroAgent(spec, config.instructions);
|
|
1088
|
+
if (plan.mode === "resume" && !plan.agentConfirmed) {
|
|
1089
|
+
// The resumed conversation comes back as its saved agent (`--agent` is ignored on resume), so until the switch
|
|
1090
|
+
// is confirmed on screen it gets its AgEnD server and instructions from the shared files (design §3).
|
|
1091
|
+
this.noteShared("mcp.json", writeSharedKiroMcpEntries(spec));
|
|
1092
|
+
if (config.instructions)
|
|
1093
|
+
this.noteShared("steering", writeTaggedKiroSteering(spec, config.instructions));
|
|
1094
|
+
this.noteShared("mcp.json", removeSharedKiroMcpEntries(spec, root, false));
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
// Running as its own agent: nothing of this instance belongs in the shared files any more.
|
|
1098
|
+
this.noteShared("mcp.json", removeSharedKiroMcpEntries(spec, root, true));
|
|
1099
|
+
this.noteShared("steering", removeTaggedKiroSteering(spec));
|
|
1100
|
+
}
|
|
1101
|
+
/** This instance's agent, by its fleet and its own wrapper scripts. */
|
|
1102
|
+
agentSpec(config) {
|
|
1103
|
+
return {
|
|
1104
|
+
workingDirectory: config.workingDirectory,
|
|
1105
|
+
instance: config.instanceName,
|
|
1106
|
+
fleet: kiroFleetTag(getAgendHome()),
|
|
1107
|
+
instanceDir: this.instanceDir,
|
|
1108
|
+
serverNames: Object.keys(config.mcpServers),
|
|
1109
|
+
};
|
|
1110
|
+
}
|
|
1111
|
+
/** A shared file AgEnD could not bring to the state isolation needs: said, never reported as isolated. */
|
|
1112
|
+
noteShared(file, outcome) {
|
|
1113
|
+
if (outcome === "conflict")
|
|
1114
|
+
this.addLaunchWarning(t("kiro.shared_conflict", file));
|
|
1115
|
+
else if (outcome === "unreadable" || outcome === "failed")
|
|
1116
|
+
this.addLaunchWarning(t("kiro.shared_unreadable", file));
|
|
1117
|
+
else if (outcome === "untagged-legacy" && !warnedUntaggedSteering.has(this.instanceDir)) {
|
|
1118
|
+
warnedUntaggedSteering.add(this.instanceDir);
|
|
1119
|
+
this.addLaunchWarning(t("kiro.untagged_steering"));
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
addLaunchWarning(message) {
|
|
1123
|
+
this.launchWarning = this.launchWarning ? `${this.launchWarning}\n${message}` : message;
|
|
1124
|
+
}
|
|
1125
|
+
/**
|
|
1126
|
+
* The launch plan of one attempt (#906, design §2/§5): the engine the plan pins, and — when this kiro-cli has
|
|
1127
|
+
* `--agent` and `--resume-id` — the conversation this instance owns and whether it already runs as its agent.
|
|
1128
|
+
* Anything else is legacy mode: today's command, not isolated.
|
|
1129
|
+
*/
|
|
1130
|
+
planInstanceLaunch(config) {
|
|
1131
|
+
const ui = config.kiroUi ?? "legacy";
|
|
1132
|
+
if (!this.fixedCompatibility) {
|
|
1133
|
+
const current = cachedKiroCliCompatibility(this.binaryPath);
|
|
1134
|
+
this.compatibility = current.compatibility;
|
|
1135
|
+
this.compatibilityCacheKey = current.cacheKey;
|
|
837
1136
|
}
|
|
1137
|
+
const plan = planKiroLaunch(ui, this.compatibility);
|
|
1138
|
+
const flags = plan.kind === "launch" ? plan.flags : [];
|
|
1139
|
+
const engine = flags.includes("--agent-engine=v1") ? "v1"
|
|
1140
|
+
: flags.includes("--agent-engine=v2") ? "v2" : ui === "v3" ? "v3" : null;
|
|
1141
|
+
const credentialProfile = resolveCredentialProfile(config.backendOptions);
|
|
1142
|
+
const base = { cwd: config.workingDirectory, skipResume: !!config.skipResume, engine, credentialProfile };
|
|
1143
|
+
const legacy = (reason) => ({ ...base, mode: "legacy", reason, agent: null, agentConfirmed: false });
|
|
1144
|
+
if (plan.kind !== "launch" || this.compatibility.source === "unknown")
|
|
1145
|
+
return legacy(null); // buildCommand refuses
|
|
1146
|
+
if (!this.compatibility.supportsInstanceAgent || !engine) {
|
|
1147
|
+
const key = this.compatibilityCacheKey ?? this.binaryPath;
|
|
1148
|
+
if (warnedNoInstanceAgentKeys.has(key))
|
|
1149
|
+
return legacy(null);
|
|
1150
|
+
warnedNoInstanceAgentKeys.add(key);
|
|
1151
|
+
return legacy(t("kiro.no_instance_agent", this.compatibility.version ?? "?", KIRO_INSTANCE_AGENT_MIN));
|
|
1152
|
+
}
|
|
1153
|
+
const agent = kiroAgentName(config.instanceName, kiroFleetTag(getAgendHome()));
|
|
1154
|
+
const agendHome = getAgendHome();
|
|
1155
|
+
let decision;
|
|
1156
|
+
if (engine === "v3") {
|
|
1157
|
+
// V3 keeps its own identity (kiro-v3-identity.ts); only whether it runs as the agent is recorded here.
|
|
1158
|
+
const id = resolveKiroV3Resume(config.instanceName, config.workingDirectory, credentialProfile, { skipResume: config.skipResume });
|
|
1159
|
+
decision = id
|
|
1160
|
+
? { mode: "resume", id, agentConfirmed: kiroAgentConfirmed(agendHome, config.instanceName, "v3", config.workingDirectory, credentialProfile, id) }
|
|
1161
|
+
: { mode: "fresh" };
|
|
1162
|
+
}
|
|
1163
|
+
else {
|
|
1164
|
+
decision = resolveKiroIdentity({
|
|
1165
|
+
instance: config.instanceName,
|
|
1166
|
+
engine,
|
|
1167
|
+
workingDirectory: config.workingDirectory,
|
|
1168
|
+
credentialProfile,
|
|
1169
|
+
skipResume: config.skipResume,
|
|
1170
|
+
agendHome,
|
|
1171
|
+
readStore: () => engine === "v1"
|
|
1172
|
+
? listKiroV1Sessions(config.workingDirectory, kiroV1DbPath(credentialProfile))
|
|
1173
|
+
: this.readPreparedV2Store(config),
|
|
1174
|
+
launchedBefore: () => kiroLaunchedHereBefore(config.instanceName, config.workingDirectory, credentialProfile, engine),
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
if (decision.mode === "legacy")
|
|
1178
|
+
return legacy(t("kiro.identity_legacy", decision.reason));
|
|
1179
|
+
return decision.mode === "resume"
|
|
1180
|
+
? { ...base, mode: "resume", id: decision.id, agent, agentConfirmed: decision.agentConfirmed, reason: null }
|
|
1181
|
+
: { ...base, mode: "fresh", agent, agentConfirmed: true, reason: null };
|
|
1182
|
+
}
|
|
1183
|
+
/**
|
|
1184
|
+
* After a resume as the instance's agent (#906 §3): what the daemon needs to read the active agent off the live
|
|
1185
|
+
* layout and, when it is not ours, switch to it with `/agent swap` and confirm. Null when there is nothing to do.
|
|
1186
|
+
*/
|
|
1187
|
+
agentSwitch() {
|
|
1188
|
+
const plan = this.activePlan;
|
|
1189
|
+
if (!plan || plan.mode !== "resume" || !plan.agent || !plan.id || !plan.engine)
|
|
1190
|
+
return null;
|
|
1191
|
+
const { agent, id, engine, cwd, credentialProfile } = plan;
|
|
1192
|
+
const ui = this.activeUi;
|
|
1193
|
+
return {
|
|
1194
|
+
agent,
|
|
1195
|
+
alreadyConfirmed: plan.agentConfirmed,
|
|
1196
|
+
readActive: (pane) => readActiveKiroAgent(pane, ui),
|
|
1197
|
+
command: `/agent swap ${agent}`,
|
|
1198
|
+
confirm: () => {
|
|
1199
|
+
const warnings = [];
|
|
1200
|
+
if (!this.activeInstance || !confirmKiroAgentSwitch(getAgendHome(), this.activeInstance, engine, cwd, credentialProfile, id)) {
|
|
1201
|
+
warnings.push(t("kiro.switch_unrecorded"));
|
|
1202
|
+
return warnings;
|
|
1203
|
+
}
|
|
1204
|
+
plan.agentConfirmed = true;
|
|
1205
|
+
const spec = this.activeSpec;
|
|
1206
|
+
if (spec) {
|
|
1207
|
+
const mcp = removeSharedKiroMcpEntries(spec, dirname(this.instanceDir), true);
|
|
1208
|
+
if (mcp === "unreadable" || mcp === "failed")
|
|
1209
|
+
warnings.push(t("kiro.shared_unreadable", "mcp.json"));
|
|
1210
|
+
const steering = removeTaggedKiroSteering(spec);
|
|
1211
|
+
if (steering === "failed" || steering === "unreadable")
|
|
1212
|
+
warnings.push(t("kiro.shared_unreadable", "steering"));
|
|
1213
|
+
}
|
|
1214
|
+
return warnings;
|
|
1215
|
+
},
|
|
1216
|
+
};
|
|
838
1217
|
}
|
|
1218
|
+
/**
|
|
1219
|
+
* An instance running as its own agent reads its instructions from the agent file's prompt (#906). Until a resumed
|
|
1220
|
+
* conversation's switch is confirmed it still runs as its saved agent, reading the steering file (the default).
|
|
1221
|
+
*/
|
|
1222
|
+
instructionsSource() {
|
|
1223
|
+
const plan = this.activePlan;
|
|
1224
|
+
return plan && plan.mode !== "legacy" && plan.agent && plan.agentConfirmed ? `.kiro/agents/${plan.agent}.json (its "prompt" field)` : null;
|
|
1225
|
+
}
|
|
1226
|
+
activeSpec = null;
|
|
1227
|
+
activeInstance = null;
|
|
839
1228
|
getReadyPattern() {
|
|
840
1229
|
// Startup: trust/banner text. Daily prompt: "22% !>" / "8% ❯";
|
|
841
1230
|
// Kiro may insert mode glyphs between them, e.g. "20% λ !>".
|
|
@@ -1028,13 +1417,7 @@ export class KiroBackend {
|
|
|
1028
1417
|
getStartupDialogs() {
|
|
1029
1418
|
return [
|
|
1030
1419
|
...KIRO_ENGINE_PROMPT_DIALOGS,
|
|
1031
|
-
|
|
1032
|
-
// Kiro CLI --trust-all-tools now shows a confirmation prompt.
|
|
1033
|
-
// Default cursor is on "No, exit" — press Down then Enter to select "Yes, I accept".
|
|
1034
|
-
pattern: /[❯›]\s*No, exit/m,
|
|
1035
|
-
keys: ["Down", "Enter"],
|
|
1036
|
-
description: "Kiro --trust-all-tools confirmation — navigate to 'Yes, I accept'",
|
|
1037
|
-
},
|
|
1420
|
+
...kiroTrustPromptDialogs(this.activeTrustAll),
|
|
1038
1421
|
];
|
|
1039
1422
|
}
|
|
1040
1423
|
getRuntimeDialogs() {
|
|
@@ -1066,13 +1449,7 @@ export class KiroBackend {
|
|
|
1066
1449
|
inputBlocked: true,
|
|
1067
1450
|
isActive: kiroModelPickerAtTail,
|
|
1068
1451
|
},
|
|
1069
|
-
|
|
1070
|
-
// Same trust prompt can also appear mid-session if Kiro re-validates.
|
|
1071
|
-
pattern: /Do you trust the files|Yes, I accept[\s\S]*No, exit/m,
|
|
1072
|
-
keys: ["Down", "Enter"],
|
|
1073
|
-
description: "Kiro trust confirmation dialog — auto-accept",
|
|
1074
|
-
isActive: kiroTrustDialogActive,
|
|
1075
|
-
},
|
|
1452
|
+
...kiroTrustPromptDialogs(this.activeTrustAll),
|
|
1076
1453
|
];
|
|
1077
1454
|
}
|
|
1078
1455
|
getContextUsage() {
|
|
@@ -1138,26 +1515,25 @@ export class KiroBackend {
|
|
|
1138
1515
|
getEffortStrategy() { return EFFORT_CAPABILITIES["kiro-cli"].strategy; }
|
|
1139
1516
|
getEffortLevels() { return [...EFFORT_CAPABILITIES["kiro-cli"].levels]; }
|
|
1140
1517
|
cleanup(config) {
|
|
1141
|
-
//
|
|
1142
|
-
//
|
|
1518
|
+
// By provenance only (#906 §4/§6): the agent file and its .bak when they are this instance's, the shared mcp.json
|
|
1519
|
+
// entries run by this instance's own wrappers, and a steering file carrying this fleet's tag for it. The user's,
|
|
1520
|
+
// another fleet's, and untagged steering from before the tag existed are kept.
|
|
1143
1521
|
try {
|
|
1144
|
-
const
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1522
|
+
const spec = this.agentSpec(config);
|
|
1523
|
+
removeKiroAgent(spec);
|
|
1524
|
+
removeSharedKiroMcpEntries(spec, dirname(this.instanceDir), true);
|
|
1525
|
+
removeTaggedKiroSteering(spec);
|
|
1526
|
+
}
|
|
1527
|
+
catch { /* best effort */ }
|
|
1528
|
+
}
|
|
1529
|
+
/** Delete or replace: forget which conversations this instance owns (they stay in kiro's store). */
|
|
1530
|
+
forget(instanceName) {
|
|
1531
|
+
try {
|
|
1532
|
+
forgetKiroIdentity(getAgendHome(), instanceName);
|
|
1154
1533
|
}
|
|
1155
1534
|
catch { /* best effort */ }
|
|
1156
|
-
// Remove fleet instructions steering file
|
|
1157
1535
|
try {
|
|
1158
|
-
|
|
1159
|
-
if (existsSync(steeringFile))
|
|
1160
|
-
unlinkSync(steeringFile);
|
|
1536
|
+
forgetKiroV3Identity(instanceName, getAgendHome());
|
|
1161
1537
|
}
|
|
1162
1538
|
catch { /* best effort */ }
|
|
1163
1539
|
}
|