wotann 0.5.0 → 0.5.39
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/dist/agents/background-agent.d.ts.map +1 -1
- package/dist/agents/background-agent.js +2 -1
- package/dist/agents/background-agent.js.map +1 -1
- package/dist/agents/file-scope-policy.d.ts +116 -0
- package/dist/agents/file-scope-policy.d.ts.map +1 -0
- package/dist/agents/file-scope-policy.js +190 -0
- package/dist/agents/file-scope-policy.js.map +1 -0
- package/dist/agents/yaml-manifest.d.ts +125 -0
- package/dist/agents/yaml-manifest.d.ts.map +1 -0
- package/dist/agents/yaml-manifest.js +901 -0
- package/dist/agents/yaml-manifest.js.map +1 -0
- package/dist/auth/login.d.ts +3 -3
- package/dist/auth/login.d.ts.map +1 -1
- package/dist/auth/login.js +80 -23
- package/dist/auth/login.js.map +1 -1
- package/dist/autopilot/completion-oracle.d.ts.map +1 -1
- package/dist/autopilot/completion-oracle.js +3 -1
- package/dist/autopilot/completion-oracle.js.map +1 -1
- package/dist/autopilot/run-manifest.d.ts +90 -0
- package/dist/autopilot/run-manifest.d.ts.map +1 -0
- package/dist/autopilot/run-manifest.js +261 -0
- package/dist/autopilot/run-manifest.js.map +1 -0
- package/dist/browser/adaptive-selectors.d.ts +170 -0
- package/dist/browser/adaptive-selectors.d.ts.map +1 -0
- package/dist/browser/adaptive-selectors.js +317 -0
- package/dist/browser/adaptive-selectors.js.map +1 -0
- package/dist/browser/humanize-input.d.ts +76 -0
- package/dist/browser/humanize-input.d.ts.map +1 -0
- package/dist/browser/humanize-input.js +386 -0
- package/dist/browser/humanize-input.js.map +1 -0
- package/dist/channels/teams.d.ts +41 -19
- package/dist/channels/teams.d.ts.map +1 -1
- package/dist/channels/teams.js +121 -24
- package/dist/channels/teams.js.map +1 -1
- package/dist/channels/terminal-mention.d.ts.map +1 -1
- package/dist/channels/terminal-mention.js +4 -1
- package/dist/channels/terminal-mention.js.map +1 -1
- package/dist/cli/commands/blast-radius.d.ts +47 -0
- package/dist/cli/commands/blast-radius.d.ts.map +1 -0
- package/dist/cli/commands/blast-radius.js +123 -0
- package/dist/cli/commands/blast-radius.js.map +1 -0
- package/dist/cli/commands/evolve.d.ts +92 -0
- package/dist/cli/commands/evolve.d.ts.map +1 -0
- package/dist/cli/commands/evolve.js +336 -0
- package/dist/cli/commands/evolve.js.map +1 -0
- package/dist/cli/commands/learning.d.ts +54 -0
- package/dist/cli/commands/learning.d.ts.map +1 -0
- package/dist/cli/commands/learning.js +380 -0
- package/dist/cli/commands/learning.js.map +1 -0
- package/dist/cli/commands/persona.d.ts +42 -0
- package/dist/cli/commands/persona.d.ts.map +1 -0
- package/dist/cli/commands/persona.js +198 -0
- package/dist/cli/commands/persona.js.map +1 -0
- package/dist/cli/commands/stuck.d.ts.map +1 -1
- package/dist/cli/commands/stuck.js +5 -2
- package/dist/cli/commands/stuck.js.map +1 -1
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +5 -2
- package/dist/cli/commands.js.map +1 -1
- package/dist/cli/orphan-wires/agent-manifest-cmd.d.ts +17 -0
- package/dist/cli/orphan-wires/agent-manifest-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/agent-manifest-cmd.js +99 -0
- package/dist/cli/orphan-wires/agent-manifest-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/arena-cmd.d.ts +26 -0
- package/dist/cli/orphan-wires/arena-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/arena-cmd.js +167 -0
- package/dist/cli/orphan-wires/arena-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/artifact-cmd.d.ts +17 -0
- package/dist/cli/orphan-wires/artifact-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/artifact-cmd.js +175 -0
- package/dist/cli/orphan-wires/artifact-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/demo-cmd.d.ts +25 -0
- package/dist/cli/orphan-wires/demo-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/demo-cmd.js +164 -0
- package/dist/cli/orphan-wires/demo-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/extras-cmd.d.ts +20 -0
- package/dist/cli/orphan-wires/extras-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/extras-cmd.js +289 -0
- package/dist/cli/orphan-wires/extras-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/harness-introspect-cmd.d.ts +15 -0
- package/dist/cli/orphan-wires/harness-introspect-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/harness-introspect-cmd.js +36 -0
- package/dist/cli/orphan-wires/harness-introspect-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/index.d.ts.map +1 -1
- package/dist/cli/orphan-wires/index.js +30 -0
- package/dist/cli/orphan-wires/index.js.map +1 -1
- package/dist/cli/orphan-wires/integrations-cmd.d.ts +38 -0
- package/dist/cli/orphan-wires/integrations-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/integrations-cmd.js +345 -0
- package/dist/cli/orphan-wires/integrations-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/mcp-scaffold-cmd.d.ts +18 -0
- package/dist/cli/orphan-wires/mcp-scaffold-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/mcp-scaffold-cmd.js +127 -0
- package/dist/cli/orphan-wires/mcp-scaffold-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/memory-consolidate-cmd.d.ts +21 -0
- package/dist/cli/orphan-wires/memory-consolidate-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/memory-consolidate-cmd.js +86 -0
- package/dist/cli/orphan-wires/memory-consolidate-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/patch-cmd.d.ts +29 -0
- package/dist/cli/orphan-wires/patch-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/patch-cmd.js +150 -0
- package/dist/cli/orphan-wires/patch-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/redteam-scan-cmd.d.ts +28 -0
- package/dist/cli/orphan-wires/redteam-scan-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/redteam-scan-cmd.js +169 -0
- package/dist/cli/orphan-wires/redteam-scan-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/scrape-adapt-cmd.d.ts +21 -0
- package/dist/cli/orphan-wires/scrape-adapt-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/scrape-adapt-cmd.js +70 -0
- package/dist/cli/orphan-wires/scrape-adapt-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/shell-tier-cmd.d.ts +20 -0
- package/dist/cli/orphan-wires/shell-tier-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/shell-tier-cmd.js +74 -0
- package/dist/cli/orphan-wires/shell-tier-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/sub-recipes-cmd.d.ts +18 -0
- package/dist/cli/orphan-wires/sub-recipes-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/sub-recipes-cmd.js +87 -0
- package/dist/cli/orphan-wires/sub-recipes-cmd.js.map +1 -0
- package/dist/cli/orphan-wires/webapp-test-cmd.d.ts +20 -0
- package/dist/cli/orphan-wires/webapp-test-cmd.d.ts.map +1 -0
- package/dist/cli/orphan-wires/webapp-test-cmd.js +115 -0
- package/dist/cli/orphan-wires/webapp-test-cmd.js.map +1 -0
- package/dist/cli/thin-client.d.ts +17 -10
- package/dist/cli/thin-client.d.ts.map +1 -1
- package/dist/cli/thin-client.js +108 -26
- package/dist/cli/thin-client.js.map +1 -1
- package/dist/computer-use/action-history-compactor.d.ts +92 -0
- package/dist/computer-use/action-history-compactor.d.ts.map +1 -0
- package/dist/computer-use/action-history-compactor.js +204 -0
- package/dist/computer-use/action-history-compactor.js.map +1 -0
- package/dist/computer-use/action-repertoire.d.ts +8 -0
- package/dist/computer-use/action-repertoire.d.ts.map +1 -1
- package/dist/computer-use/action-repertoire.js +19 -0
- package/dist/computer-use/action-repertoire.js.map +1 -1
- package/dist/computer-use/computer-agent.d.ts +232 -2
- package/dist/computer-use/computer-agent.d.ts.map +1 -1
- package/dist/computer-use/computer-agent.js +558 -19
- package/dist/computer-use/computer-agent.js.map +1 -1
- package/dist/computer-use/coordinate-scaling.d.ts +104 -0
- package/dist/computer-use/coordinate-scaling.d.ts.map +1 -0
- package/dist/computer-use/coordinate-scaling.js +175 -0
- package/dist/computer-use/coordinate-scaling.js.map +1 -0
- package/dist/computer-use/driver-contract.d.ts +158 -0
- package/dist/computer-use/driver-contract.d.ts.map +1 -0
- package/dist/computer-use/driver-contract.js +471 -0
- package/dist/computer-use/driver-contract.js.map +1 -0
- package/dist/computer-use/perception-engine.d.ts +39 -0
- package/dist/computer-use/perception-engine.d.ts.map +1 -1
- package/dist/computer-use/perception-engine.js +27 -27
- package/dist/computer-use/perception-engine.js.map +1 -1
- package/dist/computer-use/platform-bindings.d.ts.map +1 -1
- package/dist/computer-use/platform-bindings.js +216 -2
- package/dist/computer-use/platform-bindings.js.map +1 -1
- package/dist/computer-use/safe-execute.d.ts +86 -0
- package/dist/computer-use/safe-execute.d.ts.map +1 -0
- package/dist/computer-use/safe-execute.js +152 -0
- package/dist/computer-use/safe-execute.js.map +1 -0
- package/dist/context/branch-summarization.d.ts +97 -0
- package/dist/context/branch-summarization.d.ts.map +1 -0
- package/dist/context/branch-summarization.js +170 -0
- package/dist/context/branch-summarization.js.map +1 -0
- package/dist/context/compaction.d.ts +16 -1
- package/dist/context/compaction.d.ts.map +1 -1
- package/dist/context/compaction.js +50 -2
- package/dist/context/compaction.js.map +1 -1
- package/dist/context/inspector.d.ts +2 -2
- package/dist/context/inspector.d.ts.map +1 -1
- package/dist/context/inspector.js +4 -3
- package/dist/context/inspector.js.map +1 -1
- package/dist/core/agent-bridge.d.ts.map +1 -1
- package/dist/core/agent-bridge.js +200 -69
- package/dist/core/agent-bridge.js.map +1 -1
- package/dist/core/config.d.ts.map +1 -1
- package/dist/core/config.js +7 -0
- package/dist/core/config.js.map +1 -1
- package/dist/core/mode-model-preference.d.ts +95 -0
- package/dist/core/mode-model-preference.d.ts.map +1 -0
- package/dist/core/mode-model-preference.js +170 -0
- package/dist/core/mode-model-preference.js.map +1 -0
- package/dist/core/prompt-override.d.ts.map +1 -1
- package/dist/core/prompt-override.js +1 -0
- package/dist/core/prompt-override.js.map +1 -1
- package/dist/core/runtime-intelligence.d.ts +11 -0
- package/dist/core/runtime-intelligence.d.ts.map +1 -1
- package/dist/core/runtime-intelligence.js +18 -3
- package/dist/core/runtime-intelligence.js.map +1 -1
- package/dist/core/runtime-tool-dispatch.js +1 -1
- package/dist/core/runtime-tool-dispatch.js.map +1 -1
- package/dist/core/runtime.d.ts +186 -13
- package/dist/core/runtime.d.ts.map +1 -1
- package/dist/core/runtime.js +717 -228
- package/dist/core/runtime.js.map +1 -1
- package/dist/core/session-rewind.d.ts +67 -0
- package/dist/core/session-rewind.d.ts.map +1 -0
- package/dist/core/session-rewind.js +120 -0
- package/dist/core/session-rewind.js.map +1 -0
- package/dist/core/types.d.ts +19 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/daemon/file-watcher.d.ts +84 -0
- package/dist/daemon/file-watcher.d.ts.map +1 -0
- package/dist/daemon/file-watcher.js +193 -0
- package/dist/daemon/file-watcher.js.map +1 -0
- package/dist/daemon/jsonl-mode.d.ts +11 -0
- package/dist/daemon/jsonl-mode.d.ts.map +1 -0
- package/dist/daemon/jsonl-mode.js +77 -0
- package/dist/daemon/jsonl-mode.js.map +1 -0
- package/dist/daemon/kairos-ipc.d.ts +4 -1
- package/dist/daemon/kairos-ipc.d.ts.map +1 -1
- package/dist/daemon/kairos-ipc.js +38 -22
- package/dist/daemon/kairos-ipc.js.map +1 -1
- package/dist/daemon/kairos-rpc.d.ts +5 -1
- package/dist/daemon/kairos-rpc.d.ts.map +1 -1
- package/dist/daemon/kairos-rpc.js +1262 -114
- package/dist/daemon/kairos-rpc.js.map +1 -1
- package/dist/daemon/kairos.d.ts +35 -4
- package/dist/daemon/kairos.d.ts.map +1 -1
- package/dist/daemon/kairos.js +204 -24
- package/dist/daemon/kairos.js.map +1 -1
- package/dist/daemon/rpc-handlers/intelligence-rpc.d.ts.map +1 -1
- package/dist/daemon/rpc-handlers/intelligence-rpc.js +15 -3
- package/dist/daemon/rpc-handlers/intelligence-rpc.js.map +1 -1
- package/dist/daemon/transport/jsonl.d.ts +7 -0
- package/dist/daemon/transport/jsonl.d.ts.map +1 -0
- package/dist/daemon/transport/jsonl.js +38 -0
- package/dist/daemon/transport/jsonl.js.map +1 -0
- package/dist/daemon/transport/socket-path.d.ts +28 -0
- package/dist/daemon/transport/socket-path.d.ts.map +1 -0
- package/dist/daemon/transport/socket-path.js +36 -0
- package/dist/daemon/transport/socket-path.js.map +1 -0
- package/dist/design/theme-presets.d.ts +77 -0
- package/dist/design/theme-presets.d.ts.map +1 -0
- package/dist/design/theme-presets.js +274 -0
- package/dist/design/theme-presets.js.map +1 -0
- package/dist/desktop/companion-server.d.ts +67 -4
- package/dist/desktop/companion-server.d.ts.map +1 -1
- package/dist/desktop/companion-server.js +617 -70
- package/dist/desktop/companion-server.js.map +1 -1
- package/dist/desktop/web-artifacts-builder.d.ts +108 -0
- package/dist/desktop/web-artifacts-builder.d.ts.map +1 -0
- package/dist/desktop/web-artifacts-builder.js +184 -0
- package/dist/desktop/web-artifacts-builder.js.map +1 -0
- package/dist/hooks/built-in.d.ts.map +1 -1
- package/dist/hooks/built-in.js +15 -10
- package/dist/hooks/built-in.js.map +1 -1
- package/dist/index.js +1301 -167
- package/dist/index.js.map +1 -1
- package/dist/integrations/integration-manifest.d.ts +140 -0
- package/dist/integrations/integration-manifest.d.ts.map +1 -0
- package/dist/integrations/integration-manifest.js +268 -0
- package/dist/integrations/integration-manifest.js.map +1 -0
- package/dist/intelligence/apply-patch-dsl.d.ts +112 -0
- package/dist/intelligence/apply-patch-dsl.d.ts.map +1 -0
- package/dist/intelligence/apply-patch-dsl.js +264 -0
- package/dist/intelligence/apply-patch-dsl.js.map +1 -0
- package/dist/intelligence/apply-patch-executor.d.ts +147 -0
- package/dist/intelligence/apply-patch-executor.d.ts.map +1 -0
- package/dist/intelligence/apply-patch-executor.js +418 -0
- package/dist/intelligence/apply-patch-executor.js.map +1 -0
- package/dist/intelligence/blast-radius.d.ts +67 -0
- package/dist/intelligence/blast-radius.d.ts.map +1 -0
- package/dist/intelligence/blast-radius.js +536 -0
- package/dist/intelligence/blast-radius.js.map +1 -0
- package/dist/intelligence/code-graph.d.ts +58 -7
- package/dist/intelligence/code-graph.d.ts.map +1 -1
- package/dist/intelligence/code-graph.js +347 -16
- package/dist/intelligence/code-graph.js.map +1 -1
- package/dist/intelligence/codebase-health.d.ts.map +1 -1
- package/dist/intelligence/codebase-health.js +4 -3
- package/dist/intelligence/codebase-health.js.map +1 -1
- package/dist/intelligence/codemaps.d.ts +30 -1
- package/dist/intelligence/codemaps.d.ts.map +1 -1
- package/dist/intelligence/codemaps.js +99 -16
- package/dist/intelligence/codemaps.js.map +1 -1
- package/dist/intelligence/consecutive-error-counter.d.ts +89 -0
- package/dist/intelligence/consecutive-error-counter.d.ts.map +1 -0
- package/dist/intelligence/consecutive-error-counter.js +151 -0
- package/dist/intelligence/consecutive-error-counter.js.map +1 -0
- package/dist/intelligence/eval-frameworks/redteam-plugin-catalog.d.ts +87 -0
- package/dist/intelligence/eval-frameworks/redteam-plugin-catalog.d.ts.map +1 -0
- package/dist/intelligence/eval-frameworks/redteam-plugin-catalog.js +882 -0
- package/dist/intelligence/eval-frameworks/redteam-plugin-catalog.js.map +1 -0
- package/dist/intelligence/extractors/mineru.d.ts +108 -0
- package/dist/intelligence/extractors/mineru.d.ts.map +1 -0
- package/dist/intelligence/extractors/mineru.js +352 -0
- package/dist/intelligence/extractors/mineru.js.map +1 -0
- package/dist/intelligence/harness-introspect.d.ts +124 -0
- package/dist/intelligence/harness-introspect.d.ts.map +1 -0
- package/dist/intelligence/harness-introspect.js +349 -0
- package/dist/intelligence/harness-introspect.js.map +1 -0
- package/dist/intelligence/multi-patch-voter.d.ts +59 -1
- package/dist/intelligence/multi-patch-voter.d.ts.map +1 -1
- package/dist/intelligence/multi-patch-voter.js +191 -27
- package/dist/intelligence/multi-patch-voter.js.map +1 -1
- package/dist/intelligence/multimodal-extract.d.ts +44 -0
- package/dist/intelligence/multimodal-extract.d.ts.map +1 -1
- package/dist/intelligence/multimodal-extract.js +40 -1
- package/dist/intelligence/multimodal-extract.js.map +1 -1
- package/dist/intelligence/research-loops/budgeted-research.d.ts +7 -0
- package/dist/intelligence/research-loops/budgeted-research.d.ts.map +1 -1
- package/dist/intelligence/research-loops/budgeted-research.js +18 -0
- package/dist/intelligence/research-loops/budgeted-research.js.map +1 -1
- package/dist/intelligence/research-loops/constraint-guided-explorer.d.ts +124 -0
- package/dist/intelligence/research-loops/constraint-guided-explorer.d.ts.map +1 -0
- package/dist/intelligence/research-loops/constraint-guided-explorer.js +177 -0
- package/dist/intelligence/research-loops/constraint-guided-explorer.js.map +1 -0
- package/dist/intelligence/research-loops/results-collector.d.ts +62 -0
- package/dist/intelligence/research-loops/results-collector.d.ts.map +1 -0
- package/dist/intelligence/research-loops/results-collector.js +128 -0
- package/dist/intelligence/research-loops/results-collector.js.map +1 -0
- package/dist/intelligence/research-loops/results-log.d.ts +94 -0
- package/dist/intelligence/research-loops/results-log.d.ts.map +1 -0
- package/dist/intelligence/research-loops/results-log.js +178 -0
- package/dist/intelligence/research-loops/results-log.js.map +1 -0
- package/dist/intelligence/research-loops/strategies/base-strategy.d.ts +111 -0
- package/dist/intelligence/research-loops/strategies/base-strategy.d.ts.map +1 -0
- package/dist/intelligence/research-loops/strategies/base-strategy.js +72 -0
- package/dist/intelligence/research-loops/strategies/base-strategy.js.map +1 -0
- package/dist/intelligence/research-loops/strategies/dual-confidence.d.ts +57 -0
- package/dist/intelligence/research-loops/strategies/dual-confidence.d.ts.map +1 -0
- package/dist/intelligence/research-loops/strategies/dual-confidence.js +172 -0
- package/dist/intelligence/research-loops/strategies/dual-confidence.js.map +1 -0
- package/dist/intelligence/research-loops/strategies/langgraph-agent.d.ts +68 -0
- package/dist/intelligence/research-loops/strategies/langgraph-agent.d.ts.map +1 -0
- package/dist/intelligence/research-loops/strategies/langgraph-agent.js +221 -0
- package/dist/intelligence/research-loops/strategies/langgraph-agent.js.map +1 -0
- package/dist/intelligence/research-loops/strategies/parallel-constrained.d.ts +42 -0
- package/dist/intelligence/research-loops/strategies/parallel-constrained.d.ts.map +1 -0
- package/dist/intelligence/research-loops/strategies/parallel-constrained.js +132 -0
- package/dist/intelligence/research-loops/strategies/parallel-constrained.js.map +1 -0
- package/dist/intelligence/research-loops/strategies/recursive-decomposition.d.ts +55 -0
- package/dist/intelligence/research-loops/strategies/recursive-decomposition.d.ts.map +1 -0
- package/dist/intelligence/research-loops/strategies/recursive-decomposition.js +187 -0
- package/dist/intelligence/research-loops/strategies/recursive-decomposition.js.map +1 -0
- package/dist/intelligence/research-loops/strategy-registry.d.ts +43 -0
- package/dist/intelligence/research-loops/strategy-registry.d.ts.map +1 -0
- package/dist/intelligence/research-loops/strategy-registry.js +62 -0
- package/dist/intelligence/research-loops/strategy-registry.js.map +1 -0
- package/dist/intelligence/research-strategies.d.ts +133 -0
- package/dist/intelligence/research-strategies.d.ts.map +1 -0
- package/dist/intelligence/research-strategies.js +204 -0
- package/dist/intelligence/research-strategies.js.map +1 -0
- package/dist/lib.d.ts +49 -0
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +133 -0
- package/dist/lib.js.map +1 -1
- package/dist/loop/tool-description-reset.d.ts +113 -0
- package/dist/loop/tool-description-reset.d.ts.map +1 -0
- package/dist/loop/tool-description-reset.js +136 -0
- package/dist/loop/tool-description-reset.js.map +1 -0
- package/dist/lsp/server-registry.d.ts.map +1 -1
- package/dist/lsp/server-registry.js +2 -1
- package/dist/lsp/server-registry.js.map +1 -1
- package/dist/lsp/symbol-operations.d.ts.map +1 -1
- package/dist/lsp/symbol-operations.js +2 -1
- package/dist/lsp/symbol-operations.js.map +1 -1
- package/dist/marketplace/acp-agent-registry.d.ts.map +1 -1
- package/dist/marketplace/acp-agent-registry.js +2 -1
- package/dist/marketplace/acp-agent-registry.js.map +1 -1
- package/dist/marketplace/marketplace-source-git.d.ts +135 -0
- package/dist/marketplace/marketplace-source-git.d.ts.map +1 -0
- package/dist/marketplace/marketplace-source-git.js +211 -0
- package/dist/marketplace/marketplace-source-git.js.map +1 -0
- package/dist/marketplace/registry.d.ts +87 -0
- package/dist/marketplace/registry.d.ts.map +1 -1
- package/dist/marketplace/registry.js +113 -2
- package/dist/marketplace/registry.js.map +1 -1
- package/dist/mcp/chrome-devtools.d.ts +62 -2
- package/dist/mcp/chrome-devtools.d.ts.map +1 -1
- package/dist/mcp/chrome-devtools.js +183 -1
- package/dist/mcp/chrome-devtools.js.map +1 -1
- package/dist/mcp/health-probe.d.ts +1 -0
- package/dist/mcp/health-probe.d.ts.map +1 -1
- package/dist/mcp/health-probe.js +32 -1
- package/dist/mcp/health-probe.js.map +1 -1
- package/dist/mcp/mcp-scaffolder.d.ts +166 -0
- package/dist/mcp/mcp-scaffolder.d.ts.map +1 -0
- package/dist/mcp/mcp-scaffolder.js +526 -0
- package/dist/mcp/mcp-scaffolder.js.map +1 -0
- package/dist/mcp/mcp-server.d.ts.map +1 -1
- package/dist/mcp/mcp-server.js +55 -0
- package/dist/mcp/mcp-server.js.map +1 -1
- package/dist/mcp/memory-mcp.d.ts +163 -0
- package/dist/mcp/memory-mcp.d.ts.map +1 -0
- package/dist/mcp/memory-mcp.js +368 -0
- package/dist/mcp/memory-mcp.js.map +1 -0
- package/dist/mcp/tool-loader.d.ts.map +1 -1
- package/dist/mcp/tool-loader.js +13 -0
- package/dist/mcp/tool-loader.js.map +1 -1
- package/dist/meet/meeting-runtime.d.ts.map +1 -1
- package/dist/meet/meeting-runtime.js +3 -1
- package/dist/meet/meeting-runtime.js.map +1 -1
- package/dist/memory/incremental-indexer.d.ts.map +1 -1
- package/dist/memory/incremental-indexer.js +5 -1
- package/dist/memory/incremental-indexer.js.map +1 -1
- package/dist/memory/qmd-integration.d.ts.map +1 -1
- package/dist/memory/qmd-integration.js +47 -15
- package/dist/memory/qmd-integration.js.map +1 -1
- package/dist/memory/two-phase-consolidator.d.ts +118 -0
- package/dist/memory/two-phase-consolidator.d.ts.map +1 -0
- package/dist/memory/two-phase-consolidator.js +265 -0
- package/dist/memory/two-phase-consolidator.js.map +1 -0
- package/dist/middleware/doom-loop.d.ts +21 -0
- package/dist/middleware/doom-loop.d.ts.map +1 -1
- package/dist/middleware/doom-loop.js +49 -6
- package/dist/middleware/doom-loop.js.map +1 -1
- package/dist/middleware/loop-detection.d.ts +176 -6
- package/dist/middleware/loop-detection.d.ts.map +1 -1
- package/dist/middleware/loop-detection.js +341 -6
- package/dist/middleware/loop-detection.js.map +1 -1
- package/dist/middleware/pipeline.d.ts +9 -1
- package/dist/middleware/pipeline.d.ts.map +1 -1
- package/dist/middleware/pipeline.js +116 -1
- package/dist/middleware/pipeline.js.map +1 -1
- package/dist/middleware/tool-flow-gate.d.ts +20 -0
- package/dist/middleware/tool-flow-gate.d.ts.map +1 -1
- package/dist/middleware/tool-flow-gate.js +93 -0
- package/dist/middleware/tool-flow-gate.js.map +1 -1
- package/dist/mobile/ios-app.d.ts +18 -1
- package/dist/mobile/ios-app.d.ts.map +1 -1
- package/dist/mobile/ios-app.js +108 -8
- package/dist/mobile/ios-app.js.map +1 -1
- package/dist/orchestration/adversarial-cut.d.ts +85 -0
- package/dist/orchestration/adversarial-cut.d.ts.map +1 -0
- package/dist/orchestration/adversarial-cut.js +222 -0
- package/dist/orchestration/adversarial-cut.js.map +1 -0
- package/dist/orchestration/agent-kanban.d.ts +147 -0
- package/dist/orchestration/agent-kanban.d.ts.map +1 -0
- package/dist/orchestration/agent-kanban.js +414 -0
- package/dist/orchestration/agent-kanban.js.map +1 -0
- package/dist/orchestration/autonomous.d.ts +111 -0
- package/dist/orchestration/autonomous.d.ts.map +1 -1
- package/dist/orchestration/autonomous.js +183 -6
- package/dist/orchestration/autonomous.js.map +1 -1
- package/dist/orchestration/elo-tournament.d.ts +90 -0
- package/dist/orchestration/elo-tournament.d.ts.map +1 -0
- package/dist/orchestration/elo-tournament.js +203 -0
- package/dist/orchestration/elo-tournament.js.map +1 -0
- package/dist/orchestration/multi-model-arena.d.ts +138 -0
- package/dist/orchestration/multi-model-arena.d.ts.map +1 -0
- package/dist/orchestration/multi-model-arena.js +298 -0
- package/dist/orchestration/multi-model-arena.js.map +1 -0
- package/dist/orchestration/review-pipeline.d.ts +78 -0
- package/dist/orchestration/review-pipeline.d.ts.map +1 -0
- package/dist/orchestration/review-pipeline.js +202 -0
- package/dist/orchestration/review-pipeline.js.map +1 -0
- package/dist/orchestration/unified-state-thread.d.ts +186 -0
- package/dist/orchestration/unified-state-thread.d.ts.map +1 -0
- package/dist/orchestration/unified-state-thread.js +327 -0
- package/dist/orchestration/unified-state-thread.js.map +1 -0
- package/dist/plugins/manager.d.ts.map +1 -1
- package/dist/plugins/manager.js +2 -1
- package/dist/plugins/manager.js.map +1 -1
- package/dist/prompt/engine.d.ts +7 -0
- package/dist/prompt/engine.d.ts.map +1 -1
- package/dist/prompt/engine.js.map +1 -1
- package/dist/prompt/modules/caveman.d.ts +51 -0
- package/dist/prompt/modules/caveman.d.ts.map +1 -0
- package/dist/prompt/modules/caveman.js +97 -0
- package/dist/prompt/modules/caveman.js.map +1 -0
- package/dist/prompt/modules/index.d.ts +1 -0
- package/dist/prompt/modules/index.d.ts.map +1 -1
- package/dist/prompt/modules/index.js +3 -0
- package/dist/prompt/modules/index.js.map +1 -1
- package/dist/providers/account-pool.d.ts.map +1 -1
- package/dist/providers/account-pool.js +1 -0
- package/dist/providers/account-pool.js.map +1 -1
- package/dist/providers/anthropic-adapter.d.ts.map +1 -1
- package/dist/providers/anthropic-adapter.js +33 -0
- package/dist/providers/anthropic-adapter.js.map +1 -1
- package/dist/providers/cloud-offload/config-loader.d.ts +20 -0
- package/dist/providers/cloud-offload/config-loader.d.ts.map +1 -0
- package/dist/providers/cloud-offload/config-loader.js +148 -0
- package/dist/providers/cloud-offload/config-loader.js.map +1 -0
- package/dist/providers/codex-adapter.d.ts.map +1 -1
- package/dist/providers/codex-adapter.js +136 -4
- package/dist/providers/codex-adapter.js.map +1 -1
- package/dist/providers/discovery.d.ts.map +1 -1
- package/dist/providers/discovery.js +20 -0
- package/dist/providers/discovery.js.map +1 -1
- package/dist/providers/effort-cascade.d.ts +113 -0
- package/dist/providers/effort-cascade.d.ts.map +1 -0
- package/dist/providers/effort-cascade.js +215 -0
- package/dist/providers/effort-cascade.js.map +1 -0
- package/dist/providers/fallback-chain.d.ts.map +1 -1
- package/dist/providers/fallback-chain.js +1 -0
- package/dist/providers/fallback-chain.js.map +1 -1
- package/dist/providers/health-check.d.ts.map +1 -1
- package/dist/providers/health-check.js +8 -0
- package/dist/providers/health-check.js.map +1 -1
- package/dist/providers/model-defaults.d.ts +1 -1
- package/dist/providers/model-defaults.d.ts.map +1 -1
- package/dist/providers/model-defaults.js +13 -1
- package/dist/providers/model-defaults.js.map +1 -1
- package/dist/providers/model-discovery.d.ts.map +1 -1
- package/dist/providers/model-discovery.js +1 -0
- package/dist/providers/model-discovery.js.map +1 -1
- package/dist/providers/ollama-adapter.d.ts.map +1 -1
- package/dist/providers/ollama-adapter.js +21 -1
- package/dist/providers/ollama-adapter.js.map +1 -1
- package/dist/providers/openai-compat-adapter.d.ts.map +1 -1
- package/dist/providers/openai-compat-adapter.js +25 -0
- package/dist/providers/openai-compat-adapter.js.map +1 -1
- package/dist/providers/preset-library.d.ts.map +1 -1
- package/dist/providers/preset-library.js +9 -0
- package/dist/providers/preset-library.js.map +1 -1
- package/dist/providers/provider-service.d.ts.map +1 -1
- package/dist/providers/provider-service.js +40 -1
- package/dist/providers/provider-service.js.map +1 -1
- package/dist/providers/registry.d.ts.map +1 -1
- package/dist/providers/registry.js +7 -0
- package/dist/providers/registry.js.map +1 -1
- package/dist/providers/sticky-rotation.d.ts +100 -0
- package/dist/providers/sticky-rotation.d.ts.map +1 -0
- package/dist/providers/sticky-rotation.js +134 -0
- package/dist/providers/sticky-rotation.js.map +1 -0
- package/dist/providers/tool-parsers/parsers.d.ts.map +1 -1
- package/dist/providers/tool-parsers/parsers.js +17 -4
- package/dist/providers/tool-parsers/parsers.js.map +1 -1
- package/dist/providers/types.d.ts +25 -0
- package/dist/providers/types.d.ts.map +1 -1
- package/dist/recipes/final-output.d.ts +74 -0
- package/dist/recipes/final-output.d.ts.map +1 -0
- package/dist/recipes/final-output.js +232 -0
- package/dist/recipes/final-output.js.map +1 -0
- package/dist/recipes/recipe-loader.d.ts.map +1 -1
- package/dist/recipes/recipe-loader.js +29 -0
- package/dist/recipes/recipe-loader.js.map +1 -1
- package/dist/recipes/recipe-runtime.d.ts.map +1 -1
- package/dist/recipes/recipe-runtime.js +31 -0
- package/dist/recipes/recipe-runtime.js.map +1 -1
- package/dist/recipes/recipe-types.d.ts +28 -0
- package/dist/recipes/recipe-types.d.ts.map +1 -1
- package/dist/recipes/sop-crystallizer.d.ts +90 -0
- package/dist/recipes/sop-crystallizer.d.ts.map +1 -0
- package/dist/recipes/sop-crystallizer.js +238 -0
- package/dist/recipes/sop-crystallizer.js.map +1 -0
- package/dist/recipes/sub-recipe-orchestrator.d.ts +126 -0
- package/dist/recipes/sub-recipe-orchestrator.d.ts.map +1 -0
- package/dist/recipes/sub-recipe-orchestrator.js +225 -0
- package/dist/recipes/sub-recipe-orchestrator.js.map +1 -0
- package/dist/sandbox/extended-backends.d.ts.map +1 -1
- package/dist/sandbox/extended-backends.js +7 -2
- package/dist/sandbox/extended-backends.js.map +1 -1
- package/dist/sandbox/seatbelt-policy.d.ts +132 -0
- package/dist/sandbox/seatbelt-policy.d.ts.map +1 -0
- package/dist/sandbox/seatbelt-policy.js +562 -0
- package/dist/sandbox/seatbelt-policy.js.map +1 -0
- package/dist/sandbox/terminal-backends.d.ts.map +1 -1
- package/dist/sandbox/terminal-backends.js +3 -1
- package/dist/sandbox/terminal-backends.js.map +1 -1
- package/dist/security/auto-mode-ruleset.d.ts +142 -0
- package/dist/security/auto-mode-ruleset.d.ts.map +1 -0
- package/dist/security/auto-mode-ruleset.js +264 -0
- package/dist/security/auto-mode-ruleset.js.map +1 -0
- package/dist/security/bash-arity-policy.d.ts +70 -0
- package/dist/security/bash-arity-policy.d.ts.map +1 -0
- package/dist/security/bash-arity-policy.js +189 -0
- package/dist/security/bash-arity-policy.js.map +1 -0
- package/dist/security/command-sanitizer.d.ts.map +1 -1
- package/dist/security/command-sanitizer.js +24 -0
- package/dist/security/command-sanitizer.js.map +1 -1
- package/dist/security/credential-broker.d.ts +136 -0
- package/dist/security/credential-broker.d.ts.map +1 -0
- package/dist/security/credential-broker.js +284 -0
- package/dist/security/credential-broker.js.map +1 -0
- package/dist/security/invisible-text-sanitizer.d.ts +114 -0
- package/dist/security/invisible-text-sanitizer.d.ts.map +1 -0
- package/dist/security/invisible-text-sanitizer.js +221 -0
- package/dist/security/invisible-text-sanitizer.js.map +1 -0
- package/dist/security/osv-check.d.ts +174 -0
- package/dist/security/osv-check.d.ts.map +1 -0
- package/dist/security/osv-check.js +409 -0
- package/dist/security/osv-check.js.map +1 -0
- package/dist/security/process-hardening.d.ts +114 -0
- package/dist/security/process-hardening.d.ts.map +1 -0
- package/dist/security/process-hardening.js +132 -0
- package/dist/security/process-hardening.js.map +1 -0
- package/dist/security/shell-escalation-tiers.d.ts +73 -0
- package/dist/security/shell-escalation-tiers.d.ts.map +1 -0
- package/dist/security/shell-escalation-tiers.js +439 -0
- package/dist/security/shell-escalation-tiers.js.map +1 -0
- package/dist/session/fork.d.ts +100 -0
- package/dist/session/fork.d.ts.map +1 -0
- package/dist/session/fork.js +223 -0
- package/dist/session/fork.js.map +1 -0
- package/dist/skills/activation-telemetry.d.ts +154 -0
- package/dist/skills/activation-telemetry.d.ts.map +1 -0
- package/dist/skills/activation-telemetry.js +274 -0
- package/dist/skills/activation-telemetry.js.map +1 -0
- package/dist/skills/agentskills-registry.d.ts +12 -1
- package/dist/skills/agentskills-registry.d.ts.map +1 -1
- package/dist/skills/agentskills-registry.js +11 -0
- package/dist/skills/agentskills-registry.js.map +1 -1
- package/dist/skills/description-optimizer.d.ts +101 -0
- package/dist/skills/description-optimizer.d.ts.map +1 -0
- package/dist/skills/description-optimizer.js +304 -0
- package/dist/skills/description-optimizer.js.map +1 -0
- package/dist/skills/history-deduper.d.ts +109 -0
- package/dist/skills/history-deduper.d.ts.map +1 -0
- package/dist/skills/history-deduper.js +222 -0
- package/dist/skills/history-deduper.js.map +1 -0
- package/dist/skills/loader.d.ts.map +1 -1
- package/dist/skills/loader.js +2 -1
- package/dist/skills/loader.js.map +1 -1
- package/dist/skills/skill-source-adapter.d.ts +16 -0
- package/dist/skills/skill-source-adapter.d.ts.map +1 -1
- package/dist/skills/skill-source-adapter.js +0 -0
- package/dist/skills/skill-source-adapter.js.map +1 -1
- package/dist/skills/skill-standard.d.ts +29 -4
- package/dist/skills/skill-standard.d.ts.map +1 -1
- package/dist/skills/skill-standard.js +139 -66
- package/dist/skills/skill-standard.js.map +1 -1
- package/dist/skills/sop-completion-gate.d.ts +137 -0
- package/dist/skills/sop-completion-gate.d.ts.map +1 -0
- package/dist/skills/sop-completion-gate.js +159 -0
- package/dist/skills/sop-completion-gate.js.map +1 -0
- package/dist/skills/sop-template.d.ts +85 -0
- package/dist/skills/sop-template.d.ts.map +1 -0
- package/dist/skills/sop-template.js +106 -0
- package/dist/skills/sop-template.js.map +1 -0
- package/dist/skills/wotann-skills-registry.d.ts +1 -1
- package/dist/skills/wotann-skills-registry.d.ts.map +1 -1
- package/dist/skills/wotann-skills-registry.js +503 -0
- package/dist/skills/wotann-skills-registry.js.map +1 -1
- package/dist/snippets/prompt-corpus.d.ts +10 -0
- package/dist/snippets/prompt-corpus.d.ts.map +1 -0
- package/dist/snippets/prompt-corpus.js +158 -0
- package/dist/snippets/prompt-corpus.js.map +1 -0
- package/dist/snippets/snippet-store.d.ts +27 -0
- package/dist/snippets/snippet-store.d.ts.map +1 -1
- package/dist/snippets/snippet-store.js +109 -6
- package/dist/snippets/snippet-store.js.map +1 -1
- package/dist/storage/sqlite-node-backend.d.ts +47 -36
- package/dist/storage/sqlite-node-backend.d.ts.map +1 -1
- package/dist/storage/sqlite-node-backend.js +250 -94
- package/dist/storage/sqlite-node-backend.js.map +1 -1
- package/dist/testing/webapp-server-lifecycle.d.ts +74 -0
- package/dist/testing/webapp-server-lifecycle.d.ts.map +1 -0
- package/dist/testing/webapp-server-lifecycle.js +272 -0
- package/dist/testing/webapp-server-lifecycle.js.map +1 -0
- package/dist/tools/markitdown-bridge.d.ts +19 -0
- package/dist/tools/markitdown-bridge.d.ts.map +1 -1
- package/dist/tools/markitdown-bridge.js +167 -2
- package/dist/tools/markitdown-bridge.js.map +1 -1
- package/dist/tools/pdf-processor.d.ts.map +1 -1
- package/dist/tools/pdf-processor.js +7 -3
- package/dist/tools/pdf-processor.js.map +1 -1
- package/dist/tools/pptx-processor.d.ts +51 -0
- package/dist/tools/pptx-processor.d.ts.map +1 -0
- package/dist/tools/pptx-processor.js +334 -0
- package/dist/tools/pptx-processor.js.map +1 -0
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +1661 -149
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/agent-tools.d.ts +60 -0
- package/dist/ui/agent-tools.d.ts.map +1 -0
- package/dist/ui/agent-tools.js +468 -0
- package/dist/ui/agent-tools.js.map +1 -0
- package/dist/ui/alt-buffer-mode.d.ts +68 -0
- package/dist/ui/alt-buffer-mode.d.ts.map +1 -0
- package/dist/ui/alt-buffer-mode.js +114 -0
- package/dist/ui/alt-buffer-mode.js.map +1 -0
- package/dist/ui/alt-buffer.d.ts +57 -10
- package/dist/ui/alt-buffer.d.ts.map +1 -1
- package/dist/ui/alt-buffer.js +54 -12
- package/dist/ui/alt-buffer.js.map +1 -1
- package/dist/ui/components/AgentStatusPanel.d.ts.map +1 -1
- package/dist/ui/components/AgentStatusPanel.js +14 -6
- package/dist/ui/components/AgentStatusPanel.js.map +1 -1
- package/dist/ui/components/AuditLogPanel.js +3 -3
- package/dist/ui/components/AuditLogPanel.js.map +1 -1
- package/dist/ui/components/AutomationsPanel.js +3 -3
- package/dist/ui/components/AutomationsPanel.js.map +1 -1
- package/dist/ui/components/ChatView.d.ts +9 -1
- package/dist/ui/components/ChatView.d.ts.map +1 -1
- package/dist/ui/components/ChatView.js +503 -14
- package/dist/ui/components/ChatView.js.map +1 -1
- package/dist/ui/components/CommandPaletteCommands.d.ts +2 -0
- package/dist/ui/components/CommandPaletteCommands.d.ts.map +1 -1
- package/dist/ui/components/CommandPaletteCommands.js +18 -2
- package/dist/ui/components/CommandPaletteCommands.js.map +1 -1
- package/dist/ui/components/ContextHUD.d.ts.map +1 -1
- package/dist/ui/components/ContextHUD.js +3 -3
- package/dist/ui/components/ContextHUD.js.map +1 -1
- package/dist/ui/components/DispatchInbox.js +3 -3
- package/dist/ui/components/DispatchInbox.js.map +1 -1
- package/dist/ui/components/GdprPanel.d.ts.map +1 -1
- package/dist/ui/components/GdprPanel.js +2 -3
- package/dist/ui/components/GdprPanel.js.map +1 -1
- package/dist/ui/components/HistoryPicker.js +3 -3
- package/dist/ui/components/HistoryPicker.js.map +1 -1
- package/dist/ui/components/ModelPicker.d.ts +9 -6
- package/dist/ui/components/ModelPicker.d.ts.map +1 -1
- package/dist/ui/components/ModelPicker.js +12 -9
- package/dist/ui/components/ModelPicker.js.map +1 -1
- package/dist/ui/components/OptionPicker.js +3 -3
- package/dist/ui/components/OptionPicker.js.map +1 -1
- package/dist/ui/components/PermissionPrompt.js +3 -3
- package/dist/ui/components/PermissionPrompt.js.map +1 -1
- package/dist/ui/components/PromptInput.d.ts.map +1 -1
- package/dist/ui/components/PromptInput.js +65 -10
- package/dist/ui/components/PromptInput.js.map +1 -1
- package/dist/ui/components/ProviderSetupOverlay.d.ts +19 -0
- package/dist/ui/components/ProviderSetupOverlay.d.ts.map +1 -0
- package/dist/ui/components/ProviderSetupOverlay.js +124 -0
- package/dist/ui/components/ProviderSetupOverlay.js.map +1 -0
- package/dist/ui/components/StartupScreen.d.ts.map +1 -1
- package/dist/ui/components/StartupScreen.js +10 -1
- package/dist/ui/components/StartupScreen.js.map +1 -1
- package/dist/ui/components/StatusBar.d.ts.map +1 -1
- package/dist/ui/components/StatusBar.js +3 -3
- package/dist/ui/components/StatusBar.js.map +1 -1
- package/dist/ui/components/TrustPanel.js +3 -3
- package/dist/ui/components/TrustPanel.js.map +1 -1
- package/dist/ui/components/UnifiedStatusBar.d.ts.map +1 -1
- package/dist/ui/components/UnifiedStatusBar.js +76 -5
- package/dist/ui/components/UnifiedStatusBar.js.map +1 -1
- package/dist/ui/computer-action-parser.d.ts +6 -0
- package/dist/ui/computer-action-parser.d.ts.map +1 -0
- package/dist/ui/computer-action-parser.js +119 -0
- package/dist/ui/computer-action-parser.js.map +1 -0
- package/dist/ui/helpers.d.ts +1 -1
- package/dist/ui/helpers.d.ts.map +1 -1
- package/dist/ui/helpers.js +1 -1
- package/dist/ui/helpers.js.map +1 -1
- package/dist/ui/keybindings.d.ts +12 -2
- package/dist/ui/keybindings.d.ts.map +1 -1
- package/dist/ui/keybindings.js +36 -4
- package/dist/ui/keybindings.js.map +1 -1
- package/dist/ui/markdown-stream.d.ts +99 -0
- package/dist/ui/markdown-stream.d.ts.map +1 -0
- package/dist/ui/markdown-stream.js +314 -0
- package/dist/ui/markdown-stream.js.map +1 -0
- package/dist/ui/terminal-keyboard-protocol.d.ts +23 -0
- package/dist/ui/terminal-keyboard-protocol.d.ts.map +1 -0
- package/dist/ui/terminal-keyboard-protocol.js +72 -0
- package/dist/ui/terminal-keyboard-protocol.js.map +1 -0
- package/dist/ui/theme/context.d.ts +39 -0
- package/dist/ui/theme/context.d.ts.map +1 -0
- package/dist/ui/theme/context.js +42 -0
- package/dist/ui/theme/context.js.map +1 -0
- package/dist/utils/platform.d.ts +115 -0
- package/dist/utils/platform.d.ts.map +1 -0
- package/dist/utils/platform.js +146 -0
- package/dist/utils/platform.js.map +1 -0
- package/dist/verification/auto-verify-policy.d.ts +107 -0
- package/dist/verification/auto-verify-policy.d.ts.map +1 -0
- package/dist/verification/auto-verify-policy.js +309 -0
- package/dist/verification/auto-verify-policy.js.map +1 -0
- package/package.json +4 -1
- package/skills/anthropic-finance/audit-spreadsheet.md +165 -0
- package/skills/anthropic-finance/clean-data-xls.md +59 -0
- package/skills/anthropic-finance/competitive-analysis.md +288 -0
- package/skills/anthropic-finance/compliance-rules-engine.md +56 -0
- package/skills/anthropic-finance/dd-checklist.md +126 -0
- package/skills/anthropic-finance/independent-recompute.md +47 -0
- package/skills/anthropic-finance/reconcile-root-cause.md +48 -0
- package/skills/anthropic-finance/roll-forward.md +42 -0
- package/skills/anthropic-finance/untrusted-doc-parse.md +57 -0
- package/skills/anthropic-finance/variance-commentary.md +43 -0
- package/skills/doubt-driven-development.md +95 -0
- package/skills/mattpocock/diagnose.md +126 -0
- package/skills/mattpocock/grill-with-docs.md +97 -0
- package/skills/mattpocock/improve-codebase-architecture.md +80 -0
- package/skills/mattpocock/prototype.md +39 -0
- package/skills/mattpocock/review.md +87 -0
- package/skills/mattpocock/tdd.md +118 -0
- package/skills/mattpocock/zoom-out.md +17 -0
- package/skills/scientific/citation-management/SKILL.md +1113 -0
- package/skills/scientific/citation-management/assets/bibtex_template.bib +264 -0
- package/skills/scientific/citation-management/assets/citation_checklist.md +386 -0
- package/skills/scientific/citation-management/references/bibtex_formatting.md +908 -0
- package/skills/scientific/citation-management/references/citation_validation.md +794 -0
- package/skills/scientific/citation-management/references/google_scholar_search.md +725 -0
- package/skills/scientific/citation-management/references/metadata_extraction.md +870 -0
- package/skills/scientific/citation-management/references/pubmed_search.md +839 -0
- package/skills/scientific/citation-management/scripts/doi_to_bibtex.py +204 -0
- package/skills/scientific/citation-management/scripts/extract_metadata.py +569 -0
- package/skills/scientific/citation-management/scripts/format_bibtex.py +349 -0
- package/skills/scientific/citation-management/scripts/generate_schematic.py +139 -0
- package/skills/scientific/citation-management/scripts/generate_schematic_ai.py +817 -0
- package/skills/scientific/citation-management/scripts/search_google_scholar.py +282 -0
- package/skills/scientific/citation-management/scripts/search_pubmed.py +398 -0
- package/skills/scientific/citation-management/scripts/validate_citations.py +497 -0
- package/skills/scientific/database-lookup/SKILL.md +480 -0
- package/skills/scientific/database-lookup/references/addgene.md +38 -0
- package/skills/scientific/database-lookup/references/alphafold.md +40 -0
- package/skills/scientific/database-lookup/references/alphavantage.md +261 -0
- package/skills/scientific/database-lookup/references/bea.md +409 -0
- package/skills/scientific/database-lookup/references/bindingdb.md +85 -0
- package/skills/scientific/database-lookup/references/biogrid.md +110 -0
- package/skills/scientific/database-lookup/references/bls.md +235 -0
- package/skills/scientific/database-lookup/references/brenda.md +71 -0
- package/skills/scientific/database-lookup/references/cbioportal.md +206 -0
- package/skills/scientific/database-lookup/references/census.md +251 -0
- package/skills/scientific/database-lookup/references/chebi.md +103 -0
- package/skills/scientific/database-lookup/references/chembl.md +80 -0
- package/skills/scientific/database-lookup/references/clinicaltrials.md +77 -0
- package/skills/scientific/database-lookup/references/clinpgx.md +64 -0
- package/skills/scientific/database-lookup/references/clinvar.md +91 -0
- package/skills/scientific/database-lookup/references/cod.md +121 -0
- package/skills/scientific/database-lookup/references/cosmic.md +59 -0
- package/skills/scientific/database-lookup/references/dailymed.md +65 -0
- package/skills/scientific/database-lookup/references/datacommons.md +237 -0
- package/skills/scientific/database-lookup/references/dbsnp.md +143 -0
- package/skills/scientific/database-lookup/references/disgenet.md +52 -0
- package/skills/scientific/database-lookup/references/drugbank.md +54 -0
- package/skills/scientific/database-lookup/references/ecb.md +191 -0
- package/skills/scientific/database-lookup/references/emdb.md +37 -0
- package/skills/scientific/database-lookup/references/ena.md +372 -0
- package/skills/scientific/database-lookup/references/encode.md +47 -0
- package/skills/scientific/database-lookup/references/ensembl.md +539 -0
- package/skills/scientific/database-lookup/references/epa.md +232 -0
- package/skills/scientific/database-lookup/references/eurostat.md +237 -0
- package/skills/scientific/database-lookup/references/fda.md +64 -0
- package/skills/scientific/database-lookup/references/federal-reserve.md +216 -0
- package/skills/scientific/database-lookup/references/fred.md +297 -0
- package/skills/scientific/database-lookup/references/gene-ontology.md +147 -0
- package/skills/scientific/database-lookup/references/geo.md +130 -0
- package/skills/scientific/database-lookup/references/gnomad.md +93 -0
- package/skills/scientific/database-lookup/references/gtex.md +136 -0
- package/skills/scientific/database-lookup/references/gwas-catalog.md +46 -0
- package/skills/scientific/database-lookup/references/hca.md +35 -0
- package/skills/scientific/database-lookup/references/hpo.md +48 -0
- package/skills/scientific/database-lookup/references/human-protein-atlas.md +57 -0
- package/skills/scientific/database-lookup/references/interpro.md +120 -0
- package/skills/scientific/database-lookup/references/jaspar.md +50 -0
- package/skills/scientific/database-lookup/references/kegg.md +78 -0
- package/skills/scientific/database-lookup/references/lincs-l1000.md +68 -0
- package/skills/scientific/database-lookup/references/materials-project.md +123 -0
- package/skills/scientific/database-lookup/references/metabolomics-workbench.md +98 -0
- package/skills/scientific/database-lookup/references/monarch.md +46 -0
- package/skills/scientific/database-lookup/references/mousemine.md +40 -0
- package/skills/scientific/database-lookup/references/nasa-exoplanet-archive.md +112 -0
- package/skills/scientific/database-lookup/references/nasa.md +121 -0
- package/skills/scientific/database-lookup/references/ncbi-gene.md +64 -0
- package/skills/scientific/database-lookup/references/ncbi-protein.md +104 -0
- package/skills/scientific/database-lookup/references/ncbi-taxonomy.md +121 -0
- package/skills/scientific/database-lookup/references/nist.md +105 -0
- package/skills/scientific/database-lookup/references/noaa.md +199 -0
- package/skills/scientific/database-lookup/references/omim.md +114 -0
- package/skills/scientific/database-lookup/references/opentargets.md +459 -0
- package/skills/scientific/database-lookup/references/openweathermap.md +255 -0
- package/skills/scientific/database-lookup/references/pdb.md +121 -0
- package/skills/scientific/database-lookup/references/pride.md +74 -0
- package/skills/scientific/database-lookup/references/pubchem.md +145 -0
- package/skills/scientific/database-lookup/references/quickgo.md +45 -0
- package/skills/scientific/database-lookup/references/reactome.md +140 -0
- package/skills/scientific/database-lookup/references/rummageo.md +32 -0
- package/skills/scientific/database-lookup/references/sdss.md +130 -0
- package/skills/scientific/database-lookup/references/sec-edgar.md +315 -0
- package/skills/scientific/database-lookup/references/simbad.md +131 -0
- package/skills/scientific/database-lookup/references/sra.md +149 -0
- package/skills/scientific/database-lookup/references/string.md +283 -0
- package/skills/scientific/database-lookup/references/tcga-gdc.md +58 -0
- package/skills/scientific/database-lookup/references/treasury.md +215 -0
- package/skills/scientific/database-lookup/references/ucsc-genome.md +135 -0
- package/skills/scientific/database-lookup/references/uniprot.md +283 -0
- package/skills/scientific/database-lookup/references/usgs.md +260 -0
- package/skills/scientific/database-lookup/references/uspto.md +130 -0
- package/skills/scientific/database-lookup/references/who.md +283 -0
- package/skills/scientific/database-lookup/references/worldbank.md +239 -0
- package/skills/scientific/database-lookup/references/zinc.md +202 -0
- package/skills/scientific/hypothesis-generation/SKILL.md +297 -0
- package/skills/scientific/hypothesis-generation/assets/FORMATTING_GUIDE.md +672 -0
- package/skills/scientific/hypothesis-generation/assets/hypothesis_generation.sty +307 -0
- package/skills/scientific/hypothesis-generation/assets/hypothesis_report_template.tex +572 -0
- package/skills/scientific/hypothesis-generation/references/experimental_design_patterns.md +329 -0
- package/skills/scientific/hypothesis-generation/references/hypothesis_quality_criteria.md +198 -0
- package/skills/scientific/hypothesis-generation/references/literature_search_strategies.md +622 -0
- package/skills/scientific/hypothesis-generation/scripts/generate_schematic.py +139 -0
- package/skills/scientific/hypothesis-generation/scripts/generate_schematic_ai.py +817 -0
- package/skills/scientific/literature-review/SKILL.md +699 -0
- package/skills/scientific/literature-review/assets/review_template.md +412 -0
- package/skills/scientific/literature-review/references/citation_styles.md +166 -0
- package/skills/scientific/literature-review/references/database_strategies.md +455 -0
- package/skills/scientific/literature-review/scripts/generate_pdf.py +176 -0
- package/skills/scientific/literature-review/scripts/generate_schematic.py +139 -0
- package/skills/scientific/literature-review/scripts/generate_schematic_ai.py +817 -0
- package/skills/scientific/literature-review/scripts/search_databases.py +303 -0
- package/skills/scientific/literature-review/scripts/verify_citations.py +222 -0
- package/skills/scientific/markdown-mermaid-writing/SKILL.md +327 -0
- package/skills/scientific/markdown-mermaid-writing/assets/examples/example-research-report.md +221 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/architecture.md +108 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/block.md +177 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/c4.md +136 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/class.md +246 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/complex_examples.md +384 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/er.md +222 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/flowchart.md +177 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/gantt.md +138 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/git_graph.md +74 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/kanban.md +107 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/mindmap.md +74 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/packet.md +55 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/pie.md +52 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/quadrant.md +66 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/radar.md +59 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/requirement.md +88 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/sankey.md +71 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/sequence.md +174 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/state.md +150 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/timeline.md +96 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/treemap.md +66 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/user_journey.md +108 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/xy_chart.md +53 -0
- package/skills/scientific/markdown-mermaid-writing/references/diagrams/zenuml.md +71 -0
- package/skills/scientific/markdown-mermaid-writing/references/markdown_style_guide.md +733 -0
- package/skills/scientific/markdown-mermaid-writing/references/mermaid_style_guide.md +458 -0
- package/skills/scientific/markdown-mermaid-writing/templates/decision_record.md +211 -0
- package/skills/scientific/markdown-mermaid-writing/templates/how_to_guide.md +275 -0
- package/skills/scientific/markdown-mermaid-writing/templates/issue.md +303 -0
- package/skills/scientific/markdown-mermaid-writing/templates/kanban.md +223 -0
- package/skills/scientific/markdown-mermaid-writing/templates/presentation.md +312 -0
- package/skills/scientific/markdown-mermaid-writing/templates/project_documentation.md +412 -0
- package/skills/scientific/markdown-mermaid-writing/templates/pull_request.md +319 -0
- package/skills/scientific/markdown-mermaid-writing/templates/research_paper.md +304 -0
- package/skills/scientific/markdown-mermaid-writing/templates/status_report.md +185 -0
- package/skills/scientific/paper-lookup/SKILL.md +193 -0
- package/skills/scientific/paper-lookup/references/arxiv.md +161 -0
- package/skills/scientific/paper-lookup/references/biorxiv.md +118 -0
- package/skills/scientific/paper-lookup/references/core.md +150 -0
- package/skills/scientific/paper-lookup/references/crossref.md +181 -0
- package/skills/scientific/paper-lookup/references/medrxiv.md +104 -0
- package/skills/scientific/paper-lookup/references/openalex.md +174 -0
- package/skills/scientific/paper-lookup/references/pmc.md +152 -0
- package/skills/scientific/paper-lookup/references/pubmed.md +124 -0
- package/skills/scientific/paper-lookup/references/semantic-scholar.md +203 -0
- package/skills/scientific/paper-lookup/references/unpaywall.md +127 -0
- package/skills/scientific/peer-review/SKILL.md +569 -0
- package/skills/scientific/peer-review/references/common_issues.md +552 -0
- package/skills/scientific/peer-review/references/reporting_standards.md +290 -0
- package/skills/scientific/peer-review/scripts/generate_schematic.py +139 -0
- package/skills/scientific/peer-review/scripts/generate_schematic_ai.py +817 -0
- package/skills/scientific/scholar-evaluation/SKILL.md +298 -0
- package/skills/scientific/scholar-evaluation/references/evaluation_framework.md +663 -0
- package/skills/scientific/scholar-evaluation/scripts/calculate_scores.py +378 -0
- package/skills/scientific/scholar-evaluation/scripts/generate_schematic.py +139 -0
- package/skills/scientific/scholar-evaluation/scripts/generate_schematic_ai.py +817 -0
- package/skills/scientific/scientific-brainstorming/SKILL.md +189 -0
- package/skills/scientific/scientific-brainstorming/references/brainstorming_methods.md +326 -0
- package/skills/scientific/scientific-critical-thinking/SKILL.md +570 -0
- package/skills/scientific/scientific-critical-thinking/references/common_biases.md +364 -0
- package/skills/scientific/scientific-critical-thinking/references/evidence_hierarchy.md +484 -0
- package/skills/scientific/scientific-critical-thinking/references/experimental_design.md +496 -0
- package/skills/scientific/scientific-critical-thinking/references/logical_fallacies.md +478 -0
- package/skills/scientific/scientific-critical-thinking/references/scientific_method.md +169 -0
- package/skills/scientific/scientific-critical-thinking/references/statistical_pitfalls.md +506 -0
- package/skills/scientific/scientific-critical-thinking/scripts/generate_schematic.py +139 -0
- package/skills/scientific/scientific-critical-thinking/scripts/generate_schematic_ai.py +817 -0
- package/skills/wotann-imports/incremental-implementation.md +241 -0
- package/skills/wotann-imports/security-threat-model.md +81 -0
- package/skills/wotann-imports/triage.md +103 -0
- package/dist/build/deploy-targets/coolify.d.ts +0 -148
- package/dist/build/deploy-targets/coolify.d.ts.map +0 -1
- package/dist/build/deploy-targets/coolify.js +0 -339
- package/dist/build/deploy-targets/coolify.js.map +0 -1
- package/dist/build/deploy-targets/dokploy.d.ts +0 -139
- package/dist/build/deploy-targets/dokploy.d.ts.map +0 -1
- package/dist/build/deploy-targets/dokploy.js +0 -339
- package/dist/build/deploy-targets/dokploy.js.map +0 -1
- package/dist/claude/hardening/error-handler.d.ts +0 -52
- package/dist/claude/hardening/error-handler.d.ts.map +0 -1
- package/dist/claude/hardening/error-handler.js +0 -158
- package/dist/claude/hardening/error-handler.js.map +0 -1
- package/dist/cli/onboarding.d.ts +0 -34
- package/dist/cli/onboarding.d.ts.map +0 -1
- package/dist/cli/onboarding.js +0 -150
- package/dist/cli/onboarding.js.map +0 -1
- package/dist/core/agent-profiles.d.ts +0 -65
- package/dist/core/agent-profiles.d.ts.map +0 -1
- package/dist/core/agent-profiles.js +0 -137
- package/dist/core/agent-profiles.js.map +0 -1
- package/dist/desktop/supabase-relay.d.ts +0 -86
- package/dist/desktop/supabase-relay.d.ts.map +0 -1
- package/dist/desktop/supabase-relay.js +0 -335
- package/dist/desktop/supabase-relay.js.map +0 -1
- package/dist/intelligence/kg-builder.d.ts +0 -181
- package/dist/intelligence/kg-builder.d.ts.map +0 -1
- package/dist/intelligence/kg-builder.js +0 -807
- package/dist/intelligence/kg-builder.js.map +0 -1
- package/dist/orchestration/jean-orchestrator.d.ts +0 -79
- package/dist/orchestration/jean-orchestrator.d.ts.map +0 -1
- package/dist/orchestration/jean-orchestrator.js +0 -253
- package/dist/orchestration/jean-orchestrator.js.map +0 -1
- package/dist/orchestration/jean-registries/command-registry.d.ts +0 -85
- package/dist/orchestration/jean-registries/command-registry.d.ts.map +0 -1
- package/dist/orchestration/jean-registries/command-registry.js +0 -120
- package/dist/orchestration/jean-registries/command-registry.js.map +0 -1
- package/dist/orchestration/jean-registries/event-registry.d.ts +0 -80
- package/dist/orchestration/jean-registries/event-registry.d.ts.map +0 -1
- package/dist/orchestration/jean-registries/event-registry.js +0 -147
- package/dist/orchestration/jean-registries/event-registry.js.map +0 -1
- package/dist/orchestration/jean-registries/process-registry.d.ts +0 -71
- package/dist/orchestration/jean-registries/process-registry.d.ts.map +0 -1
- package/dist/orchestration/jean-registries/process-registry.js +0 -104
- package/dist/orchestration/jean-registries/process-registry.js.map +0 -1
- package/dist/orchestration/jean-registries/result-registry.d.ts +0 -71
- package/dist/orchestration/jean-registries/result-registry.d.ts.map +0 -1
- package/dist/orchestration/jean-registries/result-registry.js +0 -97
- package/dist/orchestration/jean-registries/result-registry.js.map +0 -1
- package/dist/providers/bedrock-signer.d.ts +0 -23
- package/dist/providers/bedrock-signer.d.ts.map +0 -1
- package/dist/providers/bedrock-signer.js +0 -439
- package/dist/providers/bedrock-signer.js.map +0 -1
- package/dist/providers/harness-profiles.d.ts +0 -70
- package/dist/providers/harness-profiles.d.ts.map +0 -1
- package/dist/providers/harness-profiles.js +0 -210
- package/dist/providers/harness-profiles.js.map +0 -1
- package/dist/providers/vertex-oauth.d.ts +0 -21
- package/dist/providers/vertex-oauth.d.ts.map +0 -1
- package/dist/providers/vertex-oauth.js +0 -393
- package/dist/providers/vertex-oauth.js.map +0 -1
- package/dist/sandbox/backends/cloud-auth.d.ts +0 -50
- package/dist/sandbox/backends/cloud-auth.d.ts.map +0 -1
- package/dist/sandbox/backends/cloud-auth.js +0 -93
- package/dist/sandbox/backends/cloud-auth.js.map +0 -1
- package/dist/security/anti-distillation.d.ts +0 -46
- package/dist/security/anti-distillation.d.ts.map +0 -1
- package/dist/security/anti-distillation.js +0 -358
- package/dist/security/anti-distillation.js.map +0 -1
- package/dist/security/multi-encoding-decoder.d.ts +0 -47
- package/dist/security/multi-encoding-decoder.d.ts.map +0 -1
- package/dist/security/multi-encoding-decoder.js +0 -336
- package/dist/security/multi-encoding-decoder.js.map +0 -1
- package/dist/ui/accessibility.d.ts +0 -157
- package/dist/ui/accessibility.d.ts.map +0 -1
- package/dist/ui/accessibility.js +0 -232
- package/dist/ui/accessibility.js.map +0 -1
- package/dist/ui/animations.d.ts +0 -102
- package/dist/ui/animations.d.ts.map +0 -1
- package/dist/ui/animations.js +0 -277
- package/dist/ui/animations.js.map +0 -1
- package/dist/ui/components/Sparkline.d.ts +0 -81
- package/dist/ui/components/Sparkline.d.ts.map +0 -1
- package/dist/ui/components/Sparkline.js +0 -102
- package/dist/ui/components/Sparkline.js.map +0 -1
- package/dist/ui/input/mouse.d.ts +0 -139
- package/dist/ui/input/mouse.d.ts.map +0 -1
- package/dist/ui/input/mouse.js +0 -239
- package/dist/ui/input/mouse.js.map +0 -1
- package/dist/ui/sound.d.ts +0 -85
- package/dist/ui/sound.d.ts.map +0 -1
- package/dist/ui/sound.js +0 -126
- package/dist/ui/sound.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -13,6 +13,8 @@ import { execFileNoThrow } from "./utils/execFileNoThrow.js";
|
|
|
13
13
|
import { setupProxyFromEnv } from "./utils/proxy-setup.js";
|
|
14
14
|
import { resolveWotannHome, resolveWotannHomeSubdir } from "./utils/wotann-home.js";
|
|
15
15
|
import { installProcessHandlers } from "./utils/process-handlers.js";
|
|
16
|
+
import { resolveDaemonSocketPath } from "./daemon/transport/socket-path.js";
|
|
17
|
+
import { buildShellCommand } from "./utils/platform.js";
|
|
16
18
|
// V9 Wave 6-RR (SB-9): install uncaughtException + unhandledRejection
|
|
17
19
|
// handlers BEFORE any subsystem boots. Without this, a single async
|
|
18
20
|
// rejection silently exits the CLI under Node ≥15 default behavior with
|
|
@@ -25,6 +27,12 @@ installProcessHandlers({ tag: "wotann-cli" });
|
|
|
25
27
|
// No-op when no proxy env var is set; never crashes startup on bad proxy URLs.
|
|
26
28
|
setupProxyFromEnv();
|
|
27
29
|
const VERSION = (() => {
|
|
30
|
+
// Prefer build-time injection (SEA, dev builds, anything bundled).
|
|
31
|
+
if (typeof __WOTANN_VERSION__ === "string" && __WOTANN_VERSION__.length > 0) {
|
|
32
|
+
return __WOTANN_VERSION__;
|
|
33
|
+
}
|
|
34
|
+
// Runtime fallback — node_modules install where `import.meta.url`
|
|
35
|
+
// resolves correctly relative to package.json.
|
|
28
36
|
try {
|
|
29
37
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
30
38
|
const pkgPath = resolve(here, "..", "package.json");
|
|
@@ -154,19 +162,19 @@ program
|
|
|
154
162
|
process.exit(1);
|
|
155
163
|
}
|
|
156
164
|
}
|
|
157
|
-
//
|
|
158
|
-
//
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
//
|
|
169
|
-
|
|
165
|
+
// Full runtime is the default. Thin-client TUI is opt-in via
|
|
166
|
+
// `--thin` or `WOTANN_THIN=1` and provides a much faster cold start
|
|
167
|
+
// (~150 ms vs ~2-5 s) by talking to a running daemon over IPC
|
|
168
|
+
// instead of standing up a fresh 408-module runtime in-process.
|
|
169
|
+
// If thin is requested but no daemon socket exists, launchOrFallback
|
|
170
|
+
// returns false and we fall through to the full runtime silently.
|
|
171
|
+
const requestedThin = process.env["WOTANN_THIN"] === "1" || process.argv.includes("--thin");
|
|
172
|
+
if (requestedThin && !options.pipe) {
|
|
173
|
+
const { launchOrFallback } = await import("./cli/thin-client.js");
|
|
174
|
+
const launched = await launchOrFallback();
|
|
175
|
+
if (launched)
|
|
176
|
+
return; // thin TUI rendered and exited
|
|
177
|
+
// else fall through to full runtime
|
|
170
178
|
}
|
|
171
179
|
const [{ render }, ReactModule, { WotannApp }] = await Promise.all([
|
|
172
180
|
import("ink"),
|
|
@@ -226,10 +234,23 @@ program
|
|
|
226
234
|
.description("Generate iOS pairing details from the running daemon")
|
|
227
235
|
.action(async () => {
|
|
228
236
|
const { KairosIPCClient } = await import("./daemon/kairos-ipc.js");
|
|
229
|
-
|
|
230
|
-
|
|
237
|
+
let ipcClient = new KairosIPCClient(undefined, { requestTimeoutMs: 5_000 });
|
|
238
|
+
let daemonAvailable = await ipcClient.connect();
|
|
231
239
|
if (!daemonAvailable) {
|
|
232
|
-
|
|
240
|
+
ipcClient.disconnect();
|
|
241
|
+
const repaired = await ensureDaemonIpcForCommand({
|
|
242
|
+
label: "KAIROS daemon",
|
|
243
|
+
announce: "KAIROS daemon IPC is unavailable; starting or repairing the daemon...",
|
|
244
|
+
});
|
|
245
|
+
if (repaired) {
|
|
246
|
+
ipcClient = new KairosIPCClient(undefined, { requestTimeoutMs: 5_000 });
|
|
247
|
+
daemonAvailable = await ipcClient.connect();
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (!daemonAvailable) {
|
|
251
|
+
console.error(chalk.red.bold("\n KAIROS daemon IPC is not reachable.\n"));
|
|
252
|
+
console.error(chalk.dim(await formatDaemonHealthDiagnostic(" ")));
|
|
253
|
+
console.error();
|
|
233
254
|
console.error(chalk.yellow(" To fix, do ONE of these:\n"));
|
|
234
255
|
console.error(chalk.dim(" 1. Open the WOTANN desktop app (auto-starts daemon)"));
|
|
235
256
|
console.error(chalk.dim(" 2. Run: ") + chalk.white("wotann daemon start"));
|
|
@@ -266,6 +287,25 @@ program
|
|
|
266
287
|
console.log();
|
|
267
288
|
console.log(chalk.dim(` Host: ${pairing.host ?? "unknown"}`));
|
|
268
289
|
console.log(chalk.dim(` Port: ${pairing.port ?? 3849}`));
|
|
290
|
+
const remoteEndpoints = pairing.remoteEndpoints ?? [];
|
|
291
|
+
if (remoteEndpoints.length > 0) {
|
|
292
|
+
console.log(chalk.dim(" Remote:"));
|
|
293
|
+
for (const endpoint of remoteEndpoints) {
|
|
294
|
+
const scheme = endpoint.scheme ?? "ws";
|
|
295
|
+
const host = endpoint.host ?? "unknown";
|
|
296
|
+
const port = endpoint.port ?? (scheme === "wss" ? 443 : 3849);
|
|
297
|
+
const label = endpoint.label ?? "Remote";
|
|
298
|
+
console.log(chalk.dim(` ${label}: ${scheme}://${host}:${port}`));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
else if (pairing.remoteAccess) {
|
|
302
|
+
console.log(chalk.dim(` Remote: ${pairing.remoteAccess.status ?? "missing-endpoint"}`));
|
|
303
|
+
console.log(chalk.dim(` ${pairing.remoteAccess.message ?? "Same network only."}`));
|
|
304
|
+
const recommended = pairing.remoteAccess.setupOptions?.find((option) => option.id === "tailscale");
|
|
305
|
+
if (recommended) {
|
|
306
|
+
console.log(chalk.dim(` ${recommended.label}: ${recommended.detail}`));
|
|
307
|
+
}
|
|
308
|
+
}
|
|
269
309
|
console.log(chalk.dim(` PIN: ${pairing.pin}`));
|
|
270
310
|
console.log(chalk.dim(` Expires: ${pairing.expiresAt}`));
|
|
271
311
|
console.log();
|
|
@@ -274,6 +314,77 @@ program
|
|
|
274
314
|
ipcClient.disconnect();
|
|
275
315
|
}
|
|
276
316
|
});
|
|
317
|
+
// ── wotann remote ───────────────────────────────────────────
|
|
318
|
+
program
|
|
319
|
+
.command("remote [actionOrUrl] [url]")
|
|
320
|
+
.description("Inspect or configure the iOS off-WiFi endpoint")
|
|
321
|
+
.option("--clear", "Remove the persisted remote endpoint")
|
|
322
|
+
.action(async (actionOrUrl, url, options) => {
|
|
323
|
+
const { KairosIPCClient } = await import("./daemon/kairos-ipc.js");
|
|
324
|
+
let ipcClient = new KairosIPCClient(undefined, { requestTimeoutMs: 5_000 });
|
|
325
|
+
let daemonAvailable = await ipcClient.connect();
|
|
326
|
+
if (!daemonAvailable) {
|
|
327
|
+
ipcClient.disconnect();
|
|
328
|
+
const repaired = await ensureDaemonIpcForCommand({
|
|
329
|
+
label: "KAIROS daemon",
|
|
330
|
+
announce: "KAIROS daemon IPC is unavailable; starting or repairing the daemon...",
|
|
331
|
+
});
|
|
332
|
+
if (repaired) {
|
|
333
|
+
ipcClient = new KairosIPCClient(undefined, { requestTimeoutMs: 5_000 });
|
|
334
|
+
daemonAvailable = await ipcClient.connect();
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (!daemonAvailable) {
|
|
338
|
+
console.error(chalk.red.bold("\n KAIROS daemon IPC is not reachable.\n"));
|
|
339
|
+
console.error(chalk.dim(await formatDaemonHealthDiagnostic(" ")));
|
|
340
|
+
process.exit(1);
|
|
341
|
+
}
|
|
342
|
+
try {
|
|
343
|
+
const action = actionOrUrl?.trim();
|
|
344
|
+
const targetUrl = action === "set" || action === "configure"
|
|
345
|
+
? url?.trim()
|
|
346
|
+
: action && action !== "status" && action !== "clear"
|
|
347
|
+
? action
|
|
348
|
+
: undefined;
|
|
349
|
+
if ((action === "set" || action === "configure") && !targetUrl) {
|
|
350
|
+
console.error(chalk.red("Usage: wotann remote set <ws|wss|http|https-url>"));
|
|
351
|
+
process.exitCode = 1;
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
const status = options.clear || action === "clear"
|
|
355
|
+
? await ipcClient.call("companion.remote.clear")
|
|
356
|
+
: targetUrl
|
|
357
|
+
? await ipcClient.call("companion.remote.configure", { url: targetUrl })
|
|
358
|
+
: await ipcClient.call("companion.remote.status");
|
|
359
|
+
const remote = status;
|
|
360
|
+
console.log(chalk.bold("\nWOTANN Remote Access\n"));
|
|
361
|
+
console.log(chalk.dim(` Status: ${remote.status ?? "unknown"}`));
|
|
362
|
+
console.log(chalk.dim(` Mode: ${remote.mode ?? "unknown"}`));
|
|
363
|
+
if (remote.message)
|
|
364
|
+
console.log(chalk.dim(` ${remote.message}`));
|
|
365
|
+
const endpoints = remote.endpoints ?? [];
|
|
366
|
+
if (endpoints.length > 0) {
|
|
367
|
+
console.log();
|
|
368
|
+
for (const endpoint of endpoints) {
|
|
369
|
+
const scheme = endpoint.scheme ?? "ws";
|
|
370
|
+
const port = endpoint.port ?? (scheme === "wss" ? 443 : 3849);
|
|
371
|
+
console.log(chalk.dim(` ${endpoint.label ?? "Remote"}: ${scheme}://${endpoint.host ?? "unknown"}:${port}`));
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
else {
|
|
375
|
+
const configured = remote.setupOptions?.find((option) => option.id === "configured-url");
|
|
376
|
+
if (configured?.command) {
|
|
377
|
+
console.log();
|
|
378
|
+
console.log(chalk.dim(` Configure: ${configured.command}`));
|
|
379
|
+
console.log(chalk.dim(" Or run: wotann remote set wss://your-host.example"));
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
console.log();
|
|
383
|
+
}
|
|
384
|
+
finally {
|
|
385
|
+
ipcClient.disconnect();
|
|
386
|
+
}
|
|
387
|
+
});
|
|
277
388
|
// ── wotann init ──────────────────────────────────────────────
|
|
278
389
|
program
|
|
279
390
|
.command("init")
|
|
@@ -317,10 +428,29 @@ program
|
|
|
317
428
|
console.log(chalk.dim(` Then start a new shell. WOTANN will render Warp-style blocks for every command.`));
|
|
318
429
|
return;
|
|
319
430
|
}
|
|
320
|
-
//
|
|
321
|
-
// legacy chalk flow
|
|
322
|
-
//
|
|
323
|
-
|
|
431
|
+
// Interactive Ink wizard is now the default for `wotann init`
|
|
432
|
+
// (with no flags). The legacy chalk flow runs only when the user
|
|
433
|
+
// passes an explicit mode flag (--free, --minimal, --advanced,
|
|
434
|
+
// --reset) — those flags imply the user knows what they want and
|
|
435
|
+
// the report-style output is more useful as a confirmation than
|
|
436
|
+
// as a hand-holding wizard. `--wizard` is kept as a no-op alias.
|
|
437
|
+
const hasExplicitMode = Boolean(options.free ||
|
|
438
|
+
options.minimal ||
|
|
439
|
+
options.advanced ||
|
|
440
|
+
options.reset ||
|
|
441
|
+
options.tdd ||
|
|
442
|
+
options.extendedContext);
|
|
443
|
+
// Only launch the wizard when stdin is a real TTY. Non-TTY runs
|
|
444
|
+
// (CI, piped input, headless scripts) fall through to the legacy
|
|
445
|
+
// chalk path because Ink's wizard requires raw-mode keyboard
|
|
446
|
+
// capture and crashes with "Raw mode is not supported" on a piped
|
|
447
|
+
// stdin — that's what broke `tests/e2e/cli-commands.test.ts >
|
|
448
|
+
// wotann init` after the wizard-by-default flip. `--wizard`
|
|
449
|
+
// overrides this gate so a user who really wants the TUI from a
|
|
450
|
+
// weird terminal can still get it (and accept the crash if their
|
|
451
|
+
// stdin doesn't support raw mode).
|
|
452
|
+
const isInteractiveTTY = Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
|
|
453
|
+
if ((!hasExplicitMode && isInteractiveTTY) || options.wizard) {
|
|
324
454
|
const { runOnboardingWizard } = await import("./cli/run-onboarding-wizard.js");
|
|
325
455
|
await runOnboardingWizard();
|
|
326
456
|
return;
|
|
@@ -1312,6 +1442,73 @@ program
|
|
|
1312
1442
|
runtime: interactive.runtime,
|
|
1313
1443
|
}));
|
|
1314
1444
|
});
|
|
1445
|
+
// ── wotann rewind ───────────────────────────────────────────
|
|
1446
|
+
//
|
|
1447
|
+
// Drop the last N user-bounded turns (or raw messages, with --messages)
|
|
1448
|
+
// from a saved session. Useful when the agent went off-track and you'd
|
|
1449
|
+
// rather rewind than /clear and lose the whole conversation. Writes the
|
|
1450
|
+
// rewound session back to disk; the original is overwritten — pass
|
|
1451
|
+
// --dry-run to preview without saving.
|
|
1452
|
+
program
|
|
1453
|
+
.command("rewind")
|
|
1454
|
+
.description("Rewind the latest (or named) session by N turns or messages")
|
|
1455
|
+
.option("--id <sessionId>", "Rewind a specific session by id (default: latest)")
|
|
1456
|
+
.option("--steps <n>", "Number of user-bounded turns to drop", "1")
|
|
1457
|
+
.option("--messages <n>", "Drop raw messages instead of full turns (mutually exclusive with --steps)")
|
|
1458
|
+
.option("--dry-run", "Show what would be removed without writing", false)
|
|
1459
|
+
.action(async (options) => {
|
|
1460
|
+
const { findLatestSession, restoreSession, saveSession } = await import("./core/session.js");
|
|
1461
|
+
const { rewindBySteps, rewindByMessages } = await import("./core/session-rewind.js");
|
|
1462
|
+
const sessionDir = join(process.cwd(), ".wotann", "sessions");
|
|
1463
|
+
let sessionPath = null;
|
|
1464
|
+
if (options.id) {
|
|
1465
|
+
if (!/^[a-zA-Z0-9_-]+$/.test(options.id)) {
|
|
1466
|
+
console.error(chalk.red(`error: invalid session id "${options.id}"`));
|
|
1467
|
+
process.exit(2);
|
|
1468
|
+
}
|
|
1469
|
+
const candidate = join(sessionDir, `${options.id}.json`);
|
|
1470
|
+
sessionPath = existsSync(candidate) ? candidate : null;
|
|
1471
|
+
}
|
|
1472
|
+
else {
|
|
1473
|
+
sessionPath = findLatestSession(sessionDir);
|
|
1474
|
+
}
|
|
1475
|
+
if (!sessionPath) {
|
|
1476
|
+
console.error(chalk.yellow("No matching session found."));
|
|
1477
|
+
process.exit(1);
|
|
1478
|
+
}
|
|
1479
|
+
const session = restoreSession(sessionPath);
|
|
1480
|
+
if (!session) {
|
|
1481
|
+
console.error(chalk.red("Failed to read session."));
|
|
1482
|
+
process.exit(1);
|
|
1483
|
+
}
|
|
1484
|
+
const useMessages = typeof options.messages === "string";
|
|
1485
|
+
const n = Number(useMessages ? options.messages : options.steps);
|
|
1486
|
+
if (!Number.isFinite(n) || n <= 0) {
|
|
1487
|
+
console.error(chalk.red(`error: count must be a positive integer (got "${n}")`));
|
|
1488
|
+
process.exit(2);
|
|
1489
|
+
}
|
|
1490
|
+
const result = useMessages ? rewindByMessages(session, n) : rewindBySteps(session, n);
|
|
1491
|
+
if (!result.changed) {
|
|
1492
|
+
console.log(chalk.dim("Nothing to rewind."));
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
console.log(chalk.bold(`\nRewinding ${useMessages ? "messages" : "turns"}: ${n}`));
|
|
1496
|
+
console.log(chalk.dim(` Session : ${session.id}`));
|
|
1497
|
+
console.log(chalk.dim(` Removed : ${result.removed.length} message(s) — totals recomputed`));
|
|
1498
|
+
for (const m of result.removed.slice(0, 6)) {
|
|
1499
|
+
const preview = (m.content ?? "").replace(/\s+/g, " ").slice(0, 80);
|
|
1500
|
+
console.log(chalk.dim(` [${m.role}] ${preview}${preview.length === 80 ? "…" : ""}`));
|
|
1501
|
+
}
|
|
1502
|
+
if (result.removed.length > 6) {
|
|
1503
|
+
console.log(chalk.dim(` … and ${result.removed.length - 6} more`));
|
|
1504
|
+
}
|
|
1505
|
+
if (options.dryRun === true) {
|
|
1506
|
+
console.log(chalk.yellow("\n--dry-run: not writing changes."));
|
|
1507
|
+
return;
|
|
1508
|
+
}
|
|
1509
|
+
const writtenPath = saveSession(result.session, sessionDir);
|
|
1510
|
+
console.log(chalk.green(`\n✓ Wrote rewound session to ${writtenPath}`));
|
|
1511
|
+
});
|
|
1315
1512
|
// ── wotann next ─────────────────────────────────────────────
|
|
1316
1513
|
program
|
|
1317
1514
|
.command("next")
|
|
@@ -1430,13 +1627,26 @@ daemonCmd
|
|
|
1430
1627
|
// status file already reflects the loaded heartbeat tasks
|
|
1431
1628
|
}
|
|
1432
1629
|
});
|
|
1630
|
+
daemonCmd
|
|
1631
|
+
.command("jsonl")
|
|
1632
|
+
.description("Run a foreground JSON-RPC daemon gateway over stdin/stdout")
|
|
1633
|
+
.action(async () => {
|
|
1634
|
+
try {
|
|
1635
|
+
const { runKairosJsonlMode } = await import("./daemon/jsonl-mode.js");
|
|
1636
|
+
await runKairosJsonlMode();
|
|
1637
|
+
}
|
|
1638
|
+
catch (error) {
|
|
1639
|
+
process.stderr.write(`[KAIROS JSONL] ${error instanceof Error ? error.message : String(error)}\n`);
|
|
1640
|
+
process.exit(1);
|
|
1641
|
+
}
|
|
1642
|
+
});
|
|
1433
1643
|
daemonCmd
|
|
1434
1644
|
.command("start")
|
|
1435
1645
|
.description("Start the background daemon")
|
|
1436
1646
|
.option("-v, --verbose", "Stream daemon log output to the terminal for the startup window")
|
|
1437
1647
|
.action(async (opts) => {
|
|
1438
1648
|
const { existsSync, mkdirSync, readFileSync } = await import("node:fs");
|
|
1439
|
-
const { pidPath } = getDaemonPaths();
|
|
1649
|
+
const { pidPath, statusPath } = getDaemonPaths();
|
|
1440
1650
|
const wotannDir = join(process.cwd(), ".wotann");
|
|
1441
1651
|
// TIER 4 fix: 0o700 perms — .wotann/ holds memory DBs, conversation cache,
|
|
1442
1652
|
// potentially OAuth tokens. Other-user-readable could leak credentials.
|
|
@@ -1445,8 +1655,24 @@ daemonCmd
|
|
|
1445
1655
|
if (existsSync(pidPath)) {
|
|
1446
1656
|
const existingPid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
1447
1657
|
if (isProcessAlive(existingPid)) {
|
|
1448
|
-
|
|
1449
|
-
|
|
1658
|
+
const ipcReachable = await isDaemonIpcReachable();
|
|
1659
|
+
if (ipcReachable) {
|
|
1660
|
+
console.log(chalk.yellow(`KAIROS daemon already running (PID ${existingPid}).`));
|
|
1661
|
+
return;
|
|
1662
|
+
}
|
|
1663
|
+
else {
|
|
1664
|
+
console.log(chalk.yellow(`KAIROS daemon PID ${existingPid} is alive, but the IPC socket is not reachable.`));
|
|
1665
|
+
console.log(chalk.dim("Repairing by restarting the daemon process..."));
|
|
1666
|
+
const stopped = await stopDaemonProcess(existingPid, "KAIROS daemon");
|
|
1667
|
+
if (!stopped) {
|
|
1668
|
+
console.error(chalk.red(`Could not stop KAIROS daemon PID ${existingPid}.`));
|
|
1669
|
+
process.exit(1);
|
|
1670
|
+
}
|
|
1671
|
+
await cleanupDaemonStateFiles(pidPath, statusPath);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
else {
|
|
1675
|
+
await cleanupDaemonStateFiles(pidPath, statusPath);
|
|
1450
1676
|
}
|
|
1451
1677
|
}
|
|
1452
1678
|
const entryPath = fileURLToPath(import.meta.url);
|
|
@@ -1465,7 +1691,7 @@ daemonCmd
|
|
|
1465
1691
|
process.exit(0);
|
|
1466
1692
|
});
|
|
1467
1693
|
}
|
|
1468
|
-
const ready = await waitForDaemonReady(pidPath,
|
|
1694
|
+
const ready = await waitForDaemonReady(pidPath, 15_000);
|
|
1469
1695
|
if (!ready) {
|
|
1470
1696
|
console.error(chalk.red("KAIROS daemon failed to start."));
|
|
1471
1697
|
process.exit(1);
|
|
@@ -1531,7 +1757,16 @@ daemonCmd
|
|
|
1531
1757
|
if (existsSync(pidPath)) {
|
|
1532
1758
|
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
1533
1759
|
if (isProcessAlive(pid)) {
|
|
1534
|
-
|
|
1760
|
+
const ipcReachable = await isDaemonIpcReachable();
|
|
1761
|
+
if (ipcReachable) {
|
|
1762
|
+
console.log(chalk.green(`KAIROS daemon running (PID ${pid})`));
|
|
1763
|
+
console.log(chalk.dim(" IPC: reachable"));
|
|
1764
|
+
}
|
|
1765
|
+
else {
|
|
1766
|
+
console.log(chalk.yellow(`KAIROS daemon process alive (PID ${pid}), but IPC is unreachable`));
|
|
1767
|
+
console.log(chalk.dim(" IPC: not reachable"));
|
|
1768
|
+
console.log(chalk.dim(" Run `wotann daemon start` to repair it."));
|
|
1769
|
+
}
|
|
1535
1770
|
if (existsSync(statusPath)) {
|
|
1536
1771
|
try {
|
|
1537
1772
|
const status = JSON.parse(readFileSync(statusPath, "utf-8"));
|
|
@@ -1564,7 +1799,7 @@ engineCmd
|
|
|
1564
1799
|
.description("Start the WOTANN engine (background daemon with runtime hosting)")
|
|
1565
1800
|
.action(async () => {
|
|
1566
1801
|
const { existsSync, mkdirSync, readFileSync } = await import("node:fs");
|
|
1567
|
-
const { pidPath } = getDaemonPaths();
|
|
1802
|
+
const { pidPath, statusPath } = getDaemonPaths();
|
|
1568
1803
|
const wotannDir = join(process.cwd(), ".wotann");
|
|
1569
1804
|
// TIER 4 fix: 0o700 perms — .wotann/ holds memory DBs, conversation cache,
|
|
1570
1805
|
// potentially OAuth tokens. Other-user-readable could leak credentials.
|
|
@@ -1573,8 +1808,24 @@ engineCmd
|
|
|
1573
1808
|
if (existsSync(pidPath)) {
|
|
1574
1809
|
const existingPid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
1575
1810
|
if (isProcessAlive(existingPid)) {
|
|
1576
|
-
|
|
1577
|
-
|
|
1811
|
+
const ipcReachable = await isDaemonIpcReachable();
|
|
1812
|
+
if (ipcReachable) {
|
|
1813
|
+
console.log(chalk.yellow(`WOTANN engine already running (PID ${existingPid}).`));
|
|
1814
|
+
return;
|
|
1815
|
+
}
|
|
1816
|
+
else {
|
|
1817
|
+
console.log(chalk.yellow(`WOTANN engine PID ${existingPid} is alive, but the IPC socket is not reachable.`));
|
|
1818
|
+
console.log(chalk.dim("Repairing by restarting the engine process..."));
|
|
1819
|
+
const stopped = await stopDaemonProcess(existingPid, "WOTANN engine");
|
|
1820
|
+
if (!stopped) {
|
|
1821
|
+
console.error(chalk.red(`Could not stop WOTANN engine PID ${existingPid}.`));
|
|
1822
|
+
process.exit(1);
|
|
1823
|
+
}
|
|
1824
|
+
await cleanupDaemonStateFiles(pidPath, statusPath);
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
else {
|
|
1828
|
+
await cleanupDaemonStateFiles(pidPath, statusPath);
|
|
1578
1829
|
}
|
|
1579
1830
|
}
|
|
1580
1831
|
const entryPath = fileURLToPath(import.meta.url);
|
|
@@ -1582,7 +1833,7 @@ engineCmd
|
|
|
1582
1833
|
// daemon runs independently. `void` marks the discard explicitly so
|
|
1583
1834
|
// future readers don't think the handle was forgotten by accident.
|
|
1584
1835
|
void spawnDaemonWorker(entryPath, process.cwd());
|
|
1585
|
-
const ready = await waitForDaemonReady(pidPath,
|
|
1836
|
+
const ready = await waitForDaemonReady(pidPath, 15_000);
|
|
1586
1837
|
if (!ready) {
|
|
1587
1838
|
console.error(chalk.red("WOTANN engine failed to start."));
|
|
1588
1839
|
process.exit(1);
|
|
@@ -1669,7 +1920,16 @@ engineCmd
|
|
|
1669
1920
|
if (existsSync(pidPath)) {
|
|
1670
1921
|
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
1671
1922
|
if (isProcessAlive(pid)) {
|
|
1672
|
-
|
|
1923
|
+
const ipcReachable = await isDaemonIpcReachable();
|
|
1924
|
+
if (ipcReachable) {
|
|
1925
|
+
console.log(chalk.green(`WOTANN engine running (PID ${pid})`));
|
|
1926
|
+
console.log(chalk.dim(" IPC: reachable"));
|
|
1927
|
+
}
|
|
1928
|
+
else {
|
|
1929
|
+
console.log(chalk.yellow(`WOTANN engine process alive (PID ${pid}), but IPC is unreachable`));
|
|
1930
|
+
console.log(chalk.dim(" IPC: not reachable"));
|
|
1931
|
+
console.log(chalk.dim(" Run `wotann engine start` to repair it."));
|
|
1932
|
+
}
|
|
1673
1933
|
if (existsSync(statusPath)) {
|
|
1674
1934
|
try {
|
|
1675
1935
|
// Wave 4F: richer telemetry emitted every 30s by the
|
|
@@ -1789,7 +2049,7 @@ engineCmd
|
|
|
1789
2049
|
}
|
|
1790
2050
|
const entryPath = fileURLToPath(import.meta.url);
|
|
1791
2051
|
void spawnDaemonWorker(entryPath, process.cwd());
|
|
1792
|
-
const ready = await waitForDaemonReady(pidPath,
|
|
2052
|
+
const ready = await waitForDaemonReady(pidPath, 15_000);
|
|
1793
2053
|
if (!ready) {
|
|
1794
2054
|
console.error(chalk.red("WOTANN engine failed to restart."));
|
|
1795
2055
|
process.exit(1);
|
|
@@ -3037,6 +3297,8 @@ mcpCmd
|
|
|
3037
3297
|
.option("--from-codex", "Import from ~/.codex/mcp.json")
|
|
3038
3298
|
.option("--from-vscode", "Import from VSCode settings.json (stable + Insiders, mac/linux/win)")
|
|
3039
3299
|
.option("--dry-run", "List what would be imported without modifying ~/.wotann/mcp.json")
|
|
3300
|
+
.option("--skip-malware-check", "Skip the OSV.dev malware/CVE pre-flight (not recommended)", false)
|
|
3301
|
+
.option("--strict-malware-check", "Block on high/critical CVEs (default: only block confirmed malware)", false)
|
|
3040
3302
|
.description("Import MCP servers from other tools (Claude/Cursor/Windsurf/Codex/VSCode) into ~/.wotann/mcp.json")
|
|
3041
3303
|
.action(async (options) => {
|
|
3042
3304
|
const { MCPRegistry } = await import("./marketplace/registry.js");
|
|
@@ -3092,6 +3354,21 @@ mcpCmd
|
|
|
3092
3354
|
console.log();
|
|
3093
3355
|
return;
|
|
3094
3356
|
}
|
|
3357
|
+
// OSV.dev malware/CVE pre-flight — gated before persistToDisk so a
|
|
3358
|
+
// typosquat or compromised package never reaches user config.
|
|
3359
|
+
const { preflight: osvPreflight } = await import("./security/osv-check.js");
|
|
3360
|
+
const importedServers = registry.getAllServers().map((s) => ({
|
|
3361
|
+
name: s.name,
|
|
3362
|
+
command: s.command,
|
|
3363
|
+
args: [...s.args],
|
|
3364
|
+
}));
|
|
3365
|
+
const osvVerdict = await osvPreflight(importedServers, {
|
|
3366
|
+
skip: options.skipMalwareCheck === true,
|
|
3367
|
+
strict: options.strictMalwareCheck === true,
|
|
3368
|
+
});
|
|
3369
|
+
if (!osvVerdict.proceed) {
|
|
3370
|
+
process.exit(1);
|
|
3371
|
+
}
|
|
3095
3372
|
// Persist to ~/.wotann/mcp.json so other wotann commands see the
|
|
3096
3373
|
// imports.
|
|
3097
3374
|
const path = registry.persistToDisk();
|
|
@@ -3161,6 +3438,8 @@ mcpCmd
|
|
|
3161
3438
|
.option("--args <args...>", "Arguments passed to the command (space-separated)")
|
|
3162
3439
|
.option("--transport <transport>", "Transport: stdio (default) or http", "stdio")
|
|
3163
3440
|
.option("-f, --force", "Overwrite an existing server with the same name", false)
|
|
3441
|
+
.option("--skip-malware-check", "Skip the OSV.dev malware/CVE pre-flight (not recommended)", false)
|
|
3442
|
+
.option("--strict-malware-check", "Block on high/critical CVEs (default: only block confirmed malware)", false)
|
|
3164
3443
|
.action(async (name, options) => {
|
|
3165
3444
|
if (!options.command) {
|
|
3166
3445
|
console.error(chalk.red("error: --command <cmd> is required"));
|
|
@@ -3189,6 +3468,16 @@ mcpCmd
|
|
|
3189
3468
|
console.error(chalk.dim("Use --force to overwrite, or `wotann mcp list` to see existing servers."));
|
|
3190
3469
|
process.exit(1);
|
|
3191
3470
|
}
|
|
3471
|
+
// OSV.dev malware/CVE pre-flight — gated before write so a typosquat
|
|
3472
|
+
// or known-compromised package never reaches disk.
|
|
3473
|
+
const { preflight: osvPreflight } = await import("./security/osv-check.js");
|
|
3474
|
+
const osvVerdict = await osvPreflight([{ name, command: options.command, args: options.args ?? [] }], {
|
|
3475
|
+
skip: options.skipMalwareCheck === true,
|
|
3476
|
+
strict: options.strictMalwareCheck === true,
|
|
3477
|
+
});
|
|
3478
|
+
if (!osvVerdict.proceed) {
|
|
3479
|
+
process.exit(1);
|
|
3480
|
+
}
|
|
3192
3481
|
const updated = {
|
|
3193
3482
|
...config,
|
|
3194
3483
|
[key]: {
|
|
@@ -3680,6 +3969,7 @@ skillSourceCmd
|
|
|
3680
3969
|
.description("Register a new skill source (e.g. add my-skills github.com owner/repo)")
|
|
3681
3970
|
.option("--path <subpath>", "Path within the repo (e.g. `skills`)")
|
|
3682
3971
|
.option("--ref <ref>", "Branch, tag, or commit reference")
|
|
3972
|
+
.option("--no-prefetch", "Skip the eager clone — only register in config")
|
|
3683
3973
|
.action(async (id, host, repo, options) => {
|
|
3684
3974
|
const { config, path: configPath } = await loadSkillSourceConfig();
|
|
3685
3975
|
if (config.sources.some((s) => s.id === id)) {
|
|
@@ -3702,6 +3992,35 @@ skillSourceCmd
|
|
|
3702
3992
|
await writeSkillSourceConfig(next, configPath);
|
|
3703
3993
|
console.log(chalk.green(`✓ added skill source "${id}" → ${host}/${repo}`));
|
|
3704
3994
|
console.log(chalk.dim(` config: ${configPath}`));
|
|
3995
|
+
// Eager prefetch: actively clone via addGitSource so the new source
|
|
3996
|
+
// is usable immediately, not only on the next `skill source fetch`.
|
|
3997
|
+
// Pre-Wave-2 the CLI's add command and the marketplace's
|
|
3998
|
+
// addGitSource were two separate "add a source" paradigms that
|
|
3999
|
+
// never met — `add` wrote JSON, `addGitSource` did the clone, and
|
|
4000
|
+
// nothing bridged them. This wire closes that gap. Skippable via
|
|
4001
|
+
// `--no-prefetch` for users on metered networks or when the
|
|
4002
|
+
// GitHub host can't be reached at config-time.
|
|
4003
|
+
if (options.prefetch !== false && host === "github.com") {
|
|
4004
|
+
const { addGitSource, SkillMarketplace } = await import("./marketplace/registry.js");
|
|
4005
|
+
try {
|
|
4006
|
+
const marketplace = new SkillMarketplace();
|
|
4007
|
+
const spec = options.ref !== undefined && options.ref.length > 0 ? `${repo}@${options.ref}` : repo;
|
|
4008
|
+
const result = await addGitSource(marketplace, spec, {
|
|
4009
|
+
sparsePaths: options.path !== undefined && options.path.length > 0 ? [options.path] : undefined,
|
|
4010
|
+
});
|
|
4011
|
+
if (result.ok) {
|
|
4012
|
+
console.log(chalk.dim(` prefetched → ~/.wotann/marketplace-cache/`));
|
|
4013
|
+
}
|
|
4014
|
+
else {
|
|
4015
|
+
console.log(chalk.yellow(` prefetch skipped — ${result.error}. Source is registered; run \`wotann skill source fetch ${id} <skill>\` to retry.`));
|
|
4016
|
+
}
|
|
4017
|
+
}
|
|
4018
|
+
catch (e) {
|
|
4019
|
+
// Prefetch is best-effort — never blocks the registration.
|
|
4020
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
4021
|
+
console.log(chalk.yellow(` prefetch threw — ${msg}. Source is registered.`));
|
|
4022
|
+
}
|
|
4023
|
+
}
|
|
3705
4024
|
});
|
|
3706
4025
|
skillSourceCmd
|
|
3707
4026
|
.command("fetch <sourceId> <skillName>")
|
|
@@ -4364,91 +4683,39 @@ function parseBudgetToMs(spec) {
|
|
|
4364
4683
|
return Math.floor(value * mult);
|
|
4365
4684
|
}
|
|
4366
4685
|
// ── wotann onboard ──────────────────────────────────────────
|
|
4686
|
+
//
|
|
4687
|
+
// `onboard` and `init` both route to the same interactive wizard now —
|
|
4688
|
+
// having two near-identical static-text reports was confusing (the user
|
|
4689
|
+
// flagged "wtf is this" on init's report, then independently flagged the
|
|
4690
|
+
// same thing on onboard's). One source of truth: the Ink wizard at
|
|
4691
|
+
// src/cli/onboarding-screens.tsx, invoked via runOnboardingWizard().
|
|
4692
|
+
// `onboard` stays as a discoverable verb but is structurally an alias.
|
|
4367
4693
|
program
|
|
4368
4694
|
.command("onboard")
|
|
4369
|
-
.description("Interactive provider setup
|
|
4370
|
-
.
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
const
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4386
|
-
|
|
4387
|
-
|
|
4388
|
-
provider: "codex",
|
|
4389
|
-
label: "OpenAI Codex (ChatGPT subscription)",
|
|
4390
|
-
instructions: [
|
|
4391
|
-
"Authenticate via Codex CLI (uses your ChatGPT Plus/Pro subscription):",
|
|
4392
|
-
' npx @openai/codex --full-auto "hello"',
|
|
4393
|
-
"This creates ~/.codex/auth.json with your OAuth tokens.",
|
|
4394
|
-
],
|
|
4395
|
-
},
|
|
4396
|
-
{
|
|
4397
|
-
provider: "openai",
|
|
4398
|
-
label: "OpenAI API",
|
|
4399
|
-
instructions: [
|
|
4400
|
-
"Set OPENAI_API_KEY in your shell:",
|
|
4401
|
-
" export OPENAI_API_KEY=sk-...",
|
|
4402
|
-
"Get a key at: https://platform.openai.com/api-keys",
|
|
4403
|
-
],
|
|
4404
|
-
},
|
|
4405
|
-
{
|
|
4406
|
-
provider: "copilot",
|
|
4407
|
-
label: "GitHub Copilot",
|
|
4408
|
-
instructions: [
|
|
4409
|
-
"Set GH_TOKEN with Copilot access:",
|
|
4410
|
-
" export GH_TOKEN=$(gh auth token)",
|
|
4411
|
-
"Requires GitHub Copilot subscription: https://github.com/settings/copilot",
|
|
4412
|
-
],
|
|
4413
|
-
},
|
|
4414
|
-
{
|
|
4415
|
-
provider: "gemini",
|
|
4416
|
-
label: "Google Gemini (free tier: 1.5M tokens/day)",
|
|
4417
|
-
instructions: [
|
|
4418
|
-
"Get a free API key at: https://aistudio.google.com/app/apikey",
|
|
4419
|
-
" export GEMINI_API_KEY=AI...",
|
|
4420
|
-
],
|
|
4421
|
-
},
|
|
4422
|
-
{
|
|
4423
|
-
provider: "ollama",
|
|
4424
|
-
label: "Ollama (local, free, private)",
|
|
4425
|
-
instructions: [
|
|
4426
|
-
"Install Ollama: https://ollama.ai",
|
|
4427
|
-
" ollama serve",
|
|
4428
|
-
" ollama pull qwen3.5:27b # best for 24GB+ VRAM",
|
|
4429
|
-
" ollama pull qwen3.5:9b # for 8GB VRAM",
|
|
4430
|
-
],
|
|
4431
|
-
},
|
|
4432
|
-
];
|
|
4433
|
-
for (const guide of SETUP_GUIDE) {
|
|
4434
|
-
const status = statuses.find((s) => s.provider === guide.provider);
|
|
4435
|
-
const active = status?.available ?? false;
|
|
4436
|
-
const icon = active ? chalk.green("ok") : chalk.yellow("--");
|
|
4437
|
-
const label = active ? chalk.green(guide.label) : chalk.white(guide.label);
|
|
4438
|
-
console.log(` ${icon} ${label}`);
|
|
4439
|
-
if (active) {
|
|
4440
|
-
console.log(chalk.dim(` Active (${status?.billing}) — ${status?.models.slice(0, 2).join(", ")}`));
|
|
4441
|
-
}
|
|
4442
|
-
else {
|
|
4443
|
-
for (const line of guide.instructions) {
|
|
4444
|
-
console.log(chalk.dim(` ${line}`));
|
|
4445
|
-
}
|
|
4695
|
+
.description("Interactive provider setup wizard (alias of `wotann init`)")
|
|
4696
|
+
.option("--print", "Print a static report instead of launching the wizard")
|
|
4697
|
+
.action(async (options) => {
|
|
4698
|
+
// Auto-fall-back to the print path when stdin isn't a TTY (CI,
|
|
4699
|
+
// piped input, headless scripts) — same rule as `wotann init`.
|
|
4700
|
+
// The wizard's Ink raw-mode requirement crashes otherwise.
|
|
4701
|
+
const isInteractiveTTY = Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
|
|
4702
|
+
if (options.print || !isInteractiveTTY) {
|
|
4703
|
+
// Headless / scripted path — write a machine-friendly status
|
|
4704
|
+
// report and exit. Useful for CI / dotfile bootstrap scripts that
|
|
4705
|
+
// want to verify provider setup without opening a TUI.
|
|
4706
|
+
const { discoverProviders, formatFullStatus } = await import("./providers/discovery.js");
|
|
4707
|
+
const providers = await discoverProviders();
|
|
4708
|
+
const statuses = formatFullStatus(providers);
|
|
4709
|
+
const active = statuses.filter((s) => s.available);
|
|
4710
|
+
console.log(`${active.length} providers active, ${statuses.length - active.length} available to configure`);
|
|
4711
|
+
for (const s of statuses) {
|
|
4712
|
+
const tag = s.available ? "ACTIVE" : "MISSING";
|
|
4713
|
+
console.log(`${tag}\t${s.provider}\t${s.billing ?? ""}\t${s.models.slice(0, 3).join(",")}`);
|
|
4446
4714
|
}
|
|
4447
|
-
|
|
4715
|
+
return;
|
|
4448
4716
|
}
|
|
4449
|
-
const
|
|
4450
|
-
|
|
4451
|
-
console.log(chalk.dim(" Re-run `wotann onboard` after configuration to verify.\n"));
|
|
4717
|
+
const { runOnboardingWizard } = await import("./cli/run-onboarding-wizard.js");
|
|
4718
|
+
await runOnboardingWizard();
|
|
4452
4719
|
});
|
|
4453
4720
|
// ── wotann serve ────────────────────────────────────────────
|
|
4454
4721
|
program
|
|
@@ -4885,8 +5152,120 @@ function getDaemonPaths() {
|
|
|
4885
5152
|
return {
|
|
4886
5153
|
pidPath: join(wotannDir, "daemon.pid"),
|
|
4887
5154
|
statusPath: join(wotannDir, "daemon.status.json"),
|
|
5155
|
+
socketPath: process.platform === "win32"
|
|
5156
|
+
? resolveDaemonSocketPath({ daemonId: "kairos" })
|
|
5157
|
+
: join(wotannDir, "kairos.sock"),
|
|
4888
5158
|
};
|
|
4889
5159
|
}
|
|
5160
|
+
async function isDaemonIpcReachable(timeoutMs = 750) {
|
|
5161
|
+
const { socketPath } = getDaemonPaths();
|
|
5162
|
+
if (!existsSync(socketPath))
|
|
5163
|
+
return false;
|
|
5164
|
+
const { createConnection } = await import("node:net");
|
|
5165
|
+
return new Promise((resolve) => {
|
|
5166
|
+
let settled = false;
|
|
5167
|
+
const finish = (ok) => {
|
|
5168
|
+
if (settled)
|
|
5169
|
+
return;
|
|
5170
|
+
settled = true;
|
|
5171
|
+
resolve(ok);
|
|
5172
|
+
};
|
|
5173
|
+
const client = createConnection(socketPath, () => {
|
|
5174
|
+
client.end();
|
|
5175
|
+
finish(true);
|
|
5176
|
+
});
|
|
5177
|
+
client.setTimeout(timeoutMs, () => {
|
|
5178
|
+
client.destroy();
|
|
5179
|
+
finish(false);
|
|
5180
|
+
});
|
|
5181
|
+
client.on("error", () => finish(false));
|
|
5182
|
+
client.on("close", () => finish(false));
|
|
5183
|
+
});
|
|
5184
|
+
}
|
|
5185
|
+
async function ensureDaemonIpcForCommand(options) {
|
|
5186
|
+
if (await isDaemonIpcReachable())
|
|
5187
|
+
return true;
|
|
5188
|
+
if (options.announce) {
|
|
5189
|
+
console.error(chalk.yellow(options.announce));
|
|
5190
|
+
}
|
|
5191
|
+
const { pidPath, statusPath } = getDaemonPaths();
|
|
5192
|
+
const { existsSync, readFileSync } = await import("node:fs");
|
|
5193
|
+
if (existsSync(pidPath)) {
|
|
5194
|
+
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
5195
|
+
if (isProcessAlive(pid)) {
|
|
5196
|
+
console.error(chalk.dim(`${options.label} PID ${pid} is alive, but its IPC socket is not reachable.`));
|
|
5197
|
+
console.error(chalk.dim("Repairing by restarting the process..."));
|
|
5198
|
+
const stopped = await stopDaemonProcess(pid, options.label);
|
|
5199
|
+
if (!stopped)
|
|
5200
|
+
return false;
|
|
5201
|
+
}
|
|
5202
|
+
await cleanupDaemonStateFiles(pidPath, statusPath);
|
|
5203
|
+
}
|
|
5204
|
+
const entryPath = fileURLToPath(import.meta.url);
|
|
5205
|
+
void spawnDaemonWorker(entryPath, process.cwd());
|
|
5206
|
+
return (await waitForDaemonReady(pidPath, 15_000)) !== null;
|
|
5207
|
+
}
|
|
5208
|
+
async function stopDaemonProcess(pid, label) {
|
|
5209
|
+
if (!isProcessAlive(pid))
|
|
5210
|
+
return true;
|
|
5211
|
+
try {
|
|
5212
|
+
process.kill(pid, "SIGTERM");
|
|
5213
|
+
}
|
|
5214
|
+
catch {
|
|
5215
|
+
return false;
|
|
5216
|
+
}
|
|
5217
|
+
await waitForProcessExit(pid, 5_000);
|
|
5218
|
+
if (!isProcessAlive(pid))
|
|
5219
|
+
return true;
|
|
5220
|
+
console.error(chalk.yellow(`${label} PID ${pid} did not exit after SIGTERM; escalating to SIGKILL.`));
|
|
5221
|
+
try {
|
|
5222
|
+
process.kill(pid, "SIGKILL");
|
|
5223
|
+
}
|
|
5224
|
+
catch {
|
|
5225
|
+
return false;
|
|
5226
|
+
}
|
|
5227
|
+
await waitForProcessExit(pid, 2_000);
|
|
5228
|
+
return !isProcessAlive(pid);
|
|
5229
|
+
}
|
|
5230
|
+
async function cleanupDaemonStateFiles(pidPath, statusPath) {
|
|
5231
|
+
const { unlinkSync } = await import("node:fs");
|
|
5232
|
+
for (const path of [pidPath, statusPath]) {
|
|
5233
|
+
try {
|
|
5234
|
+
unlinkSync(path);
|
|
5235
|
+
}
|
|
5236
|
+
catch {
|
|
5237
|
+
/* ignore */
|
|
5238
|
+
}
|
|
5239
|
+
}
|
|
5240
|
+
}
|
|
5241
|
+
async function formatDaemonHealthDiagnostic(indent = "") {
|
|
5242
|
+
const { pidPath, socketPath, statusPath } = getDaemonPaths();
|
|
5243
|
+
const { existsSync, readFileSync } = await import("node:fs");
|
|
5244
|
+
const lines = [];
|
|
5245
|
+
if (!existsSync(pidPath)) {
|
|
5246
|
+
lines.push(`${indent}No daemon PID file found at ${pidPath}.`);
|
|
5247
|
+
}
|
|
5248
|
+
else {
|
|
5249
|
+
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
5250
|
+
lines.push(isProcessAlive(pid)
|
|
5251
|
+
? `${indent}Daemon PID file exists (${pid}), and the process is alive.`
|
|
5252
|
+
: `${indent}Daemon PID file exists (${pid}), but the process is not alive.`);
|
|
5253
|
+
}
|
|
5254
|
+
lines.push(existsSync(socketPath)
|
|
5255
|
+
? `${indent}IPC socket exists at ${socketPath}, but connection failed.`
|
|
5256
|
+
: `${indent}IPC socket is missing at ${socketPath}.`);
|
|
5257
|
+
if (existsSync(statusPath)) {
|
|
5258
|
+
try {
|
|
5259
|
+
const status = JSON.parse(readFileSync(statusPath, "utf-8"));
|
|
5260
|
+
if (typeof status.status === "string")
|
|
5261
|
+
lines.push(`${indent}Status file says: ${status.status}.`);
|
|
5262
|
+
}
|
|
5263
|
+
catch {
|
|
5264
|
+
lines.push(`${indent}Status file is present but malformed.`);
|
|
5265
|
+
}
|
|
5266
|
+
}
|
|
5267
|
+
return lines.join("\n");
|
|
5268
|
+
}
|
|
4890
5269
|
function formatTokenCount(tokens) {
|
|
4891
5270
|
if (tokens >= 1_000_000)
|
|
4892
5271
|
return `${(tokens / 1_000_000).toFixed(tokens % 1_000_000 === 0 ? 0 : 2)}M`;
|
|
@@ -4930,7 +5309,7 @@ async function waitForDaemonReady(pidPath, timeoutMs) {
|
|
|
4930
5309
|
while (Date.now() < deadline) {
|
|
4931
5310
|
if (existsSync(pidPath)) {
|
|
4932
5311
|
const pid = parseInt(readFileSync(pidPath, "utf-8").trim(), 10);
|
|
4933
|
-
if (Number.isFinite(pid) && isProcessAlive(pid)) {
|
|
5312
|
+
if (Number.isFinite(pid) && isProcessAlive(pid) && (await isDaemonIpcReachable(250))) {
|
|
4934
5313
|
return pid;
|
|
4935
5314
|
}
|
|
4936
5315
|
}
|
|
@@ -4953,7 +5332,12 @@ function isProcessAlive(pid) {
|
|
|
4953
5332
|
process.kill(pid, 0);
|
|
4954
5333
|
return true;
|
|
4955
5334
|
}
|
|
4956
|
-
catch {
|
|
5335
|
+
catch (err) {
|
|
5336
|
+
const code = err.code;
|
|
5337
|
+
if (code === "ESRCH")
|
|
5338
|
+
return false;
|
|
5339
|
+
if (code === "EPERM")
|
|
5340
|
+
return true;
|
|
4957
5341
|
// Best-effort path — caller gets a safe fallback, no user-facing error.
|
|
4958
5342
|
return false;
|
|
4959
5343
|
}
|
|
@@ -6277,7 +6661,8 @@ program
|
|
|
6277
6661
|
const maxIter = parseInt(opts.maxIterations ?? "0", 10);
|
|
6278
6662
|
const executor = async (cmd) => {
|
|
6279
6663
|
return new Promise((resolvePromise) => {
|
|
6280
|
-
const
|
|
6664
|
+
const shell = buildShellCommand(cmd);
|
|
6665
|
+
const child = spawn(shell.file, [...shell.argv], {
|
|
6281
6666
|
stdio: "inherit",
|
|
6282
6667
|
cwd: process.cwd(),
|
|
6283
6668
|
env: process.env,
|
|
@@ -6420,6 +6805,209 @@ intentByoaCmd
|
|
|
6420
6805
|
const { registerExploitCommands } = await import("./cli/commands/exploit.js");
|
|
6421
6806
|
registerExploitCommands(program);
|
|
6422
6807
|
}
|
|
6808
|
+
// ── wotann persona — identity persona inspection + switching ──
|
|
6809
|
+
//
|
|
6810
|
+
// PersonaManager (src/identity/persona.ts) loads YAML profiles from
|
|
6811
|
+
// `.wotann/personas/` but had no CLI surface — users couldn't see
|
|
6812
|
+
// what persona was active or switch between them. This wire exposes
|
|
6813
|
+
// list/show/active/switch/init through the standard intent-style
|
|
6814
|
+
// handler pattern: pure handler in cli/commands/persona.ts, this
|
|
6815
|
+
// shell only translates commander args.
|
|
6816
|
+
{
|
|
6817
|
+
const personaCmd = program
|
|
6818
|
+
.command("persona")
|
|
6819
|
+
.description("List, show, switch, or scaffold WOTANN identity personas");
|
|
6820
|
+
// Matches prompt/engine.ts:loadPersona which expects personas under
|
|
6821
|
+
// `<workspaceRoot>/.wotann/personas/`. PersonaManager appends the
|
|
6822
|
+
// "personas" subdir; the active-persona pointer file lives next to
|
|
6823
|
+
// it as `<workspaceRoot>/.wotann/active-persona`.
|
|
6824
|
+
const dotWotann = () => join(process.cwd(), ".wotann");
|
|
6825
|
+
personaCmd
|
|
6826
|
+
.command("list")
|
|
6827
|
+
.description("List configured personas in .wotann/personas/")
|
|
6828
|
+
.action(async () => {
|
|
6829
|
+
const { runPersonaCommand } = await import("./cli/commands/persona.js");
|
|
6830
|
+
const result = await runPersonaCommand({ action: "list", wotannDir: dotWotann() });
|
|
6831
|
+
for (const line of result.lines)
|
|
6832
|
+
process.stdout.write(`${line}\n`);
|
|
6833
|
+
if (!result.success) {
|
|
6834
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6835
|
+
process.exit(1);
|
|
6836
|
+
}
|
|
6837
|
+
});
|
|
6838
|
+
personaCmd
|
|
6839
|
+
.command("show <name>")
|
|
6840
|
+
.description("Print the YAML-derived persona profile")
|
|
6841
|
+
.action(async (name) => {
|
|
6842
|
+
const { runPersonaCommand } = await import("./cli/commands/persona.js");
|
|
6843
|
+
const result = await runPersonaCommand({ action: "show", name, wotannDir: dotWotann() });
|
|
6844
|
+
for (const line of result.lines)
|
|
6845
|
+
process.stdout.write(`${line}\n`);
|
|
6846
|
+
if (!result.success) {
|
|
6847
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6848
|
+
process.exit(1);
|
|
6849
|
+
}
|
|
6850
|
+
});
|
|
6851
|
+
personaCmd
|
|
6852
|
+
.command("active")
|
|
6853
|
+
.description("Show the currently-active persona")
|
|
6854
|
+
.action(async () => {
|
|
6855
|
+
const { runPersonaCommand } = await import("./cli/commands/persona.js");
|
|
6856
|
+
const result = await runPersonaCommand({ action: "active", wotannDir: dotWotann() });
|
|
6857
|
+
for (const line of result.lines)
|
|
6858
|
+
process.stdout.write(`${line}\n`);
|
|
6859
|
+
if (!result.success) {
|
|
6860
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6861
|
+
process.exit(1);
|
|
6862
|
+
}
|
|
6863
|
+
});
|
|
6864
|
+
personaCmd
|
|
6865
|
+
.command("switch <name>")
|
|
6866
|
+
.description("Set the active persona (writes .wotann/active-persona)")
|
|
6867
|
+
.action(async (name) => {
|
|
6868
|
+
const { runPersonaCommand } = await import("./cli/commands/persona.js");
|
|
6869
|
+
const result = await runPersonaCommand({ action: "switch", name, wotannDir: dotWotann() });
|
|
6870
|
+
for (const line of result.lines)
|
|
6871
|
+
process.stdout.write(`${line}\n`);
|
|
6872
|
+
if (!result.success) {
|
|
6873
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6874
|
+
process.exit(1);
|
|
6875
|
+
}
|
|
6876
|
+
});
|
|
6877
|
+
personaCmd
|
|
6878
|
+
.command("init")
|
|
6879
|
+
.description("Scaffold a default persona under .wotann/personas/")
|
|
6880
|
+
.action(async () => {
|
|
6881
|
+
const { runPersonaCommand } = await import("./cli/commands/persona.js");
|
|
6882
|
+
const result = await runPersonaCommand({ action: "init", wotannDir: dotWotann() });
|
|
6883
|
+
for (const line of result.lines)
|
|
6884
|
+
process.stdout.write(`${line}\n`);
|
|
6885
|
+
if (!result.success) {
|
|
6886
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6887
|
+
process.exit(1);
|
|
6888
|
+
}
|
|
6889
|
+
});
|
|
6890
|
+
}
|
|
6891
|
+
// ── wotann learning — inspect daemon-internal learning state ──
|
|
6892
|
+
//
|
|
6893
|
+
// The learning subsystem (DreamPipeline, FeedbackCollector,
|
|
6894
|
+
// PatternCrystallizer, DecisionLedger) runs ONLY inside the daemon
|
|
6895
|
+
// and accumulates state in .wotann/memory.db + .wotann/.dreams/ +
|
|
6896
|
+
// .wotann/LESSONS.md. Until this wire there was no way for users to
|
|
6897
|
+
// see what the agent had learned. Pure handler in
|
|
6898
|
+
// cli/commands/learning.ts reads SQLite + disk directly (no runtime
|
|
6899
|
+
// or daemon coupling).
|
|
6900
|
+
{
|
|
6901
|
+
const learningCmd = program
|
|
6902
|
+
.command("learning")
|
|
6903
|
+
.description("Inspect dreams, patterns, decisions, lessons, and learning stats");
|
|
6904
|
+
const dotWotann = () => join(process.cwd(), ".wotann");
|
|
6905
|
+
const wireSimpleSubcommand = (name, description, action) => {
|
|
6906
|
+
learningCmd
|
|
6907
|
+
.command(name)
|
|
6908
|
+
.description(description)
|
|
6909
|
+
.action(async () => {
|
|
6910
|
+
const { runLearningCommand } = await import("./cli/commands/learning.js");
|
|
6911
|
+
const result = await runLearningCommand({ action, wotannDir: dotWotann() });
|
|
6912
|
+
for (const line of result.lines)
|
|
6913
|
+
process.stdout.write(`${line}\n`);
|
|
6914
|
+
if (!result.success) {
|
|
6915
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6916
|
+
process.exit(1);
|
|
6917
|
+
}
|
|
6918
|
+
});
|
|
6919
|
+
};
|
|
6920
|
+
wireSimpleSubcommand("dreams", "List crystallized dreams from the daemon's dream pipeline", "dreams");
|
|
6921
|
+
wireSimpleSubcommand("patterns", "List patterns from PatternCrystallizer (SQLite layer=patterns)", "patterns");
|
|
6922
|
+
wireSimpleSubcommand("decisions", "List decisions from the DecisionLedger SQLite table", "decisions");
|
|
6923
|
+
wireSimpleSubcommand("lessons", "List gotchas extracted from .wotann/LESSONS.md", "lessons");
|
|
6924
|
+
wireSimpleSubcommand("stats", "Summary counts across all learning surfaces", "stats");
|
|
6925
|
+
}
|
|
6926
|
+
// ── wotann evolve — evolutionary skill optimisation ──
|
|
6927
|
+
//
|
|
6928
|
+
// The evolution subsystem (Optimizer / Mutator / Evaluator / constraints,
|
|
6929
|
+
// ~711 LOC) was reachable only via dream-runner inside the daemon. This
|
|
6930
|
+
// wire exposes status / history / constraints inspection plus the real
|
|
6931
|
+
// runOptimization() entry-point for user-driven evolution runs.
|
|
6932
|
+
{
|
|
6933
|
+
const evolveCmd = program
|
|
6934
|
+
.command("evolve")
|
|
6935
|
+
.description("Inspect or run skill evolution (Optimizer / Mutator / Evaluator)");
|
|
6936
|
+
const dotWotann = () => join(process.cwd(), ".wotann");
|
|
6937
|
+
evolveCmd
|
|
6938
|
+
.command("status")
|
|
6939
|
+
.description("Show last evolution-run timestamp + fitness")
|
|
6940
|
+
.action(async () => {
|
|
6941
|
+
const { runEvolveCommand } = await import("./cli/commands/evolve.js");
|
|
6942
|
+
const result = await runEvolveCommand({ action: "status", wotannDir: dotWotann() });
|
|
6943
|
+
for (const line of result.lines)
|
|
6944
|
+
process.stdout.write(`${line}\n`);
|
|
6945
|
+
if (!result.success) {
|
|
6946
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6947
|
+
process.exit(1);
|
|
6948
|
+
}
|
|
6949
|
+
});
|
|
6950
|
+
evolveCmd
|
|
6951
|
+
.command("history [count]")
|
|
6952
|
+
.description("Last N generations (default 10) from .wotann/evolution-log.jsonl")
|
|
6953
|
+
.action(async (count) => {
|
|
6954
|
+
const { runEvolveCommand } = await import("./cli/commands/evolve.js");
|
|
6955
|
+
const parsedCount = count ? Number.parseInt(count, 10) : undefined;
|
|
6956
|
+
const result = await runEvolveCommand({
|
|
6957
|
+
action: "history",
|
|
6958
|
+
wotannDir: dotWotann(),
|
|
6959
|
+
...(typeof parsedCount === "number" && Number.isFinite(parsedCount)
|
|
6960
|
+
? { count: parsedCount }
|
|
6961
|
+
: {}),
|
|
6962
|
+
});
|
|
6963
|
+
for (const line of result.lines)
|
|
6964
|
+
process.stdout.write(`${line}\n`);
|
|
6965
|
+
if (!result.success) {
|
|
6966
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6967
|
+
process.exit(1);
|
|
6968
|
+
}
|
|
6969
|
+
});
|
|
6970
|
+
evolveCmd
|
|
6971
|
+
.command("constraints")
|
|
6972
|
+
.description("Print FORBIDDEN_TOKENS + structural caps")
|
|
6973
|
+
.action(async () => {
|
|
6974
|
+
const { runEvolveCommand } = await import("./cli/commands/evolve.js");
|
|
6975
|
+
const result = await runEvolveCommand({ action: "constraints", wotannDir: dotWotann() });
|
|
6976
|
+
for (const line of result.lines)
|
|
6977
|
+
process.stdout.write(`${line}\n`);
|
|
6978
|
+
if (!result.success) {
|
|
6979
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
6980
|
+
process.exit(1);
|
|
6981
|
+
}
|
|
6982
|
+
});
|
|
6983
|
+
evolveCmd
|
|
6984
|
+
.command("run <skill-path>")
|
|
6985
|
+
.description("Run one evolution round on the skill file at <skill-path>")
|
|
6986
|
+
.option("--population <n>", "Population size", (v) => Number(v))
|
|
6987
|
+
.option("--generations <n>", "Number of generations (default 1)", (v) => Number(v))
|
|
6988
|
+
.option("--target-fitness <n>", "Stop when fitness reaches this", (v) => Number(v))
|
|
6989
|
+
.option("--write", "Write the winning variant back over the skill file (original archived)")
|
|
6990
|
+
.option("--budget <usd>", "Max spend in USD before stopping", (v) => Number(v))
|
|
6991
|
+
.action(async (skillPath, opts) => {
|
|
6992
|
+
const { runEvolveCommand } = await import("./cli/commands/evolve.js");
|
|
6993
|
+
const result = await runEvolveCommand({
|
|
6994
|
+
action: "run",
|
|
6995
|
+
wotannDir: dotWotann(),
|
|
6996
|
+
skillPath,
|
|
6997
|
+
...(typeof opts.population === "number" ? { population: opts.population } : {}),
|
|
6998
|
+
...(typeof opts.generations === "number" ? { generations: opts.generations } : {}),
|
|
6999
|
+
...(typeof opts.targetFitness === "number" ? { targetFitness: opts.targetFitness } : {}),
|
|
7000
|
+
...(opts.write === true ? { write: true } : {}),
|
|
7001
|
+
...(typeof opts.budget === "number" ? { budgetUsd: opts.budget } : {}),
|
|
7002
|
+
});
|
|
7003
|
+
for (const line of result.lines)
|
|
7004
|
+
process.stdout.write(`${line}\n`);
|
|
7005
|
+
if (!result.success) {
|
|
7006
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "failed"}\n`));
|
|
7007
|
+
process.exit(1);
|
|
7008
|
+
}
|
|
7009
|
+
});
|
|
7010
|
+
}
|
|
6423
7011
|
// ── wotann grep — B9 ParallelGrep semantic-search wire (P1-B9 wire) ─
|
|
6424
7012
|
//
|
|
6425
7013
|
// ParallelGrep (src/tools/parallel-grep.ts + grep-subagent.ts, 716 LOC,
|
|
@@ -6432,6 +7020,41 @@ intentByoaCmd
|
|
|
6432
7020
|
const { registerGrepCommand } = await import("./cli/commands/grep.js");
|
|
6433
7021
|
registerGrepCommand(program);
|
|
6434
7022
|
}
|
|
7023
|
+
// ── wotann blast-radius — cross-file symbol usage tracer ───────
|
|
7024
|
+
//
|
|
7025
|
+
// Companion to grep — instead of free-text search, walks the AST (or
|
|
7026
|
+
// ripgrep fallback) for a named symbol and lists every call site
|
|
7027
|
+
// across the workspace. Emits a "LOW USAGE" warning when a symbol
|
|
7028
|
+
// has ≤1 call site, flagging likely dead exports or unused
|
|
7029
|
+
// identifiers. Pure handler in cli/commands/blast-radius.ts; this
|
|
7030
|
+
// shell only translates commander args into handler options.
|
|
7031
|
+
program
|
|
7032
|
+
.command("blast-radius <symbol>")
|
|
7033
|
+
.description("List cross-file usage sites for a symbol (function/class/variable). Warns when usage ≤1.")
|
|
7034
|
+
.option("--root <dir>", "Project root to scan (defaults to cwd)")
|
|
7035
|
+
.option("--language <lang>", "Restrict to a language (typescript|javascript|python|rust|go|swift). Repeatable.", (value, prev = []) => [...prev, value], [])
|
|
7036
|
+
.option("--max <n>", "Maximum usages to report (default 200)", (v) => Number(v))
|
|
7037
|
+
.option("--json", "Emit machine-readable JSON instead of pretty text", false)
|
|
7038
|
+
.action(async (symbol, opts) => {
|
|
7039
|
+
const { runBlastRadiusCommand } = await import("./cli/commands/blast-radius.js");
|
|
7040
|
+
const validLangs = ["typescript", "javascript", "python", "rust", "go", "swift"];
|
|
7041
|
+
const requested = (opts.language ?? []).filter((l) => validLangs.includes(l));
|
|
7042
|
+
const result = await runBlastRadiusCommand({
|
|
7043
|
+
symbol,
|
|
7044
|
+
rootDir: opts.root ?? process.cwd(),
|
|
7045
|
+
...(requested.length > 0 ? { languages: requested } : {}),
|
|
7046
|
+
...(typeof opts.max === "number" && Number.isFinite(opts.max)
|
|
7047
|
+
? { maxUsages: opts.max }
|
|
7048
|
+
: {}),
|
|
7049
|
+
...(opts.json === true ? { json: true } : {}),
|
|
7050
|
+
});
|
|
7051
|
+
for (const line of result.lines)
|
|
7052
|
+
process.stdout.write(`${line}\n`);
|
|
7053
|
+
if (!result.success) {
|
|
7054
|
+
process.stderr.write(chalk.red(`✗ ${result.error ?? "blast-radius failed"}\n`));
|
|
7055
|
+
process.exit(1);
|
|
7056
|
+
}
|
|
7057
|
+
});
|
|
6435
7058
|
// ── wotann replay — V9 T14.7 trajectory replay ───────────────
|
|
6436
7059
|
//
|
|
6437
7060
|
// `wotann replay <trajectory.json>` plays back a recorded session
|
|
@@ -6884,7 +7507,8 @@ program
|
|
|
6884
7507
|
}
|
|
6885
7508
|
const { execFileNoThrow } = await import("./utils/execFileNoThrow.js");
|
|
6886
7509
|
const probe = async () => {
|
|
6887
|
-
const
|
|
7510
|
+
const probeShell = buildShellCommand(options.probeCmd);
|
|
7511
|
+
const result = await execFileNoThrow(probeShell.file, [...probeShell.argv]);
|
|
6888
7512
|
if (result.exitCode !== 0) {
|
|
6889
7513
|
throw new Error(`probe-cmd exited ${result.exitCode}: ${result.stderr}`);
|
|
6890
7514
|
}
|
|
@@ -7884,57 +8508,51 @@ teamsCmd
|
|
|
7884
8508
|
console.log(` ${chalk.cyan(a.padEnd(20))} pending=${counts.pending} consumed=${counts.consumed} done=${counts.done}`);
|
|
7885
8509
|
}
|
|
7886
8510
|
});
|
|
7887
|
-
// ── wotann evolve (hermes-self-evolution port)
|
|
7888
|
-
|
|
7889
|
-
|
|
7890
|
-
|
|
7891
|
-
|
|
7892
|
-
|
|
7893
|
-
|
|
7894
|
-
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7898
|
-
|
|
7899
|
-
|
|
7900
|
-
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
|
|
7904
|
-
|
|
7905
|
-
|
|
7906
|
-
|
|
7907
|
-
|
|
7908
|
-
|
|
7909
|
-
|
|
7910
|
-
|
|
7911
|
-
|
|
7912
|
-
|
|
7913
|
-
|
|
7914
|
-
|
|
7915
|
-
|
|
8511
|
+
// ── wotann evolve standalone (legacy hermes-self-evolution port)
|
|
8512
|
+
//
|
|
8513
|
+
// This was the original `wotann evolve <skillPath>` standalone. It is
|
|
8514
|
+
// now superseded by the `wotann evolve run <skill-path>` subcommand
|
|
8515
|
+
// registered higher in this file (which exposes the same evolveSkill
|
|
8516
|
+
// path + auto-stub mutator/evaluator, plus --write/--budget support).
|
|
8517
|
+
// Removed at integration time to fix the duplicate `evolve` command
|
|
8518
|
+
// registration that broke startup. The new subcommand path preserves
|
|
8519
|
+
// all previous flags + adds status/history/constraints inspection.
|
|
8520
|
+
// ── wotann session — relational-storage fork primitive
|
|
8521
|
+
//
|
|
8522
|
+
// Parallel-approach exploration: fork an existing session at its last
|
|
8523
|
+
// checkpoint into a NEW session row + deep-copy the message thread up
|
|
8524
|
+
// to the fork point. Backed by .wotann/sessions.db (better-sqlite3,
|
|
8525
|
+
// see src/session/fork.ts). Distinct from `wotann fork-session`
|
|
8526
|
+
// (line ~11000 below) which forks the codex-style rollout JSON file
|
|
8527
|
+
// — this one is the relational variant for the new sessions schema.
|
|
8528
|
+
{
|
|
8529
|
+
const sessionCmd = program
|
|
8530
|
+
.command("session")
|
|
8531
|
+
.description("Session management — relational fork for parallel-approach work");
|
|
8532
|
+
sessionCmd
|
|
8533
|
+
.command("fork <sourceSessionId>")
|
|
8534
|
+
.description("Fork an existing session at its last checkpoint into a new session row")
|
|
8535
|
+
.option("--label <label>", 'Optional label for the new fork (e.g. "approach-A")')
|
|
8536
|
+
.action(async (sourceSessionId, opts) => {
|
|
8537
|
+
const { forkSession } = await import("./session/fork.js");
|
|
8538
|
+
const result = await forkSession({
|
|
8539
|
+
sourceSessionId,
|
|
8540
|
+
wotannDir: join(process.cwd(), ".wotann"),
|
|
8541
|
+
...(opts.label !== undefined ? { label: opts.label } : {}),
|
|
8542
|
+
});
|
|
8543
|
+
if (!result.ok) {
|
|
8544
|
+
process.stderr.write(chalk.red(`✗ fork failed: ${result.error ?? "unknown"}\n`));
|
|
8545
|
+
process.exit(1);
|
|
8546
|
+
}
|
|
8547
|
+
process.stdout.write(`${chalk.green("✓")} Forked session ${chalk.cyan(sourceSessionId)} → ${chalk.cyan(result.newSessionId ?? "")}\n`);
|
|
8548
|
+
if (typeof result.messageCount === "number") {
|
|
8549
|
+
process.stdout.write(` Messages copied: ${result.messageCount}\n`);
|
|
8550
|
+
}
|
|
8551
|
+
if (result.sourceCheckpoint) {
|
|
8552
|
+
process.stdout.write(` Forked from checkpoint: ${result.sourceCheckpoint}\n`);
|
|
8553
|
+
}
|
|
7916
8554
|
});
|
|
7917
|
-
|
|
7918
|
-
console.log(` baseline score : ${summary.baselineScore.toFixed(3)}`);
|
|
7919
|
-
console.log(` best score : ${summary.bestScore.toFixed(3)}`);
|
|
7920
|
-
console.log(` improvement : ${summary.improvementPct.toFixed(1)}%`);
|
|
7921
|
-
console.log(` generations : ${summary.generations}`);
|
|
7922
|
-
console.log(` cost (USD) : $${summary.totalCostUsd.toFixed(4)}`);
|
|
7923
|
-
if (summary.notes.length > 0) {
|
|
7924
|
-
console.log(chalk.dim("\n Notes:"));
|
|
7925
|
-
for (const n of summary.notes)
|
|
7926
|
-
console.log(chalk.dim(` - ${n}`));
|
|
7927
|
-
}
|
|
7928
|
-
if (options.write && summary.bestScore > summary.baselineScore) {
|
|
7929
|
-
console.log(chalk.green(`\n✓ Wrote winning variant to ${skillPath} (original archived)`));
|
|
7930
|
-
}
|
|
7931
|
-
else if (options.write) {
|
|
7932
|
-
console.log(chalk.yellow("\n No improvement found — skill file left unchanged."));
|
|
7933
|
-
}
|
|
7934
|
-
else {
|
|
7935
|
-
console.log(chalk.dim("\n (Pass --write to apply the winning variant.)"));
|
|
7936
|
-
}
|
|
7937
|
-
});
|
|
8555
|
+
}
|
|
7938
8556
|
const recipeCmd = program.command("recipe").description("Goose-style recipe management (V9 T12.4)");
|
|
7939
8557
|
// Helper: enumerate recipe filenames in .wotann/recipes/. CLI-local helper
|
|
7940
8558
|
// since other callers don't need a directory walker.
|
|
@@ -8692,6 +9310,8 @@ mcpCmd
|
|
|
8692
9310
|
.description("Register an MCP server from a .mcpb manifest into ~/.wotann/wotann.yaml")
|
|
8693
9311
|
.option("-f, --force", "Overwrite an existing server with the same name", false)
|
|
8694
9312
|
.option("--name <name>", "Override the manifest's name (rare; mostly for testing)")
|
|
9313
|
+
.option("--skip-malware-check", "Skip the OSV.dev malware/CVE pre-flight (not recommended)", false)
|
|
9314
|
+
.option("--strict-malware-check", "Block on high/critical CVEs (default: only block confirmed malware)", false)
|
|
8695
9315
|
.action(async (file, options) => {
|
|
8696
9316
|
const { parseMcpb } = await import("./marketplace/mcpb.js");
|
|
8697
9317
|
const { resolveWotannHomeSubdir } = await import("./utils/wotann-home.js");
|
|
@@ -8730,6 +9350,22 @@ mcpCmd
|
|
|
8730
9350
|
process.exit(1);
|
|
8731
9351
|
}
|
|
8732
9352
|
const env = manifest.server.mcp_config.env;
|
|
9353
|
+
// OSV.dev malware/CVE pre-flight — gated before write so a typosquat
|
|
9354
|
+
// or compromised package never reaches user config.
|
|
9355
|
+
const { preflight: osvPreflight } = await import("./security/osv-check.js");
|
|
9356
|
+
const osvVerdict = await osvPreflight([
|
|
9357
|
+
{
|
|
9358
|
+
name: serverName,
|
|
9359
|
+
command: manifest.server.mcp_config.command,
|
|
9360
|
+
args: [...manifest.server.mcp_config.args],
|
|
9361
|
+
},
|
|
9362
|
+
], {
|
|
9363
|
+
skip: options.skipMalwareCheck === true,
|
|
9364
|
+
strict: options.strictMalwareCheck === true,
|
|
9365
|
+
});
|
|
9366
|
+
if (!osvVerdict.proceed) {
|
|
9367
|
+
process.exit(1);
|
|
9368
|
+
}
|
|
8733
9369
|
const updated = {
|
|
8734
9370
|
...config,
|
|
8735
9371
|
[key]: {
|
|
@@ -8754,6 +9390,406 @@ mcpCmd
|
|
|
8754
9390
|
console.log(chalk.dim(` written to: ${configPath}`));
|
|
8755
9391
|
console.log(chalk.dim(" Restart the engine for changes to take effect: wotann engine restart"));
|
|
8756
9392
|
});
|
|
9393
|
+
// ── wotann research-strategy <query> ────────────────────────
|
|
9394
|
+
//
|
|
9395
|
+
// Surfaces the dual-confidence + IterDRAG strategies in
|
|
9396
|
+
// src/intelligence/research-strategies.ts. Default flow runs
|
|
9397
|
+
// dual-confidence (cheap, 2 search calls) and reports the Jaccard
|
|
9398
|
+
// overlap between the two passes as confidence. --strategy=iterdrag
|
|
9399
|
+
// switches to depth-bounded recursive Decompose-Retrieve-Aggregate.
|
|
9400
|
+
//
|
|
9401
|
+
// Distinct from the existing `wotann research <topic>` command which
|
|
9402
|
+
// is the LLM-driven autonomous deep-research runtime. This command is
|
|
9403
|
+
// strategy-only (no LLM call) and always returns a structured result.
|
|
9404
|
+
//
|
|
9405
|
+
// Search/decompose/synthesize callbacks are honest-stub by default
|
|
9406
|
+
// (echo-only) so the command runs offline; pass --search-cmd or
|
|
9407
|
+
// --decompose-cmd to wire your own shell-based search engine.
|
|
9408
|
+
program
|
|
9409
|
+
.command("research-strategy <query>")
|
|
9410
|
+
.description("Run a structured research-strategy pass (dual-confidence | iterdrag)")
|
|
9411
|
+
.option("--strategy <name>", "Strategy: dual-confidence (default) | iterdrag", "dual-confidence")
|
|
9412
|
+
.option("--max-depth <n>", "iterdrag tree depth cap", "2")
|
|
9413
|
+
.option("--hits-per-call <n>", "Cap hits per search invocation", "10")
|
|
9414
|
+
.option("--search-cmd <cmd>", "Shell command that takes a query string and emits JSON {url,title?,snippet?}[] on stdout")
|
|
9415
|
+
.option("--json", "Emit JSON instead of human-readable summary", false)
|
|
9416
|
+
.action(async (query, options) => {
|
|
9417
|
+
const strategies = await import("./intelligence/research-strategies.js");
|
|
9418
|
+
const { execFile } = await import("node:child_process");
|
|
9419
|
+
const { promisify } = await import("node:util");
|
|
9420
|
+
const execFileAsync = promisify(execFile);
|
|
9421
|
+
const maxDepth = Number(options.maxDepth ?? 2);
|
|
9422
|
+
const hitsPerCall = Number(options.hitsPerCall ?? 10);
|
|
9423
|
+
const search = async (q) => {
|
|
9424
|
+
if (!options.searchCmd) {
|
|
9425
|
+
// Honest-stub default: echoes one synthetic hit per query so the
|
|
9426
|
+
// pipeline is exercisable end-to-end without a real search backend.
|
|
9427
|
+
return [{ url: `wotann://stub/${encodeURIComponent(q)}`, title: q }];
|
|
9428
|
+
}
|
|
9429
|
+
try {
|
|
9430
|
+
const searchShell = buildShellCommand(`${options.searchCmd} ${JSON.stringify(q)}`);
|
|
9431
|
+
const { stdout } = await execFileAsync(searchShell.file, [...searchShell.argv]);
|
|
9432
|
+
const parsed = JSON.parse(stdout);
|
|
9433
|
+
if (Array.isArray(parsed)) {
|
|
9434
|
+
return parsed.filter((h) => !!h && typeof h === "object" && typeof h.url === "string");
|
|
9435
|
+
}
|
|
9436
|
+
return [];
|
|
9437
|
+
}
|
|
9438
|
+
catch (err) {
|
|
9439
|
+
console.error(chalk.yellow(` search-cmd failed for "${q}": ${err instanceof Error ? err.message : String(err)}`));
|
|
9440
|
+
return [];
|
|
9441
|
+
}
|
|
9442
|
+
};
|
|
9443
|
+
const strategy = (options.strategy ?? "dual-confidence").toLowerCase();
|
|
9444
|
+
if (strategy === "dual-confidence" || strategy === "dc") {
|
|
9445
|
+
const result = await strategies.dualConfidenceSearch(query, search, {
|
|
9446
|
+
hitsPerCall,
|
|
9447
|
+
});
|
|
9448
|
+
if (options.json === true) {
|
|
9449
|
+
process.stdout.write(JSON.stringify(result, null, 2) + "\n");
|
|
9450
|
+
return;
|
|
9451
|
+
}
|
|
9452
|
+
const banner = result.diverged
|
|
9453
|
+
? chalk.yellow(`Diverged (low confidence)`)
|
|
9454
|
+
: chalk.green(`Converged (high confidence)`);
|
|
9455
|
+
console.log(chalk.bold(`\nDual-confidence: ${banner}`));
|
|
9456
|
+
console.log(chalk.dim(` Confidence (Jaccard): ${result.confidence.toFixed(3)}`));
|
|
9457
|
+
console.log(chalk.dim(` Overlap hits : ${result.overlap.length}`));
|
|
9458
|
+
console.log(chalk.dim(` Primary-only : ${result.primaryHits.length}`));
|
|
9459
|
+
console.log(chalk.dim(` Twin-only : ${result.twinHits.length}`));
|
|
9460
|
+
if (result.overlap.length > 0) {
|
|
9461
|
+
console.log(chalk.bold("\nHigh-confidence sources:"));
|
|
9462
|
+
for (const h of result.overlap.slice(0, 8)) {
|
|
9463
|
+
console.log(` ${chalk.dim("●")} ${h.title ?? h.url} ${chalk.dim(h.url)}`);
|
|
9464
|
+
}
|
|
9465
|
+
}
|
|
9466
|
+
return;
|
|
9467
|
+
}
|
|
9468
|
+
if (strategy === "iterdrag") {
|
|
9469
|
+
const decompose = async (q) => {
|
|
9470
|
+
// Heuristic decomposition: split on " and "/" or "/";", or fall back
|
|
9471
|
+
// to keyword extraction. Useful default that doesn't need an LLM.
|
|
9472
|
+
const parts = q
|
|
9473
|
+
.split(/\s+(?:and|or)\s+|;\s*/i)
|
|
9474
|
+
.filter((p) => p.trim().length > 0);
|
|
9475
|
+
return parts.length > 1 ? parts : [];
|
|
9476
|
+
};
|
|
9477
|
+
const root = await strategies.iterDrag(query, search, decompose, {
|
|
9478
|
+
maxDepth,
|
|
9479
|
+
hitsPerNode: hitsPerCall,
|
|
9480
|
+
});
|
|
9481
|
+
if (options.json === true) {
|
|
9482
|
+
process.stdout.write(JSON.stringify(root, null, 2) + "\n");
|
|
9483
|
+
return;
|
|
9484
|
+
}
|
|
9485
|
+
const all = [...strategies.iterDragNodes(root)];
|
|
9486
|
+
console.log(chalk.bold(`\nIterDRAG: ${all.length} node(s) walked`));
|
|
9487
|
+
for (const n of all) {
|
|
9488
|
+
const indent = " ".repeat(n.depth);
|
|
9489
|
+
console.log(`${indent}${chalk.cyan(`Q[${n.depth}]`)} ${n.question}`);
|
|
9490
|
+
console.log(chalk.dim(`${indent} hits: ${n.hits.length}`));
|
|
9491
|
+
}
|
|
9492
|
+
if (root.aggregated) {
|
|
9493
|
+
console.log(chalk.bold("\nAggregated answer:"));
|
|
9494
|
+
console.log(root.aggregated);
|
|
9495
|
+
}
|
|
9496
|
+
return;
|
|
9497
|
+
}
|
|
9498
|
+
console.error(chalk.red(`error: unknown strategy "${strategy}"`));
|
|
9499
|
+
process.exit(2);
|
|
9500
|
+
});
|
|
9501
|
+
// ── wotann skill optimize-description <name> ────────────────
|
|
9502
|
+
//
|
|
9503
|
+
// Surfaces src/skills/description-optimizer.ts as a CLI tool. Reads
|
|
9504
|
+
// the SKILL.md frontmatter for `name`, evaluates its current
|
|
9505
|
+
// description against a labeled prompt corpus, and prints suggested
|
|
9506
|
+
// rewrites with their F1 deltas. Pass --write to overwrite the
|
|
9507
|
+
// description in-place (the body of the SKILL.md is preserved).
|
|
9508
|
+
// Reattach to the existing `skillCmd` (declared near line 4694) — defining
|
|
9509
|
+
// `program.command("skill")` again would throw at registration time
|
|
9510
|
+
// ("cannot add command 'skill' as already have command 'skill'").
|
|
9511
|
+
skillCmd
|
|
9512
|
+
.command("optimize-description <name>")
|
|
9513
|
+
.description("Suggest a higher-F1 description for the named skill")
|
|
9514
|
+
.option("--corpus <path>", "JSON file with {positives: string[], negatives: string[]}")
|
|
9515
|
+
.option("--write", "Overwrite the SKILL.md description with the best variant", false)
|
|
9516
|
+
.option("--threshold <n>", "Trigger threshold ∈ [0,1]", "0.5")
|
|
9517
|
+
.option("--from-telemetry [path]", "Mine the corpus from skill-activation telemetry (default ~/.wotann/skill-telemetry.jsonl)")
|
|
9518
|
+
.option("--max-each <n>", "Cap on positives/negatives mined from telemetry", "200")
|
|
9519
|
+
.option("--json", "Emit JSON instead of a human-readable report", false)
|
|
9520
|
+
.action(async (name, options) => {
|
|
9521
|
+
const { optimizeDescription, evaluateDescription } = await import("./skills/description-optimizer.js");
|
|
9522
|
+
const { resolveWotannHomeSubdir } = await import("./utils/wotann-home.js");
|
|
9523
|
+
const fs = await import("node:fs");
|
|
9524
|
+
const path = await import("node:path");
|
|
9525
|
+
// Locate the SKILL.md — search ~/.wotann/skills/<name>/SKILL.md, then
|
|
9526
|
+
// ./skills/<name>/SKILL.md as a workspace-local fallback.
|
|
9527
|
+
const candidates = [
|
|
9528
|
+
resolveWotannHomeSubdir(path.join("skills", name, "SKILL.md")),
|
|
9529
|
+
path.join(process.cwd(), "skills", name, "SKILL.md"),
|
|
9530
|
+
];
|
|
9531
|
+
const skillPath = candidates.find((p) => fs.existsSync(p));
|
|
9532
|
+
if (!skillPath) {
|
|
9533
|
+
console.error(chalk.red(`error: SKILL.md for "${name}" not found in:`));
|
|
9534
|
+
for (const c of candidates)
|
|
9535
|
+
console.error(chalk.dim(` ${c}`));
|
|
9536
|
+
process.exit(1);
|
|
9537
|
+
}
|
|
9538
|
+
const raw = fs.readFileSync(skillPath, "utf-8");
|
|
9539
|
+
const fmMatch = raw.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
|
|
9540
|
+
if (!fmMatch || !fmMatch[1] || !fmMatch[2]) {
|
|
9541
|
+
console.error(chalk.red(`error: SKILL.md missing frontmatter at ${skillPath}`));
|
|
9542
|
+
process.exit(1);
|
|
9543
|
+
}
|
|
9544
|
+
const frontmatter = fmMatch[1];
|
|
9545
|
+
const body = fmMatch[2];
|
|
9546
|
+
const descMatch = frontmatter.match(/^description:\s*(.+)$/m);
|
|
9547
|
+
const currentDesc = descMatch && descMatch[1] ? descMatch[1].trim() : "";
|
|
9548
|
+
if (currentDesc.length === 0) {
|
|
9549
|
+
console.error(chalk.red(`error: no "description" in frontmatter`));
|
|
9550
|
+
process.exit(1);
|
|
9551
|
+
}
|
|
9552
|
+
let positives = [];
|
|
9553
|
+
let negatives = [];
|
|
9554
|
+
if (options.corpus) {
|
|
9555
|
+
try {
|
|
9556
|
+
const parsed = JSON.parse(fs.readFileSync(options.corpus, "utf-8"));
|
|
9557
|
+
positives = Array.isArray(parsed.positives) ? parsed.positives : [];
|
|
9558
|
+
negatives = Array.isArray(parsed.negatives) ? parsed.negatives : [];
|
|
9559
|
+
}
|
|
9560
|
+
catch (err) {
|
|
9561
|
+
console.error(chalk.red(`error: failed to read corpus: ${err instanceof Error ? err.message : err}`));
|
|
9562
|
+
process.exit(1);
|
|
9563
|
+
}
|
|
9564
|
+
}
|
|
9565
|
+
// --from-telemetry: mine the corpus directly from observed activations.
|
|
9566
|
+
// This closes the loop end-to-end: real usage → telemetry log → corpus
|
|
9567
|
+
// → optimizer → improved description.
|
|
9568
|
+
if (options.fromTelemetry !== undefined) {
|
|
9569
|
+
const telemetryPath = typeof options.fromTelemetry === "string" && options.fromTelemetry.length > 0
|
|
9570
|
+
? options.fromTelemetry
|
|
9571
|
+
: resolveWotannHomeSubdir("skill-telemetry.jsonl");
|
|
9572
|
+
const { loadTelemetryLog, extractCorpusForSkill } = await import("./skills/activation-telemetry.js");
|
|
9573
|
+
const result = loadTelemetryLog(telemetryPath);
|
|
9574
|
+
const maxEach = Number(options.maxEach ?? 200);
|
|
9575
|
+
const corpus = extractCorpusForSkill(result.events, name, {
|
|
9576
|
+
maxEach: Number.isFinite(maxEach) && maxEach > 0 ? maxEach : 200,
|
|
9577
|
+
});
|
|
9578
|
+
positives = [...positives, ...corpus.positives];
|
|
9579
|
+
negatives = [...negatives, ...corpus.negatives];
|
|
9580
|
+
console.error(chalk.dim(` telemetry: ${result.events.length} events scanned (skipped ${result.skipped} malformed) → ${corpus.positives.length} positives + ${corpus.negatives.length} negatives mined for "${name}"`));
|
|
9581
|
+
}
|
|
9582
|
+
if (positives.length === 0) {
|
|
9583
|
+
console.error(chalk.yellow("no labeled prompts (use --corpus or --from-telemetry). Showing baseline eval against empty set."));
|
|
9584
|
+
}
|
|
9585
|
+
const threshold = Number(options.threshold ?? 0.5);
|
|
9586
|
+
const r = await optimizeDescription({
|
|
9587
|
+
current: currentDesc,
|
|
9588
|
+
positives,
|
|
9589
|
+
negatives,
|
|
9590
|
+
threshold,
|
|
9591
|
+
});
|
|
9592
|
+
if (options.json === true) {
|
|
9593
|
+
process.stdout.write(JSON.stringify(r, null, 2) + "\n");
|
|
9594
|
+
return;
|
|
9595
|
+
}
|
|
9596
|
+
console.log(chalk.bold(`\nSkill: ${name}`));
|
|
9597
|
+
console.log(chalk.dim(` Path: ${skillPath}`));
|
|
9598
|
+
console.log(chalk.bold("\nOriginal:"));
|
|
9599
|
+
console.log(` ${currentDesc}`);
|
|
9600
|
+
console.log(chalk.dim(` F1: ${r.originalEval.f1.toFixed(3)} (P ${r.originalEval.precision.toFixed(3)} / R ${r.originalEval.recall.toFixed(3)})`));
|
|
9601
|
+
console.log(chalk.bold("\nBest:"));
|
|
9602
|
+
console.log(` ${r.best}`);
|
|
9603
|
+
console.log(chalk.dim(` F1: ${r.bestEval.f1.toFixed(3)} (P ${r.bestEval.precision.toFixed(3)} / R ${r.bestEval.recall.toFixed(3)})`));
|
|
9604
|
+
if (r.candidates.length > 1) {
|
|
9605
|
+
console.log(chalk.bold("\nAll candidates:"));
|
|
9606
|
+
for (const c of r.candidates.slice(0, 8)) {
|
|
9607
|
+
const tag = c.description === currentDesc ? "ORIG" : " ";
|
|
9608
|
+
console.log(chalk.dim(` [${tag}] F1=${c.eval.f1.toFixed(3)} ${c.description.slice(0, 100)}`));
|
|
9609
|
+
}
|
|
9610
|
+
}
|
|
9611
|
+
if (options.write && r.best !== currentDesc) {
|
|
9612
|
+
const newFrontmatter = frontmatter.replace(/^description:\s*.+$/m, `description: ${r.best}`);
|
|
9613
|
+
const updated = `---\n${newFrontmatter}\n---\n${body}`;
|
|
9614
|
+
fs.writeFileSync(skillPath, updated);
|
|
9615
|
+
console.log(chalk.green(`\n✓ Updated description in ${skillPath}`));
|
|
9616
|
+
}
|
|
9617
|
+
else if (options.write) {
|
|
9618
|
+
console.log(chalk.dim("\n--write: best matched original; nothing to do."));
|
|
9619
|
+
}
|
|
9620
|
+
// Touch evaluateDescription so the import isn't dead-code-eliminated.
|
|
9621
|
+
void evaluateDescription;
|
|
9622
|
+
});
|
|
9623
|
+
// `wotann skill mark-outcome <sessionId> <outcome>` — manually flag the
|
|
9624
|
+
// last activation for a session as ok|regret|unknown. Lets users
|
|
9625
|
+
// retroactively correct false positives so the description-optimizer
|
|
9626
|
+
// corpus reflects real intent.
|
|
9627
|
+
skillCmd
|
|
9628
|
+
.command("mark-outcome <sessionId> <outcome>")
|
|
9629
|
+
.description("Flag the last skill activation in a session (ok | regret | unknown)")
|
|
9630
|
+
.action(async (sessionId, outcome) => {
|
|
9631
|
+
if (outcome !== "ok" && outcome !== "regret" && outcome !== "unknown") {
|
|
9632
|
+
console.error(chalk.red(`error: outcome must be ok | regret | unknown (got "${outcome}")`));
|
|
9633
|
+
process.exit(2);
|
|
9634
|
+
}
|
|
9635
|
+
const { SkillActivationTelemetry } = await import("./skills/activation-telemetry.js");
|
|
9636
|
+
const { resolveWotannHomeSubdir } = await import("./utils/wotann-home.js");
|
|
9637
|
+
const t = new SkillActivationTelemetry({
|
|
9638
|
+
path: resolveWotannHomeSubdir("skill-telemetry.jsonl"),
|
|
9639
|
+
});
|
|
9640
|
+
const ok = await t.markOutcome(sessionId, outcome);
|
|
9641
|
+
if (ok) {
|
|
9642
|
+
console.log(chalk.green(`✓ Patched session ${sessionId} → ${outcome}`));
|
|
9643
|
+
}
|
|
9644
|
+
else {
|
|
9645
|
+
console.log(chalk.dim("Telemetry disabled — no patch written."));
|
|
9646
|
+
}
|
|
9647
|
+
});
|
|
9648
|
+
// `wotann skill telemetry-stats` — show how many activation events
|
|
9649
|
+
// the local log has, plus per-skill positive/negative counts via the
|
|
9650
|
+
// optimizer corpus extractor.
|
|
9651
|
+
skillCmd
|
|
9652
|
+
.command("telemetry-stats")
|
|
9653
|
+
.description("Summarise the skill-activation telemetry log")
|
|
9654
|
+
.option("--skill <name>", "Show per-skill corpus counts for one skill")
|
|
9655
|
+
.option("--json", "Emit JSON instead of a human-readable summary", false)
|
|
9656
|
+
.action(async (options) => {
|
|
9657
|
+
const { loadTelemetryLog, extractCorpusForSkill } = await import("./skills/activation-telemetry.js");
|
|
9658
|
+
const { resolveWotannHomeSubdir } = await import("./utils/wotann-home.js");
|
|
9659
|
+
const path = resolveWotannHomeSubdir("skill-telemetry.jsonl");
|
|
9660
|
+
const result = loadTelemetryLog(path);
|
|
9661
|
+
// Aggregate counts by triggered skill (or "<none>" for null).
|
|
9662
|
+
const counts = new Map();
|
|
9663
|
+
let regretCount = 0;
|
|
9664
|
+
for (const e of result.events) {
|
|
9665
|
+
const key = e.triggered?.skill ?? "<none>";
|
|
9666
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
9667
|
+
if (e.outcome === "regret")
|
|
9668
|
+
regretCount++;
|
|
9669
|
+
}
|
|
9670
|
+
const summary = {
|
|
9671
|
+
path,
|
|
9672
|
+
events: result.events.length,
|
|
9673
|
+
malformed: result.skipped,
|
|
9674
|
+
regrets: regretCount,
|
|
9675
|
+
bySkill: Object.fromEntries([...counts.entries()].sort((a, b) => b[1] - a[1])),
|
|
9676
|
+
...(options.skill
|
|
9677
|
+
? {
|
|
9678
|
+
skill: options.skill,
|
|
9679
|
+
corpus: extractCorpusForSkill(result.events, options.skill, { maxEach: 1000 }),
|
|
9680
|
+
}
|
|
9681
|
+
: {}),
|
|
9682
|
+
};
|
|
9683
|
+
if (options.json === true) {
|
|
9684
|
+
process.stdout.write(JSON.stringify(summary, null, 2) + "\n");
|
|
9685
|
+
return;
|
|
9686
|
+
}
|
|
9687
|
+
console.log(chalk.bold(`\nSkill activation telemetry — ${path}`));
|
|
9688
|
+
console.log(chalk.dim(` events: ${summary.events} malformed: ${summary.malformed} regrets: ${summary.regrets}`));
|
|
9689
|
+
if (summary.events === 0) {
|
|
9690
|
+
console.log(chalk.yellow("\n No telemetry yet. Run a few queries through `wotann run` to populate the log."));
|
|
9691
|
+
return;
|
|
9692
|
+
}
|
|
9693
|
+
console.log(chalk.bold("\nActivations by skill:"));
|
|
9694
|
+
for (const [name, count] of Object.entries(summary.bySkill)) {
|
|
9695
|
+
console.log(` ${chalk.cyan(String(name).padEnd(28))} ${String(count).padStart(5)}`);
|
|
9696
|
+
}
|
|
9697
|
+
if (options.skill) {
|
|
9698
|
+
const extracted = extractCorpusForSkill(result.events, options.skill, { maxEach: 1000 });
|
|
9699
|
+
console.log(chalk.bold(`\nCorpus for "${options.skill}":`));
|
|
9700
|
+
console.log(` positives: ${extracted.positives.length}`);
|
|
9701
|
+
console.log(` negatives: ${extracted.negatives.length}`);
|
|
9702
|
+
}
|
|
9703
|
+
});
|
|
9704
|
+
// ── wotann manifest <trajectoryPath> ────────────────────────
|
|
9705
|
+
//
|
|
9706
|
+
// Surfaces src/autopilot/run-manifest.ts. Reads a Trajectory JSON
|
|
9707
|
+
// produced by autopilot/trajectory-recorder.ts and renders the
|
|
9708
|
+
// manifest as Markdown (default), JSON (--json), or both.
|
|
9709
|
+
program
|
|
9710
|
+
.command("manifest <trajectoryPath>")
|
|
9711
|
+
.description("Render an overnight-run manifest from a trajectory JSON")
|
|
9712
|
+
.option("--json", "Emit JSON instead of Markdown", false)
|
|
9713
|
+
.option("--out <path>", "Write the rendered manifest to a file")
|
|
9714
|
+
.option("--cost <usd>", "Total cost USD to embed in the manifest")
|
|
9715
|
+
.option("--title <title>", "Override the auto-derived task title")
|
|
9716
|
+
.action(async (trajectoryPath, options) => {
|
|
9717
|
+
const fs = await import("node:fs");
|
|
9718
|
+
const { loadTrajectory } = await import("./autopilot/trajectory-recorder.js");
|
|
9719
|
+
const { buildManifest, renderManifestMarkdown, renderManifestJson } = await import("./autopilot/run-manifest.js");
|
|
9720
|
+
if (!fs.existsSync(trajectoryPath)) {
|
|
9721
|
+
console.error(chalk.red(`error: trajectory file not found: ${trajectoryPath}`));
|
|
9722
|
+
process.exit(1);
|
|
9723
|
+
}
|
|
9724
|
+
let trajectory;
|
|
9725
|
+
try {
|
|
9726
|
+
trajectory = await loadTrajectory(trajectoryPath);
|
|
9727
|
+
}
|
|
9728
|
+
catch (err) {
|
|
9729
|
+
console.error(chalk.red(`error: failed to load trajectory: ${err instanceof Error ? err.message : err}`));
|
|
9730
|
+
process.exit(1);
|
|
9731
|
+
}
|
|
9732
|
+
const buildOpts = {};
|
|
9733
|
+
if (options.title)
|
|
9734
|
+
buildOpts.taskTitle = options.title;
|
|
9735
|
+
if (options.cost) {
|
|
9736
|
+
const cost = Number(options.cost);
|
|
9737
|
+
if (Number.isFinite(cost))
|
|
9738
|
+
buildOpts.costUsd = cost;
|
|
9739
|
+
}
|
|
9740
|
+
const manifest = buildManifest(trajectory, buildOpts);
|
|
9741
|
+
const rendered = options.json === true ? renderManifestJson(manifest) : renderManifestMarkdown(manifest);
|
|
9742
|
+
if (options.out) {
|
|
9743
|
+
fs.writeFileSync(options.out, rendered);
|
|
9744
|
+
console.log(chalk.green(`✓ Wrote manifest to ${options.out}`));
|
|
9745
|
+
return;
|
|
9746
|
+
}
|
|
9747
|
+
process.stdout.write(rendered + "\n");
|
|
9748
|
+
});
|
|
9749
|
+
// ── wotann effort <prompt> ──────────────────────────────────
|
|
9750
|
+
//
|
|
9751
|
+
// Surfaces src/providers/effort-cascade.ts. Distinct from the existing
|
|
9752
|
+
// `wotann route` command (TaskSemanticRouter / model picker) — this one
|
|
9753
|
+
// is pure heuristics that returns the recommended starting tier the
|
|
9754
|
+
// effort cascade would use. Useful for inspecting how the classifier
|
|
9755
|
+
// rates a given prompt before paying for an LLM call.
|
|
9756
|
+
program
|
|
9757
|
+
.command("effort <prompt>")
|
|
9758
|
+
.description("Show the effort-cascade tier the classifier picks for a prompt")
|
|
9759
|
+
.option("--max-tier <tier>", "minimal | low | medium | high")
|
|
9760
|
+
.option("--min-tier <tier>", "minimal | low | medium | high")
|
|
9761
|
+
.option("--bump", "Force one-tier bump (e.g. retry after low confidence)", false)
|
|
9762
|
+
.option("--json", "Emit JSON", false)
|
|
9763
|
+
.action(async (prompt, options) => {
|
|
9764
|
+
const { classifyEffort, EFFORT_ORDER } = await import("./providers/effort-cascade.js");
|
|
9765
|
+
const isTier = (t) => EFFORT_ORDER.includes(t);
|
|
9766
|
+
const hints = {};
|
|
9767
|
+
if (options.minTier) {
|
|
9768
|
+
if (!isTier(options.minTier)) {
|
|
9769
|
+
console.error(chalk.red(`error: --min-tier must be one of ${EFFORT_ORDER.join("|")}`));
|
|
9770
|
+
process.exit(2);
|
|
9771
|
+
}
|
|
9772
|
+
hints.minTier = options.minTier;
|
|
9773
|
+
}
|
|
9774
|
+
if (options.maxTier) {
|
|
9775
|
+
if (!isTier(options.maxTier)) {
|
|
9776
|
+
console.error(chalk.red(`error: --max-tier must be one of ${EFFORT_ORDER.join("|")}`));
|
|
9777
|
+
process.exit(2);
|
|
9778
|
+
}
|
|
9779
|
+
hints.maxTier = options.maxTier;
|
|
9780
|
+
}
|
|
9781
|
+
if (options.bump === true)
|
|
9782
|
+
hints.bump = true;
|
|
9783
|
+
const tier = classifyEffort(prompt, hints);
|
|
9784
|
+
if (options.json === true) {
|
|
9785
|
+
process.stdout.write(JSON.stringify({ tier, prompt }, null, 2) + "\n");
|
|
9786
|
+
return;
|
|
9787
|
+
}
|
|
9788
|
+
console.log(chalk.bold(`\nEffort tier: ${chalk.cyan(tier)}`));
|
|
9789
|
+
console.log(chalk.dim(` prompt length: ${prompt.length} chars`));
|
|
9790
|
+
console.log(chalk.dim(` Tier ladder : ${EFFORT_ORDER.map((t) => (t === tier ? chalk.cyan(t.toUpperCase()) : t)).join(" → ")}`));
|
|
9791
|
+
console.log(chalk.dim(`\nThe runtime can use this tier to map (provider, model). See effort-cascade.ts.`));
|
|
9792
|
+
});
|
|
8757
9793
|
// ── Parse ───────────────────────────────────────────────────
|
|
8758
9794
|
// Deep-link fast path — if the first positional arg is a `wotann://` URL,
|
|
8759
9795
|
// parse it and dispatch via the deep-link handler BEFORE commander sees
|
|
@@ -8791,6 +9827,9 @@ snipCmd
|
|
|
8791
9827
|
.command("list")
|
|
8792
9828
|
.description("List saved snippets")
|
|
8793
9829
|
.option("--cat <category>", "Filter by category")
|
|
9830
|
+
.option("--tag <tag>", "Filter by tag")
|
|
9831
|
+
.option("--source <source>", "Filter by imported corpus source")
|
|
9832
|
+
.option("--limit <n>", "Maximum rows to print", "200")
|
|
8794
9833
|
.option("--fav", "Only show favorites", false)
|
|
8795
9834
|
.option("--search <query>", "Free-text search via FTS5")
|
|
8796
9835
|
.action(async (opts) => {
|
|
@@ -8803,6 +9842,12 @@ snipCmd
|
|
|
8803
9842
|
const filter = {};
|
|
8804
9843
|
if (opts.cat)
|
|
8805
9844
|
filter.category = opts.cat;
|
|
9845
|
+
if (opts.tag)
|
|
9846
|
+
filter.tag = opts.tag;
|
|
9847
|
+
if (opts.source)
|
|
9848
|
+
filter.source = opts.source;
|
|
9849
|
+
if (opts.limit)
|
|
9850
|
+
filter.limit = Number(opts.limit);
|
|
8806
9851
|
if (opts.fav)
|
|
8807
9852
|
filter.favOnly = true;
|
|
8808
9853
|
if (opts.search)
|
|
@@ -8816,8 +9861,11 @@ snipCmd
|
|
|
8816
9861
|
const star = s.isFavorite ? chalk.yellow("★ ") : " ";
|
|
8817
9862
|
const used = s.useCount > 0 ? chalk.dim(` (used ${s.useCount}×)`) : "";
|
|
8818
9863
|
const cat = s.category ? chalk.dim(` [${s.category}]`) : "";
|
|
9864
|
+
const source = s.source
|
|
9865
|
+
? chalk.dim(` <${s.source}${s.version ? `@${s.version}` : ""}>`)
|
|
9866
|
+
: "";
|
|
8819
9867
|
const vars = s.variables.length > 0 ? chalk.cyan(` {${s.variables.join(", ")}}`) : "";
|
|
8820
|
-
process.stdout.write(`${star}${chalk.bold(s.title)}${cat}${vars}${used}\n`);
|
|
9868
|
+
process.stdout.write(`${star}${chalk.bold(s.title)}${cat}${source}${vars}${used}\n`);
|
|
8821
9869
|
process.stdout.write(chalk.dim(` id: ${s.id}\n`));
|
|
8822
9870
|
}
|
|
8823
9871
|
}
|
|
@@ -8876,6 +9924,45 @@ snipCmd
|
|
|
8876
9924
|
store.close();
|
|
8877
9925
|
}
|
|
8878
9926
|
});
|
|
9927
|
+
snipCmd
|
|
9928
|
+
.command("import <path>")
|
|
9929
|
+
.description("Import a JSON/YAML/Markdown prompt corpus into the shared snippet library")
|
|
9930
|
+
.option("--source <name>", "Corpus source name")
|
|
9931
|
+
.option("--version <version>", "Corpus version or release tag")
|
|
9932
|
+
.option("--url <url>", "Source URL for provenance")
|
|
9933
|
+
.option("--cat <category>", "Default category")
|
|
9934
|
+
.option("--tags <csv>", "Default comma-separated tags")
|
|
9935
|
+
.action(async (path, opts) => {
|
|
9936
|
+
const { readFileSync } = await import("node:fs");
|
|
9937
|
+
const { SnippetStore } = await import("./snippets/snippet-store.js");
|
|
9938
|
+
const { parsePromptCorpusText } = await import("./snippets/prompt-corpus.js");
|
|
9939
|
+
const { resolveWotannHomeSubdir } = await import("./utils/wotann-home.js");
|
|
9940
|
+
const { join } = await import("node:path");
|
|
9941
|
+
const text = readFileSync(path, "utf-8");
|
|
9942
|
+
const corpus = parsePromptCorpusText(text, {
|
|
9943
|
+
...(opts.source ? { source: opts.source } : {}),
|
|
9944
|
+
...(opts.version ? { version: opts.version } : {}),
|
|
9945
|
+
...(opts.url ? { sourceUrl: opts.url } : {}),
|
|
9946
|
+
...(opts.cat ? { category: opts.cat } : {}),
|
|
9947
|
+
...(opts.tags
|
|
9948
|
+
? {
|
|
9949
|
+
tags: opts.tags
|
|
9950
|
+
.split(",")
|
|
9951
|
+
.map((tag) => tag.trim())
|
|
9952
|
+
.filter((tag) => tag.length > 0),
|
|
9953
|
+
}
|
|
9954
|
+
: {}),
|
|
9955
|
+
});
|
|
9956
|
+
const dbPath = join(resolveWotannHomeSubdir(""), "snippets.db");
|
|
9957
|
+
const store = new SnippetStore(dbPath);
|
|
9958
|
+
try {
|
|
9959
|
+
const result = store.importCorpus(corpus);
|
|
9960
|
+
process.stdout.write(chalk.green(`✓ imported ${result.imported}, updated ${result.updated}, skipped ${result.skipped} from ${corpus.source}\n`));
|
|
9961
|
+
}
|
|
9962
|
+
finally {
|
|
9963
|
+
store.close();
|
|
9964
|
+
}
|
|
9965
|
+
});
|
|
8879
9966
|
snipCmd
|
|
8880
9967
|
.command("use <id>")
|
|
8881
9968
|
.description("Render a snippet (with optional --var key=value overrides) to stdout")
|
|
@@ -8960,6 +10047,10 @@ snipCmd
|
|
|
8960
10047
|
body: current.body,
|
|
8961
10048
|
category: current.category,
|
|
8962
10049
|
tags: current.tags,
|
|
10050
|
+
source: current.source,
|
|
10051
|
+
externalId: current.externalId,
|
|
10052
|
+
sourceUrl: current.sourceUrl,
|
|
10053
|
+
version: current.version,
|
|
8963
10054
|
isFavorite: next,
|
|
8964
10055
|
});
|
|
8965
10056
|
process.stdout.write(chalk.green(`✓ ${next ? "favorited" : "unfavorited"} ${current.title}\n`));
|
|
@@ -9086,6 +10177,31 @@ toolsCmd
|
|
|
9086
10177
|
if (!result.markdown.endsWith("\n"))
|
|
9087
10178
|
process.stdout.write("\n");
|
|
9088
10179
|
});
|
|
10180
|
+
toolsCmd
|
|
10181
|
+
.command("ingest-capabilities")
|
|
10182
|
+
.alias("markitdown-capabilities")
|
|
10183
|
+
.description("Show runtime-probed document/image/audio ingestion support")
|
|
10184
|
+
.option("--json", "Emit result as JSON", false)
|
|
10185
|
+
.action(async (opts) => {
|
|
10186
|
+
const { getMarkitdownCapabilities } = await import("./tools/markitdown-bridge.js");
|
|
10187
|
+
const report = await getMarkitdownCapabilities();
|
|
10188
|
+
if (opts.json) {
|
|
10189
|
+
process.stdout.write(JSON.stringify(report, null, 2) + "\n");
|
|
10190
|
+
return;
|
|
10191
|
+
}
|
|
10192
|
+
process.stdout.write(chalk.bold("Ingestion capabilities\n"));
|
|
10193
|
+
for (const capability of report.capabilities) {
|
|
10194
|
+
const statusColor = capability.status === "available"
|
|
10195
|
+
? chalk.green
|
|
10196
|
+
: capability.status === "requires_key"
|
|
10197
|
+
? chalk.yellow
|
|
10198
|
+
: chalk.red;
|
|
10199
|
+
process.stdout.write(`${statusColor(capability.status.padEnd(15))} ${capability.label} ${chalk.dim(capability.extensions.join(" "))}\n`);
|
|
10200
|
+
process.stdout.write(` ${chalk.dim(capability.converter)}\n`);
|
|
10201
|
+
if (capability.notes)
|
|
10202
|
+
process.stdout.write(` ${chalk.dim(capability.notes)}\n`);
|
|
10203
|
+
}
|
|
10204
|
+
});
|
|
9089
10205
|
// ── Orphan-wires registrar (V9 follow-up) ─────────────────────
|
|
9090
10206
|
// Mounts 14 previously-orphaned library modules under `wotann ow <verb>`
|
|
9091
10207
|
// via a single `registerOrphanWires(program)` call. Each subcommand is a
|
|
@@ -9109,6 +10225,24 @@ catch (err) {
|
|
|
9109
10225
|
if (isHelpOrVersion) {
|
|
9110
10226
|
process.exit(typeof e.exitCode === "number" ? e.exitCode : 0);
|
|
9111
10227
|
}
|
|
10228
|
+
const message = typeof e.message === "string" ? e.message : "";
|
|
10229
|
+
if (!code.startsWith("commander.") && message.length > 0) {
|
|
10230
|
+
const lower = message.toLowerCase();
|
|
10231
|
+
const daemonRelated = lower.includes("enoent") ||
|
|
10232
|
+
lower.includes("econnrefused") ||
|
|
10233
|
+
lower.includes("ipc") ||
|
|
10234
|
+
lower.includes("socket") ||
|
|
10235
|
+
lower.includes("daemon") ||
|
|
10236
|
+
lower.includes("rpc timeout") ||
|
|
10237
|
+
lower.includes("not connected");
|
|
10238
|
+
if (daemonRelated) {
|
|
10239
|
+
process.stderr.write(chalk.red(`KAIROS daemon is not reachable: ${message}\n`));
|
|
10240
|
+
process.stderr.write(chalk.dim("Run `wotann daemon start` or `wotann engine start`, then retry.\n"));
|
|
10241
|
+
}
|
|
10242
|
+
else {
|
|
10243
|
+
process.stderr.write(chalk.red(`${message}\n`));
|
|
10244
|
+
}
|
|
10245
|
+
}
|
|
9112
10246
|
// Real usage failure (unknown command, missing arg, bad option). Commander
|
|
9113
10247
|
// already wrote the error message to stderr via configureOutput.writeErr,
|
|
9114
10248
|
// so we only need to set the exit code.
|