@planu/cli 4.14.1 → 5.0.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 +35 -1
- 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 +2 -2
- 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 +1 -1
- 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 +10 -1
- package/dist/engine/evidence-gates/artifact-reader.js +115 -2
- 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/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/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 +10 -10
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +10 -10
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +10 -10
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +10 -10
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +10 -10
- package/dist/engine/readiness-checker.d.ts +1 -16
- package/dist/engine/readiness-checker.js +27 -88
- 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 +77 -18
- 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/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/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 +27 -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 +10 -0
- 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.js +5 -5
- package/dist/tools/check-readiness.js +1 -1
- package/dist/tools/configure-telemetry.js +30 -2
- package/dist/tools/create-spec/spec-builder.js +0 -11
- package/dist/tools/create-spec.d.ts +1 -0
- package/dist/tools/create-spec.js +444 -239
- 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 +17 -8
- 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 +1 -1
- 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/done-receipt-verifier.js +40 -27
- package/dist/tools/update-status/evidence-gate.js +36 -1
- package/dist/tools/update-status/file-sync.d.ts +2 -1
- package/dist/tools/update-status/file-sync.js +57 -6
- package/dist/tools/update-status/index.d.ts +2 -0
- package/dist/tools/update-status/index.js +95 -58
- 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 +32 -15
- 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/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-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 +2 -6
- package/dist/types/index.js +1 -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 +14 -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 +29 -0
- package/dist/types/spec-format.d.ts +24 -0
- package/dist/types/telemetry.d.ts +4 -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 +2 -2
- package/package.json +16 -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
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Session, SessionDecision, SessionFile, SessionActiveSpec } from '../../types/index.js';
|
|
2
|
-
/** Get the current in-memory session (may be null if none started). */
|
|
3
|
-
export declare function getCurrentSession(): Session | null;
|
|
4
|
-
/** Reset module state (for testing). */
|
|
5
|
-
export declare function resetSessionState(): void;
|
|
6
|
-
/** Start or resume a session for a project. */
|
|
7
|
-
export declare function startSession(projectId: string, existingSession?: Session): Session;
|
|
8
|
-
/** Record a tool call and maybe persist (debounce). */
|
|
9
|
-
export declare function onToolCall(projectId: string): Promise<void>;
|
|
10
|
-
/** Add an active spec to the current session. */
|
|
11
|
-
export declare function addActiveSpec(spec: SessionActiveSpec): void;
|
|
12
|
-
/** Add a decision to the current session. */
|
|
13
|
-
export declare function addDecision(decision: SessionDecision): void;
|
|
14
|
-
/** Add a modified file to the current session. */
|
|
15
|
-
export declare function addModifiedFile(file: SessionFile): void;
|
|
16
|
-
/** Force-save the current session to disk (bypasses debounce). */
|
|
17
|
-
export declare function persistCurrentSession(): Promise<void>;
|
|
18
|
-
//# sourceMappingURL=auto-save.d.ts.map
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import * as sessionStore from '../../storage/session-store.js';
|
|
2
|
-
import { randomUUID } from 'node:crypto';
|
|
3
|
-
import { buildContextSnapshot } from './context-snapshot.js';
|
|
4
|
-
import { updateCrossConversationMemory } from './memory-sync.js';
|
|
5
|
-
// --- module state ---
|
|
6
|
-
let currentSession = null;
|
|
7
|
-
let lastSaveTimestamp = 0;
|
|
8
|
-
const DEBOUNCE_MS = 30_000; // 30 seconds
|
|
9
|
-
// --- public API ---
|
|
10
|
-
/** Get the current in-memory session (may be null if none started). */
|
|
11
|
-
export function getCurrentSession() {
|
|
12
|
-
return currentSession;
|
|
13
|
-
}
|
|
14
|
-
/** Reset module state (for testing). */
|
|
15
|
-
export function resetSessionState() {
|
|
16
|
-
currentSession = null;
|
|
17
|
-
lastSaveTimestamp = 0;
|
|
18
|
-
}
|
|
19
|
-
/** Start or resume a session for a project. */
|
|
20
|
-
export function startSession(projectId, existingSession) {
|
|
21
|
-
if (existingSession) {
|
|
22
|
-
currentSession = { ...existingSession };
|
|
23
|
-
return currentSession;
|
|
24
|
-
}
|
|
25
|
-
const now = new Date().toISOString();
|
|
26
|
-
currentSession = {
|
|
27
|
-
id: randomUUID(),
|
|
28
|
-
projectId,
|
|
29
|
-
startedAt: now,
|
|
30
|
-
lastSavedAt: now,
|
|
31
|
-
activeSpecs: [],
|
|
32
|
-
decisions: [],
|
|
33
|
-
modifiedFiles: [],
|
|
34
|
-
contextSummary: '',
|
|
35
|
-
toolCallCount: 0,
|
|
36
|
-
metadata: {},
|
|
37
|
-
};
|
|
38
|
-
return currentSession;
|
|
39
|
-
}
|
|
40
|
-
/** Record a tool call and maybe persist (debounce). */
|
|
41
|
-
export async function onToolCall(projectId) {
|
|
42
|
-
if (!currentSession) {
|
|
43
|
-
startSession(projectId);
|
|
44
|
-
}
|
|
45
|
-
if (currentSession) {
|
|
46
|
-
currentSession.toolCallCount++;
|
|
47
|
-
const now = Date.now();
|
|
48
|
-
if (now - lastSaveTimestamp >= DEBOUNCE_MS) {
|
|
49
|
-
await persistCurrentSession();
|
|
50
|
-
lastSaveTimestamp = now;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
/** Add an active spec to the current session. */
|
|
55
|
-
export function addActiveSpec(spec) {
|
|
56
|
-
if (!currentSession) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const exists = currentSession.activeSpecs.some((s) => s.specId === spec.specId);
|
|
60
|
-
if (!exists) {
|
|
61
|
-
currentSession.activeSpecs.push(spec);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
/** Add a decision to the current session. */
|
|
65
|
-
export function addDecision(decision) {
|
|
66
|
-
if (!currentSession) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
currentSession.decisions.push(decision);
|
|
70
|
-
}
|
|
71
|
-
/** Add a modified file to the current session. */
|
|
72
|
-
export function addModifiedFile(file) {
|
|
73
|
-
if (!currentSession) {
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
const idx = currentSession.modifiedFiles.findIndex((f) => f.path === file.path);
|
|
77
|
-
if (idx >= 0) {
|
|
78
|
-
currentSession.modifiedFiles[idx] = file;
|
|
79
|
-
}
|
|
80
|
-
else {
|
|
81
|
-
currentSession.modifiedFiles.push(file);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/** Force-save the current session to disk (bypasses debounce). */
|
|
85
|
-
export async function persistCurrentSession() {
|
|
86
|
-
if (!currentSession) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
currentSession.lastSavedAt = new Date().toISOString();
|
|
90
|
-
currentSession.contextSummary = buildContextSnapshot(currentSession);
|
|
91
|
-
await sessionStore.save(currentSession);
|
|
92
|
-
await updateCrossConversationMemory(currentSession);
|
|
93
|
-
// Fire-and-forget cleanup
|
|
94
|
-
void sessionStore.cleanup(currentSession.projectId).catch((err) => {
|
|
95
|
-
console.error('[planu] session cleanup failed:', err);
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
//# sourceMappingURL=auto-save.js.map
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Session } from '../../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Build a markdown context summary from the current session state.
|
|
4
|
-
* Includes: specs in progress, last 5 modified files, last 3 decisions.
|
|
5
|
-
* Truncated to 2000 chars max.
|
|
6
|
-
*/
|
|
7
|
-
export declare function buildContextSnapshot(session: Session): string;
|
|
8
|
-
//# sourceMappingURL=context-snapshot.d.ts.map
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
const MAX_SUMMARY_LENGTH = 2000;
|
|
2
|
-
/**
|
|
3
|
-
* Build a markdown context summary from the current session state.
|
|
4
|
-
* Includes: specs in progress, last 5 modified files, last 3 decisions.
|
|
5
|
-
* Truncated to 2000 chars max.
|
|
6
|
-
*/
|
|
7
|
-
export function buildContextSnapshot(session) {
|
|
8
|
-
const parts = [];
|
|
9
|
-
parts.push(`## Session Summary`);
|
|
10
|
-
parts.push(`- **Started**: ${session.startedAt}`);
|
|
11
|
-
parts.push(`- **Tool calls**: ${String(session.toolCallCount)}`);
|
|
12
|
-
parts.push('');
|
|
13
|
-
// Active specs
|
|
14
|
-
if (session.activeSpecs.length > 0) {
|
|
15
|
-
parts.push('### Active Specs');
|
|
16
|
-
for (const spec of session.activeSpecs) {
|
|
17
|
-
parts.push(`- **${spec.specId}** (${spec.status}): ${spec.summary}`);
|
|
18
|
-
}
|
|
19
|
-
parts.push('');
|
|
20
|
-
}
|
|
21
|
-
// Last 5 modified files
|
|
22
|
-
if (session.modifiedFiles.length > 0) {
|
|
23
|
-
parts.push('### Recent Files');
|
|
24
|
-
const recentFiles = session.modifiedFiles.slice(-5);
|
|
25
|
-
for (const file of recentFiles) {
|
|
26
|
-
parts.push(`- \`${file.path}\` (${file.action})`);
|
|
27
|
-
}
|
|
28
|
-
parts.push('');
|
|
29
|
-
}
|
|
30
|
-
// Last 3 decisions
|
|
31
|
-
if (session.decisions.length > 0) {
|
|
32
|
-
parts.push('### Recent Decisions');
|
|
33
|
-
const recentDecisions = session.decisions.slice(-3);
|
|
34
|
-
for (const d of recentDecisions) {
|
|
35
|
-
const specRef = d.specId ? ` [${d.specId}]` : '';
|
|
36
|
-
parts.push(`- ${d.decision}${specRef}`);
|
|
37
|
-
if (d.rationale) {
|
|
38
|
-
parts.push(` _Rationale: ${d.rationale}_`);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
parts.push('');
|
|
42
|
-
}
|
|
43
|
-
const full = parts.join('\n');
|
|
44
|
-
if (full.length <= MAX_SUMMARY_LENGTH) {
|
|
45
|
-
return full;
|
|
46
|
-
}
|
|
47
|
-
return `${full.slice(0, MAX_SUMMARY_LENGTH - 3)}...`;
|
|
48
|
-
}
|
|
49
|
-
//# sourceMappingURL=context-snapshot.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Session, SessionMemory } from '../../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Update cross-conversation memory with decisions from the current session.
|
|
4
|
-
* Only persists decisions with non-empty rationale.
|
|
5
|
-
* Deduplicates by decision content. Keeps max 100 (most recent win).
|
|
6
|
-
*/
|
|
7
|
-
export declare function updateCrossConversationMemory(session: Session): Promise<void>;
|
|
8
|
-
/**
|
|
9
|
-
* Load historical decisions from memory to inject into a new session.
|
|
10
|
-
*/
|
|
11
|
-
export declare function loadHistoricalDecisions(projectId: string): Promise<SessionMemory>;
|
|
12
|
-
//# sourceMappingURL=memory-sync.d.ts.map
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import * as sessionStore from '../../storage/session-store.js';
|
|
2
|
-
const MAX_MEMORY_DECISIONS = 100;
|
|
3
|
-
/**
|
|
4
|
-
* Update cross-conversation memory with decisions from the current session.
|
|
5
|
-
* Only persists decisions with non-empty rationale.
|
|
6
|
-
* Deduplicates by decision content. Keeps max 100 (most recent win).
|
|
7
|
-
*/
|
|
8
|
-
export async function updateCrossConversationMemory(session) {
|
|
9
|
-
const newDecisions = session.decisions.filter((d) => d.rationale.length > 0);
|
|
10
|
-
if (newDecisions.length === 0) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
const memory = await sessionStore.loadMemory(session.projectId);
|
|
14
|
-
// Deduplicate by decision content
|
|
15
|
-
const existingKeys = new Set(memory.decisions.map((d) => d.decision));
|
|
16
|
-
const toAdd = newDecisions.filter((d) => !existingKeys.has(d.decision));
|
|
17
|
-
if (toAdd.length === 0) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
memory.decisions.push(...toAdd);
|
|
21
|
-
// Keep only the most recent MAX_MEMORY_DECISIONS
|
|
22
|
-
if (memory.decisions.length > MAX_MEMORY_DECISIONS) {
|
|
23
|
-
memory.decisions = memory.decisions.slice(-MAX_MEMORY_DECISIONS);
|
|
24
|
-
}
|
|
25
|
-
memory.updatedAt = new Date().toISOString();
|
|
26
|
-
await sessionStore.saveMemory(memory);
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* Load historical decisions from memory to inject into a new session.
|
|
30
|
-
*/
|
|
31
|
-
export async function loadHistoricalDecisions(projectId) {
|
|
32
|
-
return sessionStore.loadMemory(projectId);
|
|
33
|
-
}
|
|
34
|
-
//# sourceMappingURL=memory-sync.js.map
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Session, SessionDiff } from '../../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Compare two sessions and return what changed.
|
|
4
|
-
* `older` is the previous session, `newer` is the current one.
|
|
5
|
-
*/
|
|
6
|
-
export declare function diffSessions(older: Session, newer: Session): SessionDiff;
|
|
7
|
-
/**
|
|
8
|
-
* Format a session diff as a human-readable summary string.
|
|
9
|
-
*/
|
|
10
|
-
export declare function formatDiffSummary(diff: SessionDiff): string;
|
|
11
|
-
//# sourceMappingURL=session-diff.d.ts.map
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compare two sessions and return what changed.
|
|
3
|
-
* `older` is the previous session, `newer` is the current one.
|
|
4
|
-
*/
|
|
5
|
-
export function diffSessions(older, newer) {
|
|
6
|
-
const oldSpecIds = new Set(older.activeSpecs.map((s) => s.specId));
|
|
7
|
-
const newSpecIds = new Set(newer.activeSpecs.map((s) => s.specId));
|
|
8
|
-
// Specs in newer but not in older
|
|
9
|
-
const newSpecs = newer.activeSpecs.filter((s) => !oldSpecIds.has(s.specId));
|
|
10
|
-
// Specs in older but not in newer (completed/removed)
|
|
11
|
-
const completedSpecs = older.activeSpecs.filter((s) => !newSpecIds.has(s.specId));
|
|
12
|
-
// Decisions in newer that don't exist in older
|
|
13
|
-
const oldDecisionKeys = new Set(older.decisions.map((d) => `${d.timestamp}|${d.decision}`));
|
|
14
|
-
const newDecisions = newer.decisions.filter((d) => !oldDecisionKeys.has(`${d.timestamp}|${d.decision}`));
|
|
15
|
-
// File changes in newer not in older
|
|
16
|
-
const oldFilePaths = new Set(older.modifiedFiles.map((f) => f.path));
|
|
17
|
-
const fileChanges = newer.modifiedFiles.filter((f) => !oldFilePaths.has(f.path));
|
|
18
|
-
return { newSpecs, completedSpecs, newDecisions, fileChanges };
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Format a session diff as a human-readable summary string.
|
|
22
|
-
*/
|
|
23
|
-
export function formatDiffSummary(diff) {
|
|
24
|
-
const parts = [];
|
|
25
|
-
if (diff.completedSpecs.length > 0) {
|
|
26
|
-
parts.push(`${String(diff.completedSpecs.length)} spec(s) completed`);
|
|
27
|
-
}
|
|
28
|
-
if (diff.newSpecs.length > 0) {
|
|
29
|
-
parts.push(`${String(diff.newSpecs.length)} new spec(s) started`);
|
|
30
|
-
}
|
|
31
|
-
if (diff.newDecisions.length > 0) {
|
|
32
|
-
parts.push(`${String(diff.newDecisions.length)} new decision(s)`);
|
|
33
|
-
}
|
|
34
|
-
if (diff.fileChanges.length > 0) {
|
|
35
|
-
parts.push(`${String(diff.fileChanges.length)} file(s) changed`);
|
|
36
|
-
}
|
|
37
|
-
if (parts.length === 0) {
|
|
38
|
-
return 'No significant changes since last session.';
|
|
39
|
-
}
|
|
40
|
-
return `Since your last session: ${parts.join(', ')}.`;
|
|
41
|
-
}
|
|
42
|
-
//# sourceMappingURL=session-diff.js.map
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import type { Session } from '../../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Merge two sessions of the same project.
|
|
4
|
-
* - activeSpecs: union (no duplicate specId)
|
|
5
|
-
* - decisions: union (no duplicate by timestamp+decision)
|
|
6
|
-
* - modifiedFiles: union by path, most recent action wins
|
|
7
|
-
* - toolCallCount: sum
|
|
8
|
-
* - contextSummary: regenerated
|
|
9
|
-
* The returned session uses the earlier startedAt and the later lastSavedAt.
|
|
10
|
-
*/
|
|
11
|
-
export declare function mergeSessions(a: Session, b: Session): Session;
|
|
12
|
-
//# sourceMappingURL=session-merge.d.ts.map
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { buildContextSnapshot } from './context-snapshot.js';
|
|
2
|
-
/**
|
|
3
|
-
* Merge two sessions of the same project.
|
|
4
|
-
* - activeSpecs: union (no duplicate specId)
|
|
5
|
-
* - decisions: union (no duplicate by timestamp+decision)
|
|
6
|
-
* - modifiedFiles: union by path, most recent action wins
|
|
7
|
-
* - toolCallCount: sum
|
|
8
|
-
* - contextSummary: regenerated
|
|
9
|
-
* The returned session uses the earlier startedAt and the later lastSavedAt.
|
|
10
|
-
*/
|
|
11
|
-
export function mergeSessions(a, b) {
|
|
12
|
-
// Determine chronological order
|
|
13
|
-
const first = a.startedAt <= b.startedAt ? a : b;
|
|
14
|
-
const second = a.startedAt <= b.startedAt ? b : a;
|
|
15
|
-
// Merge activeSpecs (union by specId, second wins on conflict)
|
|
16
|
-
const specMap = new Map(first.activeSpecs.map((s) => [s.specId, s]));
|
|
17
|
-
for (const s of second.activeSpecs) {
|
|
18
|
-
specMap.set(s.specId, s);
|
|
19
|
-
}
|
|
20
|
-
const activeSpecs = [...specMap.values()];
|
|
21
|
-
// Merge decisions (union by timestamp+decision key)
|
|
22
|
-
const decisionKeys = new Set();
|
|
23
|
-
const allDecisions = [...first.decisions, ...second.decisions];
|
|
24
|
-
const decisions = allDecisions.filter((d) => {
|
|
25
|
-
const key = `${d.timestamp}|${d.decision}`;
|
|
26
|
-
if (decisionKeys.has(key)) {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
decisionKeys.add(key);
|
|
30
|
-
return true;
|
|
31
|
-
});
|
|
32
|
-
// Merge modifiedFiles (union by path, later session's action wins)
|
|
33
|
-
const fileMap = new Map(first.modifiedFiles.map((f) => [f.path, f]));
|
|
34
|
-
for (const f of second.modifiedFiles) {
|
|
35
|
-
fileMap.set(f.path, f);
|
|
36
|
-
}
|
|
37
|
-
const modifiedFiles = [...fileMap.values()];
|
|
38
|
-
// Merge metadata (shallow merge, second wins on conflict)
|
|
39
|
-
const metadata = { ...first.metadata, ...second.metadata };
|
|
40
|
-
const merged = {
|
|
41
|
-
id: first.id,
|
|
42
|
-
projectId: first.projectId,
|
|
43
|
-
startedAt: first.startedAt,
|
|
44
|
-
lastSavedAt: second.lastSavedAt > first.lastSavedAt ? second.lastSavedAt : first.lastSavedAt,
|
|
45
|
-
activeSpecs,
|
|
46
|
-
decisions,
|
|
47
|
-
modifiedFiles,
|
|
48
|
-
contextSummary: '',
|
|
49
|
-
toolCallCount: first.toolCallCount + second.toolCallCount,
|
|
50
|
-
metadata,
|
|
51
|
-
};
|
|
52
|
-
merged.contextSummary = buildContextSnapshot(merged);
|
|
53
|
-
return merged;
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=session-merge.js.map
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { CheckpointResult, CheckpointRunnerOptions } from '../../types/index.js';
|
|
2
|
-
/** Run a full session checkpoint: regen context, flush buffer, detect/push unpushed. */
|
|
3
|
-
export declare function runCheckpoint(options: CheckpointRunnerOptions): Promise<CheckpointResult>;
|
|
4
|
-
//# sourceMappingURL=checkpoint-runner.d.ts.map
|
|
@@ -1,70 +0,0 @@
|
|
|
1
|
-
import { detectUnpushedCommits } from './unpushed-detector.js';
|
|
2
|
-
import { flushBuffer } from './learnings-buffer.js';
|
|
3
|
-
import { safeAutopush } from './autopush.js';
|
|
4
|
-
const WARN_UNPUSHED_HOURS = 2;
|
|
5
|
-
/** Regenerate session-context.md (fire-and-forget, best-effort). */
|
|
6
|
-
async function regenerateSessionContext(projectPath) {
|
|
7
|
-
try {
|
|
8
|
-
const { generateSessionContext } = await import('../session-context-generator.js');
|
|
9
|
-
const { resolveProjectIdOrAutoDetect } = await import('../../tools/resolve-project-id.js');
|
|
10
|
-
const resolved = await resolveProjectIdOrAutoDetect({ projectPath });
|
|
11
|
-
if (!resolved.ok) {
|
|
12
|
-
return false;
|
|
13
|
-
}
|
|
14
|
-
await generateSessionContext(projectPath, resolved.projectId);
|
|
15
|
-
return true;
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return false;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
/** Build the human-readable summary line for checkpoint output. */
|
|
22
|
-
function buildHumanSummary(sessionContextRefreshed, learningsFlushed, unpushed, pushed) {
|
|
23
|
-
const parts = [];
|
|
24
|
-
if (sessionContextRefreshed) {
|
|
25
|
-
parts.push('session-context.md refreshed');
|
|
26
|
-
}
|
|
27
|
-
if (learningsFlushed > 0) {
|
|
28
|
-
parts.push(`${String(learningsFlushed)} learning(s) flushed to MEMORY.md`);
|
|
29
|
-
}
|
|
30
|
-
if (pushed !== undefined) {
|
|
31
|
-
if (pushed.pushed) {
|
|
32
|
-
parts.push(`autopush: ${String(pushed.commitsPushed)} commit(s) pushed to ${pushed.ref}`);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
parts.push(`autopush skipped (${pushed.reason})`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
else if (unpushed && unpushed.oldestAgeHours >= WARN_UNPUSHED_HOURS) {
|
|
39
|
-
parts.push(`WARNING: ${String(unpushed.count)} commit(s) unpushed for ${String(unpushed.oldestAgeHours)}h on branch ${unpushed.branch}. Run git push or enable autopush.`);
|
|
40
|
-
}
|
|
41
|
-
return parts.length > 0 ? parts.join('; ') : 'Checkpoint complete — nothing to do.';
|
|
42
|
-
}
|
|
43
|
-
/** Run a full session checkpoint: regen context, flush buffer, detect/push unpushed. */
|
|
44
|
-
export async function runCheckpoint(options) {
|
|
45
|
-
const { projectPath, dryRun = false, autopush = false, autopushBranches } = options;
|
|
46
|
-
// This runner backs the explicit checkpoint tool, so refresh even when the
|
|
47
|
-
// file mtime is recent: package releases can change semantic state instantly.
|
|
48
|
-
const sessionContextRefreshed = dryRun ? false : await regenerateSessionContext(projectPath);
|
|
49
|
-
// Flush learnings buffer
|
|
50
|
-
let learningsFlushed = 0;
|
|
51
|
-
if (!dryRun) {
|
|
52
|
-
learningsFlushed = await flushBuffer(projectPath).catch(() => 0);
|
|
53
|
-
}
|
|
54
|
-
// Detect unpushed commits
|
|
55
|
-
const unpushedCommits = await detectUnpushedCommits(projectPath);
|
|
56
|
-
// Autopush if configured
|
|
57
|
-
let pushed;
|
|
58
|
-
if (autopush && !dryRun) {
|
|
59
|
-
pushed = await safeAutopush(projectPath, autopushBranches);
|
|
60
|
-
}
|
|
61
|
-
const humanSummary = buildHumanSummary(sessionContextRefreshed, learningsFlushed, unpushedCommits, pushed);
|
|
62
|
-
return {
|
|
63
|
-
sessionContextRefreshed,
|
|
64
|
-
learningsFlushed,
|
|
65
|
-
unpushedCommits,
|
|
66
|
-
...(pushed !== undefined ? { pushed } : {}),
|
|
67
|
-
humanSummary,
|
|
68
|
-
};
|
|
69
|
-
}
|
|
70
|
-
//# sourceMappingURL=checkpoint-runner.js.map
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { LearningsBuffer, LearningEntry } from '../../types/index.js';
|
|
2
|
-
/** Read the learnings buffer for a project (best-effort, returns empty on miss). */
|
|
3
|
-
export declare function readBuffer(projectPath: string): Promise<LearningsBuffer>;
|
|
4
|
-
/**
|
|
5
|
-
* Append an entry under the shared transactional lease authority.
|
|
6
|
-
*/
|
|
7
|
-
export declare function appendToBuffer(projectPath: string, entry: LearningEntry): Promise<void>;
|
|
8
|
-
/**
|
|
9
|
-
* Flush all entries in the learnings buffer to MEMORY.md.
|
|
10
|
-
* Appends under an existing section or creates a new one.
|
|
11
|
-
* Clears the buffer after successful write.
|
|
12
|
-
* Returns the number of entries flushed.
|
|
13
|
-
*/
|
|
14
|
-
export declare function flushBuffer(projectPath: string): Promise<number>;
|
|
15
|
-
//# sourceMappingURL=learnings-buffer.d.ts.map
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
// engine/session-safeguard/learnings-buffer.ts — SPEC-585: Append/flush learnings buffer
|
|
2
|
-
import { readFile, mkdir } from 'node:fs/promises';
|
|
3
|
-
import { homedir } from 'node:os';
|
|
4
|
-
import { join } from 'node:path';
|
|
5
|
-
import { hashProjectPath, projectDataDir } from '../../storage/base-store.js';
|
|
6
|
-
import { acquireLock, releaseLock } from '../safety/file-mutex.js';
|
|
7
|
-
import { atomicWriteFile } from '../safety/atomic-write-file.js';
|
|
8
|
-
import { assertNoObsoleteFileLock } from '../safety/obsolete-lock-guard.js';
|
|
9
|
-
const BUFFER_VERSION = 1;
|
|
10
|
-
const LOCK_TIMEOUT_MS = 10_000;
|
|
11
|
-
function bufferPath(projectPath) {
|
|
12
|
-
const hash = hashProjectPath(projectPath);
|
|
13
|
-
return join(projectDataDir(hash), 'learnings-buffer.json');
|
|
14
|
-
}
|
|
15
|
-
function claudeMemoryPath(projectPath) {
|
|
16
|
-
const projectKey = projectPath.replaceAll('\\', '-').replaceAll('/', '-');
|
|
17
|
-
return join(homedir(), '.claude', 'projects', projectKey, 'memory', 'MEMORY.md');
|
|
18
|
-
}
|
|
19
|
-
function emptyBuffer() {
|
|
20
|
-
return { version: BUFFER_VERSION, entries: [] };
|
|
21
|
-
}
|
|
22
|
-
/** Read the learnings buffer for a project (best-effort, returns empty on miss). */
|
|
23
|
-
export async function readBuffer(projectPath) {
|
|
24
|
-
try {
|
|
25
|
-
const raw = await readFile(bufferPath(projectPath), 'utf-8');
|
|
26
|
-
return JSON.parse(raw);
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return emptyBuffer();
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
/** Write the buffer to disk, creating parent dirs as needed. */
|
|
33
|
-
async function writeBuffer(projectPath, buffer) {
|
|
34
|
-
const path = bufferPath(projectPath);
|
|
35
|
-
await mkdir(join(path, '..'), { recursive: true });
|
|
36
|
-
await atomicWriteFile(path, JSON.stringify(buffer, null, 2));
|
|
37
|
-
}
|
|
38
|
-
async function withBufferLock(projectPath, operation) {
|
|
39
|
-
await assertNoObsoleteFileLock(`${bufferPath(projectPath)}.lock`, 'learnings buffer');
|
|
40
|
-
const handle = await acquireLock(bufferPath(projectPath), LOCK_TIMEOUT_MS);
|
|
41
|
-
try {
|
|
42
|
-
return await operation();
|
|
43
|
-
}
|
|
44
|
-
finally {
|
|
45
|
-
await releaseLock(handle);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Append an entry under the shared transactional lease authority.
|
|
50
|
-
*/
|
|
51
|
-
export async function appendToBuffer(projectPath, entry) {
|
|
52
|
-
await withBufferLock(projectPath, async () => {
|
|
53
|
-
const buffer = await readBuffer(projectPath);
|
|
54
|
-
buffer.entries.push(entry);
|
|
55
|
-
await writeBuffer(projectPath, buffer);
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
/** Build the markdown bullet for an entry to append to MEMORY.md. */
|
|
59
|
-
function entryToMarkdown(entry) {
|
|
60
|
-
const label = `[${entry.category}/${entry.source}]`;
|
|
61
|
-
return `- ${label} ${entry.content} _(${entry.timestamp.slice(0, 10)})_`;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Flush all entries in the learnings buffer to MEMORY.md.
|
|
65
|
-
* Appends under an existing section or creates a new one.
|
|
66
|
-
* Clears the buffer after successful write.
|
|
67
|
-
* Returns the number of entries flushed.
|
|
68
|
-
*/
|
|
69
|
-
export async function flushBuffer(projectPath) {
|
|
70
|
-
return withBufferLock(projectPath, async () => {
|
|
71
|
-
const buffer = await readBuffer(projectPath);
|
|
72
|
-
if (buffer.entries.length === 0) {
|
|
73
|
-
return 0;
|
|
74
|
-
}
|
|
75
|
-
const memoryPath = claudeMemoryPath(projectPath);
|
|
76
|
-
let existing = '';
|
|
77
|
-
try {
|
|
78
|
-
existing = await readFile(memoryPath, 'utf-8');
|
|
79
|
-
}
|
|
80
|
-
catch {
|
|
81
|
-
/* file may not exist */
|
|
82
|
-
}
|
|
83
|
-
const bullets = buffer.entries.map(entryToMarkdown).join('\n');
|
|
84
|
-
const section = `\n\n## Session Learnings (auto-flushed ${new Date().toISOString().slice(0, 10)})\n\n${bullets}\n`;
|
|
85
|
-
await mkdir(join(memoryPath, '..'), { recursive: true });
|
|
86
|
-
await atomicWriteFile(memoryPath, existing + section);
|
|
87
|
-
await writeBuffer(projectPath, emptyBuffer());
|
|
88
|
-
return buffer.entries.length;
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=learnings-buffer.js.map
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { PrecompactionDrainReport, PrecompactionDrainOptions } from '../../types/claude-code-runtime.js';
|
|
2
|
-
/**
|
|
3
|
-
* Drain learnings buffer to MEMORY.md fragments, autopush unpushed commits,
|
|
4
|
-
* and write session-context.md — all before context compaction completes.
|
|
5
|
-
*
|
|
6
|
-
* Every operation is best-effort: a failure in one step does not prevent
|
|
7
|
-
* the others from running. The drain report captures all outcomes.
|
|
8
|
-
*/
|
|
9
|
-
export declare function runPrecompactionDrain(projectPath: string, options?: PrecompactionDrainOptions): Promise<PrecompactionDrainReport>;
|
|
10
|
-
//# sourceMappingURL=precompaction-drain.d.ts.map
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
// engine/session-safeguard/precompaction-drain.ts — SPEC-587
|
|
2
|
-
// Runs when PreCompaction fires: drains learnings buffer, autopushes commits,
|
|
3
|
-
// writes session-context.md — all before context compaction completes.
|
|
4
|
-
import { flushBuffer } from './learnings-buffer.js';
|
|
5
|
-
import { safeAutopush } from './autopush.js';
|
|
6
|
-
/**
|
|
7
|
-
* Regenerate session-context.md (best-effort, resolves projectId automatically).
|
|
8
|
-
* Returns true when successfully written.
|
|
9
|
-
*/
|
|
10
|
-
async function writeSessionContext(projectPath) {
|
|
11
|
-
try {
|
|
12
|
-
const { generateSessionContext } = await import('../session-context-generator.js');
|
|
13
|
-
const { resolveProjectIdOrAutoDetect } = await import('../../tools/resolve-project-id.js');
|
|
14
|
-
const resolved = await resolveProjectIdOrAutoDetect({ projectPath });
|
|
15
|
-
if (!resolved.ok) {
|
|
16
|
-
return false;
|
|
17
|
-
}
|
|
18
|
-
await generateSessionContext(projectPath, resolved.projectId);
|
|
19
|
-
return true;
|
|
20
|
-
}
|
|
21
|
-
catch {
|
|
22
|
-
return false;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Drain learnings buffer to MEMORY.md fragments, autopush unpushed commits,
|
|
27
|
-
* and write session-context.md — all before context compaction completes.
|
|
28
|
-
*
|
|
29
|
-
* Every operation is best-effort: a failure in one step does not prevent
|
|
30
|
-
* the others from running. The drain report captures all outcomes.
|
|
31
|
-
*/
|
|
32
|
-
export async function runPrecompactionDrain(projectPath, options = {}) {
|
|
33
|
-
const { dryRun = false, autopushBranches } = options;
|
|
34
|
-
// 1. Drain learnings buffer to MEMORY.md fragments
|
|
35
|
-
let learningsFlushed = 0;
|
|
36
|
-
if (!dryRun) {
|
|
37
|
-
learningsFlushed = await flushBuffer(projectPath).catch(() => 0);
|
|
38
|
-
}
|
|
39
|
-
// 2. Autopush unpushed commits (best-effort)
|
|
40
|
-
let autopushResult;
|
|
41
|
-
if (!dryRun) {
|
|
42
|
-
const result = await safeAutopush(projectPath, autopushBranches).catch((err) => {
|
|
43
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
44
|
-
return { pushed: false, reason: msg };
|
|
45
|
-
});
|
|
46
|
-
autopushResult = result.pushed
|
|
47
|
-
? { pushed: true, ref: result.ref, commitsPushed: result.commitsPushed }
|
|
48
|
-
: { pushed: false, reason: result.reason };
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
autopushResult = { pushed: false, reason: 'dry-run' };
|
|
52
|
-
}
|
|
53
|
-
// 3. Write session-context.md
|
|
54
|
-
let sessionContextWritten = false;
|
|
55
|
-
if (!dryRun) {
|
|
56
|
-
sessionContextWritten = await writeSessionContext(projectPath);
|
|
57
|
-
}
|
|
58
|
-
// Build human summary
|
|
59
|
-
const parts = [];
|
|
60
|
-
if (learningsFlushed > 0) {
|
|
61
|
-
parts.push(`${String(learningsFlushed)} learning(s) flushed to MEMORY.md`);
|
|
62
|
-
}
|
|
63
|
-
if (autopushResult.pushed) {
|
|
64
|
-
parts.push(`autopush: ${String(autopushResult.commitsPushed)} commit(s) pushed to ${autopushResult.ref}`);
|
|
65
|
-
}
|
|
66
|
-
else {
|
|
67
|
-
parts.push(`autopush skipped (${autopushResult.reason})`);
|
|
68
|
-
}
|
|
69
|
-
if (sessionContextWritten) {
|
|
70
|
-
parts.push('session-context.md written');
|
|
71
|
-
}
|
|
72
|
-
const humanSummary = parts.length > 0
|
|
73
|
-
? `PreCompaction drain: ${parts.join('; ')}`
|
|
74
|
-
: 'PreCompaction drain: nothing to do';
|
|
75
|
-
return {
|
|
76
|
-
learningsFlushed,
|
|
77
|
-
sessionContextWritten,
|
|
78
|
-
autopushResult,
|
|
79
|
-
humanSummary,
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=precompaction-drain.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { UnpushedCommitInfo } from '../../types/index.js';
|
|
2
|
-
/**
|
|
3
|
-
* Detect unpushed commits on the current branch.
|
|
4
|
-
* Returns null when not a git repo, detached HEAD, or no upstream configured.
|
|
5
|
-
*/
|
|
6
|
-
export declare function detectUnpushedCommits(projectPath: string): Promise<UnpushedCommitInfo | null>;
|
|
7
|
-
//# sourceMappingURL=unpushed-detector.d.ts.map
|