vgxness 1.20.5 → 1.20.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/claude/agent-renderer.js +82 -0
- package/dist/{mcp → adapters/claude/install}/claude-code-agent-config.js +64 -9
- package/dist/{mcp → adapters/claude/install}/claude-code-config.js +28 -6
- package/dist/{mcp → adapters/claude/install}/claude-code-project-memory.js +35 -5
- package/dist/{mcp → adapters/claude/install}/claude-code-scope.js +12 -3
- package/dist/{mcp → adapters/claude/install}/claude-code-user-config.js +26 -5
- package/dist/{mcp → adapters/claude/install}/claude-code-user-memory.js +47 -7
- package/dist/{mcp → adapters/claude/install}/client-install-claude-code-contract.js +45 -8
- package/dist/{mcp → adapters/claude/install}/client-install-claude-code.js +98 -14
- package/dist/adapters/json/agent-renderer.js +104 -0
- package/dist/adapters/opencode/agent-renderer.js +113 -0
- package/dist/{mcp → adapters/opencode/install}/client-install-opencode-contract.js +2 -2
- package/dist/{mcp → adapters/opencode/install}/client-install-opencode.js +1 -1
- package/dist/{mcp → adapters/opencode/install}/opencode-default-agent-config.js +2 -2
- package/dist/{mcp → adapters/opencode/install}/opencode-handoff-preview.js +60 -7
- package/dist/{mcp → adapters/opencode/install}/opencode-visibility.js +1 -1
- package/dist/adapters/provider-renderer.js +6 -0
- package/dist/agents/agent-activation-service.js +1 -263
- package/dist/agents/agent-lookup-contexts.js +1 -28
- package/dist/agents/agent-registry-service.js +1 -81
- package/dist/agents/agent-resolver.js +1 -287
- package/dist/agents/agent-seed-service.js +1 -157
- package/dist/agents/agent-seed-upgrade-service.js +1 -231
- package/dist/agents/agent-selector-resolver.js +1 -28
- package/dist/agents/boot-upgrade.js +1 -59
- package/dist/agents/canonical-agent-manifest.js +1 -246
- package/dist/agents/canonical-agent-projection.js +1 -236
- package/dist/agents/manager-profile-overlay-service.js +1 -60
- package/dist/agents/profile-model-routing.js +1 -30
- package/dist/agents/renderers/claude-renderer.js +1 -82
- package/dist/agents/renderers/index.js +1 -14
- package/dist/agents/renderers/json-renderer.js +1 -104
- package/dist/agents/renderers/opencode-renderer.js +1 -113
- package/dist/agents/renderers/provider-adapter.js +1 -6
- package/dist/agents/repositories/agent-seed-history.js +1 -128
- package/dist/agents/repositories/agents.js +1 -200
- package/dist/agents/repositories/manager-profile-overlays.js +1 -90
- package/dist/agents/schema.js +1 -1
- package/dist/application/agents/agent-activation-service.js +261 -0
- package/dist/application/agents/agent-lookup-contexts.js +28 -0
- package/dist/application/agents/agent-registry-service.js +81 -0
- package/dist/application/agents/agent-resolver.js +287 -0
- package/dist/application/agents/agent-seed-service.js +157 -0
- package/dist/application/agents/agent-seed-upgrade-service.js +231 -0
- package/dist/application/agents/agent-selector-resolver.js +28 -0
- package/dist/application/agents/boot-upgrade.js +59 -0
- package/dist/application/agents/canonical-agent-projection.js +236 -0
- package/dist/application/agents/manager-profile-overlay-service.js +68 -0
- package/dist/application/agents/profile-model-routing.js +30 -0
- package/dist/application/agents/renderers/claude-renderer.js +1 -0
- package/dist/application/agents/renderers/index.js +14 -0
- package/dist/application/agents/renderers/json-renderer.js +1 -0
- package/dist/application/agents/renderers/opencode-renderer.js +1 -0
- package/dist/application/agents/renderers/provider-adapter.js +1 -0
- package/dist/application/memory/active-work-preview.js +75 -0
- package/dist/application/memory/agent-memory-capture-service.js +498 -0
- package/dist/application/memory/import/dry-run-planner.js +58 -0
- package/dist/application/memory/import/index.js +3 -0
- package/dist/application/memory/import/observation-writer.js +226 -0
- package/dist/application/memory/import/package.js +179 -0
- package/dist/application/memory/memory-service.js +202 -0
- package/dist/application/memory/search.js +11 -0
- package/dist/{mcp → application/provider-setup}/provider-change-plan.js +74 -13
- package/dist/{mcp → application/provider-setup}/provider-doctor.js +201 -31
- package/dist/{mcp → application/provider-setup}/provider-health-types.js +1 -1
- package/dist/{mcp → application/provider-setup}/provider-status.js +170 -33
- package/dist/application/runs/execution-planning.js +180 -0
- package/dist/application/runs/operation-execution.js +1 -0
- package/dist/application/runs/operation-retry.js +129 -0
- package/dist/application/runs/resume-after-approval-result.js +88 -0
- package/dist/application/runs/run-insights.js +270 -0
- package/dist/application/runs/run-service.js +1480 -0
- package/dist/application/runs/run-snapshot-export-service.js +31 -0
- package/dist/application/runs/sandbox-process-execution.js +244 -0
- package/dist/application/runs/sandbox-worktree-planning.js +59 -0
- package/dist/application/runs/task-scoped-command-grant-service.js +224 -0
- package/dist/application/sdd/artifact-portability-service.js +137 -0
- package/dist/application/sdd/cockpit-read-model.js +195 -0
- package/dist/application/sdd/sdd-continuation-plan.js +265 -0
- package/dist/application/sdd/sdd-workflow-service.js +892 -0
- package/dist/application/skills/boot-seed.js +42 -0
- package/dist/application/skills/personal-skills.js +41 -0
- package/dist/application/skills/skill-export-service.js +34 -0
- package/dist/application/skills/skill-index-service.js +126 -0
- package/dist/application/skills/skill-payload.js +186 -0
- package/dist/application/skills/skill-registry-service.js +648 -0
- package/dist/application/skills/skill-resolver.js +368 -0
- package/dist/application/skills/skill-seed-service.js +242 -0
- package/dist/application/skills/skill-status-service.js +147 -0
- package/dist/cli/bun-bin.js +0 -0
- package/dist/cli/cli-flags.js +1 -387
- package/dist/cli/cli-help.js +1 -173
- package/dist/cli/cli-helpers.js +1 -77
- package/dist/cli/cli-types.js +1 -1
- package/dist/cli/commands/agent-skill-dispatcher.js +1 -700
- package/dist/cli/commands/index.js +1 -9
- package/dist/cli/commands/interactive-entrypoint-dispatcher.js +1 -14
- package/dist/cli/commands/mcp-dispatcher.js +1 -232
- package/dist/cli/commands/memory-sdd-dispatcher.js +1 -367
- package/dist/cli/commands/run-permission-dispatcher.js +1 -455
- package/dist/cli/commands/setup-dispatcher.js +1 -496
- package/dist/cli/commands/status-dispatcher.js +1 -130
- package/dist/cli/commands/verification-dispatcher.js +1 -47
- package/dist/cli/commands/workflow-dispatcher.js +1 -566
- package/dist/cli/dispatcher.js +1 -247
- package/dist/cli/doctor-renderer.js +1 -26
- package/dist/cli/home-tui-app.js +1 -411
- package/dist/cli/home-tui-controller.js +1 -314
- package/dist/cli/mcp-start-path.js +1 -21
- package/dist/cli/product-resume-renderer.js +1 -32
- package/dist/cli/product-status-renderer.js +1 -81
- package/dist/cli/sdd-renderer.js +1 -247
- package/dist/cli/setup-plan-renderer.js +1 -79
- package/dist/cli/setup-status-renderer.js +1 -50
- package/dist/cli/setup-tui-app.js +1 -130
- package/dist/cli/setup-tui-controller.js +1 -89
- package/dist/cli/tui/focus-reducer.js +1 -0
- package/dist/cli/tui/focus-types.js +1 -0
- package/dist/cli/tui/ink/app-shell.js +1 -0
- package/dist/cli/tui/ink/components.js +1 -38
- package/dist/cli/tui/ink/help-overlay.js +1 -0
- package/dist/cli/tui/ink/state-components.js +1 -0
- package/dist/cli/tui/ink/theme.js +1 -36
- package/dist/cli/tui/key-intents.js +1 -0
- package/dist/cli/tui/keymap.js +1 -20
- package/dist/cli/tui/navigation.js +1 -10
- package/dist/cli/tui/screen-registry.js +1 -0
- package/dist/cli/tui/terminal-capabilities.js +1 -12
- package/dist/cli/tui/tui-types.js +1 -1
- package/dist/cli/tui/visual/badges.js +1 -19
- package/dist/cli/tui/visual/footer.js +1 -27
- package/dist/cli/tui/visual/index.js +1 -3
- package/dist/cli/tui/visual/viewport.js +1 -11
- package/dist/cli/tui-render-helpers.js +1 -200
- package/dist/cli/verification-plan-renderer.js +1 -25
- package/dist/cli/verification-report-renderer.js +1 -19
- package/dist/domain/agents/canonical-agent-manifest.js +364 -0
- package/dist/domain/agents/schema.js +1 -0
- package/dist/domain/memory/active-work-topics.js +64 -0
- package/dist/domain/memory/memory-capture-schema.js +1 -0
- package/dist/domain/memory/schema.js +1 -0
- package/dist/domain/runs/schema.js +5 -0
- package/dist/domain/sdd/cockpit-types.js +1 -0
- package/dist/domain/sdd/schema.js +111 -0
- package/dist/domain/skills/schema.js +1 -0
- package/dist/interfaces/cli/bun-bin.js +46 -0
- package/dist/interfaces/cli/cli-flags.js +391 -0
- package/dist/interfaces/cli/cli-help.js +173 -0
- package/dist/interfaces/cli/cli-helpers.js +77 -0
- package/dist/interfaces/cli/cli-types.js +1 -0
- package/dist/interfaces/cli/commands/agent-skill-dispatcher.js +700 -0
- package/dist/interfaces/cli/commands/index.js +9 -0
- package/dist/interfaces/cli/commands/interactive-entrypoint-dispatcher.js +14 -0
- package/dist/interfaces/cli/commands/mcp-dispatcher.js +252 -0
- package/dist/interfaces/cli/commands/memory-sdd-dispatcher.js +367 -0
- package/dist/interfaces/cli/commands/run-permission-dispatcher.js +460 -0
- package/dist/interfaces/cli/commands/setup-dispatcher.js +496 -0
- package/dist/interfaces/cli/commands/status-dispatcher.js +130 -0
- package/dist/interfaces/cli/commands/verification-dispatcher.js +47 -0
- package/dist/interfaces/cli/commands/workflow-dispatcher.js +566 -0
- package/dist/interfaces/cli/dispatcher.js +247 -0
- package/dist/interfaces/cli/doctor-renderer.js +26 -0
- package/dist/interfaces/cli/home-tui-app.js +462 -0
- package/dist/interfaces/cli/home-tui-controller.js +341 -0
- package/dist/interfaces/cli/index.js +27 -0
- package/dist/interfaces/cli/mcp-start-path.js +21 -0
- package/dist/interfaces/cli/product-resume-renderer.js +32 -0
- package/dist/interfaces/cli/product-status-renderer.js +81 -0
- package/dist/interfaces/cli/sdd-renderer.js +247 -0
- package/dist/interfaces/cli/setup-plan-renderer.js +79 -0
- package/dist/interfaces/cli/setup-status-renderer.js +50 -0
- package/dist/interfaces/cli/setup-tui-app.js +135 -0
- package/dist/interfaces/cli/setup-tui-controller.js +89 -0
- package/dist/interfaces/cli/tui/focus-reducer.js +60 -0
- package/dist/interfaces/cli/tui/focus-types.js +10 -0
- package/dist/interfaces/cli/tui/ink/app-shell.js +16 -0
- package/dist/interfaces/cli/tui/ink/components.js +38 -0
- package/dist/interfaces/cli/tui/ink/help-overlay.js +6 -0
- package/dist/interfaces/cli/tui/ink/state-components.js +22 -0
- package/dist/interfaces/cli/tui/ink/theme.js +36 -0
- package/dist/interfaces/cli/tui/key-intents.js +33 -0
- package/dist/interfaces/cli/tui/keymap.js +20 -0
- package/dist/interfaces/cli/tui/navigation.js +10 -0
- package/dist/interfaces/cli/tui/screen-registry.js +43 -0
- package/dist/interfaces/cli/tui/terminal-capabilities.js +12 -0
- package/dist/interfaces/cli/tui/tui-types.js +1 -0
- package/dist/interfaces/cli/tui/visual/badges.js +19 -0
- package/dist/interfaces/cli/tui/visual/footer.js +27 -0
- package/dist/interfaces/cli/tui/visual/index.js +3 -0
- package/dist/interfaces/cli/tui/visual/viewport.js +11 -0
- package/dist/interfaces/cli/tui-render-helpers.js +200 -0
- package/dist/interfaces/cli/verification-plan-renderer.js +25 -0
- package/dist/interfaces/cli/verification-report-renderer.js +19 -0
- package/dist/interfaces/mcp/contracts/agents.js +1 -0
- package/dist/interfaces/mcp/contracts/context.js +1 -0
- package/dist/interfaces/mcp/contracts/governance.js +1 -0
- package/dist/interfaces/mcp/contracts/index.js +1 -0
- package/dist/interfaces/mcp/contracts/memory.js +1 -0
- package/dist/interfaces/mcp/contracts/providers.js +1 -0
- package/dist/interfaces/mcp/contracts/runs.js +1 -0
- package/dist/interfaces/mcp/contracts/sdd.js +1 -0
- package/dist/interfaces/mcp/contracts/sessions.js +1 -0
- package/dist/interfaces/mcp/contracts/skills.js +1 -0
- package/dist/interfaces/mcp/contracts/verification.js +1 -0
- package/dist/interfaces/mcp/control-plane/handlers/agents.js +38 -0
- package/dist/interfaces/mcp/control-plane/handlers/context.js +12 -0
- package/dist/interfaces/mcp/control-plane/handlers/memory.js +95 -0
- package/dist/interfaces/mcp/control-plane/handlers/providers.js +19 -0
- package/dist/interfaces/mcp/control-plane/handlers/runs.js +134 -0
- package/dist/interfaces/mcp/control-plane/handlers/sdd.js +225 -0
- package/dist/interfaces/mcp/control-plane/handlers/sessions.js +39 -0
- package/dist/interfaces/mcp/control-plane/handlers/skills.js +82 -0
- package/dist/interfaces/mcp/control-plane/handlers/verification.js +11 -0
- package/dist/interfaces/mcp/control-plane/types.js +1 -0
- package/dist/interfaces/mcp/control-plane.js +235 -0
- package/dist/interfaces/mcp/schema.js +174 -0
- package/dist/interfaces/mcp/schemas/common.js +121 -0
- package/dist/interfaces/mcp/schemas/inputs/agents.js +69 -0
- package/dist/interfaces/mcp/schemas/inputs/context.js +32 -0
- package/dist/interfaces/mcp/schemas/inputs/governance.js +23 -0
- package/dist/interfaces/mcp/schemas/inputs/index.js +10 -0
- package/dist/interfaces/mcp/schemas/inputs/memory.js +50 -0
- package/dist/interfaces/mcp/schemas/inputs/providers.js +35 -0
- package/dist/interfaces/mcp/schemas/inputs/runs.js +146 -0
- package/dist/interfaces/mcp/schemas/inputs/sdd.js +102 -0
- package/dist/interfaces/mcp/schemas/inputs/sessions.js +32 -0
- package/dist/interfaces/mcp/schemas/inputs/skills.js +231 -0
- package/dist/interfaces/mcp/schemas/inputs/verification.js +9 -0
- package/dist/interfaces/mcp/schemas/outputs/index.js +2 -0
- package/dist/interfaces/mcp/schemas/outputs/providers.js +28 -0
- package/dist/interfaces/mcp/schemas/outputs/sdd.js +166 -0
- package/dist/interfaces/mcp/stdio-server.js +116 -0
- package/dist/interfaces/mcp/validation/agents.js +189 -0
- package/dist/interfaces/mcp/validation/common.js +415 -0
- package/dist/interfaces/mcp/validation/governance.js +50 -0
- package/dist/interfaces/mcp/validation/memory.js +133 -0
- package/dist/interfaces/mcp/validation/providers.js +94 -0
- package/dist/interfaces/mcp/validation/runs.js +514 -0
- package/dist/interfaces/mcp/validation/sdd.js +247 -0
- package/dist/interfaces/mcp/validation/sessions.js +51 -0
- package/dist/interfaces/mcp/validation/skills.js +685 -0
- package/dist/interfaces/mcp/validation/verification.js +24 -0
- package/dist/interfaces/mcp/validation.js +149 -0
- package/dist/mcp/control-plane-snapshot-service.js +65 -2
- package/dist/mcp/control-plane.js +1 -646
- package/dist/mcp/doctor.js +1 -1
- package/dist/mcp/index.js +17 -17
- package/dist/mcp/schema.js +1 -1132
- package/dist/mcp/stdio-server.js +1 -116
- package/dist/mcp/validation.js +1 -2383
- package/dist/memory/active-work-preview.js +1 -75
- package/dist/memory/active-work-topics.js +1 -64
- package/dist/memory/agent-memory-capture-service.js +1 -497
- package/dist/memory/import/dry-run-planner.js +1 -58
- package/dist/memory/import/index.js +1 -3
- package/dist/memory/import/observation-writer.js +1 -226
- package/dist/memory/import/package.js +1 -179
- package/dist/memory/memory-capture-schema.js +1 -1
- package/dist/memory/memory-service.js +1 -201
- package/dist/memory/repositories/artifacts.js +1 -67
- package/dist/memory/repositories/observations.js +1 -217
- package/dist/memory/repositories/sessions.js +1 -125
- package/dist/memory/repositories/traces.js +1 -78
- package/dist/memory/schema.js +1 -1
- package/dist/memory/search.js +1 -11
- package/dist/memory/sqlite/database.js +1 -228
- package/dist/memory/storage-paths.js +1 -72
- package/dist/payload/context-budget-policy.js +10 -0
- package/dist/payload/context-budget-service.js +26 -0
- package/dist/payload/payload-diagnostics.js +50 -0
- package/dist/permissions/policy-evaluator.js +12 -5
- package/dist/runs/execution-planning.js +1 -178
- package/dist/runs/operation-execution.js +1 -1
- package/dist/runs/operation-retry.js +1 -129
- package/dist/runs/repositories/runs.js +1 -676
- package/dist/runs/repositories/task-scoped-command-grants.js +1 -462
- package/dist/runs/resume-after-approval-result.js +1 -84
- package/dist/runs/run-insights.js +1 -270
- package/dist/runs/run-service.js +1 -1470
- package/dist/runs/run-snapshot-export-service.js +1 -31
- package/dist/runs/sandbox-process-execution.js +1 -240
- package/dist/runs/sandbox-worktree-planning.js +1 -59
- package/dist/runs/schema.js +1 -5
- package/dist/runs/task-scoped-command-grant-service.js +1 -217
- package/dist/sdd/artifact-portability-service.js +1 -137
- package/dist/sdd/cockpit-read-model.js +1 -195
- package/dist/sdd/cockpit-types.js +1 -1
- package/dist/sdd/schema.js +1 -111
- package/dist/sdd/sdd-continuation-plan.js +1 -265
- package/dist/sdd/sdd-workflow-service.js +1 -822
- package/dist/setup/providers/claude-setup-adapter.js +11 -4
- package/dist/setup/providers/opencode-setup-adapter.js +10 -7
- package/dist/setup/setup-plan.js +20 -7
- package/dist/skills/boot-seed.js +1 -42
- package/dist/skills/personal-skills.js +1 -41
- package/dist/skills/repositories/skill-evaluation-requests.js +1 -190
- package/dist/skills/repositories/skill-evaluation-scenarios.js +1 -305
- package/dist/skills/repositories/skill-improvement-proposals.js +1 -355
- package/dist/skills/repositories/skills.js +1 -1077
- package/dist/skills/schema.js +1 -1
- package/dist/skills/skill-export-service.js +1 -34
- package/dist/skills/skill-index-service.js +1 -126
- package/dist/skills/skill-payload.js +1 -186
- package/dist/skills/skill-registry-service.js +1 -644
- package/dist/skills/skill-resolver.js +1 -368
- package/dist/skills/skill-seed-service.js +1 -242
- package/dist/skills/skill-status-service.js +1 -147
- package/dist/storage/agents/repositories/agent-seed-history.js +128 -0
- package/dist/storage/agents/repositories/agents.js +200 -0
- package/dist/storage/agents/repositories/manager-profile-overlays.js +90 -0
- package/dist/storage/memory/repositories/artifacts.js +67 -0
- package/dist/storage/memory/repositories/observations.js +217 -0
- package/dist/storage/memory/repositories/sessions.js +125 -0
- package/dist/storage/memory/repositories/traces.js +78 -0
- package/dist/storage/memory/sqlite/database.js +228 -0
- package/dist/storage/memory/storage-paths.js +72 -0
- package/dist/storage/runs/repositories/runs.js +676 -0
- package/dist/storage/runs/repositories/task-scoped-command-grants.js +464 -0
- package/dist/storage/skills/repositories/skill-evaluation-requests.js +190 -0
- package/dist/storage/skills/repositories/skill-evaluation-scenarios.js +305 -0
- package/dist/storage/skills/repositories/skill-improvement-proposals.js +355 -0
- package/dist/storage/skills/repositories/skills.js +1084 -0
- package/docs/architecture.md +2 -2
- package/docs/glossary.md +1 -1
- package/docs/mcp.md +1 -1
- package/docs/module-boundaries.md +114 -0
- package/docs/prd.md +1 -1
- package/docs/project-health-audit-v1.10.x.md +1 -1
- package/docs/providers.md +2 -2
- package/docs/safety.md +3 -3
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/apply-progress.md +122 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/archive-report.md +61 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/design.md +66 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/proposal.md +79 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/spec.md +67 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/tasks.md +63 -0
- package/docs/sdd/archive/2026-06-26-ambitious-structure-reorganization/verify-report.md +71 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/apply-progress.md +68 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/archive-report.md +61 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/design.md +43 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/proposal.md +61 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/spec.md +31 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/tasks.md +27 -0
- package/docs/sdd/archive/2026-06-26-legacy-facade-cleanup/verify-report.md +58 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/apply-progress.md +65 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/archive-report.md +53 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/design.md +64 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/proposal.md +62 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/spec.md +51 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/tasks.md +50 -0
- package/docs/sdd/archive/2026-06-26-provider-install-adapter-boundary/verify-report.md +66 -0
- package/docs/sdd/manager-prompt-autonomy/apply-progress.md +28 -0
- package/docs/sdd/manager-prompt-autonomy/design.md +63 -0
- package/docs/sdd/manager-prompt-autonomy/proposal.md +57 -0
- package/docs/sdd/manager-prompt-autonomy/tasks.md +19 -0
- package/docs/storage.md +2 -2
- package/package.json +2 -2
- /package/dist/{mcp → adapters/claude/install}/claude-code-cli.js +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/001_initial.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/002_observation_revisions.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/003_agent_registry.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/004_run_runtime.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/005_run_approvals.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/006_run_operation_attempts.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/007_abandoned_operation_attempts.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/008_run_execution_plan_events.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/009_multiple_operation_attempts.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/010_skill_registry.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/011_skill_usage_resolution_outcomes.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/012_skill_improvement_proposals.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/013_skill_evaluation_scenarios.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/014_manager_profile_overlays.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/015_artifact_metadata.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/016_agent_seed_history.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/017_intent_signal_skill_targets.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/018_skill_system_v2.sql +0 -0
- /package/dist/{memory → storage/memory}/sqlite/migrations/019_task_scoped_command_grants.sql +0 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import { normalizeSddPhaseInput } from '../../sdd/schema.js';
|
|
2
|
+
import { agentLookupContexts } from './agent-lookup-contexts.js';
|
|
3
|
+
export class AgentResolver {
|
|
4
|
+
loadAgents;
|
|
5
|
+
constructor(loadAgents) {
|
|
6
|
+
this.loadAgents = loadAgents;
|
|
7
|
+
}
|
|
8
|
+
resolve(input) {
|
|
9
|
+
const agents = this.loadAgents();
|
|
10
|
+
if (!agents.ok)
|
|
11
|
+
return agents;
|
|
12
|
+
const normalized = normalizeInput(input);
|
|
13
|
+
const candidates = [];
|
|
14
|
+
const skipped = [];
|
|
15
|
+
for (const agent of agents.value) {
|
|
16
|
+
const skipReasons = hardSkipReasons(agent, normalized);
|
|
17
|
+
if (skipReasons.length > 0) {
|
|
18
|
+
skipped.push(toSkipped(agent, skipReasons));
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
const scored = scoreAgent(agent, normalized);
|
|
22
|
+
if (scored.score <= 0) {
|
|
23
|
+
skipped.push(toSkipped(agent, ['no matching resolution signals']));
|
|
24
|
+
continue;
|
|
25
|
+
}
|
|
26
|
+
candidates.push(scored);
|
|
27
|
+
}
|
|
28
|
+
candidates.sort(compareCandidates);
|
|
29
|
+
skipped.sort(compareSkipped);
|
|
30
|
+
return ok({
|
|
31
|
+
context: {
|
|
32
|
+
...(normalized.project !== undefined ? { project: normalized.project } : {}),
|
|
33
|
+
...(normalized.scope !== undefined ? { scope: normalized.scope } : {}),
|
|
34
|
+
...(normalized.taskDescription !== undefined ? { taskDescription: normalized.taskDescription } : {}),
|
|
35
|
+
...(normalized.intent !== undefined ? { intent: normalized.intent } : {}),
|
|
36
|
+
desiredCapabilities: normalized.desiredCapabilities,
|
|
37
|
+
...(normalized.workflow !== undefined ? { workflow: normalized.workflow } : {}),
|
|
38
|
+
...(normalized.phase !== undefined ? { phase: normalized.phase } : {}),
|
|
39
|
+
...(normalized.providerAdapter !== undefined ? { providerAdapter: normalized.providerAdapter } : {}),
|
|
40
|
+
...(normalized.mode !== undefined ? { mode: normalized.mode } : {}),
|
|
41
|
+
},
|
|
42
|
+
candidates,
|
|
43
|
+
skipped,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const SDD_PHASE_SEMANTICS = [
|
|
48
|
+
{
|
|
49
|
+
name: 'sdd-planning',
|
|
50
|
+
phases: ['proposal', 'design', 'tasks'],
|
|
51
|
+
terms: ['plan', 'planning', 'proposal', 'propose', 'design', 'task', 'tasks', 'breakdown', 'slice', 'slicing'],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'sdd-verification',
|
|
55
|
+
phases: ['verify'],
|
|
56
|
+
terms: ['verify', 'verification', 'test', 'testing', 'review', 'risk', 'evidence'],
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
function normalizeInput(input) {
|
|
60
|
+
const desiredCapabilities = normalizeList(input.desiredCapabilities ?? []);
|
|
61
|
+
const taskDescription = normalizeText(input.taskDescription);
|
|
62
|
+
const intent = normalizeText(input.intent);
|
|
63
|
+
const metaWorkflow = isMetaWorkflow(input.workflow);
|
|
64
|
+
const workflow = normalizeMetaWorkflow(input.workflow);
|
|
65
|
+
const phase = metaWorkflow || input.phase === undefined ? undefined : isSddWorkflow(workflow) ? (normalizeSddPhaseInput(input.phase) ?? input.phase) : input.phase;
|
|
66
|
+
const { workflow: _workflow, phase: _phase, ...rest } = input;
|
|
67
|
+
return {
|
|
68
|
+
...rest,
|
|
69
|
+
...(workflow !== undefined ? { workflow } : {}),
|
|
70
|
+
...(phase !== undefined ? { phase } : {}),
|
|
71
|
+
...(taskDescription !== undefined ? { taskDescription } : {}),
|
|
72
|
+
...(intent !== undefined ? { intent } : {}),
|
|
73
|
+
desiredCapabilities,
|
|
74
|
+
terms: tokenize([taskDescription, intent].filter((value) => value !== undefined).join(' ')),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function normalizeMetaWorkflow(workflow) {
|
|
78
|
+
if (isMetaWorkflow(workflow))
|
|
79
|
+
return undefined;
|
|
80
|
+
return workflow;
|
|
81
|
+
}
|
|
82
|
+
function isMetaWorkflow(workflow) {
|
|
83
|
+
return workflow?.trim().toLowerCase() === 'workflow-selection';
|
|
84
|
+
}
|
|
85
|
+
function hardSkipReasons(agent, input) {
|
|
86
|
+
const reasons = [];
|
|
87
|
+
if (input.project !== undefined && !agentMatchesRequestedContext(agent, input))
|
|
88
|
+
reasons.push(`context mismatch: ${agent.project}/${agent.scope}`);
|
|
89
|
+
else if (input.project === undefined && input.scope !== undefined && agent.scope !== input.scope)
|
|
90
|
+
reasons.push(`scope mismatch: ${agent.scope}`);
|
|
91
|
+
if (input.mode !== undefined && agent.mode !== input.mode)
|
|
92
|
+
reasons.push(`mode mismatch: ${agent.mode}`);
|
|
93
|
+
if (input.providerAdapter !== undefined && Object.keys(agent.adapters).length > 0 && agent.adapters[input.providerAdapter] === undefined)
|
|
94
|
+
reasons.push(`provider adapter mismatch: ${input.providerAdapter}`);
|
|
95
|
+
if ((input.workflow !== undefined || input.phase !== undefined) && agent.workflows.length > 0 && workflowMatches(agent, input).length === 0)
|
|
96
|
+
reasons.push('workflow mismatch');
|
|
97
|
+
if (input.desiredCapabilities.length > 0 && matchingValues(agent.capabilities, input.desiredCapabilities).length === 0)
|
|
98
|
+
reasons.push('capability mismatch');
|
|
99
|
+
return reasons;
|
|
100
|
+
}
|
|
101
|
+
function agentMatchesRequestedContext(agent, input) {
|
|
102
|
+
if (input.project === undefined)
|
|
103
|
+
return true;
|
|
104
|
+
const contexts = agentLookupContexts(input.project, input.scope ?? 'project');
|
|
105
|
+
return contexts.some((context) => agent.project === context.project && agent.scope === context.scope);
|
|
106
|
+
}
|
|
107
|
+
function scoreAgent(agent, input) {
|
|
108
|
+
const reasons = [];
|
|
109
|
+
let score = 0;
|
|
110
|
+
const capabilityMatches = matchingValues(agent.capabilities, input.desiredCapabilities);
|
|
111
|
+
if (capabilityMatches.length > 0) {
|
|
112
|
+
score += capabilityMatches.length * 30;
|
|
113
|
+
reasons.push(`capabilities matched: ${capabilityMatches.join(', ')}`);
|
|
114
|
+
}
|
|
115
|
+
const workflowMatchesValue = workflowSignalMatches(agent, input);
|
|
116
|
+
if (workflowMatchesValue.exactPhase.length > 0) {
|
|
117
|
+
score += workflowMatchesValue.exactPhase.length * 25;
|
|
118
|
+
reasons.push(`workflow phase matched: ${workflowMatchesValue.exactPhase.join(', ')}`);
|
|
119
|
+
}
|
|
120
|
+
if (workflowMatchesValue.phaseOnly.length > 0) {
|
|
121
|
+
score += workflowMatchesValue.phaseOnly.length * 22;
|
|
122
|
+
reasons.push(`workflow phase-only matched: ${workflowMatchesValue.phaseOnly.join(', ')}`);
|
|
123
|
+
}
|
|
124
|
+
if (workflowMatchesValue.broad.length > 0) {
|
|
125
|
+
score += workflowMatchesValue.broad.length * 20;
|
|
126
|
+
reasons.push(`workflow matched: ${workflowMatchesValue.broad.join(', ')}`);
|
|
127
|
+
}
|
|
128
|
+
if (input.providerAdapter !== undefined) {
|
|
129
|
+
if (agent.adapters[input.providerAdapter] !== undefined) {
|
|
130
|
+
score += 20;
|
|
131
|
+
reasons.push(`provider adapter matched: ${input.providerAdapter}`);
|
|
132
|
+
}
|
|
133
|
+
else if (Object.keys(agent.adapters).length === 0) {
|
|
134
|
+
score += 5;
|
|
135
|
+
reasons.push(`provider neutral: no adapter restrictions for ${input.providerAdapter}`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const skillMatches = matchingValues(agent.skills, [...input.desiredCapabilities, ...input.terms]);
|
|
139
|
+
if (skillMatches.length > 0) {
|
|
140
|
+
score += skillMatches.length * 10;
|
|
141
|
+
reasons.push(`skills matched: ${skillMatches.join(', ')}`);
|
|
142
|
+
}
|
|
143
|
+
const textMatches = textSignalMatches(agent, input.terms);
|
|
144
|
+
if (textMatches.length > 0) {
|
|
145
|
+
score += Math.min(textMatches.length, 5) * 4;
|
|
146
|
+
reasons.push(`task text matched: ${textMatches.join(', ')}`);
|
|
147
|
+
}
|
|
148
|
+
const phaseSemanticMatches = phaseSemanticMatchesFor(agent, input);
|
|
149
|
+
for (const match of phaseSemanticMatches) {
|
|
150
|
+
score += 8;
|
|
151
|
+
reasons.push(`phase semantics matched: ${match}`);
|
|
152
|
+
}
|
|
153
|
+
if (input.mode !== undefined) {
|
|
154
|
+
score += 3;
|
|
155
|
+
reasons.push(`mode matched: ${agent.mode}`);
|
|
156
|
+
}
|
|
157
|
+
if (agent.mode === 'subagent') {
|
|
158
|
+
score += 2;
|
|
159
|
+
reasons.push(`parent constraint satisfied: ${agent.parentAgentId}`);
|
|
160
|
+
}
|
|
161
|
+
return { agent, score, reasons };
|
|
162
|
+
}
|
|
163
|
+
function workflowMatches(agent, input) {
|
|
164
|
+
const matches = workflowSignalMatches(agent, input);
|
|
165
|
+
return [...matches.broad, ...matches.phaseOnly, ...matches.exactPhase];
|
|
166
|
+
}
|
|
167
|
+
function workflowSignalMatches(agent, input) {
|
|
168
|
+
const requested = workflowRequestedSignals(input)
|
|
169
|
+
.filter((value) => value !== undefined)
|
|
170
|
+
.map(normalizeKey);
|
|
171
|
+
if (requested.length === 0)
|
|
172
|
+
return { broad: [], phaseOnly: [], exactPhase: [] };
|
|
173
|
+
const workflow = input.workflow !== undefined ? normalizeKey(input.workflow) : undefined;
|
|
174
|
+
const phase = input.phase !== undefined ? normalizeKey(input.phase) : undefined;
|
|
175
|
+
const exact = workflow !== undefined && phase !== undefined ? `${workflow}:${phase}` : undefined;
|
|
176
|
+
const matches = { broad: [], phaseOnly: [], exactPhase: [] };
|
|
177
|
+
for (const agentWorkflow of agent.workflows) {
|
|
178
|
+
const normalizedWorkflow = normalizeKey(agentWorkflow);
|
|
179
|
+
const comparableWorkflow = canonicalSddWorkflowTargetKey(agentWorkflow);
|
|
180
|
+
if (!requested.includes(normalizedWorkflow) && !requested.includes(comparableWorkflow) && !sddApplyAliasMatches(agentWorkflow, input))
|
|
181
|
+
continue;
|
|
182
|
+
if (exact !== undefined && (normalizedWorkflow === exact || comparableWorkflow === exact))
|
|
183
|
+
matches.exactPhase.push(agentWorkflow);
|
|
184
|
+
else if (phase !== undefined && normalizedWorkflow === phase)
|
|
185
|
+
matches.phaseOnly.push(agentWorkflow);
|
|
186
|
+
else if (sddApplyAliasMatches(agentWorkflow, input))
|
|
187
|
+
matches.exactPhase.push(agentWorkflow);
|
|
188
|
+
else
|
|
189
|
+
matches.broad.push(agentWorkflow);
|
|
190
|
+
}
|
|
191
|
+
return matches;
|
|
192
|
+
}
|
|
193
|
+
function canonicalSddWorkflowTargetKey(workflow) {
|
|
194
|
+
const normalized = normalizeKey(workflow);
|
|
195
|
+
const separator = normalized.indexOf(':');
|
|
196
|
+
if (separator <= 0)
|
|
197
|
+
return normalized;
|
|
198
|
+
const workflowName = normalized.slice(0, separator);
|
|
199
|
+
const phase = normalized.slice(separator + 1);
|
|
200
|
+
if (workflowName !== 'sdd')
|
|
201
|
+
return normalized;
|
|
202
|
+
return `${workflowName}:${normalizeSddPhaseInput(phase) ?? phase}`;
|
|
203
|
+
}
|
|
204
|
+
function workflowRequestedSignals(input) {
|
|
205
|
+
return [input.workflow, input.phase, input.workflow !== undefined && input.phase !== undefined ? `${input.workflow}:${input.phase}` : undefined];
|
|
206
|
+
}
|
|
207
|
+
function sddApplyAliasMatches(agentWorkflow, input) {
|
|
208
|
+
if (input.phase === undefined || normalizeKey(input.phase) !== 'apply')
|
|
209
|
+
return false;
|
|
210
|
+
if (input.workflow !== undefined && !isSddWorkflow(input.workflow))
|
|
211
|
+
return false;
|
|
212
|
+
return normalizeKey(agentWorkflow) === 'sdd:apply-progress';
|
|
213
|
+
}
|
|
214
|
+
function phaseSemanticMatchesFor(agent, input) {
|
|
215
|
+
const workflow = input.workflow !== undefined ? normalizeKey(input.workflow) : undefined;
|
|
216
|
+
if (workflow !== undefined && workflow !== 'sdd')
|
|
217
|
+
return [];
|
|
218
|
+
const inputPhase = input.phase !== undefined ? normalizeKey(input.phase) : undefined;
|
|
219
|
+
const agentTerms = tokenize([agent.name, agent.description, ...agent.capabilities, ...agent.skills, ...agent.workflows].join(' '));
|
|
220
|
+
const requestTerms = new Set(input.terms);
|
|
221
|
+
const matches = [];
|
|
222
|
+
for (const semantic of SDD_PHASE_SEMANTICS) {
|
|
223
|
+
const phaseMatches = inputPhase !== undefined && semantic.phases.includes(inputPhase);
|
|
224
|
+
const termMatches = semantic.terms.some((term) => requestTerms.has(term));
|
|
225
|
+
const agentMatches = semantic.terms.some((term) => agentTerms.includes(term));
|
|
226
|
+
if ((phaseMatches || termMatches) && agentMatches)
|
|
227
|
+
matches.push(semantic.name);
|
|
228
|
+
}
|
|
229
|
+
return matches;
|
|
230
|
+
}
|
|
231
|
+
function textSignalMatches(agent, terms) {
|
|
232
|
+
if (terms.length === 0)
|
|
233
|
+
return [];
|
|
234
|
+
const searchable = tokenize([agent.name, agent.description, ...agent.capabilities, ...agent.skills, ...agent.workflows].join(' '));
|
|
235
|
+
return terms.filter((term) => searchable.includes(term));
|
|
236
|
+
}
|
|
237
|
+
function matchingValues(values, requested) {
|
|
238
|
+
const normalizedValues = new Map(values.map((value) => [normalizeKey(value), value]));
|
|
239
|
+
const matches = [];
|
|
240
|
+
for (const requestedValue of requested) {
|
|
241
|
+
const match = normalizedValues.get(normalizeKey(requestedValue));
|
|
242
|
+
if (match !== undefined && !matches.includes(match))
|
|
243
|
+
matches.push(match);
|
|
244
|
+
}
|
|
245
|
+
return matches;
|
|
246
|
+
}
|
|
247
|
+
function compareCandidates(a, b) {
|
|
248
|
+
return (b.score - a.score || modeRank(a.agent.mode) - modeRank(b.agent.mode) || a.agent.name.localeCompare(b.agent.name) || a.agent.id.localeCompare(b.agent.id));
|
|
249
|
+
}
|
|
250
|
+
function compareSkipped(a, b) {
|
|
251
|
+
return a.agent.name.localeCompare(b.agent.name) || a.agent.id.localeCompare(b.agent.id);
|
|
252
|
+
}
|
|
253
|
+
function modeRank(mode) {
|
|
254
|
+
return mode === 'agent' ? 0 : 1;
|
|
255
|
+
}
|
|
256
|
+
function toSkipped(agent, reasons) {
|
|
257
|
+
return { agent: { id: agent.id, name: agent.name, mode: agent.mode, project: agent.project, scope: agent.scope }, reasons };
|
|
258
|
+
}
|
|
259
|
+
function normalizeList(values) {
|
|
260
|
+
return values.map(normalizeText).filter((value) => value !== undefined);
|
|
261
|
+
}
|
|
262
|
+
function normalizeText(value) {
|
|
263
|
+
const normalized = value?.trim();
|
|
264
|
+
return normalized ? normalized : undefined;
|
|
265
|
+
}
|
|
266
|
+
function normalizeKey(value) {
|
|
267
|
+
return value.trim().toLowerCase();
|
|
268
|
+
}
|
|
269
|
+
function isSddWorkflow(workflow) {
|
|
270
|
+
return workflow?.trim().toLowerCase() === 'sdd';
|
|
271
|
+
}
|
|
272
|
+
function tokenize(value) {
|
|
273
|
+
const seen = new Set();
|
|
274
|
+
return value
|
|
275
|
+
.toLowerCase()
|
|
276
|
+
.split(/[^a-z0-9-]+/)
|
|
277
|
+
.filter(Boolean)
|
|
278
|
+
.filter((term) => {
|
|
279
|
+
if (term.length < 3 || seen.has(term))
|
|
280
|
+
return false;
|
|
281
|
+
seen.add(term);
|
|
282
|
+
return true;
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
function ok(value) {
|
|
286
|
+
return { ok: true, value };
|
|
287
|
+
}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { AgentRepository } from '../../storage/agents/repositories/agents.js';
|
|
2
|
+
import { projectCanonicalAgentManifestToSeed } from './canonical-agent-projection.js';
|
|
3
|
+
const requiredManagerName = 'vgxness-manager';
|
|
4
|
+
export class AgentSeedService {
|
|
5
|
+
database;
|
|
6
|
+
agents;
|
|
7
|
+
constructor(database) {
|
|
8
|
+
this.database = database;
|
|
9
|
+
this.agents = new AgentRepository(database);
|
|
10
|
+
}
|
|
11
|
+
loadBuiltInDefaults() {
|
|
12
|
+
try {
|
|
13
|
+
return this.loadManifest(projectCanonicalAgentManifestToSeed());
|
|
14
|
+
}
|
|
15
|
+
catch (cause) {
|
|
16
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
17
|
+
return { ok: false, error: { code: 'validation_failed', message } };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
loadManifest(manifest) {
|
|
21
|
+
const validation = this.validateManifest(manifest);
|
|
22
|
+
if (!validation.ok)
|
|
23
|
+
return validation;
|
|
24
|
+
const existingNames = new Map();
|
|
25
|
+
for (const definition of [...manifest.agents, ...manifest.subagents]) {
|
|
26
|
+
const existing = this.agents.getByName(manifest.project, manifest.scope, definition.name);
|
|
27
|
+
if (existing.ok)
|
|
28
|
+
existingNames.set(definition.name, true);
|
|
29
|
+
else
|
|
30
|
+
existingNames.set(definition.name, false);
|
|
31
|
+
}
|
|
32
|
+
const transaction = this.database.transaction(() => {
|
|
33
|
+
const agents = [];
|
|
34
|
+
const subagents = [];
|
|
35
|
+
const nameToId = new Map();
|
|
36
|
+
const created = [];
|
|
37
|
+
const updated = [];
|
|
38
|
+
for (const definition of manifest.agents) {
|
|
39
|
+
const registered = this.agents.register(toRegisterInput(manifest, definition, 'agent'));
|
|
40
|
+
if (!registered.ok)
|
|
41
|
+
throw new SeedLoadError(registered.error);
|
|
42
|
+
agents.push(registered.value);
|
|
43
|
+
nameToId.set(registered.value.name, registered.value.id);
|
|
44
|
+
(existingNames.get(definition.name) ? updated : created).push(definition.name);
|
|
45
|
+
}
|
|
46
|
+
for (const definition of manifest.subagents) {
|
|
47
|
+
const parentAgentId = nameToId.get(definition.parentAgentName) ?? this.resolveExistingParentId(manifest, definition.parentAgentName);
|
|
48
|
+
if (parentAgentId === undefined) {
|
|
49
|
+
throw new SeedLoadError({ code: 'validation_failed', message: `Unresolved parentAgentName: ${definition.parentAgentName}` });
|
|
50
|
+
}
|
|
51
|
+
const registered = this.agents.register(toRegisterInput(manifest, definition, 'subagent', parentAgentId));
|
|
52
|
+
if (!registered.ok)
|
|
53
|
+
throw new SeedLoadError(registered.error);
|
|
54
|
+
subagents.push(registered.value);
|
|
55
|
+
(existingNames.get(definition.name) ? updated : created).push(definition.name);
|
|
56
|
+
}
|
|
57
|
+
return { created, updated, agents, subagents, warnings: [] };
|
|
58
|
+
});
|
|
59
|
+
if (!transaction.ok) {
|
|
60
|
+
if (transaction.error.cause instanceof SeedLoadError)
|
|
61
|
+
return { ok: false, error: transaction.error.cause.failure };
|
|
62
|
+
return transaction;
|
|
63
|
+
}
|
|
64
|
+
return transaction;
|
|
65
|
+
}
|
|
66
|
+
validateManifest(manifest) {
|
|
67
|
+
if (manifest.version !== 1)
|
|
68
|
+
return validationFailure('Agent seed manifest version must be 1');
|
|
69
|
+
if (!manifest.project?.trim())
|
|
70
|
+
return validationFailure('Agent seed manifest project is required');
|
|
71
|
+
if (manifest.scope !== 'project' && manifest.scope !== 'personal')
|
|
72
|
+
return validationFailure('Agent seed manifest scope must be project or personal');
|
|
73
|
+
if (!Array.isArray(manifest.agents))
|
|
74
|
+
return validationFailure('Agent seed manifest agents must be an array');
|
|
75
|
+
if (!Array.isArray(manifest.subagents))
|
|
76
|
+
return validationFailure('Agent seed manifest subagents must be an array');
|
|
77
|
+
const managerCount = manifest.agents.filter((agent) => agent.name === requiredManagerName).length;
|
|
78
|
+
if (managerCount !== 1)
|
|
79
|
+
return validationFailure(`Agent seed manifest must declare exactly one ${requiredManagerName} agent`);
|
|
80
|
+
const seenNames = new Set();
|
|
81
|
+
for (const definition of manifest.agents) {
|
|
82
|
+
const validation = validateDefinition(definition, 'agent');
|
|
83
|
+
if (!validation.ok)
|
|
84
|
+
return validation;
|
|
85
|
+
if (seenNames.has(definition.name))
|
|
86
|
+
return validationFailure(`Duplicate seed agent name: ${definition.name}`);
|
|
87
|
+
seenNames.add(definition.name);
|
|
88
|
+
}
|
|
89
|
+
for (const definition of manifest.subagents) {
|
|
90
|
+
const validation = validateDefinition(definition, 'subagent');
|
|
91
|
+
if (!validation.ok)
|
|
92
|
+
return validation;
|
|
93
|
+
if (seenNames.has(definition.name))
|
|
94
|
+
return validationFailure(`Duplicate seed agent name: ${definition.name}`);
|
|
95
|
+
seenNames.add(definition.name);
|
|
96
|
+
if (!definition.parentAgentName.trim())
|
|
97
|
+
return validationFailure(`Subagent ${definition.name} parentAgentName is required`);
|
|
98
|
+
if (!manifest.agents.some((agent) => agent.name === definition.parentAgentName) &&
|
|
99
|
+
this.resolveExistingParentId(manifest, definition.parentAgentName) === undefined) {
|
|
100
|
+
return validationFailure(`Unresolved parentAgentName: ${definition.parentAgentName}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return { ok: true, value: undefined };
|
|
104
|
+
}
|
|
105
|
+
resolveExistingParentId(manifest, parentAgentName) {
|
|
106
|
+
const parent = this.agents.getByName(manifest.project, manifest.scope, parentAgentName);
|
|
107
|
+
if (!parent.ok || parent.value.mode !== 'agent')
|
|
108
|
+
return undefined;
|
|
109
|
+
return parent.value.id;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
function validateDefinition(definition, mode) {
|
|
113
|
+
if (!definition.name?.trim())
|
|
114
|
+
return validationFailure(`Seed ${mode} name is required`);
|
|
115
|
+
if (!definition.description?.trim())
|
|
116
|
+
return validationFailure(`Seed ${mode} ${definition.name} description is required`);
|
|
117
|
+
if (definition.instructions?.kind !== 'inline' && definition.instructions?.kind !== 'path')
|
|
118
|
+
return validationFailure(`Seed ${mode} ${definition.name} instructions kind is invalid`);
|
|
119
|
+
if (!definition.instructions.value.trim())
|
|
120
|
+
return validationFailure(`Seed ${mode} ${definition.name} instructions are required`);
|
|
121
|
+
return { ok: true, value: undefined };
|
|
122
|
+
}
|
|
123
|
+
function toRegisterInput(manifest, definition, mode, parentAgentId) {
|
|
124
|
+
const input = {
|
|
125
|
+
project: manifest.project,
|
|
126
|
+
scope: manifest.scope,
|
|
127
|
+
mode,
|
|
128
|
+
name: definition.name,
|
|
129
|
+
description: definition.description,
|
|
130
|
+
instructions: definition.instructions,
|
|
131
|
+
};
|
|
132
|
+
if (definition.capabilities !== undefined)
|
|
133
|
+
input.capabilities = definition.capabilities;
|
|
134
|
+
if (definition.permissions !== undefined)
|
|
135
|
+
input.permissions = definition.permissions;
|
|
136
|
+
if (definition.memory !== undefined)
|
|
137
|
+
input.memory = definition.memory;
|
|
138
|
+
if (definition.workflows !== undefined)
|
|
139
|
+
input.workflows = definition.workflows;
|
|
140
|
+
if (definition.skills !== undefined)
|
|
141
|
+
input.skills = definition.skills;
|
|
142
|
+
if (definition.adapters !== undefined)
|
|
143
|
+
input.adapters = definition.adapters;
|
|
144
|
+
if (parentAgentId !== undefined)
|
|
145
|
+
input.parentAgentId = parentAgentId;
|
|
146
|
+
return input;
|
|
147
|
+
}
|
|
148
|
+
function validationFailure(message) {
|
|
149
|
+
return { ok: false, error: { code: 'validation_failed', message } };
|
|
150
|
+
}
|
|
151
|
+
class SeedLoadError extends Error {
|
|
152
|
+
failure;
|
|
153
|
+
constructor(failure) {
|
|
154
|
+
super(failure.message);
|
|
155
|
+
this.failure = failure;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { canonicalAgentManifest, canonicalPromptContractVersion, canonicalSddSubagentNames } from '../../domain/agents/canonical-agent-manifest.js';
|
|
2
|
+
import { projectCanonicalAgentManifestToSeed } from './canonical-agent-projection.js';
|
|
3
|
+
export class AgentSeedUpgradeService {
|
|
4
|
+
agents;
|
|
5
|
+
history;
|
|
6
|
+
database;
|
|
7
|
+
constructor(dependencies) {
|
|
8
|
+
this.agents = dependencies.agents;
|
|
9
|
+
this.history = dependencies.history;
|
|
10
|
+
this.database = dependencies.database;
|
|
11
|
+
}
|
|
12
|
+
upgrade(input) {
|
|
13
|
+
if (!input.project.trim())
|
|
14
|
+
return validationFailure('Agent seed upgrade project is required');
|
|
15
|
+
if (input.scope !== 'project' && input.scope !== 'personal')
|
|
16
|
+
return validationFailure('Agent seed upgrade scope is invalid');
|
|
17
|
+
const seed = projectCanonicalAgentManifestToSeed();
|
|
18
|
+
const canonicalByName = new Map();
|
|
19
|
+
for (const agent of seed.agents)
|
|
20
|
+
canonicalByName.set(agent.name, agent);
|
|
21
|
+
for (const subagent of seed.subagents)
|
|
22
|
+
canonicalByName.set(subagent.name, subagent);
|
|
23
|
+
const source = input.source ?? 'boot-upgrade';
|
|
24
|
+
const summary = {
|
|
25
|
+
created: [],
|
|
26
|
+
upgraded: [],
|
|
27
|
+
noop: [],
|
|
28
|
+
overwritten: [],
|
|
29
|
+
errors: [],
|
|
30
|
+
skipped: false,
|
|
31
|
+
};
|
|
32
|
+
const expected = canonicalPromptContractVersion;
|
|
33
|
+
const transaction = this.database.transaction(() => {
|
|
34
|
+
for (const [name, definition] of canonicalByName) {
|
|
35
|
+
const outcome = this.upgradeOne(input.project, input.scope, name, definition, source, expected);
|
|
36
|
+
if (outcome.ok) {
|
|
37
|
+
switch (outcome.value.outcome) {
|
|
38
|
+
case 'created':
|
|
39
|
+
summary.created.push(name);
|
|
40
|
+
break;
|
|
41
|
+
case 'upgraded':
|
|
42
|
+
summary.upgraded.push(name);
|
|
43
|
+
break;
|
|
44
|
+
case 'overwrote-custom-instructions':
|
|
45
|
+
summary.overwritten.push(name);
|
|
46
|
+
break;
|
|
47
|
+
case 'noop':
|
|
48
|
+
summary.noop.push(name);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
const failureOutcome = outcome.error.code === 'validation_failed' ? 'validation_failed' : 'db_error';
|
|
54
|
+
summary.errors.push({ agentName: name, outcome: failureOutcome, reason: outcome.error.message });
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return summary;
|
|
58
|
+
});
|
|
59
|
+
if (!transaction.ok) {
|
|
60
|
+
return { ok: false, error: transaction.error };
|
|
61
|
+
}
|
|
62
|
+
return transaction;
|
|
63
|
+
}
|
|
64
|
+
hasDrift(input) {
|
|
65
|
+
const expected = input.expectedVersion ?? canonicalPromptContractVersion;
|
|
66
|
+
try {
|
|
67
|
+
const canonicalNames = [canonicalAgentManifest.defaultAgentName, ...canonicalSddSubagentNames];
|
|
68
|
+
const placeholders = canonicalNames.map(() => '?').join(', ');
|
|
69
|
+
const row = this.database.connection
|
|
70
|
+
.prepare(`
|
|
71
|
+
SELECT COUNT(*) AS stale_count
|
|
72
|
+
FROM agents
|
|
73
|
+
WHERE project = ? AND scope = ? AND name IN (${placeholders})
|
|
74
|
+
AND json_extract(adapters_json, '$.opencode.config.options.vgxnessPromptContractVersion') <> ?
|
|
75
|
+
`)
|
|
76
|
+
.get(input.project, input.scope, ...canonicalNames, expected);
|
|
77
|
+
return ok((row?.stale_count ?? 0) > 0);
|
|
78
|
+
}
|
|
79
|
+
catch (cause) {
|
|
80
|
+
return fail('Failed to detect agent seed drift', cause);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
upgradeOne(project, scope, name, definition, source, expected) {
|
|
84
|
+
const existing = this.agents.getByName(project, scope, name);
|
|
85
|
+
const fromVersion = existing.ok ? readPromptContractVersion(existing.value) : null;
|
|
86
|
+
if (existing.ok && fromVersion === expected && isByteEqualToCanonical(existing.value, definition)) {
|
|
87
|
+
return ok({ outcome: 'noop', fromVersion: expected });
|
|
88
|
+
}
|
|
89
|
+
const parentAgentId = 'parentAgentName' in definition ? this.resolveParentId(project, scope, definition.parentAgentName) : undefined;
|
|
90
|
+
if ('parentAgentName' in definition && parentAgentId === undefined) {
|
|
91
|
+
return validationFailure(`Unresolved parentAgentName: ${definition.parentAgentName}`);
|
|
92
|
+
}
|
|
93
|
+
const registerInput = toRegisterInput(project, scope, definition, parentAgentId);
|
|
94
|
+
const registered = this.agents.register(registerInput);
|
|
95
|
+
if (!registered.ok) {
|
|
96
|
+
this.appendHistory({
|
|
97
|
+
project,
|
|
98
|
+
scope,
|
|
99
|
+
agentName: name,
|
|
100
|
+
fromVersion,
|
|
101
|
+
toVersion: expected,
|
|
102
|
+
outcome: registered.error.code === 'validation_failed' ? 'validation_failed' : 'db_error',
|
|
103
|
+
reason: registered.error.message,
|
|
104
|
+
source,
|
|
105
|
+
});
|
|
106
|
+
return registered;
|
|
107
|
+
}
|
|
108
|
+
let outcome;
|
|
109
|
+
if (!existing.ok) {
|
|
110
|
+
outcome = 'created';
|
|
111
|
+
}
|
|
112
|
+
else if (fromVersion !== null && fromVersion !== expected) {
|
|
113
|
+
outcome = 'upgraded';
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
outcome = 'overwrote-custom-instructions';
|
|
117
|
+
}
|
|
118
|
+
this.appendHistory({
|
|
119
|
+
project,
|
|
120
|
+
scope,
|
|
121
|
+
agentName: name,
|
|
122
|
+
fromVersion,
|
|
123
|
+
toVersion: expected,
|
|
124
|
+
outcome,
|
|
125
|
+
reason: outcomeReason(outcome, fromVersion, expected, existing.ok),
|
|
126
|
+
source,
|
|
127
|
+
});
|
|
128
|
+
return ok({ outcome, fromVersion });
|
|
129
|
+
}
|
|
130
|
+
resolveParentId(project, scope, parentAgentName) {
|
|
131
|
+
const parent = this.agents.getByName(project, scope, parentAgentName);
|
|
132
|
+
if (!parent.ok || parent.value.mode !== 'agent')
|
|
133
|
+
return undefined;
|
|
134
|
+
return parent.value.id;
|
|
135
|
+
}
|
|
136
|
+
appendHistory(input) {
|
|
137
|
+
this.history.append({
|
|
138
|
+
project: input.project,
|
|
139
|
+
scope: input.scope,
|
|
140
|
+
agentName: input.agentName,
|
|
141
|
+
fromVersion: input.fromVersion,
|
|
142
|
+
toVersion: input.toVersion,
|
|
143
|
+
outcome: input.outcome,
|
|
144
|
+
reason: input.reason,
|
|
145
|
+
source: input.source,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
function toRegisterInput(project, scope, definition, parentAgentId) {
|
|
150
|
+
const input = {
|
|
151
|
+
project,
|
|
152
|
+
scope,
|
|
153
|
+
mode: 'parentAgentName' in definition ? 'subagent' : 'agent',
|
|
154
|
+
name: definition.name,
|
|
155
|
+
description: definition.description,
|
|
156
|
+
instructions: definition.instructions,
|
|
157
|
+
};
|
|
158
|
+
if (definition.capabilities !== undefined)
|
|
159
|
+
input.capabilities = definition.capabilities;
|
|
160
|
+
if (definition.permissions !== undefined)
|
|
161
|
+
input.permissions = definition.permissions;
|
|
162
|
+
if (definition.memory !== undefined)
|
|
163
|
+
input.memory = definition.memory;
|
|
164
|
+
if (definition.workflows !== undefined)
|
|
165
|
+
input.workflows = definition.workflows;
|
|
166
|
+
if (definition.skills !== undefined)
|
|
167
|
+
input.skills = definition.skills;
|
|
168
|
+
if (definition.adapters !== undefined)
|
|
169
|
+
input.adapters = definition.adapters;
|
|
170
|
+
if (parentAgentId !== undefined)
|
|
171
|
+
input.parentAgentId = parentAgentId;
|
|
172
|
+
return input;
|
|
173
|
+
}
|
|
174
|
+
function isByteEqualToCanonical(existing, definition) {
|
|
175
|
+
if (existing.description !== definition.description)
|
|
176
|
+
return false;
|
|
177
|
+
if (existing.instructions.value !== definition.instructions.value)
|
|
178
|
+
return false;
|
|
179
|
+
if (!adaptersEqual(existing.adapters, definition.adapters ?? {}))
|
|
180
|
+
return false;
|
|
181
|
+
if (!arraysEqual(existing.capabilities, definition.capabilities ?? []))
|
|
182
|
+
return false;
|
|
183
|
+
if (!arraysEqual(existing.workflows, definition.workflows ?? []))
|
|
184
|
+
return false;
|
|
185
|
+
if (!arraysEqual(existing.skills, definition.skills ?? []))
|
|
186
|
+
return false;
|
|
187
|
+
return true;
|
|
188
|
+
}
|
|
189
|
+
function adaptersEqual(a, b) {
|
|
190
|
+
return JSON.stringify(a ?? {}) === JSON.stringify(b ?? {});
|
|
191
|
+
}
|
|
192
|
+
function arraysEqual(a, b) {
|
|
193
|
+
if (a.length !== b.length)
|
|
194
|
+
return false;
|
|
195
|
+
for (let i = 0; i < a.length; i += 1) {
|
|
196
|
+
if (a[i] !== b[i])
|
|
197
|
+
return false;
|
|
198
|
+
}
|
|
199
|
+
return true;
|
|
200
|
+
}
|
|
201
|
+
function readPromptContractVersion(agent) {
|
|
202
|
+
const opencode = agent.adapters?.opencode;
|
|
203
|
+
if (opencode === undefined)
|
|
204
|
+
return null;
|
|
205
|
+
const options = opencode.config?.options;
|
|
206
|
+
const value = options?.vgxnessPromptContractVersion;
|
|
207
|
+
if (typeof value !== 'number' || !Number.isInteger(value))
|
|
208
|
+
return null;
|
|
209
|
+
return value;
|
|
210
|
+
}
|
|
211
|
+
function outcomeReason(outcome, fromVersion, toVersion, existed) {
|
|
212
|
+
if (outcome === 'created')
|
|
213
|
+
return `created canonical row at v${toVersion}`;
|
|
214
|
+
if (outcome === 'upgraded')
|
|
215
|
+
return `upgraded v${fromVersion ?? 'unknown'} -> v${toVersion}`;
|
|
216
|
+
if (outcome === 'overwrote-custom-instructions')
|
|
217
|
+
return `overwrote customized row (was v${fromVersion ?? 'unknown'}) with v${toVersion} canonical`;
|
|
218
|
+
return existed ? `noop at v${toVersion}` : `noop at v${toVersion}`;
|
|
219
|
+
}
|
|
220
|
+
function ok(value) {
|
|
221
|
+
return { ok: true, value };
|
|
222
|
+
}
|
|
223
|
+
function validationFailure(message) {
|
|
224
|
+
return { ok: false, error: { code: 'validation_failed', message } };
|
|
225
|
+
}
|
|
226
|
+
function fail(message, cause) {
|
|
227
|
+
const error = { code: 'validation_failed', message };
|
|
228
|
+
if (cause !== undefined)
|
|
229
|
+
error.cause = cause;
|
|
230
|
+
return { ok: false, error };
|
|
231
|
+
}
|