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
|
@@ -1,368 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { canonicalDefaultAgentName } from '../agents/canonical-agent-manifest.js';
|
|
3
|
-
import { normalizeSddPhaseInput } from '../sdd/schema.js';
|
|
4
|
-
import { skillLookupContexts } from './personal-skills.js';
|
|
5
|
-
export class SkillResolver {
|
|
6
|
-
skills;
|
|
7
|
-
agents;
|
|
8
|
-
constructor(skills, agents) {
|
|
9
|
-
this.skills = skills;
|
|
10
|
-
this.agents = agents;
|
|
11
|
-
}
|
|
12
|
-
resolve(input) {
|
|
13
|
-
const agent = this.resolveAgent(input);
|
|
14
|
-
if (!agent.ok)
|
|
15
|
-
return agent;
|
|
16
|
-
const contextProject = input.project ?? agent.value.agent?.project;
|
|
17
|
-
const contextScope = input.scope ?? agent.value.agent?.scope ?? 'project';
|
|
18
|
-
const targetCandidates = this.targetCandidates(input, agent.value.agent);
|
|
19
|
-
const attachmentCandidates = this.attachmentCandidates(targetCandidates);
|
|
20
|
-
if (!attachmentCandidates.ok)
|
|
21
|
-
return attachmentCandidates;
|
|
22
|
-
const candidates = [...this.agentSkillCandidates(agent.value.agent), ...attachmentCandidates.value];
|
|
23
|
-
const bySkill = new Map();
|
|
24
|
-
const skipped = [];
|
|
25
|
-
const diagnosticSkills = new Map();
|
|
26
|
-
const diagnostics = [];
|
|
27
|
-
const provider = input.providerAdapter ?? 'unknown';
|
|
28
|
-
const providerState = provider === 'opencode' ? 'preview-only' : 'unknown';
|
|
29
|
-
for (const candidate of candidates) {
|
|
30
|
-
const skillResult = this.resolveSkill(candidate, contextProject, contextScope);
|
|
31
|
-
if (!skillResult.ok) {
|
|
32
|
-
skipped.push(skippedResolution(candidate.source, skillResult.error.message, candidate.skillId, candidate.name));
|
|
33
|
-
addSkippedDiagnostic(diagnosticSkills, diagnostics, candidate, skillResult.error.message, providerState, skillResult.error.code === 'not_found' ? 'unknown' : 'inactive');
|
|
34
|
-
continue;
|
|
35
|
-
}
|
|
36
|
-
const versionResult = this.resolveVersion(skillResult.value, candidate.versionId);
|
|
37
|
-
if (!versionResult.ok) {
|
|
38
|
-
skipped.push({ source: candidate.source, skillId: skillResult.value.id, name: skillResult.value.name, reason: versionResult.error.message });
|
|
39
|
-
addSkippedDiagnostic(diagnosticSkills, diagnostics, candidate, versionResult.error.message, providerState, 'inactive', skillResult.value.name);
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
const existing = bySkill.get(skillResult.value.id);
|
|
43
|
-
if (existing !== undefined) {
|
|
44
|
-
existing.sources.push(candidate.source);
|
|
45
|
-
const status = diagnosticSkills.get(skillResult.value.name);
|
|
46
|
-
if (status !== undefined) {
|
|
47
|
-
status.attachments.declared += 1;
|
|
48
|
-
status.attachments.resolved += 1;
|
|
49
|
-
}
|
|
50
|
-
continue;
|
|
51
|
-
}
|
|
52
|
-
bySkill.set(skillResult.value.id, { skill: skillResult.value, version: versionResult.value, sources: [candidate.source] });
|
|
53
|
-
diagnosticSkills.set(skillResult.value.name, {
|
|
54
|
-
name: skillResult.value.name,
|
|
55
|
-
registryState: 'active',
|
|
56
|
-
activeVersion: versionResult.value.version,
|
|
57
|
-
payloadState: 'preview-only',
|
|
58
|
-
providerState,
|
|
59
|
-
included: true,
|
|
60
|
-
reason: null,
|
|
61
|
-
attachments: { declared: 1, resolved: 1, missing: 0 },
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
if (providerState === 'preview-only') {
|
|
65
|
-
diagnostics.push({
|
|
66
|
-
code: 'SKILL_PROVIDER_PREVIEW_ONLY',
|
|
67
|
-
severity: 'info',
|
|
68
|
-
message: 'Skill payload is preview/context-only for OpenCode and does not install or native-load skills.',
|
|
69
|
-
details: { provider, providerState },
|
|
70
|
-
});
|
|
71
|
-
diagnostics.push({
|
|
72
|
-
code: 'SKILL_PROVIDER_NATIVE_UNSUPPORTED',
|
|
73
|
-
severity: 'info',
|
|
74
|
-
message: 'OpenCode native skill loading is not implemented by VGXNESS for this payload.',
|
|
75
|
-
details: { provider, providerState, installsNativeSkills: false, mutatesProviderConfig: false },
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
let usageRecorded = 0;
|
|
79
|
-
if (input.runId !== undefined && input.recordUsage !== undefined) {
|
|
80
|
-
for (const resolved of bySkill.values()) {
|
|
81
|
-
const usage = this.recordResolvedUsage(resolved, input.runId, input.recordUsage);
|
|
82
|
-
if (!usage.ok)
|
|
83
|
-
return usage;
|
|
84
|
-
usageRecorded += 1;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return ok({
|
|
88
|
-
context: {
|
|
89
|
-
...(contextProject !== undefined ? { project: contextProject } : {}),
|
|
90
|
-
...(contextScope !== undefined ? { scope: contextScope } : {}),
|
|
91
|
-
...(agent.value.agent?.id !== undefined ? { agentId: agent.value.agent.id } : {}),
|
|
92
|
-
...(agent.value.agent?.name !== undefined ? { agentName: agent.value.agent.name } : {}),
|
|
93
|
-
...(input.workflow !== undefined ? { workflow: input.workflow } : {}),
|
|
94
|
-
...(input.phase !== undefined ? { phase: input.phase } : {}),
|
|
95
|
-
...(input.intentSignals !== undefined && input.intentSignals.length > 0 ? { intentSignals: normalizedIntentSignals(input.intentSignals) } : {}),
|
|
96
|
-
...(input.providerAdapter !== undefined ? { providerAdapter: input.providerAdapter } : {}),
|
|
97
|
-
...(input.runId !== undefined ? { runId: input.runId } : {}),
|
|
98
|
-
},
|
|
99
|
-
skills: [...bySkill.values()].map(toResolvedSkill),
|
|
100
|
-
skipped,
|
|
101
|
-
skillDiagnostics: buildDiagnosticsSummary(provider, providerState, diagnosticSkills, diagnostics),
|
|
102
|
-
...(agent.value.warning !== undefined ? { warnings: [agent.value.warning] } : {}),
|
|
103
|
-
usageRecorded,
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
resolveAgent(input) {
|
|
107
|
-
if (input.agentId !== undefined) {
|
|
108
|
-
if (input.project === undefined) {
|
|
109
|
-
const byId = this.agents.getById(input.agentId);
|
|
110
|
-
return byId.ok ? ok({ agent: byId.value }) : byId;
|
|
111
|
-
}
|
|
112
|
-
const selected = resolveAgentSelector({ selector: input.agentId, project: input.project, scope: input.scope ?? 'project' }, { getById: (id) => this.agents.getById(id), getByName: (project, scope, name) => this.agents.getByName(project, scope, name) });
|
|
113
|
-
if (selected.ok)
|
|
114
|
-
return ok({ agent: selected.value.agent, ...(selected.value.warning !== undefined ? { warning: selected.value.warning } : {}) });
|
|
115
|
-
if (selected.error.code !== 'not_found')
|
|
116
|
-
return selected;
|
|
117
|
-
const fallback = this.resolveAgentNameFallback(input);
|
|
118
|
-
if (fallback.ok && fallback.value.agent !== undefined) {
|
|
119
|
-
const warning = `AGENT_SELECTOR_PROVIDER_ALIAS_FALLBACK: selector "${input.agentId}" did not match a VGXNESS registry agent; resolved display/provider name to canonical agent "${fallback.value.agent.name}" (${fallback.value.agent.id}).`;
|
|
120
|
-
return ok({ agent: fallback.value.agent, warning });
|
|
121
|
-
}
|
|
122
|
-
return selected;
|
|
123
|
-
}
|
|
124
|
-
if (input.agentName === undefined)
|
|
125
|
-
return ok({});
|
|
126
|
-
if (input.project === undefined)
|
|
127
|
-
return validationFailure('--project is required when resolving by agent name');
|
|
128
|
-
return this.resolveAgentNameFallback(input);
|
|
129
|
-
}
|
|
130
|
-
resolveAgentNameFallback(input) {
|
|
131
|
-
if (input.project === undefined)
|
|
132
|
-
return validationFailure('--project is required when resolving by agent name');
|
|
133
|
-
for (const name of providerAgentNameCandidates(input.agentName, input.agentId)) {
|
|
134
|
-
const selected = resolveAgentSelector({ selector: name, project: input.project, scope: input.scope ?? 'project' }, { getById: (id) => this.agents.getById(id), getByName: (project, scope, agentName) => this.agents.getByName(project, scope, agentName) });
|
|
135
|
-
if (selected.ok)
|
|
136
|
-
return ok({ agent: selected.value.agent });
|
|
137
|
-
if (selected.error.code !== 'not_found')
|
|
138
|
-
return selected;
|
|
139
|
-
}
|
|
140
|
-
if (input.agentName === undefined)
|
|
141
|
-
return ok({});
|
|
142
|
-
const exact = this.agents.getByName(input.project, input.scope ?? 'project', input.agentName);
|
|
143
|
-
return exact.ok ? ok({ agent: exact.value }) : exact;
|
|
144
|
-
}
|
|
145
|
-
targetCandidates(input, agent) {
|
|
146
|
-
const targets = [];
|
|
147
|
-
if (agent !== undefined) {
|
|
148
|
-
targets.push({ targetType: agent.mode, targetKey: agent.id });
|
|
149
|
-
targets.push({ targetType: agent.mode, targetKey: agent.name });
|
|
150
|
-
targets.push({ targetType: agent.mode, targetKey: `${agent.project}/${agent.scope}/${agent.name}` });
|
|
151
|
-
}
|
|
152
|
-
const phases = phaseTargetKeys(input.workflow, input.phase);
|
|
153
|
-
if (input.workflow !== undefined) {
|
|
154
|
-
for (const phase of phases)
|
|
155
|
-
targets.push({ targetType: 'workflow-phase', targetKey: `${input.workflow}:${phase}` });
|
|
156
|
-
}
|
|
157
|
-
for (const phase of phases)
|
|
158
|
-
targets.push({ targetType: 'workflow-phase', targetKey: phase });
|
|
159
|
-
for (const signal of normalizedIntentSignals(input.intentSignals))
|
|
160
|
-
targets.push({ targetType: 'intent-signal', targetKey: signal });
|
|
161
|
-
if (input.providerAdapter !== undefined)
|
|
162
|
-
targets.push({ targetType: 'provider-adapter', targetKey: input.providerAdapter });
|
|
163
|
-
return dedupeTargets(targets);
|
|
164
|
-
}
|
|
165
|
-
agentSkillCandidates(agent) {
|
|
166
|
-
if (agent === undefined)
|
|
167
|
-
return [];
|
|
168
|
-
return agent.skills.map((name) => ({
|
|
169
|
-
name,
|
|
170
|
-
source: { kind: 'agent-definition', targetType: agent.mode, targetKey: agent.id, reason: 'agent.skills' },
|
|
171
|
-
}));
|
|
172
|
-
}
|
|
173
|
-
attachmentCandidates(targets) {
|
|
174
|
-
const attachments = this.skills.listAttachmentsForTargets(targets);
|
|
175
|
-
if (!attachments.ok)
|
|
176
|
-
return attachments;
|
|
177
|
-
return ok(attachments.value.map((attachment) => {
|
|
178
|
-
const candidate = { skillId: attachment.skillId, source: attachmentSource(attachment) };
|
|
179
|
-
if (attachment.versionId !== undefined)
|
|
180
|
-
candidate.versionId = attachment.versionId;
|
|
181
|
-
return candidate;
|
|
182
|
-
}));
|
|
183
|
-
}
|
|
184
|
-
resolveSkill(candidate, project, scope) {
|
|
185
|
-
if (candidate.skillId !== undefined)
|
|
186
|
-
return this.skills.getById(candidate.skillId);
|
|
187
|
-
if (candidate.name === undefined)
|
|
188
|
-
return validationFailure('Resolved skill candidate has neither skill id nor name');
|
|
189
|
-
if (project === undefined)
|
|
190
|
-
return validationFailure(`Skill ${candidate.name} needs a project context`);
|
|
191
|
-
let lastMissing;
|
|
192
|
-
for (const context of skillLookupContexts(project, scope)) {
|
|
193
|
-
const result = this.skills.getByName(context.project, context.scope, candidate.name);
|
|
194
|
-
if (result.ok)
|
|
195
|
-
return result;
|
|
196
|
-
if (result.error.code !== 'not_found')
|
|
197
|
-
return result;
|
|
198
|
-
lastMissing = result;
|
|
199
|
-
}
|
|
200
|
-
return lastMissing ?? this.skills.getByName(project, scope, candidate.name);
|
|
201
|
-
}
|
|
202
|
-
resolveVersion(skill, candidateVersionId) {
|
|
203
|
-
const versionId = candidateVersionId ?? skill.currentVersionId;
|
|
204
|
-
if (versionId === undefined)
|
|
205
|
-
return validationFailure(`Skill ${skill.name} has no current version`);
|
|
206
|
-
const version = this.skills.getVersion(versionId);
|
|
207
|
-
if (!version.ok)
|
|
208
|
-
return version;
|
|
209
|
-
if (version.value.status !== 'active')
|
|
210
|
-
return validationFailure(`Skill ${skill.name} version ${version.value.version} is ${version.value.status}, not active`);
|
|
211
|
-
return version;
|
|
212
|
-
}
|
|
213
|
-
recordResolvedUsage(resolved, runId, outcome) {
|
|
214
|
-
const firstAttachment = resolved.sources.find((source) => source.kind === 'attachment');
|
|
215
|
-
const input = {
|
|
216
|
-
skillId: resolved.skill.id,
|
|
217
|
-
versionId: resolved.version.id,
|
|
218
|
-
runId,
|
|
219
|
-
outcome,
|
|
220
|
-
notes: `skill resolution v1 ${outcome}`,
|
|
221
|
-
};
|
|
222
|
-
if (firstAttachment?.targetType !== undefined && firstAttachment.targetKey !== undefined) {
|
|
223
|
-
input.targetType = firstAttachment.targetType;
|
|
224
|
-
input.targetKey = firstAttachment.targetKey;
|
|
225
|
-
}
|
|
226
|
-
return this.skills.recordUsage(input);
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
function toResolvedSkill(value) {
|
|
230
|
-
const sourceMetadata = value.version.source.inlineMetadata ?? {};
|
|
231
|
-
const summary = stringMetadata(sourceMetadata.summary);
|
|
232
|
-
const content = stringMetadata(sourceMetadata.content);
|
|
233
|
-
return {
|
|
234
|
-
skillId: value.skill.id,
|
|
235
|
-
name: value.skill.name,
|
|
236
|
-
description: value.skill.description,
|
|
237
|
-
versionId: value.version.id,
|
|
238
|
-
version: value.version.version,
|
|
239
|
-
source: value.version.source,
|
|
240
|
-
sourceMetadata,
|
|
241
|
-
...(summary !== undefined ? { summary } : {}),
|
|
242
|
-
...(content !== undefined ? { content } : {}),
|
|
243
|
-
attachmentSources: value.sources,
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
function attachmentSource(attachment) {
|
|
247
|
-
const reason = stringMetadata(attachment.metadata.reason);
|
|
248
|
-
return {
|
|
249
|
-
kind: 'attachment',
|
|
250
|
-
targetType: attachment.targetType,
|
|
251
|
-
targetKey: attachment.targetKey,
|
|
252
|
-
...(reason !== undefined ? { reason } : {}),
|
|
253
|
-
};
|
|
254
|
-
}
|
|
255
|
-
function dedupeTargets(targets) {
|
|
256
|
-
const seen = new Set();
|
|
257
|
-
return targets.filter((target) => {
|
|
258
|
-
const key = `${target.targetType}:${target.targetKey}`;
|
|
259
|
-
if (seen.has(key))
|
|
260
|
-
return false;
|
|
261
|
-
seen.add(key);
|
|
262
|
-
return true;
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
function phaseTargetKeys(workflow, phase) {
|
|
266
|
-
if (phase === undefined)
|
|
267
|
-
return [];
|
|
268
|
-
if (!isSddWorkflow(workflow))
|
|
269
|
-
return [phase];
|
|
270
|
-
const normalized = normalizeSddPhaseInput(phase);
|
|
271
|
-
if (normalized === 'apply-progress')
|
|
272
|
-
return ['apply-progress', 'apply'];
|
|
273
|
-
return normalized === undefined || normalized === phase ? [phase] : [normalized, phase];
|
|
274
|
-
}
|
|
275
|
-
function isSddWorkflow(workflow) {
|
|
276
|
-
return workflow?.trim().toLowerCase() === 'sdd';
|
|
277
|
-
}
|
|
278
|
-
function normalizedIntentSignals(signals) {
|
|
279
|
-
return [...new Set((signals ?? []).map((signal) => signal.trim().toLowerCase()).filter(Boolean))];
|
|
280
|
-
}
|
|
281
|
-
function providerAgentNameCandidates(agentName, agentId) {
|
|
282
|
-
const candidates = [];
|
|
283
|
-
const add = (value) => {
|
|
284
|
-
const normalized = value?.trim();
|
|
285
|
-
if (normalized === undefined || normalized.length === 0 || candidates.includes(normalized))
|
|
286
|
-
return;
|
|
287
|
-
candidates.push(normalized);
|
|
288
|
-
};
|
|
289
|
-
add(agentName);
|
|
290
|
-
add(slugAgentDisplayName(agentName));
|
|
291
|
-
if (isProviderManagerAlias(agentId) || isProviderManagerAlias(agentName))
|
|
292
|
-
add(canonicalDefaultAgentName);
|
|
293
|
-
return candidates;
|
|
294
|
-
}
|
|
295
|
-
function slugAgentDisplayName(value) {
|
|
296
|
-
const normalized = value
|
|
297
|
-
?.trim()
|
|
298
|
-
.toLowerCase()
|
|
299
|
-
.replace(/[^a-z0-9]+/g, '-')
|
|
300
|
-
.replace(/^-+|-+$/g, '');
|
|
301
|
-
return normalized === undefined || normalized.length === 0 ? undefined : normalized;
|
|
302
|
-
}
|
|
303
|
-
function isProviderManagerAlias(value) {
|
|
304
|
-
const normalized = slugAgentDisplayName(value);
|
|
305
|
-
return normalized === 'main-manager' || normalized === 'vgxness-manager' || normalized === 'vgxness-main-manager';
|
|
306
|
-
}
|
|
307
|
-
function stringMetadata(value) {
|
|
308
|
-
return typeof value === 'string' && value.trim() ? value : undefined;
|
|
309
|
-
}
|
|
310
|
-
function skippedResolution(source, reason, skillId, name) {
|
|
311
|
-
const skipped = { source, reason };
|
|
312
|
-
if (skillId !== undefined)
|
|
313
|
-
skipped.skillId = skillId;
|
|
314
|
-
if (name !== undefined)
|
|
315
|
-
skipped.name = name;
|
|
316
|
-
return skipped;
|
|
317
|
-
}
|
|
318
|
-
function addSkippedDiagnostic(statuses, diagnostics, candidate, reason, providerState, registryState, resolvedName) {
|
|
319
|
-
const name = resolvedName ?? candidate.name ?? candidate.skillId ?? 'unknown-skill';
|
|
320
|
-
const code = candidate.source.kind === 'attachment' && candidate.skillId !== undefined && registryState === 'unknown'
|
|
321
|
-
? 'SKILL_ATTACHMENT_MISSING'
|
|
322
|
-
: registryState === 'unknown'
|
|
323
|
-
? 'SKILL_UNKNOWN'
|
|
324
|
-
: 'SKILL_INACTIVE';
|
|
325
|
-
statuses.set(name, {
|
|
326
|
-
name,
|
|
327
|
-
registryState,
|
|
328
|
-
activeVersion: null,
|
|
329
|
-
payloadState: 'unavailable',
|
|
330
|
-
providerState,
|
|
331
|
-
included: false,
|
|
332
|
-
reason,
|
|
333
|
-
attachments: { declared: 1, resolved: 0, missing: 1 },
|
|
334
|
-
});
|
|
335
|
-
diagnostics.push({
|
|
336
|
-
code,
|
|
337
|
-
severity: 'warning',
|
|
338
|
-
skill: name,
|
|
339
|
-
message: code === 'SKILL_ATTACHMENT_MISSING'
|
|
340
|
-
? `Skill attachment references ${name}, but the registry skill could not be resolved.`
|
|
341
|
-
: code === 'SKILL_UNKNOWN'
|
|
342
|
-
? `Skill ${name} is not registered for the requested project/scope and was not included.`
|
|
343
|
-
: `Skill ${name} is registered but has no active resolvable version and was not included.`,
|
|
344
|
-
details: { registryState, payloadState: 'unavailable', providerState, reason },
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
function buildDiagnosticsSummary(provider, providerState, statuses, diagnostics) {
|
|
348
|
-
const skills = [...statuses.values()];
|
|
349
|
-
return {
|
|
350
|
-
provider,
|
|
351
|
-
providerState,
|
|
352
|
-
summary: {
|
|
353
|
-
declared: skills.length,
|
|
354
|
-
resolved: skills.filter((skill) => skill.included).length,
|
|
355
|
-
skipped: skills.filter((skill) => !skill.included).length,
|
|
356
|
-
warnings: diagnostics.filter((diagnostic) => diagnostic.severity === 'warning').length,
|
|
357
|
-
errors: diagnostics.filter((diagnostic) => diagnostic.severity === 'error').length,
|
|
358
|
-
},
|
|
359
|
-
skills,
|
|
360
|
-
diagnostics,
|
|
361
|
-
};
|
|
362
|
-
}
|
|
363
|
-
function ok(value) {
|
|
364
|
-
return { ok: true, value };
|
|
365
|
-
}
|
|
366
|
-
function validationFailure(message) {
|
|
367
|
-
return { ok: false, error: { code: 'validation_failed', message } };
|
|
368
|
-
}
|
|
1
|
+
export * from '../application/skills/skill-resolver.js';
|
|
@@ -1,242 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { SkillRegistryService } from './skill-registry-service.js';
|
|
3
|
-
const defaultManifestPath = new URL('../../seeds/skills/skill-seed-v1.json', import.meta.url);
|
|
4
|
-
const registryBoundaryText = 'registry/context skill content only';
|
|
5
|
-
const forbiddenMetadataKeys = ['path', 'url', 'sourcePath', 'sourceUrl', 'skills.paths', 'installPath', 'generatedPath', 'remoteUrl'];
|
|
6
|
-
export class SkillSeedService {
|
|
7
|
-
database;
|
|
8
|
-
registry;
|
|
9
|
-
constructor(database) {
|
|
10
|
-
this.database = database;
|
|
11
|
-
this.registry = new SkillRegistryService(database);
|
|
12
|
-
}
|
|
13
|
-
seedFromDefaultManifest(path = defaultManifestPath) {
|
|
14
|
-
try {
|
|
15
|
-
return this.seedFromManifest(JSON.parse(readFileSync(path, 'utf8')));
|
|
16
|
-
}
|
|
17
|
-
catch (cause) {
|
|
18
|
-
return fail('Failed to load skill seed manifest', cause);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
seedFromManifest(manifest) {
|
|
22
|
-
const validation = validateManifest(manifest);
|
|
23
|
-
if (!validation.ok)
|
|
24
|
-
return validation;
|
|
25
|
-
const existingNames = new Map();
|
|
26
|
-
const existingVersions = new Map();
|
|
27
|
-
const existingAttachments = new Map();
|
|
28
|
-
for (const seed of manifest.skills) {
|
|
29
|
-
const existing = this.registry.getSkillByName(manifest.project, manifest.scope, seed.name);
|
|
30
|
-
existingNames.set(seed.name, existing.ok);
|
|
31
|
-
if (existing.ok) {
|
|
32
|
-
const details = this.registry.getSkillDetails(existing.value.id);
|
|
33
|
-
if (!details.ok)
|
|
34
|
-
return details;
|
|
35
|
-
existingVersions.set(seed.name, details.value.versions.some((version) => version.version === seed.version));
|
|
36
|
-
for (const attachment of details.value.attachments)
|
|
37
|
-
existingAttachments.set(`${seed.name}:${attachment.targetType}:${attachment.targetKey}`, true);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
const transaction = this.database.transaction(() => {
|
|
41
|
-
const skillVersionIds = new Map();
|
|
42
|
-
let skillsCreated = 0;
|
|
43
|
-
let skillsUpdated = 0;
|
|
44
|
-
let versionsCreated = 0;
|
|
45
|
-
let versionsSkipped = 0;
|
|
46
|
-
let attachmentsCreated = 0;
|
|
47
|
-
let attachmentsSkipped = 0;
|
|
48
|
-
for (const seed of manifest.skills) {
|
|
49
|
-
const skill = this.registry.registerSkill({ project: manifest.project, scope: manifest.scope, name: seed.name, description: seed.description });
|
|
50
|
-
if (!skill.ok)
|
|
51
|
-
throw new SeedLoadError(skill.error);
|
|
52
|
-
if (existingNames.get(seed.name))
|
|
53
|
-
skillsUpdated += 1;
|
|
54
|
-
else
|
|
55
|
-
skillsCreated += 1;
|
|
56
|
-
const existingVersion = existingVersions.get(seed.name) === true;
|
|
57
|
-
const version = this.registry.addSkillVersion({
|
|
58
|
-
skillId: skill.value.id,
|
|
59
|
-
version: seed.version,
|
|
60
|
-
source: { kind: 'inline', inlineMetadata: { ...seed.metadata, content: seed.content, seededBy: 'vgxness' } },
|
|
61
|
-
compatibility: compatibilityFor(seed, manifest.attachments),
|
|
62
|
-
activate: true,
|
|
63
|
-
});
|
|
64
|
-
if (!version.ok)
|
|
65
|
-
throw new SeedLoadError(version.error);
|
|
66
|
-
skillVersionIds.set(seed.name, version.value.id);
|
|
67
|
-
if (existingVersion)
|
|
68
|
-
versionsSkipped += 1;
|
|
69
|
-
else
|
|
70
|
-
versionsCreated += 1;
|
|
71
|
-
}
|
|
72
|
-
for (const attachment of manifest.attachments) {
|
|
73
|
-
const skill = this.registry.getSkillByName(manifest.project, manifest.scope, attachment.skill);
|
|
74
|
-
if (!skill.ok)
|
|
75
|
-
throw new SeedLoadError(skill.error);
|
|
76
|
-
const targetType = attachmentTargetType(attachment);
|
|
77
|
-
const targetKey = attachmentTargetKey(attachment);
|
|
78
|
-
const key = `${attachment.skill}:${targetType}:${targetKey}`;
|
|
79
|
-
const attachInput = {
|
|
80
|
-
skillId: skill.value.id,
|
|
81
|
-
targetType,
|
|
82
|
-
targetKey,
|
|
83
|
-
metadata: attachmentMetadata(attachment),
|
|
84
|
-
};
|
|
85
|
-
const versionId = skillVersionIds.get(attachment.skill);
|
|
86
|
-
const attached = this.registry.attachSkill(versionId === undefined ? attachInput : { ...attachInput, versionId });
|
|
87
|
-
if (!attached.ok)
|
|
88
|
-
throw new SeedLoadError(attached.error);
|
|
89
|
-
if (existingAttachments.get(key))
|
|
90
|
-
attachmentsSkipped += 1;
|
|
91
|
-
else
|
|
92
|
-
attachmentsCreated += 1;
|
|
93
|
-
}
|
|
94
|
-
return {
|
|
95
|
-
manifestVersion: manifest.version,
|
|
96
|
-
skillsCreated,
|
|
97
|
-
skillsUpdated,
|
|
98
|
-
versionsCreated,
|
|
99
|
-
versionsSkipped,
|
|
100
|
-
attachmentsCreated,
|
|
101
|
-
attachmentsSkipped,
|
|
102
|
-
diagnostics: [
|
|
103
|
-
{
|
|
104
|
-
level: 'info',
|
|
105
|
-
code: 'SKILL_SEED_REGISTRY_CONTEXT_ONLY',
|
|
106
|
-
message: 'Seeded VGXNESS registry/context skills only; no provider-native skill installation was performed.',
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
};
|
|
110
|
-
});
|
|
111
|
-
if (!transaction.ok && transaction.error.cause instanceof SeedLoadError)
|
|
112
|
-
return { ok: false, error: transaction.error.cause.failure };
|
|
113
|
-
return transaction;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
function validateManifest(manifest) {
|
|
117
|
-
if (manifest.version !== 1)
|
|
118
|
-
return validationFailure('Skill seed manifest version must be 1');
|
|
119
|
-
if (!manifest.project?.trim())
|
|
120
|
-
return validationFailure('Skill seed manifest project is required');
|
|
121
|
-
if (manifest.scope !== 'project' && manifest.scope !== 'personal')
|
|
122
|
-
return validationFailure('Skill seed manifest scope must be project or personal');
|
|
123
|
-
if (!Array.isArray(manifest.skills))
|
|
124
|
-
return validationFailure('Skill seed manifest skills must be an array');
|
|
125
|
-
if (!Array.isArray(manifest.attachments))
|
|
126
|
-
return validationFailure('Skill seed manifest attachments must be an array');
|
|
127
|
-
const names = new Set();
|
|
128
|
-
for (const skill of manifest.skills) {
|
|
129
|
-
const validation = validateSkillSeed(skill);
|
|
130
|
-
if (!validation.ok)
|
|
131
|
-
return validation;
|
|
132
|
-
if (names.has(skill.name))
|
|
133
|
-
return validationFailure(`Duplicate skill seed name: ${skill.name}`);
|
|
134
|
-
names.add(skill.name);
|
|
135
|
-
}
|
|
136
|
-
const attachments = new Set();
|
|
137
|
-
for (const attachment of manifest.attachments) {
|
|
138
|
-
const validation = validateAttachmentSeed(attachment, names);
|
|
139
|
-
if (!validation.ok)
|
|
140
|
-
return validation;
|
|
141
|
-
const key = `${attachmentTargetType(attachment)}:${attachmentTargetKey(attachment)}:${attachment.skill}`;
|
|
142
|
-
if (attachments.has(key))
|
|
143
|
-
return validationFailure(`Duplicate skill seed attachment: ${key}`);
|
|
144
|
-
attachments.add(key);
|
|
145
|
-
}
|
|
146
|
-
return { ok: true, value: undefined };
|
|
147
|
-
}
|
|
148
|
-
function validateSkillSeed(skill) {
|
|
149
|
-
if (!skill.name?.trim())
|
|
150
|
-
return validationFailure('Skill seed name is required');
|
|
151
|
-
if (!skill.description?.trim())
|
|
152
|
-
return validationFailure(`Skill seed ${skill.name} description is required`);
|
|
153
|
-
if (!skill.version?.trim())
|
|
154
|
-
return validationFailure(`Skill seed ${skill.name} version is required`);
|
|
155
|
-
if (!skill.content?.trim())
|
|
156
|
-
return validationFailure(`Skill seed ${skill.name} inline content is required`);
|
|
157
|
-
if (!skill.content.includes(registryBoundaryText))
|
|
158
|
-
return validationFailure(`Skill seed ${skill.name} must declare registry/context-only boundary`);
|
|
159
|
-
return rejectUnsupportedNativeInputs(skill.name, skill.metadata);
|
|
160
|
-
}
|
|
161
|
-
function validateAttachmentSeed(attachment, names) {
|
|
162
|
-
if (attachment.targetType !== undefined && !isSkillAttachmentTargetType(attachment.targetType))
|
|
163
|
-
return validationFailure(`Skill seed attachment targetType is invalid: ${String(attachment.targetType)}`);
|
|
164
|
-
const targetType = attachmentTargetType(attachment);
|
|
165
|
-
if (targetType === 'workflow-phase') {
|
|
166
|
-
if (!attachment.workflow?.trim())
|
|
167
|
-
return validationFailure('Skill seed attachment workflow is required');
|
|
168
|
-
if (!attachment.phase?.trim())
|
|
169
|
-
return validationFailure('Skill seed attachment phase is required');
|
|
170
|
-
}
|
|
171
|
-
else if (!attachment.targetKey?.trim()) {
|
|
172
|
-
return validationFailure(`Skill seed attachment targetKey is required for ${targetType}`);
|
|
173
|
-
}
|
|
174
|
-
if (!attachment.skill?.trim())
|
|
175
|
-
return validationFailure('Skill seed attachment skill is required');
|
|
176
|
-
if (!names.has(attachment.skill))
|
|
177
|
-
return validationFailure(`Skill seed attachment references unknown skill: ${attachment.skill}`);
|
|
178
|
-
return rejectUnsupportedNativeInputs(attachment.skill, attachment.metadata);
|
|
179
|
-
}
|
|
180
|
-
function rejectUnsupportedNativeInputs(name, metadata) {
|
|
181
|
-
if (metadata === undefined)
|
|
182
|
-
return { ok: true, value: undefined };
|
|
183
|
-
for (const key of Object.keys(metadata)) {
|
|
184
|
-
if (forbiddenMetadataKeys.includes(key))
|
|
185
|
-
return validationFailure(`Skill seed ${name} cannot include provider-native or remote field: ${key}`);
|
|
186
|
-
}
|
|
187
|
-
const encoded = JSON.stringify(metadata);
|
|
188
|
-
if (/https?:\/\//i.test(encoded))
|
|
189
|
-
return validationFailure(`Skill seed ${name} cannot include URL or remote skill loading metadata`);
|
|
190
|
-
if (/skills\.paths|\.opencode|SKILL\.md|generated/i.test(encoded))
|
|
191
|
-
return validationFailure(`Skill seed ${name} cannot include provider-native install metadata`);
|
|
192
|
-
return { ok: true, value: undefined };
|
|
193
|
-
}
|
|
194
|
-
function compatibilityFor(seed, attachments) {
|
|
195
|
-
const matching = attachments.filter((attachment) => attachment.skill === seed.name);
|
|
196
|
-
return {
|
|
197
|
-
targets: [...new Set(matching.map(attachmentTargetType))],
|
|
198
|
-
adapters: ['opencode'],
|
|
199
|
-
workflows: [...new Set(matching.map((attachment) => attachment.workflow).filter((workflow) => workflow !== undefined))],
|
|
200
|
-
phases: [...new Set(matching.map((attachment) => attachment.phase).filter((phase) => phase !== undefined))],
|
|
201
|
-
};
|
|
202
|
-
}
|
|
203
|
-
function attachmentMetadata(attachment) {
|
|
204
|
-
const metadata = {
|
|
205
|
-
...(attachment.metadata ?? {}),
|
|
206
|
-
...(attachment.order !== undefined ? { order: attachment.order } : {}),
|
|
207
|
-
seededBy: 'vgxness',
|
|
208
|
-
targetType: attachmentTargetType(attachment),
|
|
209
|
-
targetKey: attachmentTargetKey(attachment),
|
|
210
|
-
};
|
|
211
|
-
if (attachment.workflow !== undefined)
|
|
212
|
-
metadata.workflow = attachment.workflow;
|
|
213
|
-
if (attachment.phase !== undefined)
|
|
214
|
-
metadata.phase = attachment.phase;
|
|
215
|
-
return metadata;
|
|
216
|
-
}
|
|
217
|
-
function attachmentTargetType(attachment) {
|
|
218
|
-
return attachment.targetType ?? 'workflow-phase';
|
|
219
|
-
}
|
|
220
|
-
function attachmentTargetKey(attachment) {
|
|
221
|
-
const targetType = attachmentTargetType(attachment);
|
|
222
|
-
return targetType === 'workflow-phase' ? `${attachment.workflow}:${attachment.phase}` : attachment.targetKey ?? '';
|
|
223
|
-
}
|
|
224
|
-
function isSkillAttachmentTargetType(value) {
|
|
225
|
-
return value === 'agent' || value === 'subagent' || value === 'workflow-phase' || value === 'provider-adapter' || value === 'intent-signal';
|
|
226
|
-
}
|
|
227
|
-
function validationFailure(message) {
|
|
228
|
-
return { ok: false, error: { code: 'validation_failed', message } };
|
|
229
|
-
}
|
|
230
|
-
function fail(message, cause) {
|
|
231
|
-
const error = { code: 'validation_failed', message };
|
|
232
|
-
if (cause !== undefined)
|
|
233
|
-
error.cause = cause;
|
|
234
|
-
return { ok: false, error };
|
|
235
|
-
}
|
|
236
|
-
class SeedLoadError extends Error {
|
|
237
|
-
failure;
|
|
238
|
-
constructor(failure) {
|
|
239
|
-
super(failure.message);
|
|
240
|
-
this.failure = failure;
|
|
241
|
-
}
|
|
242
|
-
}
|
|
1
|
+
export * from '../application/skills/skill-seed-service.js';
|