@devtrack-solution/codesdd 1.2.2 → 1.2.3
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/.sdd/skills/curated/api-clean-flask-langgraph/SKILL.md +17 -17
- package/.sdd/skills/curated/devtrack-api/SKILL.md +160 -28
- package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +1 -1
- package/.sdd/skills/curated/devtrack-api/references/architecture-governance.md +8 -7
- package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +93 -0
- package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +317 -0
- package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +95 -0
- package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +295 -0
- package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +4 -4
- package/.sdd/skills/curated/devtrack-api/references/imports-lint.md +4 -0
- package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +2 -2
- package/LICENSE +1 -1
- package/README.md +243 -51
- package/bin/codesdd.js +3 -2
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +11 -558
- package/dist/cli/program.d.ts +14 -0
- package/dist/cli/program.js +645 -0
- package/dist/commands/change.js +5 -5
- package/dist/commands/completion.d.ts +1 -1
- package/dist/commands/completion.js +9 -2
- package/dist/commands/config.js +159 -20
- package/dist/commands/feedback.js +1 -1
- package/dist/commands/schema.d.ts +63 -0
- package/dist/commands/schema.js +12 -12
- package/dist/commands/sdd/backlog.d.ts +3 -0
- package/dist/commands/sdd/backlog.js +54 -0
- package/dist/commands/sdd/execution.js +147 -16
- package/dist/commands/sdd/plugin.d.ts +3 -0
- package/dist/commands/sdd/plugin.js +153 -0
- package/dist/commands/sdd/shared.js +2 -23
- package/dist/commands/sdd/skills.js +7 -0
- package/dist/commands/sdd.js +69 -12
- package/dist/commands/spec.js +9 -9
- package/dist/commands/validate.js +6 -6
- package/dist/commands/workflow/instructions.js +6 -6
- package/dist/commands/workflow/new-change.js +3 -3
- package/dist/commands/workflow/shared.d.ts +1 -1
- package/dist/commands/workflow/shared.js +4 -4
- package/dist/core/archive.js +15 -5
- package/dist/core/artifact-graph/instruction-loader.d.ts +1 -1
- package/dist/core/artifact-graph/instruction-loader.js +3 -3
- package/dist/core/artifact-graph/resolver.d.ts +4 -4
- package/dist/core/artifact-graph/resolver.js +6 -6
- package/dist/core/branding.js +3 -3
- package/dist/core/cli/command-matrix.js +10 -1
- package/dist/core/cli-command-quality.d.ts +27 -0
- package/dist/core/cli-command-quality.js +171 -0
- package/dist/core/command-generation/adapters/costrict.d.ts +1 -1
- package/dist/core/command-generation/adapters/costrict.js +2 -2
- package/dist/core/command-generation/types.d.ts +1 -1
- package/dist/core/completions/command-registry.d.ts +1 -1
- package/dist/core/completions/command-registry.js +155 -12
- package/dist/core/completions/completion-provider.d.ts +14 -1
- package/dist/core/completions/completion-provider.js +29 -1
- package/dist/core/completions/generators/bash-generator.d.ts +1 -1
- package/dist/core/completions/generators/bash-generator.js +20 -12
- package/dist/core/completions/generators/fish-generator.d.ts +9 -1
- package/dist/core/completions/generators/fish-generator.js +39 -25
- package/dist/core/completions/generators/powershell-generator.d.ts +1 -1
- package/dist/core/completions/generators/powershell-generator.js +21 -11
- package/dist/core/completions/generators/zsh-generator.d.ts +3 -6
- package/dist/core/completions/generators/zsh-generator.js +21 -42
- package/dist/core/completions/installers/bash-installer.js +6 -6
- package/dist/core/completions/installers/fish-installer.js +1 -1
- package/dist/core/completions/installers/powershell-installer.js +14 -14
- package/dist/core/completions/installers/zsh-installer.d.ts +7 -1
- package/dist/core/completions/installers/zsh-installer.js +36 -8
- package/dist/core/completions/templates/bash-templates.d.ts +1 -1
- package/dist/core/completions/templates/bash-templates.js +12 -6
- package/dist/core/completions/templates/fish-templates.d.ts +2 -2
- package/dist/core/completions/templates/fish-templates.js +20 -9
- package/dist/core/completions/templates/powershell-templates.d.ts +1 -1
- package/dist/core/completions/templates/powershell-templates.js +13 -4
- package/dist/core/completions/templates/zsh-templates.d.ts +1 -1
- package/dist/core/completions/templates/zsh-templates.js +18 -9
- package/dist/core/config-schema.d.ts +3 -1
- package/dist/core/config-schema.js +26 -1
- package/dist/core/config.d.ts +3 -3
- package/dist/core/config.js +4 -4
- package/dist/core/global-config.d.ts +41 -12
- package/dist/core/global-config.js +344 -27
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +2 -2
- package/dist/core/init.d.ts +6 -1
- package/dist/core/init.js +99 -77
- package/dist/core/legacy-cleanup.d.ts +17 -17
- package/dist/core/legacy-cleanup.js +96 -79
- package/dist/core/list.js +18 -4
- package/dist/core/migration.d.ts +3 -1
- package/dist/core/migration.js +7 -8
- package/dist/core/parsers/change-parser.js +1 -1
- package/dist/core/parsers/markdown-parser.js +2 -2
- package/dist/core/profile-sync-drift.d.ts +1 -1
- package/dist/core/profile-sync-drift.js +13 -13
- package/dist/core/project-config.d.ts +4 -4
- package/dist/core/project-config.js +11 -11
- package/dist/core/schemas/change.schema.d.ts +1 -1
- package/dist/core/schemas/change.schema.js +1 -1
- package/dist/core/schemas/spec.schema.d.ts +1 -1
- package/dist/core/schemas/spec.schema.js +1 -1
- package/dist/core/sdd/adr.js +23 -1
- package/dist/core/sdd/agent-binding.d.ts +346 -0
- package/dist/core/sdd/agent-binding.js +343 -0
- package/dist/core/sdd/backlog-cli.d.ts +16 -0
- package/dist/core/sdd/backlog-cli.js +146 -0
- package/dist/core/sdd/backlog-conflict-policy.d.ts +58 -0
- package/dist/core/sdd/backlog-conflict-policy.js +230 -0
- package/dist/core/sdd/backlog-projection.d.ts +8 -0
- package/dist/core/sdd/backlog-projection.js +89 -0
- package/dist/core/sdd/backlog-provider-contract.d.ts +252 -0
- package/dist/core/sdd/backlog-provider-contract.js +158 -0
- package/dist/core/sdd/bootstrap.js +2 -2
- package/dist/core/sdd/check.d.ts +42 -0
- package/dist/core/sdd/check.js +22 -22
- package/dist/core/sdd/contract.d.ts +13 -0
- package/dist/core/sdd/contract.js +36 -0
- package/dist/core/sdd/coordination/coordination-adapters.d.ts +38 -0
- package/dist/core/sdd/coordination/coordination-adapters.js +139 -1
- package/dist/core/sdd/deepagent-contracts.d.ts +276 -0
- package/dist/core/sdd/deepagent-contracts.js +173 -0
- package/dist/core/sdd/deepagents/adr-governor.d.ts +2 -0
- package/dist/core/sdd/deepagents/adr-governor.js +30 -0
- package/dist/core/sdd/deepagents/backend.d.ts +63 -0
- package/dist/core/sdd/deepagents/backend.js +174 -0
- package/dist/core/sdd/deepagents/codesdd-tools.d.ts +39 -0
- package/dist/core/sdd/deepagents/codesdd-tools.js +83 -0
- package/dist/core/sdd/deepagents/evidence-mapper.d.ts +86 -0
- package/dist/core/sdd/deepagents/evidence-mapper.js +178 -0
- package/dist/core/sdd/deepagents/model-provider.d.ts +53 -0
- package/dist/core/sdd/deepagents/model-provider.js +379 -0
- package/dist/core/sdd/deepagents/policy-enforcement.d.ts +30 -0
- package/dist/core/sdd/deepagents/policy-enforcement.js +90 -0
- package/dist/core/sdd/deepagents/policy.d.ts +75 -0
- package/dist/core/sdd/deepagents/policy.js +358 -0
- package/dist/core/sdd/deepagents/quality-witness.d.ts +3 -0
- package/dist/core/sdd/deepagents/quality-witness.js +77 -0
- package/dist/core/sdd/deepagents/reversa-subagents.d.ts +75 -0
- package/dist/core/sdd/deepagents/reversa-subagents.js +182 -0
- package/dist/core/sdd/deepagents/runtime-factory.d.ts +90 -0
- package/dist/core/sdd/deepagents/runtime-factory.js +231 -0
- package/dist/core/sdd/deepagents/runtime-loader.d.ts +16 -0
- package/dist/core/sdd/deepagents/runtime-loader.js +65 -0
- package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
- package/dist/core/sdd/default-bootstrap-files.js +36 -2
- package/dist/core/sdd/default-skills.d.ts +30 -0
- package/dist/core/sdd/default-skills.js +181 -5
- package/dist/core/sdd/devtrack-api-appliance.d.ts +84 -0
- package/dist/core/sdd/devtrack-api-appliance.js +257 -0
- package/dist/core/sdd/devtrack-api-architecture.d.ts +31 -0
- package/dist/core/sdd/devtrack-api-architecture.js +608 -0
- package/dist/core/sdd/devtrack-api-import-boundary.d.ts +19 -0
- package/dist/core/sdd/devtrack-api-import-boundary.js +32 -0
- package/dist/core/sdd/diagnose.d.ts +59 -0
- package/dist/core/sdd/diagnose.js +37 -37
- package/dist/core/sdd/docs-sync.js +33 -5
- package/dist/core/sdd/domain/post-active-validation.d.ts +7 -0
- package/dist/core/sdd/domain/post-active-validation.js +61 -0
- package/dist/core/sdd/domain/transition-engine.js +1 -0
- package/dist/core/sdd/entity-reference.d.ts +5 -0
- package/dist/core/sdd/entity-reference.js +22 -0
- package/dist/core/sdd/governance-backfill.d.ts +31 -0
- package/dist/core/sdd/governance-backfill.js +359 -0
- package/dist/core/sdd/governance-parser.d.ts +21 -0
- package/dist/core/sdd/governance-parser.js +91 -0
- package/dist/core/sdd/governance-schemas.d.ts +245 -0
- package/dist/core/sdd/governance-schemas.js +143 -0
- package/dist/core/sdd/{import-openspec.d.ts → import-legacy-spec.d.ts} +7 -7
- package/dist/core/sdd/{import-openspec.js → import-legacy-spec.js} +21 -29
- package/dist/core/sdd/init.d.ts +3 -0
- package/dist/core/sdd/init.js +6 -3
- package/dist/core/sdd/json-schema.js +100 -6
- package/dist/core/sdd/knowledge-graph.d.ts +45 -0
- package/dist/core/sdd/knowledge-graph.js +288 -0
- package/dist/core/sdd/legacy-operations.js +431 -43
- package/dist/core/sdd/lenses.d.ts +1 -0
- package/dist/core/sdd/lenses.js +29 -1
- package/dist/core/sdd/migrate-workspace.js +56 -2
- package/dist/core/sdd/migrate.d.ts +1 -1
- package/dist/core/sdd/migrate.js +36 -2
- package/dist/core/sdd/package-structure-gate.d.ts +83 -0
- package/dist/core/sdd/package-structure-gate.js +362 -0
- package/dist/core/sdd/parallel-feat-automation.d.ts +152 -0
- package/dist/core/sdd/parallel-feat-automation.js +212 -0
- package/dist/core/sdd/plugin-broker.d.ts +558 -0
- package/dist/core/sdd/plugin-broker.js +482 -0
- package/dist/core/sdd/plugin-certification.d.ts +79 -0
- package/dist/core/sdd/plugin-certification.js +453 -0
- package/dist/core/sdd/plugin-cli.d.ts +109 -0
- package/dist/core/sdd/plugin-cli.js +198 -0
- package/dist/core/sdd/plugin-evidence.d.ts +275 -0
- package/dist/core/sdd/plugin-evidence.js +307 -0
- package/dist/core/sdd/plugin-manifest.d.ts +164 -0
- package/dist/core/sdd/plugin-manifest.js +215 -0
- package/dist/core/sdd/plugin-policy-pack.d.ts +88 -0
- package/dist/core/sdd/plugin-policy-pack.js +236 -0
- package/dist/core/sdd/plugin-policy.d.ts +68 -0
- package/dist/core/sdd/plugin-policy.js +212 -0
- package/dist/core/sdd/plugin-registry.d.ts +311 -0
- package/dist/core/sdd/plugin-registry.js +138 -0
- package/dist/core/sdd/plugin-skill-binding.d.ts +151 -0
- package/dist/core/sdd/plugin-skill-binding.js +339 -0
- package/dist/core/sdd/quality-artifact-manifest-validator.d.ts +28 -0
- package/dist/core/sdd/quality-artifact-manifest-validator.js +167 -0
- package/dist/core/sdd/quality-evidence-renderer.d.ts +65 -0
- package/dist/core/sdd/quality-evidence-renderer.js +218 -0
- package/dist/core/sdd/quality-scenario-runner.d.ts +42 -0
- package/dist/core/sdd/quality-scenario-runner.js +613 -0
- package/dist/core/sdd/quality-validation.d.ts +547 -0
- package/dist/core/sdd/quality-validation.js +239 -0
- package/dist/core/sdd/resolve-project-root.d.ts +2 -2
- package/dist/core/sdd/resolve-project-root.js +11 -5
- package/dist/core/sdd/sanitize.d.ts +30 -1
- package/dist/core/sdd/sanitize.js +23 -23
- package/dist/core/sdd/services/agent-run.service.d.ts +65 -0
- package/dist/core/sdd/services/agent-run.service.js +189 -0
- package/dist/core/sdd/services/breakdown.service.js +2 -1
- package/dist/core/sdd/services/context.service.js +18 -16
- package/dist/core/sdd/services/debate.service.js +15 -2
- package/dist/core/sdd/services/feature-lint.service.d.ts +22 -0
- package/dist/core/sdd/services/feature-lint.service.js +105 -5
- package/dist/core/sdd/services/finalize.service.d.ts +80 -0
- package/dist/core/sdd/services/finalize.service.js +323 -24
- package/dist/core/sdd/services/frontend-gap.service.js +22 -7
- package/dist/core/sdd/services/governance-control-plane-runtime-adapters.d.ts +17 -0
- package/dist/core/sdd/services/governance-control-plane-runtime-adapters.js +38 -0
- package/dist/core/sdd/services/governance-control-plane.service.d.ts +66 -0
- package/dist/core/sdd/services/governance-control-plane.service.js +134 -0
- package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
- package/dist/core/sdd/services/legacy-capability.service.d.ts +10 -7
- package/dist/core/sdd/services/legacy-capability.service.js +38 -21
- package/dist/core/sdd/services/mcp-runtime.service.d.ts +123 -8
- package/dist/core/sdd/services/mcp-runtime.service.js +1085 -33
- package/dist/core/sdd/services/onboard.service.js +2 -1
- package/dist/core/sdd/services/rebuild.service.js +6 -1
- package/dist/core/sdd/services/skills-sync.service.d.ts +17 -5
- package/dist/core/sdd/services/skills-sync.service.js +55 -2
- package/dist/core/sdd/services/start.service.js +6 -4
- package/dist/core/sdd/skill-bundles-curation-schema.d.ts +66 -0
- package/dist/core/sdd/skill-bundles-curation-schema.js +52 -0
- package/dist/core/sdd/skill-evidence.d.ts +19 -0
- package/dist/core/sdd/skill-evidence.js +38 -0
- package/dist/core/sdd/skill-policy-pool.d.ts +46 -0
- package/dist/core/sdd/skill-policy-pool.js +185 -0
- package/dist/core/sdd/state.d.ts +22 -0
- package/dist/core/sdd/state.js +66 -41
- package/dist/core/sdd/structural-health.d.ts +42 -42
- package/dist/core/sdd/types.d.ts +33 -7
- package/dist/core/sdd/types.js +17 -0
- package/dist/core/sdd/upgrade-to-codesdd.d.ts +45 -0
- package/dist/core/sdd/upgrade-to-codesdd.js +179 -0
- package/dist/core/sdd/workspace-schemas.d.ts +285 -14
- package/dist/core/sdd/workspace-schemas.js +148 -0
- package/dist/core/sdd/write-manifest.js +22 -4
- package/dist/core/shared/skill-generation.d.ts +1 -1
- package/dist/core/shared/skill-generation.js +15 -15
- package/dist/core/shared/tool-detection.d.ts +3 -3
- package/dist/core/shared/tool-detection.js +14 -14
- package/dist/core/specs-apply.js +6 -6
- package/dist/core/templates/index.d.ts +1 -1
- package/dist/core/templates/index.js +1 -1
- package/dist/core/templates/workflows/apply-change.js +14 -14
- package/dist/core/templates/workflows/archive-change.js +32 -32
- package/dist/core/templates/workflows/bulk-archive-change.js +25 -25
- package/dist/core/templates/workflows/continue-change.js +12 -12
- package/dist/core/templates/workflows/explore.js +29 -29
- package/dist/core/templates/workflows/feedback.js +6 -6
- package/dist/core/templates/workflows/ff-change.js +24 -24
- package/dist/core/templates/workflows/new-change.js +20 -20
- package/dist/core/templates/workflows/onboard.js +33 -33
- package/dist/core/templates/workflows/propose.js +23 -23
- package/dist/core/templates/workflows/sdd.js +8 -8
- package/dist/core/templates/workflows/sync-specs.js +19 -19
- package/dist/core/templates/workflows/verify-change.js +17 -17
- package/dist/core/update.d.ts +2 -2
- package/dist/core/update.js +16 -15
- package/dist/core/validation/constants.d.ts +1 -1
- package/dist/core/validation/constants.js +1 -1
- package/dist/core/view.js +11 -11
- package/dist/telemetry/config.d.ts +2 -1
- package/dist/telemetry/config.js +17 -8
- package/dist/telemetry/index.d.ts +10 -2
- package/dist/telemetry/index.js +40 -7
- package/dist/ui/ascii-patterns.d.ts +2 -2
- package/dist/ui/ascii-patterns.js +2 -2
- package/dist/ui/welcome-screen.js +2 -2
- package/dist/utils/change-metadata.d.ts +4 -4
- package/dist/utils/change-metadata.js +6 -6
- package/dist/utils/change-utils.d.ts +3 -3
- package/dist/utils/change-utils.js +5 -5
- package/dist/utils/file-system.js +1 -1
- package/dist/utils/interactive.js +1 -1
- package/dist/utils/item-discovery.js +4 -4
- package/dist/utils/legacy-spec-compat.d.ts +2 -0
- package/dist/utils/legacy-spec-compat.js +2 -0
- package/dist/utils/shell-detection.d.ts +1 -0
- package/dist/utils/shell-detection.js +16 -0
- package/package.json +27 -17
- package/schemas/sdd/1-spec.schema.json +1 -1
- package/schemas/sdd/2-plan.schema.json +73 -1
- package/schemas/sdd/3-tasks.schema.json +73 -1
- package/schemas/sdd/4-changelog.schema.json +1 -1
- package/schemas/sdd/5-quality.schema.json +442 -2
- package/schemas/sdd/adr.schema.json +148 -0
- package/schemas/sdd/agent-binding-adapter.schema.json +210 -0
- package/schemas/sdd/agent-binding-resolution.schema.json +338 -0
- package/schemas/sdd/backlog-projection-plan.schema.json +180 -0
- package/schemas/sdd/backlog-provider-contract.schema.json +260 -0
- package/schemas/sdd/codesdd-plugin.schema.json +474 -0
- package/schemas/sdd/debate.schema.json +244 -0
- package/schemas/sdd/deepagent-decision-evidence.schema.json +58 -0
- package/schemas/sdd/deepagent-env-contract.schema.json +143 -0
- package/schemas/sdd/deepagent-quality-evidence.schema.json +108 -0
- package/schemas/sdd/deepagent-run-evidence.schema.json +192 -0
- package/schemas/sdd/deepagent-run-plan.schema.json +197 -0
- package/schemas/sdd/deepagent-run-request.schema.json +321 -0
- package/schemas/sdd/deepagent-subagent-evidence.schema.json +110 -0
- package/schemas/sdd/deepagent-tool-call-evidence.schema.json +78 -0
- package/schemas/sdd/discarded.schema.json +127 -0
- package/schemas/sdd/epic.schema.json +147 -0
- package/schemas/sdd/insight.schema.json +136 -0
- package/schemas/sdd/parallel-feat-automation-plan.schema.json +215 -0
- package/schemas/sdd/parallel-feat-automation-request.schema.json +109 -0
- package/schemas/sdd/plugin-artifact-manifest.schema.json +150 -0
- package/schemas/sdd/plugin-compliance-index.schema.json +136 -0
- package/schemas/sdd/plugin-dry-run-plan.schema.json +260 -0
- package/schemas/sdd/plugin-evidence-manifest.schema.json +569 -0
- package/schemas/sdd/plugin-policy-evaluation.schema.json +92 -0
- package/schemas/sdd/plugin-policy-pack-evaluation.schema.json +94 -0
- package/schemas/sdd/plugin-policy-pack.schema.json +196 -0
- package/schemas/sdd/plugin-registry.schema.json +558 -0
- package/schemas/sdd/plugin-rollback-manifest.schema.json +87 -0
- package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +845 -0
- package/schemas/sdd/plugin-skill-binding-resolution.schema.json +305 -0
- package/schemas/sdd/plugin-skill-binding.schema.json +88 -0
- package/schemas/sdd/plugin-validation-manifest.schema.json +123 -0
- package/schemas/sdd/quality-architecture-schema.schema.json +216 -0
- package/schemas/sdd/quality-evidence-bundle.schema.json +1228 -0
- package/schemas/sdd/quality-run.schema.json +197 -0
- package/schemas/sdd/quality-scenario.schema.json +252 -0
- package/schemas/sdd/workspace-catalog.schema.json +9841 -22
- package/schemas/spec-driven/schema.yaml +4 -4
- package/schemas/spec-driven/templates/proposal.md +1 -1
- package/dist/utils/openspec-compat.d.ts +0 -2
- package/dist/utils/openspec-compat.js +0 -2
|
@@ -1,37 +1,86 @@
|
|
|
1
1
|
import { nowIso } from '../state.js';
|
|
2
2
|
import { ContextService } from './context.service.js';
|
|
3
|
-
import { FinalizeService } from './finalize.service.js';
|
|
4
3
|
import { NextService } from './next.service.js';
|
|
4
|
+
import { GovernanceControlPlaneService } from './governance-control-plane.service.js';
|
|
5
|
+
import { SkillsInvokeService } from './skills-invoke.service.js';
|
|
6
|
+
import { SddCheckCommand } from '../check.js';
|
|
7
|
+
import { SddDiagnoseCommand } from '../diagnose.js';
|
|
8
|
+
import { inspectPluginManifestFromFile, planPluginInvocationFromFile, } from '../plugin-cli.js';
|
|
9
|
+
import { parse as parseYaml } from 'yaml';
|
|
10
|
+
import { promises as fs } from 'node:fs';
|
|
11
|
+
import path from 'node:path';
|
|
12
|
+
export const MCP_RUNTIME_STATE_BOUNDARY = {
|
|
13
|
+
id: 'codesdd-canonical-sdd-state',
|
|
14
|
+
canonical_state_root: '.sdd/state',
|
|
15
|
+
canonical_state_glob: '.sdd/state/*.yaml',
|
|
16
|
+
canonical_workspace_roots: ['.sdd/planned', '.sdd/active', '.sdd/archived'],
|
|
17
|
+
adapter_boundary: 'SddStores',
|
|
18
|
+
runtime_persistence: 'delegated-to-codesdd-services',
|
|
19
|
+
hidden_state_allowed: false,
|
|
20
|
+
external_state_allowed: false,
|
|
21
|
+
};
|
|
5
22
|
const PROVIDER_PROFILES = {
|
|
6
23
|
codex: {
|
|
7
24
|
label: 'Codex',
|
|
8
|
-
session_contract: 'Use JSON tool payloads and preserve FEAT
|
|
25
|
+
session_contract: 'Use JSON tool payloads and preserve FEAT lifecycle/structural reads through canonical CodeSDD state without hidden side channels.',
|
|
9
26
|
},
|
|
10
27
|
'claude-code': {
|
|
11
28
|
label: 'Claude Code',
|
|
12
|
-
session_contract: 'Use JSON tool payloads and treat
|
|
29
|
+
session_contract: 'Use JSON tool payloads and treat CodeSDD as the canonical execution ledger for plan, context, and closure.',
|
|
30
|
+
},
|
|
31
|
+
deepagents: {
|
|
32
|
+
label: 'DeepAgents',
|
|
33
|
+
session_contract: 'Use governed agent envelopes over canonical CodeSDD state and workspace artifacts, preserving existing providers without replacement.',
|
|
13
34
|
},
|
|
14
35
|
'kimmy-code': {
|
|
15
36
|
label: 'Kimmy Code',
|
|
16
|
-
session_contract: 'Use the same stateless JSON envelopes and feed all execution evidence back into
|
|
37
|
+
session_contract: 'Use the same stateless JSON envelopes and feed all execution evidence back into CodeSDD workspaces.',
|
|
17
38
|
},
|
|
18
39
|
'kilo-code': {
|
|
19
40
|
label: 'Kilo Code',
|
|
20
|
-
session_contract: 'Use
|
|
41
|
+
session_contract: 'Use CodeSDD tool envelopes as the source of truth for lifecycle context, structural query, and workspace reads.',
|
|
21
42
|
},
|
|
22
43
|
'open-code': {
|
|
23
44
|
label: 'Open Code',
|
|
24
|
-
session_contract: 'Use stateless
|
|
45
|
+
session_contract: 'Use stateless CodeSDD tool calls for read-only lifecycle, structural query, and workspace evidence retrieval.',
|
|
25
46
|
},
|
|
26
47
|
generic: {
|
|
27
48
|
label: 'Generic MCP Client',
|
|
28
|
-
session_contract: 'Use the provider-agnostic JSON envelope and treat
|
|
49
|
+
session_contract: 'Use the provider-agnostic JSON envelope and treat CodeSDD workspace/state files as the only canonical state system.',
|
|
29
50
|
},
|
|
30
51
|
};
|
|
31
|
-
const
|
|
52
|
+
const MCP_RUNTIME_PLANNED_TOOLS = [
|
|
32
53
|
{
|
|
33
|
-
name: '
|
|
34
|
-
|
|
54
|
+
name: 'codesdd.agent.run',
|
|
55
|
+
status: 'planned',
|
|
56
|
+
title: 'CodeSDD Agent Run',
|
|
57
|
+
description: 'Planned governed run execution envelope for DeepAgents-compatible providers.',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'codesdd.agent.plan',
|
|
61
|
+
status: 'planned',
|
|
62
|
+
title: 'CodeSDD Agent Plan',
|
|
63
|
+
description: 'Planned agent planning envelope for FEAT decomposition, sequencing, and execution constraints.',
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
name: 'codesdd.agent.evidence',
|
|
67
|
+
status: 'planned',
|
|
68
|
+
title: 'CodeSDD Agent Evidence',
|
|
69
|
+
description: 'Planned structured evidence envelope linked to canonical CodeSDD FEAT workspaces.',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'codesdd.agent.status',
|
|
73
|
+
status: 'planned',
|
|
74
|
+
title: 'CodeSDD Agent Status',
|
|
75
|
+
description: 'Planned status envelope for agent lifecycle telemetry and rollout readiness.',
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
export const MCP_RUNTIME_TOOL_REGISTRY = [
|
|
79
|
+
{
|
|
80
|
+
id: 'runtime-tool:codesdd.next',
|
|
81
|
+
canonical_name: 'codesdd.next',
|
|
82
|
+
operation: 'next',
|
|
83
|
+
title: 'CodeSDD Next',
|
|
35
84
|
description: 'Return the next ready FEATs, blocked work, conflicts, and execution waves.',
|
|
36
85
|
input_schema: {
|
|
37
86
|
type: 'object',
|
|
@@ -42,10 +91,29 @@ const TOOL_DEFINITIONS = [
|
|
|
42
91
|
maxAgents: { type: 'integer', minimum: 1 },
|
|
43
92
|
},
|
|
44
93
|
},
|
|
94
|
+
output_schema: {
|
|
95
|
+
type: 'object',
|
|
96
|
+
additionalProperties: true,
|
|
97
|
+
},
|
|
98
|
+
compatibility_aliases: [],
|
|
99
|
+
governance: {
|
|
100
|
+
gate: 'read-only',
|
|
101
|
+
risk_tier: 'low',
|
|
102
|
+
evidence_behavior: 'Record selected execution wave and decisions in 5-quality.yaml when tool output drives implementation work.',
|
|
103
|
+
hitl_rule: 'No HITL required for read-only ranking output.',
|
|
104
|
+
},
|
|
105
|
+
implementation: {
|
|
106
|
+
service: 'NextService',
|
|
107
|
+
state_access: 'read',
|
|
108
|
+
reads: ['.sdd/state/*.yaml', '.sdd/{planned,active,archived}/**/*.yaml'],
|
|
109
|
+
writes: [],
|
|
110
|
+
},
|
|
45
111
|
},
|
|
46
112
|
{
|
|
47
|
-
|
|
48
|
-
|
|
113
|
+
id: 'runtime-tool:codesdd.context',
|
|
114
|
+
canonical_name: 'codesdd.context',
|
|
115
|
+
operation: 'context',
|
|
116
|
+
title: 'CodeSDD Context',
|
|
49
117
|
description: 'Return the scoped execution context for a FEAT, EPIC, FGAP, or TD reference.',
|
|
50
118
|
input_schema: {
|
|
51
119
|
type: 'object',
|
|
@@ -55,23 +123,492 @@ const TOOL_DEFINITIONS = [
|
|
|
55
123
|
ref: { type: 'string' },
|
|
56
124
|
},
|
|
57
125
|
},
|
|
126
|
+
output_schema: {
|
|
127
|
+
type: 'object',
|
|
128
|
+
additionalProperties: true,
|
|
129
|
+
},
|
|
130
|
+
compatibility_aliases: [],
|
|
131
|
+
governance: {
|
|
132
|
+
gate: 'read-only',
|
|
133
|
+
risk_tier: 'low',
|
|
134
|
+
evidence_behavior: 'Record the consumed context reference in changelog or quality evidence when used for FEAT execution.',
|
|
135
|
+
hitl_rule: 'No HITL required for context reads.',
|
|
136
|
+
},
|
|
137
|
+
implementation: {
|
|
138
|
+
service: 'ContextService',
|
|
139
|
+
state_access: 'read',
|
|
140
|
+
reads: ['.sdd/state/*.yaml', '.sdd/{planned,active,archived}/**/*.yaml'],
|
|
141
|
+
writes: [],
|
|
142
|
+
},
|
|
58
143
|
},
|
|
59
144
|
{
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
145
|
+
id: 'runtime-tool:codesdd.query',
|
|
146
|
+
canonical_name: 'codesdd.query',
|
|
147
|
+
operation: 'query',
|
|
148
|
+
title: 'CodeSDD Structural Query',
|
|
149
|
+
description: 'Query canonical CodeSDD structure by identifier dependencies or full-text terms over backlog/discovery state.',
|
|
63
150
|
input_schema: {
|
|
64
151
|
type: 'object',
|
|
65
152
|
additionalProperties: false,
|
|
66
153
|
properties: {
|
|
67
154
|
ref: { type: 'string' },
|
|
68
|
-
|
|
69
|
-
|
|
155
|
+
query: { type: 'string' },
|
|
156
|
+
scope: { type: 'string', enum: ['backlog', 'discovery', 'all'] },
|
|
157
|
+
limit: { type: 'integer', minimum: 1 },
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
output_schema: {
|
|
161
|
+
type: 'object',
|
|
162
|
+
additionalProperties: true,
|
|
163
|
+
},
|
|
164
|
+
compatibility_aliases: [],
|
|
165
|
+
governance: {
|
|
166
|
+
gate: 'read-only',
|
|
167
|
+
risk_tier: 'low',
|
|
168
|
+
evidence_behavior: 'Capture query criteria and result summary when it influences scope or dependency decisions.',
|
|
169
|
+
hitl_rule: 'No HITL required for structural queries.',
|
|
170
|
+
},
|
|
171
|
+
implementation: {
|
|
172
|
+
service: 'StructuralQueryService',
|
|
173
|
+
state_access: 'read',
|
|
174
|
+
reads: ['.sdd/state/*.yaml', '.sdd/{planned,active,archived}/**/*.yaml'],
|
|
175
|
+
writes: [],
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
id: 'runtime-tool:codesdd.read',
|
|
180
|
+
canonical_name: 'codesdd.read',
|
|
181
|
+
operation: 'read',
|
|
182
|
+
title: 'CodeSDD Workspace Read',
|
|
183
|
+
description: 'Read canonical FEAT workspace docs (spec/plan/tasks/changelog/quality) from active, planned, or archived state.',
|
|
184
|
+
input_schema: {
|
|
185
|
+
type: 'object',
|
|
186
|
+
additionalProperties: false,
|
|
187
|
+
required: ['ref'],
|
|
188
|
+
properties: {
|
|
189
|
+
ref: { type: 'string' },
|
|
190
|
+
doc: {
|
|
191
|
+
type: 'string',
|
|
192
|
+
enum: ['spec', 'plan', 'tasks', 'changelog', 'quality', 'all'],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
output_schema: {
|
|
197
|
+
type: 'object',
|
|
198
|
+
additionalProperties: true,
|
|
199
|
+
},
|
|
200
|
+
compatibility_aliases: [],
|
|
201
|
+
governance: {
|
|
202
|
+
gate: 'read-only',
|
|
203
|
+
risk_tier: 'low',
|
|
204
|
+
evidence_behavior: 'Use returned workspace docs as canonical evidence; do not replace file-based traceability with transient logs.',
|
|
205
|
+
hitl_rule: 'No HITL required for workspace reads.',
|
|
206
|
+
},
|
|
207
|
+
implementation: {
|
|
208
|
+
service: 'WorkspaceReadService',
|
|
209
|
+
state_access: 'read',
|
|
210
|
+
reads: ['.sdd/{planned,active,archived}/**/*.yaml'],
|
|
211
|
+
writes: [],
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
id: 'runtime-tool:codesdd.start',
|
|
216
|
+
canonical_name: 'codesdd.start',
|
|
217
|
+
operation: 'start',
|
|
218
|
+
title: 'CodeSDD Start Intent',
|
|
219
|
+
description: 'Plan a gated start intent for FEAT execution without mutating canonical state directly through MCP.',
|
|
220
|
+
input_schema: {
|
|
221
|
+
type: 'object',
|
|
222
|
+
additionalProperties: false,
|
|
223
|
+
required: ['refOrText'],
|
|
224
|
+
properties: {
|
|
225
|
+
refOrText: { type: 'string' },
|
|
226
|
+
scale: { type: 'string', enum: ['QUICK', 'STANDARD', 'LARGE'] },
|
|
227
|
+
schema: { type: 'string' },
|
|
228
|
+
flowMode: { type: 'string', enum: ['direct', 'standard', 'rigorous'] },
|
|
229
|
+
force: { type: 'boolean' },
|
|
70
230
|
forceTransition: { type: 'boolean' },
|
|
71
231
|
},
|
|
72
232
|
},
|
|
233
|
+
output_schema: {
|
|
234
|
+
type: 'object',
|
|
235
|
+
additionalProperties: true,
|
|
236
|
+
},
|
|
237
|
+
compatibility_aliases: [],
|
|
238
|
+
governance: {
|
|
239
|
+
gate: 'intent-only',
|
|
240
|
+
risk_tier: 'high',
|
|
241
|
+
evidence_behavior: 'Intent payload must be recorded before execution; execution evidence must be appended to 5-quality.yaml after running the CLI command.',
|
|
242
|
+
hitl_rule: 'Human approval required before executing the generated start intent command.',
|
|
243
|
+
},
|
|
244
|
+
implementation: {
|
|
245
|
+
service: 'StartService',
|
|
246
|
+
state_access: 'read-write',
|
|
247
|
+
reads: ['.sdd/state/*.yaml', '.sdd/{planned,active,archived}/**/*.yaml'],
|
|
248
|
+
writes: ['.sdd/state/*.yaml', '.sdd/active/**', '.sdd/planned/**'],
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
id: 'runtime-tool:codesdd.plugin.inspect',
|
|
253
|
+
canonical_name: 'codesdd.plugin.inspect',
|
|
254
|
+
operation: 'plugin-inspect',
|
|
255
|
+
title: 'CodeSDD Plugin Inspect',
|
|
256
|
+
description: 'Inspect plugin manifests with policy and capability metadata without executing plugins.',
|
|
257
|
+
input_schema: {
|
|
258
|
+
type: 'object',
|
|
259
|
+
additionalProperties: false,
|
|
260
|
+
required: ['manifestPath'],
|
|
261
|
+
properties: {
|
|
262
|
+
manifestPath: { type: 'string' },
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
output_schema: {
|
|
266
|
+
type: 'object',
|
|
267
|
+
additionalProperties: true,
|
|
268
|
+
},
|
|
269
|
+
compatibility_aliases: [],
|
|
270
|
+
governance: {
|
|
271
|
+
gate: 'read-only',
|
|
272
|
+
risk_tier: 'medium',
|
|
273
|
+
evidence_behavior: 'Include inspected plugin ref/version in quality evidence when plugin governance influences FEAT decisions.',
|
|
274
|
+
hitl_rule: 'No HITL required for manifest inspection.',
|
|
275
|
+
},
|
|
276
|
+
implementation: {
|
|
277
|
+
service: 'PluginCliService',
|
|
278
|
+
state_access: 'read',
|
|
279
|
+
reads: ['**/codesdd-plugin.yaml', '.sdd/**'],
|
|
280
|
+
writes: [],
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
{
|
|
284
|
+
id: 'runtime-tool:codesdd.plugin.plan',
|
|
285
|
+
canonical_name: 'codesdd.plugin.plan',
|
|
286
|
+
operation: 'plugin-plan',
|
|
287
|
+
title: 'CodeSDD Plugin Plan',
|
|
288
|
+
description: 'Build a plugin runtime invocation plan in dry-run mode with policy evaluation.',
|
|
289
|
+
input_schema: {
|
|
290
|
+
type: 'object',
|
|
291
|
+
additionalProperties: false,
|
|
292
|
+
required: ['manifestPath', 'featureRef', 'capability'],
|
|
293
|
+
properties: {
|
|
294
|
+
manifestPath: { type: 'string' },
|
|
295
|
+
featureRef: { type: 'string' },
|
|
296
|
+
capability: { type: 'string' },
|
|
297
|
+
skillRef: { type: 'string' },
|
|
298
|
+
inputs: { type: 'object' },
|
|
299
|
+
writeScope: { type: 'array', items: { type: 'string' } },
|
|
300
|
+
approvalGrants: { type: 'array', items: { type: 'string' } },
|
|
301
|
+
plannedWrites: { type: 'array', items: { type: 'string' } },
|
|
302
|
+
requestedEnv: { type: 'array', items: { type: 'string' } },
|
|
303
|
+
networkDomains: { type: 'array', items: { type: 'string' } },
|
|
304
|
+
processSpawnRequested: { type: 'boolean' },
|
|
305
|
+
},
|
|
306
|
+
},
|
|
307
|
+
output_schema: {
|
|
308
|
+
type: 'object',
|
|
309
|
+
additionalProperties: true,
|
|
310
|
+
},
|
|
311
|
+
compatibility_aliases: [],
|
|
312
|
+
governance: {
|
|
313
|
+
gate: 'read-only',
|
|
314
|
+
risk_tier: 'medium',
|
|
315
|
+
evidence_behavior: 'Persist planned policy decisions and reasons in quality evidence before promoting to apply modes.',
|
|
316
|
+
hitl_rule: 'No HITL required for dry-run planning output.',
|
|
317
|
+
},
|
|
318
|
+
implementation: {
|
|
319
|
+
service: 'PluginCliService',
|
|
320
|
+
state_access: 'read',
|
|
321
|
+
reads: ['**/codesdd-plugin.yaml', '.sdd/**'],
|
|
322
|
+
writes: [],
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
{
|
|
326
|
+
id: 'runtime-tool:codesdd.plugin.apply_sandbox',
|
|
327
|
+
canonical_name: 'codesdd.plugin.apply_sandbox',
|
|
328
|
+
operation: 'plugin-apply-sandbox',
|
|
329
|
+
title: 'CodeSDD Plugin Apply Sandbox Intent',
|
|
330
|
+
description: 'Generate a sandbox apply plan that remains gated for human approval before execution.',
|
|
331
|
+
input_schema: {
|
|
332
|
+
type: 'object',
|
|
333
|
+
additionalProperties: false,
|
|
334
|
+
required: ['manifestPath', 'featureRef', 'capability'],
|
|
335
|
+
properties: {
|
|
336
|
+
manifestPath: { type: 'string' },
|
|
337
|
+
featureRef: { type: 'string' },
|
|
338
|
+
capability: { type: 'string' },
|
|
339
|
+
skillRef: { type: 'string' },
|
|
340
|
+
inputs: { type: 'object' },
|
|
341
|
+
writeScope: { type: 'array', items: { type: 'string' } },
|
|
342
|
+
approvalGrants: { type: 'array', items: { type: 'string' } },
|
|
343
|
+
plannedWrites: { type: 'array', items: { type: 'string' } },
|
|
344
|
+
requestedEnv: { type: 'array', items: { type: 'string' } },
|
|
345
|
+
networkDomains: { type: 'array', items: { type: 'string' } },
|
|
346
|
+
processSpawnRequested: { type: 'boolean' },
|
|
347
|
+
},
|
|
348
|
+
},
|
|
349
|
+
output_schema: {
|
|
350
|
+
type: 'object',
|
|
351
|
+
additionalProperties: true,
|
|
352
|
+
},
|
|
353
|
+
compatibility_aliases: [],
|
|
354
|
+
governance: {
|
|
355
|
+
gate: 'intent-only',
|
|
356
|
+
risk_tier: 'critical',
|
|
357
|
+
evidence_behavior: 'Apply-sandbox plan and policy decision must be logged before approval; post-execution evidence must include artifacts and compensating controls.',
|
|
358
|
+
hitl_rule: 'Human approval required for apply_sandbox due to write scope and policy risk.',
|
|
359
|
+
},
|
|
360
|
+
implementation: {
|
|
361
|
+
service: 'PluginCliService',
|
|
362
|
+
state_access: 'read-write',
|
|
363
|
+
reads: ['**/codesdd-plugin.yaml', '.sdd/**'],
|
|
364
|
+
writes: ['sandbox/**'],
|
|
365
|
+
},
|
|
366
|
+
},
|
|
367
|
+
{
|
|
368
|
+
id: 'runtime-tool:codesdd.quality.evidence',
|
|
369
|
+
canonical_name: 'codesdd.quality.evidence',
|
|
370
|
+
operation: 'quality-evidence',
|
|
371
|
+
title: 'CodeSDD Quality Evidence Read',
|
|
372
|
+
description: 'Read quality evidence, acceptance matrix, and skill evidence from FEAT workspace quality docs.',
|
|
373
|
+
input_schema: {
|
|
374
|
+
type: 'object',
|
|
375
|
+
additionalProperties: false,
|
|
376
|
+
required: ['ref'],
|
|
377
|
+
properties: {
|
|
378
|
+
ref: { type: 'string' },
|
|
379
|
+
},
|
|
380
|
+
},
|
|
381
|
+
output_schema: {
|
|
382
|
+
type: 'object',
|
|
383
|
+
additionalProperties: true,
|
|
384
|
+
},
|
|
385
|
+
compatibility_aliases: [],
|
|
386
|
+
governance: {
|
|
387
|
+
gate: 'read-only',
|
|
388
|
+
risk_tier: 'medium',
|
|
389
|
+
evidence_behavior: 'Use output to validate coverage targets and remediation status before finalize.',
|
|
390
|
+
hitl_rule: 'No HITL required for evidence reads.',
|
|
391
|
+
},
|
|
392
|
+
implementation: {
|
|
393
|
+
service: 'QualityEvidenceService',
|
|
394
|
+
state_access: 'read',
|
|
395
|
+
reads: ['.sdd/{planned,active,archived}/**/5-quality.yaml'],
|
|
396
|
+
writes: [],
|
|
397
|
+
},
|
|
398
|
+
},
|
|
399
|
+
{
|
|
400
|
+
id: 'runtime-tool:codesdd.adr',
|
|
401
|
+
canonical_name: 'codesdd.adr',
|
|
402
|
+
operation: 'adr',
|
|
403
|
+
title: 'CodeSDD ADR Read',
|
|
404
|
+
description: 'List ADR documents and optional FEAT-ref matches from canonical ADR folders.',
|
|
405
|
+
input_schema: {
|
|
406
|
+
type: 'object',
|
|
407
|
+
additionalProperties: false,
|
|
408
|
+
properties: {
|
|
409
|
+
ref: { type: 'string' },
|
|
410
|
+
},
|
|
411
|
+
},
|
|
412
|
+
output_schema: {
|
|
413
|
+
type: 'object',
|
|
414
|
+
additionalProperties: true,
|
|
415
|
+
},
|
|
416
|
+
compatibility_aliases: [],
|
|
417
|
+
governance: {
|
|
418
|
+
gate: 'read-only',
|
|
419
|
+
risk_tier: 'low',
|
|
420
|
+
evidence_behavior: 'Reference ADR IDs in quality traceability when architectural decisions constrain implementation.',
|
|
421
|
+
hitl_rule: 'No HITL required for ADR indexing.',
|
|
422
|
+
},
|
|
423
|
+
implementation: {
|
|
424
|
+
service: 'AdrIndexService',
|
|
425
|
+
state_access: 'read',
|
|
426
|
+
reads: ['.sdd/core/adrs/*.md'],
|
|
427
|
+
writes: [],
|
|
428
|
+
},
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
id: 'runtime-tool:codesdd.check',
|
|
432
|
+
canonical_name: 'codesdd.check',
|
|
433
|
+
operation: 'check',
|
|
434
|
+
title: 'CodeSDD Check',
|
|
435
|
+
description: 'Run structured CodeSDD check report in read-only mode (render disabled).',
|
|
436
|
+
input_schema: {
|
|
437
|
+
type: 'object',
|
|
438
|
+
additionalProperties: false,
|
|
439
|
+
properties: {
|
|
440
|
+
strict: { type: 'boolean' },
|
|
441
|
+
},
|
|
442
|
+
},
|
|
443
|
+
output_schema: {
|
|
444
|
+
type: 'object',
|
|
445
|
+
additionalProperties: true,
|
|
446
|
+
},
|
|
447
|
+
compatibility_aliases: [],
|
|
448
|
+
governance: {
|
|
449
|
+
gate: 'read-only',
|
|
450
|
+
risk_tier: 'medium',
|
|
451
|
+
evidence_behavior: 'Attach check summary and blocking errors to 5-quality.yaml evidence_log before finalize.',
|
|
452
|
+
hitl_rule: 'No HITL required to run check in non-render mode.',
|
|
453
|
+
},
|
|
454
|
+
implementation: {
|
|
455
|
+
service: 'SddCheckCommand',
|
|
456
|
+
state_access: 'read',
|
|
457
|
+
reads: ['.sdd/**'],
|
|
458
|
+
writes: [],
|
|
459
|
+
},
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
id: 'runtime-tool:codesdd.diagnose',
|
|
463
|
+
canonical_name: 'codesdd.diagnose',
|
|
464
|
+
operation: 'diagnose',
|
|
465
|
+
title: 'CodeSDD Diagnose',
|
|
466
|
+
description: 'Run structural diagnostics without writing external report files.',
|
|
467
|
+
input_schema: {
|
|
468
|
+
type: 'object',
|
|
469
|
+
additionalProperties: false,
|
|
470
|
+
properties: {
|
|
471
|
+
strict: { type: 'boolean' },
|
|
472
|
+
},
|
|
473
|
+
},
|
|
474
|
+
output_schema: {
|
|
475
|
+
type: 'object',
|
|
476
|
+
additionalProperties: true,
|
|
477
|
+
},
|
|
478
|
+
compatibility_aliases: [],
|
|
479
|
+
governance: {
|
|
480
|
+
gate: 'read-only',
|
|
481
|
+
risk_tier: 'medium',
|
|
482
|
+
evidence_behavior: 'Include diagnose health and finding counts in quality evidence before finalize.',
|
|
483
|
+
hitl_rule: 'No HITL required for diagnostics reads.',
|
|
484
|
+
},
|
|
485
|
+
implementation: {
|
|
486
|
+
service: 'SddDiagnoseCommand',
|
|
487
|
+
state_access: 'read',
|
|
488
|
+
reads: ['.sdd/**'],
|
|
489
|
+
writes: [],
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
id: 'runtime-tool:codesdd.finalize_intent',
|
|
494
|
+
canonical_name: 'codesdd.finalize_intent',
|
|
495
|
+
operation: 'finalize-intent',
|
|
496
|
+
title: 'CodeSDD Finalize Intent',
|
|
497
|
+
description: 'Create a gated finalize intent command without mutating state from MCP directly.',
|
|
498
|
+
input_schema: {
|
|
499
|
+
type: 'object',
|
|
500
|
+
additionalProperties: false,
|
|
501
|
+
required: ['featureId'],
|
|
502
|
+
properties: {
|
|
503
|
+
featureId: { type: 'string' },
|
|
504
|
+
},
|
|
505
|
+
},
|
|
506
|
+
output_schema: {
|
|
507
|
+
type: 'object',
|
|
508
|
+
additionalProperties: true,
|
|
509
|
+
},
|
|
510
|
+
compatibility_aliases: [],
|
|
511
|
+
governance: {
|
|
512
|
+
gate: 'intent-only',
|
|
513
|
+
risk_tier: 'critical',
|
|
514
|
+
evidence_behavior: 'Finalize intent requires quality evidence coverage, frontend declaration, and post-finalize check/diagnose evidence before closure.',
|
|
515
|
+
hitl_rule: 'Human approval required before executing finalize intent command.',
|
|
516
|
+
},
|
|
517
|
+
implementation: {
|
|
518
|
+
service: 'GovernanceControlPlaneService',
|
|
519
|
+
state_access: 'read-write',
|
|
520
|
+
reads: ['.sdd/state/*.yaml', '.sdd/active/**'],
|
|
521
|
+
writes: ['.sdd/state/*.yaml', '.sdd/archived/**'],
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
id: 'runtime-tool:codesdd.frontend_impact',
|
|
526
|
+
canonical_name: 'codesdd.frontend_impact',
|
|
527
|
+
operation: 'frontend-impact',
|
|
528
|
+
title: 'CodeSDD Frontend Impact Intent',
|
|
529
|
+
description: 'Create a gated frontend-impact intent command with routes and surfaces metadata.',
|
|
530
|
+
input_schema: {
|
|
531
|
+
type: 'object',
|
|
532
|
+
additionalProperties: false,
|
|
533
|
+
required: ['featureId', 'status'],
|
|
534
|
+
properties: {
|
|
535
|
+
featureId: { type: 'string' },
|
|
536
|
+
status: { type: 'string', enum: ['unknown', 'none', 'required'] },
|
|
537
|
+
reason: { type: 'string' },
|
|
538
|
+
routes: {
|
|
539
|
+
oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }],
|
|
540
|
+
},
|
|
541
|
+
surfaces: {
|
|
542
|
+
oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }],
|
|
543
|
+
},
|
|
544
|
+
},
|
|
545
|
+
},
|
|
546
|
+
output_schema: {
|
|
547
|
+
type: 'object',
|
|
548
|
+
additionalProperties: true,
|
|
549
|
+
},
|
|
550
|
+
compatibility_aliases: [],
|
|
551
|
+
governance: {
|
|
552
|
+
gate: 'intent-only',
|
|
553
|
+
risk_tier: 'high',
|
|
554
|
+
evidence_behavior: 'Record frontend-impact declaration and rationale in quality evidence before finalize.',
|
|
555
|
+
hitl_rule: 'Human approval required before executing frontend-impact intent command.',
|
|
556
|
+
},
|
|
557
|
+
implementation: {
|
|
558
|
+
service: 'GovernanceControlPlaneService',
|
|
559
|
+
state_access: 'read-write',
|
|
560
|
+
reads: ['.sdd/state/*.yaml'],
|
|
561
|
+
writes: ['.sdd/state/backlog.yaml', '.sdd/state/frontend-map.yaml'],
|
|
562
|
+
},
|
|
563
|
+
},
|
|
564
|
+
{
|
|
565
|
+
id: 'runtime-tool:codesdd.skill_prompt',
|
|
566
|
+
canonical_name: 'codesdd.skill_prompt',
|
|
567
|
+
operation: 'skill-prompt',
|
|
568
|
+
title: 'CodeSDD Skill Prompt',
|
|
569
|
+
description: 'Select skills and generate invocation prompt payload aligned with CodeSDD catalog and context.',
|
|
570
|
+
input_schema: {
|
|
571
|
+
type: 'object',
|
|
572
|
+
additionalProperties: false,
|
|
573
|
+
properties: {
|
|
574
|
+
ids: { type: 'array', items: { type: 'string' } },
|
|
575
|
+
phase: { type: 'string' },
|
|
576
|
+
domains: { type: 'array', items: { type: 'string' } },
|
|
577
|
+
bundles: { type: 'array', items: { type: 'string' } },
|
|
578
|
+
max: { type: 'integer', minimum: 1 },
|
|
579
|
+
objective: { type: 'string' },
|
|
580
|
+
ref: { type: 'string' },
|
|
581
|
+
},
|
|
582
|
+
},
|
|
583
|
+
output_schema: {
|
|
584
|
+
type: 'object',
|
|
585
|
+
additionalProperties: true,
|
|
586
|
+
},
|
|
587
|
+
compatibility_aliases: [],
|
|
588
|
+
governance: {
|
|
589
|
+
gate: 'read-only',
|
|
590
|
+
risk_tier: 'medium',
|
|
591
|
+
evidence_behavior: 'Record selected skills in skill_evidence when prompt output is used for feature implementation.',
|
|
592
|
+
hitl_rule: 'No HITL required for prompt generation.',
|
|
593
|
+
},
|
|
594
|
+
implementation: {
|
|
595
|
+
service: 'SkillsInvokeService',
|
|
596
|
+
state_access: 'read',
|
|
597
|
+
reads: ['.sdd/state/skill-catalog.yaml', '.sdd/skills/**', '.sdd/active/**'],
|
|
598
|
+
writes: [],
|
|
599
|
+
},
|
|
73
600
|
},
|
|
74
601
|
];
|
|
602
|
+
export const MCP_RUNTIME_SUPPORTED_TOOLS = MCP_RUNTIME_TOOL_REGISTRY.flatMap((entry) => [
|
|
603
|
+
entry.canonical_name,
|
|
604
|
+
...entry.compatibility_aliases,
|
|
605
|
+
]);
|
|
606
|
+
const LEGACY_TOOL_ALIASES = MCP_RUNTIME_TOOL_REGISTRY.reduce((aliases, entry) => {
|
|
607
|
+
for (const alias of entry.compatibility_aliases) {
|
|
608
|
+
aliases[alias] = entry.canonical_name;
|
|
609
|
+
}
|
|
610
|
+
return aliases;
|
|
611
|
+
}, {});
|
|
75
612
|
function resolveProvider(provider) {
|
|
76
613
|
if (!provider)
|
|
77
614
|
return 'generic';
|
|
@@ -79,6 +616,72 @@ function resolveProvider(provider) {
|
|
|
79
616
|
return provider;
|
|
80
617
|
throw new Error(`Unknown MCP provider "${provider}". Use one of: ${Object.keys(PROVIDER_PROFILES).join(', ')}`);
|
|
81
618
|
}
|
|
619
|
+
function runtimeRegistryManifest() {
|
|
620
|
+
return {
|
|
621
|
+
name: 'codesdd-runtime-tool-registry',
|
|
622
|
+
version: 1,
|
|
623
|
+
canonical_namespace: 'codesdd',
|
|
624
|
+
compatibility_namespaces: [],
|
|
625
|
+
state_boundary_ref: MCP_RUNTIME_STATE_BOUNDARY.id,
|
|
626
|
+
entries: MCP_RUNTIME_TOOL_REGISTRY.map((entry) => ({
|
|
627
|
+
id: entry.id,
|
|
628
|
+
canonical_name: entry.canonical_name,
|
|
629
|
+
operation: entry.operation,
|
|
630
|
+
governance: {
|
|
631
|
+
gate: entry.governance.gate,
|
|
632
|
+
risk_tier: entry.governance.risk_tier,
|
|
633
|
+
evidence_behavior: entry.governance.evidence_behavior,
|
|
634
|
+
hitl_rule: entry.governance.hitl_rule,
|
|
635
|
+
},
|
|
636
|
+
compatibility_aliases: [...entry.compatibility_aliases],
|
|
637
|
+
implementation: {
|
|
638
|
+
service: entry.implementation.service,
|
|
639
|
+
state_access: entry.implementation.state_access,
|
|
640
|
+
reads: [...entry.implementation.reads],
|
|
641
|
+
writes: [...entry.implementation.writes],
|
|
642
|
+
},
|
|
643
|
+
})),
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
function toolDefinitions() {
|
|
647
|
+
return MCP_RUNTIME_TOOL_REGISTRY.map((entry) => ({
|
|
648
|
+
registry_entry_ref: entry.id,
|
|
649
|
+
name: entry.canonical_name,
|
|
650
|
+
title: entry.title,
|
|
651
|
+
description: entry.description,
|
|
652
|
+
input_schema: entry.input_schema,
|
|
653
|
+
output_schema: entry.output_schema,
|
|
654
|
+
governance: {
|
|
655
|
+
gate: entry.governance.gate,
|
|
656
|
+
risk_tier: entry.governance.risk_tier,
|
|
657
|
+
evidence_behavior: entry.governance.evidence_behavior,
|
|
658
|
+
hitl_rule: entry.governance.hitl_rule,
|
|
659
|
+
},
|
|
660
|
+
compatibility_aliases: [...entry.compatibility_aliases],
|
|
661
|
+
}));
|
|
662
|
+
}
|
|
663
|
+
function resolveToolRequest(tool) {
|
|
664
|
+
const canonicalEntry = MCP_RUNTIME_TOOL_REGISTRY.find((entry) => entry.canonical_name === tool);
|
|
665
|
+
if (canonicalEntry) {
|
|
666
|
+
return {
|
|
667
|
+
entry: canonicalEntry,
|
|
668
|
+
requestedTool: canonicalEntry.canonical_name,
|
|
669
|
+
compatibilityAliasUsed: false,
|
|
670
|
+
};
|
|
671
|
+
}
|
|
672
|
+
const canonicalName = LEGACY_TOOL_ALIASES[tool];
|
|
673
|
+
const aliasEntry = canonicalName
|
|
674
|
+
? MCP_RUNTIME_TOOL_REGISTRY.find((entry) => entry.canonical_name === canonicalName)
|
|
675
|
+
: undefined;
|
|
676
|
+
if (aliasEntry) {
|
|
677
|
+
return {
|
|
678
|
+
entry: aliasEntry,
|
|
679
|
+
requestedTool: tool,
|
|
680
|
+
compatibilityAliasUsed: true,
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
throw new Error(`Unsupported MCP tool "${tool}". Use one of: ${MCP_RUNTIME_SUPPORTED_TOOLS.join(', ')}`);
|
|
684
|
+
}
|
|
82
685
|
export class McpRuntimeService {
|
|
83
686
|
stores;
|
|
84
687
|
constructor(stores) {
|
|
@@ -87,9 +690,9 @@ export class McpRuntimeService {
|
|
|
87
690
|
manifest(provider) {
|
|
88
691
|
const providerId = resolveProvider(provider);
|
|
89
692
|
return {
|
|
90
|
-
protocol: '
|
|
693
|
+
protocol: 'codesdd-mcp-bridge/v1',
|
|
91
694
|
server: {
|
|
92
|
-
name: '
|
|
695
|
+
name: 'codesdd',
|
|
93
696
|
version: 1,
|
|
94
697
|
},
|
|
95
698
|
provider: {
|
|
@@ -98,47 +701,496 @@ export class McpRuntimeService {
|
|
|
98
701
|
transport: 'stdio',
|
|
99
702
|
session_contract: PROVIDER_PROFILES[providerId].session_contract,
|
|
100
703
|
},
|
|
101
|
-
tools:
|
|
704
|
+
tools: toolDefinitions(),
|
|
705
|
+
planned_tools: MCP_RUNTIME_PLANNED_TOOLS.map((tool) => ({ ...tool })),
|
|
706
|
+
registry: runtimeRegistryManifest(),
|
|
707
|
+
state_boundary: MCP_RUNTIME_STATE_BOUNDARY,
|
|
102
708
|
};
|
|
103
709
|
}
|
|
104
710
|
async invoke(projectRoot, input) {
|
|
105
711
|
const providerId = resolveProvider(input.provider);
|
|
106
712
|
const args = input.args || {};
|
|
713
|
+
const resolution = resolveToolRequest(input.tool);
|
|
714
|
+
const tool = resolution.entry.canonical_name;
|
|
107
715
|
let result;
|
|
108
|
-
switch (
|
|
109
|
-
case '
|
|
716
|
+
switch (tool) {
|
|
717
|
+
case 'codesdd.next':
|
|
110
718
|
result = await new NextService(this.stores).execute(projectRoot, {
|
|
111
719
|
rank: typeof args.rank === 'string' ? args.rank : undefined,
|
|
112
720
|
limit: typeof args.limit === 'number' ? args.limit : undefined,
|
|
113
721
|
maxAgents: typeof args.maxAgents === 'number' ? args.maxAgents : undefined,
|
|
114
722
|
});
|
|
115
723
|
break;
|
|
116
|
-
case '
|
|
724
|
+
case 'codesdd.context':
|
|
117
725
|
if (typeof args.ref !== 'string' || !args.ref.trim()) {
|
|
118
|
-
throw new Error('
|
|
726
|
+
throw new Error('codesdd.context requires args.ref');
|
|
119
727
|
}
|
|
120
728
|
result = await new ContextService(this.stores).execute(projectRoot, args.ref);
|
|
121
729
|
break;
|
|
122
|
-
case '
|
|
123
|
-
result = await
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
730
|
+
case 'codesdd.query':
|
|
731
|
+
result = await this.queryState(args);
|
|
732
|
+
break;
|
|
733
|
+
case 'codesdd.read':
|
|
734
|
+
result = await this.readWorkspaceDocs(projectRoot, args);
|
|
735
|
+
break;
|
|
736
|
+
case 'codesdd.start':
|
|
737
|
+
result = this.planStartIntent(projectRoot, args);
|
|
738
|
+
break;
|
|
739
|
+
case 'codesdd.plugin.inspect':
|
|
740
|
+
result = await this.inspectPlugin(args);
|
|
741
|
+
break;
|
|
742
|
+
case 'codesdd.plugin.plan':
|
|
743
|
+
result = await this.planPlugin(args, false);
|
|
744
|
+
break;
|
|
745
|
+
case 'codesdd.plugin.apply_sandbox':
|
|
746
|
+
result = await this.planPlugin(args, true);
|
|
747
|
+
break;
|
|
748
|
+
case 'codesdd.quality.evidence':
|
|
749
|
+
result = await this.readQualityEvidence(projectRoot, args);
|
|
750
|
+
break;
|
|
751
|
+
case 'codesdd.adr':
|
|
752
|
+
result = await this.readAdrIndex(projectRoot, args);
|
|
753
|
+
break;
|
|
754
|
+
case 'codesdd.check':
|
|
755
|
+
result = await new SddCheckCommand().execute(projectRoot, {
|
|
129
756
|
render: false,
|
|
757
|
+
strict: args.strict === true,
|
|
130
758
|
});
|
|
131
759
|
break;
|
|
760
|
+
case 'codesdd.diagnose':
|
|
761
|
+
result = await new SddDiagnoseCommand().execute(projectRoot, {
|
|
762
|
+
strict: args.strict === true,
|
|
763
|
+
});
|
|
764
|
+
break;
|
|
765
|
+
case 'codesdd.finalize_intent':
|
|
766
|
+
result = this.planFinalizeIntent(projectRoot, args);
|
|
767
|
+
break;
|
|
768
|
+
case 'codesdd.frontend_impact':
|
|
769
|
+
result = this.planFrontendImpactIntent(projectRoot, args);
|
|
770
|
+
break;
|
|
771
|
+
case 'codesdd.skill_prompt':
|
|
772
|
+
result = await this.buildSkillPrompt(projectRoot, args);
|
|
773
|
+
break;
|
|
132
774
|
default:
|
|
775
|
+
// The registry resolver rejects unknown tools before this switch. This branch is retained
|
|
776
|
+
// as a compile-time exhaustiveness guard if new tools are added without implementation.
|
|
133
777
|
throw new Error(`Unsupported MCP tool "${input.tool}"`);
|
|
134
778
|
}
|
|
135
779
|
return {
|
|
136
|
-
protocol: '
|
|
780
|
+
protocol: 'codesdd-mcp-bridge/v1',
|
|
137
781
|
provider: providerId,
|
|
138
|
-
tool
|
|
782
|
+
tool,
|
|
783
|
+
requested_tool: resolution.requestedTool,
|
|
784
|
+
compatibility_alias_used: resolution.compatibilityAliasUsed,
|
|
785
|
+
registry_resolution: {
|
|
786
|
+
registry: 'codesdd-runtime-tool-registry',
|
|
787
|
+
registry_entry_ref: resolution.entry.id,
|
|
788
|
+
canonical_tool: tool,
|
|
789
|
+
requested_tool: resolution.requestedTool,
|
|
790
|
+
compatibility_alias_used: resolution.compatibilityAliasUsed,
|
|
791
|
+
state_access: resolution.entry.implementation.state_access,
|
|
792
|
+
},
|
|
793
|
+
state_boundary: MCP_RUNTIME_STATE_BOUNDARY,
|
|
139
794
|
invoked_at: nowIso(),
|
|
140
795
|
result,
|
|
141
796
|
};
|
|
142
797
|
}
|
|
798
|
+
async queryState(args) {
|
|
799
|
+
const ref = typeof args.ref === 'string' ? args.ref.trim().toUpperCase() : '';
|
|
800
|
+
const query = typeof args.query === 'string' ? args.query.trim() : '';
|
|
801
|
+
const scope = args.scope === 'backlog' || args.scope === 'discovery' || args.scope === 'all'
|
|
802
|
+
? args.scope
|
|
803
|
+
: 'all';
|
|
804
|
+
const limit = typeof args.limit === 'number' && Number.isFinite(args.limit)
|
|
805
|
+
? Math.max(1, Math.floor(args.limit))
|
|
806
|
+
: 20;
|
|
807
|
+
if (!ref && !query) {
|
|
808
|
+
throw new Error('codesdd.query requires args.ref or args.query');
|
|
809
|
+
}
|
|
810
|
+
const backlog = scope === 'discovery' ? null : await this.stores.backlog.load();
|
|
811
|
+
const discovery = scope === 'backlog' ? null : await this.stores.discoveryIndex.load();
|
|
812
|
+
if (ref) {
|
|
813
|
+
const feature = backlog?.items.find((item) => item.id.toUpperCase() === ref);
|
|
814
|
+
if (feature) {
|
|
815
|
+
const dependents = backlog?.items
|
|
816
|
+
.filter((item) => item.blocked_by.includes(feature.id))
|
|
817
|
+
.map((item) => item.id) ?? [];
|
|
818
|
+
return {
|
|
819
|
+
mode: 'ref',
|
|
820
|
+
scope,
|
|
821
|
+
ref: feature.id,
|
|
822
|
+
type: 'feature',
|
|
823
|
+
result: {
|
|
824
|
+
id: feature.id,
|
|
825
|
+
title: feature.title,
|
|
826
|
+
status: feature.status,
|
|
827
|
+
blocked_by: feature.blocked_by,
|
|
828
|
+
dependents,
|
|
829
|
+
touches: feature.touches,
|
|
830
|
+
current_stage: feature.current_stage,
|
|
831
|
+
},
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
const record = discovery?.records.find((item) => item.id.toUpperCase() === ref);
|
|
835
|
+
if (record) {
|
|
836
|
+
return {
|
|
837
|
+
mode: 'ref',
|
|
838
|
+
scope,
|
|
839
|
+
ref: record.id,
|
|
840
|
+
type: record.type.toLowerCase(),
|
|
841
|
+
result: {
|
|
842
|
+
id: record.id,
|
|
843
|
+
type: record.type,
|
|
844
|
+
title: record.title,
|
|
845
|
+
status: record.status,
|
|
846
|
+
related_ids: record.related_ids,
|
|
847
|
+
warning_links: record.warning_links,
|
|
848
|
+
},
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
return { mode: 'ref', scope, ref, type: 'not_found', result: null };
|
|
852
|
+
}
|
|
853
|
+
const token = query.toLowerCase();
|
|
854
|
+
const backlogMatches = (backlog?.items ?? [])
|
|
855
|
+
.filter((item) => {
|
|
856
|
+
const haystack = [
|
|
857
|
+
item.id,
|
|
858
|
+
item.title,
|
|
859
|
+
item.summary || '',
|
|
860
|
+
item.origin_ref || '',
|
|
861
|
+
...item.touches,
|
|
862
|
+
...item.blocked_by,
|
|
863
|
+
]
|
|
864
|
+
.join(' ')
|
|
865
|
+
.toLowerCase();
|
|
866
|
+
return haystack.includes(token);
|
|
867
|
+
})
|
|
868
|
+
.slice(0, limit)
|
|
869
|
+
.map((item) => ({
|
|
870
|
+
id: item.id,
|
|
871
|
+
title: item.title,
|
|
872
|
+
status: item.status,
|
|
873
|
+
origin_ref: item.origin_ref,
|
|
874
|
+
}));
|
|
875
|
+
const discoveryMatches = (discovery?.records ?? [])
|
|
876
|
+
.filter((item) => {
|
|
877
|
+
const haystack = [
|
|
878
|
+
item.id,
|
|
879
|
+
item.type,
|
|
880
|
+
item.title,
|
|
881
|
+
...item.related_ids,
|
|
882
|
+
...item.warning_links,
|
|
883
|
+
]
|
|
884
|
+
.join(' ')
|
|
885
|
+
.toLowerCase();
|
|
886
|
+
return haystack.includes(token);
|
|
887
|
+
})
|
|
888
|
+
.slice(0, limit)
|
|
889
|
+
.map((item) => ({
|
|
890
|
+
id: item.id,
|
|
891
|
+
type: item.type,
|
|
892
|
+
title: item.title,
|
|
893
|
+
status: item.status,
|
|
894
|
+
}));
|
|
895
|
+
return {
|
|
896
|
+
mode: 'search',
|
|
897
|
+
scope,
|
|
898
|
+
query,
|
|
899
|
+
limit,
|
|
900
|
+
counts: {
|
|
901
|
+
backlog: backlogMatches.length,
|
|
902
|
+
discovery: discoveryMatches.length,
|
|
903
|
+
},
|
|
904
|
+
results: {
|
|
905
|
+
backlog: backlogMatches,
|
|
906
|
+
discovery: discoveryMatches,
|
|
907
|
+
},
|
|
908
|
+
};
|
|
909
|
+
}
|
|
910
|
+
async readWorkspaceDocs(projectRoot, args) {
|
|
911
|
+
const ref = typeof args.ref === 'string' ? args.ref.trim().toUpperCase() : '';
|
|
912
|
+
if (!ref) {
|
|
913
|
+
throw new Error('codesdd.read requires args.ref');
|
|
914
|
+
}
|
|
915
|
+
const doc = typeof args.doc === 'string' &&
|
|
916
|
+
['spec', 'plan', 'tasks', 'changelog', 'quality', 'all'].includes(args.doc)
|
|
917
|
+
? args.doc
|
|
918
|
+
: 'all';
|
|
919
|
+
const roots = [
|
|
920
|
+
{ state: 'active', dir: path.join(projectRoot, '.sdd', 'active') },
|
|
921
|
+
{ state: 'planned', dir: path.join(projectRoot, '.sdd', 'planned') },
|
|
922
|
+
{ state: 'archived', dir: path.join(projectRoot, '.sdd', 'archived') },
|
|
923
|
+
];
|
|
924
|
+
let root = null;
|
|
925
|
+
for (const candidate of roots) {
|
|
926
|
+
const workspaceDir = path.join(candidate.dir, ref);
|
|
927
|
+
try {
|
|
928
|
+
await fs.access(workspaceDir);
|
|
929
|
+
root = candidate;
|
|
930
|
+
break;
|
|
931
|
+
}
|
|
932
|
+
catch {
|
|
933
|
+
continue;
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
if (!root) {
|
|
937
|
+
return {
|
|
938
|
+
ref,
|
|
939
|
+
workspace_state: 'not_found',
|
|
940
|
+
workspace_path: '',
|
|
941
|
+
docs: {},
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
const workspaceDir = path.join(root.dir, ref);
|
|
945
|
+
const docMap = {
|
|
946
|
+
spec: '1-spec.yaml',
|
|
947
|
+
plan: '2-plan.yaml',
|
|
948
|
+
tasks: '3-tasks.yaml',
|
|
949
|
+
changelog: '4-changelog.yaml',
|
|
950
|
+
quality: '5-quality.yaml',
|
|
951
|
+
};
|
|
952
|
+
const requestedDocs = doc === 'all'
|
|
953
|
+
? Object.keys(docMap)
|
|
954
|
+
: [doc];
|
|
955
|
+
const docs = {};
|
|
956
|
+
for (const docKey of requestedDocs) {
|
|
957
|
+
const filePath = path.join(workspaceDir, docMap[docKey]);
|
|
958
|
+
const content = await fs.readFile(filePath, 'utf-8').catch(() => '');
|
|
959
|
+
if (!content.trim()) {
|
|
960
|
+
docs[docKey] = null;
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
963
|
+
try {
|
|
964
|
+
docs[docKey] = parseYaml(content);
|
|
965
|
+
}
|
|
966
|
+
catch {
|
|
967
|
+
docs[docKey] = { parse_error: true };
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
return {
|
|
971
|
+
ref,
|
|
972
|
+
workspace_state: root.state,
|
|
973
|
+
workspace_path: path.relative(projectRoot, workspaceDir).replace(/\\/g, '/'),
|
|
974
|
+
docs,
|
|
975
|
+
};
|
|
976
|
+
}
|
|
977
|
+
planStartIntent(projectRoot, args) {
|
|
978
|
+
const refOrText = typeof args.refOrText === 'string' ? args.refOrText.trim() : '';
|
|
979
|
+
if (!refOrText) {
|
|
980
|
+
throw new Error('codesdd.start requires args.refOrText');
|
|
981
|
+
}
|
|
982
|
+
const commandArgs = ['sdd', 'start', refOrText, '--json'];
|
|
983
|
+
if (typeof args.scale === 'string' && ['QUICK', 'STANDARD', 'LARGE'].includes(args.scale)) {
|
|
984
|
+
commandArgs.push('--scale', args.scale);
|
|
985
|
+
}
|
|
986
|
+
if (typeof args.schema === 'string' && args.schema.trim()) {
|
|
987
|
+
commandArgs.push('--schema', args.schema.trim());
|
|
988
|
+
}
|
|
989
|
+
if (typeof args.flowMode === 'string' && ['direct', 'standard', 'rigorous'].includes(args.flowMode)) {
|
|
990
|
+
commandArgs.push('--flow-mode', args.flowMode);
|
|
991
|
+
}
|
|
992
|
+
if (args.force === true) {
|
|
993
|
+
commandArgs.push('--force');
|
|
994
|
+
}
|
|
995
|
+
if (args.forceTransition === true) {
|
|
996
|
+
commandArgs.push('--force-transition');
|
|
997
|
+
}
|
|
998
|
+
return {
|
|
999
|
+
action: 'start',
|
|
1000
|
+
intent_only: true,
|
|
1001
|
+
command: {
|
|
1002
|
+
bin: process.execPath,
|
|
1003
|
+
args: [path.join(projectRoot, 'bin', 'codesdd.js'), ...commandArgs],
|
|
1004
|
+
cwd: projectRoot,
|
|
1005
|
+
},
|
|
1006
|
+
gate: {
|
|
1007
|
+
executes_immediately: false,
|
|
1008
|
+
required_flag: '--allow-mutation-execution',
|
|
1009
|
+
ui_can_write_state_directly: false,
|
|
1010
|
+
},
|
|
1011
|
+
};
|
|
1012
|
+
}
|
|
1013
|
+
async inspectPlugin(args) {
|
|
1014
|
+
const manifestPath = typeof args.manifestPath === 'string' ? args.manifestPath.trim() : '';
|
|
1015
|
+
if (!manifestPath) {
|
|
1016
|
+
throw new Error('codesdd.plugin.inspect requires args.manifestPath');
|
|
1017
|
+
}
|
|
1018
|
+
return inspectPluginManifestFromFile(manifestPath);
|
|
1019
|
+
}
|
|
1020
|
+
async planPlugin(args, applySandbox) {
|
|
1021
|
+
const manifestPath = typeof args.manifestPath === 'string' ? args.manifestPath.trim() : '';
|
|
1022
|
+
const featureRef = typeof args.featureRef === 'string' ? args.featureRef.trim() : '';
|
|
1023
|
+
const capability = typeof args.capability === 'string' ? args.capability.trim() : '';
|
|
1024
|
+
if (!manifestPath) {
|
|
1025
|
+
throw new Error('codesdd.plugin.plan requires args.manifestPath');
|
|
1026
|
+
}
|
|
1027
|
+
if (!featureRef) {
|
|
1028
|
+
throw new Error('codesdd.plugin.plan requires args.featureRef');
|
|
1029
|
+
}
|
|
1030
|
+
if (!capability) {
|
|
1031
|
+
throw new Error('codesdd.plugin.plan requires args.capability');
|
|
1032
|
+
}
|
|
1033
|
+
const result = await planPluginInvocationFromFile(manifestPath, {
|
|
1034
|
+
feature_ref: featureRef,
|
|
1035
|
+
capability,
|
|
1036
|
+
mode: applySandbox ? 'apply' : 'dry-run',
|
|
1037
|
+
skill_ref: typeof args.skillRef === 'string' ? args.skillRef : undefined,
|
|
1038
|
+
inputs: args.inputs && typeof args.inputs === 'object' && !Array.isArray(args.inputs)
|
|
1039
|
+
? args.inputs
|
|
1040
|
+
: {},
|
|
1041
|
+
requested_write_scope: parseStringArrayArg(args.writeScope),
|
|
1042
|
+
approval_grants: parseStringArrayArg(args.approvalGrants),
|
|
1043
|
+
operation_id: typeof args.operationId === 'string' ? args.operationId : undefined,
|
|
1044
|
+
source_checksum: typeof args.sourceChecksum === 'string' ? args.sourceChecksum : undefined,
|
|
1045
|
+
planned_writes: parseStringArrayArg(args.plannedWrites),
|
|
1046
|
+
requested_env: parseStringArrayArg(args.requestedEnv),
|
|
1047
|
+
network_domains: parseStringArrayArg(args.networkDomains),
|
|
1048
|
+
process_spawn_requested: args.processSpawnRequested === true,
|
|
1049
|
+
technology: args.technology && typeof args.technology === 'object' && !Array.isArray(args.technology)
|
|
1050
|
+
? args.technology
|
|
1051
|
+
: undefined,
|
|
1052
|
+
});
|
|
1053
|
+
return applySandbox
|
|
1054
|
+
? {
|
|
1055
|
+
action: 'plugin.apply_sandbox',
|
|
1056
|
+
intent_only: true,
|
|
1057
|
+
plan: result,
|
|
1058
|
+
gate: {
|
|
1059
|
+
executes_immediately: false,
|
|
1060
|
+
required_flag: '--allow-mutation-execution',
|
|
1061
|
+
ui_can_write_state_directly: false,
|
|
1062
|
+
},
|
|
1063
|
+
}
|
|
1064
|
+
: result;
|
|
1065
|
+
}
|
|
1066
|
+
async readQualityEvidence(projectRoot, args) {
|
|
1067
|
+
const ref = typeof args.ref === 'string' ? args.ref.trim().toUpperCase() : '';
|
|
1068
|
+
if (!ref) {
|
|
1069
|
+
throw new Error('codesdd.quality.evidence requires args.ref');
|
|
1070
|
+
}
|
|
1071
|
+
const workspace = (await this.readWorkspaceDocs(projectRoot, {
|
|
1072
|
+
ref,
|
|
1073
|
+
doc: 'quality',
|
|
1074
|
+
}));
|
|
1075
|
+
const quality = workspace.docs?.quality;
|
|
1076
|
+
if (!quality || typeof quality !== 'object') {
|
|
1077
|
+
return {
|
|
1078
|
+
ref: workspace.ref,
|
|
1079
|
+
workspace_state: workspace.workspace_state,
|
|
1080
|
+
workspace_path: workspace.workspace_path,
|
|
1081
|
+
status: 'quality_document_not_found',
|
|
1082
|
+
quality: null,
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
return {
|
|
1086
|
+
ref: workspace.ref,
|
|
1087
|
+
workspace_state: workspace.workspace_state,
|
|
1088
|
+
workspace_path: workspace.workspace_path,
|
|
1089
|
+
status: 'ok',
|
|
1090
|
+
quality: {
|
|
1091
|
+
coverage_targets: quality.coverage_targets ?? null,
|
|
1092
|
+
evidence_log: quality.evidence_log ?? [],
|
|
1093
|
+
skill_evidence: quality.skill_evidence ?? null,
|
|
1094
|
+
acceptance_matrix: quality.acceptance_matrix ?? [],
|
|
1095
|
+
exceptions: quality.exceptions ?? [],
|
|
1096
|
+
},
|
|
1097
|
+
};
|
|
1098
|
+
}
|
|
1099
|
+
async readAdrIndex(projectRoot, args) {
|
|
1100
|
+
const ref = typeof args.ref === 'string' ? args.ref.trim().toUpperCase() : '';
|
|
1101
|
+
const adrDir = path.join(projectRoot, '.sdd', 'core', 'adrs');
|
|
1102
|
+
const names = await fs.readdir(adrDir).catch(() => []);
|
|
1103
|
+
const files = names
|
|
1104
|
+
.filter((name) => /^ADR-.*\.md$/u.test(name))
|
|
1105
|
+
.sort();
|
|
1106
|
+
const entries = await Promise.all(files.map(async (name) => {
|
|
1107
|
+
const absolutePath = path.join(adrDir, name);
|
|
1108
|
+
const relativePath = path.relative(projectRoot, absolutePath).replace(/\\/g, '/');
|
|
1109
|
+
if (!ref) {
|
|
1110
|
+
return {
|
|
1111
|
+
adr_id: name.replace(/\.md$/u, ''),
|
|
1112
|
+
path: relativePath,
|
|
1113
|
+
related_to_ref: false,
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
const content = await fs.readFile(absolutePath, 'utf-8').catch(() => '');
|
|
1117
|
+
const related = content.toUpperCase().includes(ref);
|
|
1118
|
+
return {
|
|
1119
|
+
adr_id: name.replace(/\.md$/u, ''),
|
|
1120
|
+
path: relativePath,
|
|
1121
|
+
related_to_ref: related,
|
|
1122
|
+
};
|
|
1123
|
+
}));
|
|
1124
|
+
return {
|
|
1125
|
+
ref: ref || null,
|
|
1126
|
+
total: entries.length,
|
|
1127
|
+
matches: ref ? entries.filter((entry) => entry.related_to_ref) : entries,
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
planFinalizeIntent(projectRoot, args) {
|
|
1131
|
+
const featureId = typeof args.featureId === 'string' ? args.featureId.trim() : '';
|
|
1132
|
+
if (!featureId) {
|
|
1133
|
+
throw new Error('codesdd.finalize_intent requires args.featureId');
|
|
1134
|
+
}
|
|
1135
|
+
return {
|
|
1136
|
+
...new GovernanceControlPlaneService().planMutationIntent(projectRoot, 'finalize', {
|
|
1137
|
+
featureId,
|
|
1138
|
+
}),
|
|
1139
|
+
};
|
|
1140
|
+
}
|
|
1141
|
+
planFrontendImpactIntent(projectRoot, args) {
|
|
1142
|
+
const featureId = typeof args.featureId === 'string' ? args.featureId.trim() : '';
|
|
1143
|
+
const status = typeof args.status === 'string' ? args.status.trim() : '';
|
|
1144
|
+
if (!featureId) {
|
|
1145
|
+
throw new Error('codesdd.frontend_impact requires args.featureId');
|
|
1146
|
+
}
|
|
1147
|
+
if (!status) {
|
|
1148
|
+
throw new Error('codesdd.frontend_impact requires args.status');
|
|
1149
|
+
}
|
|
1150
|
+
const params = {
|
|
1151
|
+
featureId,
|
|
1152
|
+
status,
|
|
1153
|
+
};
|
|
1154
|
+
if (typeof args.reason === 'string' && args.reason.trim()) {
|
|
1155
|
+
params.reason = args.reason.trim();
|
|
1156
|
+
}
|
|
1157
|
+
const routes = parseStringArrayArg(args.routes).join(',');
|
|
1158
|
+
if (routes) {
|
|
1159
|
+
params.routes = routes;
|
|
1160
|
+
}
|
|
1161
|
+
const surfaces = parseStringArrayArg(args.surfaces).join(',');
|
|
1162
|
+
if (surfaces) {
|
|
1163
|
+
params.surfaces = surfaces;
|
|
1164
|
+
}
|
|
1165
|
+
return {
|
|
1166
|
+
...new GovernanceControlPlaneService().planMutationIntent(projectRoot, 'frontend-impact', params),
|
|
1167
|
+
};
|
|
1168
|
+
}
|
|
1169
|
+
async buildSkillPrompt(projectRoot, args) {
|
|
1170
|
+
return new SkillsInvokeService(this.stores).execute(projectRoot, {
|
|
1171
|
+
ids: parseStringArrayArg(args.ids),
|
|
1172
|
+
phase: typeof args.phase === 'string' ? args.phase : undefined,
|
|
1173
|
+
domains: parseStringArrayArg(args.domains),
|
|
1174
|
+
bundles: parseStringArrayArg(args.bundles),
|
|
1175
|
+
max: typeof args.max === 'number' ? Math.max(1, Math.floor(args.max)) : undefined,
|
|
1176
|
+
objective: typeof args.objective === 'string' ? args.objective : undefined,
|
|
1177
|
+
ref: typeof args.ref === 'string' ? args.ref : undefined,
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
function parseStringArrayArg(input) {
|
|
1182
|
+
if (Array.isArray(input)) {
|
|
1183
|
+
return input
|
|
1184
|
+
.filter((value) => typeof value === 'string')
|
|
1185
|
+
.map((value) => value.trim())
|
|
1186
|
+
.filter(Boolean);
|
|
1187
|
+
}
|
|
1188
|
+
if (typeof input === 'string') {
|
|
1189
|
+
return input
|
|
1190
|
+
.split(',')
|
|
1191
|
+
.map((value) => value.trim())
|
|
1192
|
+
.filter(Boolean);
|
|
1193
|
+
}
|
|
1194
|
+
return [];
|
|
143
1195
|
}
|
|
144
1196
|
//# sourceMappingURL=mcp-runtime.service.js.map
|