@planu/cli 5.3.68 → 5.4.0
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 +78 -0
- package/dist/.planu-build.json +1 -1
- package/dist/cli/commands/install.d.ts +2 -15
- package/dist/config/skill-templates/planu-dogfood-bug.md +43 -0
- package/dist/config/skill-templates/planu-implement.md +42 -0
- package/dist/config/skill-templates/planu-review.md +47 -0
- package/dist/core/shared/fs.d.ts +11 -0
- package/dist/core/shared/fs.js +90 -0
- package/dist/core/shared/strings.d.ts +3 -0
- package/dist/core/shared/strings.js +13 -0
- package/dist/engine/actuals/git-analyzer.js +1 -1
- package/dist/engine/actuals/progress-parser.js +1 -3
- package/dist/engine/agent-handoff-store.js +1 -0
- package/dist/engine/agent-squad/dispatcher.js +1 -0
- package/dist/engine/agent-telemetry.js +1 -0
- package/dist/engine/auth/config.js +1 -0
- package/dist/engine/auto-updater/atomic-upgrade.js +1 -0
- package/dist/engine/auto-updater/index.js +1 -0
- package/dist/engine/autopilot/action-registry.js +20 -0
- package/dist/engine/autopilot/audit-logger.js +1 -0
- package/dist/engine/autopilot/bootstrap.js +9 -2
- package/dist/engine/autopilot/complete-loop.js +4 -0
- package/dist/engine/autopilot/crash-shield-rate-limiter.js +1 -0
- package/dist/engine/autopilot/event-bus.js +1 -0
- package/dist/engine/autopilot/state-updater.js +6 -0
- package/dist/engine/browser-validator.js +1 -3
- package/dist/engine/build-tool-detector.js +1 -8
- package/dist/engine/bundle-installer.js +2 -10
- package/dist/engine/cascade-hooks/core/append-releases.js +1 -0
- package/dist/engine/cascade-hooks/core/write-session-json.js +2 -2
- package/dist/engine/cascade-hooks/hooks/dispatch-hook-event.hook.d.ts +3 -1
- package/dist/engine/cascade-hooks/hooks/dispatch-hook-event.hook.js +12 -3
- package/dist/engine/cascade-hooks/hooks/estimate-calibration.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/housekeeping-on-done.hook.js +2 -0
- package/dist/engine/cascade-hooks/hooks/implementing-kickoff.hook.js +5 -1
- package/dist/engine/cascade-hooks/hooks/lesson-drift.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/orchestration-plan.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/session-context.hook.js +4 -2
- package/dist/engine/cascade-hooks/hooks/slack-notify.hook.js +1 -0
- package/dist/engine/cascade-hooks/hooks/status-json.hook.js +2 -0
- package/dist/engine/cascade-hooks/hooks/velocity-profile.hook.js +2 -0
- package/dist/engine/cascade-hooks/runner.js +2 -0
- package/dist/engine/cascade-hooks/state-drift-detector.js +2 -0
- package/dist/engine/checkpoint/checkpoint-manager.js +2 -0
- package/dist/engine/checkpoint/policy-engine.js +1 -0
- package/dist/engine/ci-generator/stack-detector.js +2 -10
- package/dist/engine/clarification-gate/token-store.js +1 -0
- package/dist/engine/claude-config-auditor/claudemd-auditor.js +2 -10
- package/dist/engine/claude-config-auditor/settings-auditor.js +2 -10
- package/dist/engine/client-detection.js +2 -10
- package/dist/engine/compliance/auto-remediator.js +1 -0
- package/dist/engine/compliance/evidence-builder.d.ts +2 -2
- package/dist/engine/compliance/framework-catalog.d.ts +6 -6
- package/dist/engine/compliance/gap-analyzer.d.ts +2 -2
- package/dist/engine/config-health/build-tool-checker.js +1 -9
- package/dist/engine/config-health/ci-commands-collector.d.ts +2 -1
- package/dist/engine/config-health/ci-commands-collector.js +2 -9
- package/dist/engine/config-health/go-checker.js +1 -9
- package/dist/engine/config-health/mcp-config-checker.js +2 -10
- package/dist/engine/config-health/python-checker.js +1 -9
- package/dist/engine/config-health/rust-checker.js +1 -9
- package/dist/engine/config-health/ts-checker-scripts.js +1 -9
- package/dist/engine/config-health/ts-checker.js +1 -9
- package/dist/engine/context-artifacts/store.js +1 -0
- package/dist/engine/context-md-generator.js +1 -0
- package/dist/engine/context-orchestrator/index.js +2 -0
- package/dist/engine/convention-scanner/convention-parser.js +2 -9
- package/dist/engine/cost-guardrails.js +1 -0
- package/dist/engine/cost-tracking/ledger.js +1 -0
- package/dist/engine/criterion-identity.js +1 -1
- package/dist/engine/dashboard/data-loader.js +1 -0
- package/dist/engine/dashboard/drift-score.js +2 -0
- package/dist/engine/dashboard/spec-updater.d.ts +3 -1
- package/dist/engine/dashboard/spec-updater.js +9 -2
- package/dist/engine/dashboard/templates-layout.d.ts +2 -2
- package/dist/engine/dashboard/templates-layout.js +2 -9
- package/dist/engine/data-projects-gc/gc-runner.js +2 -4
- package/dist/engine/deleter/audit-logger.js +1 -0
- package/dist/engine/deleter/core.js +6 -0
- package/dist/engine/deleter/trash-manager.js +1 -0
- package/dist/engine/desktop-detector.js +1 -9
- package/dist/engine/detection-utils.d.ts +2 -1
- package/dist/engine/detection-utils.js +3 -10
- package/dist/engine/detectors/advanced-framework-detector/helpers.d.ts +3 -2
- package/dist/engine/detectors/advanced-framework-detector/helpers.js +3 -17
- package/dist/engine/detectors/cicd-detector.js +2 -10
- package/dist/engine/detectors/css-framework-detector.js +2 -10
- package/dist/engine/detectors/deployment-detector.js +3 -12
- package/dist/engine/detectors/frontend-perf-detector.js +2 -10
- package/dist/engine/detectors/gitops-detector.js +3 -11
- package/dist/engine/detectors/idp-detector.js +1 -3
- package/dist/engine/detectors/k3s-detector.js +3 -11
- package/dist/engine/detectors/llm-detector/file-readers.d.ts +2 -1
- package/dist/engine/detectors/llm-detector/file-readers.js +2 -9
- package/dist/engine/detectors/mfe-detector.js +5 -13
- package/dist/engine/detectors/monitoring-detector.js +2 -11
- package/dist/engine/detectors/monorepo-detector.d.ts +1 -0
- package/dist/engine/detectors/monorepo-detector.js +1 -10
- package/dist/engine/detectors/nomad-detector.js +3 -11
- package/dist/engine/detectors/otel-ecosystem-detectors.d.ts +2 -1
- package/dist/engine/detectors/otel-ecosystem-detectors.js +2 -10
- package/dist/engine/doc-generator/executive-summary/html-template.js +1 -7
- package/dist/engine/doc-generator/executive-summary/section-builders.js +1 -7
- package/dist/engine/doc-generator/per-spec-report/mermaid-renderer.js +1 -7
- package/dist/engine/doc-generator/per-spec-report/spec-section-builders.js +1 -7
- package/dist/engine/doc-generator/per-spec-report/technical-report.js +1 -7
- package/dist/engine/doc-generator/portal/analytics-page.js +1 -7
- package/dist/engine/doc-generator/portal/architecture-page.js +1 -7
- package/dist/engine/doc-generator/portal/changelog-page.js +1 -7
- package/dist/engine/doc-generator/portal/decision-page.js +1 -7
- package/dist/engine/doc-generator/portal/decision-timeline-builder.js +1 -7
- package/dist/engine/doc-generator/portal/kanban-view-builder.js +1 -7
- package/dist/engine/doc-generator/portal/portal-breadcrumbs.js +1 -7
- package/dist/engine/doc-generator/portal/portal-landing-cards.js +1 -7
- package/dist/engine/doc-generator/portal/portal-navbar.js +1 -7
- package/dist/engine/doc-generator/portal/portal-page-detector.d.ts +3 -0
- package/dist/engine/doc-generator/portal/portal-page-detector.js +1 -10
- package/dist/engine/doc-generator/portal/portal-regenerator.js +2 -0
- package/dist/engine/doc-generator/portal/risk-matrix-svg.js +1 -7
- package/dist/engine/doc-generator/portal/risk-page.js +1 -7
- package/dist/engine/doc-generator/portal/roadmap-page.js +1 -7
- package/dist/engine/doc-generator/proposal/proposal-gantt-builder.js +1 -7
- package/dist/engine/doc-generator/proposal/proposal-kpi-builder.js +1 -7
- package/dist/engine/doc-generator/proposal/proposal-section-builders-advanced.js +2 -8
- package/dist/engine/doc-generator/proposal/proposal-section-builders.js +1 -7
- package/dist/engine/docs-site-generator/html-templates.js +1 -7
- package/dist/engine/docs-site-generator/markdown-renderer.js +1 -7
- package/dist/engine/drift/violation-resolver.js +2 -0
- package/dist/engine/dynamic-knowledge/knowledge-cache.js +1 -0
- package/dist/engine/ecosystem-absorber/knowledge-cache.js +1 -0
- package/dist/engine/edge-db-detector.js +1 -10
- package/dist/engine/escalator/retry-counter.js +1 -0
- package/dist/engine/evidence-gates/artifact-reader.js +1 -0
- package/dist/engine/evidence-gates/evidence-autofill.js +1 -0
- package/dist/engine/evidence-gates/evidence-skeletons.js +1 -0
- package/dist/engine/evidence-gates/reconciliation-freshness.js +1 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.js +1 -0
- package/dist/engine/execution/job-runtime.js +2 -0
- package/dist/engine/execution/validate-job-executor.d.ts +1 -1
- package/dist/engine/execution/validate-job-executor.js +3 -0
- package/dist/engine/execution/validate-job-payload.js +1 -0
- package/dist/engine/execution/validate-worker-thread.js +1 -0
- package/dist/engine/facilitate/context-loader.js +1 -0
- package/dist/engine/figma/change-detector.d.ts +1 -8
- package/dist/engine/figma/code-connect-fetcher.d.ts +1 -7
- package/dist/engine/figma/design-enricher.d.ts +1 -17
- package/dist/engine/figma/design-enricher.js +0 -1
- package/dist/engine/figma/e2e-generator.d.ts +1 -23
- package/dist/engine/figma/flow-analyzer.d.ts +1 -11
- package/dist/engine/figma/frame-extractor.d.ts +1 -11
- package/dist/engine/figma/frame-extractor.js +3 -0
- package/dist/engine/figma/multi-file-manager.d.ts +1 -6
- package/dist/engine/figma/spec-generator.js +2 -0
- package/dist/engine/figma/thumbnail-fetcher.d.ts +1 -1
- package/dist/engine/figma/token-extractor.d.ts +1 -6
- package/dist/engine/figma/token-extractor.js +0 -1
- package/dist/engine/figma/version-tracker.d.ts +1 -7
- package/dist/engine/figma/version-tracker.js +0 -1
- package/dist/engine/figma/visual-qa.d.ts +5 -19
- package/dist/engine/figma/visual-qa.js +1 -2
- package/dist/engine/figma/webhook-manager.d.ts +1 -7
- package/dist/engine/frontmatter-sha/reseal.js +1 -0
- package/dist/engine/frontmatter-sha/verify-terminal.js +1 -0
- package/dist/engine/git-hook-injector.js +2 -10
- package/dist/engine/github/quality-dimensions.js +1 -3
- package/dist/engine/global-rules-manager.js +2 -3
- package/dist/engine/handoff-artifacts/implementation-review-reader.js +1 -0
- package/dist/engine/handoff-artifacts/io.js +2 -0
- package/dist/engine/handoff-packager.js +2 -1
- package/dist/engine/health/auto-fixer.js +1 -0
- package/dist/engine/hooks/context-injector.js +1 -0
- package/dist/engine/hooks-reconciler.js +1 -8
- package/dist/engine/impact-detector/index.js +2 -9
- package/dist/engine/implementation-contract/common.js +1 -3
- package/dist/engine/implementation-contract/evaluator.js +1 -3
- package/dist/engine/keyword-matcher/boundary.d.ts +2 -7
- package/dist/engine/keyword-matcher/boundary.js +2 -14
- package/dist/engine/lifecycle-reconciliation-io.js +1 -0
- package/dist/engine/lifecycle-reconciliation.js +3 -0
- package/dist/engine/local-first/detector.js +1 -9
- package/dist/engine/marketplace-fetcher/cache.js +2 -0
- package/dist/engine/marketplace-fetcher/index.js +1 -0
- package/dist/engine/mcp-config/mcp-config-writer.js +2 -10
- package/dist/engine/migrations/remove-commercial-state.js +2 -0
- package/dist/engine/mobile-detector-shared.d.ts +1 -1
- package/dist/engine/mobile-detector-shared.js +2 -9
- package/dist/engine/multi-channel-notifier.js +1 -0
- package/dist/engine/multi-teammate-review/disagreement-counter.js +1 -0
- package/dist/engine/multi-teammate-review/panel-orchestrator.js +1 -0
- package/dist/engine/onboarding-engine.js +1 -9
- package/dist/engine/permissions-merger/stack-detectors.js +2 -10
- package/dist/engine/pii-detector/core.js +1 -3
- package/dist/engine/platform-engineering/dx-analyzer.js +1 -10
- package/dist/engine/platform-engineering/idp-detector.js +2 -10
- package/dist/engine/project-dna/ai-tool-detector.js +2 -10
- package/dist/engine/project-dna/stack-detector.js +2 -10
- package/dist/engine/project-graph/builder.js +11 -2
- package/dist/engine/project-graph/cache.d.ts +5 -2
- package/dist/engine/project-graph/cache.js +174 -34
- package/dist/engine/project-graph/extractors/decision-store-extractor.js +1 -0
- package/dist/engine/project-graph/freshness-projection.js +3 -0
- package/dist/engine/project-graph/query.js +14 -11
- package/dist/engine/project-health-checker.js +2 -6
- package/dist/engine/provider-adapters/shared/spec-loader.js +1 -0
- package/dist/engine/quality-gates/gate-evaluator.js +1 -3
- package/dist/engine/react-detector.js +6 -14
- package/dist/engine/reconcile/apply-changes.js +1 -3
- package/dist/engine/registry/core.js +1 -0
- package/dist/engine/registry/loader.js +2 -0
- package/dist/engine/release/postmortem-generator.js +1 -0
- package/dist/engine/release/rollback-runner.d.ts +2 -2
- package/dist/engine/release/stuck-spec-detector.js +7 -0
- package/dist/engine/release-pipeline/release-spec-closer.js +3 -0
- package/dist/engine/rules-reconciler.d.ts +1 -1
- package/dist/engine/rules-reconciler.js +2 -9
- package/dist/engine/safety/atomic-writer.js +1 -0
- package/dist/engine/safety/cross-process-lock.js +2 -0
- package/dist/engine/safety/file-mutex.js +1 -0
- package/dist/engine/safety/lock-lease-store.js +1 -0
- package/dist/engine/safety/lock-scavenger.js +2 -0
- package/dist/engine/saga/transition-cascade.js +3 -0
- package/dist/engine/scan-project/index.js +1 -0
- package/dist/engine/scan-project/module-discoverer.js +1 -9
- package/dist/engine/schema-parity-auditor/handler-checker.js +1 -3
- package/dist/engine/schema-parity-auditor/index.js +1 -3
- package/dist/engine/schema-parity-auditor/type-checker.js +1 -3
- package/dist/engine/self-healing/strategies/coverage-fix.js +2 -10
- package/dist/engine/session-context-generator.d.ts +8 -0
- package/dist/engine/session-context-generator.js +33 -23
- package/dist/engine/session-state/session-artifact-refresher.d.ts +7 -0
- package/dist/engine/session-state/session-artifact-refresher.js +140 -0
- package/dist/engine/session-state/writer.d.ts +3 -0
- package/dist/engine/session-state/writer.js +35 -17
- package/dist/engine/shared-agent-memory.js +1 -0
- package/dist/engine/skill-adapter/index.js +3 -0
- package/dist/engine/skill-bootstrap/registry-fetcher.js +1 -0
- package/dist/engine/skill-bootstrap/skill-writer.js +2 -9
- package/dist/engine/skill-bootstrap/stack-matcher.js +1 -9
- package/dist/engine/skill-discovery/multi-agent-writer.d.ts +1 -0
- package/dist/engine/skill-discovery/multi-agent-writer.js +1 -9
- package/dist/engine/skill-generator/workflow-skill-generator.js +1 -0
- package/dist/engine/skill-registry/ttl-refresh.js +2 -0
- package/dist/engine/spec-audit/index.js +2 -0
- package/dist/engine/spec-audit/report-writer.js +1 -0
- package/dist/engine/spec-coverage/core.js +1 -0
- package/dist/engine/spec-decomposer/analyzer.js +1 -11
- package/dist/engine/spec-dependency-graph/dot-exporter.d.ts +1 -1
- package/dist/engine/spec-dependency-graph/graph-builder.d.ts +1 -20
- package/dist/engine/spec-dependency-graph/superseded-set.d.ts +1 -1
- package/dist/engine/spec-diff-engine.js +1 -7
- package/dist/engine/spec-format/read-technical-section.js +1 -3
- package/dist/engine/spec-format/replace-section.js +1 -3
- package/dist/engine/spec-format/spec-id.d.ts +9 -1
- package/dist/engine/spec-format/spec-id.js +24 -3
- package/dist/engine/spec-format/unified-spec-builder.js +1 -3
- package/dist/engine/spec-migrator/canonical-deduplicator.js +2 -0
- package/dist/engine/spec-observability/tracker.js +1 -0
- package/dist/engine/spec-registry/adapter.js +2 -10
- package/dist/engine/spec-registry/validator.d.ts +1 -0
- package/dist/engine/spec-registry/validator.js +1 -9
- package/dist/engine/spec-state-machine/transition-spec.js +1 -0
- package/dist/engine/spec-templates/custom-loader.js +1 -0
- package/dist/engine/stack-auditor/build-tool-auditor.js +1 -9
- package/dist/engine/staleness/stale-implementing.js +5 -14
- package/dist/engine/status-reconciler/index.js +4 -1
- package/dist/engine/structural-memory/helpers.js +1 -0
- package/dist/engine/supply-chain/slsa-checker.js +1 -9
- package/dist/engine/tdd-enforcer/stub-artifact-path.js +1 -0
- package/dist/engine/telemetry/health-checker.js +1 -0
- package/dist/engine/telemetry/telemetry-store.js +1 -0
- package/dist/engine/token-optimizer/response-cache.js +1 -3
- package/dist/engine/tool-groups/group-manager.js +2 -0
- package/dist/engine/update-notifier.js +1 -0
- package/dist/engine/validation/approved-spec-portability.js +1 -0
- package/dist/engine/validation/durable-validation.js +1 -0
- package/dist/engine/validation/validation-freshness.js +2 -0
- package/dist/engine/validation/validation-receipt.js +1 -0
- package/dist/engine/validation/validation-submission.d.ts +1 -1
- package/dist/engine/validation-evidence-ledger.js +1 -0
- package/dist/engine/validator/deep-code-checker.js +1 -3
- package/dist/engine/validator/executable-evidence.d.ts +1 -14
- package/dist/engine/validator/scope-resolver.d.ts +2 -2
- package/dist/engine/validator/spec-compliance-runner.d.ts +1 -31
- package/dist/engine/validator/validation-report-writer.js +1 -1
- package/dist/engine/validator.d.ts +1 -1
- package/dist/engine/validator.js +1 -0
- package/dist/engine/velocity/measure-velocity.js +2 -0
- package/dist/engine/version-resolver.js +1 -0
- package/dist/engine/workers/handlers/auto-drift.js +3 -0
- package/dist/engine/workspace-manager.js +4 -0
- package/dist/hosts/gemini/config-scaffold.js +2 -10
- package/dist/storage/approval-operation-lock.js +1 -0
- package/dist/storage/auto-promoter-config-store.js +1 -0
- package/dist/storage/autopilot-log-store.js +1 -0
- package/dist/storage/base-store.js +1 -0
- package/dist/storage/checkpoint-store.js +1 -0
- package/dist/storage/feedback-remote.js +1 -0
- package/dist/storage/gaps-log.js +1 -0
- package/dist/storage/global-projects-store.js +1 -0
- package/dist/storage/global-store.js +1 -0
- package/dist/storage/knowledge-store/sessions.js +2 -0
- package/dist/storage/migrations/canonical-storage.js +42 -18
- package/dist/storage/project-drift-store.js +1 -0
- package/dist/storage/project-identity.js +1 -0
- package/dist/storage/project-resolver.js +1 -17
- package/dist/storage/runtime-db.d.ts +2 -20
- package/dist/storage/runtime-db.js +2 -9
- package/dist/storage/semantic-index-store.js +1 -0
- package/dist/storage/sentry-store.js +1 -0
- package/dist/storage/session-state-store.js +1 -0
- package/dist/storage/spec-store.d.ts +7 -0
- package/dist/storage/spec-store.js +21 -1
- package/dist/storage/status-store/atomic-status-write.js +1 -0
- package/dist/storage/status-store/file-lock.js +1 -0
- package/dist/storage/status-store/self-healing.js +1 -0
- package/dist/storage/storage-bundle.d.ts +12 -2
- package/dist/storage/supabase-store.js +1 -0
- package/dist/storage/technology-selection-store.js +1 -0
- package/dist/storage/trash-store.d.ts +2 -4
- package/dist/storage/trash-store.js +2 -15
- package/dist/storage/vector-store/json-fallback.js +1 -0
- package/dist/storage/vector-store/migrator.js +1 -0
- package/dist/storage/vector-store/sqlite-adapter.js +1 -0
- package/dist/tools/audit-claude-config.js +1 -10
- package/dist/tools/check-readiness.js +104 -30
- package/dist/tools/clarify-requirements/multiple-choice.d.ts +3 -3
- package/dist/tools/configure-oauth-handler.js +1 -0
- package/dist/tools/create-skill.js +11 -9
- package/dist/tools/create-spec-helpers.d.ts +1 -3
- package/dist/tools/create-spec-helpers.js +1 -8
- package/dist/tools/create-spec.js +1 -13
- package/dist/tools/dashboard.js +5 -0
- package/dist/tools/github-pr-handler.js +1 -0
- package/dist/tools/github-release-handler.d.ts +1 -0
- package/dist/tools/github-release-handler.js +4 -3
- package/dist/tools/graph-specs.d.ts +1 -1
- package/dist/tools/heal-spec-docs.js +1 -3
- package/dist/tools/init-project/git-setup.d.ts +2 -2
- package/dist/tools/init-project/host-assets-writer.js +9 -10
- package/dist/tools/init-project/lifecycle-helpers.d.ts +2 -2
- package/dist/tools/init-project/lint-scaffolder.js +2 -10
- package/dist/tools/init-project/stack-detector.d.ts +2 -2
- package/dist/tools/reconcile-interactive-question-hooks.d.ts +2 -2
- package/dist/tools/register-sdd-tools.js +1 -0
- package/dist/tools/safe-handler.js +1 -0
- package/dist/tools/schemas/spec-id.d.ts +1 -6
- package/dist/tools/schemas/spec-id.js +1 -16
- package/dist/tools/tool-entry.d.ts +2 -2
- package/dist/tools/tool-entry.js +1 -1
- package/dist/tools/tool-registry/core-tools.d.ts +2 -2
- package/dist/tools/tool-registry/deprecated-stubs.d.ts +3 -3
- package/dist/tools/tool-registry/deprecated-stubs.js +1 -1
- package/dist/tools/triage-request.d.ts +2 -2
- package/dist/tools/update-status/approval-gates.d.ts +2 -2
- package/dist/tools/update-status/approval-gates.js +1 -0
- package/dist/tools/update-status/dod-gates.d.ts +1 -1
- package/dist/tools/update-status/done-receipt-verifier.d.ts +1 -1
- package/dist/tools/update-status/side-effects.js +5 -0
- package/dist/tools/update-status-actions.js +28 -40
- package/dist/tools/validate-graph-coverage.js +14 -2
- package/dist/tools/validate.js +2 -0
- package/dist/transports/middleware/types.d.ts +3 -3
- package/dist/types/atomic-upgrade.d.ts +1 -1
- package/dist/types/cascade-hooks.d.ts +3 -0
- package/dist/types/dashboard.d.ts +4 -1
- package/dist/types/durable-job.d.ts +20 -0
- package/dist/types/durable-job.js +9 -1
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types/installation.d.ts +16 -0
- package/dist/types/installation.js +2 -0
- package/dist/types/project-knowledge-graph.d.ts +11 -0
- package/dist/types/session-checkpoint.d.ts +16 -0
- package/dist/types/spec-dependency-graph.d.ts +21 -0
- package/dist/types/spec-dependency-graph.js +2 -0
- package/dist/types/universal-rules/index.d.ts +1 -0
- package/dist/types/validation-evidence.d.ts +45 -0
- package/package.json +16 -16
- package/planu-plugin.json +1 -1
- package/dist/types/storage-bundle.d.ts +0 -13
- package/dist/types/storage-bundle.js +0 -2
|
@@ -4,22 +4,64 @@ import { isAbsolute } from 'node:path';
|
|
|
4
4
|
import { specStore } from '../storage/index.js';
|
|
5
5
|
import { resolveVerifiedSpecPath } from '../storage/project-identity.js';
|
|
6
6
|
import { buildCheckReadinessSummary } from '../engine/human-summary.js';
|
|
7
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
7
8
|
import { validateSpecFormat } from '../core/spec-validator.js';
|
|
8
9
|
import { parseFrontmatter } from '../engine/frontmatter-parser.js';
|
|
9
10
|
import { resolveProjectId } from './resolve-project-id.js';
|
|
10
11
|
const VALID_DIFFICULTIES = [1, 2, 3, 4, 5];
|
|
11
12
|
const VALID_SCOPES = ['trivial', 'feature', 'cross-module', 'architectural'];
|
|
13
|
+
const VALID_SPEC_TYPES = [
|
|
14
|
+
'feature',
|
|
15
|
+
'refactor',
|
|
16
|
+
'bugfix',
|
|
17
|
+
'infra',
|
|
18
|
+
'docs',
|
|
19
|
+
'project',
|
|
20
|
+
'agent',
|
|
21
|
+
'tech-debt',
|
|
22
|
+
];
|
|
23
|
+
const VALID_SPEC_TARGETS = [
|
|
24
|
+
'frontend',
|
|
25
|
+
'backend',
|
|
26
|
+
'shared',
|
|
27
|
+
'fullstack',
|
|
28
|
+
'infrastructure',
|
|
29
|
+
'database',
|
|
30
|
+
'ios',
|
|
31
|
+
'android',
|
|
32
|
+
];
|
|
12
33
|
function asDifficulty(value) {
|
|
13
34
|
return VALID_DIFFICULTIES.find((candidate) => candidate === value);
|
|
14
35
|
}
|
|
15
36
|
function asSpecScope(value) {
|
|
16
37
|
return VALID_SCOPES.find((candidate) => candidate === value);
|
|
17
38
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
39
|
+
function asSpecType(value) {
|
|
40
|
+
return VALID_SPEC_TYPES.find((candidate) => candidate === value);
|
|
41
|
+
}
|
|
42
|
+
function asSpecTarget(value) {
|
|
43
|
+
return VALID_SPEC_TARGETS.find((candidate) => candidate === value);
|
|
44
|
+
}
|
|
45
|
+
function asStringTags(value) {
|
|
46
|
+
return Array.isArray(value) ? value.filter((tag) => typeof tag === 'string') : [];
|
|
47
|
+
}
|
|
48
|
+
async function synthesizeSpecFromDiscoveredPath(specId, discoveredPath) {
|
|
49
|
+
const raw = await readFile(discoveredPath, 'utf-8');
|
|
50
|
+
const { metadata } = parseFrontmatter(raw);
|
|
51
|
+
return {
|
|
52
|
+
id: specId,
|
|
53
|
+
specPath: discoveredPath,
|
|
54
|
+
difficulty: asDifficulty(metadata.difficulty) ?? 3,
|
|
55
|
+
tags: asStringTags(metadata.tags),
|
|
56
|
+
dependencies: [],
|
|
57
|
+
scope: asSpecScope(metadata.scope) ?? 'feature',
|
|
58
|
+
target: asSpecTarget(metadata.target) ?? 'backend',
|
|
59
|
+
type: asSpecType(metadata.type) ?? 'feature',
|
|
60
|
+
title: typeof metadata.title === 'string' && metadata.title.trim().length > 0
|
|
61
|
+
? metadata.title
|
|
62
|
+
: specId,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
23
65
|
async function readFreshDifficultyAndScope(specId, specPath, projectPath) {
|
|
24
66
|
try {
|
|
25
67
|
const resolvedPath = projectPath
|
|
@@ -43,8 +85,12 @@ async function resolveEffectiveSpecPath(specId, specPath, projectPath) {
|
|
|
43
85
|
try {
|
|
44
86
|
return await resolveVerifiedSpecPath(specId, specPath, projectPath);
|
|
45
87
|
}
|
|
46
|
-
catch {
|
|
47
|
-
|
|
88
|
+
catch (error) {
|
|
89
|
+
const discovered = await specStore.discoverCanonicalSpecPath(specId, projectPath);
|
|
90
|
+
if (discovered === null) {
|
|
91
|
+
throw error;
|
|
92
|
+
}
|
|
93
|
+
return discovered;
|
|
48
94
|
}
|
|
49
95
|
}
|
|
50
96
|
// ── Formatting helpers ───────────────────────────────────────────────────────
|
|
@@ -165,30 +211,58 @@ export async function handleCheckReadiness(args) {
|
|
|
165
211
|
}
|
|
166
212
|
const { specId, mode = 'strict' } = args;
|
|
167
213
|
const spec = await specStore.getSpecFresh(projectId, specId, args.projectPath);
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
214
|
+
let effectiveSpec;
|
|
215
|
+
if (spec) {
|
|
216
|
+
const fresh = spec.specPath
|
|
217
|
+
? await readFreshDifficultyAndScope(spec.id, spec.specPath, args.projectPath)
|
|
218
|
+
: {};
|
|
219
|
+
let resolvedSpecPath = spec.specPath;
|
|
220
|
+
if (spec.specPath) {
|
|
221
|
+
try {
|
|
222
|
+
resolvedSpecPath = await resolveEffectiveSpecPath(spec.id, spec.specPath, args.projectPath);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
226
|
+
return {
|
|
227
|
+
content: [
|
|
228
|
+
{
|
|
229
|
+
type: 'text',
|
|
230
|
+
text: `Spec '${specId}' path could not be resolved: ${reason}`,
|
|
231
|
+
},
|
|
232
|
+
],
|
|
233
|
+
isError: true,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
effectiveSpec = {
|
|
238
|
+
id: spec.id,
|
|
239
|
+
specPath: resolvedSpecPath,
|
|
240
|
+
difficulty: fresh.difficulty ?? spec.difficulty,
|
|
241
|
+
scope: fresh.scope ?? spec.scope,
|
|
242
|
+
target: spec.target,
|
|
243
|
+
type: spec.type,
|
|
244
|
+
title: spec.title,
|
|
245
|
+
tags: spec.tags,
|
|
246
|
+
dependencies: spec.dependencies,
|
|
177
247
|
};
|
|
178
248
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
249
|
+
else {
|
|
250
|
+
const discoveredPath = args.projectPath
|
|
251
|
+
? await specStore.discoverCanonicalSpecPath(specId, args.projectPath)
|
|
252
|
+
: null;
|
|
253
|
+
if (!discoveredPath) {
|
|
254
|
+
return {
|
|
255
|
+
content: [
|
|
256
|
+
{
|
|
257
|
+
type: 'text',
|
|
258
|
+
text: `Spec '${specId}' not found in project '${projectId}'`,
|
|
259
|
+
},
|
|
260
|
+
],
|
|
261
|
+
isError: true,
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
effectiveSpec = await synthesizeSpecFromDiscoveredPath(specId, discoveredPath);
|
|
265
|
+
}
|
|
192
266
|
// validateSpecFormat owns the readiness and quality evaluation so the response
|
|
193
267
|
// cannot combine separately computed evidence from different reads of spec.md.
|
|
194
268
|
const validationResult = await validateSpecFormat(effectiveSpec, { readinessMode: mode });
|
|
@@ -197,7 +271,7 @@ export async function handleCheckReadiness(args) {
|
|
|
197
271
|
// report — MISSING_FRONTMATTER due to file-not-found is best-effort since
|
|
198
272
|
// the readiness checker already handles missing files gracefully.
|
|
199
273
|
const vr = validationResult;
|
|
200
|
-
const report = vr.readinessReport ?? createFailClosedReport(
|
|
274
|
+
const report = vr.readinessReport ?? createFailClosedReport(effectiveSpec.id, mode);
|
|
201
275
|
const hardFormatErrors = vr.errors.filter((e) => e.code !== 'MISSING_FRONTMATTER' && !(e.code === 'READINESS_CHECK_FAILED'));
|
|
202
276
|
const hardFormatMessages = hardFormatErrors.map((e) => e.message);
|
|
203
277
|
const formatWarnings = vr.warnings
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ClarificationQuestion } from '../../types/index.js';
|
|
2
2
|
/** Detected stack info from package files in the project directory. */
|
|
3
|
-
export interface
|
|
3
|
+
export interface ClarifyStackDetectionResult {
|
|
4
4
|
framework: string | null;
|
|
5
5
|
language: string | null;
|
|
6
6
|
database: string | null;
|
|
@@ -11,12 +11,12 @@ export interface StackDetectionResult {
|
|
|
11
11
|
* Detect the project stack by reading package.json and/or requirements.txt
|
|
12
12
|
* from the given project path.
|
|
13
13
|
*/
|
|
14
|
-
export declare function detectStack(projectPath: string): Promise<
|
|
14
|
+
export declare function detectStack(projectPath: string): Promise<ClarifyStackDetectionResult>;
|
|
15
15
|
/**
|
|
16
16
|
* Returns true if the question should be skipped because the stack already
|
|
17
17
|
* provides a definitive answer.
|
|
18
18
|
*/
|
|
19
|
-
export declare function shouldSkipQuestion(question: ClarificationQuestion, stack:
|
|
19
|
+
export declare function shouldSkipQuestion(question: ClarificationQuestion, stack: ClarifyStackDetectionResult): boolean;
|
|
20
20
|
/**
|
|
21
21
|
* Attaches structured `options[]` to a question based on its content.
|
|
22
22
|
* Each question gets 3-8 concrete choices + 'Other: ___' fallback.
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// configure-oauth-handler.ts — Handler for the configure_oauth MCP tool (SPEC-161).
|
|
2
2
|
// Reads and displays the current OAuth config status (without exposing secrets).
|
|
3
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
3
4
|
import { loadOAuthConfig, extractBearerToken, validateToken, } from '../transports/oauth-validator.js';
|
|
4
5
|
function buildStatusLines(config) {
|
|
5
6
|
const exampleCurl = config.enabled
|
|
@@ -26,14 +26,14 @@ function resolveHost(input) {
|
|
|
26
26
|
// ---------------------------------------------------------------------------
|
|
27
27
|
// Writers per host
|
|
28
28
|
// ---------------------------------------------------------------------------
|
|
29
|
-
async function writeSkillForClaudeCode(name, content, description, projectPath, overwrite) {
|
|
29
|
+
async function writeSkillForClaudeCode(name, content, description, projectPath, overwrite, managedByPlanu) {
|
|
30
30
|
const dirPath = join(projectPath, '.claude', 'skills', name);
|
|
31
31
|
const skillFilePath = join(dirPath, 'SKILL.md');
|
|
32
32
|
// Overwrite protection
|
|
33
33
|
try {
|
|
34
34
|
const existing = await readFile(skillFilePath, 'utf-8');
|
|
35
35
|
const existingHash = hashContent(existing);
|
|
36
|
-
const newContent = buildSkillMd(name, description, content);
|
|
36
|
+
const newContent = buildSkillMd(name, description, content, managedByPlanu);
|
|
37
37
|
const newHash = hashContent(newContent);
|
|
38
38
|
if (existingHash !== newHash && !overwrite) {
|
|
39
39
|
throw new Error(`Skill already exists at ${skillFilePath}. Pass overwriteExisting: true to replace.`);
|
|
@@ -46,13 +46,14 @@ async function writeSkillForClaudeCode(name, content, description, projectPath,
|
|
|
46
46
|
// File doesn't exist — proceed
|
|
47
47
|
}
|
|
48
48
|
await mkdir(dirPath, { recursive: true });
|
|
49
|
-
const skillContent = buildSkillMd(name, description, content);
|
|
49
|
+
const skillContent = buildSkillMd(name, description, content, managedByPlanu);
|
|
50
50
|
await writeFile(skillFilePath, skillContent, 'utf-8');
|
|
51
51
|
return { dirPath, skillFilePath };
|
|
52
52
|
}
|
|
53
|
-
function buildSkillMd(name, description, body) {
|
|
53
|
+
function buildSkillMd(name, description, body, managedByPlanu) {
|
|
54
54
|
const desc = description.length > 0 ? description : `Auto-generated skill: ${name}`;
|
|
55
|
-
|
|
55
|
+
const managedByLine = managedByPlanu ? 'managed-by: planu\n' : '';
|
|
56
|
+
return `---\nname: ${name}\ndescription: "${desc}"\n${managedByLine}---\n\n${body}\n`;
|
|
56
57
|
}
|
|
57
58
|
async function writeSkillForCodex(name, content, description, projectPath) {
|
|
58
59
|
// For Codex, append to AGENTS.md with markers
|
|
@@ -80,13 +81,13 @@ async function writeSkillForCodex(name, content, description, projectPath) {
|
|
|
80
81
|
await writeFile(agentsMdPath, updated, 'utf-8');
|
|
81
82
|
return { dirPath: projectPath, skillFilePath: agentsMdPath };
|
|
82
83
|
}
|
|
83
|
-
async function writeSkillForGemini(name, content, description, projectPath) {
|
|
84
|
+
async function writeSkillForGemini(name, content, description, projectPath, managedByPlanu) {
|
|
84
85
|
const geminiDir = join(projectPath, '.gemini');
|
|
85
86
|
const skillsDir = join(geminiDir, 'skills');
|
|
86
87
|
await mkdir(skillsDir, { recursive: true });
|
|
87
88
|
const skillFilePath = join(skillsDir, `${name}.md`);
|
|
88
89
|
const desc = description.length > 0 ? description : name;
|
|
89
|
-
const skillContent = buildSkillMd(name, desc, content);
|
|
90
|
+
const skillContent = buildSkillMd(name, desc, content, managedByPlanu);
|
|
90
91
|
await writeFile(skillFilePath, skillContent, 'utf-8');
|
|
91
92
|
return { dirPath: skillsDir, skillFilePath };
|
|
92
93
|
}
|
|
@@ -96,6 +97,7 @@ async function writeSkillForGemini(name, content, description, projectPath) {
|
|
|
96
97
|
export async function handleCreateSkill(input) {
|
|
97
98
|
const { projectPath, name, content, overwriteExisting } = input;
|
|
98
99
|
const description = input.description ?? '';
|
|
100
|
+
const managedByPlanu = input.managedByPlanu === true;
|
|
99
101
|
const host = resolveHost(input);
|
|
100
102
|
const languageValidation = validateEnglishOnlyArtifactText(`${name}\n\n${description}\n\n${content}`, 'skill');
|
|
101
103
|
if (!languageValidation.ok) {
|
|
@@ -121,13 +123,13 @@ export async function handleCreateSkill(input) {
|
|
|
121
123
|
try {
|
|
122
124
|
switch (host) {
|
|
123
125
|
case 'claude-code':
|
|
124
|
-
result = await writeSkillForClaudeCode(name, content, description, projectPath, overwriteExisting === true);
|
|
126
|
+
result = await writeSkillForClaudeCode(name, content, description, projectPath, overwriteExisting === true, managedByPlanu);
|
|
125
127
|
break;
|
|
126
128
|
case 'codex':
|
|
127
129
|
result = await writeSkillForCodex(name, content, description, projectPath);
|
|
128
130
|
break;
|
|
129
131
|
case 'gemini':
|
|
130
|
-
result = await writeSkillForGemini(name, content, description, projectPath);
|
|
132
|
+
result = await writeSkillForGemini(name, content, description, projectPath, managedByPlanu);
|
|
131
133
|
break;
|
|
132
134
|
}
|
|
133
135
|
}
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import type { GitSetupResult, GitAutoSetupOptions } from '../types/index.js';
|
|
2
|
+
export { generateSpecId } from '../engine/spec-format/spec-id.js';
|
|
2
3
|
export declare function slugify(text: string): string;
|
|
3
|
-
export declare function generateSpecId(existingSpecs: {
|
|
4
|
-
id: string;
|
|
5
|
-
}[]): string;
|
|
6
4
|
export declare function generateBranchName(specId: string, slug: string, type: string): string;
|
|
7
5
|
/** Try auto-setup git branch. Returns result or undefined on failure. */
|
|
8
6
|
export declare function tryAutoSetupGit(projectId: string, specId: string, options?: GitAutoSetupOptions): Promise<GitSetupResult | undefined>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { handleAutoSetup } from './git/branch-ops.js';
|
|
2
|
+
export { generateSpecId } from '../engine/spec-format/spec-id.js';
|
|
2
3
|
export function slugify(text) {
|
|
3
4
|
return text
|
|
4
5
|
.toLowerCase()
|
|
@@ -8,14 +9,6 @@ export function slugify(text) {
|
|
|
8
9
|
.replace(/^-+|-+$/g, '')
|
|
9
10
|
.slice(0, 60);
|
|
10
11
|
}
|
|
11
|
-
export function generateSpecId(existingSpecs) {
|
|
12
|
-
const maxNum = existingSpecs.reduce((max, spec) => {
|
|
13
|
-
const match = /^SPEC-(\d+)$/.exec(spec.id);
|
|
14
|
-
const num = match?.[1] ? parseInt(match[1], 10) : 0;
|
|
15
|
-
return Math.max(max, num);
|
|
16
|
-
}, 0);
|
|
17
|
-
return `SPEC-${String(maxNum + 1).padStart(3, '0')}`;
|
|
18
|
-
}
|
|
19
12
|
const BRANCH_PREFIXES = {
|
|
20
13
|
feature: 'feat',
|
|
21
14
|
refactor: 'refactor',
|
|
@@ -6,6 +6,7 @@ import { readTechnologySelectionContract } from '../storage/technology-selection
|
|
|
6
6
|
import { toolResult, interactiveResult } from './response-helpers.js';
|
|
7
7
|
import { readFile, stat as fsStat } from 'node:fs/promises';
|
|
8
8
|
import { createHash, randomUUID } from 'node:crypto';
|
|
9
|
+
import { pathExistsByStat as pathExists } from '../core/shared/fs.js';
|
|
9
10
|
import { basename as pathBasename, dirname as pathDirname, isAbsolute as pathIsAbsolute, join as pathJoin, relative as pathRelative, sep as pathSeparator, } from 'node:path';
|
|
10
11
|
import { withFileLock } from '../storage/file-mutex.js';
|
|
11
12
|
import { generateBranchName } from './create-spec-helpers.js';
|
|
@@ -261,19 +262,6 @@ function isDerivedFromGroundedSource(testPath, modifyFiles) {
|
|
|
261
262
|
return testPath === `tests/${base}.test${ext}` || testPath === `tests/${withoutSrc}`;
|
|
262
263
|
});
|
|
263
264
|
}
|
|
264
|
-
async function pathExists(path) {
|
|
265
|
-
try {
|
|
266
|
-
const fs = await import('node:fs/promises');
|
|
267
|
-
if (typeof fs.stat !== 'function') {
|
|
268
|
-
return false;
|
|
269
|
-
}
|
|
270
|
-
await fs.stat(path);
|
|
271
|
-
return true;
|
|
272
|
-
}
|
|
273
|
-
catch {
|
|
274
|
-
return false;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
265
|
const HIGH_RISK_WARNING = 'High-risk spec — consider: ' +
|
|
278
266
|
'1) Is the approach technically feasible within the project constraints? ' +
|
|
279
267
|
'2) What edge cases (network failure, concurrent writes, empty state) could break this? ' +
|
package/dist/tools/dashboard.js
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
// tools/dashboard.ts — MCP tool handlers for start_dashboard and stop_dashboard.
|
|
2
2
|
import { startDashboardWithFallback, stopDashboardServer, registerCleanupHandlers, openBrowser, DEFAULT_DASHBOARD_PORT, } from '../engine/dashboard/server.js';
|
|
3
|
+
import { registerUpdateStatusHandler } from '../engine/dashboard/spec-updater.js';
|
|
4
|
+
import { handleUpdateStatus } from './update-status/index.js';
|
|
3
5
|
// Register process-exit cleanup once at module load time
|
|
4
6
|
registerCleanupHandlers();
|
|
7
|
+
// Wire the tools-layer status gate into the engine's dashboard status route
|
|
8
|
+
// (see engine/dashboard/spec-updater.ts — engine must not import tools/ directly).
|
|
9
|
+
registerUpdateStatusHandler(handleUpdateStatus);
|
|
5
10
|
/** Handle start_dashboard tool invocation */
|
|
6
11
|
export async function handleStartDashboard(args) {
|
|
7
12
|
const port = args.port ?? DEFAULT_DASHBOARD_PORT;
|
|
@@ -3,6 +3,7 @@ import { createPlatformClient, getCurrentBranch, getRemoteUrl } from '../engine/
|
|
|
3
3
|
import { detectAuth } from '../engine/github/auth.js';
|
|
4
4
|
import { generatePRTitle, generatePRBody } from '../engine/github/pr-template.js';
|
|
5
5
|
import { findLinkedPRs } from '../engine/github/spec-linker.js';
|
|
6
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
6
7
|
import { validateSpecFormat } from '../core/spec-validator.js';
|
|
7
8
|
import { readFile } from 'node:fs/promises';
|
|
8
9
|
import { runAbortableProcess } from '../engine/abortable-process-runner.js';
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ToolResult } from '../types/index.js';
|
|
2
2
|
import type { ExecFileFn } from '../types/github.js';
|
|
3
3
|
import type { EscalateResult } from '../types/escalator.js';
|
|
4
|
+
import './update-status/side-effects.js';
|
|
4
5
|
/**
|
|
5
6
|
* Returns a ToolResult error if stuck specs are detected and no bypass flag
|
|
6
7
|
* is set, or null if release may proceed. Handles autoFixDrift by closing
|
|
@@ -8,6 +8,8 @@ import { readFile, writeFile } from 'node:fs/promises';
|
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { promisify } from 'node:util';
|
|
10
10
|
import { withEscalation } from '../engine/escalator/with-escalation.js';
|
|
11
|
+
// Side-effect import: registers dispatchHookEvent on the cascade hook before runCascade() below.
|
|
12
|
+
import './update-status/side-effects.js';
|
|
11
13
|
const defaultExec = async (cmd, args) => {
|
|
12
14
|
return promisify(nodeExecFile)(cmd, args, { maxBuffer: 10 * 1024 * 1024 });
|
|
13
15
|
};
|
|
@@ -127,14 +129,13 @@ export async function handleCreateRelease(args, exec = defaultExec) {
|
|
|
127
129
|
draft: args.draft,
|
|
128
130
|
prerelease: args.prerelease,
|
|
129
131
|
});
|
|
130
|
-
// SPEC-496: Regenerate session context on release
|
|
131
132
|
try {
|
|
132
|
-
const {
|
|
133
|
+
const { refreshSessionArtifacts } = await import('../engine/session-state/session-artifact-refresher.js');
|
|
133
134
|
const releasePath = process.cwd();
|
|
134
135
|
const { resolveProjectIdOrAutoDetect } = await import('./resolve-project-id.js');
|
|
135
136
|
const resolved = await resolveProjectIdOrAutoDetect({ projectPath: releasePath });
|
|
136
137
|
if (resolved.ok) {
|
|
137
|
-
void
|
|
138
|
+
void refreshSessionArtifacts(releasePath, resolved.projectId).catch(() => {
|
|
138
139
|
/* best-effort */
|
|
139
140
|
});
|
|
140
141
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import {
|
|
2
|
+
import type { SpecGraph } from '../types/spec-dependency-graph.js';
|
|
3
3
|
export type GraphSpecsResult = {
|
|
4
4
|
format: 'json';
|
|
5
5
|
graph: SpecGraph;
|
|
@@ -12,6 +12,7 @@ import { jaccard } from '../engine/spec-format/jaccard.js';
|
|
|
12
12
|
import { replaceSectionInSpec } from '../engine/spec-format/replace-section.js';
|
|
13
13
|
import { executionRemove } from '../engine/execution/deadline-io.js';
|
|
14
14
|
import { buildMigrationDirective, scanLegacyArtifacts, } from '../engine/spec-migrator/legacy-classifier.js';
|
|
15
|
+
import { escapeRegex } from '../core/shared/strings.js';
|
|
15
16
|
const SPANISH_INDICATORS = [
|
|
16
17
|
'de',
|
|
17
18
|
'del',
|
|
@@ -112,9 +113,6 @@ function removeTopLevelSection(content, sectionName) {
|
|
|
112
113
|
}
|
|
113
114
|
return `${before}\n\n${after.trimEnd()}\n`;
|
|
114
115
|
}
|
|
115
|
-
function escapeRegex(input) {
|
|
116
|
-
return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
117
|
-
}
|
|
118
116
|
/** Local extraction of ## Technical body to avoid circular imports. */
|
|
119
117
|
function extractTechnicalBodyLocal(content) {
|
|
120
118
|
return extractSectionBodyLocal(content, 'Technical') ?? '';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export interface
|
|
1
|
+
export interface InitGitSetupResult {
|
|
2
2
|
hooksInstalled: string[];
|
|
3
3
|
gitFlowType: string;
|
|
4
4
|
gitignoreUpdated: boolean;
|
|
@@ -7,7 +7,7 @@ export interface GitSetupResult {
|
|
|
7
7
|
}
|
|
8
8
|
/** SPEC-001 + SPEC-539: Setup git hooks, detect branching model, and configure .gitignore.
|
|
9
9
|
* SPEC-539: Only installs hooks if a git repository is detected — never creates .git. */
|
|
10
|
-
export declare function runGitSetup(projectPath: string, projectId: string): Promise<
|
|
10
|
+
export declare function runGitSetup(projectPath: string, projectId: string): Promise<InitGitSetupResult>;
|
|
11
11
|
/** SPEC-466: Also exported for list_specs auto-cleanup. */
|
|
12
12
|
export declare function configureGitignoreForPlanu(projectPath: string): Promise<boolean>;
|
|
13
13
|
//# sourceMappingURL=git-setup.d.ts.map
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// tools/init-project/host-assets-writer.ts — Host-aware rules/skills installed by init_project
|
|
2
|
-
import {
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { detectHost } from '../../engine/host-detection/detect-host.js';
|
|
5
5
|
import { handleCreateSkill } from '../create-skill.js';
|
|
6
|
+
import { fileExists } from '../../core/shared/fs.js';
|
|
6
7
|
const CORE_SKILL_TEMPLATES = [
|
|
7
8
|
'planu-new-spec.md',
|
|
8
9
|
'planu-validate.md',
|
|
@@ -11,16 +12,10 @@ const CORE_SKILL_TEMPLATES = [
|
|
|
11
12
|
'planu-native.md',
|
|
12
13
|
'planu-multi-teammate-review.md',
|
|
13
14
|
'planu-context-assets.md',
|
|
15
|
+
'planu-review.md',
|
|
16
|
+
'planu-implement.md',
|
|
17
|
+
'planu-dogfood-bug.md',
|
|
14
18
|
];
|
|
15
|
-
async function fileExists(path) {
|
|
16
|
-
try {
|
|
17
|
-
await access(path);
|
|
18
|
-
return true;
|
|
19
|
-
}
|
|
20
|
-
catch {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
19
|
function addHost(hosts, host) {
|
|
25
20
|
if (!hosts.includes(host)) {
|
|
26
21
|
hosts.push(host);
|
|
@@ -115,6 +110,9 @@ async function canRefreshCoreSkill(projectPath, host, name) {
|
|
|
115
110
|
return (existing.includes(`<!-- planu:skills:${name} -->`) ||
|
|
116
111
|
!existing.includes(`## Skill: ${name}`));
|
|
117
112
|
}
|
|
113
|
+
if (existing.includes('managed-by: planu')) {
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
118
116
|
return existing.includes(`name: ${name}`) && existing.includes(`# /${name}`);
|
|
119
117
|
}
|
|
120
118
|
catch {
|
|
@@ -138,6 +136,7 @@ async function installCoreSkillsForHost(projectPath, host) {
|
|
|
138
136
|
description: template.description,
|
|
139
137
|
content: template.content,
|
|
140
138
|
overwriteExisting: true,
|
|
139
|
+
managedByPlanu: true,
|
|
141
140
|
});
|
|
142
141
|
if (result.isError === true) {
|
|
143
142
|
continue;
|
|
@@ -22,11 +22,11 @@ export declare function generateAndWriteRules(projectPath: string): {
|
|
|
22
22
|
};
|
|
23
23
|
export declare function fireTelemetry(knowledge: ProjectKnowledge): Promise<boolean>;
|
|
24
24
|
export declare function runConventionScanSafe(projectPath: string): Promise<'ok' | 'failed' | 'skipped'>;
|
|
25
|
-
export interface
|
|
25
|
+
export interface LifecycleSkillInstallResult {
|
|
26
26
|
skillsAutoInstalled: string[];
|
|
27
27
|
skillsPendingInstall: string[];
|
|
28
28
|
skillsSkipped: string[];
|
|
29
29
|
}
|
|
30
30
|
/** Orchestrate skill discovery and installation with autoInstall logic. */
|
|
31
|
-
export declare function orchestrateSkillInstalls(recommendedSkills: RecommendedSkill[], projectPath: string, autoInstallFromConfig: boolean): Promise<
|
|
31
|
+
export declare function orchestrateSkillInstalls(recommendedSkills: RecommendedSkill[], projectPath: string, autoInstallFromConfig: boolean): Promise<LifecycleSkillInstallResult>;
|
|
32
32
|
//# sourceMappingURL=lifecycle-helpers.d.ts.map
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { technologyValue } from '../../engine/technology-registry.js';
|
|
2
|
-
import {
|
|
2
|
+
import { fileExists } from '../../core/shared/fs.js';
|
|
3
|
+
import { readFile, writeFile } from 'node:fs/promises';
|
|
3
4
|
import { join } from 'node:path';
|
|
4
5
|
const ESLINT_CONFIG_FILES = [
|
|
5
6
|
'eslint.config.js',
|
|
@@ -22,15 +23,6 @@ const PRETTIER_CONFIG_FILES = [
|
|
|
22
23
|
'prettier.config.js',
|
|
23
24
|
'prettier.config.cjs',
|
|
24
25
|
];
|
|
25
|
-
async function fileExists(filePath) {
|
|
26
|
-
try {
|
|
27
|
-
await access(filePath);
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return false;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
26
|
async function anyFileExists(dir, names) {
|
|
35
27
|
for (const name of names) {
|
|
36
28
|
if (await fileExists(join(dir, name))) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { detectModernPatterns, detectDdd } from '../../engine/architecture-pattern-detector.js';
|
|
2
2
|
import { detectAgileProcess } from '../../engine/agile-config-builder.js';
|
|
3
3
|
import { detectOrchestratorInfo, detectComposeMultiplatform } from './helpers.js';
|
|
4
|
-
export interface
|
|
4
|
+
export interface InitStackDetectionResult {
|
|
5
5
|
modernPatterns: Awaited<ReturnType<typeof detectModernPatterns>>;
|
|
6
6
|
dddConfig: Awaited<ReturnType<typeof detectDdd>>;
|
|
7
7
|
agileDetection: Awaited<ReturnType<typeof detectAgileProcess>>;
|
|
@@ -12,5 +12,5 @@ export interface StackDetectionResult {
|
|
|
12
12
|
* SPEC-033: Detect modern architecture patterns, DDD config, agile process,
|
|
13
13
|
* container orchestrator, and Compose Multiplatform — all in parallel.
|
|
14
14
|
*/
|
|
15
|
-
export declare function detectStackPatterns(projectPath: string): Promise<
|
|
15
|
+
export declare function detectStackPatterns(projectPath: string): Promise<InitStackDetectionResult>;
|
|
16
16
|
//# sourceMappingURL=stack-detector.d.ts.map
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { ToolResult } from '../types/index.js';
|
|
2
|
-
export interface
|
|
2
|
+
export interface HookReconcileResult {
|
|
3
3
|
hookInstalled: boolean;
|
|
4
4
|
settingsUpdated: boolean;
|
|
5
5
|
humanSummary: string;
|
|
6
6
|
}
|
|
7
|
-
export declare function reconcileInteractiveQuestionHooks(projectPath: string): Promise<
|
|
7
|
+
export declare function reconcileInteractiveQuestionHooks(projectPath: string): Promise<HookReconcileResult>;
|
|
8
8
|
export declare function handleReconcileInteractiveQuestionHooks(args: {
|
|
9
9
|
projectPath: string;
|
|
10
10
|
}): Promise<ToolResult>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// register-sdd-tools.ts — Canonical MCP surface for Planu's SDD workflow.
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
3
4
|
import { registerResources } from '../resources/registry.js';
|
|
4
5
|
import { registerFromEntries } from './tool-entry.js';
|
|
5
6
|
import coreToolsRegistry from './tool-registry/core-tools.js';
|
|
@@ -31,6 +31,7 @@ import { loadCompactThresholds } from '../engine/compact/registry-loader.js';
|
|
|
31
31
|
import { applyCompactMode } from '../engine/compact/compact-middleware.js';
|
|
32
32
|
import { globalCompactStateStore } from '../engine/compact/state-store.js';
|
|
33
33
|
import { recordCompactDecision, recordVerboseDecision, recordNoHeader, } from '../engine/compact/metrics.js';
|
|
34
|
+
// eslint-disable-next-line no-restricted-imports -- grandfathered layer violation, remediation SPEC-1661 SPEC-1662 SPEC-1663
|
|
34
35
|
import { getSessionContext } from '../transports/session-context.js';
|
|
35
36
|
import { LocalExecutionSpan } from '../engine/observability/local-execution-spans.js';
|
|
36
37
|
import { classifyBoundaryFailure } from '../errors/error-taxonomy.js';
|
|
@@ -1,7 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export declare const SPEC_ID_PATTERN: RegExp;
|
|
3
|
-
export declare const SPEC_DIR_NAME_PATTERN: RegExp;
|
|
4
|
-
export declare const SpecIdSchema: z.ZodString;
|
|
5
|
-
export declare const SpecDirNameSchema: z.ZodString;
|
|
6
|
-
export declare function isCanonicalSpecId(value: string): boolean;
|
|
1
|
+
export { SPEC_ID_PATTERN, SPEC_DIR_NAME_PATTERN, SpecIdSchema, SpecDirNameSchema, isCanonicalSpecId, } from '../../engine/spec-format/spec-id.js';
|
|
7
2
|
//# sourceMappingURL=spec-id.d.ts.map
|
|
@@ -1,17 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export const SPEC_ID_PATTERN = /^SPEC-\d+$/;
|
|
3
|
-
export const SPEC_DIR_NAME_PATTERN = /^SPEC-\d+(?:-[a-z0-9]+(?:-[a-z0-9]+)*)?$/;
|
|
4
|
-
export const SpecIdSchema = z
|
|
5
|
-
.string()
|
|
6
|
-
.min(1)
|
|
7
|
-
.max(50)
|
|
8
|
-
.regex(SPEC_ID_PATTERN, 'Spec ID must use canonical numeric format like SPEC-042.');
|
|
9
|
-
export const SpecDirNameSchema = z
|
|
10
|
-
.string()
|
|
11
|
-
.min(1)
|
|
12
|
-
.max(200)
|
|
13
|
-
.regex(SPEC_DIR_NAME_PATTERN, 'Spec directory must start with a canonical numeric ID like SPEC-042 or SPEC-042-my-feature.');
|
|
14
|
-
export function isCanonicalSpecId(value) {
|
|
15
|
-
return SPEC_ID_PATTERN.test(value);
|
|
16
|
-
}
|
|
1
|
+
export { SPEC_ID_PATTERN, SPEC_DIR_NAME_PATTERN, SpecIdSchema, SpecDirNameSchema, isCanonicalSpecId, } from '../../engine/spec-format/spec-id.js';
|
|
17
2
|
//# sourceMappingURL=spec-id.js.map
|
|
@@ -15,7 +15,7 @@ export type ToolInputSchema = Record<string, ZodType>;
|
|
|
15
15
|
* The `wrap` field controls which safe-handler wrapper is applied by
|
|
16
16
|
* registerFromEntries(). Defaults to 'tracked' when omitted.
|
|
17
17
|
*/
|
|
18
|
-
export interface
|
|
18
|
+
export interface McpToolEntry {
|
|
19
19
|
/** MCP tool name, e.g. 'generate_batch_script'. snake_case. */
|
|
20
20
|
name: string;
|
|
21
21
|
/** Human-readable description surfaced to LLMs. */
|
|
@@ -49,5 +49,5 @@ export interface ToolEntry {
|
|
|
49
49
|
*
|
|
50
50
|
* Drop-in replacement for calling register*Tools(server) on each migrated file.
|
|
51
51
|
*/
|
|
52
|
-
export declare function registerFromEntries(server: McpServer, entries:
|
|
52
|
+
export declare function registerFromEntries(server: McpServer, entries: McpToolEntry[]): void;
|
|
53
53
|
//# sourceMappingURL=tool-entry.d.ts.map
|
package/dist/tools/tool-entry.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// tools/tool-entry.ts — Declarative
|
|
1
|
+
// tools/tool-entry.ts — Declarative McpToolEntry type for registry-based tool registration.
|
|
2
2
|
//
|
|
3
3
|
// Phase 1 (refactor/declarative-registry): replaces the register-*-tools.ts boilerplate pattern:
|
|
4
4
|
// server.registerTool(name, { description, inputSchema, annotations }, safeXxx(name, handler))
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
declare const coreToolsRegistry:
|
|
1
|
+
import type { McpToolEntry } from '../tool-entry.js';
|
|
2
|
+
declare const coreToolsRegistry: McpToolEntry[];
|
|
3
3
|
export default coreToolsRegistry;
|
|
4
4
|
//# sourceMappingURL=core-tools.d.ts.map
|