@kolisachint/hoocode-agent 0.4.106 → 0.4.108
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +0 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/extension-mcp-servers.d.ts +1 -1
- package/dist/core/extension-mcp-servers.d.ts.map +1 -1
- package/dist/core/extension-mcp-servers.js +1 -1
- package/dist/core/extension-mcp-servers.js.map +1 -1
- package/dist/core/extensions/plugins/index.d.ts.map +1 -1
- package/dist/core/extensions/plugins/index.js +1 -1
- package/dist/core/extensions/plugins/index.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/mode-prompts.d.ts +1 -1
- package/dist/core/mode-prompts.d.ts.map +1 -1
- package/dist/core/mode-prompts.js +1 -1
- package/dist/core/mode-prompts.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +1 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +2 -97
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -65
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +2 -3
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +2 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/{browser-continue.d.ts → browser/browser-continue.d.ts} +1 -1
- package/dist/core/tools/browser/browser-continue.d.ts.map +1 -0
- package/dist/core/tools/{browser-continue.js → browser/browser-continue.js} +2 -2
- package/dist/core/tools/browser/browser-continue.js.map +1 -0
- package/dist/core/tools/{browser-run.d.ts → browser/browser-run.d.ts} +2 -2
- package/dist/core/tools/browser/browser-run.d.ts.map +1 -0
- package/dist/core/tools/{browser-run.js → browser/browser-run.js} +2 -2
- package/dist/core/tools/browser/browser-run.js.map +1 -0
- package/dist/core/tools/browser/browsertools-shared.d.ts.map +1 -0
- package/dist/core/tools/{browsertools-shared.js → browser/browsertools-shared.js} +1 -1
- package/dist/core/tools/browser/browsertools-shared.js.map +1 -0
- package/dist/core/tools/browser/index.d.ts +8 -0
- package/dist/core/tools/browser/index.d.ts.map +1 -0
- package/dist/core/tools/browser/index.js +8 -0
- package/dist/core/tools/browser/index.js.map +1 -0
- package/dist/core/tools/{docedit.d.ts → doc/docedit.d.ts} +2 -2
- package/dist/core/tools/doc/docedit.d.ts.map +1 -0
- package/dist/core/tools/{docedit.js → doc/docedit.js} +7 -7
- package/dist/core/tools/doc/docedit.js.map +1 -0
- package/dist/core/tools/{docgrep.d.ts → doc/docgrep.d.ts} +2 -2
- package/dist/core/tools/doc/docgrep.d.ts.map +1 -0
- package/dist/core/tools/{docgrep.js → doc/docgrep.js} +6 -6
- package/dist/core/tools/doc/docgrep.js.map +1 -0
- package/dist/core/tools/{docpeek.d.ts → doc/docpeek.d.ts} +2 -2
- package/dist/core/tools/{docpeek.js.map → doc/docpeek.d.ts.map} +1 -1
- package/dist/core/tools/{docpeek.js → doc/docpeek.js} +6 -6
- package/dist/core/tools/doc/docpeek.js.map +1 -0
- package/dist/core/tools/{docread.d.ts → doc/docread.d.ts} +2 -2
- package/dist/core/tools/doc/docread.d.ts.map +1 -0
- package/dist/core/tools/{docread.js → doc/docread.js} +6 -6
- package/dist/core/tools/doc/docread.js.map +1 -0
- package/dist/core/tools/{docscan.d.ts → doc/docscan.d.ts} +2 -2
- package/dist/core/tools/doc/docscan.d.ts.map +1 -0
- package/dist/core/tools/{docscan.js → doc/docscan.js} +6 -6
- package/dist/core/tools/doc/docscan.js.map +1 -0
- package/dist/core/tools/{docwrite.d.ts → doc/docwrite.d.ts} +1 -1
- package/dist/core/tools/doc/docwrite.d.ts.map +1 -0
- package/dist/core/tools/{docwrite.js → doc/docwrite.js} +6 -6
- package/dist/core/tools/doc/docwrite.js.map +1 -0
- package/dist/core/tools/doc/index.d.ts +11 -0
- package/dist/core/tools/doc/index.d.ts.map +1 -0
- package/dist/core/tools/doc/index.js +11 -0
- package/dist/core/tools/doc/index.js.map +1 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +42 -28
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +61 -199
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/extensions/core/ask-options.d.ts +10 -0
- package/dist/extensions/core/ask-options.d.ts.map +1 -0
- package/dist/extensions/core/ask-options.js +83 -0
- package/dist/extensions/core/ask-options.js.map +1 -0
- package/dist/extensions/core/config.d.ts +80 -0
- package/dist/extensions/core/config.d.ts.map +1 -0
- package/dist/extensions/core/config.js +110 -0
- package/dist/extensions/core/config.js.map +1 -0
- package/dist/extensions/core/cost.d.ts +11 -0
- package/dist/extensions/core/cost.d.ts.map +1 -0
- package/dist/extensions/core/cost.js +64 -0
- package/dist/extensions/core/cost.js.map +1 -0
- package/dist/extensions/core/hoo-core.d.ts +16 -179
- package/dist/extensions/core/hoo-core.d.ts.map +1 -1
- package/dist/extensions/core/hoo-core.js +27 -1663
- package/dist/extensions/core/hoo-core.js.map +1 -1
- package/dist/extensions/core/loop.d.ts +15 -0
- package/dist/extensions/core/loop.d.ts.map +1 -0
- package/dist/extensions/core/loop.js +235 -0
- package/dist/extensions/core/loop.js.map +1 -0
- package/dist/extensions/core/marketplace.d.ts +17 -0
- package/dist/extensions/core/marketplace.d.ts.map +1 -0
- package/dist/extensions/core/marketplace.js +167 -0
- package/dist/extensions/core/marketplace.js.map +1 -0
- package/dist/extensions/core/mcp-loader.d.ts +26 -0
- package/dist/extensions/core/mcp-loader.d.ts.map +1 -0
- package/dist/extensions/core/mcp-loader.js +391 -0
- package/dist/extensions/core/mcp-loader.js.map +1 -0
- package/dist/extensions/core/modes.d.ts +56 -0
- package/dist/extensions/core/modes.d.ts.map +1 -0
- package/dist/extensions/core/modes.js +268 -0
- package/dist/extensions/core/modes.js.map +1 -0
- package/dist/extensions/core/permission-gate.d.ts +10 -0
- package/dist/extensions/core/permission-gate.d.ts.map +1 -0
- package/dist/extensions/core/permission-gate.js +167 -0
- package/dist/extensions/core/permission-gate.js.map +1 -0
- package/dist/extensions/core/scaffold.d.ts +9 -0
- package/dist/extensions/core/scaffold.d.ts.map +1 -0
- package/dist/extensions/core/scaffold.js +146 -0
- package/dist/extensions/core/scaffold.js.map +1 -0
- package/dist/extensions/core/thinking-escalation.d.ts +18 -0
- package/dist/extensions/core/thinking-escalation.d.ts.map +1 -0
- package/dist/extensions/core/thinking-escalation.js +70 -0
- package/dist/extensions/core/thinking-escalation.js.map +1 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/bash-execution-controller.d.ts +34 -0
- package/dist/modes/interactive/bash-execution-controller.d.ts.map +1 -0
- package/dist/modes/interactive/bash-execution-controller.js +98 -0
- package/dist/modes/interactive/bash-execution-controller.js.map +1 -0
- package/dist/modes/interactive/command-executor.d.ts +0 -5
- package/dist/modes/interactive/command-executor.d.ts.map +1 -1
- package/dist/modes/interactive/command-executor.js +0 -7
- package/dist/modes/interactive/command-executor.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +0 -2
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -2
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/extension-chrome.d.ts +56 -0
- package/dist/modes/interactive/extension-chrome.d.ts.map +1 -0
- package/dist/modes/interactive/extension-chrome.js +172 -0
- package/dist/modes/interactive/extension-chrome.js.map +1 -0
- package/dist/modes/interactive/extension-dialogs.d.ts +82 -0
- package/dist/modes/interactive/extension-dialogs.d.ts.map +1 -0
- package/dist/modes/interactive/extension-dialogs.js +259 -0
- package/dist/modes/interactive/extension-dialogs.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +16 -206
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +359 -2370
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/login-controller.d.ts +50 -0
- package/dist/modes/interactive/login-controller.d.ts.map +1 -0
- package/dist/modes/interactive/login-controller.js +352 -0
- package/dist/modes/interactive/login-controller.js.map +1 -0
- package/dist/modes/interactive/message-queue-controller.d.ts +49 -0
- package/dist/modes/interactive/message-queue-controller.d.ts.map +1 -0
- package/dist/modes/interactive/message-queue-controller.js +184 -0
- package/dist/modes/interactive/message-queue-controller.js.map +1 -0
- package/dist/modes/interactive/model-controller.d.ts +43 -0
- package/dist/modes/interactive/model-controller.d.ts.map +1 -0
- package/dist/modes/interactive/model-controller.js +184 -0
- package/dist/modes/interactive/model-controller.js.map +1 -0
- package/dist/modes/interactive/resource-display.d.ts +59 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -0
- package/dist/modes/interactive/resource-display.js +499 -0
- package/dist/modes/interactive/resource-display.js.map +1 -0
- package/dist/modes/interactive/startup-checks.d.ts +17 -0
- package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
- package/dist/modes/interactive/startup-checks.js +102 -0
- package/dist/modes/interactive/startup-checks.js.map +1 -0
- package/dist/modes/interactive/team-focus.d.ts +56 -0
- package/dist/modes/interactive/team-focus.d.ts.map +1 -0
- package/dist/modes/interactive/team-focus.js +167 -0
- package/dist/modes/interactive/team-focus.js.map +1 -0
- package/dist/modes/interactive/voice/voice-controller.d.ts +66 -0
- package/dist/modes/interactive/voice/voice-controller.d.ts.map +1 -0
- package/dist/modes/interactive/voice/voice-controller.js +312 -0
- package/dist/modes/interactive/voice/voice-controller.js.map +1 -0
- package/dist/modes/interactive/voice/voice-panel.d.ts.map +1 -0
- package/dist/modes/interactive/voice/voice-panel.js.map +1 -0
- package/dist/modes/interactive/voice/voice-transcribe.d.ts.map +1 -0
- package/dist/modes/interactive/voice/voice-transcribe.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -2
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/resources-cli.d.ts.map +1 -1
- package/dist/resources-cli.js +1 -1
- package/dist/resources-cli.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +2 -2
- package/dist/utils/version-check.js.map +1 -1
- package/docs/project-local-resources.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
- package/dist/core/compaction/branch-summarization.d.ts +0 -88
- package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/core/compaction/branch-summarization.js +0 -243
- package/dist/core/compaction/branch-summarization.js.map +0 -1
- package/dist/core/compaction/compaction.d.ts +0 -123
- package/dist/core/compaction/compaction.d.ts.map +0 -1
- package/dist/core/compaction/compaction.js +0 -635
- package/dist/core/compaction/compaction.js.map +0 -1
- package/dist/core/compaction/index.d.ts +0 -7
- package/dist/core/compaction/index.d.ts.map +0 -1
- package/dist/core/compaction/index.js +0 -7
- package/dist/core/compaction/index.js.map +0 -1
- package/dist/core/compaction/utils.d.ts +0 -38
- package/dist/core/compaction/utils.d.ts.map +0 -1
- package/dist/core/compaction/utils.js +0 -156
- package/dist/core/compaction/utils.js.map +0 -1
- package/dist/core/messages.d.ts +0 -124
- package/dist/core/messages.d.ts.map +0 -1
- package/dist/core/messages.js +0 -221
- package/dist/core/messages.js.map +0 -1
- package/dist/core/tools/browser-continue.d.ts.map +0 -1
- package/dist/core/tools/browser-continue.js.map +0 -1
- package/dist/core/tools/browser-run.d.ts.map +0 -1
- package/dist/core/tools/browser-run.js.map +0 -1
- package/dist/core/tools/browsertools-shared.d.ts.map +0 -1
- package/dist/core/tools/browsertools-shared.js.map +0 -1
- package/dist/core/tools/docedit.d.ts.map +0 -1
- package/dist/core/tools/docedit.js.map +0 -1
- package/dist/core/tools/docgrep.d.ts.map +0 -1
- package/dist/core/tools/docgrep.js.map +0 -1
- package/dist/core/tools/docpeek.d.ts.map +0 -1
- package/dist/core/tools/docread.d.ts.map +0 -1
- package/dist/core/tools/docread.js.map +0 -1
- package/dist/core/tools/docscan.d.ts.map +0 -1
- package/dist/core/tools/docscan.js.map +0 -1
- package/dist/core/tools/docwrite.d.ts.map +0 -1
- package/dist/core/tools/docwrite.js.map +0 -1
- package/dist/core/tools/output-compression.d.ts +0 -53
- package/dist/core/tools/output-compression.d.ts.map +0 -1
- package/dist/core/tools/output-compression.js +0 -392
- package/dist/core/tools/output-compression.js.map +0 -1
- package/dist/modes/interactive/components/armin.d.ts +0 -34
- package/dist/modes/interactive/components/armin.d.ts.map +0 -1
- package/dist/modes/interactive/components/armin.js +0 -333
- package/dist/modes/interactive/components/armin.js.map +0 -1
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
- package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
- package/dist/modes/interactive/components/daxnuts.js +0 -140
- package/dist/modes/interactive/components/daxnuts.js.map +0 -1
- package/dist/modes/interactive/components/voice-panel.d.ts.map +0 -1
- package/dist/modes/interactive/components/voice-panel.js.map +0 -1
- package/dist/modes/interactive/voice-transcribe.d.ts.map +0 -1
- package/dist/modes/interactive/voice-transcribe.js.map +0 -1
- /package/dist/core/tools/{browsertools-shared.d.ts → browser/browsertools-shared.d.ts} +0 -0
- /package/dist/modes/interactive/{components → voice}/voice-panel.d.ts +0 -0
- /package/dist/modes/interactive/{components → voice}/voice-panel.js +0 -0
- /package/dist/modes/interactive/{voice-transcribe.d.ts → voice/voice-transcribe.d.ts} +0 -0
- /package/dist/modes/interactive/{voice-transcribe.js → voice/voice-transcribe.js} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash-executor.d.ts","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"bash-executor.d.ts","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAOtD,MAAM,WAAW,mBAAmB;IACnC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,mCAAmC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IAC1B,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,mDAAmD;IACnD,SAAS,EAAE,OAAO,CAAC;IACnB,uCAAuC;IACvC,SAAS,EAAE,OAAO,CAAC;IACnB,yFAAyF;IACzF,cAAc,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;GAGG;AACH,wBAAsB,yBAAyB,CAC9C,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,cAAc,EAC1B,OAAO,CAAC,EAAE,mBAAmB,GAC3B,OAAO,CAAC,UAAU,CAAC,CAuGrB","sourcesContent":["/**\n * Bash command execution with streaming support and cancellation.\n *\n * This module provides a unified bash execution implementation used by:\n * - AgentSession.executeBash() for interactive and RPC modes\n * - Direct calls from modes that need bash execution\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { compressBashOutput } from \"@kolisachint/hoocode-agent-core\";\nimport stripAnsi from \"strip-ansi\";\nimport { sanitizeBinaryOutput } from \"../utils/shell.js\";\nimport type { BashOperations } from \"./tools/bash.js\";\nimport { DEFAULT_MAX_BYTES, truncateTail } from \"./tools/truncate.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BashExecutorOptions {\n\t/** Callback for streaming output chunks (already sanitized) */\n\tonChunk?: (chunk: string) => void;\n\t/** AbortSignal for cancellation */\n\tsignal?: AbortSignal;\n}\n\nexport interface BashResult {\n\t/** Combined stdout + stderr output (sanitized, possibly truncated) */\n\toutput: string;\n\t/** Process exit code (undefined if killed/cancelled) */\n\texitCode: number | undefined;\n\t/** Whether the command was cancelled via signal */\n\tcancelled: boolean;\n\t/** Whether the output was truncated */\n\ttruncated: boolean;\n\t/** Path to temp file containing full output (if output exceeded truncation threshold) */\n\tfullOutputPath?: string;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Execute a bash command using custom BashOperations.\n * Used for remote execution (SSH, containers, etc.).\n */\nexport async function executeBashWithOperations(\n\tcommand: string,\n\tcwd: string,\n\toperations: BashOperations,\n\toptions?: BashExecutorOptions,\n): Promise<BashResult> {\n\tconst outputChunks: string[] = [];\n\tlet outputBytes = 0;\n\tconst maxOutputBytes = DEFAULT_MAX_BYTES * 2;\n\n\tlet tempFilePath: string | undefined;\n\tlet tempFileStream: WriteStream | undefined;\n\tlet totalBytes = 0;\n\n\tconst ensureTempFile = () => {\n\t\tif (tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tconst id = randomBytes(8).toString(\"hex\");\n\t\ttempFilePath = join(tmpdir(), `hoocode-bash-${id}.log`);\n\t\ttempFileStream = createWriteStream(tempFilePath);\n\t\tfor (const chunk of outputChunks) {\n\t\t\ttempFileStream.write(chunk);\n\t\t}\n\t};\n\n\tconst decoder = new TextDecoder();\n\n\tconst onData = (data: Buffer) => {\n\t\ttotalBytes += data.length;\n\n\t\t// Sanitize: strip ANSI, replace binary garbage, normalize newlines\n\t\tconst text = sanitizeBinaryOutput(stripAnsi(decoder.decode(data, { stream: true }))).replace(/\\r/g, \"\");\n\n\t\t// Start writing to temp file if exceeds threshold\n\t\tif (totalBytes > DEFAULT_MAX_BYTES) {\n\t\t\tensureTempFile();\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.write(text);\n\t\t}\n\n\t\t// Keep rolling buffer\n\t\toutputChunks.push(text);\n\t\toutputBytes += text.length;\n\t\twhile (outputBytes > maxOutputBytes && outputChunks.length > 1) {\n\t\t\tconst removed = outputChunks.shift()!;\n\t\t\toutputBytes -= removed.length;\n\t\t}\n\n\t\t// Stream to callback\n\t\tif (options?.onChunk) {\n\t\t\toptions.onChunk(text);\n\t\t}\n\t};\n\n\ttry {\n\t\tconst result = await operations.exec(command, cwd, {\n\t\t\tonData,\n\t\t\tsignal: options?.signal,\n\t\t});\n\n\t\tconst fullOutput = outputChunks.join(\"\");\n\t\tconst compressedOutput = compressBashOutput(command, fullOutput);\n\t\tconst truncationResult = truncateTail(compressedOutput);\n\t\tif (truncationResult.truncated) {\n\t\t\tensureTempFile();\n\t\t}\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\t\tconst cancelled = options?.signal?.aborted ?? false;\n\n\t\treturn {\n\t\t\toutput: truncationResult.truncated ? truncationResult.content : compressedOutput,\n\t\t\texitCode: cancelled ? undefined : (result.exitCode ?? undefined),\n\t\t\tcancelled,\n\t\t\ttruncated: truncationResult.truncated,\n\t\t\tfullOutputPath: tempFilePath,\n\t\t};\n\t} catch (err) {\n\t\t// Check if it was an abort\n\t\tif (options?.signal?.aborted) {\n\t\t\tconst fullOutput = outputChunks.join(\"\");\n\t\t\tconst compressedOutput = compressBashOutput(command, fullOutput);\n\t\t\tconst truncationResult = truncateTail(compressedOutput);\n\t\t\tif (truncationResult.truncated) {\n\t\t\t\tensureTempFile();\n\t\t\t}\n\t\t\tif (tempFileStream) {\n\t\t\t\ttempFileStream.end();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toutput: truncationResult.truncated ? truncationResult.content : compressedOutput,\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: true,\n\t\t\t\ttruncated: truncationResult.truncated,\n\t\t\t\tfullOutputPath: tempFilePath,\n\t\t\t};\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\n\t\tthrow err;\n\t}\n}\n"]}
|
|
@@ -9,9 +9,9 @@ import { randomBytes } from "node:crypto";
|
|
|
9
9
|
import { createWriteStream } from "node:fs";
|
|
10
10
|
import { tmpdir } from "node:os";
|
|
11
11
|
import { join } from "node:path";
|
|
12
|
+
import { compressBashOutput } from "@kolisachint/hoocode-agent-core";
|
|
12
13
|
import stripAnsi from "strip-ansi";
|
|
13
14
|
import { sanitizeBinaryOutput } from "../utils/shell.js";
|
|
14
|
-
import { compressBashOutput } from "./tools/output-compression.js";
|
|
15
15
|
import { DEFAULT_MAX_BYTES, truncateTail } from "./tools/truncate.js";
|
|
16
16
|
// ============================================================================
|
|
17
17
|
// Implementation
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bash-executor.js","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAoB,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,
|
|
1
|
+
{"version":3,"file":"bash-executor.js","sourceRoot":"","sources":["../../src/core/bash-executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,iBAAiB,EAAoB,MAAM,SAAS,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AACrE,OAAO,SAAS,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AA0BtE,+EAA+E;AAC/E,iBAAiB;AACjB,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC9C,OAAe,EACf,GAAW,EACX,UAA0B,EAC1B,OAA6B,EACP;IACtB,MAAM,YAAY,GAAa,EAAE,CAAC;IAClC,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,cAAc,GAAG,iBAAiB,GAAG,CAAC,CAAC;IAE7C,IAAI,YAAgC,CAAC;IACrC,IAAI,cAAuC,CAAC;IAC5C,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,MAAM,cAAc,GAAG,GAAG,EAAE,CAAC;QAC5B,IAAI,YAAY,EAAE,CAAC;YAClB,OAAO;QACR,CAAC;QACD,MAAM,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC1C,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;QACxD,cAAc,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC;QACjD,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;YAClC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC;IAAA,CACD,CAAC;IAEF,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAElC,MAAM,MAAM,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC;QAChC,UAAU,IAAI,IAAI,CAAC,MAAM,CAAC;QAE1B,mEAAmE;QACnE,MAAM,IAAI,GAAG,oBAAoB,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAExG,kDAAkD;QAClD,IAAI,UAAU,GAAG,iBAAiB,EAAE,CAAC;YACpC,cAAc,EAAE,CAAC;QAClB,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACpB,cAAc,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QAED,sBAAsB;QACtB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxB,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC;QAC3B,OAAO,WAAW,GAAG,cAAc,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChE,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,EAAG,CAAC;YACtC,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC;QAC/B,CAAC;QAED,qBAAqB;QACrB,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC;YACtB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACvB,CAAC;IAAA,CACD,CAAC;IAEF,IAAI,CAAC;QACJ,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE;YAClD,MAAM;YACN,MAAM,EAAE,OAAO,EAAE,MAAM;SACvB,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACzC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;QACjE,MAAM,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;QACxD,IAAI,gBAAgB,CAAC,SAAS,EAAE,CAAC;YAChC,cAAc,EAAE,CAAC;QAClB,CAAC;QACD,IAAI,cAAc,EAAE,CAAC;YACpB,cAAc,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC;QACD,MAAM,SAAS,GAAG,OAAO,EAAE,MAAM,EAAE,OAAO,IAAI,KAAK,CAAC;QAEpD,OAAO;YACN,MAAM,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB;YAChF,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,IAAI,SAAS,CAAC;YAChE,SAAS;YACT,SAAS,EAAE,gBAAgB,CAAC,SAAS;YACrC,cAAc,EAAE,YAAY;SAC5B,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACd,2BAA2B;QAC3B,IAAI,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;YAC9B,MAAM,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACzC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YACjE,MAAM,gBAAgB,GAAG,YAAY,CAAC,gBAAgB,CAAC,CAAC;YACxD,IAAI,gBAAgB,CAAC,SAAS,EAAE,CAAC;gBAChC,cAAc,EAAE,CAAC;YAClB,CAAC;YACD,IAAI,cAAc,EAAE,CAAC;gBACpB,cAAc,CAAC,GAAG,EAAE,CAAC;YACtB,CAAC;YACD,OAAO;gBACN,MAAM,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB;gBAChF,QAAQ,EAAE,SAAS;gBACnB,SAAS,EAAE,IAAI;gBACf,SAAS,EAAE,gBAAgB,CAAC,SAAS;gBACrC,cAAc,EAAE,YAAY;aAC5B,CAAC;QACH,CAAC;QAED,IAAI,cAAc,EAAE,CAAC;YACpB,cAAc,CAAC,GAAG,EAAE,CAAC;QACtB,CAAC;QAED,MAAM,GAAG,CAAC;IACX,CAAC;AAAA,CACD","sourcesContent":["/**\n * Bash command execution with streaming support and cancellation.\n *\n * This module provides a unified bash execution implementation used by:\n * - AgentSession.executeBash() for interactive and RPC modes\n * - Direct calls from modes that need bash execution\n */\n\nimport { randomBytes } from \"node:crypto\";\nimport { createWriteStream, type WriteStream } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { compressBashOutput } from \"@kolisachint/hoocode-agent-core\";\nimport stripAnsi from \"strip-ansi\";\nimport { sanitizeBinaryOutput } from \"../utils/shell.js\";\nimport type { BashOperations } from \"./tools/bash.js\";\nimport { DEFAULT_MAX_BYTES, truncateTail } from \"./tools/truncate.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface BashExecutorOptions {\n\t/** Callback for streaming output chunks (already sanitized) */\n\tonChunk?: (chunk: string) => void;\n\t/** AbortSignal for cancellation */\n\tsignal?: AbortSignal;\n}\n\nexport interface BashResult {\n\t/** Combined stdout + stderr output (sanitized, possibly truncated) */\n\toutput: string;\n\t/** Process exit code (undefined if killed/cancelled) */\n\texitCode: number | undefined;\n\t/** Whether the command was cancelled via signal */\n\tcancelled: boolean;\n\t/** Whether the output was truncated */\n\ttruncated: boolean;\n\t/** Path to temp file containing full output (if output exceeded truncation threshold) */\n\tfullOutputPath?: string;\n}\n\n// ============================================================================\n// Implementation\n// ============================================================================\n\n/**\n * Execute a bash command using custom BashOperations.\n * Used for remote execution (SSH, containers, etc.).\n */\nexport async function executeBashWithOperations(\n\tcommand: string,\n\tcwd: string,\n\toperations: BashOperations,\n\toptions?: BashExecutorOptions,\n): Promise<BashResult> {\n\tconst outputChunks: string[] = [];\n\tlet outputBytes = 0;\n\tconst maxOutputBytes = DEFAULT_MAX_BYTES * 2;\n\n\tlet tempFilePath: string | undefined;\n\tlet tempFileStream: WriteStream | undefined;\n\tlet totalBytes = 0;\n\n\tconst ensureTempFile = () => {\n\t\tif (tempFilePath) {\n\t\t\treturn;\n\t\t}\n\t\tconst id = randomBytes(8).toString(\"hex\");\n\t\ttempFilePath = join(tmpdir(), `hoocode-bash-${id}.log`);\n\t\ttempFileStream = createWriteStream(tempFilePath);\n\t\tfor (const chunk of outputChunks) {\n\t\t\ttempFileStream.write(chunk);\n\t\t}\n\t};\n\n\tconst decoder = new TextDecoder();\n\n\tconst onData = (data: Buffer) => {\n\t\ttotalBytes += data.length;\n\n\t\t// Sanitize: strip ANSI, replace binary garbage, normalize newlines\n\t\tconst text = sanitizeBinaryOutput(stripAnsi(decoder.decode(data, { stream: true }))).replace(/\\r/g, \"\");\n\n\t\t// Start writing to temp file if exceeds threshold\n\t\tif (totalBytes > DEFAULT_MAX_BYTES) {\n\t\t\tensureTempFile();\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.write(text);\n\t\t}\n\n\t\t// Keep rolling buffer\n\t\toutputChunks.push(text);\n\t\toutputBytes += text.length;\n\t\twhile (outputBytes > maxOutputBytes && outputChunks.length > 1) {\n\t\t\tconst removed = outputChunks.shift()!;\n\t\t\toutputBytes -= removed.length;\n\t\t}\n\n\t\t// Stream to callback\n\t\tif (options?.onChunk) {\n\t\t\toptions.onChunk(text);\n\t\t}\n\t};\n\n\ttry {\n\t\tconst result = await operations.exec(command, cwd, {\n\t\t\tonData,\n\t\t\tsignal: options?.signal,\n\t\t});\n\n\t\tconst fullOutput = outputChunks.join(\"\");\n\t\tconst compressedOutput = compressBashOutput(command, fullOutput);\n\t\tconst truncationResult = truncateTail(compressedOutput);\n\t\tif (truncationResult.truncated) {\n\t\t\tensureTempFile();\n\t\t}\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\t\tconst cancelled = options?.signal?.aborted ?? false;\n\n\t\treturn {\n\t\t\toutput: truncationResult.truncated ? truncationResult.content : compressedOutput,\n\t\t\texitCode: cancelled ? undefined : (result.exitCode ?? undefined),\n\t\t\tcancelled,\n\t\t\ttruncated: truncationResult.truncated,\n\t\t\tfullOutputPath: tempFilePath,\n\t\t};\n\t} catch (err) {\n\t\t// Check if it was an abort\n\t\tif (options?.signal?.aborted) {\n\t\t\tconst fullOutput = outputChunks.join(\"\");\n\t\t\tconst compressedOutput = compressBashOutput(command, fullOutput);\n\t\t\tconst truncationResult = truncateTail(compressedOutput);\n\t\t\tif (truncationResult.truncated) {\n\t\t\t\tensureTempFile();\n\t\t\t}\n\t\t\tif (tempFileStream) {\n\t\t\t\ttempFileStream.end();\n\t\t\t}\n\t\t\treturn {\n\t\t\t\toutput: truncationResult.truncated ? truncationResult.content : compressedOutput,\n\t\t\t\texitCode: undefined,\n\t\t\t\tcancelled: true,\n\t\t\t\ttruncated: truncationResult.truncated,\n\t\t\t\tfullOutputPath: tempFilePath,\n\t\t\t};\n\t\t}\n\n\t\tif (tempFileStream) {\n\t\t\ttempFileStream.end();\n\t\t}\n\n\t\tthrow err;\n\t}\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Process-global registry of MCP servers contributed by extensions/plugins.
|
|
3
3
|
*
|
|
4
4
|
* Plugins declare `mcpServers` in their manifest (or a `.mcp.json`), but MCP
|
|
5
|
-
* connection happens in hoo-core's `setupMcpLoader` on `session_start`, which
|
|
5
|
+
* connection happens in the hoo-core `mcp-loader` module's `setupMcpLoader` on `session_start`, which
|
|
6
6
|
* reads from fixed file locations. This registry bridges the two: plugin
|
|
7
7
|
* factories register their servers here during load, and `setupMcpLoader` reads
|
|
8
8
|
* them when connecting. Mirrors the module-global approach of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-mcp-servers.d.ts","sourceRoot":"","sources":["../../src/core/extension-mcp-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uEAAuE;AACvE,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IACjC,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,+DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACrD;AAID,8DAA8D;AAC9D,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAClD,IAAI,CAGN;AAED,0DAA0D;AAC1D,wBAAgB,sBAAsB,IAAI,iBAAiB,EAAE,CAE5D;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C","sourcesContent":["/**\n * Process-global registry of MCP servers contributed by extensions/plugins.\n *\n * Plugins declare `mcpServers` in their manifest (or a `.mcp.json`), but MCP\n * connection happens in hoo-core's `setupMcpLoader` on `session_start`, which\n * reads from fixed file locations. This registry bridges the two: plugin\n * factories register their servers here during load, and `setupMcpLoader` reads\n * them when connecting. Mirrors the module-global approach of\n * `agent-manifest-paths.ts`.\n *\n * Entries are keyed by `source` so a reload can rebuild the set cleanly: call\n * {@link clearExtensionMcpServers} before (re)loading plugins, then register.\n */\n\n/** Standard MCP server config (Claude Desktop / `.mcp.json` shape). */\nexport interface ExtensionMcpServerConfig {\n\tcommand: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tbackground?: boolean;\n}\n\nexport interface ExtensionMcpEntry {\n\t/** Identifier of the contributing plugin/extension (for diagnostics + dedup). */\n\tsource: string;\n\t/** Server name → config, in standard `mcpServers` format. */\n\tmcpServers: Record<string, ExtensionMcpServerConfig>;\n}\n\nlet registered: ExtensionMcpEntry[] = [];\n\n/** Register MCP servers contributed by a plugin/extension. */\nexport function registerExtensionMcpServers(\n\tsource: string,\n\tmcpServers: Record<string, ExtensionMcpServerConfig>,\n): void {\n\tif (!mcpServers || Object.keys(mcpServers).length === 0) return;\n\tregistered.push({ source, mcpServers });\n}\n\n/** Get all currently registered extension MCP servers. */\nexport function getExtensionMcpServers(): ExtensionMcpEntry[] {\n\treturn [...registered];\n}\n\n/** Clear the registry. Call before (re)loading plugins so reloads don't accumulate. */\nexport function clearExtensionMcpServers(): void {\n\tregistered = [];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"extension-mcp-servers.d.ts","sourceRoot":"","sources":["../../src/core/extension-mcp-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,uEAAuE;AACvE,MAAM,WAAW,wBAAwB;IACxC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IACjC,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;IACf,+DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAC;CACrD;AAID,8DAA8D;AAC9D,wBAAgB,2BAA2B,CAC1C,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,GAClD,IAAI,CAGN;AAED,0DAA0D;AAC1D,wBAAgB,sBAAsB,IAAI,iBAAiB,EAAE,CAE5D;AAED,uFAAuF;AACvF,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C","sourcesContent":["/**\n * Process-global registry of MCP servers contributed by extensions/plugins.\n *\n * Plugins declare `mcpServers` in their manifest (or a `.mcp.json`), but MCP\n * connection happens in the hoo-core `mcp-loader` module's `setupMcpLoader` on `session_start`, which\n * reads from fixed file locations. This registry bridges the two: plugin\n * factories register their servers here during load, and `setupMcpLoader` reads\n * them when connecting. Mirrors the module-global approach of\n * `agent-manifest-paths.ts`.\n *\n * Entries are keyed by `source` so a reload can rebuild the set cleanly: call\n * {@link clearExtensionMcpServers} before (re)loading plugins, then register.\n */\n\n/** Standard MCP server config (Claude Desktop / `.mcp.json` shape). */\nexport interface ExtensionMcpServerConfig {\n\tcommand: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tbackground?: boolean;\n}\n\nexport interface ExtensionMcpEntry {\n\t/** Identifier of the contributing plugin/extension (for diagnostics + dedup). */\n\tsource: string;\n\t/** Server name → config, in standard `mcpServers` format. */\n\tmcpServers: Record<string, ExtensionMcpServerConfig>;\n}\n\nlet registered: ExtensionMcpEntry[] = [];\n\n/** Register MCP servers contributed by a plugin/extension. */\nexport function registerExtensionMcpServers(\n\tsource: string,\n\tmcpServers: Record<string, ExtensionMcpServerConfig>,\n): void {\n\tif (!mcpServers || Object.keys(mcpServers).length === 0) return;\n\tregistered.push({ source, mcpServers });\n}\n\n/** Get all currently registered extension MCP servers. */\nexport function getExtensionMcpServers(): ExtensionMcpEntry[] {\n\treturn [...registered];\n}\n\n/** Clear the registry. Call before (re)loading plugins so reloads don't accumulate. */\nexport function clearExtensionMcpServers(): void {\n\tregistered = [];\n}\n"]}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Process-global registry of MCP servers contributed by extensions/plugins.
|
|
3
3
|
*
|
|
4
4
|
* Plugins declare `mcpServers` in their manifest (or a `.mcp.json`), but MCP
|
|
5
|
-
* connection happens in hoo-core's `setupMcpLoader` on `session_start`, which
|
|
5
|
+
* connection happens in the hoo-core `mcp-loader` module's `setupMcpLoader` on `session_start`, which
|
|
6
6
|
* reads from fixed file locations. This registry bridges the two: plugin
|
|
7
7
|
* factories register their servers here during load, and `setupMcpLoader` reads
|
|
8
8
|
* them when connecting. Mirrors the module-global approach of
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-mcp-servers.js","sourceRoot":"","sources":["../../src/core/extension-mcp-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiBH,IAAI,UAAU,GAAwB,EAAE,CAAC;AAEzC,8DAA8D;AAC9D,MAAM,UAAU,2BAA2B,CAC1C,MAAc,EACd,UAAoD,EAC7C;IACP,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAChE,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AAAA,CACxC;AAED,0DAA0D;AAC1D,MAAM,UAAU,sBAAsB,GAAwB;IAC7D,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC;AAAA,CACvB;AAED,uFAAuF;AACvF,MAAM,UAAU,wBAAwB,GAAS;IAChD,UAAU,GAAG,EAAE,CAAC;AAAA,CAChB","sourcesContent":["/**\n * Process-global registry of MCP servers contributed by extensions/plugins.\n *\n * Plugins declare `mcpServers` in their manifest (or a `.mcp.json`), but MCP\n * connection happens in hoo-core's `setupMcpLoader` on `session_start`, which\n * reads from fixed file locations. This registry bridges the two: plugin\n * factories register their servers here during load, and `setupMcpLoader` reads\n * them when connecting. Mirrors the module-global approach of\n * `agent-manifest-paths.ts`.\n *\n * Entries are keyed by `source` so a reload can rebuild the set cleanly: call\n * {@link clearExtensionMcpServers} before (re)loading plugins, then register.\n */\n\n/** Standard MCP server config (Claude Desktop / `.mcp.json` shape). */\nexport interface ExtensionMcpServerConfig {\n\tcommand: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tbackground?: boolean;\n}\n\nexport interface ExtensionMcpEntry {\n\t/** Identifier of the contributing plugin/extension (for diagnostics + dedup). */\n\tsource: string;\n\t/** Server name → config, in standard `mcpServers` format. */\n\tmcpServers: Record<string, ExtensionMcpServerConfig>;\n}\n\nlet registered: ExtensionMcpEntry[] = [];\n\n/** Register MCP servers contributed by a plugin/extension. */\nexport function registerExtensionMcpServers(\n\tsource: string,\n\tmcpServers: Record<string, ExtensionMcpServerConfig>,\n): void {\n\tif (!mcpServers || Object.keys(mcpServers).length === 0) return;\n\tregistered.push({ source, mcpServers });\n}\n\n/** Get all currently registered extension MCP servers. */\nexport function getExtensionMcpServers(): ExtensionMcpEntry[] {\n\treturn [...registered];\n}\n\n/** Clear the registry. Call before (re)loading plugins so reloads don't accumulate. */\nexport function clearExtensionMcpServers(): void {\n\tregistered = [];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"extension-mcp-servers.js","sourceRoot":"","sources":["../../src/core/extension-mcp-servers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAiBH,IAAI,UAAU,GAAwB,EAAE,CAAC;AAEzC,8DAA8D;AAC9D,MAAM,UAAU,2BAA2B,CAC1C,MAAc,EACd,UAAoD,EAC7C;IACP,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO;IAChE,UAAU,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC,CAAC;AAAA,CACxC;AAED,0DAA0D;AAC1D,MAAM,UAAU,sBAAsB,GAAwB;IAC7D,OAAO,CAAC,GAAG,UAAU,CAAC,CAAC;AAAA,CACvB;AAED,uFAAuF;AACvF,MAAM,UAAU,wBAAwB,GAAS;IAChD,UAAU,GAAG,EAAE,CAAC;AAAA,CAChB","sourcesContent":["/**\n * Process-global registry of MCP servers contributed by extensions/plugins.\n *\n * Plugins declare `mcpServers` in their manifest (or a `.mcp.json`), but MCP\n * connection happens in the hoo-core `mcp-loader` module's `setupMcpLoader` on `session_start`, which\n * reads from fixed file locations. This registry bridges the two: plugin\n * factories register their servers here during load, and `setupMcpLoader` reads\n * them when connecting. Mirrors the module-global approach of\n * `agent-manifest-paths.ts`.\n *\n * Entries are keyed by `source` so a reload can rebuild the set cleanly: call\n * {@link clearExtensionMcpServers} before (re)loading plugins, then register.\n */\n\n/** Standard MCP server config (Claude Desktop / `.mcp.json` shape). */\nexport interface ExtensionMcpServerConfig {\n\tcommand: string;\n\targs?: string[];\n\tenv?: Record<string, string>;\n\tbackground?: boolean;\n}\n\nexport interface ExtensionMcpEntry {\n\t/** Identifier of the contributing plugin/extension (for diagnostics + dedup). */\n\tsource: string;\n\t/** Server name → config, in standard `mcpServers` format. */\n\tmcpServers: Record<string, ExtensionMcpServerConfig>;\n}\n\nlet registered: ExtensionMcpEntry[] = [];\n\n/** Register MCP servers contributed by a plugin/extension. */\nexport function registerExtensionMcpServers(\n\tsource: string,\n\tmcpServers: Record<string, ExtensionMcpServerConfig>,\n): void {\n\tif (!mcpServers || Object.keys(mcpServers).length === 0) return;\n\tregistered.push({ source, mcpServers });\n}\n\n/** Get all currently registered extension MCP servers. */\nexport function getExtensionMcpServers(): ExtensionMcpEntry[] {\n\treturn [...registered];\n}\n\n/** Clear the registry. Call before (re)loading plugins so reloads don't accumulate. */\nexport function clearExtensionMcpServers(): void {\n\tregistered = [];\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,KAAK,gBAAgB,EAAkB,MAAM,eAAe,CAAC;AA6BtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAuBxE;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAkC7E","sourcesContent":["/**\n * Plugin discovery and wiring.\n *\n * Discovers plugin directories under the `plugins/` folders, parses their\n * manifests (see {@link parsePluginDir}), and turns each into a synthetic\n * {@link ExtensionFactory} that registers the plugin's capabilities through the\n * existing ExtensionAPI. The factory is loaded by the standard extension loader,\n * so plugins are just extensions assembled from a manifest instead of code.\n *\n * Capability wiring (minimum):\n * - skills / themes → `resources_discover` skill/theme paths\n * - commands → `resources_discover` slash-command paths (`.agents/commands`)\n * - agents → `resources_discover` agent paths (`.agents/agents` subagents)\n * - providers (native only) → `registerProvider`\n * - hooks → shell-protocol bridge (see hooks-bridge.ts)\n * - mcpServers → parsed; wiring deferred (see design doc)\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { type ExtensionMcpServerConfig, registerExtensionMcpServers } from \"../../extension-mcp-servers.js\";\nimport type { ExtensionAPI, ExtensionFactory } from \"../types.js\";\nimport { installPluginHooks } from \"./hooks-bridge.js\";\nimport { type NormalizedPlugin, parsePluginDir } from \"./manifest.js\";\n\n/** Substitute ${CLAUDE_PLUGIN_ROOT} / ${AGENTS_PLUGIN_ROOT} with the plugin root in a string. */\nfunction substituteRoot(value: string, root: string): string {\n\treturn value.replace(/\\$\\{(?:CLAUDE|AGENTS)_PLUGIN_ROOT\\}/g, root);\n}\n\n/** Coerce parsed mcpServers into the standard config shape, substituting root vars. */\nfunction resolveMcpServers(\n\tmcpServers: Record<string, unknown>,\n\troot: string,\n): Record<string, ExtensionMcpServerConfig> {\n\tconst out: Record<string, ExtensionMcpServerConfig> = {};\n\tfor (const [name, raw] of Object.entries(mcpServers)) {\n\t\tif (!raw || typeof raw !== \"object\") continue;\n\t\tconst cfg = raw as ExtensionMcpServerConfig;\n\t\tif (typeof cfg.command !== \"string\") continue;\n\t\tout[name] = {\n\t\t\tcommand: substituteRoot(cfg.command, root),\n\t\t\targs: cfg.args?.map((a) => substituteRoot(String(a), root)),\n\t\t\tenv: cfg.env\n\t\t\t\t? Object.fromEntries(Object.entries(cfg.env).map(([k, v]) => [k, substituteRoot(String(v), root)]))\n\t\t\t\t: undefined,\n\t\t\tbackground: cfg.background,\n\t\t};\n\t}\n\treturn out;\n}\n\nexport type { NormalizedPlugin } from \"./manifest.js\";\nexport { parsePluginDir } from \"./manifest.js\";\n\n/**\n * Discover plugins across the given `plugins/` directories.\n * First-wins on duplicate ids (project dirs should be listed before global).\n */\nexport function discoverPlugins(pluginDirs: string[]): NormalizedPlugin[] {\n\tconst plugins: NormalizedPlugin[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const dir of pluginDirs) {\n\t\tif (!fs.existsSync(dir)) continue;\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = fs.readdirSync(dir, { withFileTypes: true });\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\t\t\tconst plugin = parsePluginDir(path.join(dir, entry.name));\n\t\t\tif (plugin && !seen.has(plugin.id)) {\n\t\t\t\tseen.add(plugin.id);\n\t\t\t\tplugins.push(plugin);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn plugins;\n}\n\n/** Build a synthetic extension factory that wires one normalized plugin. */\nexport function buildPluginFactory(plugin: NormalizedPlugin): ExtensionFactory {\n\tconst factory: ExtensionFactory = (pi: ExtensionAPI) => {\n\t\t// Resources: contribute the plugin's capability directories. Commands map to\n\t\t// the slash-command surface (`.agents/commands`) and agents to subagent\n\t\t// definitions (`.agents/agents`), matching hoocode's native conventions.\n\t\tif (plugin.skillsDir || plugin.commandsDir || plugin.themesDir || plugin.agentsDir) {\n\t\t\tpi.on(\"resources_discover\", () => ({\n\t\t\t\tskillPaths: plugin.skillsDir ? [plugin.skillsDir] : undefined,\n\t\t\t\tthemePaths: plugin.themesDir ? [plugin.themesDir] : undefined,\n\t\t\t\tslashCommandPaths: plugin.commandsDir ? [plugin.commandsDir] : undefined,\n\t\t\t\tagentPaths: plugin.agentsDir ? [plugin.agentsDir] : undefined,\n\t\t\t}));\n\t\t}\n\n\t\t// Providers (native plugins only).\n\t\tfor (const provider of plugin.providers ?? []) {\n\t\t\tpi.registerProvider(provider.name, provider.config);\n\t\t}\n\n\t\t// Hooks: true-parity shell bridge.\n\t\tif (plugin.hooks) {\n\t\t\tinstallPluginHooks(pi, plugin.hooks, plugin.root, () => {\n\t\t\t\t// Non-blocking hook failures are intentionally quiet (Claude Code parity).\n\t\t\t});\n\t\t}\n\n\t\t// MCP servers: register for hoo-core
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/plugins/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAKH,OAAO,KAAK,EAAgB,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAElE,OAAO,EAAE,KAAK,gBAAgB,EAAkB,MAAM,eAAe,CAAC;AA6BtE,YAAY,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,gBAAgB,EAAE,CAuBxE;AAED,4EAA4E;AAC5E,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAkC7E","sourcesContent":["/**\n * Plugin discovery and wiring.\n *\n * Discovers plugin directories under the `plugins/` folders, parses their\n * manifests (see {@link parsePluginDir}), and turns each into a synthetic\n * {@link ExtensionFactory} that registers the plugin's capabilities through the\n * existing ExtensionAPI. The factory is loaded by the standard extension loader,\n * so plugins are just extensions assembled from a manifest instead of code.\n *\n * Capability wiring (minimum):\n * - skills / themes → `resources_discover` skill/theme paths\n * - commands → `resources_discover` slash-command paths (`.agents/commands`)\n * - agents → `resources_discover` agent paths (`.agents/agents` subagents)\n * - providers (native only) → `registerProvider`\n * - hooks → shell-protocol bridge (see hooks-bridge.ts)\n * - mcpServers → parsed; wiring deferred (see design doc)\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { type ExtensionMcpServerConfig, registerExtensionMcpServers } from \"../../extension-mcp-servers.js\";\nimport type { ExtensionAPI, ExtensionFactory } from \"../types.js\";\nimport { installPluginHooks } from \"./hooks-bridge.js\";\nimport { type NormalizedPlugin, parsePluginDir } from \"./manifest.js\";\n\n/** Substitute ${CLAUDE_PLUGIN_ROOT} / ${AGENTS_PLUGIN_ROOT} with the plugin root in a string. */\nfunction substituteRoot(value: string, root: string): string {\n\treturn value.replace(/\\$\\{(?:CLAUDE|AGENTS)_PLUGIN_ROOT\\}/g, root);\n}\n\n/** Coerce parsed mcpServers into the standard config shape, substituting root vars. */\nfunction resolveMcpServers(\n\tmcpServers: Record<string, unknown>,\n\troot: string,\n): Record<string, ExtensionMcpServerConfig> {\n\tconst out: Record<string, ExtensionMcpServerConfig> = {};\n\tfor (const [name, raw] of Object.entries(mcpServers)) {\n\t\tif (!raw || typeof raw !== \"object\") continue;\n\t\tconst cfg = raw as ExtensionMcpServerConfig;\n\t\tif (typeof cfg.command !== \"string\") continue;\n\t\tout[name] = {\n\t\t\tcommand: substituteRoot(cfg.command, root),\n\t\t\targs: cfg.args?.map((a) => substituteRoot(String(a), root)),\n\t\t\tenv: cfg.env\n\t\t\t\t? Object.fromEntries(Object.entries(cfg.env).map(([k, v]) => [k, substituteRoot(String(v), root)]))\n\t\t\t\t: undefined,\n\t\t\tbackground: cfg.background,\n\t\t};\n\t}\n\treturn out;\n}\n\nexport type { NormalizedPlugin } from \"./manifest.js\";\nexport { parsePluginDir } from \"./manifest.js\";\n\n/**\n * Discover plugins across the given `plugins/` directories.\n * First-wins on duplicate ids (project dirs should be listed before global).\n */\nexport function discoverPlugins(pluginDirs: string[]): NormalizedPlugin[] {\n\tconst plugins: NormalizedPlugin[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const dir of pluginDirs) {\n\t\tif (!fs.existsSync(dir)) continue;\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = fs.readdirSync(dir, { withFileTypes: true });\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\t\t\tconst plugin = parsePluginDir(path.join(dir, entry.name));\n\t\t\tif (plugin && !seen.has(plugin.id)) {\n\t\t\t\tseen.add(plugin.id);\n\t\t\t\tplugins.push(plugin);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn plugins;\n}\n\n/** Build a synthetic extension factory that wires one normalized plugin. */\nexport function buildPluginFactory(plugin: NormalizedPlugin): ExtensionFactory {\n\tconst factory: ExtensionFactory = (pi: ExtensionAPI) => {\n\t\t// Resources: contribute the plugin's capability directories. Commands map to\n\t\t// the slash-command surface (`.agents/commands`) and agents to subagent\n\t\t// definitions (`.agents/agents`), matching hoocode's native conventions.\n\t\tif (plugin.skillsDir || plugin.commandsDir || plugin.themesDir || plugin.agentsDir) {\n\t\t\tpi.on(\"resources_discover\", () => ({\n\t\t\t\tskillPaths: plugin.skillsDir ? [plugin.skillsDir] : undefined,\n\t\t\t\tthemePaths: plugin.themesDir ? [plugin.themesDir] : undefined,\n\t\t\t\tslashCommandPaths: plugin.commandsDir ? [plugin.commandsDir] : undefined,\n\t\t\t\tagentPaths: plugin.agentsDir ? [plugin.agentsDir] : undefined,\n\t\t\t}));\n\t\t}\n\n\t\t// Providers (native plugins only).\n\t\tfor (const provider of plugin.providers ?? []) {\n\t\t\tpi.registerProvider(provider.name, provider.config);\n\t\t}\n\n\t\t// Hooks: true-parity shell bridge.\n\t\tif (plugin.hooks) {\n\t\t\tinstallPluginHooks(pi, plugin.hooks, plugin.root, () => {\n\t\t\t\t// Non-blocking hook failures are intentionally quiet (Claude Code parity).\n\t\t\t});\n\t\t}\n\n\t\t// MCP servers: register for the hoo-core mcp-loader to connect on session_start.\n\t\tif (plugin.mcpServers) {\n\t\t\tregisterExtensionMcpServers(plugin.id, resolveMcpServers(plugin.mcpServers, plugin.root));\n\t\t}\n\t};\n\n\tfactory.displayName = `plugin:${plugin.id}`;\n\treturn factory;\n}\n"]}
|
|
@@ -98,7 +98,7 @@ export function buildPluginFactory(plugin) {
|
|
|
98
98
|
// Non-blocking hook failures are intentionally quiet (Claude Code parity).
|
|
99
99
|
});
|
|
100
100
|
}
|
|
101
|
-
// MCP servers: register for hoo-core
|
|
101
|
+
// MCP servers: register for the hoo-core mcp-loader to connect on session_start.
|
|
102
102
|
if (plugin.mcpServers) {
|
|
103
103
|
registerExtensionMcpServers(plugin.id, resolveMcpServers(plugin.mcpServers, plugin.root));
|
|
104
104
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/extensions/plugins/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/core/extensions/plugins/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Plugin discovery and wiring.\n *\n * Discovers plugin directories under the `plugins/` folders, parses their\n * manifests (see {@link parsePluginDir}), and turns each into a synthetic\n * {@link ExtensionFactory} that registers the plugin's capabilities through the\n * existing ExtensionAPI. The factory is loaded by the standard extension loader,\n * so plugins are just extensions assembled from a manifest instead of code.\n *\n * Capability wiring (minimum):\n * - skills / themes → `resources_discover` skill/theme paths\n * - commands → `resources_discover` slash-command paths (`.agents/commands`)\n * - agents → `resources_discover` agent paths (`.agents/agents` subagents)\n * - providers (native only) → `registerProvider`\n * - hooks → shell-protocol bridge (see hooks-bridge.ts)\n * - mcpServers → parsed; wiring deferred (see design doc)\n */\n\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { type ExtensionMcpServerConfig, registerExtensionMcpServers } from \"../../extension-mcp-servers.js\";\nimport type { ExtensionAPI, ExtensionFactory } from \"../types.js\";\nimport { installPluginHooks } from \"./hooks-bridge.js\";\nimport { type NormalizedPlugin, parsePluginDir } from \"./manifest.js\";\n\n/** Substitute ${CLAUDE_PLUGIN_ROOT} / ${AGENTS_PLUGIN_ROOT} with the plugin root in a string. */\nfunction substituteRoot(value: string, root: string): string {\n\treturn value.replace(/\\$\\{(?:CLAUDE|AGENTS)_PLUGIN_ROOT\\}/g, root);\n}\n\n/** Coerce parsed mcpServers into the standard config shape, substituting root vars. */\nfunction resolveMcpServers(\n\tmcpServers: Record<string, unknown>,\n\troot: string,\n): Record<string, ExtensionMcpServerConfig> {\n\tconst out: Record<string, ExtensionMcpServerConfig> = {};\n\tfor (const [name, raw] of Object.entries(mcpServers)) {\n\t\tif (!raw || typeof raw !== \"object\") continue;\n\t\tconst cfg = raw as ExtensionMcpServerConfig;\n\t\tif (typeof cfg.command !== \"string\") continue;\n\t\tout[name] = {\n\t\t\tcommand: substituteRoot(cfg.command, root),\n\t\t\targs: cfg.args?.map((a) => substituteRoot(String(a), root)),\n\t\t\tenv: cfg.env\n\t\t\t\t? Object.fromEntries(Object.entries(cfg.env).map(([k, v]) => [k, substituteRoot(String(v), root)]))\n\t\t\t\t: undefined,\n\t\t\tbackground: cfg.background,\n\t\t};\n\t}\n\treturn out;\n}\n\nexport type { NormalizedPlugin } from \"./manifest.js\";\nexport { parsePluginDir } from \"./manifest.js\";\n\n/**\n * Discover plugins across the given `plugins/` directories.\n * First-wins on duplicate ids (project dirs should be listed before global).\n */\nexport function discoverPlugins(pluginDirs: string[]): NormalizedPlugin[] {\n\tconst plugins: NormalizedPlugin[] = [];\n\tconst seen = new Set<string>();\n\n\tfor (const dir of pluginDirs) {\n\t\tif (!fs.existsSync(dir)) continue;\n\t\tlet entries: fs.Dirent[];\n\t\ttry {\n\t\t\tentries = fs.readdirSync(dir, { withFileTypes: true });\n\t\t} catch {\n\t\t\tcontinue;\n\t\t}\n\t\tfor (const entry of entries) {\n\t\t\tif (!entry.isDirectory() && !entry.isSymbolicLink()) continue;\n\t\t\tconst plugin = parsePluginDir(path.join(dir, entry.name));\n\t\t\tif (plugin && !seen.has(plugin.id)) {\n\t\t\t\tseen.add(plugin.id);\n\t\t\t\tplugins.push(plugin);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn plugins;\n}\n\n/** Build a synthetic extension factory that wires one normalized plugin. */\nexport function buildPluginFactory(plugin: NormalizedPlugin): ExtensionFactory {\n\tconst factory: ExtensionFactory = (pi: ExtensionAPI) => {\n\t\t// Resources: contribute the plugin's capability directories. Commands map to\n\t\t// the slash-command surface (`.agents/commands`) and agents to subagent\n\t\t// definitions (`.agents/agents`), matching hoocode's native conventions.\n\t\tif (plugin.skillsDir || plugin.commandsDir || plugin.themesDir || plugin.agentsDir) {\n\t\t\tpi.on(\"resources_discover\", () => ({\n\t\t\t\tskillPaths: plugin.skillsDir ? [plugin.skillsDir] : undefined,\n\t\t\t\tthemePaths: plugin.themesDir ? [plugin.themesDir] : undefined,\n\t\t\t\tslashCommandPaths: plugin.commandsDir ? [plugin.commandsDir] : undefined,\n\t\t\t\tagentPaths: plugin.agentsDir ? [plugin.agentsDir] : undefined,\n\t\t\t}));\n\t\t}\n\n\t\t// Providers (native plugins only).\n\t\tfor (const provider of plugin.providers ?? []) {\n\t\t\tpi.registerProvider(provider.name, provider.config);\n\t\t}\n\n\t\t// Hooks: true-parity shell bridge.\n\t\tif (plugin.hooks) {\n\t\t\tinstallPluginHooks(pi, plugin.hooks, plugin.root, () => {\n\t\t\t\t// Non-blocking hook failures are intentionally quiet (Claude Code parity).\n\t\t\t});\n\t\t}\n\n\t\t// MCP servers: register for the hoo-core mcp-loader to connect on session_start.\n\t\tif (plugin.mcpServers) {\n\t\t\tregisterExtensionMcpServers(plugin.id, resolveMcpServers(plugin.mcpServers, plugin.root));\n\t\t}\n\t};\n\n\tfactory.displayName = `plugin:${plugin.id}`;\n\treturn factory;\n}\n"]}
|
|
@@ -7,18 +7,16 @@
|
|
|
7
7
|
* - Register commands, keyboard shortcuts, and CLI flags
|
|
8
8
|
* - Interact with the user via UI primitives
|
|
9
9
|
*/
|
|
10
|
-
import type { AgentMessage, AgentToolCall, AgentToolResult, AgentToolUpdateCallback, ThinkingLevel, ToolExecutionMode } from "@kolisachint/hoocode-agent-core";
|
|
10
|
+
import type { AgentMessage, AgentToolCall, AgentToolResult, AgentToolUpdateCallback, CompactionPreparation, CompactionResult, CustomMessage, ThinkingLevel, ToolExecutionMode } from "@kolisachint/hoocode-agent-core";
|
|
11
11
|
import type { Api, AssistantMessageEvent, AssistantMessageEventStream, Context, ImageContent, Model, OAuthCredentials, OAuthLoginCallbacks, SimpleStreamOptions, TextContent, ToolResultMessage } from "@kolisachint/hoocode-ai";
|
|
12
12
|
import type { AutocompleteItem, AutocompleteProvider, Component, EditorComponent, EditorTheme, KeyId, OverlayHandle, OverlayOptions, TUI } from "@kolisachint/hoocode-tui";
|
|
13
13
|
import type { Static, TSchema } from "typebox";
|
|
14
14
|
import type { Theme } from "../../modes/interactive/theme/theme.js";
|
|
15
15
|
import type { BashResult } from "../bash-executor.js";
|
|
16
|
-
import type { CompactionPreparation, CompactionResult } from "../compaction/index.js";
|
|
17
16
|
import type { EventBus } from "../event-bus.js";
|
|
18
17
|
import type { ExecOptions, ExecResult } from "../exec.js";
|
|
19
18
|
import type { ReadonlyFooterDataProvider } from "../footer-data-provider.js";
|
|
20
19
|
import type { KeybindingsManager } from "../keybindings.js";
|
|
21
|
-
import type { CustomMessage } from "../messages.js";
|
|
22
20
|
import type { ModelRegistry } from "../model-registry.js";
|
|
23
21
|
import type { BranchSummaryEntry, CompactionEntry, ReadonlySessionManager, SessionEntry, SessionManager } from "../session-manager.js";
|
|
24
22
|
import type { SlashCommandInfo } from "../slash-commands.js";
|