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
|
@@ -5,13 +5,15 @@
|
|
|
5
5
|
* plan-then-apply split every adapter already uses.
|
|
6
6
|
*/
|
|
7
7
|
import type { AgentId, McpServerDef } from "../core/types.js";
|
|
8
|
+
import type { BackupSession } from "../lib/backup.js";
|
|
9
|
+
import { type NativeMemoryCandidate, type NativeMemoryDiscovery } from "../lib/nativeMemory.js";
|
|
8
10
|
export type MigrateAction = "create" | "skip-symlink" | "skip-case-broken" | "skip-unsupported" | "already-migrated" | "reclassify" | "conflict" | "extract-secret";
|
|
9
11
|
/** Internal kind naming, unchanged since before `--only` existed
|
|
10
12
|
* (trellis-migrate-category-selection design.md D2) — the CLI-facing
|
|
11
13
|
* flag value is the plural `"skills"`, mapped to this singular `"skill"`
|
|
12
14
|
* in `runMigrate`, not renamed here to avoid touching every existing
|
|
13
15
|
* `MigratePlanItem.kind` comparison for no functional reason. */
|
|
14
|
-
export type MigrateKind = "skill" | "instructions" | "mcp";
|
|
16
|
+
export type MigrateKind = "skill" | "instructions" | "mcp" | "memory";
|
|
15
17
|
export interface MigratePlanItem {
|
|
16
18
|
kind: MigrateKind;
|
|
17
19
|
name: string;
|
|
@@ -45,11 +47,19 @@ export interface MigratePlanItem {
|
|
|
45
47
|
* already-migrated server extracted before this naming scheme existed,
|
|
46
48
|
* which never reaches this action at all (already-migrated instead). */
|
|
47
49
|
extractSourceKey?: string;
|
|
50
|
+
/** Memory migration only: source is re-read at apply time and the target
|
|
51
|
+
* path is canonical, so the plan never serializes the real body. */
|
|
52
|
+
memorySourcePath?: string;
|
|
53
|
+
memorySourceId?: string;
|
|
54
|
+
memoryTargetPath?: string;
|
|
48
55
|
}
|
|
49
56
|
export interface MigratePlan {
|
|
50
57
|
agent: AgentId;
|
|
51
58
|
present: boolean;
|
|
52
59
|
items: MigratePlanItem[];
|
|
60
|
+
memoryDiscovery?: Omit<NativeMemoryDiscovery, "candidates"> & {
|
|
61
|
+
candidates: Array<Omit<NativeMemoryCandidate, "content">>;
|
|
62
|
+
};
|
|
53
63
|
}
|
|
54
64
|
/**
|
|
55
65
|
* True when `existing` and `def` differ ONLY in which of `env`/
|
|
@@ -72,14 +82,15 @@ export declare function isSafeReclassification(existing: McpServerDef, def: McpS
|
|
|
72
82
|
* conflict. Omitting `only` (or passing both kinds) is exactly today's
|
|
73
83
|
* behavior.
|
|
74
84
|
*/
|
|
75
|
-
export declare function collectMigratePlan(agent: AgentId, homeDir?: string, only?: readonly MigrateKind[]): Promise<MigratePlan>;
|
|
76
|
-
export declare function applyMigratePlan(plan: MigratePlan, homeDir?: string): void;
|
|
85
|
+
export declare function collectMigratePlan(agent: AgentId, homeDir?: string, only?: readonly MigrateKind[], workspaceDir?: string): Promise<MigratePlan>;
|
|
86
|
+
export declare function applyMigratePlan(plan: MigratePlan, homeDir?: string, backup?: BackupSession): void;
|
|
77
87
|
/** CLI-facing spelling: `"skills"` (plural — a run usually touches more
|
|
78
|
-
* than one), `"instructions"` (already singular-shaped),
|
|
88
|
+
* than one), `"instructions"` (already singular-shaped), `"mcp"`, or
|
|
89
|
+
* `"memory"`
|
|
79
90
|
* (already the CLI's own convention, matching `trellis mcp`'s own
|
|
80
91
|
* command name). Mapped to `MigrateKind` in `runMigrate`, the one place
|
|
81
92
|
* this translation lives. */
|
|
82
|
-
export type MigrateOnlyValue = "skills" | "instructions" | "mcp";
|
|
93
|
+
export type MigrateOnlyValue = "skills" | "instructions" | "mcp" | "memory";
|
|
83
94
|
export interface RunMigrateOptions {
|
|
84
95
|
from?: string;
|
|
85
96
|
/** Restricts the run to one category (`"skills"`, `"instructions"`, or
|
package/dist/commands/migrate.js
CHANGED
|
@@ -4,21 +4,24 @@
|
|
|
4
4
|
* Pure `collectMigratePlan` / effectful `applyMigratePlan`, same
|
|
5
5
|
* plan-then-apply split every adapter already uses.
|
|
6
6
|
*/
|
|
7
|
-
import { cpSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
7
|
+
import { cpSync, existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
8
8
|
import { homedir } from "node:os";
|
|
9
|
-
import { join } from "node:path";
|
|
9
|
+
import { dirname, join } from "node:path";
|
|
10
10
|
import * as claudeCodeProbe from "../probes/claude-code.js";
|
|
11
11
|
import * as codexProbe from "../probes/codex.js";
|
|
12
12
|
import * as kiroProbe from "../probes/kiro.js";
|
|
13
13
|
import * as piProbe from "../probes/pi.js";
|
|
14
|
+
import * as kimiCodeProbe from "../probes/kimi-code.js";
|
|
15
|
+
import * as zcodeProbe from "../probes/zcode.js";
|
|
14
16
|
import { AGENTS_MD_TEMPLATE } from "./init.js";
|
|
15
17
|
import { decideDirImport } from "../lib/dirEquals.js";
|
|
16
18
|
import { deepEqual } from "../lib/deepEqual.js";
|
|
17
|
-
import { readClaudeCodeMcpDefs, readCodexMcpDefs, readKiroMcpDefs, resolvedEnvTextMap } from "../lib/mcpMigrateRead.js";
|
|
19
|
+
import { readClaudeCodeMcpDefs, readCodexMcpDefs, readKiroMcpDefs, readKimiCodeMcpDefs, readZcodeMcpDefs, resolvedEnvTextMap } from "../lib/mcpMigrateRead.js";
|
|
18
20
|
import { parseDotenv, writeLocalSecretValue } from "../lib/secretEnv.js";
|
|
19
21
|
import { findLiteralSecret } from "../adapters/mcpPlan.js";
|
|
20
22
|
import { ensureGitignoreEntry, ensureShellEnvSource, loadCanonicalSource, upsertServerYaml, writeSecretsPolicyExtraction } from "../core/canonical.js";
|
|
21
23
|
import { ALL_AGENTS } from "../core/types.js";
|
|
24
|
+
import { discoverNativeMemory, MAX_NATIVE_MEMORY_BYTES, renderNativeMemory } from "../lib/nativeMemory.js";
|
|
22
25
|
/** Where a `staticEnv` literal secret's real value goes when
|
|
23
26
|
* `secrets.policy.yaml` doesn't already have its own `env_file`
|
|
24
27
|
* (trellis-migrate-extract-static-env-secrets design.md D3) — a sibling
|
|
@@ -48,6 +51,8 @@ const PROBES = {
|
|
|
48
51
|
codex: (homeDir) => codexProbe.probe(homeDir),
|
|
49
52
|
kiro: (homeDir) => kiroProbe.probe(homeDir),
|
|
50
53
|
pi: (homeDir) => piProbe.probe(homeDir),
|
|
54
|
+
"kimi-code": (homeDir) => kimiCodeProbe.probe(homeDir),
|
|
55
|
+
zcode: (homeDir) => zcodeProbe.probe(homeDir),
|
|
51
56
|
};
|
|
52
57
|
/** pi has no static MCP config to read at all (roadmap.md P14/
|
|
53
58
|
* trellis-migrate-mcp-servers) — deliberately absent, not an oversight;
|
|
@@ -56,6 +61,8 @@ const MCP_READERS = {
|
|
|
56
61
|
"claude-code": readClaudeCodeMcpDefs,
|
|
57
62
|
kiro: readKiroMcpDefs,
|
|
58
63
|
codex: readCodexMcpDefs,
|
|
64
|
+
"kimi-code": readKimiCodeMcpDefs,
|
|
65
|
+
zcode: readZcodeMcpDefs,
|
|
59
66
|
};
|
|
60
67
|
function planSkill(name, sourceDir, isSymlink, caseCorrect, canonicalDir) {
|
|
61
68
|
if (isSymlink) {
|
|
@@ -116,6 +123,32 @@ function planInstructions(snapshot, canonicalAgentsMd) {
|
|
|
116
123
|
remediation: `compare \`~/.trellis/agents.md\` against ${snapshot.instructionsFile.path} and either merge by hand or delete whichever copy you don't want to keep`,
|
|
117
124
|
};
|
|
118
125
|
}
|
|
126
|
+
function planNativeMemoryCandidate(candidate, homeDir) {
|
|
127
|
+
const targetPath = join(homeDir, ".trellis", "memories", `${candidate.targetName}.md`);
|
|
128
|
+
const rendered = renderNativeMemory(candidate);
|
|
129
|
+
if (!existsSync(targetPath)) {
|
|
130
|
+
return {
|
|
131
|
+
kind: "memory",
|
|
132
|
+
name: candidate.targetName,
|
|
133
|
+
action: "create",
|
|
134
|
+
detail: `will import ${candidate.displayName} from ${candidate.sourceAgent} native memory`,
|
|
135
|
+
memorySourcePath: candidate.sourcePath,
|
|
136
|
+
memorySourceId: candidate.sourceId,
|
|
137
|
+
memoryTargetPath: targetPath,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const current = readFileSync(targetPath, "utf8");
|
|
141
|
+
if (current === rendered) {
|
|
142
|
+
return { kind: "memory", name: candidate.targetName, action: "already-migrated", detail: "canonical memory is byte-identical" };
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
kind: "memory",
|
|
146
|
+
name: candidate.targetName,
|
|
147
|
+
action: "conflict",
|
|
148
|
+
detail: `canonical memories/${candidate.targetName}.md already has different content — resolve by hand`,
|
|
149
|
+
remediation: `compare the canonical file with ${candidate.sourcePath} and decide which memory to keep before re-running migration`,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
119
152
|
/**
|
|
120
153
|
* True when `existing` and `def` differ ONLY in which of `env`/
|
|
121
154
|
* `envAliases`/`staticEnv` an env value is filed under, while every
|
|
@@ -273,13 +306,14 @@ function planMcpServer(name, def, existing, homeDir, policy) {
|
|
|
273
306
|
* conflict. Omitting `only` (or passing both kinds) is exactly today's
|
|
274
307
|
* behavior.
|
|
275
308
|
*/
|
|
276
|
-
export async function collectMigratePlan(agent, homeDir = homedir(), only) {
|
|
309
|
+
export async function collectMigratePlan(agent, homeDir = homedir(), only, workspaceDir = process.cwd()) {
|
|
277
310
|
const snapshot = await PROBES[agent](homeDir);
|
|
278
311
|
if (!snapshot.present) {
|
|
279
312
|
return { agent, present: false, items: [] };
|
|
280
313
|
}
|
|
281
314
|
const canonicalRoot = join(homeDir, ".trellis");
|
|
282
315
|
const items = [];
|
|
316
|
+
let memoryDiscovery;
|
|
283
317
|
const wants = (kind) => !only || only.includes(kind);
|
|
284
318
|
if (wants("skill")) {
|
|
285
319
|
for (const root of snapshot.skillRoots) {
|
|
@@ -306,7 +340,14 @@ export async function collectMigratePlan(agent, homeDir = homedir(), only) {
|
|
|
306
340
|
}
|
|
307
341
|
}
|
|
308
342
|
}
|
|
309
|
-
|
|
343
|
+
if (wants("memory")) {
|
|
344
|
+
const discovery = discoverNativeMemory(agent, homeDir, workspaceDir);
|
|
345
|
+
memoryDiscovery = { ...discovery, candidates: discovery.candidates.map(({ content: _content, ...safe }) => safe) };
|
|
346
|
+
for (const candidate of discovery.candidates) {
|
|
347
|
+
items.push(planNativeMemoryCandidate(candidate, homeDir));
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return { agent, present: true, items, ...(memoryDiscovery ? { memoryDiscovery } : {}) };
|
|
310
351
|
}
|
|
311
352
|
/**
|
|
312
353
|
* Re-reads the source agent's real MCP entries at apply time to recover
|
|
@@ -319,18 +360,31 @@ export async function collectMigratePlan(agent, homeDir = homedir(), only) {
|
|
|
319
360
|
* written under, design.md D11) are looked up and written under
|
|
320
361
|
* separately — they are not, in general, the same string.
|
|
321
362
|
*/
|
|
322
|
-
function applyStaticEnvExtraction(agent, serverName, sourceKey, varName, targetPath, homeDir) {
|
|
363
|
+
function applyStaticEnvExtraction(agent, serverName, sourceKey, varName, targetPath, homeDir, backup) {
|
|
323
364
|
const reader = MCP_READERS[agent];
|
|
324
365
|
const realValue = reader?.(homeDir).entries.find((e) => e.name === serverName)?.def.staticEnv?.[sourceKey];
|
|
325
366
|
if (realValue === undefined)
|
|
326
367
|
return; // source changed between plan and apply; nothing left to extract
|
|
327
368
|
if (targetPath === defaultLocalSecretsEnvFilePath(homeDir)) {
|
|
328
|
-
ensureGitignoreEntry(join(homeDir, ".trellis", ".gitignore"), "mcp/servers.local.env");
|
|
369
|
+
ensureGitignoreEntry(join(homeDir, ".trellis", ".gitignore"), "mcp/servers.local.env", backup);
|
|
370
|
+
}
|
|
371
|
+
writeLocalSecretValue(targetPath, varName, realValue, backup);
|
|
372
|
+
writeSecretsPolicyExtraction(join(homeDir, ".trellis", "secrets.policy.yaml"), { varName, envFilePath: DEFAULT_LOCAL_SECRETS_ENV_FILE_TILDE }, backup);
|
|
373
|
+
}
|
|
374
|
+
function copyDirectoryThroughBackup(sourceDir, destDir, backup) {
|
|
375
|
+
for (const entry of readdirSync(sourceDir)) {
|
|
376
|
+
const source = join(sourceDir, entry);
|
|
377
|
+
const dest = join(destDir, entry);
|
|
378
|
+
if (statSync(source).isDirectory()) {
|
|
379
|
+
mkdirSync(dest, { recursive: true });
|
|
380
|
+
copyDirectoryThroughBackup(source, dest, backup);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
backup.writeFile(dest, readFileSync(source, "utf-8"));
|
|
384
|
+
}
|
|
329
385
|
}
|
|
330
|
-
writeLocalSecretValue(targetPath, varName, realValue);
|
|
331
|
-
writeSecretsPolicyExtraction(join(homeDir, ".trellis", "secrets.policy.yaml"), { varName, envFilePath: DEFAULT_LOCAL_SECRETS_ENV_FILE_TILDE });
|
|
332
386
|
}
|
|
333
|
-
export function applyMigratePlan(plan, homeDir = homedir()) {
|
|
387
|
+
export function applyMigratePlan(plan, homeDir = homedir(), backup) {
|
|
334
388
|
const canonicalRoot = join(homeDir, ".trellis");
|
|
335
389
|
for (const item of plan.items) {
|
|
336
390
|
if (item.action !== "create" && item.action !== "reclassify" && item.action !== "extract-secret")
|
|
@@ -338,18 +392,35 @@ export function applyMigratePlan(plan, homeDir = homedir()) {
|
|
|
338
392
|
if (item.kind === "skill" && item.sourceDir) {
|
|
339
393
|
const dest = join(canonicalRoot, "skills", item.name);
|
|
340
394
|
mkdirSync(dest, { recursive: true });
|
|
341
|
-
|
|
395
|
+
if (backup)
|
|
396
|
+
copyDirectoryThroughBackup(item.sourceDir, dest, backup);
|
|
397
|
+
else
|
|
398
|
+
cpSync(item.sourceDir, dest, { recursive: true });
|
|
342
399
|
}
|
|
343
400
|
else if (item.kind === "instructions" && item.sourceContent !== undefined) {
|
|
344
401
|
mkdirSync(canonicalRoot, { recursive: true });
|
|
345
|
-
|
|
402
|
+
if (backup)
|
|
403
|
+
backup.writeFile(join(canonicalRoot, "agents.md"), item.sourceContent);
|
|
404
|
+
else
|
|
405
|
+
writeFileSync(join(canonicalRoot, "agents.md"), item.sourceContent);
|
|
346
406
|
}
|
|
347
407
|
else if (item.kind === "mcp" && item.mcpDef) {
|
|
348
|
-
upsertServerYaml(join(canonicalRoot, "mcp", "servers.yaml"), item.name, item.mcpDef);
|
|
408
|
+
upsertServerYaml(join(canonicalRoot, "mcp", "servers.yaml"), item.name, item.mcpDef, backup);
|
|
349
409
|
if (item.action === "extract-secret" && item.extractVarName && item.extractTargetPath && item.extractSourceKey) {
|
|
350
|
-
applyStaticEnvExtraction(plan.agent, item.name, item.extractSourceKey, item.extractVarName, item.extractTargetPath, homeDir);
|
|
410
|
+
applyStaticEnvExtraction(plan.agent, item.name, item.extractSourceKey, item.extractVarName, item.extractTargetPath, homeDir, backup);
|
|
351
411
|
}
|
|
352
412
|
}
|
|
413
|
+
else if (item.kind === "memory" && item.memorySourcePath && item.memorySourceId && item.memoryTargetPath) {
|
|
414
|
+
if (statSync(item.memorySourcePath).size > MAX_NATIVE_MEMORY_BYTES)
|
|
415
|
+
throw new Error(`native memory source exceeds the ${MAX_NATIVE_MEMORY_BYTES}-byte limit: ${item.memorySourcePath}`);
|
|
416
|
+
const content = readFileSync(item.memorySourcePath, "utf8");
|
|
417
|
+
const imported = renderNativeMemory({ sourceAgent: plan.agent, sourceId: item.memorySourceId, content });
|
|
418
|
+
mkdirSync(dirname(item.memoryTargetPath), { recursive: true });
|
|
419
|
+
if (backup)
|
|
420
|
+
backup.writeFile(item.memoryTargetPath, imported);
|
|
421
|
+
else
|
|
422
|
+
writeFileSync(item.memoryTargetPath, imported);
|
|
423
|
+
}
|
|
353
424
|
}
|
|
354
425
|
// Runs every real (non-dry-run) migrate invocation, not just the one that
|
|
355
426
|
// performed a fresh extraction — a machine that already extracted a
|
|
@@ -357,10 +428,10 @@ export function applyMigratePlan(plan, homeDir = homedir()) {
|
|
|
357
428
|
// migrate runs at all, not only on its next brand-new extraction.
|
|
358
429
|
const envFile = loadCanonicalSource(homeDir).secretsPolicy.envFile;
|
|
359
430
|
if (envFile) {
|
|
360
|
-
ensureShellEnvSource(defaultShellRcPath(homeDir), envFile);
|
|
431
|
+
ensureShellEnvSource(defaultShellRcPath(homeDir), envFile, backup);
|
|
361
432
|
}
|
|
362
433
|
}
|
|
363
|
-
const ONLY_VALUES = ["skills", "instructions", "mcp"];
|
|
434
|
+
const ONLY_VALUES = ["skills", "instructions", "mcp", "memory"];
|
|
364
435
|
function isMigrateOnlyValue(value) {
|
|
365
436
|
return ONLY_VALUES.includes(value);
|
|
366
437
|
}
|
|
@@ -369,6 +440,8 @@ function toMigrateKinds(only) {
|
|
|
369
440
|
return ["skill"];
|
|
370
441
|
if (only === "instructions")
|
|
371
442
|
return ["instructions"];
|
|
443
|
+
if (only === "memory")
|
|
444
|
+
return ["memory"];
|
|
372
445
|
return ["mcp"];
|
|
373
446
|
}
|
|
374
447
|
export async function runMigrate(opts = {}) {
|
|
@@ -405,12 +478,15 @@ export async function runMigrate(opts = {}) {
|
|
|
405
478
|
* this formatting (including the empty-plan "nothing to migrate" case). */
|
|
406
479
|
export function printPlan(plan, dryRun) {
|
|
407
480
|
console.log(`${dryRun ? "[dry run] " : ""}migrate --from ${plan.agent}`);
|
|
481
|
+
if (plan.memoryDiscovery && plan.memoryDiscovery.status !== "supported") {
|
|
482
|
+
console.log(` memory source — [${plan.memoryDiscovery.status}] ${plan.memoryDiscovery.detail}`);
|
|
483
|
+
}
|
|
408
484
|
if (plan.items.length === 0) {
|
|
409
485
|
console.log(" nothing to migrate");
|
|
410
486
|
return;
|
|
411
487
|
}
|
|
412
488
|
for (const item of plan.items) {
|
|
413
|
-
const label = item.kind === "skill" ? `skill "${item.name}"` : item.kind === "mcp" ? `mcp server "${item.name}"` : "instructions";
|
|
489
|
+
const label = item.kind === "skill" ? `skill "${item.name}"` : item.kind === "mcp" ? `mcp server "${item.name}"` : item.kind === "memory" ? `memory "${item.name}"` : "instructions";
|
|
414
490
|
console.log(` [${item.action}] ${label} — ${item.detail}`);
|
|
415
491
|
}
|
|
416
492
|
}
|
|
@@ -12,15 +12,39 @@
|
|
|
12
12
|
* new skill-copy, symlink, conflict-detection, or secrets-scanning
|
|
13
13
|
* judgment is made here.
|
|
14
14
|
*/
|
|
15
|
-
import type { AgentId } from "../core/types.js";
|
|
15
|
+
import type { AgentId, McpConfig, McpRouteMode } from "../core/types.js";
|
|
16
|
+
import { type CapabilityInventory } from "../core/capabilitySelection.js";
|
|
17
|
+
import { type NativeMemoryStatus } from "../lib/nativeMemory.js";
|
|
16
18
|
import type { MigrateKind, MigratePlan } from "./migrate.js";
|
|
17
19
|
import type { SyncReport } from "./sync.js";
|
|
18
20
|
import type { McpSyncReport } from "./mcp.js";
|
|
19
21
|
import type { SecretsAuditReport } from "./secretsAudit.js";
|
|
20
22
|
import type { MemorySyncResult } from "./memory.js";
|
|
21
23
|
import type { DoctorReport } from "./doctor.js";
|
|
24
|
+
import type { RollbackReport } from "./rollback.js";
|
|
22
25
|
import type { ConfirmAndInstallOptions } from "../lib/installAgent.js";
|
|
23
26
|
import type { VerdictItem } from "./onboardVerdict.js";
|
|
27
|
+
/**
|
|
28
|
+
* Scores only real source-side content. The recommendation is a hint for a
|
|
29
|
+
* first-time user, never a filter: every candidate remains selectable.
|
|
30
|
+
*/
|
|
31
|
+
export declare function migrationSourceScore(summary: Pick<OnboardAgentSummary, "skillCount" | "mcpServerCount" | "hasRealInstructions">): number;
|
|
32
|
+
export declare function recommendedMigrationSource(summaries: readonly (Pick<OnboardAgentSummary, "agent" | "skillCount" | "mcpServerCount" | "hasRealInstructions">)[]): AgentId | undefined;
|
|
33
|
+
export declare const MCP_ROUTE_OPTIONS: ({
|
|
34
|
+
mode: "gateway";
|
|
35
|
+
label: string;
|
|
36
|
+
} | {
|
|
37
|
+
mode: "direct";
|
|
38
|
+
label: string;
|
|
39
|
+
} | {
|
|
40
|
+
mode: "hub";
|
|
41
|
+
label: string;
|
|
42
|
+
})[];
|
|
43
|
+
export declare function interactiveMcpRouteOptions(hubConfigured: boolean): Array<{
|
|
44
|
+
mode: McpRouteMode;
|
|
45
|
+
label: string;
|
|
46
|
+
disabled?: boolean;
|
|
47
|
+
}>;
|
|
24
48
|
export interface OnboardAgentSummary {
|
|
25
49
|
agent: AgentId;
|
|
26
50
|
present: boolean;
|
|
@@ -37,8 +61,13 @@ export interface OnboardAgentSummary {
|
|
|
37
61
|
* memory). 0 for pi, which has no MCP reader at all — not a gap here,
|
|
38
62
|
* the same fact `migrate.ts` already establishes. */
|
|
39
63
|
mcpServerCount: number;
|
|
64
|
+
mcpServerNames: string[];
|
|
65
|
+
nativeMemoryStatus: NativeMemoryStatus;
|
|
66
|
+
nativeMemoryCount: number;
|
|
67
|
+
nativeMemoryNames: string[];
|
|
68
|
+
nativeMemoryDetail: string;
|
|
40
69
|
}
|
|
41
|
-
export declare function collectOnboardSummary(homeDir?: string): Promise<OnboardAgentSummary[]>;
|
|
70
|
+
export declare function collectOnboardSummary(homeDir?: string, workspaceDir?: string): Promise<OnboardAgentSummary[]>;
|
|
42
71
|
export interface RunOnboardOptions {
|
|
43
72
|
/** Non-interactive migration-source choice. */
|
|
44
73
|
agent?: string;
|
|
@@ -60,10 +89,19 @@ export interface RunOnboardOptions {
|
|
|
60
89
|
* Omitted leaves whatever's already configured untouched — same
|
|
61
90
|
* no-prompt posture as `mcpMode` (design.md D12). */
|
|
62
91
|
memory?: string;
|
|
92
|
+
/** Non-interactive native-source memory migration toggle: `"on"` or
|
|
93
|
+
* `"off"`. Omitted preserves the current state and prompts only when
|
|
94
|
+
* supported source candidates are available in a real terminal. */
|
|
95
|
+
memoryMigrate?: string;
|
|
96
|
+
/** Optional YAML/JSON item-level capability selection for automation. */
|
|
97
|
+
selectionFile?: string;
|
|
63
98
|
dryRun?: boolean;
|
|
64
99
|
json?: boolean;
|
|
65
100
|
/** Defaults to the real `~`; overridable for tests only. */
|
|
66
101
|
homeDir?: string;
|
|
102
|
+
/** Defaults to the current working directory; controls project-scoped
|
|
103
|
+
* native-memory discovery and is overridable for tests. */
|
|
104
|
+
workspaceDir?: string;
|
|
67
105
|
/** Test-only: overrides the real `process.stdin.isTTY` check so the
|
|
68
106
|
* interactive-vs-refuse branch is exercisable without a real terminal. */
|
|
69
107
|
isTTY?: boolean;
|
|
@@ -84,6 +122,13 @@ export interface RunOnboardOptions {
|
|
|
84
122
|
* (design.md D9). `true` means "apply for real", matching what
|
|
85
123
|
* accepting the real picker's "Yes, apply now" option means. */
|
|
86
124
|
promptToApply?: () => Promise<boolean>;
|
|
125
|
+
/** Test-only: replaces the real mode-transition confirmation. */
|
|
126
|
+
promptForModeChange?: (previous: "direct" | "hub" | "gateway", next: "direct" | "hub" | "gateway", agents: readonly AgentId[]) => Promise<boolean>;
|
|
127
|
+
/** Test-only: replaces the interactive shared-Memory choice. `keep` leaves
|
|
128
|
+
* the existing state untouched; the real picker puts that choice first. */
|
|
129
|
+
promptForMemory?: (current: "on" | "off") => Promise<"keep" | "on" | "off">;
|
|
130
|
+
/** Test-only: replaces the interactive native-memory migration choice. */
|
|
131
|
+
promptForMemoryMigration?: (source: AgentId, count: number) => Promise<"keep" | "on" | "off">;
|
|
87
132
|
/** Test-only: injected into every `confirmAndInstall` call for a
|
|
88
133
|
* selected, not-yet-present agent. Never a real terminal prompt or a
|
|
89
134
|
* real `npm install` in a unit test. */
|
|
@@ -96,6 +141,23 @@ export interface OnboardInstallResult {
|
|
|
96
141
|
}
|
|
97
142
|
export interface OnboardResult {
|
|
98
143
|
summary: OnboardAgentSummary[];
|
|
144
|
+
inventory?: CapabilityInventory;
|
|
145
|
+
capabilitySummary?: {
|
|
146
|
+
awarenessSkill: boolean;
|
|
147
|
+
globalInstructions: {
|
|
148
|
+
available: boolean;
|
|
149
|
+
native: boolean;
|
|
150
|
+
runtimeReadable: boolean;
|
|
151
|
+
};
|
|
152
|
+
skills: number;
|
|
153
|
+
memories: number;
|
|
154
|
+
mcpServers: number;
|
|
155
|
+
};
|
|
156
|
+
managedAgentRuntime?: Array<{
|
|
157
|
+
agent: AgentId;
|
|
158
|
+
delivery: "native" | "mcp" | "both";
|
|
159
|
+
route: "direct" | "gateway" | "hub";
|
|
160
|
+
}>;
|
|
99
161
|
source?: AgentId;
|
|
100
162
|
sourceReason?: "auto-selected" | "flag" | "prompt";
|
|
101
163
|
/** The full managed set this run acted against — the union of whatever
|
|
@@ -131,6 +193,8 @@ export interface OnboardResult {
|
|
|
131
193
|
* inconsistent across agents independent of this run.
|
|
132
194
|
*/
|
|
133
195
|
doctorReport?: DoctorReport;
|
|
196
|
+
/** Present when a blocking real run was automatically restored. */
|
|
197
|
+
rollback?: RollbackReport;
|
|
134
198
|
/**
|
|
135
199
|
* The resolved MCP mode after this run (trellis-onboard-mcp-mode
|
|
136
200
|
* design.md D7) — `current` reflects canonical's state whether or not
|
|
@@ -165,6 +229,14 @@ export interface OnboardResult {
|
|
|
165
229
|
*/
|
|
166
230
|
verdict: VerdictItem[];
|
|
167
231
|
}
|
|
232
|
+
/** Converges explicit per-Agent route lists with the shared Memory toggle.
|
|
233
|
+
* Legacy/top-level routes without a `servers` list already expose every
|
|
234
|
+
* eligible server and need no rewrite. Hub routes are intentionally opaque:
|
|
235
|
+
* the external hub owns its upstream set. */
|
|
236
|
+
export declare function mergeMemoryIntoExplicitRoutes(mcp: McpConfig, managedAgents: readonly AgentId[], memoryEnabled: boolean): {
|
|
237
|
+
mcp: McpConfig;
|
|
238
|
+
changed: boolean;
|
|
239
|
+
};
|
|
168
240
|
export declare function collectOnboardPlan(opts?: RunOnboardOptions): Promise<OnboardResult>;
|
|
169
241
|
export declare function runOnboard(opts?: RunOnboardOptions): Promise<{
|
|
170
242
|
exitCode: number;
|