@planu/cli 4.14.1 → 5.1.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/CHANGELOG.md +82 -0
- package/LICENSE +55 -12
- package/README.md +10 -2
- package/dist/cli/commands/install.d.ts +1 -12
- package/dist/cli/commands/install.js +9 -65
- package/dist/cli/commands/job.js +4 -3
- package/dist/cli/commands/spec.js +12 -3
- package/dist/cli/commands/validate.js +2 -2
- package/dist/cli/router.js +1 -3
- package/dist/config/environment-schema.json +1 -3
- package/dist/config/official-sdd-tools.d.ts +4 -0
- package/dist/config/official-sdd-tools.js +35 -0
- package/dist/config/product-public.d.ts +139 -3
- package/dist/config/product-public.js +8 -1
- package/dist/config/product-public.json +7 -36
- package/dist/config/registries/hosts/codex.json +20 -363
- package/dist/config/release-policy.json +84 -2
- package/dist/config/runtime-policy.json +12 -1
- package/dist/config/skill-templates/planu-resume-work.md +2 -2
- package/dist/core/index.d.ts +1 -1
- package/dist/core/spec-validator.d.ts +4 -4
- package/dist/core/spec-validator.js +33 -19
- package/dist/engine/abortable-process-runner.d.ts +20 -2
- package/dist/engine/abortable-process-runner.js +243 -74
- package/dist/engine/ambiguity-scorer.js +4 -26
- package/dist/engine/auth/scope-mapper.js +1 -7
- package/dist/engine/autopilot/state-updater.js +4 -4
- package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
- package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
- package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
- package/dist/engine/ci-generator/planu-config.js +1 -7
- package/dist/engine/clarification-gate/gate.d.ts +3 -3
- package/dist/engine/code-scanner/layer-scanner.js +6 -22
- package/dist/engine/core-bridge.d.ts +3 -3
- package/dist/engine/cost-guardrails.d.ts +1 -1
- package/dist/engine/cost-guardrails.js +1 -1
- package/dist/engine/criterion-identity.d.ts +1 -0
- package/dist/engine/criterion-identity.js +7 -0
- package/dist/engine/dashboard/data-loader.js +2 -7
- package/dist/engine/dashboard/templates-layout.js +0 -3
- package/dist/engine/dashboard/templates-project.js +1 -13
- package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
- package/dist/engine/docs-site-generator/data-collector.js +7 -28
- package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
- package/dist/engine/evidence-gates/artifact-reader.d.ts +12 -1
- package/dist/engine/evidence-gates/artifact-reader.js +174 -4
- package/dist/engine/evidence-gates/evidence-autofill.d.ts +10 -0
- package/dist/engine/evidence-gates/evidence-autofill.js +148 -0
- package/dist/engine/evidence-gates/evidence-skeletons.d.ts +19 -0
- package/dist/engine/evidence-gates/evidence-skeletons.js +69 -0
- package/dist/engine/evidence-gates/lifecycle-gate.js +4 -3
- package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
- package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
- package/dist/engine/evidence-index/done-drift.d.ts +1 -1
- package/dist/engine/evidence-index/done-drift.js +40 -18
- package/dist/engine/execution/context.js +3 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
- package/dist/engine/execution/job-runtime.d.ts +30 -0
- package/dist/engine/execution/job-runtime.js +114 -6
- package/dist/engine/execution/operation-journal.js +10 -4
- package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
- package/dist/engine/execution/public-job-sanitizer.js +31 -0
- package/dist/engine/execution/validate-job-executor.d.ts +12 -1
- package/dist/engine/execution/validate-job-executor.js +549 -86
- package/dist/engine/execution/validate-job-payload.js +107 -50
- package/dist/engine/execution/validate-job-recovery.js +1 -1
- package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
- package/dist/engine/execution/validate-worker-runtime.js +90 -2
- package/dist/engine/execution/validate-worker-thread.js +17 -24
- package/dist/engine/handoff-artifacts/schemas.d.ts +2 -1
- package/dist/engine/handoff-artifacts/schemas.js +33 -0
- package/dist/engine/handoff-packager.d.ts +19 -0
- package/dist/engine/handoff-packager.js +415 -13
- package/dist/engine/hooks/effort-configurator.js +1 -1
- package/dist/engine/impact-detector/test-break-predictor.js +3 -3
- package/dist/engine/impact-detector/tool-registration.js +1 -1
- package/dist/engine/implementation-contract/renderer.js +23 -8
- package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
- package/dist/engine/lifecycle-reconciliation-io.js +180 -0
- package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
- package/dist/engine/lifecycle-reconciliation.js +406 -0
- package/dist/engine/local-first/tool-classification.js +2 -0
- package/dist/engine/macos-keychain-native-port.d.ts +5 -0
- package/dist/engine/macos-keychain-native-port.js +19 -7
- package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
- package/dist/engine/migrations/remove-commercial-state.js +343 -0
- package/dist/engine/minimality/policy-loader.js +247 -6
- package/dist/engine/network-policy.js +1 -0
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +20 -20
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +20 -20
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +20 -20
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +20 -20
- package/dist/engine/readiness-checker.d.ts +1 -16
- package/dist/engine/readiness-checker.js +27 -88
- package/dist/engine/reverse-engineer/api-detector.js +2 -13
- package/dist/engine/reverse-engineer/complexity-analyzer.js +2 -13
- package/dist/engine/reverse-engineer/config-analyzer.js +2 -13
- package/dist/engine/reverse-engineer/dependency-graph.js +2 -13
- package/dist/engine/reverse-engineer/test-analyzer.js +2 -13
- package/dist/engine/reverse-engineer/walk-ignore.d.ts +3 -0
- package/dist/engine/reverse-engineer/walk-ignore.js +26 -0
- package/dist/engine/runtime-policy.d.ts +2 -0
- package/dist/engine/runtime-policy.js +42 -5
- package/dist/engine/runtime-security/rate-limiter.js +0 -1
- package/dist/engine/safety/contained-project-file.d.ts +3 -0
- package/dist/engine/safety/contained-project-file.js +23 -0
- package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
- package/dist/engine/scope-boundaries/scope-validator.js +45 -7
- package/dist/engine/session/checkpoint-writer.js +0 -9
- package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
- package/dist/engine/spec-format/acceptance-criteria.js +82 -22
- package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
- package/dist/engine/spec-format/markdown-sections.js +105 -0
- package/dist/engine/spec-format/read-technical-section.js +33 -5
- package/dist/engine/spec-format/technical-md-populator.js +3 -2
- package/dist/engine/spec-format/text-fences.js +20 -2
- package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
- package/dist/engine/spec-format/unified-spec-builder.js +202 -0
- package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
- package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
- package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
- package/dist/engine/spec-migrator/filesystem-import.js +121 -14
- package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
- package/dist/engine/spec-migrator/index.d.ts +1 -0
- package/dist/engine/spec-migrator/index.js +1 -0
- package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
- package/dist/engine/spec-state-machine/transition-spec.js +10 -1
- package/dist/engine/spec-state-syncer.js +1 -1
- package/dist/engine/technical-enricher/index.js +16 -8
- package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
- package/dist/engine/technical-enricher/render-enriched.js +42 -14
- package/dist/engine/telemetry/health-checker.js +53 -17
- package/dist/engine/telemetry/telemetry-client.js +26 -8
- package/dist/engine/text-signal-boundaries.d.ts +2 -0
- package/dist/engine/text-signal-boundaries.js +25 -2
- package/dist/engine/time/relative-date.d.ts +3 -0
- package/dist/engine/time/relative-date.js +16 -0
- package/dist/engine/timing/budget.d.ts +11 -0
- package/dist/engine/timing/budget.js +31 -9
- package/dist/engine/token-optimizer/analytics.d.ts +1 -1
- package/dist/engine/token-optimizer/analytics.js +5 -6
- package/dist/engine/usage-tracker/core.d.ts +2 -2
- package/dist/engine/usage-tracker/core.js +1 -2
- package/dist/engine/usage-tracker/index.d.ts +0 -3
- package/dist/engine/usage-tracker/index.js +0 -3
- package/dist/engine/usage-tracker/stats.d.ts +2 -2
- package/dist/engine/usage-tracker/stats.js +1 -28
- package/dist/engine/validation/durable-validation.d.ts +1 -1
- package/dist/engine/validation/durable-validation.js +3 -82
- package/dist/engine/validation/validation-freshness.d.ts +11 -1
- package/dist/engine/validation/validation-freshness.js +231 -91
- package/dist/engine/validation/validation-receipt.d.ts +9 -6
- package/dist/engine/validation/validation-receipt.js +84 -24
- package/dist/engine/validation/validation-source-digest.d.ts +2 -0
- package/dist/engine/validation/validation-source-digest.js +86 -0
- package/dist/engine/validation/validation-submission.d.ts +5 -4
- package/dist/engine/validation/validation-submission.js +25 -11
- package/dist/engine/validation/validation-worktree.d.ts +21 -0
- package/dist/engine/validation/validation-worktree.js +260 -0
- package/dist/engine/validation-impact-planner.d.ts +14 -2
- package/dist/engine/validation-impact-planner.js +0 -3
- package/dist/engine/validator/dor-dod.d.ts +1 -0
- package/dist/engine/validator/dor-dod.js +5 -3
- package/dist/engine/validator/extractors.d.ts +1 -5
- package/dist/engine/validator/extractors.js +24 -69
- package/dist/engine/validator/spec-compliance-runner.d.ts +12 -24
- package/dist/engine/validator/spec-compliance-runner.js +429 -211
- package/dist/engine/validator.js +35 -22
- package/dist/index.js +4 -16
- package/dist/resources/usage-stats-resource.js +2 -18
- package/dist/security/adapters/linux-secret-service.js +7 -3
- package/dist/security/adapters/windows-credential-manager.js +6 -4
- package/dist/server/routes/specs.js +13 -1
- package/dist/storage/base-store.d.ts +1 -1
- package/dist/storage/base-store.js +1 -1
- package/dist/storage/feedback-remote.d.ts +2 -3
- package/dist/storage/feedback-remote.js +45 -31
- package/dist/storage/global-store.d.ts +1 -17
- package/dist/storage/global-store.js +1 -42
- package/dist/storage/index.d.ts +0 -2
- package/dist/storage/index.js +0 -2
- package/dist/storage/migrations/canonical-storage.js +124 -11
- package/dist/storage/runtime-db.d.ts +9 -0
- package/dist/storage/runtime-db.js +64 -8
- package/dist/storage/spec-store.d.ts +14 -2
- package/dist/storage/spec-store.js +104 -14
- package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
- package/dist/storage/status-store/atomic-status-write.js +57 -0
- package/dist/storage/status-store/file-lock.js +30 -11
- package/dist/storage/status-store/self-healing.js +3 -3
- package/dist/storage/status-store/version-sync.d.ts +2 -1
- package/dist/storage/status-store/version-sync.js +35 -40
- package/dist/storage/usage-store.d.ts +1 -5
- package/dist/storage/usage-store.js +0 -35
- package/dist/tools/auto-update-handler.d.ts +3 -3
- package/dist/tools/auto-update-handler.js +3 -3
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
- package/dist/tools/challenge-spec/scenario-collector.js +1 -1
- package/dist/tools/challenge-spec/scenarios-data.js +1 -1
- package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
- package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
- package/dist/tools/challenge-spec-helpers.d.ts +10 -1
- package/dist/tools/challenge-spec-helpers.js +63 -22
- package/dist/tools/challenge-spec.js +23 -8
- package/dist/tools/check-readiness.js +38 -14
- package/dist/tools/configure-telemetry.js +30 -2
- package/dist/tools/create-spec/spec-builder.d.ts +7 -0
- package/dist/tools/create-spec/spec-builder.js +19 -15
- package/dist/tools/create-spec.d.ts +1 -0
- package/dist/tools/create-spec.js +584 -309
- package/dist/tools/git/branch-ops.d.ts +1 -1
- package/dist/tools/git/branch-ops.js +3 -2
- package/dist/tools/init-project/handler.js +10 -12
- package/dist/tools/init-project/host-assets-writer.js +26 -1
- package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
- package/dist/tools/init-project/migration-runner.d.ts +2 -4
- package/dist/tools/init-project/migration-runner.js +3 -2
- package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
- package/dist/tools/init-project/portable-index-reconciler.js +14 -0
- package/dist/tools/init-project/result-builder.js +1 -3
- package/dist/tools/jobs/handlers.js +38 -6
- package/dist/tools/list-specs.js +5 -26
- package/dist/tools/merge-risk-handler.js +2 -2
- package/dist/tools/package-handoff.js +2 -0
- package/dist/tools/reconcile-spec.js +0 -27
- package/dist/tools/register-agent-squad-tools.js +2 -2
- package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
- package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
- package/dist/tools/register-sdd-tools.d.ts +1 -1
- package/dist/tools/register-sdd-tools.js +2 -29
- package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
- package/dist/tools/register-spec-tools/core-spec-tools.js +29 -19
- package/dist/tools/safe-handler.d.ts +5 -13
- package/dist/tools/safe-handler.js +7 -23
- package/dist/tools/schemas/index.d.ts +1 -1
- package/dist/tools/schemas/index.js +1 -1
- package/dist/tools/schemas/output-schemas.d.ts +0 -23
- package/dist/tools/schemas/output-schemas.js +0 -28
- package/dist/tools/schemas/spec.d.ts +4 -0
- package/dist/tools/schemas/spec.js +3 -0
- package/dist/tools/schemas/validate-output-schema.d.ts +11 -0
- package/dist/tools/schemas/validate-output-schema.js +7 -0
- package/dist/tools/spec-prompt-handler.js +3 -3
- package/dist/tools/sync-spec-state-handler.d.ts +1 -1
- package/dist/tools/sync-spec-state-handler.js +50 -2
- package/dist/tools/tool-entry.d.ts +4 -4
- package/dist/tools/tool-entry.js +3 -3
- package/dist/tools/tool-registry/core-tools.js +31 -15
- package/dist/tools/tool-registry/group-infra.js +27 -110
- package/dist/tools/tool-registry/group-quality-compliance.js +26 -26
- package/dist/tools/tool-registry/inventory.d.ts +2 -0
- package/dist/tools/tool-registry/inventory.js +2 -0
- package/dist/tools/tool-registry-helpers.d.ts +3 -3
- package/dist/tools/tool-registry-helpers.js +3 -3
- package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
- package/dist/tools/tool-usage-report/registered-tools.js +3 -15
- package/dist/tools/update-status/approval-gates.js +3 -0
- package/dist/tools/update-status/batch.d.ts +6 -2
- package/dist/tools/update-status/batch.js +58 -1
- package/dist/tools/update-status/dod-gates.d.ts +16 -1
- package/dist/tools/update-status/dod-gates.js +191 -1
- package/dist/tools/update-status/done-receipt-verifier.d.ts +8 -0
- package/dist/tools/update-status/done-receipt-verifier.js +75 -27
- package/dist/tools/update-status/evidence-gate.d.ts +4 -0
- package/dist/tools/update-status/evidence-gate.js +103 -3
- package/dist/tools/update-status/file-sync.d.ts +4 -3
- package/dist/tools/update-status/file-sync.js +57 -6
- package/dist/tools/update-status/index.d.ts +25 -1
- package/dist/tools/update-status/index.js +292 -78
- package/dist/tools/update-status/response-builder.js +3 -3
- package/dist/tools/update-status/side-effects.d.ts +2 -0
- package/dist/tools/update-status/side-effects.js +2 -2
- package/dist/tools/update-status/transition-guard.js +45 -16
- package/dist/tools/update-status-actions.d.ts +4 -2
- package/dist/tools/update-status-actions.js +16 -14
- package/dist/tools/usage-report.js +1 -16
- package/dist/tools/usage-stats.js +1 -18
- package/dist/tools/usage-tracking.d.ts +4 -0
- package/dist/tools/usage-tracking.js +20 -0
- package/dist/tools/validate-lint.d.ts +1 -0
- package/dist/tools/validate-lint.js +1 -1
- package/dist/tools/validate.d.ts +2 -1
- package/dist/tools/validate.js +114 -34
- package/dist/tools/workspace-dashboard-handler.js +38 -0
- package/dist/transports/http-transport.js +6 -8
- package/dist/transports/mcp-types.d.ts +0 -2
- package/dist/transports/session-context.js +1 -1
- package/dist/types/cascade-hooks.d.ts +1 -1
- package/dist/types/ci.d.ts +0 -4
- package/dist/types/clarification-token.d.ts +1 -1
- package/dist/types/claude-code-runtime.d.ts +0 -27
- package/dist/types/commercial-migration.d.ts +17 -0
- package/dist/types/commercial-migration.js +2 -0
- package/dist/types/common/primitives.d.ts +0 -2
- package/dist/types/core-bridge.d.ts +4 -10
- package/dist/types/dashboard.d.ts +3 -7
- package/dist/types/docs.d.ts +0 -1
- package/dist/types/durable-job.d.ts +4 -4
- package/dist/types/durable-validation.d.ts +100 -2
- package/dist/types/durable-validation.js +165 -1
- package/dist/types/errors/structured-error.d.ts +3 -3
- package/dist/types/estimation.d.ts +2 -0
- package/dist/types/evidence-autofill.d.ts +34 -0
- package/dist/types/evidence-autofill.js +2 -0
- package/dist/types/evidence-gates.d.ts +9 -1
- package/dist/types/execution.d.ts +2 -0
- package/dist/types/gemini-integration.d.ts +0 -11
- package/dist/types/handoff-artifacts.d.ts +41 -0
- package/dist/types/hooks-advanced.d.ts +0 -13
- package/dist/types/impact-detection.d.ts +2 -2
- package/dist/types/index.d.ts +3 -6
- package/dist/types/index.js +2 -5
- package/dist/types/kiro-integration.d.ts +0 -6
- package/dist/types/network-policy.d.ts +1 -1
- package/dist/types/project/lint-scaffolder.d.ts +1 -1
- package/dist/types/runtime-policy.d.ts +11 -0
- package/dist/types/session-safeguard.d.ts +0 -31
- package/dist/types/spec/canonical-repair.d.ts +81 -0
- package/dist/types/spec/canonical-repair.js +2 -0
- package/dist/types/spec/core.d.ts +20 -0
- package/dist/types/spec/index.d.ts +1 -0
- package/dist/types/spec/index.js +1 -0
- package/dist/types/spec/inputs.d.ts +35 -1
- package/dist/types/spec-format.d.ts +25 -1
- package/dist/types/telemetry.d.ts +4 -1
- package/dist/types/transition-log.d.ts +1 -1
- package/dist/types/transport.d.ts +0 -2
- package/dist/types/usage.d.ts +1 -36
- package/dist/types/usage.js +1 -1
- package/dist/types/validate-worker.d.ts +6 -0
- package/dist/types/validation-receipt.d.ts +1 -1
- package/dist/types/validation.d.ts +10 -4
- package/package.json +17 -12
- package/planu-native.json +1 -1
- package/planu-plugin.json +23 -40
- package/scripts/lib/pending-release-file.mjs +93 -0
- package/src/i18n/messages/en.json +0 -41
- package/src/i18n/messages/es.json +0 -41
- package/src/i18n/messages/pt.json +0 -41
- package/dist/cli/commands/activate.d.ts +0 -14
- package/dist/cli/commands/activate.js +0 -174
- package/dist/config/license-plans.json +0 -251
- package/dist/config/product-public.ts +0 -148
- package/dist/config/server-instructions.ts +0 -121
- package/dist/config/version-defaults.ts +0 -76
- package/dist/config/version.ts +0 -21
- package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
- package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
- package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
- package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
- package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
- package/dist/engine/hooks/full-spectrum-generator.js +0 -117
- package/dist/engine/license-validator/config-loader.d.ts +0 -5
- package/dist/engine/license-validator/config-loader.js +0 -16
- package/dist/engine/license-validator/core.d.ts +0 -15
- package/dist/engine/license-validator/core.js +0 -151
- package/dist/engine/license-validator/fingerprint.d.ts +0 -3
- package/dist/engine/license-validator/fingerprint.js +0 -17
- package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
- package/dist/engine/license-validator/lemon-squeezy.js +0 -55
- package/dist/engine/license-validator.d.ts +0 -5
- package/dist/engine/license-validator.js +0 -6
- package/dist/engine/product-intelligence/index.d.ts +0 -7
- package/dist/engine/product-intelligence/index.js +0 -211
- package/dist/engine/session/auto-save.d.ts +0 -18
- package/dist/engine/session/auto-save.js +0 -98
- package/dist/engine/session/context-snapshot.d.ts +0 -8
- package/dist/engine/session/context-snapshot.js +0 -49
- package/dist/engine/session/memory-sync.d.ts +0 -12
- package/dist/engine/session/memory-sync.js +0 -34
- package/dist/engine/session/session-diff.d.ts +0 -11
- package/dist/engine/session/session-diff.js +0 -42
- package/dist/engine/session/session-merge.d.ts +0 -12
- package/dist/engine/session/session-merge.js +0 -55
- package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
- package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
- package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -15
- package/dist/engine/session-safeguard/learnings-buffer.js +0 -91
- package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
- package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
- package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
- package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
- package/dist/engine/spec-changelog/core.d.ts +0 -16
- package/dist/engine/spec-changelog/core.js +0 -176
- package/dist/engine/spec-changelog/diff.d.ts +0 -18
- package/dist/engine/spec-changelog/diff.js +0 -121
- package/dist/engine/spec-changelog/index.d.ts +0 -3
- package/dist/engine/spec-changelog/index.js +0 -4
- package/dist/engine/trial-engine.d.ts +0 -5
- package/dist/engine/trial-engine.js +0 -14
- package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
- package/dist/engine/usage-tracker/rate-check.js +0 -18
- package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
- package/dist/engine/usage-tracker/rate-limiter.js +0 -73
- package/dist/engine/usage-tracker/trial.d.ts +0 -27
- package/dist/engine/usage-tracker/trial.js +0 -49
- package/dist/engine/webhook/event-handlers.d.ts +0 -25
- package/dist/engine/webhook/event-handlers.js +0 -89
- package/dist/engine/webhook/index.d.ts +0 -4
- package/dist/engine/webhook/index.js +0 -5
- package/dist/engine/webhook/server.d.ts +0 -12
- package/dist/engine/webhook/server.js +0 -249
- package/dist/engine/webhook/signature.d.ts +0 -16
- package/dist/engine/webhook/signature.js +0 -49
- package/dist/storage/license-store.d.ts +0 -6
- package/dist/storage/license-store.js +0 -63
- package/dist/storage/session-store.d.ts +0 -20
- package/dist/storage/session-store.js +0 -136
- package/dist/tools/activate-license.d.ts +0 -6
- package/dist/tools/activate-license.js +0 -132
- package/dist/tools/checkpoint-handler.d.ts +0 -3
- package/dist/tools/checkpoint-handler.js +0 -130
- package/dist/tools/export-session.d.ts +0 -3
- package/dist/tools/export-session.js +0 -90
- package/dist/tools/license-gate.d.ts +0 -18
- package/dist/tools/license-gate.js +0 -222
- package/dist/tools/license-status.d.ts +0 -3
- package/dist/tools/license-status.js +0 -93
- package/dist/tools/list-sessions.d.ts +0 -3
- package/dist/tools/list-sessions.js +0 -46
- package/dist/tools/planu-session-checkpoint.d.ts +0 -6
- package/dist/tools/planu-session-checkpoint.js +0 -42
- package/dist/tools/restore-session.d.ts +0 -3
- package/dist/tools/restore-session.js +0 -71
- package/dist/tools/spec-history.d.ts +0 -3
- package/dist/tools/spec-history.js +0 -59
- package/dist/tools/webhook.d.ts +0 -6
- package/dist/tools/webhook.js +0 -150
- package/dist/types/changelog.d.ts +0 -49
- package/dist/types/changelog.js +0 -3
- package/dist/types/licensing.d.ts +0 -109
- package/dist/types/licensing.js +0 -4
- package/dist/types/product-intelligence.d.ts +0 -60
- package/dist/types/product-intelligence.js +0 -3
- package/dist/types/session.d.ts +0 -84
- package/dist/types/session.js +0 -3
- package/dist/types/webhook.d.ts +0 -62
- package/dist/types/webhook.js +0 -4
|
@@ -24,10 +24,44 @@ const GENERIC_SCOPE_TOKENS = new Set([
|
|
|
24
24
|
'tool',
|
|
25
25
|
'tools',
|
|
26
26
|
]);
|
|
27
|
+
const GENERIC_SEMANTIC_TOKENS = new Set([
|
|
28
|
+
'change',
|
|
29
|
+
'validation',
|
|
30
|
+
'evidence',
|
|
31
|
+
'format',
|
|
32
|
+
'semantic',
|
|
33
|
+
'schema',
|
|
34
|
+
'receipt',
|
|
35
|
+
]);
|
|
36
|
+
function inflectionCandidates(token) {
|
|
37
|
+
const candidates = [token];
|
|
38
|
+
if (token.endsWith('s')) {
|
|
39
|
+
candidates.push(token.slice(0, -1));
|
|
40
|
+
}
|
|
41
|
+
for (const suffix of ['ed', 'ing']) {
|
|
42
|
+
if (token.endsWith(suffix)) {
|
|
43
|
+
const stem = token.slice(0, -suffix.length);
|
|
44
|
+
candidates.push(stem, `${stem}e`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return [...new Set(candidates.filter((candidate) => candidate.length >= 4))];
|
|
48
|
+
}
|
|
49
|
+
function semanticToken(token) {
|
|
50
|
+
const candidates = inflectionCandidates(token);
|
|
51
|
+
const generic = candidates.find((candidate) => GENERIC_SEMANTIC_TOKENS.has(candidate));
|
|
52
|
+
if (generic) {
|
|
53
|
+
return generic;
|
|
54
|
+
}
|
|
55
|
+
const singular = token.endsWith('s') ? token.slice(0, -1) : token;
|
|
56
|
+
return singular.length >= 4 ? singular : token;
|
|
57
|
+
}
|
|
27
58
|
function keywords(phrase) {
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
|
|
59
|
+
return [
|
|
60
|
+
...new Set(normalize(phrase)
|
|
61
|
+
.split(' ')
|
|
62
|
+
.filter((word) => word.length > 2 && !STOP_WORDS.has(word) && !GENERIC_SCOPE_TOKENS.has(word))
|
|
63
|
+
.map(semanticToken)),
|
|
64
|
+
];
|
|
31
65
|
}
|
|
32
66
|
/**
|
|
33
67
|
* Determine whether a file path matches an out-of-scope item.
|
|
@@ -39,9 +73,12 @@ function fileMatchesScopeItem(filePath, scopeItem) {
|
|
|
39
73
|
if (scopeKws.length === 0) {
|
|
40
74
|
return false;
|
|
41
75
|
}
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
76
|
+
const pathKeywords = new Set(keywords(normPath));
|
|
77
|
+
const specific = scopeKws.filter((token) => !GENERIC_SEMANTIC_TOKENS.has(token));
|
|
78
|
+
const matched = scopeKws.filter((token) => pathKeywords.has(token));
|
|
79
|
+
return specific.length > 0
|
|
80
|
+
? specific.some((token) => pathKeywords.has(token))
|
|
81
|
+
: new Set(matched).size >= 2;
|
|
45
82
|
}
|
|
46
83
|
/**
|
|
47
84
|
* Validate implementation file paths against the spec's outOfScope declarations.
|
|
@@ -52,8 +89,9 @@ export function validateScopeCompliance(outOfScope, filePaths) {
|
|
|
52
89
|
for (const filePath of filePaths) {
|
|
53
90
|
for (const scopeItem of outOfScope) {
|
|
54
91
|
if (fileMatchesScopeItem(filePath, scopeItem)) {
|
|
92
|
+
const pathKeywords = new Set(keywords(filePath));
|
|
55
93
|
const matchedKws = keywords(scopeItem)
|
|
56
|
-
.filter((
|
|
94
|
+
.filter((keyword) => pathKeywords.has(keyword))
|
|
57
95
|
.join(', ');
|
|
58
96
|
warnings.push({
|
|
59
97
|
filePath,
|
|
@@ -74,15 +74,6 @@ export async function writeCheckpoint(projectPath, snapshot) {
|
|
|
74
74
|
const updated = replaceLatestCheckpoint(existing, newBlock);
|
|
75
75
|
await mkdir(planuDir, { recursive: true });
|
|
76
76
|
await writeFile(filePath, updated, 'utf8');
|
|
77
|
-
void (async () => {
|
|
78
|
-
try {
|
|
79
|
-
const { planuAutoCommit } = await import('../git/planu-autocommit.js');
|
|
80
|
-
await planuAutoCommit({ projectPath, reason: 'session-checkpoint' });
|
|
81
|
-
}
|
|
82
|
-
catch {
|
|
83
|
-
/* best-effort — never blocks checkpoint writer */
|
|
84
|
-
}
|
|
85
|
-
})();
|
|
86
77
|
}
|
|
87
78
|
/**
|
|
88
79
|
* Fire-and-forget helper: records the tool call, then writes a checkpoint if
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import type { NormalizedAcceptanceCriterion } from '../../types/spec-format.js';
|
|
2
|
-
export declare function extractNormalizedAcceptanceCriteria(raw: string
|
|
3
|
-
|
|
2
|
+
export declare function extractNormalizedAcceptanceCriteria(raw: string, options?: {
|
|
3
|
+
allowLegacyBodyFallback?: boolean;
|
|
4
|
+
}): NormalizedAcceptanceCriterion[];
|
|
5
|
+
export declare function extractAcceptanceCriteriaTexts(raw: string, options?: {
|
|
6
|
+
allowLegacyBodyFallback?: boolean;
|
|
7
|
+
}): string[];
|
|
4
8
|
export declare function normalizeAcceptanceCriterionToken(value: string): string;
|
|
5
9
|
//# sourceMappingURL=acceptance-criteria.d.ts.map
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { parseFrontmatterScenarios } from '../validator/spec-compliance-runner.js';
|
|
2
2
|
import { stripFrontmatter } from '../frontmatter-parser.js';
|
|
3
|
-
import { extractListItems, extractSection } from '
|
|
3
|
+
import { extractListItems, extractSection } from './markdown-sections.js';
|
|
4
|
+
import { stripFencedBlocks } from './text-fences.js';
|
|
4
5
|
import { createCriterionIdentity, normalizeCriterionText } from '../criterion-identity.js';
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
const BDD_STEP = /^(GIVEN|WHEN|THEN|AND|DADO|CUANDO|ENTONCES|Y)\b/i;
|
|
7
|
+
const BDD_START = /^(GIVEN|DADO)\b/i;
|
|
8
|
+
const TECHNICAL_MARKER = /^(FILES|FUNCTIONS|TEST|OWNER):/i;
|
|
9
|
+
const EXPLICIT_CRITERION_HEADING = /^#{3,6}\s+((?:AC|AB)\s*-?\s*\d+)\b/i;
|
|
10
|
+
function extractBddBlocks(section) {
|
|
10
11
|
const lines = section.split('\n').map((line) => line.trim());
|
|
11
12
|
if (lines.length === 0) {
|
|
12
13
|
return [];
|
|
@@ -21,16 +22,21 @@ function extractSectionCriteria(section) {
|
|
|
21
22
|
}
|
|
22
23
|
continue;
|
|
23
24
|
}
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
const withoutListMarker = line.replace(/^(?:[-*+]\s+(?:\[[ xX]\]\s*)?|\d+[.)]\s+)/, '');
|
|
26
|
+
if (TECHNICAL_MARKER.test(withoutListMarker) || /^#{1,6}\s+/.test(withoutListMarker)) {
|
|
27
|
+
if (current.length > 0) {
|
|
26
28
|
bddBlocks.push(current.join(' '));
|
|
27
29
|
current = [];
|
|
28
30
|
}
|
|
29
|
-
current.push(line.replace(/^[-*+]\s*/, ''));
|
|
30
31
|
continue;
|
|
31
32
|
}
|
|
32
|
-
if (
|
|
33
|
-
|
|
33
|
+
if (BDD_STEP.test(withoutListMarker)) {
|
|
34
|
+
if (BDD_START.test(withoutListMarker) && current.length > 0) {
|
|
35
|
+
bddBlocks.push(current.join(' '));
|
|
36
|
+
current = [];
|
|
37
|
+
}
|
|
38
|
+
current.push(withoutListMarker);
|
|
39
|
+
continue;
|
|
34
40
|
}
|
|
35
41
|
}
|
|
36
42
|
if (current.length > 0) {
|
|
@@ -38,8 +44,55 @@ function extractSectionCriteria(section) {
|
|
|
38
44
|
}
|
|
39
45
|
return bddBlocks;
|
|
40
46
|
}
|
|
41
|
-
function
|
|
42
|
-
const
|
|
47
|
+
function extractExplicitCriterionBodies(section) {
|
|
48
|
+
const lines = section.split('\n');
|
|
49
|
+
const bodies = [];
|
|
50
|
+
let current = null;
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
const heading = EXPLICIT_CRITERION_HEADING.exec(line.trim());
|
|
53
|
+
if (heading?.[1]) {
|
|
54
|
+
if (current !== null) {
|
|
55
|
+
bodies.push(current);
|
|
56
|
+
}
|
|
57
|
+
current = { id: heading[1].replace(/[\s-]/g, ''), body: '' };
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (current !== null) {
|
|
61
|
+
current.body += `${current.body.length > 0 ? '\n' : ''}${line}`;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (current !== null) {
|
|
65
|
+
bodies.push(current);
|
|
66
|
+
}
|
|
67
|
+
return bodies;
|
|
68
|
+
}
|
|
69
|
+
function extractOneCriterion(body) {
|
|
70
|
+
const bddBlocks = extractBddBlocks(body);
|
|
71
|
+
if (bddBlocks.length > 0) {
|
|
72
|
+
return bddBlocks.reduce((selected, candidate) => candidate.length > selected.length ? candidate : selected);
|
|
73
|
+
}
|
|
74
|
+
const listItem = extractListItems(body).find((item) => !TECHNICAL_MARKER.test(item));
|
|
75
|
+
return listItem ?? null;
|
|
76
|
+
}
|
|
77
|
+
function extractSectionCriteria(section) {
|
|
78
|
+
const explicitBodies = extractExplicitCriterionBodies(section);
|
|
79
|
+
if (explicitBodies.length > 0) {
|
|
80
|
+
return explicitBodies
|
|
81
|
+
.map(({ id, body }) => {
|
|
82
|
+
const criterion = extractOneCriterion(body);
|
|
83
|
+
return criterion === null ? null : `${id}: ${criterion}`;
|
|
84
|
+
})
|
|
85
|
+
.filter((criterion) => criterion !== null);
|
|
86
|
+
}
|
|
87
|
+
const listItems = extractListItems(section).filter((item) => !TECHNICAL_MARKER.test(item));
|
|
88
|
+
if (listItems.length > 0) {
|
|
89
|
+
const nonStepItems = listItems.filter((item) => !BDD_STEP.test(item));
|
|
90
|
+
return nonStepItems.length > 0 ? nonStepItems : extractBddBlocks(section);
|
|
91
|
+
}
|
|
92
|
+
return extractBddBlocks(section);
|
|
93
|
+
}
|
|
94
|
+
function extractBodyCriteria(raw, options) {
|
|
95
|
+
const body = stripFencedBlocks(stripFrontmatter(raw));
|
|
43
96
|
const acceptanceCriteria = extractSection(body, 'acceptance criteria', 'criterios de aceptaci');
|
|
44
97
|
if (acceptanceCriteria) {
|
|
45
98
|
const sectionCriteria = extractSectionCriteria(acceptanceCriteria);
|
|
@@ -47,11 +100,18 @@ function extractBodyCriteria(raw) {
|
|
|
47
100
|
return sectionCriteria;
|
|
48
101
|
}
|
|
49
102
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
103
|
+
if (options.allowLegacyBodyFallback !== false) {
|
|
104
|
+
const checkboxCriteria = body
|
|
105
|
+
.split('\n')
|
|
106
|
+
.map((line) => line.trim())
|
|
107
|
+
.filter((line) => /^-\s*\[[ x]\]/i.test(line))
|
|
108
|
+
.map((line) => line.replace(/^-\s*\[[ x]\]\s*/i, '').trim());
|
|
109
|
+
if (checkboxCriteria.length > 0) {
|
|
110
|
+
return checkboxCriteria;
|
|
111
|
+
}
|
|
112
|
+
return extractBddBlocks(body);
|
|
113
|
+
}
|
|
114
|
+
return [];
|
|
55
115
|
}
|
|
56
116
|
function buildCriterion(text, source, index) {
|
|
57
117
|
const trimmed = text.trim();
|
|
@@ -68,8 +128,8 @@ function buildCriterion(text, source, index) {
|
|
|
68
128
|
aliases: identity.aliases,
|
|
69
129
|
};
|
|
70
130
|
}
|
|
71
|
-
export function extractNormalizedAcceptanceCriteria(raw) {
|
|
72
|
-
const bodyCriteria = extractBodyCriteria(raw)
|
|
131
|
+
export function extractNormalizedAcceptanceCriteria(raw, options = {}) {
|
|
132
|
+
const bodyCriteria = extractBodyCriteria(raw, options)
|
|
73
133
|
.map((criterion, index) => buildCriterion(criterion, 'body', index))
|
|
74
134
|
.filter((criterion) => criterion !== null);
|
|
75
135
|
if (bodyCriteria.length > 0) {
|
|
@@ -79,8 +139,8 @@ export function extractNormalizedAcceptanceCriteria(raw) {
|
|
|
79
139
|
.map((scenario, index) => buildCriterion(scenario.title, 'frontmatter', index))
|
|
80
140
|
.filter((criterion) => criterion !== null);
|
|
81
141
|
}
|
|
82
|
-
export function extractAcceptanceCriteriaTexts(raw) {
|
|
83
|
-
return extractNormalizedAcceptanceCriteria(raw).map((criterion) => criterion.text);
|
|
142
|
+
export function extractAcceptanceCriteriaTexts(raw, options = {}) {
|
|
143
|
+
return extractNormalizedAcceptanceCriteria(raw, options).map((criterion) => criterion.text);
|
|
84
144
|
}
|
|
85
145
|
export function normalizeAcceptanceCriterionToken(value) {
|
|
86
146
|
return normalizeCriterionText(value);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Locate one exact markdown section without normalizing or copying source bytes. */
|
|
2
|
+
export declare function findMarkdownSectionRange(content: string, headingName: string): {
|
|
3
|
+
headingStart: number;
|
|
4
|
+
contentStart: number;
|
|
5
|
+
end: number;
|
|
6
|
+
level: number;
|
|
7
|
+
} | null;
|
|
8
|
+
/**
|
|
9
|
+
* Extract the text content under a markdown heading that matches any keyword.
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractSection(content: string, ...headingKeywords: string[]): string | null;
|
|
12
|
+
/** Extract bullet and numbered-list item text from a markdown block. */
|
|
13
|
+
export declare function extractListItems(content: string): string[];
|
|
14
|
+
//# sourceMappingURL=markdown-sections.d.ts.map
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
function markdownLines(content) {
|
|
2
|
+
const lines = [];
|
|
3
|
+
let start = 0;
|
|
4
|
+
while (start < content.length) {
|
|
5
|
+
const newline = content.indexOf('\n', start);
|
|
6
|
+
const end = newline === -1 ? content.length : newline + 1;
|
|
7
|
+
const contentEnd = newline === -1
|
|
8
|
+
? end
|
|
9
|
+
: newline > start && content[newline - 1] === '\r'
|
|
10
|
+
? newline - 1
|
|
11
|
+
: newline;
|
|
12
|
+
lines.push({ start, contentEnd, end });
|
|
13
|
+
start = end;
|
|
14
|
+
}
|
|
15
|
+
return lines;
|
|
16
|
+
}
|
|
17
|
+
/** Locate one exact markdown section without normalizing or copying source bytes. */
|
|
18
|
+
export function findMarkdownSectionRange(content, headingName) {
|
|
19
|
+
let selected = null;
|
|
20
|
+
let fence = null;
|
|
21
|
+
for (const line of markdownLines(content)) {
|
|
22
|
+
const text = content.slice(line.start, line.contentEnd);
|
|
23
|
+
const fenceMatch = /^[ \t]{0,3}(`{3,}|~{3,})/.exec(text);
|
|
24
|
+
if (fenceMatch?.[1]) {
|
|
25
|
+
const marker = fenceMatch[1][0];
|
|
26
|
+
if (fence === null) {
|
|
27
|
+
fence = { marker, length: fenceMatch[1].length };
|
|
28
|
+
}
|
|
29
|
+
else if (fence.marker === marker && fenceMatch[1].length >= fence.length) {
|
|
30
|
+
fence = null;
|
|
31
|
+
}
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (fence !== null) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
const heading = /^(#{1,6})[ \t]+(.+?)[ \t]*#*[ \t]*$/.exec(text);
|
|
38
|
+
if (!heading?.[1] || heading[2] === undefined) {
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
const level = heading[1].length;
|
|
42
|
+
if (selected !== null && level <= selected.level) {
|
|
43
|
+
return { ...selected, end: line.start };
|
|
44
|
+
}
|
|
45
|
+
if (selected === null && heading[2].trim().toLowerCase() === headingName.trim().toLowerCase()) {
|
|
46
|
+
selected = {
|
|
47
|
+
headingStart: line.start,
|
|
48
|
+
contentStart: line.end,
|
|
49
|
+
end: content.length,
|
|
50
|
+
level,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return selected;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Extract the text content under a markdown heading that matches any keyword.
|
|
58
|
+
*/
|
|
59
|
+
export function extractSection(content, ...headingKeywords) {
|
|
60
|
+
const lines = content.split('\n');
|
|
61
|
+
let capturing = false;
|
|
62
|
+
let capturedLevel = 0;
|
|
63
|
+
const captured = [];
|
|
64
|
+
for (const line of lines) {
|
|
65
|
+
const headingMatch = /^(#{1,6})\s+(.+)/.exec(line);
|
|
66
|
+
if (headingMatch?.[1] !== undefined && headingMatch[2] !== undefined) {
|
|
67
|
+
const level = headingMatch[1].length;
|
|
68
|
+
const title = headingMatch[2].toLowerCase();
|
|
69
|
+
if (capturing && level <= capturedLevel) {
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
if (!capturing && headingKeywords.some((keyword) => title.includes(keyword))) {
|
|
73
|
+
capturing = true;
|
|
74
|
+
capturedLevel = level;
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (capturing) {
|
|
79
|
+
captured.push(line);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return captured.length > 0 ? captured.join('\n') : null;
|
|
83
|
+
}
|
|
84
|
+
/** Extract bullet and numbered-list item text from a markdown block. */
|
|
85
|
+
export function extractListItems(content) {
|
|
86
|
+
const items = [];
|
|
87
|
+
for (const line of content.split('\n')) {
|
|
88
|
+
const listMatch = /^\s*[-*+]\s+\[?\s*[xX ]?\s*\]?\s*(.+)/.exec(line);
|
|
89
|
+
if (listMatch?.[1]) {
|
|
90
|
+
const item = listMatch[1].trim();
|
|
91
|
+
if (item.length > 5) {
|
|
92
|
+
items.push(item);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const numberedMatch = /^\s*\d+[.)]\s+(.+)/.exec(line);
|
|
96
|
+
if (numberedMatch?.[1]) {
|
|
97
|
+
const item = numberedMatch[1].trim();
|
|
98
|
+
if (item.length > 5) {
|
|
99
|
+
items.push(item);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return items;
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=markdown-sections.js.map
|
|
@@ -60,11 +60,39 @@ export function extractSectionBody(body, sectionName) {
|
|
|
60
60
|
* against the masked variant.
|
|
61
61
|
*/
|
|
62
62
|
function maskFencedBlocks(body) {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
63
|
+
const masked = body.split('');
|
|
64
|
+
let activeMarker = null;
|
|
65
|
+
let minimumClosingLength = 0;
|
|
66
|
+
let lineStart = 0;
|
|
67
|
+
while (lineStart < body.length) {
|
|
68
|
+
const newlineIndex = body.indexOf('\n', lineStart);
|
|
69
|
+
const lineEnd = newlineIndex === -1 ? body.length : newlineIndex;
|
|
70
|
+
const line = body.slice(lineStart, lineEnd);
|
|
71
|
+
if (activeMarker === null) {
|
|
72
|
+
const opening = /^ {0,3}(`{3,}|~{3,})/.exec(line)?.[1];
|
|
73
|
+
if (opening !== undefined) {
|
|
74
|
+
activeMarker = opening[0];
|
|
75
|
+
minimumClosingLength = opening.length;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const closing = /^ {0,3}(`+|~+)[ \t]*$/.exec(line)?.[1];
|
|
80
|
+
if (closing?.startsWith(activeMarker) === true && closing.length >= minimumClosingLength) {
|
|
81
|
+
activeMarker = null;
|
|
82
|
+
minimumClosingLength = 0;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (activeMarker !== null || minimumClosingLength === 0) {
|
|
86
|
+
const isFenceBoundary = /^ {0,3}(`{3,}|~{3,})/.test(line) || /^ {0,3}(`+|~+)[ \t]*$/.test(line);
|
|
87
|
+
if (activeMarker !== null || isFenceBoundary) {
|
|
88
|
+
for (let index = lineStart; index < lineEnd; index += 1) {
|
|
89
|
+
masked[index] = ' ';
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
lineStart = newlineIndex === -1 ? body.length : newlineIndex + 1;
|
|
94
|
+
}
|
|
95
|
+
return masked.join('');
|
|
68
96
|
}
|
|
69
97
|
function escapeRegex(input) {
|
|
70
98
|
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
@@ -18,7 +18,7 @@ function extractPathsFromSection(sectionText) {
|
|
|
18
18
|
return paths;
|
|
19
19
|
}
|
|
20
20
|
function parseSectionedFileLists(body) {
|
|
21
|
-
const filesSection = /##\s+Files
|
|
21
|
+
const filesSection = /##\s+Files(?:\s+likely\s+to\s+change)?\s*[\s\S]*?(?=\n##\s|$)/.exec(body);
|
|
22
22
|
const scopedBody = filesSection?.[0] ?? body;
|
|
23
23
|
const createSection = /###\s+Create[\s\S]*?(?=\n###|\n##\s|$)/.exec(scopedBody);
|
|
24
24
|
const modifySection = /###\s+Modify[\s\S]*?(?=\n###|\n##\s|$)/.exec(scopedBody);
|
|
@@ -67,7 +67,8 @@ async function categorizeByExistence(paths, projectPath) {
|
|
|
67
67
|
*/
|
|
68
68
|
export async function extractFilesFromSpecBody(specBody, projectPath) {
|
|
69
69
|
const structured = parseSectionedFileLists(specBody);
|
|
70
|
-
if (structured !== null &&
|
|
70
|
+
if (structured !== null &&
|
|
71
|
+
(structured.create.length > 0 || structured.modify.length > 0 || structured.test.length > 0)) {
|
|
71
72
|
return structured;
|
|
72
73
|
}
|
|
73
74
|
const allPaths = [...new Set(Array.from(specBody.matchAll(FILE_PATH_RE), (m) => m[0]))];
|
|
@@ -4,7 +4,25 @@
|
|
|
4
4
|
* Returns the remaining prose only, preserving line structure.
|
|
5
5
|
*/
|
|
6
6
|
export function stripFencedBlocks(md) {
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
const lines = md.split('\n');
|
|
8
|
+
let openFence;
|
|
9
|
+
return lines
|
|
10
|
+
.map((line) => {
|
|
11
|
+
if (openFence !== undefined) {
|
|
12
|
+
const close = new RegExp(`^ {0,3}${openFence.marker}{${String(openFence.length)},}[ \\t]*\\r?$`);
|
|
13
|
+
if (close.test(line)) {
|
|
14
|
+
openFence = undefined;
|
|
15
|
+
}
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
const opening = /^ {0,3}(`{3,}|~{3,})[^\r\n]*\r?$/.exec(line);
|
|
19
|
+
if (opening?.[1]) {
|
|
20
|
+
const marker = opening[1][0];
|
|
21
|
+
openFence = { marker, length: opening[1].length };
|
|
22
|
+
return '';
|
|
23
|
+
}
|
|
24
|
+
return line;
|
|
25
|
+
})
|
|
26
|
+
.join('\n');
|
|
9
27
|
}
|
|
10
28
|
//# sourceMappingURL=text-fences.js.map
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { CanonicalUnifiedSpecInput, UnifiedSpecCandidateValidation } from '../../types/index.js';
|
|
2
|
+
/** Compose the one canonical persisted spec document from already-grounded inputs. */
|
|
3
|
+
export declare function buildCanonicalUnifiedSpecContent(input: CanonicalUnifiedSpecInput): string;
|
|
1
4
|
/**
|
|
2
5
|
* Combine a generated lean spec.md body and a generated lean technical.md body
|
|
3
6
|
* into a single unified spec.md content. The technical body's YAML frontmatter
|
|
@@ -10,4 +13,8 @@
|
|
|
10
13
|
* inject sections the user did not author themselves.
|
|
11
14
|
*/
|
|
12
15
|
export declare function buildUnifiedSpecContent(leanSpecBody: string, leanTechnicalBody: string): string;
|
|
16
|
+
/** Pure pre-persistence validation for the complete unified spec candidate. */
|
|
17
|
+
export declare function validateUnifiedSpecCandidate(candidate: string, options?: {
|
|
18
|
+
groundedFilePaths?: Iterable<string>;
|
|
19
|
+
}): UnifiedSpecCandidateValidation;
|
|
13
20
|
//# sourceMappingURL=unified-spec-builder.d.ts.map
|