specweave 0.29.2 → 0.30.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -16
- package/bin/specweave.js +16 -0
- package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.d.ts +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.js +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-commit-sync.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js +1 -1
- package/dist/plugins/specweave-ado/lib/ado-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts +134 -0
- package/dist/plugins/specweave-ado/lib/conflict-resolver.d.ts.map +1 -0
- package/dist/plugins/specweave-ado/lib/conflict-resolver.js +423 -0
- package/dist/plugins/specweave-ado/lib/conflict-resolver.js.map +1 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts +23 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-client-v2.js +95 -0
- package/dist/plugins/specweave-github/lib/github-client-v2.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-commit-sync.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-commit-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-commit-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-commit-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js +1 -1
- package/dist/plugins/specweave-github/lib/github-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-github/lib/types.d.ts +20 -0
- package/dist/plugins/specweave-github/lib/types.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-commit-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.d.ts +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.js +1 -1
- package/dist/plugins/specweave-jira/lib/jira-spec-content-sync.js.map +1 -1
- package/dist/plugins/specweave-jira/lib/setup-wizard.d.ts +2 -2
- package/dist/plugins/specweave-jira/lib/setup-wizard.d.ts.map +1 -1
- package/dist/plugins/specweave-jira/lib/setup-wizard.js +1 -1
- package/dist/plugins/specweave-jira/lib/setup-wizard.js.map +1 -1
- package/dist/src/adapters/claude/adapter.js +1 -1
- package/dist/src/adapters/claude/adapter.js.map +1 -1
- package/dist/src/cli/commands/detect-project.js +1 -1
- package/dist/src/cli/commands/detect-project.js.map +1 -1
- package/dist/src/cli/commands/detect-specs.js +1 -1
- package/dist/src/cli/commands/detect-specs.js.map +1 -1
- package/dist/src/cli/commands/import-docs.js +1 -1
- package/dist/src/cli/commands/import-docs.js.map +1 -1
- package/dist/src/cli/commands/init-multiproject.js +1 -1
- package/dist/src/cli/commands/init-multiproject.js.map +1 -1
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +31 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/jobs.js +15 -1
- package/dist/src/cli/commands/jobs.js.map +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.js +1 -1
- package/dist/src/cli/commands/migrate-to-multiproject.js.map +1 -1
- package/dist/src/cli/commands/switch-project.js +1 -1
- package/dist/src/cli/commands/switch-project.js.map +1 -1
- package/dist/src/cli/commands/sync-scheduled.d.ts +38 -0
- package/dist/src/cli/commands/sync-scheduled.d.ts.map +1 -0
- package/dist/src/cli/commands/sync-scheduled.js +170 -0
- package/dist/src/cli/commands/sync-scheduled.js.map +1 -0
- package/dist/src/cli/helpers/init/external-import-grouping.d.ts +53 -0
- package/dist/src/cli/helpers/init/external-import-grouping.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/external-import-grouping.js +287 -0
- package/dist/src/cli/helpers/init/external-import-grouping.js.map +1 -0
- package/dist/src/cli/helpers/init/external-import.d.ts +1 -34
- package/dist/src/cli/helpers/init/external-import.d.ts.map +1 -1
- package/dist/src/cli/helpers/init/external-import.js +15 -486
- package/dist/src/cli/helpers/init/external-import.js.map +1 -1
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts +58 -0
- package/dist/src/cli/helpers/init/living-docs-preflight.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/living-docs-preflight.js +290 -0
- package/dist/src/cli/helpers/init/living-docs-preflight.js.map +1 -0
- package/dist/src/cli/helpers/init/sync-profile-helpers.d.ts +48 -0
- package/dist/src/cli/helpers/init/sync-profile-helpers.d.ts.map +1 -0
- package/dist/src/cli/helpers/init/sync-profile-helpers.js +238 -0
- package/dist/src/cli/helpers/init/sync-profile-helpers.js.map +1 -0
- package/dist/src/cli/helpers/init/types.d.ts +1 -0
- package/dist/src/cli/helpers/init/types.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/ado.js +113 -3
- package/dist/src/cli/helpers/issue-tracker/ado.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/index.js +2 -287
- package/dist/src/cli/helpers/issue-tracker/index.js.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts +25 -0
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.d.ts.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js +306 -0
- package/dist/src/cli/helpers/issue-tracker/sync-config-writer.js.map +1 -0
- package/dist/src/cli/helpers/issue-tracker/types.d.ts +27 -0
- package/dist/src/cli/helpers/issue-tracker/types.d.ts.map +1 -1
- package/dist/src/cli/helpers/issue-tracker/types.js.map +1 -1
- package/dist/src/cli/workers/living-docs-worker.d.ts +16 -0
- package/dist/src/cli/workers/living-docs-worker.d.ts.map +1 -0
- package/dist/src/cli/workers/living-docs-worker.js +395 -0
- package/dist/src/cli/workers/living-docs-worker.js.map +1 -0
- package/dist/src/core/background/job-dependency.d.ts +45 -0
- package/dist/src/core/background/job-dependency.d.ts.map +1 -0
- package/dist/src/core/background/job-dependency.js +144 -0
- package/dist/src/core/background/job-dependency.js.map +1 -0
- package/dist/src/core/background/job-launcher.d.ts +21 -1
- package/dist/src/core/background/job-launcher.d.ts.map +1 -1
- package/dist/src/core/background/job-launcher.js +93 -0
- package/dist/src/core/background/job-launcher.js.map +1 -1
- package/dist/src/core/background/types.d.ts +73 -2
- package/dist/src/core/background/types.d.ts.map +1 -1
- package/dist/src/core/brownfield/importer.js +1 -1
- package/dist/src/core/brownfield/importer.js.map +1 -1
- package/dist/src/core/comment-builder.d.ts +1 -1
- package/dist/src/core/comment-builder.d.ts.map +1 -1
- package/dist/src/core/{cost-tracker.d.ts → cost/cost-tracker.d.ts} +2 -2
- package/dist/src/core/cost/cost-tracker.d.ts.map +1 -0
- package/dist/src/core/{cost-tracker.js → cost/cost-tracker.js} +2 -2
- package/dist/src/core/cost/cost-tracker.js.map +1 -0
- package/dist/src/core/credentials/credentials-manager.d.ts.map +1 -0
- package/dist/src/core/credentials/credentials-manager.js.map +1 -0
- package/dist/src/core/increment/discipline-checker.js +1 -1
- package/dist/src/core/increment/discipline-checker.js.map +1 -1
- package/dist/src/core/increment/increment-archiver.d.ts +9 -8
- package/dist/src/core/increment/increment-archiver.d.ts.map +1 -1
- package/dist/src/core/increment/increment-archiver.js +40 -42
- package/dist/src/core/increment/increment-archiver.js.map +1 -1
- package/dist/src/core/increment/increment-status.d.ts.map +1 -0
- package/dist/src/core/{increment-status.js → increment/increment-status.js} +1 -1
- package/dist/src/core/increment/increment-status.js.map +1 -0
- package/dist/src/core/increment/increment-utils.d.ts.map +1 -0
- package/dist/src/core/increment/increment-utils.js.map +1 -0
- package/dist/src/core/increment/metadata-validator.js +1 -1
- package/dist/src/core/increment/metadata-validator.js.map +1 -1
- package/dist/src/core/living-docs/checkpoint-manager.d.ts +120 -0
- package/dist/src/core/living-docs/checkpoint-manager.d.ts.map +1 -0
- package/dist/src/core/living-docs/checkpoint-manager.js +231 -0
- package/dist/src/core/living-docs/checkpoint-manager.js.map +1 -0
- package/dist/src/core/living-docs/discovery.d.ts +91 -0
- package/dist/src/core/living-docs/discovery.d.ts.map +1 -0
- package/dist/src/core/living-docs/discovery.js +656 -0
- package/dist/src/core/living-docs/discovery.js.map +1 -0
- package/dist/src/core/living-docs/feature-archiver.d.ts +23 -4
- package/dist/src/core/living-docs/feature-archiver.d.ts.map +1 -1
- package/dist/src/core/living-docs/feature-archiver.js +133 -30
- package/dist/src/core/living-docs/feature-archiver.js.map +1 -1
- package/dist/src/core/living-docs/foundation-builder.d.ts +37 -0
- package/dist/src/core/living-docs/foundation-builder.d.ts.map +1 -0
- package/dist/src/core/living-docs/foundation-builder.js +357 -0
- package/dist/src/core/living-docs/foundation-builder.js.map +1 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts +58 -0
- package/dist/src/core/living-docs/living-docs-sync.d.ts.map +1 -1
- package/dist/src/core/living-docs/living-docs-sync.js +204 -7
- package/dist/src/core/living-docs/living-docs-sync.js.map +1 -1
- package/dist/src/core/living-docs/module-analyzer.d.ts +97 -0
- package/dist/src/core/living-docs/module-analyzer.d.ts.map +1 -0
- package/dist/src/core/living-docs/module-analyzer.js +427 -0
- package/dist/src/core/living-docs/module-analyzer.js.map +1 -0
- package/dist/src/core/living-docs/suggestions-generator.d.ts +112 -0
- package/dist/src/core/living-docs/suggestions-generator.d.ts.map +1 -0
- package/dist/src/core/living-docs/suggestions-generator.js +362 -0
- package/dist/src/core/living-docs/suggestions-generator.js.map +1 -0
- package/dist/src/core/living-docs/workitem-matcher.d.ts +116 -0
- package/dist/src/core/living-docs/workitem-matcher.d.ts.map +1 -0
- package/dist/src/core/living-docs/workitem-matcher.js +356 -0
- package/dist/src/core/living-docs/workitem-matcher.js.map +1 -0
- package/dist/src/core/{plugin-loader.d.ts → plugins/plugin-loader.d.ts} +1 -1
- package/dist/src/core/plugins/plugin-loader.d.ts.map +1 -0
- package/dist/src/core/{plugin-loader.js → plugins/plugin-loader.js} +2 -2
- package/dist/src/core/plugins/plugin-loader.js.map +1 -0
- package/dist/src/core/{project-manager.d.ts → project/project-manager.d.ts} +1 -1
- package/dist/src/core/project/project-manager.d.ts.map +1 -0
- package/dist/src/core/{project-manager.js → project/project-manager.js} +3 -3
- package/dist/src/core/project/project-manager.js.map +1 -0
- package/dist/src/core/project/project-structure-detector.d.ts.map +1 -0
- package/dist/src/core/project/project-structure-detector.js.map +1 -0
- package/dist/src/core/{rfc-generator-v2.d.ts → rfc/rfc-generator-v2.d.ts} +1 -1
- package/dist/src/core/rfc/rfc-generator-v2.d.ts.map +1 -0
- package/dist/src/core/{rfc-generator-v2.js → rfc/rfc-generator-v2.js} +1 -1
- package/dist/src/core/rfc/rfc-generator-v2.js.map +1 -0
- package/dist/src/core/scheduler/index.d.ts +1 -0
- package/dist/src/core/scheduler/index.d.ts.map +1 -1
- package/dist/src/core/scheduler/index.js +1 -0
- package/dist/src/core/scheduler/index.js.map +1 -1
- package/dist/src/core/scheduler/scheduled-job.d.ts +1 -1
- package/dist/src/core/scheduler/scheduled-job.d.ts.map +1 -1
- package/dist/src/core/scheduler/scheduled-job.js.map +1 -1
- package/dist/src/core/scheduler/session-sync-executor.d.ts +138 -0
- package/dist/src/core/scheduler/session-sync-executor.d.ts.map +1 -0
- package/dist/src/core/scheduler/session-sync-executor.js +333 -0
- package/dist/src/core/scheduler/session-sync-executor.js.map +1 -0
- package/dist/src/core/{spec-content-sync.d.ts → specs/spec-content-sync.d.ts} +2 -2
- package/dist/src/core/specs/spec-content-sync.d.ts.map +1 -0
- package/dist/src/core/{spec-content-sync.js → specs/spec-content-sync.js} +1 -1
- package/dist/src/core/specs/spec-content-sync.js.map +1 -0
- package/dist/src/core/{spec-detector.d.ts → specs/spec-detector.d.ts} +1 -1
- package/dist/src/core/specs/spec-detector.d.ts.map +1 -0
- package/dist/src/core/{spec-detector.js → specs/spec-detector.js} +1 -1
- package/dist/src/core/specs/spec-detector.js.map +1 -0
- package/dist/src/core/{spec-identifier-detector.d.ts → specs/spec-identifier-detector.d.ts} +2 -2
- package/dist/src/core/specs/spec-identifier-detector.d.ts.map +1 -0
- package/dist/src/core/{spec-identifier-detector.js → specs/spec-identifier-detector.js} +1 -1
- package/dist/src/core/specs/spec-identifier-detector.js.map +1 -0
- package/dist/src/core/specs/spec-metadata-manager.js +1 -1
- package/dist/src/core/specs/spec-metadata-manager.js.map +1 -1
- package/dist/src/core/specs/spec-task-mapper.d.ts.map +1 -0
- package/dist/src/core/specs/spec-task-mapper.js.map +1 -0
- package/dist/src/core/sync/sync-audit-logger.d.ts +62 -0
- package/dist/src/core/sync/sync-audit-logger.d.ts.map +1 -1
- package/dist/src/core/sync/sync-audit-logger.js +59 -0
- package/dist/src/core/sync/sync-audit-logger.js.map +1 -1
- package/dist/src/importers/item-converter.d.ts +51 -27
- package/dist/src/importers/item-converter.d.ts.map +1 -1
- package/dist/src/importers/item-converter.js +219 -179
- package/dist/src/importers/item-converter.js.map +1 -1
- package/dist/src/importers/markdown-generator.d.ts +75 -0
- package/dist/src/importers/markdown-generator.d.ts.map +1 -0
- package/dist/src/importers/markdown-generator.js +250 -0
- package/dist/src/importers/markdown-generator.js.map +1 -0
- package/dist/src/integrations/ado/ado-client.d.ts +93 -0
- package/dist/src/integrations/ado/ado-client.d.ts.map +1 -1
- package/dist/src/integrations/ado/ado-client.js +172 -1
- package/dist/src/integrations/ado/ado-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-client.d.ts +44 -0
- package/dist/src/integrations/jira/jira-client.d.ts.map +1 -1
- package/dist/src/integrations/jira/jira-client.js +119 -1
- package/dist/src/integrations/jira/jira-client.js.map +1 -1
- package/dist/src/integrations/jira/jira-incremental-mapper.js +2 -2
- package/dist/src/integrations/jira/jira-incremental-mapper.js.map +1 -1
- package/dist/src/integrations/jira/jira-mapper.js +1 -1
- package/dist/src/integrations/jira/jira-mapper.js.map +1 -1
- package/dist/src/living-docs/epic-id-allocator.d.ts +177 -0
- package/dist/src/living-docs/epic-id-allocator.d.ts.map +1 -0
- package/dist/src/living-docs/epic-id-allocator.js +363 -0
- package/dist/src/living-docs/epic-id-allocator.js.map +1 -0
- package/dist/src/sync/external-change-puller.d.ts +94 -0
- package/dist/src/sync/external-change-puller.d.ts.map +1 -0
- package/dist/src/sync/external-change-puller.js +181 -0
- package/dist/src/sync/external-change-puller.js.map +1 -0
- package/dist/src/sync/index.d.ts +4 -0
- package/dist/src/sync/index.d.ts.map +1 -1
- package/dist/src/sync/index.js +2 -0
- package/dist/src/sync/index.js.map +1 -1
- package/dist/src/sync/living-docs-updater.d.ts +93 -0
- package/dist/src/sync/living-docs-updater.d.ts.map +1 -0
- package/dist/src/sync/living-docs-updater.js +218 -0
- package/dist/src/sync/living-docs-updater.js.map +1 -0
- package/dist/src/testing/test-generator.js +1 -1
- package/dist/src/testing/test-generator.js.map +1 -1
- package/dist/src/utils/cost-reporter.d.ts +1 -1
- package/dist/src/utils/cost-reporter.d.ts.map +1 -1
- package/dist/src/utils/model-selection.js +4 -4
- package/dist/src/utils/model-selection.js.map +1 -1
- package/dist/src/utils/pricing-constants.d.ts +2 -2
- package/dist/src/utils/pricing-constants.js +2 -2
- package/package.json +1 -1
- package/plugins/specweave/.claude-plugin/plugin.json +1 -28
- package/plugins/specweave/agents/code-standards-detective/AGENT.md +3 -3
- package/plugins/specweave/agents/infrastructure/AGENT.md +4 -0
- package/plugins/specweave/agents/performance/AGENT.md +2 -2
- package/plugins/specweave/agents/reflective-reviewer/AGENT.md +3 -3
- package/plugins/specweave/agents/translator/AGENT.md +2 -2
- package/plugins/specweave/commands/specweave-costs.md +2 -2
- package/plugins/specweave/commands/specweave-do.md +2 -2
- package/plugins/specweave/hooks/lib/scheduler-startup.sh +59 -8
- package/plugins/specweave/skills/code-reviewer/SKILL.md +1 -1
- package/plugins/specweave/skills/role-orchestrator/README.md +1 -1
- package/plugins/specweave-ado/agents/ado-manager/AGENT.md +8 -2
- package/plugins/specweave-ado/agents/ado-multi-project-mapper/AGENT.md +2 -2
- package/plugins/specweave-ado/agents/ado-sync-judge/AGENT.md +2 -2
- package/plugins/specweave-ado/lib/ado-spec-commit-sync.d.ts +1 -1
- package/plugins/specweave-ado/lib/ado-spec-commit-sync.js +1 -1
- package/plugins/specweave-ado/lib/ado-spec-commit-sync.ts +1 -1
- package/plugins/specweave-ado/lib/ado-spec-content-sync.js +1 -1
- package/plugins/specweave-ado/lib/ado-spec-content-sync.ts +1 -1
- package/plugins/specweave-ado/lib/conflict-resolver.js +87 -0
- package/plugins/specweave-ado/lib/conflict-resolver.ts +124 -0
- package/plugins/specweave-ado/skills/specweave-ado-mapper/SKILL.md +1 -1
- package/plugins/specweave-backend/agents/database-optimizer/AGENT.md +3 -3
- package/plugins/specweave-backend/skills/dotnet-backend/SKILL.md +1 -1
- package/plugins/specweave-backend/skills/nodejs-backend/SKILL.md +1 -1
- package/plugins/specweave-backend/skills/python-backend/SKILL.md +1 -1
- package/plugins/specweave-confluent/agents/confluent-architect/AGENT.md +6 -1
- package/plugins/specweave-diagrams/agents/diagrams-architect/AGENT.md +2 -2
- package/plugins/specweave-diagrams/skills/diagrams-architect/SKILL.md +1 -1
- package/plugins/specweave-frontend/agents/frontend-architect/AGENT.md +4 -0
- package/plugins/specweave-github/agents/github-manager/AGENT.md +1 -1
- package/plugins/specweave-github/agents/github-task-splitter/AGENT.md +11 -1
- package/plugins/specweave-github/agents/user-story-updater/AGENT.md +6 -1
- package/plugins/specweave-github/hooks/.specweave/logs/hooks-debug.log +90 -0
- package/plugins/specweave-github/lib/github-client-v2.js +97 -0
- package/plugins/specweave-github/lib/github-client-v2.ts +115 -1
- package/plugins/specweave-github/lib/github-spec-commit-sync.d.ts +1 -1
- package/plugins/specweave-github/lib/github-spec-commit-sync.js +1 -1
- package/plugins/specweave-github/lib/github-spec-commit-sync.ts +1 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.js +1 -1
- package/plugins/specweave-github/lib/github-spec-content-sync.ts +1 -1
- package/plugins/specweave-github/lib/types.ts +21 -0
- package/plugins/specweave-infrastructure/agents/devops/AGENT.md +1 -1
- package/plugins/specweave-infrastructure/agents/network-engineer/AGENT.md +3 -3
- package/plugins/specweave-infrastructure/agents/observability-engineer/AGENT.md +2 -2
- package/plugins/specweave-infrastructure/agents/performance-engineer/AGENT.md +3 -3
- package/plugins/specweave-infrastructure/agents/sre/AGENT.md +2 -2
- package/plugins/specweave-jira/agents/jira-manager/AGENT.md +11 -1
- package/plugins/specweave-jira/commands/import-projects.js +1 -1
- package/plugins/specweave-jira/commands/import-projects.ts +1 -1
- package/plugins/specweave-jira/lib/jira-spec-commit-sync.d.ts +1 -1
- package/plugins/specweave-jira/lib/jira-spec-commit-sync.js +1 -1
- package/plugins/specweave-jira/lib/jira-spec-commit-sync.ts +1 -1
- package/plugins/specweave-jira/lib/jira-spec-content-sync.js +1 -1
- package/plugins/specweave-jira/lib/jira-spec-content-sync.ts +1 -1
- package/plugins/specweave-jira/lib/setup-wizard.js +2 -2
- package/plugins/specweave-jira/lib/setup-wizard.ts +2 -2
- package/plugins/specweave-jira/skills/specweave-jira-mapper/SKILL.md +1 -1
- package/plugins/specweave-kafka/agents/kafka-architect/AGENT.md +5 -1
- package/plugins/specweave-kafka/agents/kafka-devops/AGENT.md +6 -1
- package/plugins/specweave-kafka/agents/kafka-observability/AGENT.md +6 -1
- package/plugins/specweave-kubernetes/agents/kubernetes-architect/AGENT.md +3 -3
- package/plugins/specweave-ml/agents/data-scientist/AGENT.md +2 -1
- package/plugins/specweave-ml/agents/ml-engineer/AGENT.md +2 -1
- package/plugins/specweave-ml/agents/mlops-engineer/AGENT.md +3 -3
- package/plugins/specweave-mobile/agents/mobile-architect/AGENT.md +6 -1
- package/plugins/specweave-payments/agents/payment-integration/AGENT.md +3 -3
- package/plugins/specweave-release/agents/release-manager/AGENT.md +6 -1
- package/plugins/specweave-release/commands/specweave-release-npm.md +8 -0
- package/plugins/specweave-release/hooks/.specweave/logs/dora-tracking.log +135 -0
- package/plugins/specweave-testing/agents/qa-engineer/AGENT.md +5 -0
- package/src/templates/AGENTS.md.template +97 -0
- package/dist/src/core/cost-tracker.d.ts.map +0 -1
- package/dist/src/core/cost-tracker.js.map +0 -1
- package/dist/src/core/credentials-manager.d.ts.map +0 -1
- package/dist/src/core/credentials-manager.js.map +0 -1
- package/dist/src/core/increment-status.d.ts.map +0 -1
- package/dist/src/core/increment-status.js.map +0 -1
- package/dist/src/core/increment-utils.d.ts.map +0 -1
- package/dist/src/core/increment-utils.js.map +0 -1
- package/dist/src/core/plugin-loader.d.ts.map +0 -1
- package/dist/src/core/plugin-loader.js.map +0 -1
- package/dist/src/core/project-manager.d.ts.map +0 -1
- package/dist/src/core/project-manager.js.map +0 -1
- package/dist/src/core/project-structure-detector.d.ts.map +0 -1
- package/dist/src/core/project-structure-detector.js.map +0 -1
- package/dist/src/core/rfc-generator-v2.d.ts.map +0 -1
- package/dist/src/core/rfc-generator-v2.js.map +0 -1
- package/dist/src/core/spec-content-sync.d.ts.map +0 -1
- package/dist/src/core/spec-content-sync.js.map +0 -1
- package/dist/src/core/spec-detector.d.ts.map +0 -1
- package/dist/src/core/spec-detector.js.map +0 -1
- package/dist/src/core/spec-identifier-detector.d.ts.map +0 -1
- package/dist/src/core/spec-identifier-detector.js.map +0 -1
- package/dist/src/core/spec-task-mapper.d.ts.map +0 -1
- package/dist/src/core/spec-task-mapper.js.map +0 -1
- package/dist/src/utils/spec-parser.d.ts +0 -145
- package/dist/src/utils/spec-parser.d.ts.map +0 -1
- package/dist/src/utils/spec-parser.js +0 -640
- package/dist/src/utils/spec-parser.js.map +0 -1
- package/plugins/specweave/agents/pm/AGENT.md.bak2 +0 -1754
- package/plugins/specweave/hooks/hooks.json.bak +0 -72
- package/plugins/specweave/hooks/hooks.json.v1-backup +0 -16
- package/plugins/specweave/hooks/v2/hooks.json +0 -16
- /package/dist/src/core/{credentials-manager.d.ts → credentials/credentials-manager.d.ts} +0 -0
- /package/dist/src/core/{credentials-manager.js → credentials/credentials-manager.js} +0 -0
- /package/dist/src/core/{increment-status.d.ts → increment/increment-status.d.ts} +0 -0
- /package/dist/src/core/{increment-utils.d.ts → increment/increment-utils.d.ts} +0 -0
- /package/dist/src/core/{increment-utils.js → increment/increment-utils.js} +0 -0
- /package/dist/src/core/{project-structure-detector.d.ts → project/project-structure-detector.d.ts} +0 -0
- /package/dist/src/core/{project-structure-detector.js → project/project-structure-detector.js} +0 -0
- /package/dist/src/core/{spec-task-mapper.d.ts → specs/spec-task-mapper.d.ts} +0 -0
- /package/dist/src/core/{spec-task-mapper.js → specs/spec-task-mapper.js} +0 -0
|
@@ -1,640 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SpecWeave Spec Parser Utilities
|
|
3
|
-
*
|
|
4
|
-
* Parses increment and living docs specifications to extract structured data.
|
|
5
|
-
*
|
|
6
|
-
* Key responsibilities:
|
|
7
|
-
* - Extract user stories from markdown
|
|
8
|
-
* - Parse increment specs (temporary, implementation-focused)
|
|
9
|
-
* - Parse living docs specs (permanent, epic-level)
|
|
10
|
-
* - Generate links to related documentation (avoid duplication)
|
|
11
|
-
* - Merge user stories intelligently
|
|
12
|
-
*
|
|
13
|
-
* @author SpecWeave Team
|
|
14
|
-
* @version 2.0.0
|
|
15
|
-
*/
|
|
16
|
-
import * as fs from '../utils/fs-native.js';
|
|
17
|
-
import path from 'path';
|
|
18
|
-
// ============================================================================
|
|
19
|
-
// PARSING FUNCTIONS
|
|
20
|
-
// ============================================================================
|
|
21
|
-
/**
|
|
22
|
-
* Parse increment spec.md into structured data
|
|
23
|
-
*
|
|
24
|
-
* Extracts user stories, acceptance criteria, and metadata.
|
|
25
|
-
* Discards architecture details (those belong in architecture/ folder).
|
|
26
|
-
*/
|
|
27
|
-
export async function parseIncrementSpec(filePath) {
|
|
28
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
29
|
-
// Extract metadata from frontmatter
|
|
30
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
31
|
-
let metadata = {};
|
|
32
|
-
if (frontmatterMatch) {
|
|
33
|
-
const frontmatter = frontmatterMatch[1];
|
|
34
|
-
const lines = frontmatter.split('\n');
|
|
35
|
-
for (const line of lines) {
|
|
36
|
-
const [key, ...valueParts] = line.split(':');
|
|
37
|
-
if (key && valueParts.length > 0) {
|
|
38
|
-
const value = valueParts.join(':').trim().replace(/^["']|["']$/g, '');
|
|
39
|
-
metadata[key.trim()] = value;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
// Extract title (from frontmatter or first heading)
|
|
44
|
-
let title = metadata.title || '';
|
|
45
|
-
if (!title) {
|
|
46
|
-
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
47
|
-
if (titleMatch) {
|
|
48
|
-
title = titleMatch[1];
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
// Extract overview (first paragraph after title)
|
|
52
|
-
const overviewMatch = content.match(/##\s+Overview\s*\n+([\s\S]*?)(?=\n##|\n---|\Z)/i);
|
|
53
|
-
const overview = overviewMatch ? overviewMatch[1].trim() : '';
|
|
54
|
-
// Extract user stories
|
|
55
|
-
const userStories = extractUserStories(content);
|
|
56
|
-
// Extract "Implements" reference
|
|
57
|
-
const implementsMatch = content.match(/\*\*Implements\*\*:\s*(?:\[)?SPEC-(\d+)/i);
|
|
58
|
-
const implementsSpec = implementsMatch ? `SPEC-${implementsMatch[1]}` : undefined;
|
|
59
|
-
// Extract out of scope
|
|
60
|
-
const outOfScopeMatch = content.match(/##\s+Out of Scope[\s\S]*?\n([\s\S]*?)(?=\n##|\Z)/i);
|
|
61
|
-
const outOfScope = [];
|
|
62
|
-
if (outOfScopeMatch) {
|
|
63
|
-
const outOfScopeText = outOfScopeMatch[1];
|
|
64
|
-
const storyMatches = outOfScopeText.matchAll(/US-(\d+)/g);
|
|
65
|
-
for (const match of storyMatches) {
|
|
66
|
-
outOfScope.push(`US-${match[1]}`);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
return {
|
|
70
|
-
id: metadata.increment || path.basename(path.dirname(filePath)),
|
|
71
|
-
title: title.replace(/^Increment \d+:\s*/, ''),
|
|
72
|
-
overview,
|
|
73
|
-
implementsSpec,
|
|
74
|
-
userStories,
|
|
75
|
-
outOfScope,
|
|
76
|
-
priority: metadata.priority,
|
|
77
|
-
status: metadata.status,
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* Parse living docs spec.md into structured data
|
|
82
|
-
*/
|
|
83
|
-
export async function parseLivingDocsSpec(filePath) {
|
|
84
|
-
const content = await fs.readFile(filePath, 'utf-8');
|
|
85
|
-
// Extract metadata from frontmatter
|
|
86
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
87
|
-
let metadata = {};
|
|
88
|
-
if (frontmatterMatch) {
|
|
89
|
-
const frontmatter = frontmatterMatch[1];
|
|
90
|
-
const lines = frontmatter.split('\n');
|
|
91
|
-
for (const line of lines) {
|
|
92
|
-
const [key, ...valueParts] = line.split(':');
|
|
93
|
-
if (key && valueParts.length > 0) {
|
|
94
|
-
const value = valueParts.join(':').trim().replace(/^["']|["']$/g, '');
|
|
95
|
-
metadata[key.trim()] = value;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
// Extract title
|
|
100
|
-
let title = metadata.title || '';
|
|
101
|
-
if (!title) {
|
|
102
|
-
const titleMatch = content.match(/^#\s+SPEC-\d+:\s*(.+)$/m);
|
|
103
|
-
if (titleMatch) {
|
|
104
|
-
title = titleMatch[1];
|
|
105
|
-
}
|
|
106
|
-
}
|
|
107
|
-
// Extract spec ID
|
|
108
|
-
const specIdMatch = content.match(/^#\s+(SPEC-\d+)/m) || content.match(/id:\s*(SPEC-\d+)/i);
|
|
109
|
-
const id = specIdMatch ? specIdMatch[1] : metadata.id || '';
|
|
110
|
-
// Extract feature area
|
|
111
|
-
const featureAreaMatch = content.match(/\*\*Feature Area\*\*:\s*(.+)/);
|
|
112
|
-
const featureArea = featureAreaMatch ? featureAreaMatch[1].trim() : '';
|
|
113
|
-
// Extract overview
|
|
114
|
-
const overviewMatch = content.match(/##\s+Overview\s*\n+([\s\S]*?)(?=\n##|\n---|\Z)/i);
|
|
115
|
-
const overview = overviewMatch ? overviewMatch[1].trim() : '';
|
|
116
|
-
// Extract user stories
|
|
117
|
-
const userStories = extractUserStories(content);
|
|
118
|
-
// Extract implementation history
|
|
119
|
-
const implementationHistory = extractImplementationHistory(content);
|
|
120
|
-
// Extract related docs (links only)
|
|
121
|
-
const relatedDocs = extractRelatedDocs(content);
|
|
122
|
-
// Extract external links
|
|
123
|
-
const externalLinks = extractExternalLinks(content);
|
|
124
|
-
return {
|
|
125
|
-
id,
|
|
126
|
-
title,
|
|
127
|
-
featureArea,
|
|
128
|
-
overview,
|
|
129
|
-
userStories,
|
|
130
|
-
implementationHistory,
|
|
131
|
-
relatedDocs,
|
|
132
|
-
externalLinks,
|
|
133
|
-
priority: metadata.priority,
|
|
134
|
-
status: metadata.status,
|
|
135
|
-
created: metadata.created,
|
|
136
|
-
lastUpdated: metadata.last_updated || new Date().toISOString().split('T')[0],
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
/**
|
|
140
|
-
* Extract user stories from markdown content
|
|
141
|
-
*
|
|
142
|
-
* Supports formats:
|
|
143
|
-
* - **US-001**: Description
|
|
144
|
-
* - ### US-001: Title
|
|
145
|
-
* - **US1**: Description (legacy)
|
|
146
|
-
*/
|
|
147
|
-
export function extractUserStories(markdown) {
|
|
148
|
-
const stories = [];
|
|
149
|
-
// Find all user story sections
|
|
150
|
-
// Pattern 1: ### US-001: Title (most common in living docs)
|
|
151
|
-
// Pattern 2: **US-001**: Description (common in increment specs)
|
|
152
|
-
const storyPattern = /(?:###\s+US-(\d+):\s*(.+)|\\*\\*US-(\d+)\\*\\*:\s*As a\s+(.+?)(?=\n\n|\n\\*\\*|\\Z))/gs;
|
|
153
|
-
let match;
|
|
154
|
-
while ((match = storyPattern.exec(markdown)) !== null) {
|
|
155
|
-
const storyId = match[1] || match[3];
|
|
156
|
-
const storyTitle = match[2] || '';
|
|
157
|
-
const storyDescription = match[4] || '';
|
|
158
|
-
if (!storyId)
|
|
159
|
-
continue;
|
|
160
|
-
const id = `US-${storyId.padStart(3, '0')}`;
|
|
161
|
-
// Find the full story content
|
|
162
|
-
const storyStartIndex = match.index;
|
|
163
|
-
const nextStoryMatch = markdown.slice(storyStartIndex + match[0].length).match(/(?:###\s+US-\d+|\\*\\*US-\d+\\*\\*)/);
|
|
164
|
-
const storyEndIndex = nextStoryMatch
|
|
165
|
-
? storyStartIndex + match[0].length + nextStoryMatch.index
|
|
166
|
-
: markdown.length;
|
|
167
|
-
const storyContent = markdown.slice(storyStartIndex, storyEndIndex);
|
|
168
|
-
// Extract acceptance criteria
|
|
169
|
-
const acceptanceCriteria = extractAcceptanceCriteria(storyContent, id);
|
|
170
|
-
// Extract epic (if present)
|
|
171
|
-
const epicMatch = markdown.slice(0, storyStartIndex).match(/###\s+(Epic\s+\d+:[^\n]+)/g);
|
|
172
|
-
const epic = epicMatch ? epicMatch[epicMatch.length - 1].replace(/^###\s+/, '') : undefined;
|
|
173
|
-
// Extract priority
|
|
174
|
-
const priorityMatch = storyContent.match(/Priority:\s*(P[0-3])/i);
|
|
175
|
-
const priority = priorityMatch ? priorityMatch[1] : undefined;
|
|
176
|
-
// Determine status (check if all ACs are completed)
|
|
177
|
-
const allCompleted = acceptanceCriteria.length > 0 && acceptanceCriteria.every(ac => ac.completed);
|
|
178
|
-
const anyInProgress = acceptanceCriteria.some(ac => !ac.completed);
|
|
179
|
-
const status = allCompleted ? 'complete' : anyInProgress ? 'in-progress' : 'pending';
|
|
180
|
-
// Extract implementation reference
|
|
181
|
-
const implementedInMatch = storyContent.match(/\\*\\*Implementation\\*\\*:\s*Increment\s+(\d{4}-[a-z0-9-]+)/i);
|
|
182
|
-
const implementedIn = implementedInMatch ? implementedInMatch[1] : undefined;
|
|
183
|
-
stories.push({
|
|
184
|
-
id,
|
|
185
|
-
title: storyTitle.trim() || storyDescription.split('\n')[0].trim(),
|
|
186
|
-
description: storyContent.trim(),
|
|
187
|
-
acceptanceCriteria,
|
|
188
|
-
epic,
|
|
189
|
-
priority,
|
|
190
|
-
status,
|
|
191
|
-
implementedIn,
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
return stories;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Extract acceptance criteria from user story content
|
|
198
|
-
*/
|
|
199
|
-
function extractAcceptanceCriteria(storyContent, storyId) {
|
|
200
|
-
const criteria = [];
|
|
201
|
-
// Pattern: - [ ] **AC-US1-01**: Description (P1, Testable: Yes)
|
|
202
|
-
// Pattern: - [x] **AC-US1-01**: Description
|
|
203
|
-
const acPattern = /- \[([ xX])\]\s+\*\*AC-([^:]+)\*\*:\s*(.+?)(?:\((.+?)\))?$/gm;
|
|
204
|
-
let match;
|
|
205
|
-
while ((match = acPattern.exec(storyContent)) !== null) {
|
|
206
|
-
const completed = match[1].toLowerCase() === 'x';
|
|
207
|
-
const acId = `AC-${match[2]}`;
|
|
208
|
-
const description = match[3].trim();
|
|
209
|
-
const metadata = match[4] || '';
|
|
210
|
-
// Extract priority and testable flag from metadata
|
|
211
|
-
const priorityMatch = metadata.match(/P[0-3]/);
|
|
212
|
-
const priority = priorityMatch ? priorityMatch[0] : undefined;
|
|
213
|
-
const testableMatch = metadata.match(/Testable:\s*(Yes|No)/i);
|
|
214
|
-
const testable = testableMatch ? testableMatch[1].toLowerCase() === 'yes' : true;
|
|
215
|
-
criteria.push({
|
|
216
|
-
id: acId,
|
|
217
|
-
description,
|
|
218
|
-
priority,
|
|
219
|
-
testable,
|
|
220
|
-
completed,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
return criteria;
|
|
224
|
-
}
|
|
225
|
-
/**
|
|
226
|
-
* Extract implementation history from living docs
|
|
227
|
-
*/
|
|
228
|
-
function extractImplementationHistory(markdown) {
|
|
229
|
-
const history = [];
|
|
230
|
-
// Find implementation history table
|
|
231
|
-
const tableMatch = markdown.match(/##\s+(?:Increments|Implementation History)[\s\S]*?\n\|[\s\S]*?\n([\s\S]*?)(?=\n##|\Z)/i);
|
|
232
|
-
if (!tableMatch)
|
|
233
|
-
return history;
|
|
234
|
-
const tableContent = tableMatch[1];
|
|
235
|
-
// Parse table rows
|
|
236
|
-
const rows = tableContent.split('\n').filter(line => line.trim().startsWith('|'));
|
|
237
|
-
for (const row of rows) {
|
|
238
|
-
if (row.includes('Increment') || row.includes('---'))
|
|
239
|
-
continue; // Skip header
|
|
240
|
-
const cells = row.split('|').map(c => c.trim()).filter(c => c);
|
|
241
|
-
if (cells.length < 2)
|
|
242
|
-
continue;
|
|
243
|
-
const incrementMatch = cells[0].match(/(\d{4}-[a-z0-9-]+)/);
|
|
244
|
-
if (!incrementMatch)
|
|
245
|
-
continue;
|
|
246
|
-
const increment = incrementMatch[1];
|
|
247
|
-
// Extract stories from second column
|
|
248
|
-
const storiesText = cells[1] || '';
|
|
249
|
-
const storyMatches = Array.from(storiesText.matchAll(/US-(\d+)/g));
|
|
250
|
-
const stories = storyMatches.map(m => `US-${m[1]}`);
|
|
251
|
-
// Extract status
|
|
252
|
-
const statusMatch = cells[2]?.match(/(Complete|In Progress|Planned)/i);
|
|
253
|
-
const status = statusMatch
|
|
254
|
-
? statusMatch[1].toLowerCase().replace(' ', '-')
|
|
255
|
-
: 'planned';
|
|
256
|
-
// Extract date
|
|
257
|
-
const dateMatch = cells[3]?.match(/\d{4}-\d{2}-\d{2}/);
|
|
258
|
-
const date = dateMatch ? dateMatch[0] : undefined;
|
|
259
|
-
history.push({
|
|
260
|
-
increment,
|
|
261
|
-
stories,
|
|
262
|
-
status,
|
|
263
|
-
date,
|
|
264
|
-
});
|
|
265
|
-
}
|
|
266
|
-
return history;
|
|
267
|
-
}
|
|
268
|
-
/**
|
|
269
|
-
* Extract related documentation links
|
|
270
|
-
*/
|
|
271
|
-
function extractRelatedDocs(markdown) {
|
|
272
|
-
const relatedDocs = {
|
|
273
|
-
architecture: [],
|
|
274
|
-
adrs: [],
|
|
275
|
-
strategy: [],
|
|
276
|
-
operations: [],
|
|
277
|
-
delivery: [],
|
|
278
|
-
};
|
|
279
|
-
// Find related documentation section
|
|
280
|
-
const relatedMatch = markdown.match(/##\s+(?:Architecture & Design|Related Documentation)[\s\S]*?\n([\s\S]*?)(?=\n##|\Z)/i);
|
|
281
|
-
if (!relatedMatch)
|
|
282
|
-
return relatedDocs;
|
|
283
|
-
const content = relatedMatch[1];
|
|
284
|
-
// Extract links
|
|
285
|
-
const linkPattern = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
286
|
-
let match;
|
|
287
|
-
while ((match = linkPattern.exec(content)) !== null) {
|
|
288
|
-
const linkText = match[1];
|
|
289
|
-
const linkPath = match[2];
|
|
290
|
-
if (linkPath.includes('/architecture/') && !linkPath.includes('/adr/')) {
|
|
291
|
-
relatedDocs.architecture.push(linkPath);
|
|
292
|
-
}
|
|
293
|
-
else if (linkPath.includes('/adr/')) {
|
|
294
|
-
relatedDocs.adrs.push(linkPath);
|
|
295
|
-
}
|
|
296
|
-
else if (linkPath.includes('/strategy/')) {
|
|
297
|
-
relatedDocs.strategy.push(linkPath);
|
|
298
|
-
}
|
|
299
|
-
else if (linkPath.includes('/operations/')) {
|
|
300
|
-
relatedDocs.operations.push(linkPath);
|
|
301
|
-
}
|
|
302
|
-
else if (linkPath.includes('/delivery/')) {
|
|
303
|
-
relatedDocs.delivery.push(linkPath);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
return relatedDocs;
|
|
307
|
-
}
|
|
308
|
-
/**
|
|
309
|
-
* Extract external tool links
|
|
310
|
-
*/
|
|
311
|
-
function extractExternalLinks(markdown) {
|
|
312
|
-
const externalLinks = {};
|
|
313
|
-
// Find external tools section
|
|
314
|
-
const externalMatch = markdown.match(/##\s+External Tool Links[\s\S]*?\n([\s\S]*?)(?=\n##|\Z)/i);
|
|
315
|
-
if (!externalMatch)
|
|
316
|
-
return externalLinks;
|
|
317
|
-
const content = externalMatch[1];
|
|
318
|
-
// Extract GitHub link
|
|
319
|
-
const githubMatch = content.match(/\*\*GitHub\*\*:\s*\[([^\]]+)\]\(([^)]+)\)/);
|
|
320
|
-
if (githubMatch) {
|
|
321
|
-
externalLinks.github = githubMatch[2];
|
|
322
|
-
}
|
|
323
|
-
// Extract Jira link
|
|
324
|
-
const jiraMatch = content.match(/\*\*Jira\*\*:\s*\[([^\]]+)\]\(([^)]+)\)/);
|
|
325
|
-
if (jiraMatch) {
|
|
326
|
-
externalLinks.jira = jiraMatch[2];
|
|
327
|
-
}
|
|
328
|
-
// Extract Azure DevOps link
|
|
329
|
-
const adoMatch = content.match(/\*\*Azure DevOps\*\*:\s*\[([^\]]+)\]\(([^)]+)\)/);
|
|
330
|
-
if (adoMatch) {
|
|
331
|
-
externalLinks.ado = adoMatch[2];
|
|
332
|
-
}
|
|
333
|
-
return externalLinks;
|
|
334
|
-
}
|
|
335
|
-
// ============================================================================
|
|
336
|
-
// LINK GENERATION
|
|
337
|
-
// ============================================================================
|
|
338
|
-
/**
|
|
339
|
-
* Generate links to related documentation (avoid duplication)
|
|
340
|
-
*
|
|
341
|
-
* Analyzes increment spec to find architecture references and generates
|
|
342
|
-
* proper links instead of duplicating content.
|
|
343
|
-
*/
|
|
344
|
-
export function generateRelatedDocsLinks(spec, projectRoot = process.cwd()) {
|
|
345
|
-
const relatedDocs = {
|
|
346
|
-
architecture: [],
|
|
347
|
-
adrs: [],
|
|
348
|
-
strategy: [],
|
|
349
|
-
operations: [],
|
|
350
|
-
delivery: [],
|
|
351
|
-
};
|
|
352
|
-
// Check for architecture folder
|
|
353
|
-
const architectureDir = path.join(projectRoot, '.specweave', 'docs', 'internal', 'architecture');
|
|
354
|
-
if (fs.existsSync(architectureDir)) {
|
|
355
|
-
// Find HLD files
|
|
356
|
-
const hldPattern = `hld-*.md`;
|
|
357
|
-
const hldFiles = fs.readdirSync(architectureDir).filter(f => f.startsWith('hld-') && f.endsWith('.md'));
|
|
358
|
-
for (const file of hldFiles) {
|
|
359
|
-
relatedDocs.architecture.push(`../../architecture/${file}`);
|
|
360
|
-
}
|
|
361
|
-
// Find ADR files
|
|
362
|
-
const adrDir = path.join(architectureDir, 'adr');
|
|
363
|
-
if (fs.existsSync(adrDir)) {
|
|
364
|
-
const adrFiles = fs.readdirSync(adrDir).filter(f => f.endsWith('.md'));
|
|
365
|
-
for (const file of adrFiles) {
|
|
366
|
-
relatedDocs.adrs.push(`../../architecture/adr/${file}`);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
// Check for strategy folder
|
|
371
|
-
const strategyDir = path.join(projectRoot, '.specweave', 'docs', 'internal', 'strategy');
|
|
372
|
-
if (fs.existsSync(strategyDir)) {
|
|
373
|
-
const strategyFiles = fs.readdirSync(strategyDir).filter(f => f.endsWith('.md'));
|
|
374
|
-
for (const file of strategyFiles) {
|
|
375
|
-
relatedDocs.strategy.push(`../../strategy/${file}`);
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
// Check for operations folder
|
|
379
|
-
const operationsDir = path.join(projectRoot, '.specweave', 'docs', 'internal', 'operations');
|
|
380
|
-
if (fs.existsSync(operationsDir)) {
|
|
381
|
-
const operationsFiles = fs.readdirSync(operationsDir).filter(f => f.endsWith('.md'));
|
|
382
|
-
for (const file of operationsFiles) {
|
|
383
|
-
relatedDocs.operations.push(`../../operations/${file}`);
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
// Check for delivery folder
|
|
387
|
-
const deliveryDir = path.join(projectRoot, '.specweave', 'docs', 'internal', 'delivery');
|
|
388
|
-
if (fs.existsSync(deliveryDir)) {
|
|
389
|
-
const deliveryFiles = fs.readdirSync(deliveryDir).filter(f => f.endsWith('.md'));
|
|
390
|
-
for (const file of deliveryFiles) {
|
|
391
|
-
relatedDocs.delivery.push(`../../delivery/${file}`);
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
return relatedDocs;
|
|
395
|
-
}
|
|
396
|
-
// ============================================================================
|
|
397
|
-
// UTILITY FUNCTIONS
|
|
398
|
-
// ============================================================================
|
|
399
|
-
/**
|
|
400
|
-
* Extract spec ID from increment ID
|
|
401
|
-
*
|
|
402
|
-
* Examples:
|
|
403
|
-
* - 0001-core-framework → SPEC-001
|
|
404
|
-
* - 0002-core-enhancements → SPEC-002 (if part of same spec)
|
|
405
|
-
* - 0005-cross-platform-cli → SPEC-001 (if part of core spec)
|
|
406
|
-
*/
|
|
407
|
-
export function extractSpecId(incrementId) {
|
|
408
|
-
// Extract numeric prefix
|
|
409
|
-
const numMatch = incrementId.match(/^(\d+)/);
|
|
410
|
-
const num = numMatch ? parseInt(numMatch[1], 10) : 1;
|
|
411
|
-
// For now, use same numbering (can be customized later)
|
|
412
|
-
return `SPEC-${num.toString().padStart(3, '0')}`;
|
|
413
|
-
}
|
|
414
|
-
/**
|
|
415
|
-
* Merge user stories from increment into living docs
|
|
416
|
-
*
|
|
417
|
-
* Adds new stories, updates existing stories with completion status.
|
|
418
|
-
*/
|
|
419
|
-
export function mergeUserStories(existingStories, newStories, incrementId) {
|
|
420
|
-
const merged = [...existingStories];
|
|
421
|
-
for (const newStory of newStories) {
|
|
422
|
-
const existingIndex = merged.findIndex(s => s.id === newStory.id);
|
|
423
|
-
if (existingIndex >= 0) {
|
|
424
|
-
// Update existing story
|
|
425
|
-
merged[existingIndex] = {
|
|
426
|
-
...merged[existingIndex],
|
|
427
|
-
...newStory,
|
|
428
|
-
implementedIn: incrementId,
|
|
429
|
-
status: newStory.status,
|
|
430
|
-
};
|
|
431
|
-
}
|
|
432
|
-
else {
|
|
433
|
-
// Add new story
|
|
434
|
-
merged.push({
|
|
435
|
-
...newStory,
|
|
436
|
-
implementedIn: incrementId,
|
|
437
|
-
});
|
|
438
|
-
}
|
|
439
|
-
}
|
|
440
|
-
// Sort by ID
|
|
441
|
-
merged.sort((a, b) => a.id.localeCompare(b.id));
|
|
442
|
-
return merged;
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Write living docs spec to file
|
|
446
|
-
*/
|
|
447
|
-
export async function writeLivingDocsSpec(filePath, spec) {
|
|
448
|
-
const content = formatLivingDocsSpec(spec);
|
|
449
|
-
await fs.ensureDir(path.dirname(filePath));
|
|
450
|
-
await fs.writeFile(filePath, content, 'utf-8');
|
|
451
|
-
}
|
|
452
|
-
/**
|
|
453
|
-
* Format living docs spec as markdown
|
|
454
|
-
*/
|
|
455
|
-
function formatLivingDocsSpec(spec) {
|
|
456
|
-
const lines = [];
|
|
457
|
-
// Frontmatter
|
|
458
|
-
lines.push('---');
|
|
459
|
-
lines.push(`id: ${spec.id}`);
|
|
460
|
-
lines.push(`title: "${spec.title}"`);
|
|
461
|
-
if (spec.status)
|
|
462
|
-
lines.push(`status: ${spec.status}`);
|
|
463
|
-
if (spec.priority)
|
|
464
|
-
lines.push(`priority: ${spec.priority}`);
|
|
465
|
-
if (spec.created)
|
|
466
|
-
lines.push(`created: ${spec.created}`);
|
|
467
|
-
lines.push(`last_updated: ${spec.lastUpdated || new Date().toISOString().split('T')[0]}`);
|
|
468
|
-
lines.push('---');
|
|
469
|
-
lines.push('');
|
|
470
|
-
// Title
|
|
471
|
-
lines.push(`# ${spec.id}: ${spec.title}`);
|
|
472
|
-
lines.push('');
|
|
473
|
-
lines.push(`**Feature Area**: ${spec.featureArea}`);
|
|
474
|
-
if (spec.status)
|
|
475
|
-
lines.push(`**Status**: ${spec.status}`);
|
|
476
|
-
if (spec.priority)
|
|
477
|
-
lines.push(`**Priority**: ${spec.priority}`);
|
|
478
|
-
lines.push('');
|
|
479
|
-
lines.push('---');
|
|
480
|
-
lines.push('');
|
|
481
|
-
// Overview
|
|
482
|
-
lines.push('## Overview');
|
|
483
|
-
lines.push('');
|
|
484
|
-
lines.push(spec.overview);
|
|
485
|
-
lines.push('');
|
|
486
|
-
lines.push('---');
|
|
487
|
-
lines.push('');
|
|
488
|
-
// Implementation History
|
|
489
|
-
if (spec.implementationHistory.length > 0) {
|
|
490
|
-
lines.push('## Implementation History');
|
|
491
|
-
lines.push('');
|
|
492
|
-
lines.push('| Increment | Stories Implemented | Status | Completion Date |');
|
|
493
|
-
lines.push('|-----------|-------------------|--------|----------------|');
|
|
494
|
-
for (const entry of spec.implementationHistory) {
|
|
495
|
-
const statusEmoji = entry.status === 'complete' ? '✅' : entry.status === 'in-progress' ? '⏳' : '📋';
|
|
496
|
-
// Link to increment tasks.md instead of just folder
|
|
497
|
-
const incrementLink = `[${entry.increment}](../../../../increments/${entry.increment}/tasks.md)`;
|
|
498
|
-
// Generate story summary instead of listing all IDs
|
|
499
|
-
const storyCount = entry.stories.length;
|
|
500
|
-
const firstStory = entry.stories[0];
|
|
501
|
-
const lastStory = entry.stories[entry.stories.length - 1];
|
|
502
|
-
const storiesText = storyCount === 1
|
|
503
|
-
? firstStory
|
|
504
|
-
: storyCount === entry.stories.length
|
|
505
|
-
? `${firstStory} through ${lastStory} (all)`
|
|
506
|
-
: entry.stories.join(', ');
|
|
507
|
-
const dateText = entry.date || '-';
|
|
508
|
-
lines.push(`| ${incrementLink} | ${storiesText} | ${statusEmoji} ${entry.status.charAt(0).toUpperCase() + entry.status.slice(1)} | ${dateText} |`);
|
|
509
|
-
}
|
|
510
|
-
const totalStories = spec.userStories.length;
|
|
511
|
-
const completeStories = spec.userStories.filter(s => s.status === 'complete').length;
|
|
512
|
-
const percentage = totalStories > 0 ? Math.round((completeStories / totalStories) * 100) : 0;
|
|
513
|
-
lines.push('');
|
|
514
|
-
lines.push(`**Overall Progress**: ${completeStories}/${totalStories} user stories complete (${percentage}%)`);
|
|
515
|
-
lines.push('');
|
|
516
|
-
lines.push('---');
|
|
517
|
-
lines.push('');
|
|
518
|
-
}
|
|
519
|
-
// User Stories & Acceptance Criteria
|
|
520
|
-
lines.push('## User Stories & Acceptance Criteria');
|
|
521
|
-
lines.push('');
|
|
522
|
-
// Group by epic
|
|
523
|
-
const epicGroups = new Map();
|
|
524
|
-
for (const story of spec.userStories) {
|
|
525
|
-
const epicName = story.epic || 'General';
|
|
526
|
-
if (!epicGroups.has(epicName)) {
|
|
527
|
-
epicGroups.set(epicName, []);
|
|
528
|
-
}
|
|
529
|
-
epicGroups.get(epicName).push(story);
|
|
530
|
-
}
|
|
531
|
-
for (const [epicName, stories] of epicGroups) {
|
|
532
|
-
if (epicName !== 'General') {
|
|
533
|
-
lines.push(`### ${epicName}`);
|
|
534
|
-
lines.push('');
|
|
535
|
-
}
|
|
536
|
-
for (const story of stories) {
|
|
537
|
-
const statusEmoji = story.status === 'complete' ? '✅' : story.status === 'in-progress' ? '⏳' : '📋';
|
|
538
|
-
lines.push(`**${story.id}**: ${story.title} ${statusEmoji}`);
|
|
539
|
-
lines.push('');
|
|
540
|
-
if (story.acceptanceCriteria.length > 0) {
|
|
541
|
-
lines.push('**Acceptance Criteria**:');
|
|
542
|
-
for (const ac of story.acceptanceCriteria) {
|
|
543
|
-
const checkbox = ac.completed ? '[x]' : '[ ]';
|
|
544
|
-
const priorityText = ac.priority ? ` (${ac.priority})` : '';
|
|
545
|
-
lines.push(`- ${checkbox} **${ac.id}**: ${ac.description}${priorityText}`);
|
|
546
|
-
}
|
|
547
|
-
lines.push('');
|
|
548
|
-
}
|
|
549
|
-
if (story.implementedIn) {
|
|
550
|
-
lines.push(`**Implementation**: Increment ${story.implementedIn}`);
|
|
551
|
-
lines.push('');
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
lines.push('---');
|
|
556
|
-
lines.push('');
|
|
557
|
-
// Architecture & Design (LINKS ONLY)
|
|
558
|
-
lines.push('## Architecture & Design');
|
|
559
|
-
lines.push('');
|
|
560
|
-
if (spec.relatedDocs.architecture.length > 0) {
|
|
561
|
-
lines.push('**High-Level Design**:');
|
|
562
|
-
for (const link of spec.relatedDocs.architecture) {
|
|
563
|
-
const fileName = path.basename(link, '.md');
|
|
564
|
-
const title = fileName.replace(/^hld-/, '').replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
565
|
-
lines.push(`- [${title}](${link})`);
|
|
566
|
-
}
|
|
567
|
-
lines.push('');
|
|
568
|
-
}
|
|
569
|
-
if (spec.relatedDocs.adrs.length > 0) {
|
|
570
|
-
lines.push('**Architecture Decisions**:');
|
|
571
|
-
for (const link of spec.relatedDocs.adrs) {
|
|
572
|
-
const fileName = path.basename(link, '.md');
|
|
573
|
-
// Extract ADR title from filename (e.g., "0001-plugin-system" -> "ADR-001: Plugin System")
|
|
574
|
-
const numMatch = fileName.match(/^(\d+)/);
|
|
575
|
-
const num = numMatch ? numMatch[1] : '001';
|
|
576
|
-
const title = fileName.replace(/^\d+-/, '').replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
577
|
-
lines.push(`- [ADR-${num}: ${title}](${link})`);
|
|
578
|
-
}
|
|
579
|
-
lines.push('');
|
|
580
|
-
}
|
|
581
|
-
lines.push('---');
|
|
582
|
-
lines.push('');
|
|
583
|
-
// External Tool Links
|
|
584
|
-
if (spec.externalLinks.github || spec.externalLinks.jira || spec.externalLinks.ado) {
|
|
585
|
-
lines.push('## External Tool Links');
|
|
586
|
-
lines.push('');
|
|
587
|
-
if (spec.externalLinks.github) {
|
|
588
|
-
lines.push(`**GitHub**: [Project Board](${spec.externalLinks.github})`);
|
|
589
|
-
}
|
|
590
|
-
if (spec.externalLinks.jira) {
|
|
591
|
-
lines.push(`**Jira**: [Epic](${spec.externalLinks.jira})`);
|
|
592
|
-
}
|
|
593
|
-
if (spec.externalLinks.ado) {
|
|
594
|
-
lines.push(`**Azure DevOps**: [Feature](${spec.externalLinks.ado})`);
|
|
595
|
-
}
|
|
596
|
-
lines.push('');
|
|
597
|
-
lines.push('---');
|
|
598
|
-
lines.push('');
|
|
599
|
-
}
|
|
600
|
-
// Related Documentation (other folders)
|
|
601
|
-
if (spec.relatedDocs.strategy.length > 0 || spec.relatedDocs.operations.length > 0 || spec.relatedDocs.delivery.length > 0) {
|
|
602
|
-
lines.push('## Related Documentation');
|
|
603
|
-
lines.push('');
|
|
604
|
-
if (spec.relatedDocs.strategy.length > 0) {
|
|
605
|
-
lines.push('**Strategy**:');
|
|
606
|
-
for (const link of spec.relatedDocs.strategy) {
|
|
607
|
-
const fileName = path.basename(link, '.md');
|
|
608
|
-
const title = fileName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
609
|
-
lines.push(`- [${title}](${link})`);
|
|
610
|
-
}
|
|
611
|
-
lines.push('');
|
|
612
|
-
}
|
|
613
|
-
if (spec.relatedDocs.operations.length > 0) {
|
|
614
|
-
lines.push('**Operations**:');
|
|
615
|
-
for (const link of spec.relatedDocs.operations) {
|
|
616
|
-
const fileName = path.basename(link, '.md');
|
|
617
|
-
const title = fileName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
618
|
-
lines.push(`- [${title}](${link})`);
|
|
619
|
-
}
|
|
620
|
-
lines.push('');
|
|
621
|
-
}
|
|
622
|
-
if (spec.relatedDocs.delivery.length > 0) {
|
|
623
|
-
lines.push('**Delivery**:');
|
|
624
|
-
for (const link of spec.relatedDocs.delivery) {
|
|
625
|
-
const fileName = path.basename(link, '.md');
|
|
626
|
-
const title = fileName.replace(/-/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
|
|
627
|
-
lines.push(`- [${title}](${link})`);
|
|
628
|
-
}
|
|
629
|
-
lines.push('');
|
|
630
|
-
}
|
|
631
|
-
lines.push('---');
|
|
632
|
-
lines.push('');
|
|
633
|
-
}
|
|
634
|
-
// Footer
|
|
635
|
-
lines.push(`**Last Updated**: ${spec.lastUpdated || new Date().toISOString().split('T')[0]}`);
|
|
636
|
-
lines.push(`**Owner**: SpecWeave Core Team`);
|
|
637
|
-
lines.push('');
|
|
638
|
-
return lines.join('\n');
|
|
639
|
-
}
|
|
640
|
-
//# sourceMappingURL=spec-parser.js.map
|