iosm-cli 0.1.0
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/CHANGELOG.md +55 -0
- package/LICENSE +21 -0
- package/README.md +650 -0
- package/dist/cli/args.d.ts +54 -0
- package/dist/cli/args.d.ts.map +1 -0
- package/dist/cli/args.js +331 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/config-selector.d.ts +14 -0
- package/dist/cli/config-selector.d.ts.map +1 -0
- package/dist/cli/config-selector.js +31 -0
- package/dist/cli/config-selector.js.map +1 -0
- package/dist/cli/file-processor.d.ts +15 -0
- package/dist/cli/file-processor.d.ts.map +1 -0
- package/dist/cli/file-processor.js +79 -0
- package/dist/cli/file-processor.js.map +1 -0
- package/dist/cli/list-models.d.ts +9 -0
- package/dist/cli/list-models.d.ts.map +1 -0
- package/dist/cli/list-models.js +92 -0
- package/dist/cli/list-models.js.map +1 -0
- package/dist/cli/session-picker.d.ts +9 -0
- package/dist/cli/session-picker.d.ts.map +1 -0
- package/dist/cli/session-picker.js +34 -0
- package/dist/cli/session-picker.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +88 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +262 -0
- package/dist/config.js.map +1 -0
- package/dist/core/agent-profiles.d.ts +29 -0
- package/dist/core/agent-profiles.d.ts.map +1 -0
- package/dist/core/agent-profiles.js +86 -0
- package/dist/core/agent-profiles.js.map +1 -0
- package/dist/core/agent-session.d.ts +688 -0
- package/dist/core/agent-session.d.ts.map +1 -0
- package/dist/core/agent-session.js +3112 -0
- package/dist/core/agent-session.js.map +1 -0
- package/dist/core/agent-teams.d.ts +41 -0
- package/dist/core/agent-teams.d.ts.map +1 -0
- package/dist/core/agent-teams.js +90 -0
- package/dist/core/agent-teams.js.map +1 -0
- package/dist/core/ask-user-tool.d.ts +22 -0
- package/dist/core/ask-user-tool.d.ts.map +1 -0
- package/dist/core/ask-user-tool.js +115 -0
- package/dist/core/ask-user-tool.js.map +1 -0
- package/dist/core/auth-storage.d.ts +133 -0
- package/dist/core/auth-storage.d.ts.map +1 -0
- package/dist/core/auth-storage.js +391 -0
- package/dist/core/auth-storage.js.map +1 -0
- package/dist/core/bash-executor.d.ts +49 -0
- package/dist/core/bash-executor.d.ts.map +1 -0
- package/dist/core/bash-executor.js +213 -0
- package/dist/core/bash-executor.js.map +1 -0
- package/dist/core/compaction/branch-summarization.d.ts +86 -0
- package/dist/core/compaction/branch-summarization.d.ts.map +1 -0
- package/dist/core/compaction/branch-summarization.js +242 -0
- package/dist/core/compaction/branch-summarization.js.map +1 -0
- package/dist/core/compaction/compaction.d.ts +121 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -0
- package/dist/core/compaction/compaction.js +610 -0
- package/dist/core/compaction/compaction.js.map +1 -0
- package/dist/core/compaction/index.d.ts +7 -0
- package/dist/core/compaction/index.d.ts.map +1 -0
- package/dist/core/compaction/index.js +7 -0
- package/dist/core/compaction/index.js.map +1 -0
- package/dist/core/compaction/utils.d.ts +35 -0
- package/dist/core/compaction/utils.d.ts.map +1 -0
- package/dist/core/compaction/utils.js +138 -0
- package/dist/core/compaction/utils.js.map +1 -0
- package/dist/core/defaults.d.ts +3 -0
- package/dist/core/defaults.d.ts.map +1 -0
- package/dist/core/defaults.js +2 -0
- package/dist/core/defaults.js.map +1 -0
- package/dist/core/diagnostics.d.ts +15 -0
- package/dist/core/diagnostics.d.ts.map +1 -0
- package/dist/core/diagnostics.js +2 -0
- package/dist/core/diagnostics.js.map +1 -0
- package/dist/core/event-bus.d.ts +9 -0
- package/dist/core/event-bus.d.ts.map +1 -0
- package/dist/core/event-bus.js +25 -0
- package/dist/core/event-bus.js.map +1 -0
- package/dist/core/exec.d.ts +29 -0
- package/dist/core/exec.d.ts.map +1 -0
- package/dist/core/exec.js +71 -0
- package/dist/core/exec.js.map +1 -0
- package/dist/core/export-html/ansi-to-html.d.ts +22 -0
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
- package/dist/core/export-html/ansi-to-html.js +249 -0
- package/dist/core/export-html/ansi-to-html.js.map +1 -0
- package/dist/core/export-html/index.d.ts +34 -0
- package/dist/core/export-html/index.d.ts.map +1 -0
- package/dist/core/export-html/index.js +222 -0
- package/dist/core/export-html/index.js.map +1 -0
- package/dist/core/export-html/template.css +971 -0
- package/dist/core/export-html/template.html +54 -0
- package/dist/core/export-html/template.js +1590 -0
- package/dist/core/export-html/tool-renderer.d.ts +35 -0
- package/dist/core/export-html/tool-renderer.d.ts.map +1 -0
- package/dist/core/export-html/tool-renderer.js +63 -0
- package/dist/core/export-html/tool-renderer.js.map +1 -0
- package/dist/core/export-html/vendor/highlight.min.js +1213 -0
- package/dist/core/export-html/vendor/marked.min.js +6 -0
- package/dist/core/extensions/index.d.ts +11 -0
- package/dist/core/extensions/index.d.ts.map +1 -0
- package/dist/core/extensions/index.js +9 -0
- package/dist/core/extensions/index.js.map +1 -0
- package/dist/core/extensions/loader.d.ts +25 -0
- package/dist/core/extensions/loader.d.ts.map +1 -0
- package/dist/core/extensions/loader.js +447 -0
- package/dist/core/extensions/loader.js.map +1 -0
- package/dist/core/extensions/runner.d.ts +146 -0
- package/dist/core/extensions/runner.d.ts.map +1 -0
- package/dist/core/extensions/runner.js +652 -0
- package/dist/core/extensions/runner.js.map +1 -0
- package/dist/core/extensions/types.d.ts +1074 -0
- package/dist/core/extensions/types.d.ts.map +1 -0
- package/dist/core/extensions/types.js +35 -0
- package/dist/core/extensions/types.js.map +1 -0
- package/dist/core/extensions/wrapper.d.ts +27 -0
- package/dist/core/extensions/wrapper.d.ts.map +1 -0
- package/dist/core/extensions/wrapper.js +102 -0
- package/dist/core/extensions/wrapper.js.map +1 -0
- package/dist/core/footer-data-provider.d.ts +32 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -0
- package/dist/core/footer-data-provider.js +134 -0
- package/dist/core/footer-data-provider.js.map +1 -0
- package/dist/core/hooks.d.ts +53 -0
- package/dist/core/hooks.d.ts.map +1 -0
- package/dist/core/hooks.js +332 -0
- package/dist/core/hooks.js.map +1 -0
- package/dist/core/index.d.ts +9 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +9 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/keybindings.d.ts +55 -0
- package/dist/core/keybindings.d.ts.map +1 -0
- package/dist/core/keybindings.js +157 -0
- package/dist/core/keybindings.js.map +1 -0
- package/dist/core/mcp/cli.d.ts +27 -0
- package/dist/core/mcp/cli.d.ts.map +1 -0
- package/dist/core/mcp/cli.js +275 -0
- package/dist/core/mcp/cli.js.map +1 -0
- package/dist/core/mcp/config.d.ts +11 -0
- package/dist/core/mcp/config.d.ts.map +1 -0
- package/dist/core/mcp/config.js +310 -0
- package/dist/core/mcp/config.js.map +1 -0
- package/dist/core/mcp/index.d.ts +5 -0
- package/dist/core/mcp/index.d.ts.map +1 -0
- package/dist/core/mcp/index.js +4 -0
- package/dist/core/mcp/index.js.map +1 -0
- package/dist/core/mcp/runtime.d.ts +42 -0
- package/dist/core/mcp/runtime.d.ts.map +1 -0
- package/dist/core/mcp/runtime.js +387 -0
- package/dist/core/mcp/runtime.js.map +1 -0
- package/dist/core/mcp/types.d.ts +76 -0
- package/dist/core/mcp/types.d.ts.map +1 -0
- package/dist/core/mcp/types.js +2 -0
- package/dist/core/mcp/types.js.map +1 -0
- package/dist/core/memory.d.ts +27 -0
- package/dist/core/memory.d.ts.map +1 -0
- package/dist/core/memory.js +203 -0
- package/dist/core/memory.js.map +1 -0
- package/dist/core/messages.d.ts +84 -0
- package/dist/core/messages.d.ts.map +1 -0
- package/dist/core/messages.js +141 -0
- package/dist/core/messages.js.map +1 -0
- package/dist/core/model-registry.d.ts +115 -0
- package/dist/core/model-registry.d.ts.map +1 -0
- package/dist/core/model-registry.js +549 -0
- package/dist/core/model-registry.js.map +1 -0
- package/dist/core/model-resolver.d.ts +104 -0
- package/dist/core/model-resolver.d.ts.map +1 -0
- package/dist/core/model-resolver.js +448 -0
- package/dist/core/model-resolver.js.map +1 -0
- package/dist/core/package-manager.d.ts +156 -0
- package/dist/core/package-manager.d.ts.map +1 -0
- package/dist/core/package-manager.js +1465 -0
- package/dist/core/package-manager.js.map +1 -0
- package/dist/core/parallel-task-agent.d.ts +19 -0
- package/dist/core/parallel-task-agent.d.ts.map +1 -0
- package/dist/core/parallel-task-agent.js +482 -0
- package/dist/core/parallel-task-agent.js.map +1 -0
- package/dist/core/prompt-templates.d.ts +50 -0
- package/dist/core/prompt-templates.d.ts.map +1 -0
- package/dist/core/prompt-templates.js +251 -0
- package/dist/core/prompt-templates.js.map +1 -0
- package/dist/core/qwen-cli-provider.d.ts +10 -0
- package/dist/core/qwen-cli-provider.d.ts.map +1 -0
- package/dist/core/qwen-cli-provider.js +271 -0
- package/dist/core/qwen-cli-provider.js.map +1 -0
- package/dist/core/resolve-config-value.d.ts +17 -0
- package/dist/core/resolve-config-value.d.ts.map +1 -0
- package/dist/core/resolve-config-value.js +60 -0
- package/dist/core/resolve-config-value.js.map +1 -0
- package/dist/core/resource-loader.d.ts +195 -0
- package/dist/core/resource-loader.d.ts.map +1 -0
- package/dist/core/resource-loader.js +820 -0
- package/dist/core/resource-loader.js.map +1 -0
- package/dist/core/sdk.d.ts +106 -0
- package/dist/core/sdk.d.ts.map +1 -0
- package/dist/core/sdk.js +460 -0
- package/dist/core/sdk.js.map +1 -0
- package/dist/core/session-manager.d.ts +323 -0
- package/dist/core/session-manager.d.ts.map +1 -0
- package/dist/core/session-manager.js +1094 -0
- package/dist/core/session-manager.js.map +1 -0
- package/dist/core/settings-manager.d.ts +243 -0
- package/dist/core/settings-manager.d.ts.map +1 -0
- package/dist/core/settings-manager.js +691 -0
- package/dist/core/settings-manager.js.map +1 -0
- package/dist/core/skills.d.ts +58 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +364 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/slash-commands.d.ts +15 -0
- package/dist/core/slash-commands.d.ts.map +1 -0
- package/dist/core/slash-commands.js +64 -0
- package/dist/core/slash-commands.js.map +1 -0
- package/dist/core/subagent-runs.d.ts +16 -0
- package/dist/core/subagent-runs.d.ts.map +1 -0
- package/dist/core/subagent-runs.js +70 -0
- package/dist/core/subagent-runs.js.map +1 -0
- package/dist/core/subagents.d.ts +45 -0
- package/dist/core/subagents.d.ts.map +1 -0
- package/dist/core/subagents.js +467 -0
- package/dist/core/subagents.js.map +1 -0
- package/dist/core/system-prompt.d.ts +28 -0
- package/dist/core/system-prompt.d.ts.map +1 -0
- package/dist/core/system-prompt.js +196 -0
- package/dist/core/system-prompt.js.map +1 -0
- package/dist/core/task-plan.d.ts +32 -0
- package/dist/core/task-plan.d.ts.map +1 -0
- package/dist/core/task-plan.js +155 -0
- package/dist/core/task-plan.js.map +1 -0
- package/dist/core/timings.d.ts +7 -0
- package/dist/core/timings.d.ts.map +1 -0
- package/dist/core/timings.js +26 -0
- package/dist/core/timings.js.map +1 -0
- package/dist/core/tools/bash.d.ts +58 -0
- package/dist/core/tools/bash.d.ts.map +1 -0
- package/dist/core/tools/bash.js +275 -0
- package/dist/core/tools/bash.js.map +1 -0
- package/dist/core/tools/edit-diff.d.ts +63 -0
- package/dist/core/tools/edit-diff.d.ts.map +1 -0
- package/dist/core/tools/edit-diff.js +243 -0
- package/dist/core/tools/edit-diff.js.map +1 -0
- package/dist/core/tools/edit.d.ts +42 -0
- package/dist/core/tools/edit.d.ts.map +1 -0
- package/dist/core/tools/edit.js +158 -0
- package/dist/core/tools/edit.js.map +1 -0
- package/dist/core/tools/find.d.ts +39 -0
- package/dist/core/tools/find.d.ts.map +1 -0
- package/dist/core/tools/find.js +219 -0
- package/dist/core/tools/find.js.map +1 -0
- package/dist/core/tools/grep.d.ts +45 -0
- package/dist/core/tools/grep.d.ts.map +1 -0
- package/dist/core/tools/grep.js +254 -0
- package/dist/core/tools/grep.js.map +1 -0
- package/dist/core/tools/ignore-filter.d.ts +5 -0
- package/dist/core/tools/ignore-filter.d.ts.map +1 -0
- package/dist/core/tools/ignore-filter.js +97 -0
- package/dist/core/tools/ignore-filter.js.map +1 -0
- package/dist/core/tools/index.d.ts +97 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +78 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/ls.d.ts +46 -0
- package/dist/core/tools/ls.d.ts.map +1 -0
- package/dist/core/tools/ls.js +136 -0
- package/dist/core/tools/ls.js.map +1 -0
- package/dist/core/tools/path-utils.d.ts +8 -0
- package/dist/core/tools/path-utils.d.ts.map +1 -0
- package/dist/core/tools/path-utils.js +81 -0
- package/dist/core/tools/path-utils.js.map +1 -0
- package/dist/core/tools/permissions.d.ts +8 -0
- package/dist/core/tools/permissions.d.ts.map +1 -0
- package/dist/core/tools/permissions.js +2 -0
- package/dist/core/tools/permissions.js.map +1 -0
- package/dist/core/tools/read.d.ts +39 -0
- package/dist/core/tools/read.d.ts.map +1 -0
- package/dist/core/tools/read.js +166 -0
- package/dist/core/tools/read.js.map +1 -0
- package/dist/core/tools/task.d.ts +109 -0
- package/dist/core/tools/task.d.ts.map +1 -0
- package/dist/core/tools/task.js +1065 -0
- package/dist/core/tools/task.js.map +1 -0
- package/dist/core/tools/todo.d.ts +42 -0
- package/dist/core/tools/todo.d.ts.map +1 -0
- package/dist/core/tools/todo.js +159 -0
- package/dist/core/tools/todo.js.map +1 -0
- package/dist/core/tools/truncate.d.ts +70 -0
- package/dist/core/tools/truncate.d.ts.map +1 -0
- package/dist/core/tools/truncate.js +205 -0
- package/dist/core/tools/truncate.js.map +1 -0
- package/dist/core/tools/write.d.ts +32 -0
- package/dist/core/tools/write.d.ts.map +1 -0
- package/dist/core/tools/write.js +90 -0
- package/dist/core/tools/write.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/iosm/agent-verification.d.ts +16 -0
- package/dist/iosm/agent-verification.d.ts.map +1 -0
- package/dist/iosm/agent-verification.js +138 -0
- package/dist/iosm/agent-verification.js.map +1 -0
- package/dist/iosm/automation.d.ts +40 -0
- package/dist/iosm/automation.d.ts.map +1 -0
- package/dist/iosm/automation.js +76 -0
- package/dist/iosm/automation.js.map +1 -0
- package/dist/iosm/config.d.ts +151 -0
- package/dist/iosm/config.d.ts.map +1 -0
- package/dist/iosm/config.js +323 -0
- package/dist/iosm/config.js.map +1 -0
- package/dist/iosm/context-loader.d.ts +12 -0
- package/dist/iosm/context-loader.d.ts.map +1 -0
- package/dist/iosm/context-loader.js +50 -0
- package/dist/iosm/context-loader.js.map +1 -0
- package/dist/iosm/cycle.d.ts +51 -0
- package/dist/iosm/cycle.d.ts.map +1 -0
- package/dist/iosm/cycle.js +861 -0
- package/dist/iosm/cycle.js.map +1 -0
- package/dist/iosm/guide.d.ts +31 -0
- package/dist/iosm/guide.d.ts.map +1 -0
- package/dist/iosm/guide.js +101 -0
- package/dist/iosm/guide.js.map +1 -0
- package/dist/iosm/index.d.ts +12 -0
- package/dist/iosm/index.d.ts.map +1 -0
- package/dist/iosm/index.js +11 -0
- package/dist/iosm/index.js.map +1 -0
- package/dist/iosm/init.d.ts +58 -0
- package/dist/iosm/init.d.ts.map +1 -0
- package/dist/iosm/init.js +1221 -0
- package/dist/iosm/init.js.map +1 -0
- package/dist/iosm/metrics.d.ts +23 -0
- package/dist/iosm/metrics.d.ts.map +1 -0
- package/dist/iosm/metrics.js +336 -0
- package/dist/iosm/metrics.js.map +1 -0
- package/dist/iosm/paths.d.ts +24 -0
- package/dist/iosm/paths.d.ts.map +1 -0
- package/dist/iosm/paths.js +77 -0
- package/dist/iosm/paths.js.map +1 -0
- package/dist/iosm/runtime-context.d.ts +20 -0
- package/dist/iosm/runtime-context.d.ts.map +1 -0
- package/dist/iosm/runtime-context.js +170 -0
- package/dist/iosm/runtime-context.js.map +1 -0
- package/dist/iosm/types.d.ts +151 -0
- package/dist/iosm/types.d.ts.map +1 -0
- package/dist/iosm/types.js +3 -0
- package/dist/iosm/types.js.map +1 -0
- package/dist/main.d.ts +8 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +1478 -0
- package/dist/main.js.map +1 -0
- package/dist/migrations.d.ts +33 -0
- package/dist/migrations.d.ts.map +1 -0
- package/dist/migrations.js +261 -0
- package/dist/migrations.js.map +1 -0
- package/dist/modes/index.d.ts +9 -0
- package/dist/modes/index.d.ts.map +1 -0
- package/dist/modes/index.js +8 -0
- package/dist/modes/index.js.map +1 -0
- package/dist/modes/interactive/components/armin.d.ts +34 -0
- package/dist/modes/interactive/components/armin.d.ts.map +1 -0
- package/dist/modes/interactive/components/armin.js +329 -0
- package/dist/modes/interactive/components/armin.js.map +1 -0
- package/dist/modes/interactive/components/ascii-logo.d.ts +11 -0
- package/dist/modes/interactive/components/ascii-logo.d.ts.map +1 -0
- package/dist/modes/interactive/components/ascii-logo.js +25 -0
- package/dist/modes/interactive/components/ascii-logo.js.map +1 -0
- package/dist/modes/interactive/components/assistant-message.d.ts +16 -0
- package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/assistant-message.js +92 -0
- package/dist/modes/interactive/components/assistant-message.js.map +1 -0
- package/dist/modes/interactive/components/bash-execution.d.ts +36 -0
- package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/bash-execution.js +170 -0
- package/dist/modes/interactive/components/bash-execution.js.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts +16 -0
- package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/bordered-loader.js +48 -0
- package/dist/modes/interactive/components/bordered-loader.js.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/branch-summary-message.js +42 -0
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +16 -0
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/compaction-summary-message.js +43 -0
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -0
- package/dist/modes/interactive/components/config-selector.d.ts +71 -0
- package/dist/modes/interactive/components/config-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/config-selector.js +470 -0
- package/dist/modes/interactive/components/config-selector.js.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts +14 -0
- package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -0
- package/dist/modes/interactive/components/countdown-timer.js +28 -0
- package/dist/modes/interactive/components/countdown-timer.js.map +1 -0
- package/dist/modes/interactive/components/custom-editor.d.ts +21 -0
- package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-editor.js +63 -0
- package/dist/modes/interactive/components/custom-editor.js.map +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts +20 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/custom-message.js +74 -0
- package/dist/modes/interactive/components/custom-message.js.map +1 -0
- package/dist/modes/interactive/components/daxnuts.d.ts +23 -0
- package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -0
- package/dist/modes/interactive/components/daxnuts.js +138 -0
- package/dist/modes/interactive/components/daxnuts.js.map +1 -0
- package/dist/modes/interactive/components/decrypt-loader.d.ts +25 -0
- package/dist/modes/interactive/components/decrypt-loader.d.ts.map +1 -0
- package/dist/modes/interactive/components/decrypt-loader.js +102 -0
- package/dist/modes/interactive/components/decrypt-loader.js.map +1 -0
- package/dist/modes/interactive/components/diff.d.ts +12 -0
- package/dist/modes/interactive/components/diff.d.ts.map +1 -0
- package/dist/modes/interactive/components/diff.js +133 -0
- package/dist/modes/interactive/components/diff.js.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts +15 -0
- package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -0
- package/dist/modes/interactive/components/dynamic-border.js +20 -0
- package/dist/modes/interactive/components/dynamic-border.js.map +1 -0
- package/dist/modes/interactive/components/extension-editor.d.ts +20 -0
- package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-editor.js +105 -0
- package/dist/modes/interactive/components/extension-editor.js.map +1 -0
- package/dist/modes/interactive/components/extension-input.d.ts +23 -0
- package/dist/modes/interactive/components/extension-input.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-input.js +55 -0
- package/dist/modes/interactive/components/extension-input.js.map +1 -0
- package/dist/modes/interactive/components/extension-selector.d.ts +24 -0
- package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/extension-selector.js +71 -0
- package/dist/modes/interactive/components/extension-selector.js.map +1 -0
- package/dist/modes/interactive/components/footer.d.ts +39 -0
- package/dist/modes/interactive/components/footer.d.ts.map +1 -0
- package/dist/modes/interactive/components/footer.js +285 -0
- package/dist/modes/interactive/components/footer.js.map +1 -0
- package/dist/modes/interactive/components/index.d.ts +33 -0
- package/dist/modes/interactive/components/index.d.ts.map +1 -0
- package/dist/modes/interactive/components/index.js +34 -0
- package/dist/modes/interactive/components/index.js.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts +50 -0
- package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -0
- package/dist/modes/interactive/components/keybinding-hints.js +85 -0
- package/dist/modes/interactive/components/keybinding-hints.js.map +1 -0
- package/dist/modes/interactive/components/login-dialog.d.ts +42 -0
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -0
- package/dist/modes/interactive/components/login-dialog.js +139 -0
- package/dist/modes/interactive/components/login-dialog.js.map +1 -0
- package/dist/modes/interactive/components/mcp-selector.d.ts +31 -0
- package/dist/modes/interactive/components/mcp-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/mcp-selector.js +171 -0
- package/dist/modes/interactive/components/mcp-selector.js.map +1 -0
- package/dist/modes/interactive/components/model-selector.d.ts +51 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/model-selector.js +292 -0
- package/dist/modes/interactive/components/model-selector.js.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts +19 -0
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/oauth-selector.js +134 -0
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts +49 -0
- package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/scoped-models-selector.js +271 -0
- package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts +23 -0
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector-search.js +155 -0
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -0
- package/dist/modes/interactive/components/session-selector.d.ts +95 -0
- package/dist/modes/interactive/components/session-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/session-selector.js +839 -0
- package/dist/modes/interactive/components/session-selector.js.map +1 -0
- package/dist/modes/interactive/components/settings-selector.d.ts +60 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/settings-selector.js +311 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts +10 -0
- package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/show-images-selector.js +34 -0
- package/dist/modes/interactive/components/show-images-selector.js.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts +17 -0
- package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/skill-invocation-message.js +45 -0
- package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -0
- package/dist/modes/interactive/components/subagent-message.d.ts +91 -0
- package/dist/modes/interactive/components/subagent-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/subagent-message.js +306 -0
- package/dist/modes/interactive/components/subagent-message.js.map +1 -0
- package/dist/modes/interactive/components/task-plan-message.d.ts +12 -0
- package/dist/modes/interactive/components/task-plan-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/task-plan-message.js +61 -0
- package/dist/modes/interactive/components/task-plan-message.js.map +1 -0
- package/dist/modes/interactive/components/theme-selector.d.ts +11 -0
- package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/theme-selector.js +44 -0
- package/dist/modes/interactive/components/theme-selector.js.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts +11 -0
- package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/thinking-selector.js +46 -0
- package/dist/modes/interactive/components/thinking-selector.js.map +1 -0
- package/dist/modes/interactive/components/tool-execution.d.ts +78 -0
- package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -0
- package/dist/modes/interactive/components/tool-execution.js +880 -0
- package/dist/modes/interactive/components/tool-execution.js.map +1 -0
- package/dist/modes/interactive/components/tree-selector.d.ts +70 -0
- package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/tree-selector.js +921 -0
- package/dist/modes/interactive/components/tree-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts +30 -0
- package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message-selector.js +110 -0
- package/dist/modes/interactive/components/user-message-selector.js.map +1 -0
- package/dist/modes/interactive/components/user-message.d.ts +9 -0
- package/dist/modes/interactive/components/user-message.d.ts.map +1 -0
- package/dist/modes/interactive/components/user-message.js +27 -0
- package/dist/modes/interactive/components/user-message.js.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts +24 -0
- package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -0
- package/dist/modes/interactive/components/visual-truncate.js +33 -0
- package/dist/modes/interactive/components/visual-truncate.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +453 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -0
- package/dist/modes/interactive/interactive-mode.js +8669 -0
- package/dist/modes/interactive/interactive-mode.js.map +1 -0
- package/dist/modes/interactive/theme/dark.json +85 -0
- package/dist/modes/interactive/theme/light.json +84 -0
- package/dist/modes/interactive/theme/theme-schema.json +335 -0
- package/dist/modes/interactive/theme/theme.d.ts +78 -0
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -0
- package/dist/modes/interactive/theme/theme.js +944 -0
- package/dist/modes/interactive/theme/theme.js.map +1 -0
- package/dist/modes/print-mode.d.ts +28 -0
- package/dist/modes/print-mode.d.ts.map +1 -0
- package/dist/modes/print-mode.js +101 -0
- package/dist/modes/print-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +217 -0
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-client.js +404 -0
- package/dist/modes/rpc/rpc-client.js.map +1 -0
- package/dist/modes/rpc/rpc-mode.d.ts +20 -0
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-mode.js +580 -0
- package/dist/modes/rpc/rpc-mode.js.map +1 -0
- package/dist/modes/rpc/rpc-types.d.ts +409 -0
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -0
- package/dist/modes/rpc/rpc-types.js +8 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -0
- package/dist/utils/changelog.d.ts +21 -0
- package/dist/utils/changelog.d.ts.map +1 -0
- package/dist/utils/changelog.js +87 -0
- package/dist/utils/changelog.js.map +1 -0
- package/dist/utils/clipboard-image.d.ts +11 -0
- package/dist/utils/clipboard-image.d.ts.map +1 -0
- package/dist/utils/clipboard-image.js +162 -0
- package/dist/utils/clipboard-image.js.map +1 -0
- package/dist/utils/clipboard-native.d.ts +7 -0
- package/dist/utils/clipboard-native.d.ts.map +1 -0
- package/dist/utils/clipboard-native.js +14 -0
- package/dist/utils/clipboard-native.js.map +1 -0
- package/dist/utils/clipboard.d.ts +2 -0
- package/dist/utils/clipboard.d.ts.map +1 -0
- package/dist/utils/clipboard.js +67 -0
- package/dist/utils/clipboard.js.map +1 -0
- package/dist/utils/frontmatter.d.ts +8 -0
- package/dist/utils/frontmatter.d.ts.map +1 -0
- package/dist/utils/frontmatter.js +26 -0
- package/dist/utils/frontmatter.js.map +1 -0
- package/dist/utils/git.d.ts +26 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +163 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/image-convert.d.ts +9 -0
- package/dist/utils/image-convert.d.ts.map +1 -0
- package/dist/utils/image-convert.js +35 -0
- package/dist/utils/image-convert.js.map +1 -0
- package/dist/utils/image-resize.d.ts +36 -0
- package/dist/utils/image-resize.d.ts.map +1 -0
- package/dist/utils/image-resize.js +181 -0
- package/dist/utils/image-resize.js.map +1 -0
- package/dist/utils/mime.d.ts +2 -0
- package/dist/utils/mime.d.ts.map +1 -0
- package/dist/utils/mime.js +26 -0
- package/dist/utils/mime.js.map +1 -0
- package/dist/utils/photon.d.ts +21 -0
- package/dist/utils/photon.d.ts.map +1 -0
- package/dist/utils/photon.js +121 -0
- package/dist/utils/photon.js.map +1 -0
- package/dist/utils/shell.d.ts +26 -0
- package/dist/utils/shell.d.ts.map +1 -0
- package/dist/utils/shell.js +186 -0
- package/dist/utils/shell.js.map +1 -0
- package/dist/utils/sleep.d.ts +5 -0
- package/dist/utils/sleep.d.ts.map +1 -0
- package/dist/utils/sleep.js +17 -0
- package/dist/utils/sleep.js.map +1 -0
- package/dist/utils/tools-manager.d.ts +3 -0
- package/dist/utils/tools-manager.d.ts.map +1 -0
- package/dist/utils/tools-manager.js +251 -0
- package/dist/utils/tools-manager.js.map +1 -0
- package/docs/README.md +32 -0
- package/docs/cli-reference.md +342 -0
- package/docs/configuration.md +301 -0
- package/docs/development-and-testing.md +295 -0
- package/docs/extensions-packages-themes.md +415 -0
- package/docs/getting-started.md +246 -0
- package/docs/interactive-mode.md +272 -0
- package/docs/iosm-init-and-cycles.md +355 -0
- package/docs/orchestration-and-subagents.md +273 -0
- package/docs/rpc-json-sdk.md +353 -0
- package/docs/sessions-traces-export.md +260 -0
- package/examples/README.md +120 -0
- package/examples/extensions/README.md +306 -0
- package/examples/extensions/antigravity-image-gen.ts +415 -0
- package/examples/extensions/auto-commit-on-exit.ts +49 -0
- package/examples/extensions/bash-spawn-hook.ts +30 -0
- package/examples/extensions/bookmark.ts +50 -0
- package/examples/extensions/built-in-tool-renderer.ts +246 -0
- package/examples/extensions/claude-rules.ts +86 -0
- package/examples/extensions/commands.ts +72 -0
- package/examples/extensions/confirm-destructive.ts +59 -0
- package/examples/extensions/custom-compaction.ts +114 -0
- package/examples/extensions/custom-footer.ts +64 -0
- package/examples/extensions/custom-header.ts +73 -0
- package/examples/extensions/custom-provider-anthropic/index.ts +604 -0
- package/examples/extensions/custom-provider-anthropic/package-lock.json +24 -0
- package/examples/extensions/custom-provider-anthropic/package.json +19 -0
- package/examples/extensions/custom-provider-gitlab-duo/index.ts +349 -0
- package/examples/extensions/custom-provider-gitlab-duo/package.json +16 -0
- package/examples/extensions/custom-provider-gitlab-duo/test.ts +82 -0
- package/examples/extensions/custom-provider-qwen-cli/index.ts +345 -0
- package/examples/extensions/custom-provider-qwen-cli/package.json +16 -0
- package/examples/extensions/dirty-repo-guard.ts +56 -0
- package/examples/extensions/doom-overlay/README.md +46 -0
- package/examples/extensions/doom-overlay/doom/build/doom.js +21 -0
- package/examples/extensions/doom-overlay/doom/build/doom.wasm +0 -0
- package/examples/extensions/doom-overlay/doom/build.sh +152 -0
- package/examples/extensions/doom-overlay/doom/doomgeneric_pi.c +72 -0
- package/examples/extensions/doom-overlay/doom-component.ts +132 -0
- package/examples/extensions/doom-overlay/doom-engine.ts +173 -0
- package/examples/extensions/doom-overlay/doom-keys.ts +104 -0
- package/examples/extensions/doom-overlay/index.ts +74 -0
- package/examples/extensions/doom-overlay/wad-finder.ts +51 -0
- package/examples/extensions/dynamic-resources/SKILL.md +8 -0
- package/examples/extensions/dynamic-resources/dynamic.json +79 -0
- package/examples/extensions/dynamic-resources/dynamic.md +5 -0
- package/examples/extensions/dynamic-resources/index.ts +15 -0
- package/examples/extensions/dynamic-tools.ts +74 -0
- package/examples/extensions/event-bus.ts +43 -0
- package/examples/extensions/file-trigger.ts +41 -0
- package/examples/extensions/git-checkpoint.ts +53 -0
- package/examples/extensions/handoff.ts +150 -0
- package/examples/extensions/hello.ts +25 -0
- package/examples/extensions/inline-bash.ts +94 -0
- package/examples/extensions/input-transform.ts +43 -0
- package/examples/extensions/interactive-shell.ts +196 -0
- package/examples/extensions/mac-system-theme.ts +47 -0
- package/examples/extensions/message-renderer.ts +59 -0
- package/examples/extensions/minimal-mode.ts +426 -0
- package/examples/extensions/modal-editor.ts +85 -0
- package/examples/extensions/model-status.ts +31 -0
- package/examples/extensions/notify.ts +55 -0
- package/examples/extensions/overlay-qa-tests.ts +881 -0
- package/examples/extensions/overlay-test.ts +150 -0
- package/examples/extensions/permission-gate.ts +34 -0
- package/examples/extensions/pirate.ts +47 -0
- package/examples/extensions/plan-mode/README.md +65 -0
- package/examples/extensions/plan-mode/index.ts +340 -0
- package/examples/extensions/plan-mode/utils.ts +168 -0
- package/examples/extensions/preset.ts +398 -0
- package/examples/extensions/protected-paths.ts +30 -0
- package/examples/extensions/qna.ts +119 -0
- package/examples/extensions/question.ts +264 -0
- package/examples/extensions/questionnaire.ts +427 -0
- package/examples/extensions/rainbow-editor.ts +88 -0
- package/examples/extensions/reload-runtime.ts +37 -0
- package/examples/extensions/rpc-demo.ts +124 -0
- package/examples/extensions/sandbox/index.ts +318 -0
- package/examples/extensions/sandbox/package-lock.json +92 -0
- package/examples/extensions/sandbox/package.json +19 -0
- package/examples/extensions/send-user-message.ts +97 -0
- package/examples/extensions/session-name.ts +27 -0
- package/examples/extensions/shutdown-command.ts +63 -0
- package/examples/extensions/snake.ts +343 -0
- package/examples/extensions/space-invaders.ts +560 -0
- package/examples/extensions/ssh.ts +220 -0
- package/examples/extensions/status-line.ts +40 -0
- package/examples/extensions/subagent/README.md +172 -0
- package/examples/extensions/subagent/agents/planner.md +37 -0
- package/examples/extensions/subagent/agents/reviewer.md +35 -0
- package/examples/extensions/subagent/agents/scout.md +50 -0
- package/examples/extensions/subagent/agents/worker.md +24 -0
- package/examples/extensions/subagent/agents.ts +126 -0
- package/examples/extensions/subagent/index.ts +964 -0
- package/examples/extensions/subagent/prompts/implement-and-review.md +10 -0
- package/examples/extensions/subagent/prompts/implement.md +10 -0
- package/examples/extensions/subagent/prompts/scout-and-plan.md +9 -0
- package/examples/extensions/summarize.ts +195 -0
- package/examples/extensions/system-prompt-header.ts +17 -0
- package/examples/extensions/timed-confirm.ts +70 -0
- package/examples/extensions/titlebar-spinner.ts +58 -0
- package/examples/extensions/todo.ts +299 -0
- package/examples/extensions/tool-override.ts +143 -0
- package/examples/extensions/tools.ts +146 -0
- package/examples/extensions/trigger-compact.ts +40 -0
- package/examples/extensions/truncated-tool.ts +192 -0
- package/examples/extensions/widget-placement.ts +17 -0
- package/examples/extensions/with-deps/index.ts +36 -0
- package/examples/extensions/with-deps/package-lock.json +31 -0
- package/examples/extensions/with-deps/package.json +22 -0
- package/examples/rpc-extension-ui.ts +632 -0
- package/examples/sdk/01-minimal.ts +22 -0
- package/examples/sdk/02-custom-model.ts +49 -0
- package/examples/sdk/03-custom-prompt.ts +55 -0
- package/examples/sdk/04-skills.ts +46 -0
- package/examples/sdk/05-tools.ts +56 -0
- package/examples/sdk/06-extensions.ts +88 -0
- package/examples/sdk/07-context-files.ts +40 -0
- package/examples/sdk/08-prompt-templates.ts +47 -0
- package/examples/sdk/09-api-keys-and-oauth.ts +48 -0
- package/examples/sdk/10-settings.ts +51 -0
- package/examples/sdk/11-sessions.ts +48 -0
- package/examples/sdk/12-full-control.ts +82 -0
- package/examples/sdk/README.md +337 -0
- package/examples/tsconfig.json +3 -0
- package/package.json +107 -0
package/dist/main.js
ADDED
|
@@ -0,0 +1,1478 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Main entry point for the coding agent CLI.
|
|
3
|
+
*
|
|
4
|
+
* This file handles CLI argument parsing and translates them into
|
|
5
|
+
* createAgentSession() options. The SDK does the heavy lifting.
|
|
6
|
+
*/
|
|
7
|
+
import { supportsXhigh } from "@mariozechner/pi-ai";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { writeFileSync } from "node:fs";
|
|
10
|
+
import { resolve } from "node:path";
|
|
11
|
+
import { createInterface } from "readline";
|
|
12
|
+
import { parseArgs, printHelp } from "./cli/args.js";
|
|
13
|
+
import { selectConfig } from "./cli/config-selector.js";
|
|
14
|
+
import { processFileArguments } from "./cli/file-processor.js";
|
|
15
|
+
import { listModels } from "./cli/list-models.js";
|
|
16
|
+
import { selectSession } from "./cli/session-picker.js";
|
|
17
|
+
import { APP_NAME, CONFIG_DIR_NAME, ENV_OFFLINE, ENV_SESSION_TRACE, ENV_SESSION_TRACE_DIR, ENV_SKIP_VERSION_CHECK, getAgentDir, getModelsPath, getSessionTracePath, isSessionTraceEnabled, isTruthyEnvFlag, VERSION, } from "./config.js";
|
|
18
|
+
import { AuthStorage } from "./core/auth-storage.js";
|
|
19
|
+
import { exportFromFile } from "./core/export-html/index.js";
|
|
20
|
+
import { KeybindingsManager } from "./core/keybindings.js";
|
|
21
|
+
import { ModelRegistry } from "./core/model-registry.js";
|
|
22
|
+
import { resolveCliModel, resolveModelScope } from "./core/model-resolver.js";
|
|
23
|
+
import { getMcpCommandHelp, getMergedServerByName, loadMergedMcpConfig, McpRuntime, parseMcpAddCommand, parseMcpTargetCommand, } from "./core/mcp/index.js";
|
|
24
|
+
import { DefaultPackageManager } from "./core/package-manager.js";
|
|
25
|
+
import { DefaultResourceLoader } from "./core/resource-loader.js";
|
|
26
|
+
import { createAgentSession } from "./core/sdk.js";
|
|
27
|
+
import { getProfileNames, isValidProfileName } from "./core/agent-profiles.js";
|
|
28
|
+
import { SessionManager } from "./core/session-manager.js";
|
|
29
|
+
import { SettingsManager } from "./core/settings-manager.js";
|
|
30
|
+
import { printTimings, time } from "./core/timings.js";
|
|
31
|
+
import { allTools } from "./core/tools/index.js";
|
|
32
|
+
import { runMigrations, showDeprecationWarnings } from "./migrations.js";
|
|
33
|
+
import { InteractiveMode, runPrintMode, runRpcMode } from "./modes/index.js";
|
|
34
|
+
import { initTheme, stopThemeWatcher } from "./modes/interactive/theme/theme.js";
|
|
35
|
+
import { buildIosmAgentVerificationPrompt, buildIosmGuideAuthoringPrompt, buildIosmPriorityChecklist, createMetricSnapshot, extractAssistantText, formatMetricSnapshot, getIosmGuidePath, initIosmWorkspace, inspectIosmCycle, listIosmCycles, planIosmCycle, readIosmCycleReport, recordIosmCycleHistory, normalizeIosmGuideMarkdown, writeIosmGuideDocument, } from "./iosm/index.js";
|
|
36
|
+
/**
|
|
37
|
+
* Read all content from piped stdin.
|
|
38
|
+
* Returns undefined if stdin is a TTY (interactive terminal).
|
|
39
|
+
*/
|
|
40
|
+
async function readPipedStdin() {
|
|
41
|
+
// If stdin is a TTY, we're running interactively - don't read stdin
|
|
42
|
+
if (process.stdin.isTTY) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
return new Promise((resolve) => {
|
|
46
|
+
let data = "";
|
|
47
|
+
process.stdin.setEncoding("utf8");
|
|
48
|
+
process.stdin.on("data", (chunk) => {
|
|
49
|
+
data += chunk;
|
|
50
|
+
});
|
|
51
|
+
process.stdin.on("end", () => {
|
|
52
|
+
resolve(data.trim() || undefined);
|
|
53
|
+
});
|
|
54
|
+
process.stdin.resume();
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
function reportSettingsErrors(settingsManager, context) {
|
|
58
|
+
const errors = settingsManager.drainErrors();
|
|
59
|
+
for (const { scope, error } of errors) {
|
|
60
|
+
console.error(chalk.yellow(`Warning (${context}, ${scope} settings): ${error.message}`));
|
|
61
|
+
if (error.stack) {
|
|
62
|
+
console.error(chalk.dim(error.stack));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function applySessionTraceCliOverrides(args) {
|
|
67
|
+
let sessionTraceEnabled = false;
|
|
68
|
+
let sessionTraceDir;
|
|
69
|
+
for (let index = 0; index < args.length; index++) {
|
|
70
|
+
const arg = args[index];
|
|
71
|
+
if (arg === "--session-trace") {
|
|
72
|
+
sessionTraceEnabled = true;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (arg === "--session-trace-dir" && index + 1 < args.length) {
|
|
76
|
+
sessionTraceDir = resolve(args[index + 1]);
|
|
77
|
+
index += 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
if (sessionTraceEnabled) {
|
|
81
|
+
process.env[ENV_SESSION_TRACE] = "1";
|
|
82
|
+
process.env.PI_SESSION_TRACE = "1";
|
|
83
|
+
}
|
|
84
|
+
if (sessionTraceDir) {
|
|
85
|
+
process.env[ENV_SESSION_TRACE_DIR] = sessionTraceDir;
|
|
86
|
+
process.env.PI_SESSION_TRACE_DIR = sessionTraceDir;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
function getPackageCommandUsage(command) {
|
|
90
|
+
switch (command) {
|
|
91
|
+
case "install":
|
|
92
|
+
return `${APP_NAME} install <source> [-l]`;
|
|
93
|
+
case "remove":
|
|
94
|
+
return `${APP_NAME} remove <source> [-l]`;
|
|
95
|
+
case "update":
|
|
96
|
+
return `${APP_NAME} update [source]`;
|
|
97
|
+
case "list":
|
|
98
|
+
return `${APP_NAME} list`;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function printPackageCommandHelp(command) {
|
|
102
|
+
switch (command) {
|
|
103
|
+
case "install":
|
|
104
|
+
console.log(`${chalk.bold("Usage:")}
|
|
105
|
+
${getPackageCommandUsage("install")}
|
|
106
|
+
|
|
107
|
+
Install a package and add it to settings.
|
|
108
|
+
|
|
109
|
+
Options:
|
|
110
|
+
-l, --local Install project-locally (${CONFIG_DIR_NAME}/settings.json)
|
|
111
|
+
|
|
112
|
+
Examples:
|
|
113
|
+
${APP_NAME} install npm:@foo/bar
|
|
114
|
+
${APP_NAME} install git:github.com/user/repo
|
|
115
|
+
${APP_NAME} install git:git@github.com:user/repo
|
|
116
|
+
${APP_NAME} install https://github.com/user/repo
|
|
117
|
+
${APP_NAME} install ssh://git@github.com/user/repo
|
|
118
|
+
${APP_NAME} install ./local/path
|
|
119
|
+
`);
|
|
120
|
+
return;
|
|
121
|
+
case "remove":
|
|
122
|
+
console.log(`${chalk.bold("Usage:")}
|
|
123
|
+
${getPackageCommandUsage("remove")}
|
|
124
|
+
|
|
125
|
+
Remove a package and its source from settings.
|
|
126
|
+
|
|
127
|
+
Options:
|
|
128
|
+
-l, --local Remove from project settings (${CONFIG_DIR_NAME}/settings.json)
|
|
129
|
+
|
|
130
|
+
Example:
|
|
131
|
+
${APP_NAME} remove npm:@foo/bar
|
|
132
|
+
`);
|
|
133
|
+
return;
|
|
134
|
+
case "update":
|
|
135
|
+
console.log(`${chalk.bold("Usage:")}
|
|
136
|
+
${getPackageCommandUsage("update")}
|
|
137
|
+
|
|
138
|
+
Update installed packages.
|
|
139
|
+
If <source> is provided, only that package is updated.
|
|
140
|
+
`);
|
|
141
|
+
return;
|
|
142
|
+
case "list":
|
|
143
|
+
console.log(`${chalk.bold("Usage:")}
|
|
144
|
+
${getPackageCommandUsage("list")}
|
|
145
|
+
|
|
146
|
+
List installed packages from user and project settings.
|
|
147
|
+
`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
function parsePackageCommand(args) {
|
|
152
|
+
const [command, ...rest] = args;
|
|
153
|
+
if (command !== "install" && command !== "remove" && command !== "update" && command !== "list") {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
let local = false;
|
|
157
|
+
let help = false;
|
|
158
|
+
let invalidOption;
|
|
159
|
+
let source;
|
|
160
|
+
for (const arg of rest) {
|
|
161
|
+
if (arg === "-h" || arg === "--help") {
|
|
162
|
+
help = true;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
if (arg === "-l" || arg === "--local") {
|
|
166
|
+
if (command === "install" || command === "remove") {
|
|
167
|
+
local = true;
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
invalidOption = invalidOption ?? arg;
|
|
171
|
+
}
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
if (arg.startsWith("-")) {
|
|
175
|
+
invalidOption = invalidOption ?? arg;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
if (!source) {
|
|
179
|
+
source = arg;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return { command, source, local, help, invalidOption };
|
|
183
|
+
}
|
|
184
|
+
async function handlePackageCommand(args) {
|
|
185
|
+
const options = parsePackageCommand(args);
|
|
186
|
+
if (!options) {
|
|
187
|
+
return false;
|
|
188
|
+
}
|
|
189
|
+
if (options.help) {
|
|
190
|
+
printPackageCommandHelp(options.command);
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
if (options.invalidOption) {
|
|
194
|
+
console.error(chalk.red(`Unknown option ${options.invalidOption} for "${options.command}".`));
|
|
195
|
+
console.error(chalk.dim(`Use "${APP_NAME} --help" or "${getPackageCommandUsage(options.command)}".`));
|
|
196
|
+
process.exitCode = 1;
|
|
197
|
+
return true;
|
|
198
|
+
}
|
|
199
|
+
const source = options.source;
|
|
200
|
+
if ((options.command === "install" || options.command === "remove") && !source) {
|
|
201
|
+
console.error(chalk.red(`Missing ${options.command} source.`));
|
|
202
|
+
console.error(chalk.dim(`Usage: ${getPackageCommandUsage(options.command)}`));
|
|
203
|
+
process.exitCode = 1;
|
|
204
|
+
return true;
|
|
205
|
+
}
|
|
206
|
+
const cwd = process.cwd();
|
|
207
|
+
const agentDir = getAgentDir();
|
|
208
|
+
const settingsManager = SettingsManager.create(cwd, agentDir);
|
|
209
|
+
reportSettingsErrors(settingsManager, "package command");
|
|
210
|
+
const packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });
|
|
211
|
+
packageManager.setProgressCallback((event) => {
|
|
212
|
+
if (event.type === "start") {
|
|
213
|
+
process.stdout.write(chalk.dim(`${event.message}\n`));
|
|
214
|
+
}
|
|
215
|
+
});
|
|
216
|
+
try {
|
|
217
|
+
switch (options.command) {
|
|
218
|
+
case "install":
|
|
219
|
+
await packageManager.install(source, { local: options.local });
|
|
220
|
+
packageManager.addSourceToSettings(source, { local: options.local });
|
|
221
|
+
console.log(chalk.green(`Installed ${source}`));
|
|
222
|
+
return true;
|
|
223
|
+
case "remove": {
|
|
224
|
+
await packageManager.remove(source, { local: options.local });
|
|
225
|
+
const removed = packageManager.removeSourceFromSettings(source, { local: options.local });
|
|
226
|
+
if (!removed) {
|
|
227
|
+
console.error(chalk.red(`No matching package found for ${source}`));
|
|
228
|
+
process.exitCode = 1;
|
|
229
|
+
return true;
|
|
230
|
+
}
|
|
231
|
+
console.log(chalk.green(`Removed ${source}`));
|
|
232
|
+
return true;
|
|
233
|
+
}
|
|
234
|
+
case "list": {
|
|
235
|
+
const globalSettings = settingsManager.getGlobalSettings();
|
|
236
|
+
const projectSettings = settingsManager.getProjectSettings();
|
|
237
|
+
const globalPackages = globalSettings.packages ?? [];
|
|
238
|
+
const projectPackages = projectSettings.packages ?? [];
|
|
239
|
+
if (globalPackages.length === 0 && projectPackages.length === 0) {
|
|
240
|
+
console.log(chalk.dim("No packages installed."));
|
|
241
|
+
return true;
|
|
242
|
+
}
|
|
243
|
+
const formatPackage = (pkg, scope) => {
|
|
244
|
+
const source = typeof pkg === "string" ? pkg : pkg.source;
|
|
245
|
+
const filtered = typeof pkg === "object";
|
|
246
|
+
const display = filtered ? `${source} (filtered)` : source;
|
|
247
|
+
console.log(` ${display}`);
|
|
248
|
+
const path = packageManager.getInstalledPath(source, scope);
|
|
249
|
+
if (path) {
|
|
250
|
+
console.log(chalk.dim(` ${path}`));
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
if (globalPackages.length > 0) {
|
|
254
|
+
console.log(chalk.bold("User packages:"));
|
|
255
|
+
for (const pkg of globalPackages) {
|
|
256
|
+
formatPackage(pkg, "user");
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (projectPackages.length > 0) {
|
|
260
|
+
if (globalPackages.length > 0)
|
|
261
|
+
console.log();
|
|
262
|
+
console.log(chalk.bold("Project packages:"));
|
|
263
|
+
for (const pkg of projectPackages) {
|
|
264
|
+
formatPackage(pkg, "project");
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
case "update":
|
|
270
|
+
await packageManager.update(source);
|
|
271
|
+
if (source) {
|
|
272
|
+
console.log(chalk.green(`Updated ${source}`));
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
console.log(chalk.green("Updated packages"));
|
|
276
|
+
}
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
const message = error instanceof Error ? error.message : "Unknown package command error";
|
|
282
|
+
console.error(chalk.red(`Error: ${message}`));
|
|
283
|
+
process.exitCode = 1;
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
function getLastAssistantMessage(sessionMessages) {
|
|
288
|
+
for (let index = sessionMessages.length - 1; index >= 0; index--) {
|
|
289
|
+
const message = sessionMessages[index];
|
|
290
|
+
if (message.role === "assistant") {
|
|
291
|
+
return message;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
async function runIosmInitAgentVerification(targetDir, result) {
|
|
297
|
+
if (!result.cycle) {
|
|
298
|
+
return {
|
|
299
|
+
completed: false,
|
|
300
|
+
skippedReason: "No cycle scaffold was available for verification.",
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
const cycleId = result.cycle.cycleId;
|
|
304
|
+
// Always enable full trace for this one-shot verifier session.
|
|
305
|
+
process.env[ENV_SESSION_TRACE] = "1";
|
|
306
|
+
process.env.PI_SESSION_TRACE = "1";
|
|
307
|
+
const agentDir = getAgentDir();
|
|
308
|
+
const settingsManager = SettingsManager.create(targetDir, agentDir);
|
|
309
|
+
reportSettingsErrors(settingsManager, "iosm init verify");
|
|
310
|
+
const authStorage = AuthStorage.create();
|
|
311
|
+
const modelRegistry = new ModelRegistry(authStorage, getModelsPath());
|
|
312
|
+
const resourceLoader = new DefaultResourceLoader({
|
|
313
|
+
cwd: targetDir,
|
|
314
|
+
agentDir,
|
|
315
|
+
settingsManager,
|
|
316
|
+
contextProfile: "iosm",
|
|
317
|
+
noExtensions: true,
|
|
318
|
+
});
|
|
319
|
+
await resourceLoader.reload();
|
|
320
|
+
const { session, modelFallbackMessage } = await createAgentSession({
|
|
321
|
+
cwd: targetDir,
|
|
322
|
+
sessionManager: SessionManager.inMemory(),
|
|
323
|
+
settingsManager,
|
|
324
|
+
authStorage,
|
|
325
|
+
modelRegistry,
|
|
326
|
+
resourceLoader,
|
|
327
|
+
});
|
|
328
|
+
let toolExecutions = 0;
|
|
329
|
+
const unsubscribe = session.subscribe((event) => {
|
|
330
|
+
if (event.type !== "tool_execution_start") {
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
toolExecutions += 1;
|
|
334
|
+
if (event.toolName === "bash") {
|
|
335
|
+
const commandRaw = event.args && typeof event.args === "object" && "command" in event.args
|
|
336
|
+
? String(event.args.command ?? "")
|
|
337
|
+
: "";
|
|
338
|
+
const preview = commandRaw.replace(/\s+/g, " ").trim().slice(0, 68);
|
|
339
|
+
console.log(chalk.dim(`verify> bash #${toolExecutions}${preview ? ` ${preview}${commandRaw.length > 68 ? "..." : ""}` : ""}`));
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
console.log(chalk.dim(`verify> ${event.toolName} #${toolExecutions}`));
|
|
343
|
+
});
|
|
344
|
+
try {
|
|
345
|
+
if (!session.model) {
|
|
346
|
+
return {
|
|
347
|
+
completed: false,
|
|
348
|
+
skippedReason: modelFallbackMessage ??
|
|
349
|
+
"No model available for agent verification. Configure /login or an API key, then re-run init.",
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
const verificationPrompt = buildIosmAgentVerificationPrompt(result);
|
|
353
|
+
const timeoutMs = 180_000;
|
|
354
|
+
const startedAt = Date.now();
|
|
355
|
+
const heartbeatMs = 10_000;
|
|
356
|
+
let timeoutHandle;
|
|
357
|
+
let heartbeatHandle;
|
|
358
|
+
try {
|
|
359
|
+
console.log(chalk.dim("verify> waiting for model response..."));
|
|
360
|
+
heartbeatHandle = setInterval(() => {
|
|
361
|
+
const elapsedSec = Math.round((Date.now() - startedAt) / 1000);
|
|
362
|
+
if (toolExecutions === 0) {
|
|
363
|
+
console.log(chalk.dim(`verify> waiting for model response... ${elapsedSec}s`));
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
console.log(chalk.dim(`verify> running... ${elapsedSec}s, tool calls=${toolExecutions}`));
|
|
367
|
+
}, heartbeatMs);
|
|
368
|
+
await Promise.race([
|
|
369
|
+
session.prompt(verificationPrompt, {
|
|
370
|
+
expandPromptTemplates: false,
|
|
371
|
+
skipIosmAutopilot: true,
|
|
372
|
+
source: "interactive",
|
|
373
|
+
}),
|
|
374
|
+
new Promise((_resolve, reject) => {
|
|
375
|
+
timeoutHandle = setTimeout(() => {
|
|
376
|
+
reject(new Error(`Verifier timeout after ${Math.round(timeoutMs / 1000)}s.`));
|
|
377
|
+
}, timeoutMs);
|
|
378
|
+
}),
|
|
379
|
+
]);
|
|
380
|
+
}
|
|
381
|
+
finally {
|
|
382
|
+
if (timeoutHandle) {
|
|
383
|
+
clearTimeout(timeoutHandle);
|
|
384
|
+
}
|
|
385
|
+
if (heartbeatHandle) {
|
|
386
|
+
clearInterval(heartbeatHandle);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
const lastAssistant = getLastAssistantMessage(session.state.messages);
|
|
390
|
+
if (lastAssistant &&
|
|
391
|
+
(lastAssistant.stopReason === "error" || lastAssistant.stopReason === "aborted")) {
|
|
392
|
+
return {
|
|
393
|
+
completed: false,
|
|
394
|
+
error: lastAssistant.errorMessage ?? `Verifier finished with ${lastAssistant.stopReason}.`,
|
|
395
|
+
tracePath: session.sessionTracePath ??
|
|
396
|
+
(isSessionTraceEnabled() ? getSessionTracePath(session.sessionManager.getSessionId()) : undefined),
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
let authoredGuide;
|
|
400
|
+
try {
|
|
401
|
+
console.log(chalk.dim("verify> authoring IOSM.md from repository evidence..."));
|
|
402
|
+
await session.prompt(buildIosmGuideAuthoringPrompt(result), {
|
|
403
|
+
expandPromptTemplates: false,
|
|
404
|
+
skipIosmAutopilot: true,
|
|
405
|
+
source: "interactive",
|
|
406
|
+
});
|
|
407
|
+
const guideAssistant = getLastAssistantMessage(session.state.messages);
|
|
408
|
+
const guideText = extractAssistantText(guideAssistant);
|
|
409
|
+
const normalizedGuide = normalizeIosmGuideMarkdown(guideText);
|
|
410
|
+
if (normalizedGuide.trim().length > 0) {
|
|
411
|
+
authoredGuide = normalizedGuide;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
catch {
|
|
415
|
+
console.log(chalk.dim("verify> IOSM.md authoring failed; using structured fallback"));
|
|
416
|
+
}
|
|
417
|
+
let current;
|
|
418
|
+
let guidePath;
|
|
419
|
+
try {
|
|
420
|
+
const report = readIosmCycleReport(targetDir, cycleId);
|
|
421
|
+
current = createMetricSnapshot(report);
|
|
422
|
+
if (authoredGuide) {
|
|
423
|
+
guidePath = getIosmGuidePath(targetDir);
|
|
424
|
+
writeFileSync(guidePath, authoredGuide, "utf8");
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
guidePath = writeIosmGuideDocument({
|
|
428
|
+
rootDir: targetDir,
|
|
429
|
+
cycleId,
|
|
430
|
+
assessmentSource: "verified",
|
|
431
|
+
metrics: report.metrics,
|
|
432
|
+
iosmIndex: report.iosm_index,
|
|
433
|
+
decisionConfidence: report.decision_confidence,
|
|
434
|
+
goals: report.goals,
|
|
435
|
+
filesAnalyzed: result.analysis.files_analyzed,
|
|
436
|
+
sourceFileCount: result.analysis.source_file_count,
|
|
437
|
+
testFileCount: result.analysis.test_file_count,
|
|
438
|
+
docFileCount: result.analysis.doc_file_count,
|
|
439
|
+
}, true).path;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
catch {
|
|
443
|
+
current = undefined;
|
|
444
|
+
guidePath = undefined;
|
|
445
|
+
}
|
|
446
|
+
let historyPath;
|
|
447
|
+
try {
|
|
448
|
+
const history = recordIosmCycleHistory(targetDir, cycleId);
|
|
449
|
+
historyPath = history.historyPath;
|
|
450
|
+
}
|
|
451
|
+
catch {
|
|
452
|
+
historyPath = undefined;
|
|
453
|
+
}
|
|
454
|
+
return {
|
|
455
|
+
completed: true,
|
|
456
|
+
current,
|
|
457
|
+
historyPath,
|
|
458
|
+
guidePath,
|
|
459
|
+
toolCalls: toolExecutions,
|
|
460
|
+
tracePath: session.sessionTracePath ??
|
|
461
|
+
(isSessionTraceEnabled() ? getSessionTracePath(session.sessionManager.getSessionId()) : undefined),
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
catch (error) {
|
|
465
|
+
return {
|
|
466
|
+
completed: false,
|
|
467
|
+
error: error instanceof Error ? error.message : String(error),
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
finally {
|
|
471
|
+
unsubscribe();
|
|
472
|
+
session.dispose();
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
function printIosmInitHelp() {
|
|
476
|
+
console.log(`${chalk.bold("Usage:")}
|
|
477
|
+
${APP_NAME} init [path] [--force] [--no-agent-verify]
|
|
478
|
+
|
|
479
|
+
Initialize IOSM workspace, analyze the project, run verification, and maintain IOSM.md playbook/checklist.
|
|
480
|
+
|
|
481
|
+
Options:
|
|
482
|
+
-f, --force Overwrite scaffold files if they already exist
|
|
483
|
+
--agent-verify Force post-init agent verification (default)
|
|
484
|
+
--no-agent-verify Skip post-init agent verification and keep static baseline only
|
|
485
|
+
|
|
486
|
+
Examples:
|
|
487
|
+
${APP_NAME} init
|
|
488
|
+
${APP_NAME} init .
|
|
489
|
+
${APP_NAME} init ../service-a --force
|
|
490
|
+
${APP_NAME} init --no-agent-verify
|
|
491
|
+
`);
|
|
492
|
+
}
|
|
493
|
+
function parseIosmInitCommand(args) {
|
|
494
|
+
const [command, ...rest] = args;
|
|
495
|
+
if (command !== "init") {
|
|
496
|
+
return undefined;
|
|
497
|
+
}
|
|
498
|
+
let targetDir;
|
|
499
|
+
let force = false;
|
|
500
|
+
let agentVerify = true;
|
|
501
|
+
let help = false;
|
|
502
|
+
let invalidOption;
|
|
503
|
+
let extraArg;
|
|
504
|
+
for (const arg of rest) {
|
|
505
|
+
if (arg === "-h" || arg === "--help") {
|
|
506
|
+
help = true;
|
|
507
|
+
continue;
|
|
508
|
+
}
|
|
509
|
+
if (arg === "-f" || arg === "--force") {
|
|
510
|
+
force = true;
|
|
511
|
+
continue;
|
|
512
|
+
}
|
|
513
|
+
if (arg === "--agent-verify") {
|
|
514
|
+
agentVerify = true;
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
if (arg === "--no-agent-verify" || arg === "--static-only") {
|
|
518
|
+
agentVerify = false;
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
if (arg.startsWith("-")) {
|
|
522
|
+
invalidOption = invalidOption ?? arg;
|
|
523
|
+
continue;
|
|
524
|
+
}
|
|
525
|
+
if (!targetDir) {
|
|
526
|
+
targetDir = arg;
|
|
527
|
+
continue;
|
|
528
|
+
}
|
|
529
|
+
extraArg = extraArg ?? arg;
|
|
530
|
+
}
|
|
531
|
+
return { targetDir, force, agentVerify, help, invalidOption, extraArg };
|
|
532
|
+
}
|
|
533
|
+
async function handleIosmInitCommand(args) {
|
|
534
|
+
const options = parseIosmInitCommand(args);
|
|
535
|
+
if (!options) {
|
|
536
|
+
return false;
|
|
537
|
+
}
|
|
538
|
+
if (options.help) {
|
|
539
|
+
printIosmInitHelp();
|
|
540
|
+
return true;
|
|
541
|
+
}
|
|
542
|
+
if (options.invalidOption) {
|
|
543
|
+
console.error(chalk.red(`Unknown option ${options.invalidOption} for "init".`));
|
|
544
|
+
console.error(chalk.dim(`Use "${APP_NAME} init --help".`));
|
|
545
|
+
process.exitCode = 1;
|
|
546
|
+
return true;
|
|
547
|
+
}
|
|
548
|
+
if (options.extraArg) {
|
|
549
|
+
console.error(chalk.red(`Unexpected argument "${options.extraArg}" for "init".`));
|
|
550
|
+
console.error(chalk.dim(`Use "${APP_NAME} init --help".`));
|
|
551
|
+
process.exitCode = 1;
|
|
552
|
+
return true;
|
|
553
|
+
}
|
|
554
|
+
const targetDir = resolve(options.targetDir ?? process.cwd());
|
|
555
|
+
const result = await initIosmWorkspace({ cwd: targetDir, force: options.force });
|
|
556
|
+
console.log(chalk.green(`Initialized IOSM workspace at ${result.rootDir}`));
|
|
557
|
+
console.log(chalk.dim(`Analyzed ${result.analysis.files_analyzed} files (${result.analysis.source_file_count} source, ${result.analysis.test_file_count} tests, ${result.analysis.doc_file_count} docs)`));
|
|
558
|
+
if (options.agentVerify) {
|
|
559
|
+
console.log(chalk.dim("Initial heuristic baseline captured (internal)."));
|
|
560
|
+
}
|
|
561
|
+
else {
|
|
562
|
+
console.log(chalk.dim(`Heuristic metrics (verification skipped): ${Object.entries(result.analysis.metrics)
|
|
563
|
+
.map(([metric, value]) => `${metric}=${value === null ? "n/a" : value.toFixed(3)}`)
|
|
564
|
+
.join(", ")}`));
|
|
565
|
+
}
|
|
566
|
+
console.log(chalk.dim(`Goals: ${result.analysis.goals.join(" | ")}`));
|
|
567
|
+
if (result.cycle) {
|
|
568
|
+
const cycleLine = result.cycle.reusedExistingCycle
|
|
569
|
+
? `Using existing cycle ${result.cycle.cycleId}`
|
|
570
|
+
: `Seeded cycle ${result.cycle.cycleId}`;
|
|
571
|
+
console.log(chalk.dim(cycleLine));
|
|
572
|
+
}
|
|
573
|
+
let verification;
|
|
574
|
+
if (options.agentVerify) {
|
|
575
|
+
console.log(chalk.dim("\nRunning post-init agent verification pass..."));
|
|
576
|
+
verification = await runIosmInitAgentVerification(targetDir, result);
|
|
577
|
+
if (verification.completed) {
|
|
578
|
+
console.log(chalk.green("Agent verification completed."));
|
|
579
|
+
if (verification.current) {
|
|
580
|
+
console.log(chalk.dim(`Current IOSM snapshot: ${formatMetricSnapshot(verification.current)}`));
|
|
581
|
+
}
|
|
582
|
+
if (verification.historyPath) {
|
|
583
|
+
console.log(chalk.dim(`Metrics history updated: ${verification.historyPath}`));
|
|
584
|
+
}
|
|
585
|
+
if (verification.guidePath) {
|
|
586
|
+
console.log(chalk.dim(`Playbook updated: ${verification.guidePath}`));
|
|
587
|
+
}
|
|
588
|
+
if (verification.toolCalls !== undefined) {
|
|
589
|
+
console.log(chalk.dim(`Verifier activity: ${verification.toolCalls} tool calls`));
|
|
590
|
+
}
|
|
591
|
+
if (verification.tracePath) {
|
|
592
|
+
console.log(chalk.dim(`Session trace: ${verification.tracePath}`));
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
else if (verification.skippedReason) {
|
|
596
|
+
console.log(chalk.yellow(`Agent verification skipped: ${verification.skippedReason}`));
|
|
597
|
+
}
|
|
598
|
+
else if (verification.error) {
|
|
599
|
+
console.log(chalk.red(`Agent verification failed: ${verification.error}`));
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
let currentSnapshot = verification?.current;
|
|
603
|
+
if (!currentSnapshot && result.cycle) {
|
|
604
|
+
try {
|
|
605
|
+
currentSnapshot = createMetricSnapshot(readIosmCycleReport(targetDir, result.cycle.cycleId));
|
|
606
|
+
}
|
|
607
|
+
catch {
|
|
608
|
+
currentSnapshot = undefined;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
currentSnapshot ??= {
|
|
612
|
+
metrics: result.analysis.metrics,
|
|
613
|
+
iosm_index: null,
|
|
614
|
+
decision_confidence: null,
|
|
615
|
+
};
|
|
616
|
+
const checklist = buildIosmPriorityChecklist(currentSnapshot.metrics, 3);
|
|
617
|
+
const guidePath = verification?.guidePath ?? getIosmGuidePath(result.rootDir);
|
|
618
|
+
console.log(chalk.bold("\nInit report:"));
|
|
619
|
+
console.log(` project: ${result.rootDir}`);
|
|
620
|
+
console.log(` metrics: ${formatMetricSnapshot(currentSnapshot)}`);
|
|
621
|
+
console.log(" top priorities:");
|
|
622
|
+
for (const [index, item] of checklist.entries()) {
|
|
623
|
+
console.log(` ${index + 1}. ${item.title} (${item.value === null ? "n/a" : item.value.toFixed(3)}) -> ${item.action}`);
|
|
624
|
+
}
|
|
625
|
+
console.log(" key files:");
|
|
626
|
+
console.log(` playbook: ${guidePath}`);
|
|
627
|
+
console.log(` iosm config: ${result.rootDir}/iosm.yaml`);
|
|
628
|
+
if (result.cycle) {
|
|
629
|
+
console.log(` cycle report: ${result.cycle.reportPath}`);
|
|
630
|
+
console.log(` baseline report: ${result.cycle.baselineReportPath}`);
|
|
631
|
+
}
|
|
632
|
+
if (result.created.length > 0) {
|
|
633
|
+
console.log(chalk.bold("\nCreated:"));
|
|
634
|
+
for (const filePath of result.created) {
|
|
635
|
+
console.log(` ${filePath}`);
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
if (result.overwritten.length > 0) {
|
|
639
|
+
console.log(chalk.bold("\nOverwritten:"));
|
|
640
|
+
for (const filePath of result.overwritten) {
|
|
641
|
+
console.log(` ${filePath}`);
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (result.skipped.length > 0) {
|
|
645
|
+
console.log(chalk.bold("\nSkipped:"));
|
|
646
|
+
for (const filePath of result.skipped) {
|
|
647
|
+
console.log(` ${filePath}`);
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
return true;
|
|
651
|
+
}
|
|
652
|
+
function printIosmCycleHelp() {
|
|
653
|
+
console.log(`${chalk.bold("Usage:")}
|
|
654
|
+
${APP_NAME} cycle list
|
|
655
|
+
${APP_NAME} cycle plan [--id <cycle-id>] [--force] <goal...>
|
|
656
|
+
${APP_NAME} cycle report [cycle-id]
|
|
657
|
+
${APP_NAME} cycle status [cycle-id]
|
|
658
|
+
|
|
659
|
+
Subcommands:
|
|
660
|
+
list List known IOSM cycles
|
|
661
|
+
plan Create a new cycle scaffold with baseline, hypotheses, and report templates
|
|
662
|
+
report Print a synchronized cycle report as JSON (latest by default)
|
|
663
|
+
status Show a human-readable completeness and gate summary for a cycle
|
|
664
|
+
|
|
665
|
+
Examples:
|
|
666
|
+
${APP_NAME} cycle list
|
|
667
|
+
${APP_NAME} cycle plan "reduce checkout latency" "remove redundant admin API"
|
|
668
|
+
${APP_NAME} cycle plan --id iosm-2026-03-06-001 --force "stabilize worker retries"
|
|
669
|
+
${APP_NAME} cycle report
|
|
670
|
+
${APP_NAME} cycle report iosm-2026-03-06-001
|
|
671
|
+
${APP_NAME} cycle status
|
|
672
|
+
`);
|
|
673
|
+
}
|
|
674
|
+
function parseIosmCycleCommand(args) {
|
|
675
|
+
const [command, subcommand, ...rest] = args;
|
|
676
|
+
if (command !== "cycle") {
|
|
677
|
+
return undefined;
|
|
678
|
+
}
|
|
679
|
+
if (!subcommand || subcommand === "-h" || subcommand === "--help") {
|
|
680
|
+
return { kind: "help" };
|
|
681
|
+
}
|
|
682
|
+
if (subcommand === "list") {
|
|
683
|
+
if (rest.some((arg) => arg === "-h" || arg === "--help")) {
|
|
684
|
+
return { kind: "help" };
|
|
685
|
+
}
|
|
686
|
+
if (rest.length > 0) {
|
|
687
|
+
throw new Error(`Unexpected arguments for "cycle list": ${rest.join(" ")}`);
|
|
688
|
+
}
|
|
689
|
+
return { kind: "list" };
|
|
690
|
+
}
|
|
691
|
+
if (subcommand === "plan") {
|
|
692
|
+
let force = false;
|
|
693
|
+
let cycleId;
|
|
694
|
+
const goals = [];
|
|
695
|
+
for (let index = 0; index < rest.length; index++) {
|
|
696
|
+
const arg = rest[index];
|
|
697
|
+
if (arg === "-h" || arg === "--help") {
|
|
698
|
+
return { kind: "help" };
|
|
699
|
+
}
|
|
700
|
+
if (arg === "-f" || arg === "--force") {
|
|
701
|
+
force = true;
|
|
702
|
+
continue;
|
|
703
|
+
}
|
|
704
|
+
if (arg === "--id") {
|
|
705
|
+
if (index + 1 >= rest.length) {
|
|
706
|
+
throw new Error('Missing value for "--id".');
|
|
707
|
+
}
|
|
708
|
+
cycleId = rest[index + 1];
|
|
709
|
+
index += 1;
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
if (arg.startsWith("-")) {
|
|
713
|
+
throw new Error(`Unknown option for "cycle plan": ${arg}`);
|
|
714
|
+
}
|
|
715
|
+
goals.push(arg);
|
|
716
|
+
}
|
|
717
|
+
return { kind: "plan", goals, force, cycleId };
|
|
718
|
+
}
|
|
719
|
+
if (subcommand === "report") {
|
|
720
|
+
let cycleId;
|
|
721
|
+
for (let index = 0; index < rest.length; index++) {
|
|
722
|
+
const arg = rest[index];
|
|
723
|
+
if (arg === "-h" || arg === "--help") {
|
|
724
|
+
return { kind: "help" };
|
|
725
|
+
}
|
|
726
|
+
if (arg.startsWith("-")) {
|
|
727
|
+
throw new Error(`Unknown option for "cycle report": ${arg}`);
|
|
728
|
+
}
|
|
729
|
+
if (!cycleId) {
|
|
730
|
+
cycleId = arg;
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
throw new Error(`Unexpected argument for "cycle report": ${arg}`);
|
|
734
|
+
}
|
|
735
|
+
return { kind: "report", cycleId };
|
|
736
|
+
}
|
|
737
|
+
if (subcommand === "status") {
|
|
738
|
+
let cycleId;
|
|
739
|
+
for (let index = 0; index < rest.length; index++) {
|
|
740
|
+
const arg = rest[index];
|
|
741
|
+
if (arg === "-h" || arg === "--help") {
|
|
742
|
+
return { kind: "help" };
|
|
743
|
+
}
|
|
744
|
+
if (arg.startsWith("-")) {
|
|
745
|
+
throw new Error(`Unknown option for "cycle status": ${arg}`);
|
|
746
|
+
}
|
|
747
|
+
if (!cycleId) {
|
|
748
|
+
cycleId = arg;
|
|
749
|
+
continue;
|
|
750
|
+
}
|
|
751
|
+
throw new Error(`Unexpected argument for "cycle status": ${arg}`);
|
|
752
|
+
}
|
|
753
|
+
return { kind: "status", cycleId };
|
|
754
|
+
}
|
|
755
|
+
throw new Error(`Unknown cycle subcommand: ${subcommand}`);
|
|
756
|
+
}
|
|
757
|
+
function printIosmCycleStatus(cycleId, status) {
|
|
758
|
+
console.log(`${chalk.bold("Cycle:")} ${cycleId}`);
|
|
759
|
+
console.log(`${chalk.bold("Status:")} ${status.status}`);
|
|
760
|
+
console.log(`${chalk.bold("Decision:")} ${status.decision}`);
|
|
761
|
+
console.log(`${chalk.bold("Report:")} ${status.reportPath}`);
|
|
762
|
+
console.log(`${chalk.bold("Capacity:")} ${status.capacityPass ? "pass" : "fail"}`);
|
|
763
|
+
console.log(`${chalk.bold("Guardrails:")} ${status.guardrailsPass === null ? "pending" : status.guardrailsPass ? "pass" : "fail"}`);
|
|
764
|
+
console.log(`${chalk.bold("Report Complete:")} ${status.reportComplete ? "yes" : "no"}`);
|
|
765
|
+
console.log(`${chalk.bold("Learning Closed:")} ${status.learningClosed ? "yes" : "no"}`);
|
|
766
|
+
console.log(`${chalk.bold("History Recorded:")} ${status.historyRecorded ? "yes" : "no"}`);
|
|
767
|
+
if (status.blockingIssues.length > 0) {
|
|
768
|
+
console.log(chalk.bold("\nBlocking Issues:"));
|
|
769
|
+
for (const issue of status.blockingIssues) {
|
|
770
|
+
console.log(` - ${issue}`);
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
if (status.warnings.length > 0) {
|
|
774
|
+
console.log(chalk.bold("\nWarnings:"));
|
|
775
|
+
for (const warning of status.warnings) {
|
|
776
|
+
console.log(` - ${warning}`);
|
|
777
|
+
}
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
async function handleIosmCycleCommand(args) {
|
|
781
|
+
let command;
|
|
782
|
+
try {
|
|
783
|
+
command = parseIosmCycleCommand(args);
|
|
784
|
+
}
|
|
785
|
+
catch (error) {
|
|
786
|
+
const message = error instanceof Error ? error.message : "Invalid cycle command";
|
|
787
|
+
console.error(chalk.red(message));
|
|
788
|
+
console.error(chalk.dim(`Use "${APP_NAME} cycle --help".`));
|
|
789
|
+
process.exitCode = 1;
|
|
790
|
+
return true;
|
|
791
|
+
}
|
|
792
|
+
if (!command) {
|
|
793
|
+
return false;
|
|
794
|
+
}
|
|
795
|
+
if (command.kind === "help") {
|
|
796
|
+
printIosmCycleHelp();
|
|
797
|
+
return true;
|
|
798
|
+
}
|
|
799
|
+
try {
|
|
800
|
+
switch (command.kind) {
|
|
801
|
+
case "list": {
|
|
802
|
+
const cycles = listIosmCycles();
|
|
803
|
+
if (cycles.length === 0) {
|
|
804
|
+
console.log(chalk.dim("No IOSM cycles found."));
|
|
805
|
+
return true;
|
|
806
|
+
}
|
|
807
|
+
for (const cycle of cycles) {
|
|
808
|
+
const goals = cycle.goals.length > 0 ? cycle.goals.join("; ") : "no goals recorded";
|
|
809
|
+
console.log(`${cycle.cycleId} ${cycle.status} ${cycle.decision}`);
|
|
810
|
+
console.log(chalk.dim(` ${goals}`));
|
|
811
|
+
}
|
|
812
|
+
return true;
|
|
813
|
+
}
|
|
814
|
+
case "plan": {
|
|
815
|
+
const planned = planIosmCycle({
|
|
816
|
+
goals: command.goals,
|
|
817
|
+
force: command.force,
|
|
818
|
+
cycleId: command.cycleId,
|
|
819
|
+
});
|
|
820
|
+
console.log(chalk.green(`Planned IOSM cycle ${planned.cycleId}`));
|
|
821
|
+
console.log(` ${planned.cycleDir}`);
|
|
822
|
+
console.log(chalk.dim(` baseline: ${planned.baselineReportPath}`));
|
|
823
|
+
console.log(chalk.dim(` hypotheses: ${planned.hypothesesPath}`));
|
|
824
|
+
console.log(chalk.dim(` report: ${planned.reportPath}`));
|
|
825
|
+
return true;
|
|
826
|
+
}
|
|
827
|
+
case "report": {
|
|
828
|
+
const report = readIosmCycleReport(process.cwd(), command.cycleId);
|
|
829
|
+
console.log(JSON.stringify(report, null, 2));
|
|
830
|
+
return true;
|
|
831
|
+
}
|
|
832
|
+
case "status": {
|
|
833
|
+
const status = inspectIosmCycle(process.cwd(), command.cycleId);
|
|
834
|
+
printIosmCycleStatus(status.cycleId, status);
|
|
835
|
+
return true;
|
|
836
|
+
}
|
|
837
|
+
default:
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
catch (error) {
|
|
842
|
+
const message = error instanceof Error ? error.message : "Cycle command failed";
|
|
843
|
+
console.error(chalk.red(`Error: ${message}`));
|
|
844
|
+
process.exitCode = 1;
|
|
845
|
+
return true;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
async function prepareInitialMessage(parsed, autoResizeImages) {
|
|
849
|
+
if (parsed.fileArgs.length === 0) {
|
|
850
|
+
return {};
|
|
851
|
+
}
|
|
852
|
+
const { text, images } = await processFileArguments(parsed.fileArgs, { autoResizeImages });
|
|
853
|
+
let initialMessage;
|
|
854
|
+
if (parsed.messages.length > 0) {
|
|
855
|
+
initialMessage = text + parsed.messages[0];
|
|
856
|
+
parsed.messages.shift();
|
|
857
|
+
}
|
|
858
|
+
else {
|
|
859
|
+
initialMessage = text;
|
|
860
|
+
}
|
|
861
|
+
return {
|
|
862
|
+
initialMessage,
|
|
863
|
+
initialImages: images.length > 0 ? images : undefined,
|
|
864
|
+
};
|
|
865
|
+
}
|
|
866
|
+
/**
|
|
867
|
+
* Resolve a session argument to a file path.
|
|
868
|
+
* If it looks like a path, use as-is. Otherwise try to match as session ID prefix.
|
|
869
|
+
*/
|
|
870
|
+
async function resolveSessionPath(sessionArg, cwd, sessionDir) {
|
|
871
|
+
// If it looks like a file path, use as-is
|
|
872
|
+
if (sessionArg.includes("/") || sessionArg.includes("\\") || sessionArg.endsWith(".jsonl")) {
|
|
873
|
+
return { type: "path", path: sessionArg };
|
|
874
|
+
}
|
|
875
|
+
// Try to match as session ID in current project first
|
|
876
|
+
const localSessions = await SessionManager.list(cwd, sessionDir);
|
|
877
|
+
const localMatches = localSessions.filter((s) => s.id.startsWith(sessionArg));
|
|
878
|
+
if (localMatches.length >= 1) {
|
|
879
|
+
return { type: "local", path: localMatches[0].path };
|
|
880
|
+
}
|
|
881
|
+
// Try global search across all projects
|
|
882
|
+
const allSessions = await SessionManager.listAll();
|
|
883
|
+
const globalMatches = allSessions.filter((s) => s.id.startsWith(sessionArg));
|
|
884
|
+
if (globalMatches.length >= 1) {
|
|
885
|
+
const match = globalMatches[0];
|
|
886
|
+
return { type: "global", path: match.path, cwd: match.cwd };
|
|
887
|
+
}
|
|
888
|
+
// Not found anywhere
|
|
889
|
+
return { type: "not_found", arg: sessionArg };
|
|
890
|
+
}
|
|
891
|
+
/** Prompt user for yes/no confirmation */
|
|
892
|
+
async function promptConfirm(message) {
|
|
893
|
+
return new Promise((resolve) => {
|
|
894
|
+
const rl = createInterface({
|
|
895
|
+
input: process.stdin,
|
|
896
|
+
output: process.stdout,
|
|
897
|
+
});
|
|
898
|
+
rl.question(`${message} [y/N] `, (answer) => {
|
|
899
|
+
rl.close();
|
|
900
|
+
resolve(answer.toLowerCase() === "y" || answer.toLowerCase() === "yes");
|
|
901
|
+
});
|
|
902
|
+
});
|
|
903
|
+
}
|
|
904
|
+
async function createSessionManager(parsed, cwd) {
|
|
905
|
+
if (parsed.noSession) {
|
|
906
|
+
return SessionManager.inMemory();
|
|
907
|
+
}
|
|
908
|
+
if (parsed.session) {
|
|
909
|
+
const resolved = await resolveSessionPath(parsed.session, cwd, parsed.sessionDir);
|
|
910
|
+
switch (resolved.type) {
|
|
911
|
+
case "path":
|
|
912
|
+
case "local":
|
|
913
|
+
return SessionManager.open(resolved.path, parsed.sessionDir);
|
|
914
|
+
case "global": {
|
|
915
|
+
// Session found in different project - ask user if they want to fork
|
|
916
|
+
console.log(chalk.yellow(`Session found in different project: ${resolved.cwd}`));
|
|
917
|
+
const shouldFork = await promptConfirm("Fork this session into current directory?");
|
|
918
|
+
if (!shouldFork) {
|
|
919
|
+
console.log(chalk.dim("Aborted."));
|
|
920
|
+
process.exit(0);
|
|
921
|
+
}
|
|
922
|
+
return SessionManager.forkFrom(resolved.path, cwd, parsed.sessionDir);
|
|
923
|
+
}
|
|
924
|
+
case "not_found":
|
|
925
|
+
console.error(chalk.red(`No session found matching '${resolved.arg}'`));
|
|
926
|
+
process.exit(1);
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
if (parsed.continue) {
|
|
930
|
+
return SessionManager.continueRecent(cwd, parsed.sessionDir);
|
|
931
|
+
}
|
|
932
|
+
// --resume is handled separately (needs picker UI)
|
|
933
|
+
// If --session-dir provided without --continue/--resume, create new session there
|
|
934
|
+
if (parsed.sessionDir) {
|
|
935
|
+
return SessionManager.create(cwd, parsed.sessionDir);
|
|
936
|
+
}
|
|
937
|
+
// Default case (new session) returns undefined, SDK will create one
|
|
938
|
+
return undefined;
|
|
939
|
+
}
|
|
940
|
+
function buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry) {
|
|
941
|
+
const options = {};
|
|
942
|
+
let cliThinkingFromModel = false;
|
|
943
|
+
if (sessionManager) {
|
|
944
|
+
options.sessionManager = sessionManager;
|
|
945
|
+
}
|
|
946
|
+
// Model from CLI
|
|
947
|
+
// - supports --provider <name> --model <pattern>
|
|
948
|
+
// - supports --model <provider>/<pattern>
|
|
949
|
+
if (parsed.model) {
|
|
950
|
+
const resolved = resolveCliModel({
|
|
951
|
+
cliProvider: parsed.provider,
|
|
952
|
+
cliModel: parsed.model,
|
|
953
|
+
modelRegistry,
|
|
954
|
+
});
|
|
955
|
+
if (resolved.warning) {
|
|
956
|
+
console.warn(chalk.yellow(`Warning: ${resolved.warning}`));
|
|
957
|
+
}
|
|
958
|
+
if (resolved.error) {
|
|
959
|
+
console.error(chalk.red(resolved.error));
|
|
960
|
+
process.exit(1);
|
|
961
|
+
}
|
|
962
|
+
if (resolved.model) {
|
|
963
|
+
options.model = resolved.model;
|
|
964
|
+
// Allow "--model <pattern>:<thinking>" as a shorthand.
|
|
965
|
+
// Explicit --thinking still takes precedence (applied later).
|
|
966
|
+
if (!parsed.thinking && resolved.thinkingLevel) {
|
|
967
|
+
options.thinkingLevel = resolved.thinkingLevel;
|
|
968
|
+
cliThinkingFromModel = true;
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
// Thinking level from CLI (takes precedence over scoped model thinking levels set above)
|
|
973
|
+
if (parsed.thinking) {
|
|
974
|
+
options.thinkingLevel = parsed.thinking;
|
|
975
|
+
}
|
|
976
|
+
// Scoped models for Ctrl+P cycling
|
|
977
|
+
// Keep thinking level undefined when not explicitly set in the model pattern.
|
|
978
|
+
// Undefined means "inherit current session thinking level" during cycling.
|
|
979
|
+
if (scopedModels.length > 0) {
|
|
980
|
+
options.scopedModels = scopedModels.map((sm) => ({
|
|
981
|
+
model: sm.model,
|
|
982
|
+
thinkingLevel: sm.thinkingLevel,
|
|
983
|
+
}));
|
|
984
|
+
}
|
|
985
|
+
// API key from CLI - set in authStorage
|
|
986
|
+
// (handled by caller before createAgentSession)
|
|
987
|
+
// Tools
|
|
988
|
+
if (parsed.noTools) {
|
|
989
|
+
// --no-tools: start with no built-in tools
|
|
990
|
+
// --tools can still add specific ones back
|
|
991
|
+
if (parsed.tools && parsed.tools.length > 0) {
|
|
992
|
+
options.tools = parsed.tools.map((name) => allTools[name]);
|
|
993
|
+
}
|
|
994
|
+
else {
|
|
995
|
+
options.tools = [];
|
|
996
|
+
}
|
|
997
|
+
}
|
|
998
|
+
else if (parsed.tools) {
|
|
999
|
+
options.tools = parsed.tools.map((name) => allTools[name]);
|
|
1000
|
+
}
|
|
1001
|
+
// Agent profile: --profile overrides tool set and thinking level
|
|
1002
|
+
// --plan is shorthand for --profile plan
|
|
1003
|
+
if (parsed.plan && !parsed.profile) {
|
|
1004
|
+
options.profile = "plan";
|
|
1005
|
+
}
|
|
1006
|
+
else if (parsed.profile) {
|
|
1007
|
+
if (!isValidProfileName(parsed.profile)) {
|
|
1008
|
+
console.error(chalk.yellow(`Warning: Unknown profile "${parsed.profile}". Valid profiles: ${getProfileNames().join(", ")}`));
|
|
1009
|
+
}
|
|
1010
|
+
else {
|
|
1011
|
+
options.profile = parsed.profile;
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
return { options, cliThinkingFromModel };
|
|
1015
|
+
}
|
|
1016
|
+
async function handleConfigCommand(args) {
|
|
1017
|
+
if (args[0] !== "config") {
|
|
1018
|
+
return false;
|
|
1019
|
+
}
|
|
1020
|
+
const cwd = process.cwd();
|
|
1021
|
+
const agentDir = getAgentDir();
|
|
1022
|
+
const settingsManager = SettingsManager.create(cwd, agentDir);
|
|
1023
|
+
reportSettingsErrors(settingsManager, "config command");
|
|
1024
|
+
const packageManager = new DefaultPackageManager({ cwd, agentDir, settingsManager });
|
|
1025
|
+
const resolvedPaths = await packageManager.resolve();
|
|
1026
|
+
await selectConfig({
|
|
1027
|
+
resolvedPaths,
|
|
1028
|
+
settingsManager,
|
|
1029
|
+
cwd,
|
|
1030
|
+
agentDir,
|
|
1031
|
+
});
|
|
1032
|
+
process.exit(0);
|
|
1033
|
+
}
|
|
1034
|
+
function printMcpConfigWarnings(errors) {
|
|
1035
|
+
for (const error of errors) {
|
|
1036
|
+
console.error(chalk.yellow(`Warning: ${error}`));
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
function formatMcpServerLine(server) {
|
|
1040
|
+
const state = server.enabled ? "enabled" : "disabled";
|
|
1041
|
+
const endpoint = server.transport === "stdio"
|
|
1042
|
+
? `${server.command ?? "(missing command)"}${server.args.length > 0 ? ` ${server.args.join(" ")}` : ""}`
|
|
1043
|
+
: server.url ?? "(missing url)";
|
|
1044
|
+
return `${chalk.bold(server.name)} (${server.scope}, ${server.transport}, ${state})\n ${chalk.dim(endpoint)}`;
|
|
1045
|
+
}
|
|
1046
|
+
async function handleMcpCommand(args) {
|
|
1047
|
+
if (args[0] !== "mcp") {
|
|
1048
|
+
return false;
|
|
1049
|
+
}
|
|
1050
|
+
const cwd = process.cwd();
|
|
1051
|
+
const agentDir = getAgentDir();
|
|
1052
|
+
const subcommand = args[1] ?? "list";
|
|
1053
|
+
const rest = args.slice(2);
|
|
1054
|
+
const printHelp = () => console.log(getMcpCommandHelp(`${APP_NAME} mcp`));
|
|
1055
|
+
if (subcommand === "help" || subcommand === "-h" || subcommand === "--help") {
|
|
1056
|
+
printHelp();
|
|
1057
|
+
return true;
|
|
1058
|
+
}
|
|
1059
|
+
if (subcommand === "list") {
|
|
1060
|
+
const merged = loadMergedMcpConfig(cwd, agentDir);
|
|
1061
|
+
printMcpConfigWarnings(merged.errors);
|
|
1062
|
+
if (merged.servers.length === 0) {
|
|
1063
|
+
console.log(chalk.dim("No MCP servers configured. Use `iosm mcp add ...`."));
|
|
1064
|
+
return true;
|
|
1065
|
+
}
|
|
1066
|
+
for (const server of merged.servers) {
|
|
1067
|
+
console.log(formatMcpServerLine(server));
|
|
1068
|
+
}
|
|
1069
|
+
return true;
|
|
1070
|
+
}
|
|
1071
|
+
if (subcommand === "get") {
|
|
1072
|
+
const parsed = parseMcpTargetCommand(rest, "all");
|
|
1073
|
+
if (!parsed.ok) {
|
|
1074
|
+
if ("help" in parsed) {
|
|
1075
|
+
printHelp();
|
|
1076
|
+
return true;
|
|
1077
|
+
}
|
|
1078
|
+
console.error(chalk.red(parsed.error));
|
|
1079
|
+
process.exitCode = 1;
|
|
1080
|
+
return true;
|
|
1081
|
+
}
|
|
1082
|
+
const server = getMergedServerByName(parsed.value.name, cwd, agentDir);
|
|
1083
|
+
if (!server) {
|
|
1084
|
+
console.error(chalk.red(`MCP server "${parsed.value.name}" not found.`));
|
|
1085
|
+
process.exitCode = 1;
|
|
1086
|
+
return true;
|
|
1087
|
+
}
|
|
1088
|
+
console.log(JSON.stringify(server, null, 2));
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
const runtime = new McpRuntime({
|
|
1092
|
+
cwd,
|
|
1093
|
+
agentDir,
|
|
1094
|
+
clientName: APP_NAME,
|
|
1095
|
+
clientVersion: VERSION,
|
|
1096
|
+
});
|
|
1097
|
+
try {
|
|
1098
|
+
if (subcommand === "add") {
|
|
1099
|
+
const parsed = parseMcpAddCommand(rest);
|
|
1100
|
+
if (!parsed.ok) {
|
|
1101
|
+
if ("help" in parsed) {
|
|
1102
|
+
printHelp();
|
|
1103
|
+
return true;
|
|
1104
|
+
}
|
|
1105
|
+
console.error(chalk.red(parsed.error));
|
|
1106
|
+
process.exitCode = 1;
|
|
1107
|
+
return true;
|
|
1108
|
+
}
|
|
1109
|
+
const path = await runtime.addServer(parsed.value.name, parsed.value.scope, parsed.value.config);
|
|
1110
|
+
const status = runtime.getServer(parsed.value.name);
|
|
1111
|
+
console.log(chalk.green(`Added MCP server "${parsed.value.name}" to ${parsed.value.scope} scope.`));
|
|
1112
|
+
console.log(chalk.dim(`Config: ${path}`));
|
|
1113
|
+
if (status?.state === "connected") {
|
|
1114
|
+
console.log(chalk.dim(`Connected: ${status.toolCount} tool(s)`));
|
|
1115
|
+
}
|
|
1116
|
+
else if (status?.state === "error") {
|
|
1117
|
+
console.log(chalk.yellow(`Connection warning: ${status.error ?? "unknown error"}`));
|
|
1118
|
+
}
|
|
1119
|
+
printMcpConfigWarnings(runtime.getErrors());
|
|
1120
|
+
return true;
|
|
1121
|
+
}
|
|
1122
|
+
if (subcommand === "remove") {
|
|
1123
|
+
const parsed = parseMcpTargetCommand(rest, "all");
|
|
1124
|
+
if (!parsed.ok) {
|
|
1125
|
+
if ("help" in parsed) {
|
|
1126
|
+
printHelp();
|
|
1127
|
+
return true;
|
|
1128
|
+
}
|
|
1129
|
+
console.error(chalk.red(parsed.error));
|
|
1130
|
+
process.exitCode = 1;
|
|
1131
|
+
return true;
|
|
1132
|
+
}
|
|
1133
|
+
const removed = await runtime.removeServer(parsed.value.name, parsed.value.scope);
|
|
1134
|
+
if (removed.length === 0) {
|
|
1135
|
+
console.error(chalk.red(`MCP server "${parsed.value.name}" not found.`));
|
|
1136
|
+
process.exitCode = 1;
|
|
1137
|
+
return true;
|
|
1138
|
+
}
|
|
1139
|
+
console.log(chalk.green(`Removed MCP server "${parsed.value.name}" from ${removed.join(", ")} scope.`));
|
|
1140
|
+
printMcpConfigWarnings(runtime.getErrors());
|
|
1141
|
+
return true;
|
|
1142
|
+
}
|
|
1143
|
+
if (subcommand === "enable" || subcommand === "disable") {
|
|
1144
|
+
const parsed = parseMcpTargetCommand(rest, "all");
|
|
1145
|
+
if (!parsed.ok) {
|
|
1146
|
+
if ("help" in parsed) {
|
|
1147
|
+
printHelp();
|
|
1148
|
+
return true;
|
|
1149
|
+
}
|
|
1150
|
+
console.error(chalk.red(parsed.error));
|
|
1151
|
+
process.exitCode = 1;
|
|
1152
|
+
return true;
|
|
1153
|
+
}
|
|
1154
|
+
const enabled = subcommand === "enable";
|
|
1155
|
+
let updatedScope;
|
|
1156
|
+
if (parsed.value.scope === "all") {
|
|
1157
|
+
updatedScope =
|
|
1158
|
+
(await runtime.setServerEnabled(parsed.value.name, enabled, "project")) ??
|
|
1159
|
+
(await runtime.setServerEnabled(parsed.value.name, enabled, "user"));
|
|
1160
|
+
}
|
|
1161
|
+
else {
|
|
1162
|
+
updatedScope = await runtime.setServerEnabled(parsed.value.name, enabled, parsed.value.scope);
|
|
1163
|
+
}
|
|
1164
|
+
if (!updatedScope) {
|
|
1165
|
+
console.error(chalk.red(`MCP server "${parsed.value.name}" not found.`));
|
|
1166
|
+
process.exitCode = 1;
|
|
1167
|
+
return true;
|
|
1168
|
+
}
|
|
1169
|
+
console.log(chalk.green(`${enabled ? "Enabled" : "Disabled"} MCP server "${parsed.value.name}" (${updatedScope}).`));
|
|
1170
|
+
printMcpConfigWarnings(runtime.getErrors());
|
|
1171
|
+
return true;
|
|
1172
|
+
}
|
|
1173
|
+
if (subcommand === "tools") {
|
|
1174
|
+
await runtime.refresh();
|
|
1175
|
+
printMcpConfigWarnings(runtime.getErrors());
|
|
1176
|
+
const serverName = rest[0];
|
|
1177
|
+
const statuses = runtime.getServers();
|
|
1178
|
+
const targets = serverName ? statuses.filter((server) => server.name === serverName) : statuses;
|
|
1179
|
+
if (targets.length === 0) {
|
|
1180
|
+
console.error(chalk.red(serverName ? `MCP server "${serverName}" not found.` : "No MCP servers configured."));
|
|
1181
|
+
process.exitCode = 1;
|
|
1182
|
+
return true;
|
|
1183
|
+
}
|
|
1184
|
+
for (const server of targets) {
|
|
1185
|
+
console.log(chalk.bold(`${server.name} (${server.state})`));
|
|
1186
|
+
if (server.state !== "connected") {
|
|
1187
|
+
console.log(chalk.dim(` ${server.error ?? "not connected"}`));
|
|
1188
|
+
continue;
|
|
1189
|
+
}
|
|
1190
|
+
if (server.tools.length === 0) {
|
|
1191
|
+
console.log(chalk.dim(" No tools exposed."));
|
|
1192
|
+
continue;
|
|
1193
|
+
}
|
|
1194
|
+
for (const tool of server.tools) {
|
|
1195
|
+
const aliasSuffix = tool.name === tool.exposedName ? "" : ` -> ${tool.exposedName}`;
|
|
1196
|
+
console.log(` - ${tool.name}${aliasSuffix}`);
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
return true;
|
|
1200
|
+
}
|
|
1201
|
+
if (subcommand === "test") {
|
|
1202
|
+
const parsed = parseMcpTargetCommand(rest, "all");
|
|
1203
|
+
if (!parsed.ok) {
|
|
1204
|
+
if ("help" in parsed) {
|
|
1205
|
+
printHelp();
|
|
1206
|
+
return true;
|
|
1207
|
+
}
|
|
1208
|
+
console.error(chalk.red(parsed.error));
|
|
1209
|
+
process.exitCode = 1;
|
|
1210
|
+
return true;
|
|
1211
|
+
}
|
|
1212
|
+
await runtime.refresh();
|
|
1213
|
+
printMcpConfigWarnings(runtime.getErrors());
|
|
1214
|
+
const status = runtime.getServer(parsed.value.name);
|
|
1215
|
+
if (!status) {
|
|
1216
|
+
console.error(chalk.red(`MCP server "${parsed.value.name}" not found.`));
|
|
1217
|
+
process.exitCode = 1;
|
|
1218
|
+
return true;
|
|
1219
|
+
}
|
|
1220
|
+
if (status.state !== "connected") {
|
|
1221
|
+
console.error(chalk.red(`MCP server "${parsed.value.name}" failed: ${status.error ?? "unknown error"}`));
|
|
1222
|
+
process.exitCode = 1;
|
|
1223
|
+
return true;
|
|
1224
|
+
}
|
|
1225
|
+
console.log(chalk.green(`MCP server "${parsed.value.name}" is connected (${status.toolCount} tool(s)).`));
|
|
1226
|
+
return true;
|
|
1227
|
+
}
|
|
1228
|
+
console.error(chalk.red(`Unknown MCP subcommand "${subcommand}".`));
|
|
1229
|
+
printHelp();
|
|
1230
|
+
process.exitCode = 1;
|
|
1231
|
+
return true;
|
|
1232
|
+
}
|
|
1233
|
+
finally {
|
|
1234
|
+
await runtime.dispose();
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
export async function main(args) {
|
|
1238
|
+
applySessionTraceCliOverrides(args);
|
|
1239
|
+
const offlineMode = args.includes("--offline") || isTruthyEnvFlag(process.env[ENV_OFFLINE]) || isTruthyEnvFlag(process.env.PI_OFFLINE);
|
|
1240
|
+
if (offlineMode) {
|
|
1241
|
+
process.env[ENV_OFFLINE] = "1";
|
|
1242
|
+
process.env[ENV_SKIP_VERSION_CHECK] = "1";
|
|
1243
|
+
process.env.PI_OFFLINE = "1";
|
|
1244
|
+
process.env.PI_SKIP_VERSION_CHECK = "1";
|
|
1245
|
+
}
|
|
1246
|
+
if (await handleIosmInitCommand(args)) {
|
|
1247
|
+
return;
|
|
1248
|
+
}
|
|
1249
|
+
if (await handleIosmCycleCommand(args)) {
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
if (await handlePackageCommand(args)) {
|
|
1253
|
+
return;
|
|
1254
|
+
}
|
|
1255
|
+
if (await handleMcpCommand(args)) {
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1258
|
+
if (await handleConfigCommand(args)) {
|
|
1259
|
+
return;
|
|
1260
|
+
}
|
|
1261
|
+
// Run migrations (pass cwd for project-local migrations)
|
|
1262
|
+
const { migratedAuthProviders: migratedProviders, deprecationWarnings } = runMigrations(process.cwd());
|
|
1263
|
+
// First pass: parse args to get --extension paths
|
|
1264
|
+
const firstPass = parseArgs(args);
|
|
1265
|
+
const firstPassProfile = firstPass.profile ?? (firstPass.plan ? "plan" : "full");
|
|
1266
|
+
const contextProfile = firstPassProfile.toLowerCase() === "iosm" ? "iosm" : "standard";
|
|
1267
|
+
// Early load extensions to discover their CLI flags
|
|
1268
|
+
const cwd = process.cwd();
|
|
1269
|
+
const agentDir = getAgentDir();
|
|
1270
|
+
const settingsManager = SettingsManager.create(cwd, agentDir);
|
|
1271
|
+
reportSettingsErrors(settingsManager, "startup");
|
|
1272
|
+
const authStorage = AuthStorage.create();
|
|
1273
|
+
const modelRegistry = new ModelRegistry(authStorage, getModelsPath());
|
|
1274
|
+
const resourceLoader = new DefaultResourceLoader({
|
|
1275
|
+
cwd,
|
|
1276
|
+
agentDir,
|
|
1277
|
+
settingsManager,
|
|
1278
|
+
contextProfile,
|
|
1279
|
+
additionalExtensionPaths: firstPass.extensions,
|
|
1280
|
+
additionalSkillPaths: firstPass.skills,
|
|
1281
|
+
additionalPromptTemplatePaths: firstPass.promptTemplates,
|
|
1282
|
+
additionalThemePaths: firstPass.themes,
|
|
1283
|
+
noExtensions: firstPass.noExtensions,
|
|
1284
|
+
noSkills: firstPass.noSkills,
|
|
1285
|
+
noPromptTemplates: firstPass.noPromptTemplates,
|
|
1286
|
+
noThemes: firstPass.noThemes,
|
|
1287
|
+
systemPrompt: firstPass.systemPrompt,
|
|
1288
|
+
appendSystemPrompt: firstPass.appendSystemPrompt,
|
|
1289
|
+
});
|
|
1290
|
+
await resourceLoader.reload();
|
|
1291
|
+
time("resourceLoader.reload");
|
|
1292
|
+
const extensionsResult = resourceLoader.getExtensions();
|
|
1293
|
+
for (const { path, error } of extensionsResult.errors) {
|
|
1294
|
+
console.error(chalk.red(`Failed to load extension "${path}": ${error}`));
|
|
1295
|
+
}
|
|
1296
|
+
// Apply pending provider registrations from extensions immediately
|
|
1297
|
+
// so they're available for model resolution before AgentSession is created
|
|
1298
|
+
for (const { name, config } of extensionsResult.runtime.pendingProviderRegistrations) {
|
|
1299
|
+
modelRegistry.registerProvider(name, config);
|
|
1300
|
+
}
|
|
1301
|
+
extensionsResult.runtime.pendingProviderRegistrations = [];
|
|
1302
|
+
const extensionFlags = new Map();
|
|
1303
|
+
for (const ext of extensionsResult.extensions) {
|
|
1304
|
+
for (const [name, flag] of ext.flags) {
|
|
1305
|
+
extensionFlags.set(name, { type: flag.type });
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
// Second pass: parse args with extension flags
|
|
1309
|
+
const parsed = parseArgs(args, extensionFlags);
|
|
1310
|
+
// Pass flag values to extensions via runtime
|
|
1311
|
+
for (const [name, value] of parsed.unknownFlags) {
|
|
1312
|
+
extensionsResult.runtime.flagValues.set(name, value);
|
|
1313
|
+
}
|
|
1314
|
+
if (parsed.version) {
|
|
1315
|
+
console.log(VERSION);
|
|
1316
|
+
process.exit(0);
|
|
1317
|
+
}
|
|
1318
|
+
if (parsed.help) {
|
|
1319
|
+
printHelp();
|
|
1320
|
+
process.exit(0);
|
|
1321
|
+
}
|
|
1322
|
+
if (parsed.listModels !== undefined) {
|
|
1323
|
+
const searchPattern = typeof parsed.listModels === "string" ? parsed.listModels : undefined;
|
|
1324
|
+
await listModels(modelRegistry, searchPattern);
|
|
1325
|
+
process.exit(0);
|
|
1326
|
+
}
|
|
1327
|
+
// Read piped stdin content (if any) - skip for RPC mode which uses stdin for JSON-RPC
|
|
1328
|
+
if (parsed.mode !== "rpc") {
|
|
1329
|
+
const stdinContent = await readPipedStdin();
|
|
1330
|
+
if (stdinContent !== undefined) {
|
|
1331
|
+
// Force print mode since interactive mode requires a TTY for keyboard input
|
|
1332
|
+
parsed.print = true;
|
|
1333
|
+
// Prepend stdin content to messages
|
|
1334
|
+
parsed.messages.unshift(stdinContent);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1337
|
+
if (parsed.export) {
|
|
1338
|
+
let result;
|
|
1339
|
+
try {
|
|
1340
|
+
const outputPath = parsed.messages.length > 0 ? parsed.messages[0] : undefined;
|
|
1341
|
+
result = await exportFromFile(parsed.export, outputPath);
|
|
1342
|
+
}
|
|
1343
|
+
catch (error) {
|
|
1344
|
+
const message = error instanceof Error ? error.message : "Failed to export session";
|
|
1345
|
+
console.error(chalk.red(`Error: ${message}`));
|
|
1346
|
+
process.exit(1);
|
|
1347
|
+
}
|
|
1348
|
+
console.log(`Exported to: ${result}`);
|
|
1349
|
+
process.exit(0);
|
|
1350
|
+
}
|
|
1351
|
+
if (parsed.mode === "rpc" && parsed.fileArgs.length > 0) {
|
|
1352
|
+
console.error(chalk.red("Error: @file arguments are not supported in RPC mode"));
|
|
1353
|
+
process.exit(1);
|
|
1354
|
+
}
|
|
1355
|
+
const { initialMessage, initialImages } = await prepareInitialMessage(parsed, settingsManager.getImageAutoResize());
|
|
1356
|
+
const isInteractive = !parsed.print && parsed.mode === undefined;
|
|
1357
|
+
const mode = parsed.mode || "text";
|
|
1358
|
+
initTheme(settingsManager.getTheme(), isInteractive);
|
|
1359
|
+
// Show deprecation warnings in interactive mode
|
|
1360
|
+
if (isInteractive && deprecationWarnings.length > 0) {
|
|
1361
|
+
await showDeprecationWarnings(deprecationWarnings);
|
|
1362
|
+
}
|
|
1363
|
+
let scopedModels = [];
|
|
1364
|
+
const modelPatterns = parsed.models ?? settingsManager.getEnabledModels();
|
|
1365
|
+
if (modelPatterns && modelPatterns.length > 0) {
|
|
1366
|
+
scopedModels = await resolveModelScope(modelPatterns, modelRegistry);
|
|
1367
|
+
}
|
|
1368
|
+
// Create session manager based on CLI flags
|
|
1369
|
+
let sessionManager = await createSessionManager(parsed, cwd);
|
|
1370
|
+
// Handle --resume: show session picker
|
|
1371
|
+
if (parsed.resume) {
|
|
1372
|
+
// Initialize keybindings so session picker respects user config
|
|
1373
|
+
KeybindingsManager.create();
|
|
1374
|
+
const selectedPath = await selectSession((onProgress) => SessionManager.list(cwd, parsed.sessionDir, onProgress), SessionManager.listAll);
|
|
1375
|
+
if (!selectedPath) {
|
|
1376
|
+
console.log(chalk.dim("No session selected"));
|
|
1377
|
+
stopThemeWatcher();
|
|
1378
|
+
process.exit(0);
|
|
1379
|
+
}
|
|
1380
|
+
sessionManager = SessionManager.open(selectedPath);
|
|
1381
|
+
}
|
|
1382
|
+
const { options: sessionOptions, cliThinkingFromModel } = buildSessionOptions(parsed, scopedModels, sessionManager, modelRegistry);
|
|
1383
|
+
sessionOptions.authStorage = authStorage;
|
|
1384
|
+
sessionOptions.modelRegistry = modelRegistry;
|
|
1385
|
+
sessionOptions.resourceLoader = resourceLoader;
|
|
1386
|
+
sessionOptions.enableAskUserTool = isInteractive || mode === "rpc";
|
|
1387
|
+
// Handle CLI --api-key as runtime override (not persisted)
|
|
1388
|
+
if (parsed.apiKey) {
|
|
1389
|
+
if (!sessionOptions.model) {
|
|
1390
|
+
console.error(chalk.red("--api-key requires a model to be specified via --model (optionally with --provider)"));
|
|
1391
|
+
process.exit(1);
|
|
1392
|
+
}
|
|
1393
|
+
authStorage.setRuntimeApiKey(sessionOptions.model.provider, parsed.apiKey);
|
|
1394
|
+
}
|
|
1395
|
+
let mcpRuntime;
|
|
1396
|
+
try {
|
|
1397
|
+
mcpRuntime = new McpRuntime({
|
|
1398
|
+
cwd,
|
|
1399
|
+
agentDir,
|
|
1400
|
+
clientName: APP_NAME,
|
|
1401
|
+
clientVersion: VERSION,
|
|
1402
|
+
});
|
|
1403
|
+
await mcpRuntime.refresh();
|
|
1404
|
+
printMcpConfigWarnings(mcpRuntime.getErrors());
|
|
1405
|
+
const mcpTools = mcpRuntime.getToolDefinitions();
|
|
1406
|
+
if (mcpTools.length > 0) {
|
|
1407
|
+
sessionOptions.customTools = [...(sessionOptions.customTools ?? []), ...mcpTools];
|
|
1408
|
+
}
|
|
1409
|
+
const { session, modelFallbackMessage } = await createAgentSession(sessionOptions);
|
|
1410
|
+
if (!isInteractive && !session.model) {
|
|
1411
|
+
console.error(chalk.red("No model selected."));
|
|
1412
|
+
console.error(chalk.yellow("\nSelect one explicitly:"));
|
|
1413
|
+
console.error(` ${APP_NAME} --provider <provider> --model <model-id> ...`);
|
|
1414
|
+
console.error(` ${APP_NAME} --model <provider/model-id> ...`);
|
|
1415
|
+
console.error(chalk.yellow("\nFor interactive mode, launch and choose with /model."));
|
|
1416
|
+
console.error(chalk.dim(`Configured models file: ${getModelsPath()}`));
|
|
1417
|
+
process.exit(1);
|
|
1418
|
+
}
|
|
1419
|
+
// Clamp thinking level to model capabilities for CLI-provided thinking levels.
|
|
1420
|
+
// This covers both --thinking <level> and --model <pattern>:<thinking>.
|
|
1421
|
+
const cliThinkingOverride = parsed.thinking !== undefined || cliThinkingFromModel;
|
|
1422
|
+
if (session.model && cliThinkingOverride) {
|
|
1423
|
+
let effectiveThinking = session.thinkingLevel;
|
|
1424
|
+
if (!session.model.reasoning) {
|
|
1425
|
+
effectiveThinking = "off";
|
|
1426
|
+
}
|
|
1427
|
+
else if (effectiveThinking === "xhigh" && !supportsXhigh(session.model)) {
|
|
1428
|
+
effectiveThinking = "high";
|
|
1429
|
+
}
|
|
1430
|
+
if (effectiveThinking !== session.thinkingLevel) {
|
|
1431
|
+
session.setThinkingLevel(effectiveThinking);
|
|
1432
|
+
}
|
|
1433
|
+
}
|
|
1434
|
+
if (mode === "rpc") {
|
|
1435
|
+
await runRpcMode(session);
|
|
1436
|
+
}
|
|
1437
|
+
else if (isInteractive) {
|
|
1438
|
+
if (scopedModels.length > 0 && (parsed.verbose || !settingsManager.getQuietStartup())) {
|
|
1439
|
+
const modelList = scopedModels
|
|
1440
|
+
.map((sm) => {
|
|
1441
|
+
const thinkingStr = sm.thinkingLevel ? `:${sm.thinkingLevel}` : "";
|
|
1442
|
+
return `${sm.model.id}${thinkingStr}`;
|
|
1443
|
+
})
|
|
1444
|
+
.join(", ");
|
|
1445
|
+
console.log(chalk.dim(`Model scope: ${modelList} ${chalk.gray("(Ctrl+P to cycle)")}`));
|
|
1446
|
+
}
|
|
1447
|
+
printTimings();
|
|
1448
|
+
const mode = new InteractiveMode(session, {
|
|
1449
|
+
migratedProviders,
|
|
1450
|
+
modelFallbackMessage,
|
|
1451
|
+
initialMessage,
|
|
1452
|
+
initialImages,
|
|
1453
|
+
initialMessages: parsed.messages,
|
|
1454
|
+
verbose: parsed.verbose,
|
|
1455
|
+
planMode: parsed.plan,
|
|
1456
|
+
profile: sessionOptions.profile,
|
|
1457
|
+
mcpRuntime,
|
|
1458
|
+
});
|
|
1459
|
+
await mode.run();
|
|
1460
|
+
}
|
|
1461
|
+
else {
|
|
1462
|
+
await runPrintMode(session, {
|
|
1463
|
+
mode,
|
|
1464
|
+
messages: parsed.messages,
|
|
1465
|
+
initialMessage,
|
|
1466
|
+
initialImages,
|
|
1467
|
+
});
|
|
1468
|
+
stopThemeWatcher();
|
|
1469
|
+
if (process.stdout.writableLength > 0) {
|
|
1470
|
+
await new Promise((resolve) => process.stdout.once("drain", resolve));
|
|
1471
|
+
}
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
finally {
|
|
1475
|
+
await mcpRuntime?.dispose();
|
|
1476
|
+
}
|
|
1477
|
+
}
|
|
1478
|
+
//# sourceMappingURL=main.js.map
|