@nexus-cortex/cli 4.26.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cortex/agents/AGENT_PROFILE_GUIDE.md +307 -0
- package/.cortex/agents/README.md +268 -0
- package/.cortex/agents/a-frontend-landing-page-designer.md +41 -0
- package/.cortex/agents/autoresearch-agent.md +49 -0
- package/.cortex/agents/code-reviewer.md +63 -0
- package/.cortex/agents/context-research.md +26 -0
- package/.cortex/agents/doc-writer.md +92 -0
- package/.cortex/agents/explore.md +63 -0
- package/.cortex/agents/new-model-api-integrator-analyst.md +41 -0
- package/.cortex/agents/plan.md +109 -0
- package/.cortex/agents/pr-architecture-reviewer.md +77 -0
- package/.cortex/agents/pr-code-quality.md +78 -0
- package/.cortex/agents/pr-implementer.md +50 -0
- package/.cortex/agents/pr-security-auditor.md +62 -0
- package/.cortex/agents/pr-test-writer.md +67 -0
- package/.cortex/agents/refactor.md +118 -0
- package/.cortex/agents/test-writer.md +72 -0
- package/.cortex/agents/web-researcher.md +72 -0
- package/.cortex/bench/tasks/sample-tasks.json +20 -0
- package/.cortex/commands/compare.md +14 -0
- package/.cortex/commands/deps.md +16 -0
- package/.cortex/commands/diff.md +14 -0
- package/.cortex/commands/explain.md +16 -0
- package/.cortex/commands/find-bug.md +13 -0
- package/.cortex/commands/profile.md +15 -0
- package/.cortex/commands/review.md +18 -0
- package/.cortex/commands/search.md +16 -0
- package/.cortex/commands/test.md +15 -0
- package/.cortex/permissions.dev.json +20 -0
- package/.cortex/permissions.example.json +71 -0
- package/.cortex/permissions.prod.json +63 -0
- package/.cortex/permissions.test.json +19 -0
- package/.cortex/skills/autoresearch/SKILL.md +77 -0
- package/.cortex/skills/autoresearch/personas/README.md +45 -0
- package/.cortex/skills/autoresearch/personas/aggressive-refactor.md +25 -0
- package/.cortex/skills/autoresearch/personas/creative.md +29 -0
- package/.cortex/skills/autoresearch/personas/perf-hunter.md +27 -0
- package/.cortex/skills/autoresearch/personas/precise.md +23 -0
- package/.cortex/skills/autoresearch/personas/root-cause.md +26 -0
- package/.cortex/skills/autoresearch/personas/security-auditor.md +29 -0
- package/.cortex/skills/autoresearch/personas/skeptic-reviewer.md +31 -0
- package/.cortex/skills/autoresearch/personas/test-first.md +25 -0
- package/.cortex/skills/best-of-n/SKILL.md +76 -0
- package/.cortex/skills/cortex/SKILL.md +834 -0
- package/.cortex/skills/cortex-bench/SKILL.md +354 -0
- package/.cortex/skills/docx/SKILL.md +83 -0
- package/.cortex/skills/pdf-documents/SKILL.md +297 -0
- package/.cortex/skills/pdf-documents/sections/01-image-acquisition.md +132 -0
- package/.cortex/skills/pdf-documents/sections/02-ai-image-generation.md +274 -0
- package/.cortex/skills/pdf-documents/sections/03-paper-sizes.md +89 -0
- package/.cortex/skills/pdf-documents/sections/04-design-system.md +549 -0
- package/.cortex/skills/pdf-documents/sections/05-css-print-rules.md +135 -0
- package/.cortex/skills/pdf-documents/sections/06-svg-charts.md +100 -0
- package/.cortex/skills/pdf-documents/sections/07-templates.md +224 -0
- package/.cortex/skills/pdf-documents/sections/08-scaled-output.md +164 -0
- package/.cortex/skills/pdf-documents/sections/09-preview-qa.md +66 -0
- package/.cortex/skills/pdf-documents/sections/10-reading-pdfs.md +499 -0
- package/.cortex/skills/pdf-documents/sections/11-form-filling.md +241 -0
- package/.cortex/skills/pptx/SKILL.md +90 -0
- package/.cortex/skills/resume-analyst/SKILL.md +373 -0
- package/.cortex/skills/verify-work/SKILL.md +74 -0
- package/.cortex/skills/xlsx/SKILL.md +101 -0
- package/.cortex/system-messages/messages/WORK_QUALITY.md +159 -0
- package/.cortex/system-messages/registry.json +18 -0
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +13 -0
- package/bin/cortex.js +548 -0
- package/dist/agent-mode.d.ts +21 -0
- package/dist/agent-mode.d.ts.map +1 -0
- package/dist/agent-mode.js +511 -0
- package/dist/agent-mode.js.map +1 -0
- package/dist/client/CortexClient.d.ts +84 -0
- package/dist/client/CortexClient.d.ts.map +1 -0
- package/dist/client/CortexClient.js +163 -0
- package/dist/client/CortexClient.js.map +1 -0
- package/dist/commands/artifact/list.d.ts +15 -0
- package/dist/commands/artifact/list.d.ts.map +1 -0
- package/dist/commands/artifact/list.js +89 -0
- package/dist/commands/artifact/list.js.map +1 -0
- package/dist/commands/artifact/restart.d.ts +13 -0
- package/dist/commands/artifact/restart.d.ts.map +1 -0
- package/dist/commands/artifact/restart.js +56 -0
- package/dist/commands/artifact/restart.js.map +1 -0
- package/dist/commands/artifact/status.d.ts +13 -0
- package/dist/commands/artifact/status.d.ts.map +1 -0
- package/dist/commands/artifact/status.js +100 -0
- package/dist/commands/artifact/status.js.map +1 -0
- package/dist/commands/artifact/stop.d.ts +13 -0
- package/dist/commands/artifact/stop.d.ts.map +1 -0
- package/dist/commands/artifact/stop.js +50 -0
- package/dist/commands/artifact/stop.js.map +1 -0
- package/dist/commands/autoresearch/bench.d.ts +32 -0
- package/dist/commands/autoresearch/bench.d.ts.map +1 -0
- package/dist/commands/autoresearch/bench.js +123 -0
- package/dist/commands/autoresearch/bench.js.map +1 -0
- package/dist/commands/autoresearch/commandRunner.d.ts +35 -0
- package/dist/commands/autoresearch/commandRunner.d.ts.map +1 -0
- package/dist/commands/autoresearch/commandRunner.js +91 -0
- package/dist/commands/autoresearch/commandRunner.js.map +1 -0
- package/dist/commands/autoresearch/evaluate.d.ts +18 -0
- package/dist/commands/autoresearch/evaluate.d.ts.map +1 -0
- package/dist/commands/autoresearch/evaluate.js +117 -0
- package/dist/commands/autoresearch/evaluate.js.map +1 -0
- package/dist/commands/autoresearch/experiment.d.ts +38 -0
- package/dist/commands/autoresearch/experiment.d.ts.map +1 -0
- package/dist/commands/autoresearch/experiment.js +168 -0
- package/dist/commands/autoresearch/experiment.js.map +1 -0
- package/dist/commands/autoresearch/fix.d.ts +10 -0
- package/dist/commands/autoresearch/fix.d.ts.map +1 -0
- package/dist/commands/autoresearch/fix.js +86 -0
- package/dist/commands/autoresearch/fix.js.map +1 -0
- package/dist/commands/autoresearch/harnessProcess.d.ts +48 -0
- package/dist/commands/autoresearch/harnessProcess.d.ts.map +1 -0
- package/dist/commands/autoresearch/harnessProcess.js +140 -0
- package/dist/commands/autoresearch/harnessProcess.js.map +1 -0
- package/dist/commands/autoresearch/list.d.ts +6 -0
- package/dist/commands/autoresearch/list.d.ts.map +1 -0
- package/dist/commands/autoresearch/list.js +38 -0
- package/dist/commands/autoresearch/list.js.map +1 -0
- package/dist/commands/autoresearch/loop.d.ts +26 -0
- package/dist/commands/autoresearch/loop.d.ts.map +1 -0
- package/dist/commands/autoresearch/loop.js +242 -0
- package/dist/commands/autoresearch/loop.js.map +1 -0
- package/dist/commands/cache/metrics.d.ts +13 -0
- package/dist/commands/cache/metrics.d.ts.map +1 -0
- package/dist/commands/cache/metrics.js +77 -0
- package/dist/commands/cache/metrics.js.map +1 -0
- package/dist/commands/chat/AgenticChat.d.ts +39 -0
- package/dist/commands/chat/AgenticChat.d.ts.map +1 -0
- package/dist/commands/chat/AgenticChat.js +201 -0
- package/dist/commands/chat/AgenticChat.js.map +1 -0
- package/dist/commands/chat/renderers/CodeRenderer.d.ts +36 -0
- package/dist/commands/chat/renderers/CodeRenderer.d.ts.map +1 -0
- package/dist/commands/chat/renderers/CodeRenderer.js +85 -0
- package/dist/commands/chat/renderers/CodeRenderer.js.map +1 -0
- package/dist/commands/chat/renderers/ToolRenderer.d.ts +30 -0
- package/dist/commands/chat/renderers/ToolRenderer.d.ts.map +1 -0
- package/dist/commands/chat/renderers/ToolRenderer.js +93 -0
- package/dist/commands/chat/renderers/ToolRenderer.js.map +1 -0
- package/dist/commands/chat/single-message.d.ts +15 -0
- package/dist/commands/chat/single-message.d.ts.map +1 -0
- package/dist/commands/chat/single-message.js +85 -0
- package/dist/commands/chat/single-message.js.map +1 -0
- package/dist/commands/config/categories.d.ts +8 -0
- package/dist/commands/config/categories.d.ts.map +1 -0
- package/dist/commands/config/categories.js +75 -0
- package/dist/commands/config/categories.js.map +1 -0
- package/dist/commands/config/category.d.ts +8 -0
- package/dist/commands/config/category.d.ts.map +1 -0
- package/dist/commands/config/category.js +81 -0
- package/dist/commands/config/category.js.map +1 -0
- package/dist/commands/config/get.d.ts +9 -0
- package/dist/commands/config/get.d.ts.map +1 -0
- package/dist/commands/config/get.js +98 -0
- package/dist/commands/config/get.js.map +1 -0
- package/dist/commands/config/reset.d.ts +6 -0
- package/dist/commands/config/reset.d.ts.map +1 -0
- package/dist/commands/config/reset.js +68 -0
- package/dist/commands/config/reset.js.map +1 -0
- package/dist/commands/config/set.d.ts +6 -0
- package/dist/commands/config/set.d.ts.map +1 -0
- package/dist/commands/config/set.js +60 -0
- package/dist/commands/config/set.js.map +1 -0
- package/dist/commands/config/utils.d.ts +14 -0
- package/dist/commands/config/utils.d.ts.map +1 -0
- package/dist/commands/config/utils.js +54 -0
- package/dist/commands/config/utils.js.map +1 -0
- package/dist/commands/context/boundaries.d.ts +13 -0
- package/dist/commands/context/boundaries.d.ts.map +1 -0
- package/dist/commands/context/boundaries.js +45 -0
- package/dist/commands/context/boundaries.js.map +1 -0
- package/dist/commands/context/compact.d.ts +13 -0
- package/dist/commands/context/compact.d.ts.map +1 -0
- package/dist/commands/context/compact.js +41 -0
- package/dist/commands/context/compact.js.map +1 -0
- package/dist/commands/context/savings.d.ts +13 -0
- package/dist/commands/context/savings.d.ts.map +1 -0
- package/dist/commands/context/savings.js +49 -0
- package/dist/commands/context/savings.js.map +1 -0
- package/dist/commands/context/status.d.ts +13 -0
- package/dist/commands/context/status.d.ts.map +1 -0
- package/dist/commands/context/status.js +52 -0
- package/dist/commands/context/status.js.map +1 -0
- package/dist/commands/context/strategy.d.ts +13 -0
- package/dist/commands/context/strategy.d.ts.map +1 -0
- package/dist/commands/context/strategy.js +66 -0
- package/dist/commands/context/strategy.js.map +1 -0
- package/dist/commands/mcp/disable.d.ts +5 -0
- package/dist/commands/mcp/disable.d.ts.map +1 -0
- package/dist/commands/mcp/disable.js +26 -0
- package/dist/commands/mcp/disable.js.map +1 -0
- package/dist/commands/mcp/edit.d.ts +9 -0
- package/dist/commands/mcp/edit.d.ts.map +1 -0
- package/dist/commands/mcp/edit.js +62 -0
- package/dist/commands/mcp/edit.js.map +1 -0
- package/dist/commands/mcp/enable.d.ts +5 -0
- package/dist/commands/mcp/enable.d.ts.map +1 -0
- package/dist/commands/mcp/enable.js +27 -0
- package/dist/commands/mcp/enable.js.map +1 -0
- package/dist/commands/mcp/init.d.ts +9 -0
- package/dist/commands/mcp/init.d.ts.map +1 -0
- package/dist/commands/mcp/init.js +97 -0
- package/dist/commands/mcp/init.js.map +1 -0
- package/dist/commands/mcp/list.d.ts +6 -0
- package/dist/commands/mcp/list.d.ts.map +1 -0
- package/dist/commands/mcp/list.js +56 -0
- package/dist/commands/mcp/list.js.map +1 -0
- package/dist/commands/mcp/server.d.ts +6 -0
- package/dist/commands/mcp/server.d.ts.map +1 -0
- package/dist/commands/mcp/server.js +44 -0
- package/dist/commands/mcp/server.js.map +1 -0
- package/dist/commands/mcp/status.d.ts +6 -0
- package/dist/commands/mcp/status.d.ts.map +1 -0
- package/dist/commands/mcp/status.js +43 -0
- package/dist/commands/mcp/status.js.map +1 -0
- package/dist/commands/mcp/tools.d.ts +7 -0
- package/dist/commands/mcp/tools.d.ts.map +1 -0
- package/dist/commands/mcp/tools.js +82 -0
- package/dist/commands/mcp/tools.js.map +1 -0
- package/dist/commands/mcp/validate.d.ts +8 -0
- package/dist/commands/mcp/validate.d.ts.map +1 -0
- package/dist/commands/mcp/validate.js +121 -0
- package/dist/commands/mcp/validate.js.map +1 -0
- package/dist/commands/middleware/config.d.ts +13 -0
- package/dist/commands/middleware/config.d.ts.map +1 -0
- package/dist/commands/middleware/config.js +87 -0
- package/dist/commands/middleware/config.js.map +1 -0
- package/dist/commands/middleware/disable.d.ts +13 -0
- package/dist/commands/middleware/disable.d.ts.map +1 -0
- package/dist/commands/middleware/disable.js +50 -0
- package/dist/commands/middleware/disable.js.map +1 -0
- package/dist/commands/middleware/enable.d.ts +13 -0
- package/dist/commands/middleware/enable.d.ts.map +1 -0
- package/dist/commands/middleware/enable.js +50 -0
- package/dist/commands/middleware/enable.js.map +1 -0
- package/dist/commands/middleware/list.d.ts +13 -0
- package/dist/commands/middleware/list.d.ts.map +1 -0
- package/dist/commands/middleware/list.js +64 -0
- package/dist/commands/middleware/list.js.map +1 -0
- package/dist/commands/middleware/status.d.ts +13 -0
- package/dist/commands/middleware/status.d.ts.map +1 -0
- package/dist/commands/middleware/status.js +80 -0
- package/dist/commands/middleware/status.js.map +1 -0
- package/dist/commands/models/compare.d.ts +9 -0
- package/dist/commands/models/compare.d.ts.map +1 -0
- package/dist/commands/models/compare.js +76 -0
- package/dist/commands/models/compare.js.map +1 -0
- package/dist/commands/models/cost.d.ts +9 -0
- package/dist/commands/models/cost.d.ts.map +1 -0
- package/dist/commands/models/cost.js +64 -0
- package/dist/commands/models/cost.js.map +1 -0
- package/dist/commands/models/info.d.ts +9 -0
- package/dist/commands/models/info.d.ts.map +1 -0
- package/dist/commands/models/info.js +61 -0
- package/dist/commands/models/info.js.map +1 -0
- package/dist/commands/models/list.d.ts +6 -0
- package/dist/commands/models/list.d.ts.map +1 -0
- package/dist/commands/models/list.js +66 -0
- package/dist/commands/models/list.js.map +1 -0
- package/dist/commands/models/providers.d.ts +13 -0
- package/dist/commands/models/providers.d.ts.map +1 -0
- package/dist/commands/models/providers.js +45 -0
- package/dist/commands/models/providers.js.map +1 -0
- package/dist/commands/models/search.d.ts +10 -0
- package/dist/commands/models/search.d.ts.map +1 -0
- package/dist/commands/models/search.js +56 -0
- package/dist/commands/models/search.js.map +1 -0
- package/dist/commands/models/switch.d.ts +14 -0
- package/dist/commands/models/switch.d.ts.map +1 -0
- package/dist/commands/models/switch.js +67 -0
- package/dist/commands/models/switch.js.map +1 -0
- package/dist/commands/permissions/auto-approve.d.ts +13 -0
- package/dist/commands/permissions/auto-approve.d.ts.map +1 -0
- package/dist/commands/permissions/auto-approve.js +53 -0
- package/dist/commands/permissions/auto-approve.js.map +1 -0
- package/dist/commands/permissions/grant.d.ts +13 -0
- package/dist/commands/permissions/grant.d.ts.map +1 -0
- package/dist/commands/permissions/grant.js +46 -0
- package/dist/commands/permissions/grant.js.map +1 -0
- package/dist/commands/permissions/mode.d.ts +12 -0
- package/dist/commands/permissions/mode.d.ts.map +1 -0
- package/dist/commands/permissions/mode.js +61 -0
- package/dist/commands/permissions/mode.js.map +1 -0
- package/dist/commands/permissions/policies.d.ts +13 -0
- package/dist/commands/permissions/policies.d.ts.map +1 -0
- package/dist/commands/permissions/policies.js +47 -0
- package/dist/commands/permissions/policies.js.map +1 -0
- package/dist/commands/permissions/revoke.d.ts +13 -0
- package/dist/commands/permissions/revoke.d.ts.map +1 -0
- package/dist/commands/permissions/revoke.js +46 -0
- package/dist/commands/permissions/revoke.js.map +1 -0
- package/dist/commands/permissions/set.d.ts +13 -0
- package/dist/commands/permissions/set.d.ts.map +1 -0
- package/dist/commands/permissions/set.js +57 -0
- package/dist/commands/permissions/set.js.map +1 -0
- package/dist/commands/permissions/tools.d.ts +13 -0
- package/dist/commands/permissions/tools.d.ts.map +1 -0
- package/dist/commands/permissions/tools.js +50 -0
- package/dist/commands/permissions/tools.js.map +1 -0
- package/dist/commands/server/start.d.ts +11 -0
- package/dist/commands/server/start.d.ts.map +1 -0
- package/dist/commands/server/start.js +58 -0
- package/dist/commands/server/start.js.map +1 -0
- package/dist/commands/session/checkpoints.d.ts +6 -0
- package/dist/commands/session/checkpoints.d.ts.map +1 -0
- package/dist/commands/session/checkpoints.js +41 -0
- package/dist/commands/session/checkpoints.js.map +1 -0
- package/dist/commands/session/compact.d.ts +13 -0
- package/dist/commands/session/compact.d.ts.map +1 -0
- package/dist/commands/session/compact.js +56 -0
- package/dist/commands/session/compact.js.map +1 -0
- package/dist/commands/session/export.d.ts +6 -0
- package/dist/commands/session/export.d.ts.map +1 -0
- package/dist/commands/session/export.js +31 -0
- package/dist/commands/session/export.js.map +1 -0
- package/dist/commands/session/list.d.ts +7 -0
- package/dist/commands/session/list.d.ts.map +1 -0
- package/dist/commands/session/list.js +63 -0
- package/dist/commands/session/list.js.map +1 -0
- package/dist/commands/session/new.d.ts +8 -0
- package/dist/commands/session/new.d.ts.map +1 -0
- package/dist/commands/session/new.js +23 -0
- package/dist/commands/session/new.js.map +1 -0
- package/dist/commands/session/resume.d.ts +6 -0
- package/dist/commands/session/resume.d.ts.map +1 -0
- package/dist/commands/session/resume.js +32 -0
- package/dist/commands/session/resume.js.map +1 -0
- package/dist/commands/session/search.d.ts +10 -0
- package/dist/commands/session/search.d.ts.map +1 -0
- package/dist/commands/session/search.js +65 -0
- package/dist/commands/session/search.js.map +1 -0
- package/dist/commands/session/stats.d.ts +6 -0
- package/dist/commands/session/stats.d.ts.map +1 -0
- package/dist/commands/session/stats.js +58 -0
- package/dist/commands/session/stats.js.map +1 -0
- package/dist/commands/session/view.d.ts +6 -0
- package/dist/commands/session/view.d.ts.map +1 -0
- package/dist/commands/session/view.js +65 -0
- package/dist/commands/session/view.js.map +1 -0
- package/dist/commands/slash/CommandPalette.d.ts +60 -0
- package/dist/commands/slash/CommandPalette.d.ts.map +1 -0
- package/dist/commands/slash/CommandPalette.js +351 -0
- package/dist/commands/slash/CommandPalette.js.map +1 -0
- package/dist/commands/slash/SlashCommandParser.d.ts +11 -0
- package/dist/commands/slash/SlashCommandParser.d.ts.map +1 -0
- package/dist/commands/slash/SlashCommandParser.js +11 -0
- package/dist/commands/slash/SlashCommandParser.js.map +1 -0
- package/dist/commands/slash/SlashCommandRegistry.d.ts +11 -0
- package/dist/commands/slash/SlashCommandRegistry.d.ts.map +1 -0
- package/dist/commands/slash/SlashCommandRegistry.js +11 -0
- package/dist/commands/slash/SlashCommandRegistry.js.map +1 -0
- package/dist/commands/slash/index.d.ts +11 -0
- package/dist/commands/slash/index.d.ts.map +1 -0
- package/dist/commands/slash/index.js +13 -0
- package/dist/commands/slash/index.js.map +1 -0
- package/dist/commands/system-messages/list.d.ts +13 -0
- package/dist/commands/system-messages/list.d.ts.map +1 -0
- package/dist/commands/system-messages/list.js +54 -0
- package/dist/commands/system-messages/list.js.map +1 -0
- package/dist/commands/system-messages/reload.d.ts +13 -0
- package/dist/commands/system-messages/reload.d.ts.map +1 -0
- package/dist/commands/system-messages/reload.js +36 -0
- package/dist/commands/system-messages/reload.js.map +1 -0
- package/dist/commands/system-messages/view.d.ts +13 -0
- package/dist/commands/system-messages/view.d.ts.map +1 -0
- package/dist/commands/system-messages/view.js +52 -0
- package/dist/commands/system-messages/view.js.map +1 -0
- package/dist/commands/tmux/list.d.ts +13 -0
- package/dist/commands/tmux/list.d.ts.map +1 -0
- package/dist/commands/tmux/list.js +68 -0
- package/dist/commands/tmux/list.js.map +1 -0
- package/dist/commands/tools/info.d.ts +13 -0
- package/dist/commands/tools/info.d.ts.map +1 -0
- package/dist/commands/tools/info.js +82 -0
- package/dist/commands/tools/info.js.map +1 -0
- package/dist/commands/tools/list.d.ts +14 -0
- package/dist/commands/tools/list.d.ts.map +1 -0
- package/dist/commands/tools/list.js +67 -0
- package/dist/commands/tools/list.js.map +1 -0
- package/dist/config/ConfigManager.d.ts +40 -0
- package/dist/config/ConfigManager.d.ts.map +1 -0
- package/dist/config/ConfigManager.js +162 -0
- package/dist/config/ConfigManager.js.map +1 -0
- package/dist/config/extension.d.ts +12 -0
- package/dist/config/extension.d.ts.map +1 -0
- package/dist/config/extension.js +5 -0
- package/dist/config/extension.js.map +1 -0
- package/dist/config/settings.d.ts +42 -0
- package/dist/config/settings.d.ts.map +1 -0
- package/dist/config/settings.js +32 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +883 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestrator/OrchestratorClient.d.ts +385 -0
- package/dist/orchestrator/OrchestratorClient.d.ts.map +1 -0
- package/dist/orchestrator/OrchestratorClient.js +1195 -0
- package/dist/orchestrator/OrchestratorClient.js.map +1 -0
- package/dist/themes/DefaultTheme.d.ts +9 -0
- package/dist/themes/DefaultTheme.d.ts.map +1 -0
- package/dist/themes/DefaultTheme.js +29 -0
- package/dist/themes/DefaultTheme.js.map +1 -0
- package/dist/themes/MinimalTheme.d.ts +9 -0
- package/dist/themes/MinimalTheme.d.ts.map +1 -0
- package/dist/themes/MinimalTheme.js +29 -0
- package/dist/themes/MinimalTheme.js.map +1 -0
- package/dist/themes/Theme.interface.d.ts +36 -0
- package/dist/themes/Theme.interface.d.ts.map +1 -0
- package/dist/themes/Theme.interface.js +5 -0
- package/dist/themes/Theme.interface.js.map +1 -0
- package/dist/themes/ThemeManager.d.ts +63 -0
- package/dist/themes/ThemeManager.d.ts.map +1 -0
- package/dist/themes/ThemeManager.js +257 -0
- package/dist/themes/ThemeManager.js.map +1 -0
- package/dist/themes/colors.d.ts +108 -0
- package/dist/themes/colors.d.ts.map +1 -0
- package/dist/themes/colors.js +284 -0
- package/dist/themes/colors.js.map +1 -0
- package/dist/themes/createTheme.d.ts +40 -0
- package/dist/themes/createTheme.d.ts.map +1 -0
- package/dist/themes/createTheme.js +114 -0
- package/dist/themes/createTheme.js.map +1 -0
- package/dist/themes/themeDefinitions.d.ts +27 -0
- package/dist/themes/themeDefinitions.d.ts.map +1 -0
- package/dist/themes/themeDefinitions.js +244 -0
- package/dist/themes/themeDefinitions.js.map +1 -0
- package/dist/utils/CodeDiffRenderer.d.ts +124 -0
- package/dist/utils/CodeDiffRenderer.d.ts.map +1 -0
- package/dist/utils/CodeDiffRenderer.js +257 -0
- package/dist/utils/CodeDiffRenderer.js.map +1 -0
- package/dist/utils/MarkdownRenderer.d.ts +74 -0
- package/dist/utils/MarkdownRenderer.d.ts.map +1 -0
- package/dist/utils/MarkdownRenderer.js +260 -0
- package/dist/utils/MarkdownRenderer.js.map +1 -0
- package/dist/utils/MessageRenderer.d.ts +200 -0
- package/dist/utils/MessageRenderer.d.ts.map +1 -0
- package/dist/utils/MessageRenderer.js +283 -0
- package/dist/utils/MessageRenderer.js.map +1 -0
- package/dist/utils/ToolFormatter.d.ts +103 -0
- package/dist/utils/ToolFormatter.d.ts.map +1 -0
- package/dist/utils/ToolFormatter.js +357 -0
- package/dist/utils/ToolFormatter.js.map +1 -0
- package/dist/utils/boxDrawing.d.ts +23 -0
- package/dist/utils/boxDrawing.d.ts.map +1 -0
- package/dist/utils/boxDrawing.js +78 -0
- package/dist/utils/boxDrawing.js.map +1 -0
- package/dist/utils/checks.d.ts +9 -0
- package/dist/utils/checks.d.ts.map +1 -0
- package/dist/utils/checks.js +11 -0
- package/dist/utils/checks.js.map +1 -0
- package/dist/utils/events.d.ts +24 -0
- package/dist/utils/events.d.ts.map +1 -0
- package/dist/utils/events.js +17 -0
- package/dist/utils/events.js.map +1 -0
- package/dist/utils/formatters.d.ts +255 -0
- package/dist/utils/formatters.d.ts.map +1 -0
- package/dist/utils/formatters.js +361 -0
- package/dist/utils/formatters.js.map +1 -0
- package/dist/utils/math.d.ts +11 -0
- package/dist/utils/math.d.ts.map +1 -0
- package/dist/utils/math.js +13 -0
- package/dist/utils/math.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1,1195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified Orchestrator Client
|
|
3
|
+
*
|
|
4
|
+
* Supports two modes:
|
|
5
|
+
* 1. Direct Mode (DEFAULT): Imports core library directly for maximum performance
|
|
6
|
+
* 2. Server Mode (--server): Uses HTTP client to connect to remote server
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* const client = new OrchestratorClient({ mode: 'direct' });
|
|
10
|
+
* const client = new OrchestratorClient({ mode: 'server', serverUrl: 'http://localhost:4000' });
|
|
11
|
+
*/
|
|
12
|
+
import { existsSync, readFileSync, realpathSync } from 'fs';
|
|
13
|
+
import { join, dirname } from 'path';
|
|
14
|
+
import { fileURLToPath } from 'url';
|
|
15
|
+
// Get installation root from this file's location
|
|
16
|
+
// Use realpathSync to resolve symlinks (important for npm link)
|
|
17
|
+
// Compiled file is at: packages/cli/dist/orchestrator/OrchestratorClient.js
|
|
18
|
+
// Installation root is 4 levels up: orchestrator -> dist -> cli -> packages -> root
|
|
19
|
+
const __filename = realpathSync(fileURLToPath(import.meta.url));
|
|
20
|
+
const __dirname = dirname(__filename);
|
|
21
|
+
const CLI_INSTALLATION_ROOT = join(__dirname, '..', '..', '..', '..');
|
|
22
|
+
export class OrchestratorClient {
|
|
23
|
+
mode;
|
|
24
|
+
orchestrator;
|
|
25
|
+
serverUrl;
|
|
26
|
+
options;
|
|
27
|
+
constructor(options = {}) {
|
|
28
|
+
this.mode = options.mode || 'direct';
|
|
29
|
+
this.serverUrl = options.serverUrl;
|
|
30
|
+
this.options = options;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Set input handler callbacks for pausing/resuming custom input during approval dialogs.
|
|
34
|
+
* Call this before initialize() if you need to set up callbacks that depend on other
|
|
35
|
+
* objects created after the client (e.g., persistentInput).
|
|
36
|
+
*/
|
|
37
|
+
setInputHandlerCallbacks(callbacks) {
|
|
38
|
+
this.options.inputHandlerCallbacks = callbacks;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Set preview renderer for showing tool-specific previews before approval prompts.
|
|
42
|
+
* Call this before initialize() to configure diff previews for Edit tools, etc.
|
|
43
|
+
*/
|
|
44
|
+
setPreviewRenderer(renderer) {
|
|
45
|
+
this.options.previewRenderer = renderer;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Initialize the client
|
|
49
|
+
*/
|
|
50
|
+
async initialize() {
|
|
51
|
+
if (this.mode === 'direct') {
|
|
52
|
+
await this.initializeDirect();
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
await this.initializeServer();
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Release resources held by the orchestrator in direct mode (MCP sockets,
|
|
60
|
+
* file watchers). Without this, MCP TCP handles keep the event loop alive
|
|
61
|
+
* and short-lived commands (tools/models list) never exit. Safe to call
|
|
62
|
+
* multiple times and in server mode (no-op).
|
|
63
|
+
*/
|
|
64
|
+
async disconnect() {
|
|
65
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
66
|
+
try {
|
|
67
|
+
await this.orchestrator.cleanup();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// best-effort teardown — never let cleanup failure mask the result
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Resume an existing session
|
|
76
|
+
*/
|
|
77
|
+
async resumeSession(sessionId) {
|
|
78
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
79
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
80
|
+
await this.orchestrator.resumeSession(sessionId, projectPath);
|
|
81
|
+
if (this.options.debug) {
|
|
82
|
+
console.log(' Session resumed');
|
|
83
|
+
console.log(` Session ID: ${sessionId}`);
|
|
84
|
+
console.log(` Messages: ${this.orchestrator.getMessageHistory().length}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else if (this.mode === 'server') {
|
|
88
|
+
throw new Error('Session resume not yet supported in server mode');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Find Nexus Cortex installation root (for locating .cortex/ config, not for tool cwd)
|
|
93
|
+
*/
|
|
94
|
+
static findInstallRoot() {
|
|
95
|
+
const cortexRoot = (process.env.CORTEX_ROOT);
|
|
96
|
+
if (cortexRoot && existsSync(cortexRoot)) {
|
|
97
|
+
return cortexRoot;
|
|
98
|
+
}
|
|
99
|
+
if (existsSync(join(CLI_INSTALLATION_ROOT, 'package.json'))) {
|
|
100
|
+
try {
|
|
101
|
+
const packageJson = JSON.parse(readFileSync(join(CLI_INSTALLATION_ROOT, 'package.json'), 'utf-8'));
|
|
102
|
+
if (packageJson.name === 'nexus-cortex-monorepo') {
|
|
103
|
+
return CLI_INSTALLATION_ROOT;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Invalid package.json, continue
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return CLI_INSTALLATION_ROOT;
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* @deprecated Use findInstallRoot() for config, process.cwd() for tool cwd
|
|
114
|
+
*/
|
|
115
|
+
static findProjectRoot(_startPath) {
|
|
116
|
+
return OrchestratorClient.findInstallRoot();
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolve the project root + profile name used for file-backed permission
|
|
120
|
+
* edits. Profile honors PERMISSION_PROFILE (dev|test|prod), default 'dev'.
|
|
121
|
+
*/
|
|
122
|
+
static resolvePermissionTarget() {
|
|
123
|
+
const raw = (process.env.PERMISSION_PROFILE || 'dev').toLowerCase();
|
|
124
|
+
const profile = (['dev', 'test', 'prod'].includes(raw) ? raw : 'dev');
|
|
125
|
+
return { root: OrchestratorClient.findInstallRoot(), profile };
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Get the resolved project path — this is the working directory for tool execution.
|
|
129
|
+
* Always uses the user's cwd unless explicitly overridden via constructor option.
|
|
130
|
+
*/
|
|
131
|
+
getProjectPath() {
|
|
132
|
+
return this.options.projectPath || process.cwd();
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Initialize direct mode (import core library)
|
|
136
|
+
*/
|
|
137
|
+
async initializeDirect() {
|
|
138
|
+
const { createOrchestrator } = await import('@nexus-cortex/core');
|
|
139
|
+
const defaultModelId = this.options.defaultModelId ||
|
|
140
|
+
process.env.DEFAULT_MODEL_ID ||
|
|
141
|
+
'grok-4-fast';
|
|
142
|
+
const installRoot = OrchestratorClient.findInstallRoot();
|
|
143
|
+
const workingDir = this.options.projectPath || process.cwd();
|
|
144
|
+
this.orchestrator = await createOrchestrator({
|
|
145
|
+
defaultModelId,
|
|
146
|
+
projectPath: installRoot,
|
|
147
|
+
workingDirectory: workingDir,
|
|
148
|
+
enableTimeline: true,
|
|
149
|
+
debug: this.options.debug || false,
|
|
150
|
+
// Pass sub-agent event callback for real-time UI updates
|
|
151
|
+
onSubAgentEvent: this.options.onSubAgentEvent
|
|
152
|
+
}, {
|
|
153
|
+
permissionMode: 'interactive',
|
|
154
|
+
// Pass input handler callbacks for pausing/resuming during approval dialogs
|
|
155
|
+
inputHandlerCallbacks: this.options.inputHandlerCallbacks,
|
|
156
|
+
// Pass preview renderer for showing diffs before approval prompts
|
|
157
|
+
previewRenderer: this.options.previewRenderer
|
|
158
|
+
});
|
|
159
|
+
await this.orchestrator.createSession(installRoot, defaultModelId);
|
|
160
|
+
if (this.options.debug) {
|
|
161
|
+
console.log(' Direct mode initialized');
|
|
162
|
+
console.log(` Model: ${defaultModelId}`);
|
|
163
|
+
console.log(` Session: ${this.orchestrator.getSessionId()}`);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Initialize server mode (check server health)
|
|
168
|
+
*/
|
|
169
|
+
async initializeServer() {
|
|
170
|
+
if (!this.serverUrl) {
|
|
171
|
+
throw new Error('Server URL required for server mode');
|
|
172
|
+
}
|
|
173
|
+
try {
|
|
174
|
+
const response = await fetch(`${this.serverUrl}/health`);
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
throw new Error(`Server health check failed: ${response.status}`);
|
|
177
|
+
}
|
|
178
|
+
const health = await response.json();
|
|
179
|
+
if (this.options.debug) {
|
|
180
|
+
console.log(' Server mode initialized');
|
|
181
|
+
console.log(` URL: ${this.serverUrl}`);
|
|
182
|
+
console.log(` Status: ${health.status}`);
|
|
183
|
+
}
|
|
184
|
+
// Create a new session on the server
|
|
185
|
+
await this.createNewSession();
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
throw new Error(`Failed to connect to server: ${error.message}`);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Send a message
|
|
193
|
+
*/
|
|
194
|
+
async sendMessage(content, options = {}) {
|
|
195
|
+
if (this.mode === 'direct') {
|
|
196
|
+
return await this.sendMessageDirect(content, options);
|
|
197
|
+
}
|
|
198
|
+
else {
|
|
199
|
+
return await this.sendMessageServer(content, options);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Send message in direct mode
|
|
204
|
+
*/
|
|
205
|
+
async sendMessageDirect(content, options) {
|
|
206
|
+
if (!this.orchestrator) {
|
|
207
|
+
throw new Error('Orchestrator not initialized');
|
|
208
|
+
}
|
|
209
|
+
// Map CLI options to core orchestrator options
|
|
210
|
+
// IMPORTANT: Only include tools if explicitly provided, otherwise let orchestrator use its defaults
|
|
211
|
+
const sendOptions = {};
|
|
212
|
+
// Only pass tools if explicitly provided (non-undefined)
|
|
213
|
+
if (options.tools !== undefined) {
|
|
214
|
+
sendOptions.tools = options.tools;
|
|
215
|
+
}
|
|
216
|
+
if (options.model) {
|
|
217
|
+
sendOptions.modelId = options.model;
|
|
218
|
+
}
|
|
219
|
+
if (options.system) {
|
|
220
|
+
sendOptions.systemMessages = [options.system];
|
|
221
|
+
}
|
|
222
|
+
if (options.max_tokens !== undefined) {
|
|
223
|
+
sendOptions.maxTokens = options.max_tokens;
|
|
224
|
+
}
|
|
225
|
+
if (options.temperature !== undefined) {
|
|
226
|
+
sendOptions.temperature = options.temperature;
|
|
227
|
+
}
|
|
228
|
+
if (options.top_p !== undefined) {
|
|
229
|
+
sendOptions.topP = options.top_p;
|
|
230
|
+
}
|
|
231
|
+
// Send message through orchestrator (pass content directly, not messages array)
|
|
232
|
+
// The orchestrator maintains its own internal message history
|
|
233
|
+
const result = await this.orchestrator.sendMessage(content, sendOptions);
|
|
234
|
+
return result;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Send message in server mode
|
|
238
|
+
*/
|
|
239
|
+
async sendMessageServer(content, options) {
|
|
240
|
+
const response = await fetch(`${this.serverUrl}/v1/messages`, {
|
|
241
|
+
method: 'POST',
|
|
242
|
+
headers: { 'Content-Type': 'application/json' },
|
|
243
|
+
body: JSON.stringify({
|
|
244
|
+
content,
|
|
245
|
+
model: this.options.defaultModelId,
|
|
246
|
+
...options
|
|
247
|
+
})
|
|
248
|
+
});
|
|
249
|
+
if (!response.ok) {
|
|
250
|
+
const error = await response.json();
|
|
251
|
+
throw new Error(error.error?.message || 'Request failed');
|
|
252
|
+
}
|
|
253
|
+
return await response.json();
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Stream a message with real-time response chunks
|
|
257
|
+
*
|
|
258
|
+
* Returns async generator that yields StreamChunk objects:
|
|
259
|
+
* - text_delta: Text content
|
|
260
|
+
* - content_block_delta: Thinking/reasoning content (check chunk.data.reasoning === true)
|
|
261
|
+
* - tool_use_complete: Complete tool ready for execution
|
|
262
|
+
* - message_start, message_stop, etc.
|
|
263
|
+
*/
|
|
264
|
+
async *streamMessage(content, options = {}) {
|
|
265
|
+
if (this.mode === 'direct') {
|
|
266
|
+
yield* this.streamMessageDirect(content, options);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
// Server mode streaming not yet implemented
|
|
270
|
+
throw new Error('Streaming not yet supported in server mode. Use direct mode (default) for streaming.');
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Stream message in direct mode
|
|
275
|
+
*/
|
|
276
|
+
async *streamMessageDirect(content, options) {
|
|
277
|
+
if (!this.orchestrator) {
|
|
278
|
+
throw new Error('Orchestrator not initialized');
|
|
279
|
+
}
|
|
280
|
+
// Map CLI options to core orchestrator options
|
|
281
|
+
// IMPORTANT: Only include tools if explicitly provided, otherwise let orchestrator use its defaults
|
|
282
|
+
const sendOptions = {};
|
|
283
|
+
// Only pass tools if explicitly provided (non-undefined)
|
|
284
|
+
if (options.tools !== undefined) {
|
|
285
|
+
sendOptions.tools = options.tools;
|
|
286
|
+
}
|
|
287
|
+
if (options.model) {
|
|
288
|
+
sendOptions.modelId = options.model;
|
|
289
|
+
}
|
|
290
|
+
if (options.system) {
|
|
291
|
+
sendOptions.systemMessages = [options.system];
|
|
292
|
+
}
|
|
293
|
+
if (options.max_tokens !== undefined) {
|
|
294
|
+
sendOptions.maxTokens = options.max_tokens;
|
|
295
|
+
}
|
|
296
|
+
if (options.temperature !== undefined) {
|
|
297
|
+
sendOptions.temperature = options.temperature;
|
|
298
|
+
}
|
|
299
|
+
if (options.top_p !== undefined) {
|
|
300
|
+
sendOptions.topP = options.top_p;
|
|
301
|
+
}
|
|
302
|
+
// Pass reasoning effort for OpenAI GPT-5 models
|
|
303
|
+
if (options.reasoningEffort !== undefined) {
|
|
304
|
+
sendOptions.parameters = sendOptions.parameters || {};
|
|
305
|
+
sendOptions.parameters.reasoningEffort = options.reasoningEffort;
|
|
306
|
+
}
|
|
307
|
+
// Pass abort signal for ESC key cancellation
|
|
308
|
+
if (options.abortSignal) {
|
|
309
|
+
sendOptions.abortSignal = options.abortSignal;
|
|
310
|
+
}
|
|
311
|
+
// Track whether stream completed normally (vs interrupted by ESC)
|
|
312
|
+
let streamCompleted = false;
|
|
313
|
+
let stream = null;
|
|
314
|
+
try {
|
|
315
|
+
// Stream message through orchestrator
|
|
316
|
+
stream = this.orchestrator.streamMessage(content, sendOptions);
|
|
317
|
+
// Yield all chunks from the orchestrator
|
|
318
|
+
for await (const chunk of stream) {
|
|
319
|
+
yield chunk;
|
|
320
|
+
}
|
|
321
|
+
// Stream completed normally
|
|
322
|
+
streamCompleted = true;
|
|
323
|
+
}
|
|
324
|
+
catch (error) {
|
|
325
|
+
// If abort signal was triggered, exit cleanly - this is expected during ESC
|
|
326
|
+
if (options.abortSignal?.aborted) {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
// Re-throw other errors with more context for debugging
|
|
330
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
331
|
+
const enhancedError = new Error(`Stream error: ${errorMessage}`);
|
|
332
|
+
enhancedError.originalError = error;
|
|
333
|
+
throw enhancedError;
|
|
334
|
+
}
|
|
335
|
+
finally {
|
|
336
|
+
// If stream was interrupted (ESC pressed), try to clean up gracefully
|
|
337
|
+
if (!streamCompleted && stream) {
|
|
338
|
+
try {
|
|
339
|
+
// Try to close the stream properly
|
|
340
|
+
await stream.return(undefined);
|
|
341
|
+
}
|
|
342
|
+
catch {
|
|
343
|
+
// Ignore cleanup errors - stream was already interrupted
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
/**
|
|
349
|
+
* Create a new session (server mode only)
|
|
350
|
+
*/
|
|
351
|
+
async createNewSession() {
|
|
352
|
+
if (this.mode !== 'server') {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const response = await fetch(`${this.serverUrl}/sessions/new`, {
|
|
356
|
+
method: 'POST',
|
|
357
|
+
headers: { 'Content-Type': 'application/json' },
|
|
358
|
+
body: JSON.stringify({
|
|
359
|
+
modelId: this.options.defaultModelId,
|
|
360
|
+
projectPath: this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd())
|
|
361
|
+
})
|
|
362
|
+
});
|
|
363
|
+
if (!response.ok) {
|
|
364
|
+
throw new Error('Failed to create session');
|
|
365
|
+
}
|
|
366
|
+
const result = await response.json();
|
|
367
|
+
if (this.options.debug) {
|
|
368
|
+
console.log(` Session: ${result.sessionId}`);
|
|
369
|
+
console.log(` Model: ${result.model.name}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Get current model
|
|
374
|
+
*/
|
|
375
|
+
getCurrentModel() {
|
|
376
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
377
|
+
return this.orchestrator.getCurrentModel();
|
|
378
|
+
}
|
|
379
|
+
return null;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* Switch model
|
|
383
|
+
*/
|
|
384
|
+
async switchModel(modelId, reason) {
|
|
385
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
386
|
+
await this.orchestrator.switchModel(modelId, { reason });
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
const response = await fetch(`${this.serverUrl}/sessions/current/model`, {
|
|
390
|
+
method: 'POST',
|
|
391
|
+
headers: { 'Content-Type': 'application/json' },
|
|
392
|
+
body: JSON.stringify({ modelId, reason })
|
|
393
|
+
});
|
|
394
|
+
if (!response.ok) {
|
|
395
|
+
throw new Error('Failed to switch model');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Get cache metrics
|
|
401
|
+
*/
|
|
402
|
+
async getCacheMetrics() {
|
|
403
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
404
|
+
const metrics = this.orchestrator.getCacheMetrics();
|
|
405
|
+
const report = this.orchestrator.getCacheReport();
|
|
406
|
+
const sessionId = this.orchestrator.getSessionId();
|
|
407
|
+
return {
|
|
408
|
+
sessionId: sessionId || 'unknown',
|
|
409
|
+
metrics,
|
|
410
|
+
report,
|
|
411
|
+
timestamp: new Date().toISOString()
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
else {
|
|
415
|
+
// In server mode, get current session ID first
|
|
416
|
+
const sessionId = await this.getSessionId();
|
|
417
|
+
if (!sessionId) {
|
|
418
|
+
throw new Error('No active session');
|
|
419
|
+
}
|
|
420
|
+
const response = await fetch(`${this.serverUrl}/sessions/${sessionId}/cache/metrics`);
|
|
421
|
+
if (!response.ok) {
|
|
422
|
+
throw new Error('Failed to fetch cache metrics');
|
|
423
|
+
}
|
|
424
|
+
return await response.json();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Get message history
|
|
429
|
+
*/
|
|
430
|
+
getMessageHistory() {
|
|
431
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
432
|
+
return this.orchestrator.getMessageHistory();
|
|
433
|
+
}
|
|
434
|
+
return [];
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Get session ID
|
|
438
|
+
*/
|
|
439
|
+
getSessionId() {
|
|
440
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
441
|
+
return this.orchestrator.getSessionId();
|
|
442
|
+
}
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Get approval mode
|
|
447
|
+
*/
|
|
448
|
+
async getApprovalMode() {
|
|
449
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
450
|
+
// Live session — read the running orchestrator's runtime mode.
|
|
451
|
+
return this.orchestrator.getApprovalMode();
|
|
452
|
+
}
|
|
453
|
+
if (this.mode === 'direct') {
|
|
454
|
+
// Headless — read the active profile's approvalHandler from disk.
|
|
455
|
+
const { root, profile } = OrchestratorClient.resolvePermissionTarget();
|
|
456
|
+
const { getApprovalHandlerFromProfile, resolvePermissionWriteTarget } = await import('@nexus-cortex/core');
|
|
457
|
+
const handler = getApprovalHandlerFromProfile(root, profile);
|
|
458
|
+
return {
|
|
459
|
+
autoApproveActions: handler === 'auto-approve',
|
|
460
|
+
yoloMode: process.env.YOLO === 'true',
|
|
461
|
+
context: `profile:${profile} (${resolvePermissionWriteTarget(root, profile)})`,
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
const response = await fetch(`${this.serverUrl}/approval/mode`);
|
|
465
|
+
if (!response.ok) {
|
|
466
|
+
throw new Error('Failed to get approval mode');
|
|
467
|
+
}
|
|
468
|
+
return await response.json();
|
|
469
|
+
}
|
|
470
|
+
/**
|
|
471
|
+
* Set approval mode
|
|
472
|
+
*/
|
|
473
|
+
async setApprovalMode(autoApprove) {
|
|
474
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
475
|
+
// Live session — toggle the running orchestrator's runtime mode.
|
|
476
|
+
this.orchestrator.setApprovalMode({ autoApproveActions: autoApprove });
|
|
477
|
+
return {
|
|
478
|
+
success: true,
|
|
479
|
+
message: `Auto-approve ${autoApprove ? 'enabled' : 'disabled'}`
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
if (this.mode === 'direct') {
|
|
483
|
+
// Headless — persist to the active profile's approvalHandler.
|
|
484
|
+
const { root, profile } = OrchestratorClient.resolvePermissionTarget();
|
|
485
|
+
const { setApprovalHandlerInProfile } = await import('@nexus-cortex/core');
|
|
486
|
+
const handler = autoApprove ? 'auto-approve' : 'cli';
|
|
487
|
+
const res = setApprovalHandlerInProfile(root, profile, handler);
|
|
488
|
+
return {
|
|
489
|
+
success: true,
|
|
490
|
+
message: `Profile '${profile}' approvalHandler -> ${handler}`,
|
|
491
|
+
path: res.path,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
const response = await fetch(`${this.serverUrl}/approval/mode`, {
|
|
495
|
+
method: 'POST',
|
|
496
|
+
headers: { 'Content-Type': 'application/json' },
|
|
497
|
+
body: JSON.stringify({ autoApproveActions: autoApprove })
|
|
498
|
+
});
|
|
499
|
+
if (!response.ok) {
|
|
500
|
+
throw new Error('Failed to set approval mode');
|
|
501
|
+
}
|
|
502
|
+
return await response.json();
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Enable YOLO mode - auto-approve ALL operations (white/gray/blacklist)
|
|
506
|
+
*/
|
|
507
|
+
async enableYoloMode() {
|
|
508
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
509
|
+
await this.orchestrator.enableYoloMode();
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
const response = await fetch(`${this.serverUrl}/approval/yolo/enable`, {
|
|
513
|
+
method: 'POST',
|
|
514
|
+
headers: { 'Content-Type': 'application/json' }
|
|
515
|
+
});
|
|
516
|
+
if (!response.ok) {
|
|
517
|
+
throw new Error('Failed to enable YOLO mode');
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
/**
|
|
522
|
+
* Disable YOLO mode
|
|
523
|
+
*/
|
|
524
|
+
async disableYoloMode() {
|
|
525
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
526
|
+
await this.orchestrator.disableYoloMode();
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
const response = await fetch(`${this.serverUrl}/approval/yolo/disable`, {
|
|
530
|
+
method: 'POST',
|
|
531
|
+
headers: { 'Content-Type': 'application/json' }
|
|
532
|
+
});
|
|
533
|
+
if (!response.ok) {
|
|
534
|
+
throw new Error('Failed to disable YOLO mode');
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
/**
|
|
539
|
+
* Check if YOLO mode is active
|
|
540
|
+
*/
|
|
541
|
+
isYoloModeActive() {
|
|
542
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
543
|
+
return this.orchestrator.isYoloModeActive();
|
|
544
|
+
}
|
|
545
|
+
return false;
|
|
546
|
+
}
|
|
547
|
+
updateRuntimeConfig(updates) {
|
|
548
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
549
|
+
this.orchestrator.updateRuntimeConfig(updates);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
setDebug(enabled) {
|
|
553
|
+
this.updateRuntimeConfig({ debug: enabled });
|
|
554
|
+
}
|
|
555
|
+
isDebugActive() {
|
|
556
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
557
|
+
return this.orchestrator.config?.debug === true;
|
|
558
|
+
}
|
|
559
|
+
return process.env.DEBUG === 'true';
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Set a custom approval handler for tool permissions
|
|
563
|
+
*
|
|
564
|
+
* This allows UI frameworks (like React/Ink) to provide their own
|
|
565
|
+
* approval dialog implementation instead of using the default CLI handler.
|
|
566
|
+
*
|
|
567
|
+
* @param handler - Custom ApprovalHandler implementation with requestApproval method
|
|
568
|
+
*/
|
|
569
|
+
setApprovalHandler(handler) {
|
|
570
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
571
|
+
this.orchestrator.setApprovalHandler(handler);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
/**
|
|
575
|
+
* Set sub-agent event callback for real-time UI updates.
|
|
576
|
+
* Call this to display sub-agent progress in the UI.
|
|
577
|
+
*
|
|
578
|
+
* @param callback - Function to receive sub-agent events
|
|
579
|
+
*/
|
|
580
|
+
setSubAgentEventCallback(callback) {
|
|
581
|
+
this.options.onSubAgentEvent = callback;
|
|
582
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
583
|
+
this.orchestrator.setSubAgentEventCallback(callback);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Get all registered permission policies
|
|
588
|
+
*/
|
|
589
|
+
async getPolicies() {
|
|
590
|
+
if (this.mode === 'direct') {
|
|
591
|
+
// Headless: read the active permission profile file directly (the source
|
|
592
|
+
// of truth the orchestrator loads at startup). No orchestrator/MCP needed.
|
|
593
|
+
const { root, profile } = OrchestratorClient.resolvePermissionTarget();
|
|
594
|
+
const { listProfilePolicies } = await import('@nexus-cortex/core');
|
|
595
|
+
return listProfilePolicies(root, profile);
|
|
596
|
+
}
|
|
597
|
+
else {
|
|
598
|
+
const response = await fetch(`${this.serverUrl}/permissions/policies`);
|
|
599
|
+
if (!response.ok) {
|
|
600
|
+
throw new Error('Failed to get policies');
|
|
601
|
+
}
|
|
602
|
+
const data = await response.json();
|
|
603
|
+
return data.policies || [];
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Get audit log for session
|
|
608
|
+
*/
|
|
609
|
+
async getAuditLog(sessionId) {
|
|
610
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
611
|
+
return this.orchestrator.getAuditLog(sessionId);
|
|
612
|
+
}
|
|
613
|
+
else {
|
|
614
|
+
const url = sessionId
|
|
615
|
+
? `${this.serverUrl}/permissions/audit/${sessionId}`
|
|
616
|
+
: `${this.serverUrl}/permissions/audit`;
|
|
617
|
+
const response = await fetch(url);
|
|
618
|
+
if (!response.ok) {
|
|
619
|
+
throw new Error('Failed to get audit log');
|
|
620
|
+
}
|
|
621
|
+
const data = await response.json();
|
|
622
|
+
return data.entries || [];
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
/**
|
|
626
|
+
* Get audit statistics
|
|
627
|
+
*/
|
|
628
|
+
async getAuditStatistics() {
|
|
629
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
630
|
+
return await this.orchestrator.getAuditStatistics();
|
|
631
|
+
}
|
|
632
|
+
else {
|
|
633
|
+
const response = await fetch(`${this.serverUrl}/permissions/audit/statistics`);
|
|
634
|
+
if (!response.ok) {
|
|
635
|
+
throw new Error('Failed to get audit statistics');
|
|
636
|
+
}
|
|
637
|
+
return await response.json();
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Get all denied operations
|
|
642
|
+
*/
|
|
643
|
+
async getDeniedOperations() {
|
|
644
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
645
|
+
return await this.orchestrator.getAllDeniedOperations();
|
|
646
|
+
}
|
|
647
|
+
else {
|
|
648
|
+
const response = await fetch(`${this.serverUrl}/permissions/denied`);
|
|
649
|
+
if (!response.ok) {
|
|
650
|
+
throw new Error('Failed to get denied operations');
|
|
651
|
+
}
|
|
652
|
+
const data = await response.json();
|
|
653
|
+
return data.operations || [];
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* Grant permission to a tool (convenience method)
|
|
658
|
+
* Creates a WhitelistPolicy for the specified tool
|
|
659
|
+
*/
|
|
660
|
+
async grantToolPermission(toolName) {
|
|
661
|
+
if (this.mode === 'direct') {
|
|
662
|
+
// Headless: persist to the active permission profile file so the grant
|
|
663
|
+
// survives across invocations (in-memory registerPolicy would evaporate).
|
|
664
|
+
const { root, profile } = OrchestratorClient.resolvePermissionTarget();
|
|
665
|
+
const { grantToolInProfile } = await import('@nexus-cortex/core');
|
|
666
|
+
return grantToolInProfile(root, profile, toolName);
|
|
667
|
+
}
|
|
668
|
+
else {
|
|
669
|
+
const response = await fetch(`${this.serverUrl}/permissions/tool/${toolName}`, {
|
|
670
|
+
method: 'POST',
|
|
671
|
+
headers: { 'Content-Type': 'application/json' },
|
|
672
|
+
body: JSON.stringify({ action: 'grant' })
|
|
673
|
+
});
|
|
674
|
+
if (!response.ok) {
|
|
675
|
+
throw new Error('Failed to grant permission');
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
/**
|
|
680
|
+
* Revoke permission from a tool (convenience method)
|
|
681
|
+
* Creates a BlacklistPolicy for the specified tool
|
|
682
|
+
*/
|
|
683
|
+
async revokeToolPermission(toolName) {
|
|
684
|
+
if (this.mode === 'direct') {
|
|
685
|
+
// Headless: persist to the active permission profile file.
|
|
686
|
+
const { root, profile } = OrchestratorClient.resolvePermissionTarget();
|
|
687
|
+
const { revokeToolInProfile } = await import('@nexus-cortex/core');
|
|
688
|
+
return revokeToolInProfile(root, profile, toolName);
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
const response = await fetch(`${this.serverUrl}/permissions/tool/${toolName}`, {
|
|
692
|
+
method: 'DELETE'
|
|
693
|
+
});
|
|
694
|
+
if (!response.ok) {
|
|
695
|
+
throw new Error('Failed to revoke permission');
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
/**
|
|
700
|
+
* Register a custom permission policy
|
|
701
|
+
*/
|
|
702
|
+
async registerPolicy(policy) {
|
|
703
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
704
|
+
this.orchestrator.registerPolicy(policy);
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
const response = await fetch(`${this.serverUrl}/permissions/policies`, {
|
|
708
|
+
method: 'POST',
|
|
709
|
+
headers: { 'Content-Type': 'application/json' },
|
|
710
|
+
body: JSON.stringify({ policy })
|
|
711
|
+
});
|
|
712
|
+
if (!response.ok) {
|
|
713
|
+
throw new Error('Failed to register policy');
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
/**
|
|
718
|
+
* Unregister a permission policy
|
|
719
|
+
*/
|
|
720
|
+
async unregisterPolicy(policyName) {
|
|
721
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
722
|
+
return this.orchestrator.unregisterPolicy(policyName);
|
|
723
|
+
}
|
|
724
|
+
else {
|
|
725
|
+
const response = await fetch(`${this.serverUrl}/permissions/policies/${policyName}`, {
|
|
726
|
+
method: 'DELETE'
|
|
727
|
+
});
|
|
728
|
+
if (!response.ok) {
|
|
729
|
+
throw new Error('Failed to unregister policy');
|
|
730
|
+
}
|
|
731
|
+
const data = await response.json();
|
|
732
|
+
return data.removed || false;
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
/**
|
|
736
|
+
* Create checkpoint
|
|
737
|
+
*/
|
|
738
|
+
async createCheckpoint(name) {
|
|
739
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
740
|
+
return await this.orchestrator.createCheckpoint({ description: name });
|
|
741
|
+
}
|
|
742
|
+
else {
|
|
743
|
+
const response = await fetch(`${this.serverUrl}/checkpoints`, {
|
|
744
|
+
method: 'POST',
|
|
745
|
+
headers: { 'Content-Type': 'application/json' },
|
|
746
|
+
body: JSON.stringify({ name })
|
|
747
|
+
});
|
|
748
|
+
return await response.json();
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
/**
|
|
752
|
+
* List checkpoints
|
|
753
|
+
*/
|
|
754
|
+
async listCheckpoints() {
|
|
755
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
756
|
+
return this.orchestrator.listCheckpoints();
|
|
757
|
+
}
|
|
758
|
+
else {
|
|
759
|
+
const response = await fetch(`${this.serverUrl}/checkpoints`);
|
|
760
|
+
const result = await response.json();
|
|
761
|
+
return result.checkpoints || [];
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* Get cache report
|
|
766
|
+
*/
|
|
767
|
+
getCacheReport() {
|
|
768
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
769
|
+
return this.orchestrator.getCacheReport();
|
|
770
|
+
}
|
|
771
|
+
return 'Cache report not available in server mode';
|
|
772
|
+
}
|
|
773
|
+
/**
|
|
774
|
+
* Get client mode
|
|
775
|
+
*/
|
|
776
|
+
getMode() {
|
|
777
|
+
return this.mode;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Get server URL (if in server mode)
|
|
781
|
+
*/
|
|
782
|
+
getServerUrl() {
|
|
783
|
+
return this.serverUrl;
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* List all available models
|
|
787
|
+
*
|
|
788
|
+
* Uses core library's listAvailableModels method in direct mode.
|
|
789
|
+
* In server mode, makes HTTP request to server.
|
|
790
|
+
*
|
|
791
|
+
* Transforms ModelConfig format to CLI-expected format
|
|
792
|
+
*/
|
|
793
|
+
async listModels() {
|
|
794
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
795
|
+
// [OK] Use core library method and transform to CLI format
|
|
796
|
+
const models = this.orchestrator.listAvailableModels();
|
|
797
|
+
// Transform ModelConfig to CLI-expected format
|
|
798
|
+
return models.map(model => ({
|
|
799
|
+
id: model.id,
|
|
800
|
+
owned_by: model.provider,
|
|
801
|
+
displayName: model.displayName,
|
|
802
|
+
apiPattern: model.api.pattern,
|
|
803
|
+
contextWindow: model.limits.contextWindow,
|
|
804
|
+
outputTokens: model.limits.outputTokens,
|
|
805
|
+
inputCostPer1M: model.cost?.inputPerMillion || 0,
|
|
806
|
+
outputCostPer1M: model.cost?.outputPerMillion || 0,
|
|
807
|
+
supportsTools: model.tools.supported,
|
|
808
|
+
supportsStreaming: model.streaming.supported,
|
|
809
|
+
reasoning: model.reasoning
|
|
810
|
+
}));
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
// Server mode - HTTP API call
|
|
814
|
+
const response = await fetch(`${this.serverUrl}/models`);
|
|
815
|
+
if (!response.ok) {
|
|
816
|
+
throw new Error('Failed to fetch models');
|
|
817
|
+
}
|
|
818
|
+
const result = await response.json();
|
|
819
|
+
return result.data || [];
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* List MCP servers
|
|
824
|
+
*/
|
|
825
|
+
async listMcpServers() {
|
|
826
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
827
|
+
const mcpEnabled = this.orchestrator.isMcpEnabled();
|
|
828
|
+
if (!mcpEnabled) {
|
|
829
|
+
return { enabled: false, servers: [] };
|
|
830
|
+
}
|
|
831
|
+
const serverInfo = this.orchestrator.getMcpServerInfo();
|
|
832
|
+
return { enabled: true, servers: serverInfo };
|
|
833
|
+
}
|
|
834
|
+
else {
|
|
835
|
+
const response = await fetch(`${this.serverUrl}/mcp/servers`);
|
|
836
|
+
if (!response.ok) {
|
|
837
|
+
throw new Error('Failed to fetch MCP servers');
|
|
838
|
+
}
|
|
839
|
+
return await response.json();
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
/**
|
|
843
|
+
* List all sessions
|
|
844
|
+
*/
|
|
845
|
+
async listSessions() {
|
|
846
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
847
|
+
// In direct mode, we have a single session
|
|
848
|
+
// Get session metadata from the orchestrator
|
|
849
|
+
const sessionId = this.orchestrator.getSessionId();
|
|
850
|
+
const messageHistory = this.orchestrator.getMessageHistory();
|
|
851
|
+
if (!sessionId) {
|
|
852
|
+
return { sessions: [] };
|
|
853
|
+
}
|
|
854
|
+
// Calculate basic session info
|
|
855
|
+
const session = {
|
|
856
|
+
sessionId,
|
|
857
|
+
messageCount: messageHistory.length,
|
|
858
|
+
metadata: {
|
|
859
|
+
startTime: new Date().toISOString(),
|
|
860
|
+
model: this.orchestrator.getCurrentModel().id
|
|
861
|
+
},
|
|
862
|
+
fileSize: 0 // Not applicable in direct mode
|
|
863
|
+
};
|
|
864
|
+
return { sessions: [session] };
|
|
865
|
+
}
|
|
866
|
+
else {
|
|
867
|
+
const response = await fetch(`${this.serverUrl}/sessions`);
|
|
868
|
+
if (!response.ok) {
|
|
869
|
+
throw new Error('Failed to fetch sessions');
|
|
870
|
+
}
|
|
871
|
+
return await response.json();
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
/**
|
|
875
|
+
* List all available tools
|
|
876
|
+
*/
|
|
877
|
+
async listTools(grouped) {
|
|
878
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
879
|
+
// Get tool definitions from orchestrator
|
|
880
|
+
const toolDefs = this.orchestrator.getToolDefinitions();
|
|
881
|
+
if (grouped) {
|
|
882
|
+
// Group tools by category
|
|
883
|
+
const groupedTools = {};
|
|
884
|
+
for (const tool of toolDefs) {
|
|
885
|
+
const category = tool.category || 'general';
|
|
886
|
+
if (!groupedTools[category]) {
|
|
887
|
+
groupedTools[category] = [];
|
|
888
|
+
}
|
|
889
|
+
groupedTools[category].push(tool);
|
|
890
|
+
}
|
|
891
|
+
return {
|
|
892
|
+
totalCount: toolDefs.length,
|
|
893
|
+
grouped: groupedTools
|
|
894
|
+
};
|
|
895
|
+
}
|
|
896
|
+
return {
|
|
897
|
+
totalCount: toolDefs.length,
|
|
898
|
+
tools: toolDefs
|
|
899
|
+
};
|
|
900
|
+
}
|
|
901
|
+
else {
|
|
902
|
+
const queryParams = grouped ? '?grouped=true' : '';
|
|
903
|
+
const response = await fetch(`${this.serverUrl}/tools${queryParams}`);
|
|
904
|
+
if (!response.ok) {
|
|
905
|
+
throw new Error('Failed to fetch tools');
|
|
906
|
+
}
|
|
907
|
+
return await response.json();
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
/**
|
|
911
|
+
* Get detailed information about a specific tool
|
|
912
|
+
*/
|
|
913
|
+
async getToolInfo(toolName) {
|
|
914
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
915
|
+
// Get all tool definitions and find the requested one
|
|
916
|
+
const toolDefs = this.orchestrator.getToolDefinitions();
|
|
917
|
+
const tool = toolDefs.find((t) => t.name === toolName);
|
|
918
|
+
if (!tool) {
|
|
919
|
+
throw new Error(`Tool '${toolName}' not found`);
|
|
920
|
+
}
|
|
921
|
+
return tool;
|
|
922
|
+
}
|
|
923
|
+
else {
|
|
924
|
+
const response = await fetch(`${this.serverUrl}/tools/${toolName}`);
|
|
925
|
+
if (!response.ok) {
|
|
926
|
+
if (response.status === 404) {
|
|
927
|
+
throw new Error(`Tool '${toolName}' not found`);
|
|
928
|
+
}
|
|
929
|
+
throw new Error('Failed to fetch tool info');
|
|
930
|
+
}
|
|
931
|
+
return await response.json();
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Get detailed model information
|
|
936
|
+
*
|
|
937
|
+
* Uses core library's listAvailableModels method in direct mode.
|
|
938
|
+
* In server mode, makes HTTP request to server.
|
|
939
|
+
*/
|
|
940
|
+
async getModelInfo(modelId) {
|
|
941
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
942
|
+
// [OK] Use core library method
|
|
943
|
+
const models = this.orchestrator.listAvailableModels();
|
|
944
|
+
const model = models.find(m => m.id === modelId);
|
|
945
|
+
if (!model) {
|
|
946
|
+
throw new Error(`Model '${modelId}' not found`);
|
|
947
|
+
}
|
|
948
|
+
return model;
|
|
949
|
+
}
|
|
950
|
+
else {
|
|
951
|
+
// Server mode - HTTP API call
|
|
952
|
+
const response = await fetch(`${this.serverUrl}/models/${modelId}`);
|
|
953
|
+
if (!response.ok) {
|
|
954
|
+
if (response.status === 404) {
|
|
955
|
+
throw new Error(`Model '${modelId}' not found`);
|
|
956
|
+
}
|
|
957
|
+
throw new Error('Failed to fetch model info');
|
|
958
|
+
}
|
|
959
|
+
return await response.json();
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
/**
|
|
963
|
+
* Enable an MCP server
|
|
964
|
+
*
|
|
965
|
+
* Uses EnableMcpServer tool executor with managers from orchestrator.
|
|
966
|
+
* In server mode, makes HTTP request to server.
|
|
967
|
+
*/
|
|
968
|
+
async enableMCPServer(serverName) {
|
|
969
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
970
|
+
// Get managers from orchestrator
|
|
971
|
+
const { EnableMcpServer } = await import('@nexus-cortex/core');
|
|
972
|
+
const configManager = this.orchestrator.getMcpConfigManager();
|
|
973
|
+
const registry = this.orchestrator.getMcpServerRegistry();
|
|
974
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
975
|
+
// Call tool executor
|
|
976
|
+
const result = await EnableMcpServer.execute({ server_name: serverName }, registry, configManager, projectPath);
|
|
977
|
+
if (result.status !== 'success' && result.status !== 'already_enabled') {
|
|
978
|
+
throw new Error(result.message);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
else {
|
|
982
|
+
// Server mode - HTTP API call
|
|
983
|
+
const response = await fetch(`${this.serverUrl}/mcp/servers/${serverName}/enable`, {
|
|
984
|
+
method: 'POST'
|
|
985
|
+
});
|
|
986
|
+
if (!response.ok) {
|
|
987
|
+
throw new Error(`Failed to enable MCP server: ${serverName}`);
|
|
988
|
+
}
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
/**
|
|
992
|
+
* Disable an MCP server
|
|
993
|
+
*
|
|
994
|
+
* Uses DisableMcpServer tool executor with managers from orchestrator.
|
|
995
|
+
* In server mode, makes HTTP request to server.
|
|
996
|
+
*/
|
|
997
|
+
async disableMCPServer(serverName) {
|
|
998
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
999
|
+
// Get config manager from orchestrator
|
|
1000
|
+
const { DisableMcpServer } = await import('@nexus-cortex/core');
|
|
1001
|
+
const configManager = this.orchestrator.getMcpConfigManager();
|
|
1002
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
1003
|
+
// Call tool executor (doesn't need registry, only configManager)
|
|
1004
|
+
const result = await DisableMcpServer.execute({ server_name: serverName }, configManager, projectPath);
|
|
1005
|
+
if (result.status !== 'success') {
|
|
1006
|
+
throw new Error(result.message);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
else {
|
|
1010
|
+
// Server mode - HTTP API call
|
|
1011
|
+
const response = await fetch(`${this.serverUrl}/mcp/servers/${serverName}/disable`, {
|
|
1012
|
+
method: 'POST'
|
|
1013
|
+
});
|
|
1014
|
+
if (!response.ok) {
|
|
1015
|
+
throw new Error(`Failed to disable MCP server: ${serverName}`);
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
/**
|
|
1020
|
+
* Get configuration value
|
|
1021
|
+
*
|
|
1022
|
+
* Uses SettingsLoader from core library in direct mode.
|
|
1023
|
+
* In server mode, makes HTTP request to server.
|
|
1024
|
+
*/
|
|
1025
|
+
async getConfig(key) {
|
|
1026
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
1027
|
+
// Use SettingsLoader from core library
|
|
1028
|
+
const { SettingsLoader } = await import('@nexus-cortex/core');
|
|
1029
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
1030
|
+
const loader = new SettingsLoader(projectPath);
|
|
1031
|
+
const value = loader.get(key);
|
|
1032
|
+
if (!value) {
|
|
1033
|
+
throw new Error(`Configuration key '${key}' not found`);
|
|
1034
|
+
}
|
|
1035
|
+
return value;
|
|
1036
|
+
}
|
|
1037
|
+
else {
|
|
1038
|
+
// Server mode - HTTP API call
|
|
1039
|
+
const response = await fetch(`${this.serverUrl}/config/${key}`);
|
|
1040
|
+
if (!response.ok) {
|
|
1041
|
+
if (response.status === 404) {
|
|
1042
|
+
throw new Error(`Configuration key '${key}' not found`);
|
|
1043
|
+
}
|
|
1044
|
+
throw new Error('Failed to get configuration');
|
|
1045
|
+
}
|
|
1046
|
+
const result = await response.json();
|
|
1047
|
+
return result.value;
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Set configuration value
|
|
1052
|
+
*
|
|
1053
|
+
* Uses SettingsWriter from core library in direct mode.
|
|
1054
|
+
* In server mode, makes HTTP request to server.
|
|
1055
|
+
*
|
|
1056
|
+
* Note: Direct mode currently requires restart for changes to take effect.
|
|
1057
|
+
*/
|
|
1058
|
+
async setConfig(key, value) {
|
|
1059
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
1060
|
+
// Use SettingsWriter from core library
|
|
1061
|
+
const { SettingsWriter } = await import('@nexus-cortex/core');
|
|
1062
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
1063
|
+
const writer = new SettingsWriter(projectPath);
|
|
1064
|
+
writer.update({ [key]: value });
|
|
1065
|
+
// Apply to process.env so env-read-per-turn vars take immediate effect
|
|
1066
|
+
process.env[key] = value;
|
|
1067
|
+
}
|
|
1068
|
+
else {
|
|
1069
|
+
// Server mode - HTTP API call
|
|
1070
|
+
const response = await fetch(`${this.serverUrl}/config/${key}`, {
|
|
1071
|
+
method: 'PUT',
|
|
1072
|
+
headers: {
|
|
1073
|
+
'Content-Type': 'application/json'
|
|
1074
|
+
},
|
|
1075
|
+
body: JSON.stringify({ value })
|
|
1076
|
+
});
|
|
1077
|
+
if (!response.ok) {
|
|
1078
|
+
throw new Error('Failed to set configuration');
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
}
|
|
1082
|
+
/**
|
|
1083
|
+
* Get all configuration settings with summary
|
|
1084
|
+
*
|
|
1085
|
+
* Uses SettingsLoader from core library in direct mode.
|
|
1086
|
+
*/
|
|
1087
|
+
async getConfigSummary() {
|
|
1088
|
+
if (this.mode === 'direct' && this.orchestrator) {
|
|
1089
|
+
const { SettingsLoader } = await import('@nexus-cortex/core');
|
|
1090
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
1091
|
+
const loader = new SettingsLoader(projectPath);
|
|
1092
|
+
const summary = loader.getSummary();
|
|
1093
|
+
const allSettings = loader.getEnvironment();
|
|
1094
|
+
// Filter out sensitive API keys for display
|
|
1095
|
+
const safeSettings = {};
|
|
1096
|
+
for (const [key, value] of Object.entries(allSettings)) {
|
|
1097
|
+
if (key.includes('API_KEY')) {
|
|
1098
|
+
safeSettings[key] = value ? '***configured***' : '(not set)';
|
|
1099
|
+
}
|
|
1100
|
+
else {
|
|
1101
|
+
safeSettings[key] = value;
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
return {
|
|
1105
|
+
...summary,
|
|
1106
|
+
allSettings: safeSettings
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
else {
|
|
1110
|
+
const response = await fetch(`${this.serverUrl}/config`);
|
|
1111
|
+
if (!response.ok) {
|
|
1112
|
+
throw new Error('Failed to get configuration');
|
|
1113
|
+
}
|
|
1114
|
+
return await response.json();
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
/**
|
|
1118
|
+
* List available configuration keys
|
|
1119
|
+
*/
|
|
1120
|
+
async listConfigKeys() {
|
|
1121
|
+
if (this.mode === 'direct') {
|
|
1122
|
+
const { SETTINGS_METADATA } = await import('@nexus-cortex/core');
|
|
1123
|
+
return SETTINGS_METADATA.map((s) => s.key);
|
|
1124
|
+
}
|
|
1125
|
+
else {
|
|
1126
|
+
const response = await fetch(`${this.serverUrl}/config/keys`);
|
|
1127
|
+
if (!response.ok) {
|
|
1128
|
+
throw new Error('Failed to list config keys');
|
|
1129
|
+
}
|
|
1130
|
+
const result = await response.json();
|
|
1131
|
+
return result.keys || [];
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
/**
|
|
1135
|
+
* List system messages
|
|
1136
|
+
*
|
|
1137
|
+
* Returns list of system message files in .cortex/system-messages/
|
|
1138
|
+
*/
|
|
1139
|
+
async listSystemMessages() {
|
|
1140
|
+
if (this.mode === 'direct') {
|
|
1141
|
+
const { existsSync, readdirSync } = await import('fs');
|
|
1142
|
+
const { join } = await import('path');
|
|
1143
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
1144
|
+
const messagesDir = join(projectPath, '.cortex', 'system-messages');
|
|
1145
|
+
if (!existsSync(messagesDir)) {
|
|
1146
|
+
return [];
|
|
1147
|
+
}
|
|
1148
|
+
const files = readdirSync(messagesDir)
|
|
1149
|
+
.filter(f => f.endsWith('.md'))
|
|
1150
|
+
.sort();
|
|
1151
|
+
return files.map(filename => {
|
|
1152
|
+
// Extract priority from filename (e.g., "01-base.md" -> 1)
|
|
1153
|
+
const match = filename.match(/^(\d+)-/);
|
|
1154
|
+
const priority = match && match[1] ? parseInt(match[1], 10) : 99;
|
|
1155
|
+
return {
|
|
1156
|
+
filename,
|
|
1157
|
+
priority,
|
|
1158
|
+
path: join(messagesDir, filename)
|
|
1159
|
+
};
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1162
|
+
else {
|
|
1163
|
+
const response = await fetch(`${this.serverUrl}/system-messages`);
|
|
1164
|
+
if (!response.ok) {
|
|
1165
|
+
throw new Error('Failed to list system messages');
|
|
1166
|
+
}
|
|
1167
|
+
const result = await response.json();
|
|
1168
|
+
return result.messages || [];
|
|
1169
|
+
}
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Get system message content
|
|
1173
|
+
*/
|
|
1174
|
+
async getSystemMessageContent(filename) {
|
|
1175
|
+
if (this.mode === 'direct') {
|
|
1176
|
+
const { existsSync, readFileSync } = await import('fs');
|
|
1177
|
+
const { join } = await import('path');
|
|
1178
|
+
const projectPath = this.options.projectPath || OrchestratorClient.findProjectRoot(process.cwd());
|
|
1179
|
+
const messagePath = join(projectPath, '.cortex', 'system-messages', filename);
|
|
1180
|
+
if (!existsSync(messagePath)) {
|
|
1181
|
+
throw new Error(`System message not found: ${filename}`);
|
|
1182
|
+
}
|
|
1183
|
+
return readFileSync(messagePath, 'utf-8');
|
|
1184
|
+
}
|
|
1185
|
+
else {
|
|
1186
|
+
const response = await fetch(`${this.serverUrl}/system-messages/${filename}`);
|
|
1187
|
+
if (!response.ok) {
|
|
1188
|
+
throw new Error(`Failed to get system message: ${filename}`);
|
|
1189
|
+
}
|
|
1190
|
+
const result = await response.json();
|
|
1191
|
+
return result.content;
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1194
|
+
}
|
|
1195
|
+
//# sourceMappingURL=OrchestratorClient.js.map
|