agent-trellis 0.7.0 → 0.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -153
- package/dist/adapters/claude-code.js +3 -2
- package/dist/adapters/codex.js +3 -2
- package/dist/adapters/jsonMcp.d.ts +3 -1
- package/dist/adapters/jsonMcp.js +18 -4
- package/dist/adapters/kimi-code.d.ts +21 -0
- package/dist/adapters/kimi-code.js +107 -0
- package/dist/adapters/kiro.js +3 -2
- package/dist/adapters/mcpPlan.d.ts +6 -1
- package/dist/adapters/mcpPlan.js +106 -8
- package/dist/adapters/pi.js +22 -3
- package/dist/adapters/symlinkPlan.d.ts +7 -0
- package/dist/adapters/symlinkPlan.js +16 -7
- package/dist/adapters/zcode.d.ts +21 -0
- package/dist/adapters/zcode.js +234 -0
- package/dist/cli.js +145 -29
- package/dist/commands/doctor.d.ts +7 -2
- package/dist/commands/doctor.js +40 -2
- package/dist/commands/init.d.ts +4 -2
- package/dist/commands/init.js +29 -13
- package/dist/commands/kimi.d.ts +16 -0
- package/dist/commands/kimi.js +64 -0
- package/dist/commands/manage.d.ts +39 -0
- package/dist/commands/manage.js +126 -0
- package/dist/commands/mcp.d.ts +77 -14
- package/dist/commands/mcp.js +169 -29
- package/dist/commands/mcpGateway.d.ts +6 -0
- package/dist/commands/mcpGateway.js +35 -14
- package/dist/commands/mcpImport.d.ts +46 -0
- package/dist/commands/mcpImport.js +359 -0
- package/dist/commands/memory.d.ts +17 -3
- package/dist/commands/memory.js +27 -8
- package/dist/commands/migrate.d.ts +16 -5
- package/dist/commands/migrate.js +93 -17
- package/dist/commands/onboard.d.ts +74 -2
- package/dist/commands/onboard.js +469 -71
- package/dist/commands/rollback.js +28 -2
- package/dist/commands/secretsAudit.js +4 -1
- package/dist/commands/skill.d.ts +52 -6
- package/dist/commands/skill.js +114 -15
- package/dist/commands/sync.js +5 -1
- package/dist/core/adapter.d.ts +11 -1
- package/dist/core/canonical.d.ts +15 -7
- package/dist/core/canonical.js +101 -13
- package/dist/core/capabilitySelection.d.ts +45 -0
- package/dist/core/capabilitySelection.js +124 -0
- package/dist/core/types.d.ts +25 -2
- package/dist/core/types.js +8 -0
- package/dist/lib/agentBridge.d.ts +169 -0
- package/dist/lib/agentBridge.js +367 -0
- package/dist/lib/agentBridgeProvider.d.ts +14 -0
- package/dist/lib/agentBridgeProvider.js +95 -0
- package/dist/lib/backup.d.ts +32 -0
- package/dist/lib/backup.js +20 -1
- package/dist/lib/builtinSkills.d.ts +2 -0
- package/dist/lib/builtinSkills.js +4 -0
- package/dist/lib/chatAgents.d.ts +42 -0
- package/dist/lib/chatAgents.js +59 -0
- package/dist/lib/cliMetadata.d.ts +1 -0
- package/dist/lib/cliMetadata.js +14 -0
- package/dist/lib/envVarNames.d.ts +3 -0
- package/dist/lib/envVarNames.js +19 -0
- package/dist/lib/gatewayBackend.d.ts +28 -0
- package/dist/lib/gatewayBackend.js +72 -1
- package/dist/lib/installAgent.d.ts +7 -5
- package/dist/lib/installAgent.js +4 -3
- package/dist/lib/mcpConnect.js +5 -1
- package/dist/lib/mcpMigrateRead.d.ts +2 -0
- package/dist/lib/mcpMigrateRead.js +22 -1
- package/dist/lib/mcpRuntime.d.ts +46 -0
- package/dist/lib/mcpRuntime.js +185 -0
- package/dist/lib/mcpStatusProvider.d.ts +10 -0
- package/dist/lib/mcpStatusProvider.js +25 -0
- package/dist/lib/mcpToolRegistry.d.ts +18 -0
- package/dist/lib/mcpToolRegistry.js +107 -14
- package/dist/lib/memoryGraph.d.ts +1 -1
- package/dist/lib/memoryGraph.js +9 -3
- package/dist/lib/memoryProvider.d.ts +58 -0
- package/dist/lib/memoryProvider.js +175 -0
- package/dist/lib/memoryStatus.d.ts +17 -0
- package/dist/lib/memoryStatus.js +88 -0
- package/dist/lib/nativeMemory.d.ts +19 -0
- package/dist/lib/nativeMemory.js +129 -0
- package/dist/lib/realHomeSnapshot.js +5 -0
- package/dist/lib/runtimeControlProvider.d.ts +16 -0
- package/dist/lib/runtimeControlProvider.js +170 -0
- package/dist/lib/secretEnv.d.ts +2 -1
- package/dist/lib/secretEnv.js +6 -2
- package/dist/lib/skillProvider.d.ts +13 -0
- package/dist/lib/skillProvider.js +210 -0
- package/dist/lib/taskProvider.d.ts +7 -0
- package/dist/lib/taskProvider.js +43 -0
- package/dist/lib/taskStore.d.ts +46 -0
- package/dist/lib/taskStore.js +156 -0
- package/dist/lib/terminalPicker.d.ts +23 -49
- package/dist/lib/terminalPicker.js +80 -218
- package/dist/lib/zcodeOwnership.d.ts +17 -0
- package/dist/lib/zcodeOwnership.js +37 -0
- package/dist/pi-bridge/bundle.js +476 -37
- package/dist/pi-bridge/index.js +42 -21
- package/dist/pi-bridge/schemaTranslate.d.ts +4 -8
- package/dist/pi-bridge/schemaTranslate.js +4 -8
- package/dist/probes/codex.d.ts +7 -0
- package/dist/probes/codex.js +37 -5
- package/dist/probes/kimi-code.d.ts +12 -0
- package/dist/probes/kimi-code.js +55 -0
- package/dist/probes/zcode.d.ts +32 -0
- package/dist/probes/zcode.js +140 -0
- package/dist/sdk.d.ts +1 -1
- package/docs/architecture.md +230 -28
- package/docs/assets/brand-v3/trellis-mark-v3-a.png +0 -0
- package/docs/assets/brand-v3/trellis-mark-v3-a.svg +10 -0
- package/docs/assets/poster-series-v3/README.md +60 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-horizontal-en.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-horizontal-en.svg +51 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-horizontal-zh.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-horizontal-zh.svg +51 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-memory-en.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-memory-en.svg +48 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-memory-zh.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-memory-zh.svg +48 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-migrate-en.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-migrate-en.svg +56 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-migrate-zh.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-migrate-zh.svg +56 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-switch-en.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-switch-en.svg +47 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-switch-zh.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-switch-zh.svg +47 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-unified-en.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-unified-en.svg +51 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-unified-zh.png +0 -0
- package/docs/assets/poster-series-v3/agent-trellis-poster-v3-unified-zh.svg +51 -0
- package/docs/getting-started.md +496 -42
- package/docs/overview.md +134 -0
- package/docs/overview.zh-CN.md +102 -0
- package/docs/research.md +59 -0
- package/docs/roadmap.md +11 -6
- package/docs/video/README.md +76 -0
- package/docs/video/build/audio/01-opening.aiff +0 -0
- package/docs/video/build/audio/01-opening.mp3 +0 -0
- package/docs/video/build/audio/02-pain.aiff +0 -0
- package/docs/video/build/audio/02-pain.mp3 +0 -0
- package/docs/video/build/audio/03-solution.aiff +0 -0
- package/docs/video/build/audio/03-solution.mp3 +0 -0
- package/docs/video/build/audio/04-install.aiff +0 -0
- package/docs/video/build/audio/04-install.mp3 +0 -0
- package/docs/video/build/audio/04-setup.mp3 +0 -0
- package/docs/video/build/audio/05-dryrun.mp3 +0 -0
- package/docs/video/build/audio/05-init.aiff +0 -0
- package/docs/video/build/audio/05-init.mp3 +0 -0
- package/docs/video/build/audio/05-interactive.mp3 +0 -0
- package/docs/video/build/audio/06-dryrun.aiff +0 -0
- package/docs/video/build/audio/06-dryrun.mp3 +0 -0
- package/docs/video/build/audio/06-onboard.mp3 +0 -0
- package/docs/video/build/audio/06-run.mp3 +0 -0
- package/docs/video/build/audio/07-onboard.aiff +0 -0
- package/docs/video/build/audio/07-onboard.mp3 +0 -0
- package/docs/video/build/audio/07-verify.mp3 +0 -0
- package/docs/video/build/audio/08-closing.mp3 +0 -0
- package/docs/video/build/audio/08-doctor.aiff +0 -0
- package/docs/video/build/audio/08-doctor.mp3 +0 -0
- package/docs/video/build/audio/09-rollback.aiff +0 -0
- package/docs/video/build/audio/09-rollback.mp3 +0 -0
- package/docs/video/build/audio/10-principles.aiff +0 -0
- package/docs/video/build/audio/10-principles.mp3 +0 -0
- package/docs/video/build/audio/11-closing.aiff +0 -0
- package/docs/video/build/audio/11-closing.mp3 +0 -0
- package/docs/video/build/frames/01-opening-0.png +0 -0
- package/docs/video/build/frames/02-pain-1.png +0 -0
- package/docs/video/build/frames/02-pain-2.png +0 -0
- package/docs/video/build/frames/03-solution-3.png +0 -0
- package/docs/video/build/frames/04-install-4.png +0 -0
- package/docs/video/build/frames/04-setup-4.png +0 -0
- package/docs/video/build/frames/04-setup-5.png +0 -0
- package/docs/video/build/frames/05-dryrun-6.png +0 -0
- package/docs/video/build/frames/05-init-5.png +0 -0
- package/docs/video/build/frames/05-interactive-5.png +0 -0
- package/docs/video/build/frames/05-interactive-6.png +0 -0
- package/docs/video/build/frames/06-dryrun-6.png +0 -0
- package/docs/video/build/frames/06-dryrun-7.png +0 -0
- package/docs/video/build/frames/06-onboard-7.png +0 -0
- package/docs/video/build/frames/06-onboard-8.png +0 -0
- package/docs/video/build/frames/06-run-7.png +0 -0
- package/docs/video/build/frames/06-run-8.png +0 -0
- package/docs/video/build/frames/07-onboard-10.png +0 -0
- package/docs/video/build/frames/07-onboard-7.png +0 -0
- package/docs/video/build/frames/07-onboard-8.png +0 -0
- package/docs/video/build/frames/07-onboard-9.png +0 -0
- package/docs/video/build/frames/07-verify-10.png +0 -0
- package/docs/video/build/frames/07-verify-8.png +0 -0
- package/docs/video/build/frames/07-verify-9.png +0 -0
- package/docs/video/build/frames/08-closing-10.png +0 -0
- package/docs/video/build/frames/08-closing-11.png +0 -0
- package/docs/video/build/frames/08-doctor-11.png +0 -0
- package/docs/video/build/frames/08-doctor-9.png +0 -0
- package/docs/video/build/frames/09-rollback-10.png +0 -0
- package/docs/video/build/frames/09-rollback-12.png +0 -0
- package/docs/video/build/frames/10-principles-11.png +0 -0
- package/docs/video/build/frames/10-principles-13.png +0 -0
- package/docs/video/build/frames/11-closing-12.png +0 -0
- package/docs/video/build/frames/11-closing-14.png +0 -0
- package/docs/video/build/segments/01-opening.mp4 +0 -0
- package/docs/video/build/segments/01-opening.txt +3 -0
- package/docs/video/build/segments/02-pain.mp4 +0 -0
- package/docs/video/build/segments/02-pain.txt +5 -0
- package/docs/video/build/segments/03-solution.mp4 +0 -0
- package/docs/video/build/segments/03-solution.txt +3 -0
- package/docs/video/build/segments/04-install.mp4 +0 -0
- package/docs/video/build/segments/04-install.txt +3 -0
- package/docs/video/build/segments/04-setup.mp4 +0 -0
- package/docs/video/build/segments/04-setup.txt +3 -0
- package/docs/video/build/segments/05-dryrun.mp4 +0 -0
- package/docs/video/build/segments/05-dryrun.txt +3 -0
- package/docs/video/build/segments/05-init.mp4 +0 -0
- package/docs/video/build/segments/05-init.txt +3 -0
- package/docs/video/build/segments/05-interactive.mp4 +0 -0
- package/docs/video/build/segments/05-interactive.txt +5 -0
- package/docs/video/build/segments/06-dryrun.mp4 +0 -0
- package/docs/video/build/segments/06-dryrun.txt +3 -0
- package/docs/video/build/segments/06-onboard.mp4 +0 -0
- package/docs/video/build/segments/06-onboard.txt +5 -0
- package/docs/video/build/segments/06-run.mp4 +0 -0
- package/docs/video/build/segments/06-run.txt +3 -0
- package/docs/video/build/segments/07-onboard.mp4 +0 -0
- package/docs/video/build/segments/07-onboard.txt +5 -0
- package/docs/video/build/segments/07-verify.mp4 +0 -0
- package/docs/video/build/segments/07-verify.txt +5 -0
- package/docs/video/build/segments/08-closing.mp4 +0 -0
- package/docs/video/build/segments/08-closing.txt +3 -0
- package/docs/video/build/segments/08-doctor.mp4 +0 -0
- package/docs/video/build/segments/08-doctor.txt +3 -0
- package/docs/video/build/segments/09-rollback.mp4 +0 -0
- package/docs/video/build/segments/09-rollback.txt +3 -0
- package/docs/video/build/segments/10-principles.mp4 +0 -0
- package/docs/video/build/segments/10-principles.txt +3 -0
- package/docs/video/build/segments/11-closing.mp4 +0 -0
- package/docs/video/build/segments/11-closing.txt +3 -0
- package/docs/video/build/segments/final.txt +8 -0
- package/docs/video/build-ai/audio/01-hook.mp3 +0 -0
- package/docs/video/build-ai/audio/02-pain.mp3 +0 -0
- package/docs/video/build-ai/audio/03-solution.mp3 +0 -0
- package/docs/video/build-ai/audio/04-how.mp3 +0 -0
- package/docs/video/build-ai/audio/05-safe.mp3 +0 -0
- package/docs/video/build-ai/audio/06-closing.mp3 +0 -0
- package/docs/video/build-ai/clips/01-hook.mp4 +0 -0
- package/docs/video/build-ai/clips/02-pain.mp4 +0 -0
- package/docs/video/build-ai/clips/03-solution.mp4 +0 -0
- package/docs/video/build-ai/clips/04-how.mp4 +0 -0
- package/docs/video/build-ai/clips/05-safe.mp4 +0 -0
- package/docs/video/build-ai/clips/06-closing.mp4 +0 -0
- package/docs/video/build-ai/first-frame-02-pain.png +0 -0
- package/docs/video/build-ai/first-frame-03-solution.png +0 -0
- package/docs/video/build-ai/first-frame-04-how.png +0 -0
- package/docs/video/build-ai/first-frame-05-safe.png +0 -0
- package/docs/video/build-ai/segments/01-hook.caption.txt +2 -0
- package/docs/video/build-ai/segments/01-hook.mp4 +0 -0
- package/docs/video/build-ai/segments/02-pain.mp4 +0 -0
- package/docs/video/build-ai/segments/03-solution.mp4 +0 -0
- package/docs/video/build-ai/segments/04-how.mp4 +0 -0
- package/docs/video/build-ai/segments/05-safe.mp4 +0 -0
- package/docs/video/build-ai/segments/06-closing.mp4 +0 -0
- package/docs/video/build-ai/segments/cap-01-hook.png +0 -0
- package/docs/video/build-ai/segments/cap-02-pain.png +0 -0
- package/docs/video/build-ai/segments/cap-03-solution.png +0 -0
- package/docs/video/build-ai/segments/cap-04-how.png +0 -0
- package/docs/video/build-ai/segments/cap-05-safe.png +0 -0
- package/docs/video/build-ai/segments/cap-06-closing.png +0 -0
- package/docs/video/build-ai/segments/final.txt +6 -0
- package/docs/video/build-posters/audio/01-hook.mp3 +0 -0
- package/docs/video/build-posters/audio/02-pain.mp3 +0 -0
- package/docs/video/build-posters/audio/03-solution.mp3 +0 -0
- package/docs/video/build-posters/audio/04-how.mp3 +0 -0
- package/docs/video/build-posters/audio/05-safe.mp3 +0 -0
- package/docs/video/build-posters/audio/06-closing.mp3 +0 -0
- package/docs/video/build-posters/cap-01-hook.png +0 -0
- package/docs/video/build-posters/cap-02-pain.png +0 -0
- package/docs/video/build-posters/cap-03-solution.png +0 -0
- package/docs/video/build-posters/cap-04-how.png +0 -0
- package/docs/video/build-posters/cap-05-safe.png +0 -0
- package/docs/video/build-posters/cap-06-closing.png +0 -0
- package/docs/video/build-posters/card-01-hook.png +0 -0
- package/docs/video/build-posters/card-06-closing.png +0 -0
- package/docs/video/build-posters/segments/01-hook.mp4 +0 -0
- package/docs/video/build-posters/segments/02-pain.mp4 +0 -0
- package/docs/video/build-posters/segments/03-solution.mp4 +0 -0
- package/docs/video/build-posters/segments/04-how.mp4 +0 -0
- package/docs/video/build-posters/segments/05-safe.mp4 +0 -0
- package/docs/video/build-posters/segments/06-closing.mp4 +0 -0
- package/docs/video/build-posters/segments/final.txt +6 -0
- package/docs/video/generate-video-ai.mjs +334 -0
- package/docs/video/generate-video-posters.mjs +204 -0
- package/docs/video/generate-video.mjs +426 -0
- package/docs/video/outline.zh-CN.md +102 -0
- package/docs/video/trellis-demo-video-ai.mp4 +0 -0
- package/docs/video/trellis-demo-video.mp4 +0 -0
- package/docs/video/voiceover.zh-CN.md +49 -0
- package/package.json +6 -2
- package/schema/builtin-skills/trellis-runtime/SKILL.md +117 -0
- package/schema/capability-selection.example.yaml +23 -0
- package/schema/scope.example.yaml +1 -1
- package/schema/servers.example.yaml +15 -1
package/dist/pi-bridge/index.js
CHANGED
|
@@ -15,29 +15,17 @@ import { homedir } from "node:os";
|
|
|
15
15
|
import { loadCanonicalSource } from "../core/canonical.js";
|
|
16
16
|
import { resolveMcpPlan } from "../adapters/mcpPlan.js";
|
|
17
17
|
import { connectServer, withTimeout, DEFAULT_CONNECT_TIMEOUT_MS } from "../lib/mcpConnect.js";
|
|
18
|
+
import { McpToolRegistry } from "../lib/mcpToolRegistry.js";
|
|
19
|
+
import { withOAuthHeader } from "../lib/gatewayBackend.js";
|
|
18
20
|
import { ALL_AGENTS } from "../core/types.js";
|
|
19
|
-
import {
|
|
21
|
+
import { toParametersSchema, toPiContent } from "./schemaTranslate.js";
|
|
20
22
|
/** Re-exported so `trellis-mcp-connect-timeout`'s existing test keeps
|
|
21
23
|
* importing it from the module it was written against — proving the
|
|
22
24
|
* extraction changed nothing it could observe. */
|
|
23
25
|
export { withTimeout };
|
|
24
26
|
const CLIENT_INFO = { name: "trellis-mcp-bridge", version: "0.0.0" };
|
|
25
|
-
function
|
|
26
|
-
return withTimeout(client.listTools(), timeoutMs, `listTools timed out after ${timeoutMs}ms`).then((result) =>
|
|
27
|
-
for (const tool of result.tools) {
|
|
28
|
-
pi.registerTool({
|
|
29
|
-
name: bridgedToolName(serverName, tool.name),
|
|
30
|
-
label: tool.name,
|
|
31
|
-
description: tool.description ?? `MCP tool "${tool.name}" from server "${serverName}"`,
|
|
32
|
-
parameters: toParametersSchema(tool.inputSchema),
|
|
33
|
-
async execute(_toolCallId, params) {
|
|
34
|
-
const result = await client.callTool({ name: tool.name, arguments: params });
|
|
35
|
-
const content = Array.isArray(result.content) ? result.content : [];
|
|
36
|
-
return { content: toPiContent(content), details: result };
|
|
37
|
-
},
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
});
|
|
27
|
+
function listServerTools(client, timeoutMs) {
|
|
28
|
+
return withTimeout(client.listTools(), timeoutMs, `listTools timed out after ${timeoutMs}ms`).then((result) => result.tools);
|
|
41
29
|
}
|
|
42
30
|
/**
|
|
43
31
|
* `homeDir`/`connectTimeoutMs` default to the real `~` / 10s — only
|
|
@@ -57,6 +45,7 @@ export default async function trellisMcpBridge(pi, homeDir = homedir(), connectT
|
|
|
57
45
|
// is pi reading canonical directly at its own runtime, P4's own concern.
|
|
58
46
|
const { desired } = resolveMcpPlan("pi", canonical.mcp, ALL_AGENTS, canonical.secretsPolicy);
|
|
59
47
|
const clients = new Set();
|
|
48
|
+
const registry = new McpToolRegistry();
|
|
60
49
|
const closeClient = async (client) => {
|
|
61
50
|
if (!clients.delete(client))
|
|
62
51
|
return;
|
|
@@ -83,25 +72,57 @@ export default async function trellisMcpBridge(pi, homeDir = homedir(), connectT
|
|
|
83
72
|
// pi 0.85.x emits this before tearing down an extension runtime. Keep the
|
|
84
73
|
// hook optional so the bridge remains loadable in older compatible hosts.
|
|
85
74
|
pi.on?.("session_shutdown", closeAllClients);
|
|
86
|
-
await Promise.all(desired.map(async ({ name, def }) => {
|
|
75
|
+
const discovered = await Promise.all(desired.map(async ({ name, def }) => {
|
|
87
76
|
let client;
|
|
88
77
|
try {
|
|
89
|
-
|
|
78
|
+
const effectiveDef = def.auth === "oauth" && def.url
|
|
79
|
+
? await withOAuthHeader(name, def, homeDir)
|
|
80
|
+
: def;
|
|
81
|
+
client = await connectServer(effectiveDef, canonical.secretsPolicy, connectTimeoutMs, CLIENT_INFO);
|
|
90
82
|
}
|
|
91
83
|
catch (err) {
|
|
92
84
|
// One unreachable/misconfigured (including permanently hanging —
|
|
93
85
|
// trellis-mcp-connect-timeout) server must never prevent every
|
|
94
86
|
// other server's tools from registering (tasks.md 3.2).
|
|
95
87
|
console.error(`trellis-mcp-bridge: failed to connect to MCP server "${name}": ${err instanceof Error ? err.message : String(err)}`);
|
|
96
|
-
return;
|
|
88
|
+
return undefined;
|
|
97
89
|
}
|
|
98
90
|
clients.add(client);
|
|
99
91
|
try {
|
|
100
|
-
await
|
|
92
|
+
const tools = await listServerTools(client, connectTimeoutMs);
|
|
93
|
+
return { name, client, tools };
|
|
101
94
|
}
|
|
102
95
|
catch (err) {
|
|
103
96
|
console.error(`trellis-mcp-bridge: failed to list tools for MCP server "${name}": ${err instanceof Error ? err.message : String(err)}`);
|
|
104
97
|
await closeClient(client);
|
|
98
|
+
return undefined;
|
|
105
99
|
}
|
|
106
100
|
}));
|
|
101
|
+
// Add in canonical plan order, not completion order, so allocation remains
|
|
102
|
+
// stable when multiple upstreams answer concurrently.
|
|
103
|
+
for (const result of discovered) {
|
|
104
|
+
if (!result)
|
|
105
|
+
continue;
|
|
106
|
+
registry.add(result.name, result.client, result.tools);
|
|
107
|
+
}
|
|
108
|
+
for (const tool of registry.listTools()) {
|
|
109
|
+
const target = registry.resolve(tool.name);
|
|
110
|
+
if (!target)
|
|
111
|
+
continue;
|
|
112
|
+
const originalName = target.toolName;
|
|
113
|
+
const serverName = target.serverName;
|
|
114
|
+
pi.registerTool({
|
|
115
|
+
name: tool.name,
|
|
116
|
+
label: originalName,
|
|
117
|
+
description: tool.description ?? `MCP tool "${originalName}" from server "${serverName}"`,
|
|
118
|
+
parameters: toParametersSchema(tool.inputSchema),
|
|
119
|
+
async execute(_toolCallId, params) {
|
|
120
|
+
const result = await registry.callTool(tool.name, params);
|
|
121
|
+
const content = Array.isArray(result.content)
|
|
122
|
+
? result.content
|
|
123
|
+
: [];
|
|
124
|
+
return { content: toPiContent(content), details: result };
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
107
128
|
}
|
|
@@ -50,12 +50,8 @@ export declare function toParametersSchema(inputSchema: unknown): TSchema;
|
|
|
50
50
|
* own `AgentToolResult.content` has no representation for them
|
|
51
51
|
* (design.md D3). */
|
|
52
52
|
export declare function toPiContent(items: McpContentItem[]): PiContent[];
|
|
53
|
-
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
* than two identical ones: the naming convention is the contract between
|
|
58
|
-
* a prefixed name and the server it routes to, and two copies of it could
|
|
59
|
-
* drift into routing tools to the wrong upstream
|
|
60
|
-
* (trellis-mcp-gateway-hosting design.md D3). */
|
|
53
|
+
/** Legacy direct prefix helper kept for callers/tests that need to render a
|
|
54
|
+
* source-qualified name. The live bridge uses `McpToolRegistry` so it can
|
|
55
|
+
* allocate short names across all connected servers, normalize invalid
|
|
56
|
+
* characters, and retain the raw name for routing. */
|
|
61
57
|
export { prefixedToolName as bridgedToolName } from "../lib/mcpToolRegistry.js";
|
|
@@ -33,12 +33,8 @@ export function toPiContent(items) {
|
|
|
33
33
|
}
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
|
-
/**
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
* than two identical ones: the naming convention is the contract between
|
|
41
|
-
* a prefixed name and the server it routes to, and two copies of it could
|
|
42
|
-
* drift into routing tools to the wrong upstream
|
|
43
|
-
* (trellis-mcp-gateway-hosting design.md D3). */
|
|
36
|
+
/** Legacy direct prefix helper kept for callers/tests that need to render a
|
|
37
|
+
* source-qualified name. The live bridge uses `McpToolRegistry` so it can
|
|
38
|
+
* allocate short names across all connected servers, normalize invalid
|
|
39
|
+
* characters, and retain the raw name for routing. */
|
|
44
40
|
export { prefixedToolName as bridgedToolName } from "../lib/mcpToolRegistry.js";
|
package/dist/probes/codex.d.ts
CHANGED
|
@@ -21,4 +21,11 @@ export interface ProbeOptions {
|
|
|
21
21
|
* default — see docs/architecture.md "MCP handshake probing is opt-in". */
|
|
22
22
|
probeMcp?: boolean;
|
|
23
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Codex resolves its config through HOME, but Volta's shim resolves its own
|
|
26
|
+
* installation through VOLTA_HOME. A probe against a scratch HOME must keep
|
|
27
|
+
* those identities separate or `codex mcp list` fails before it can read the
|
|
28
|
+
* scratch config.
|
|
29
|
+
*/
|
|
30
|
+
export declare function codexEnv(homeDir: string, env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
24
31
|
export declare function probe(homeDir?: string, opts?: ProbeOptions): Promise<AgentSnapshot>;
|
package/dist/probes/codex.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
import { execFileSync } from "node:child_process";
|
|
12
12
|
import { existsSync, readFileSync } from "node:fs";
|
|
13
13
|
import { homedir } from "node:os";
|
|
14
|
-
import { join } from "node:path";
|
|
14
|
+
import { delimiter, join } from "node:path";
|
|
15
15
|
import { probeMcpServer } from "../lib/mcpProbe.js";
|
|
16
16
|
import { pathRef, resolveEnvRefs, scanSkillRoot } from "../lib/probeCommon.js";
|
|
17
17
|
/**
|
|
@@ -30,6 +30,30 @@ export function readInstructionsPath(configTomlPath) {
|
|
|
30
30
|
}
|
|
31
31
|
return /^\s*instructions\s*=\s*"([^"]*)"/m.exec(content)?.[1];
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Codex resolves its config through HOME, but Volta's shim resolves its own
|
|
35
|
+
* installation through VOLTA_HOME. A probe against a scratch HOME must keep
|
|
36
|
+
* those identities separate or `codex mcp list` fails before it can read the
|
|
37
|
+
* scratch config.
|
|
38
|
+
*/
|
|
39
|
+
export function codexEnv(homeDir, env = process.env) {
|
|
40
|
+
const voltaHome = env.VOLTA_HOME ?? join(homedir(), ".volta");
|
|
41
|
+
const voltaBin = join(voltaHome, "bin");
|
|
42
|
+
const pathParts = (env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
43
|
+
const hasVolta = existsSync(voltaBin);
|
|
44
|
+
if (hasVolta && !pathParts.includes(voltaBin))
|
|
45
|
+
pathParts.unshift(voltaBin);
|
|
46
|
+
return {
|
|
47
|
+
...env,
|
|
48
|
+
HOME: homeDir,
|
|
49
|
+
// A host may inject CODEX_HOME for its own relay/session state. It has
|
|
50
|
+
// higher priority than HOME inside Codex, so override it as well or a
|
|
51
|
+
// scratch-home probe silently reads the host's real configuration.
|
|
52
|
+
CODEX_HOME: join(homeDir, ".codex"),
|
|
53
|
+
...(hasVolta ? { VOLTA_HOME: voltaHome } : {}),
|
|
54
|
+
...(pathParts.length ? { PATH: pathParts.join(delimiter) } : {}),
|
|
55
|
+
};
|
|
56
|
+
}
|
|
33
57
|
export async function probe(homeDir = homedir(), opts = {}) {
|
|
34
58
|
const configTomlPath = join(homeDir, ".codex", "config.toml");
|
|
35
59
|
if (!existsSync(configTomlPath)) {
|
|
@@ -43,21 +67,29 @@ export async function probe(homeDir = homedir(), opts = {}) {
|
|
|
43
67
|
// default `homeDir` would silently get this real machine's real MCP
|
|
44
68
|
// server list instead (trellis-migrate-mcp-servers found this gap in
|
|
45
69
|
// src/lib/mcpMigrateRead.ts's own equivalent call; fixed there first).
|
|
46
|
-
const
|
|
70
|
+
const scopedCodexEnv = codexEnv(homeDir);
|
|
47
71
|
let version;
|
|
48
72
|
try {
|
|
49
|
-
version = execFileSync("codex", ["--version"], { encoding: "utf-8", timeout: 5_000, env:
|
|
73
|
+
version = execFileSync("codex", ["--version"], { encoding: "utf-8", timeout: 5_000, env: scopedCodexEnv }).trim();
|
|
50
74
|
}
|
|
51
75
|
catch {
|
|
52
76
|
// config exists without the binary on PATH — unusual, still probeable
|
|
53
77
|
}
|
|
54
78
|
let mcpEntries = [];
|
|
55
79
|
try {
|
|
56
|
-
const raw = execFileSync("codex", ["mcp", "list", "--json"], { encoding: "utf-8", timeout: 5_000, env:
|
|
80
|
+
const raw = execFileSync("codex", ["mcp", "list", "--json"], { encoding: "utf-8", timeout: 5_000, env: scopedCodexEnv });
|
|
57
81
|
mcpEntries = JSON.parse(raw);
|
|
58
82
|
}
|
|
59
83
|
catch (err) {
|
|
60
|
-
|
|
84
|
+
// ENOENT means the binary itself isn't on PATH — the same benign,
|
|
85
|
+
// config-without-binary condition the `--version` check above already
|
|
86
|
+
// swallows silently, not a real failure worth alarming the user with a
|
|
87
|
+
// raw spawn error string. Anything else (malformed JSON, a non-zero
|
|
88
|
+
// exit for another reason, a timeout) is a genuine, unexpected failure
|
|
89
|
+
// and stays a diagnostic.
|
|
90
|
+
if (err?.code !== "ENOENT") {
|
|
91
|
+
diagnostics.push(`codex mcp list --json failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
92
|
+
}
|
|
61
93
|
}
|
|
62
94
|
const mcpServers = mcpEntries.map((entry) => ({
|
|
63
95
|
name: entry.name,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kimi Code probe. Kimi 2.x stores user MCP declarations in
|
|
3
|
+
* `~/.kimi-code/mcp.json`, user Skills in `~/.kimi-code/skills`, and global
|
|
4
|
+
* instructions in `~/.kimi-code/AGENTS.md`. Kimi also discovers the generic
|
|
5
|
+
* `~/.agents/skills` root; it is reported so doctor can observe it, while the
|
|
6
|
+
* Runtime-only launcher can explicitly isolate it later.
|
|
7
|
+
*/
|
|
8
|
+
import type { AgentSnapshot } from "../core/types.js";
|
|
9
|
+
export interface ProbeOptions {
|
|
10
|
+
probeMcp?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare function probe(homeDir?: string, opts?: ProbeOptions): Promise<AgentSnapshot>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kimi Code probe. Kimi 2.x stores user MCP declarations in
|
|
3
|
+
* `~/.kimi-code/mcp.json`, user Skills in `~/.kimi-code/skills`, and global
|
|
4
|
+
* instructions in `~/.kimi-code/AGENTS.md`. Kimi also discovers the generic
|
|
5
|
+
* `~/.agents/skills` root; it is reported so doctor can observe it, while the
|
|
6
|
+
* Runtime-only launcher can explicitly isolate it later.
|
|
7
|
+
*/
|
|
8
|
+
import { execFileSync } from "node:child_process";
|
|
9
|
+
import { homedir } from "node:os";
|
|
10
|
+
import { join } from "node:path";
|
|
11
|
+
import { probeMcpServer } from "../lib/mcpProbe.js";
|
|
12
|
+
import { pathRef, readJsonFile, resolveEnvRefs, scanSkillRoot } from "../lib/probeCommon.js";
|
|
13
|
+
function kimiEnv(homeDir) {
|
|
14
|
+
return { ...process.env, HOME: homeDir, KIMI_CODE_HOME: join(homeDir, ".kimi-code") };
|
|
15
|
+
}
|
|
16
|
+
export async function probe(homeDir = homedir(), opts = {}) {
|
|
17
|
+
const root = join(homeDir, ".kimi-code");
|
|
18
|
+
const mcpPath = join(root, "mcp.json");
|
|
19
|
+
const mcpConfig = readJsonFile(mcpPath);
|
|
20
|
+
const kimiRoot = pathRef(root);
|
|
21
|
+
if (kimiRoot === undefined) {
|
|
22
|
+
return { agent: "kimi-code", present: false, skillRoots: [], mcpServers: [], diagnostics: [] };
|
|
23
|
+
}
|
|
24
|
+
let version;
|
|
25
|
+
try {
|
|
26
|
+
version = execFileSync("kimi", ["--version"], { encoding: "utf-8", timeout: 5_000, env: kimiEnv(homeDir) }).trim();
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
// A config-only fixture remains probeable without a binary on PATH.
|
|
30
|
+
}
|
|
31
|
+
const mcpServers = Object.entries(mcpConfig?.mcpServers ?? {}).map(([name, def]) => ({
|
|
32
|
+
name,
|
|
33
|
+
transport: def.url ? (def.transport === "sse" ? "sse" : "http") : "stdio",
|
|
34
|
+
}));
|
|
35
|
+
if (opts.probeMcp) {
|
|
36
|
+
await Promise.all(Object.entries(mcpConfig?.mcpServers ?? {}).map(async ([name, def], index) => {
|
|
37
|
+
if (def.url || !def.command)
|
|
38
|
+
return;
|
|
39
|
+
mcpServers[index].probe = await probeMcpServer({ transport: "stdio", command: def.command, args: def.args }, resolveEnvRefs(def.env, kimiEnv(homeDir)));
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
const skillRoots = [
|
|
43
|
+
scanSkillRoot(join(root, "skills")),
|
|
44
|
+
scanSkillRoot(join(homeDir, ".agents", "skills")),
|
|
45
|
+
].filter((entry) => entry !== undefined);
|
|
46
|
+
return {
|
|
47
|
+
agent: "kimi-code",
|
|
48
|
+
present: true,
|
|
49
|
+
version,
|
|
50
|
+
skillRoots,
|
|
51
|
+
mcpServers,
|
|
52
|
+
instructionsFile: pathRef(join(root, "AGENTS.md")),
|
|
53
|
+
diagnostics: [],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZCode probe and profile selection.
|
|
3
|
+
*
|
|
4
|
+
* ZCode has two public configuration layouts in circulation. The official
|
|
5
|
+
* source/distribution reads ~/.zcode/cli/config.json, while the installed
|
|
6
|
+
* zcode-app-cli compatibility distribution keeps runtime settings (including
|
|
7
|
+
* mcp.servers) in ~/.zcode/cli/setting.json. We select one profile before any
|
|
8
|
+
* adapter plans a write; writing both would make ZCode's native precedence
|
|
9
|
+
* ambiguous and can hide a managed MCP entry.
|
|
10
|
+
*/
|
|
11
|
+
import type { AgentSnapshot } from "../core/types.js";
|
|
12
|
+
export type ZcodeProfileKind = "community-cli" | "official" | "configuration-only";
|
|
13
|
+
export interface ZcodeProfile {
|
|
14
|
+
kind: ZcodeProfileKind;
|
|
15
|
+
configPath: string;
|
|
16
|
+
executable?: string;
|
|
17
|
+
executableVersion?: string;
|
|
18
|
+
supportsExecution: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ProbeOptions {
|
|
21
|
+
probeMcp?: boolean;
|
|
22
|
+
env?: NodeJS.ProcessEnv;
|
|
23
|
+
}
|
|
24
|
+
export declare function zcodeEnv(homeDir: string, env?: NodeJS.ProcessEnv): NodeJS.ProcessEnv;
|
|
25
|
+
export declare function selectZcodeProfile(homeDir: string, facts?: {
|
|
26
|
+
command?: string;
|
|
27
|
+
version?: string;
|
|
28
|
+
help?: string;
|
|
29
|
+
outputFormatSupported?: boolean;
|
|
30
|
+
}): ZcodeProfile | undefined;
|
|
31
|
+
export declare function resolveZcodeProfile(homeDir?: string, env?: NodeJS.ProcessEnv): ZcodeProfile | undefined;
|
|
32
|
+
export declare function probe(homeDir?: string, opts?: ProbeOptions): Promise<AgentSnapshot>;
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZCode probe and profile selection.
|
|
3
|
+
*
|
|
4
|
+
* ZCode has two public configuration layouts in circulation. The official
|
|
5
|
+
* source/distribution reads ~/.zcode/cli/config.json, while the installed
|
|
6
|
+
* zcode-app-cli compatibility distribution keeps runtime settings (including
|
|
7
|
+
* mcp.servers) in ~/.zcode/cli/setting.json. We select one profile before any
|
|
8
|
+
* adapter plans a write; writing both would make ZCode's native precedence
|
|
9
|
+
* ambiguous and can hide a managed MCP entry.
|
|
10
|
+
*/
|
|
11
|
+
import { execFileSync } from "node:child_process";
|
|
12
|
+
import { existsSync } from "node:fs";
|
|
13
|
+
import { homedir } from "node:os";
|
|
14
|
+
import { delimiter, join } from "node:path";
|
|
15
|
+
import { probeMcpServer } from "../lib/mcpProbe.js";
|
|
16
|
+
import { pathRef, readJsonFile, resolveEnvRefs, scanSkillRoot } from "../lib/probeCommon.js";
|
|
17
|
+
export function zcodeEnv(homeDir, env = process.env) {
|
|
18
|
+
// A Node host can inherit Volta's selected Node binary without inheriting
|
|
19
|
+
// Volta's shim directory in PATH. Keep the user's explicit PATH order, but
|
|
20
|
+
// add the documented Volta bin location when necessary so `zcode` resolves
|
|
21
|
+
// the same way it does in their interactive terminal.
|
|
22
|
+
const voltaBin = env.VOLTA_HOME ? join(env.VOLTA_HOME, "bin") : undefined;
|
|
23
|
+
const pathParts = (env.PATH ?? "").split(delimiter).filter(Boolean);
|
|
24
|
+
if (voltaBin && !pathParts.includes(voltaBin))
|
|
25
|
+
pathParts.unshift(voltaBin);
|
|
26
|
+
return { ...env, HOME: homeDir, ...(pathParts.length ? { PATH: pathParts.join(delimiter) } : {}) };
|
|
27
|
+
}
|
|
28
|
+
function configPaths(homeDir) {
|
|
29
|
+
const root = join(homeDir, ".zcode");
|
|
30
|
+
return {
|
|
31
|
+
root,
|
|
32
|
+
community: join(root, "cli", "setting.json"),
|
|
33
|
+
official: join(root, "cli", "config.json"),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
function publicCommand(env) {
|
|
37
|
+
return env.TRELLIS_ZCODE_BIN?.trim() || "zcode";
|
|
38
|
+
}
|
|
39
|
+
function cliFacts(homeDir, env) {
|
|
40
|
+
const command = publicCommand(env);
|
|
41
|
+
const childEnv = zcodeEnv(homeDir, env);
|
|
42
|
+
try {
|
|
43
|
+
const version = execFileSync(command, ["version"], { encoding: "utf-8", timeout: 5_000, env: childEnv }).trim();
|
|
44
|
+
let help;
|
|
45
|
+
let outputFormatSupported = false;
|
|
46
|
+
try {
|
|
47
|
+
help = execFileSync(command, ["--help"], { encoding: "utf-8", timeout: 5_000, env: childEnv });
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
// A version identity still permits a configuration-only profile.
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
// Some zcode-app-cli builds accept --output-format but omit it from
|
|
54
|
+
// their generated help text. --version never starts a model turn, so
|
|
55
|
+
// it is a safe capability probe for the public argument contract.
|
|
56
|
+
execFileSync(command, ["--output-format", "stream-json", "--version"], { encoding: "utf-8", timeout: 5_000, env: childEnv });
|
|
57
|
+
outputFormatSupported = true;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Keep the false value; callers then leave execution disabled.
|
|
61
|
+
}
|
|
62
|
+
return { command, version, ...(help ? { help } : {}), outputFormatSupported };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return {};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
export function selectZcodeProfile(homeDir, facts = {}) {
|
|
69
|
+
const paths = configPaths(homeDir);
|
|
70
|
+
const version = facts.version ?? "";
|
|
71
|
+
const supportsExecution = Boolean(facts.command
|
|
72
|
+
&& facts.help?.includes("--prompt")
|
|
73
|
+
&& facts.help.includes("--resume")
|
|
74
|
+
&& (facts.help.includes("--output-format") || facts.outputFormatSupported === true));
|
|
75
|
+
if (/^zcode-app-cli\b/im.test(version) || (existsSync(paths.community) && !existsSync(paths.official))) {
|
|
76
|
+
return {
|
|
77
|
+
kind: "community-cli",
|
|
78
|
+
configPath: paths.community,
|
|
79
|
+
...(facts.command ? { executable: facts.command } : {}),
|
|
80
|
+
...(facts.version ? { executableVersion: facts.version } : {}),
|
|
81
|
+
supportsExecution,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
if (facts.command || existsSync(paths.official)) {
|
|
85
|
+
return {
|
|
86
|
+
kind: facts.command ? "official" : "configuration-only",
|
|
87
|
+
configPath: paths.official,
|
|
88
|
+
...(facts.command ? { executable: facts.command } : {}),
|
|
89
|
+
...(facts.version ? { executableVersion: facts.version } : {}),
|
|
90
|
+
supportsExecution,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (existsSync(paths.root)) {
|
|
94
|
+
return { kind: "configuration-only", configPath: paths.official, supportsExecution: false };
|
|
95
|
+
}
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
export function resolveZcodeProfile(homeDir = homedir(), env = process.env) {
|
|
99
|
+
// A public `zcode` binary is installed system-wide, whereas probes run
|
|
100
|
+
// against an explicit home directory. Do not let the real machine's CLI
|
|
101
|
+
// make an empty sandbox home appear to have ZCode installed; the profile
|
|
102
|
+
// must have local `.zcode` state before any executable is queried.
|
|
103
|
+
if (!existsSync(configPaths(homeDir).root))
|
|
104
|
+
return undefined;
|
|
105
|
+
return selectZcodeProfile(homeDir, cliFacts(homeDir, env));
|
|
106
|
+
}
|
|
107
|
+
export async function probe(homeDir = homedir(), opts = {}) {
|
|
108
|
+
const env = opts.env ?? process.env;
|
|
109
|
+
const profile = resolveZcodeProfile(homeDir, env);
|
|
110
|
+
if (!profile)
|
|
111
|
+
return { agent: "zcode", present: false, skillRoots: [], mcpServers: [], diagnostics: [] };
|
|
112
|
+
const config = readJsonFile(profile.configPath);
|
|
113
|
+
const mcpServers = Object.entries(config?.mcp?.servers ?? {}).map(([name, def]) => ({
|
|
114
|
+
name,
|
|
115
|
+
transport: def.url ? (def.type === "sse" ? "sse" : "http") : "stdio",
|
|
116
|
+
}));
|
|
117
|
+
if (opts.probeMcp) {
|
|
118
|
+
await Promise.all(Object.entries(config?.mcp?.servers ?? {}).map(async ([name, def], index) => {
|
|
119
|
+
if (def.url || !def.command)
|
|
120
|
+
return;
|
|
121
|
+
mcpServers[index].probe = await probeMcpServer({ transport: "stdio", command: def.command, args: def.args }, resolveEnvRefs(def.env, zcodeEnv(homeDir, env)));
|
|
122
|
+
}));
|
|
123
|
+
}
|
|
124
|
+
const skillRoots = [
|
|
125
|
+
scanSkillRoot(join(homeDir, ".zcode", "skills")),
|
|
126
|
+
scanSkillRoot(join(homeDir, ".agents", "skills")),
|
|
127
|
+
].filter((root) => root !== undefined);
|
|
128
|
+
const diagnostics = [];
|
|
129
|
+
if (!profile.supportsExecution)
|
|
130
|
+
diagnostics.push("ZCode public CLI execution is unavailable; configuration-only management is supported");
|
|
131
|
+
return {
|
|
132
|
+
agent: "zcode",
|
|
133
|
+
present: true,
|
|
134
|
+
...(profile.executableVersion ? { version: profile.executableVersion } : {}),
|
|
135
|
+
skillRoots,
|
|
136
|
+
mcpServers,
|
|
137
|
+
instructionsFile: pathRef(join(homeDir, ".zcode", "AGENTS.md")),
|
|
138
|
+
diagnostics,
|
|
139
|
+
};
|
|
140
|
+
}
|
package/dist/sdk.d.ts
CHANGED
|
@@ -11,4 +11,4 @@
|
|
|
11
11
|
*/
|
|
12
12
|
export { loadCanonicalSource } from "./core/canonical.js";
|
|
13
13
|
export { ALL_AGENTS, resolveScope } from "./core/types.js";
|
|
14
|
-
export type { AgentId, AgentProfile, CanonicalSource, HubConfig, McpConfig, McpServerDef, MemoryEntry, Scope, SecretsPolicy, SkillRef, Transport, } from "./core/types.js";
|
|
14
|
+
export type { AgentId, AgentProfile, CapabilityDelivery, CanonicalSource, HubConfig, McpConfig, McpRuntimeConfig, McpServerDef, MemoryEntry, Scope, SecretsPolicy, SkillRef, Transport, } from "./core/types.js";
|