@planu/cli 4.14.1 → 5.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +82 -0
- package/LICENSE +55 -12
- package/README.md +10 -2
- package/dist/cli/commands/install.d.ts +1 -12
- package/dist/cli/commands/install.js +9 -65
- package/dist/cli/commands/job.js +4 -3
- package/dist/cli/commands/spec.js +12 -3
- package/dist/cli/commands/validate.js +2 -2
- package/dist/cli/router.js +1 -3
- package/dist/config/environment-schema.json +1 -3
- package/dist/config/official-sdd-tools.d.ts +4 -0
- package/dist/config/official-sdd-tools.js +35 -0
- package/dist/config/product-public.d.ts +139 -3
- package/dist/config/product-public.js +8 -1
- package/dist/config/product-public.json +7 -36
- package/dist/config/registries/hosts/codex.json +20 -363
- package/dist/config/release-policy.json +84 -2
- package/dist/config/runtime-policy.json +12 -1
- package/dist/config/skill-templates/planu-resume-work.md +2 -2
- package/dist/core/index.d.ts +1 -1
- package/dist/core/spec-validator.d.ts +4 -4
- package/dist/core/spec-validator.js +33 -19
- package/dist/engine/abortable-process-runner.d.ts +20 -2
- package/dist/engine/abortable-process-runner.js +243 -74
- package/dist/engine/ambiguity-scorer.js +4 -26
- package/dist/engine/auth/scope-mapper.js +1 -7
- package/dist/engine/autopilot/state-updater.js +4 -4
- package/dist/engine/cascade-hooks/hooks/review-enricher.hook.js +9 -6
- package/dist/engine/cascade-hooks/state-drift-detector.d.ts +3 -3
- package/dist/engine/cascade-hooks/state-drift-detector.js +1 -1
- package/dist/engine/ci-generator/planu-config.js +1 -7
- package/dist/engine/clarification-gate/gate.d.ts +3 -3
- package/dist/engine/code-scanner/layer-scanner.js +6 -22
- package/dist/engine/core-bridge.d.ts +3 -3
- package/dist/engine/cost-guardrails.d.ts +1 -1
- package/dist/engine/cost-guardrails.js +1 -1
- package/dist/engine/criterion-identity.d.ts +1 -0
- package/dist/engine/criterion-identity.js +7 -0
- package/dist/engine/dashboard/data-loader.js +2 -7
- package/dist/engine/dashboard/templates-layout.js +0 -3
- package/dist/engine/dashboard/templates-project.js +1 -13
- package/dist/engine/docs-site-generator/data-collector.d.ts +1 -1
- package/dist/engine/docs-site-generator/data-collector.js +7 -28
- package/dist/engine/docs-site-generator/tools-renderer.js +3 -10
- package/dist/engine/evidence-gates/artifact-reader.d.ts +12 -1
- package/dist/engine/evidence-gates/artifact-reader.js +174 -4
- package/dist/engine/evidence-gates/evidence-autofill.d.ts +10 -0
- package/dist/engine/evidence-gates/evidence-autofill.js +148 -0
- package/dist/engine/evidence-gates/evidence-skeletons.d.ts +19 -0
- package/dist/engine/evidence-gates/evidence-skeletons.js +69 -0
- package/dist/engine/evidence-gates/lifecycle-gate.js +4 -3
- package/dist/engine/evidence-gates/reconciliation-freshness.d.ts +11 -0
- package/dist/engine/evidence-gates/reconciliation-freshness.js +72 -0
- package/dist/engine/evidence-index/done-drift.d.ts +1 -1
- package/dist/engine/evidence-index/done-drift.js +40 -18
- package/dist/engine/execution/context.js +3 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.d.ts +4 -0
- package/dist/engine/execution/durable-job-heartbeat-runtime.js +400 -0
- package/dist/engine/execution/job-runtime.d.ts +30 -0
- package/dist/engine/execution/job-runtime.js +114 -6
- package/dist/engine/execution/operation-journal.js +10 -4
- package/dist/engine/execution/public-job-sanitizer.d.ts +4 -0
- package/dist/engine/execution/public-job-sanitizer.js +31 -0
- package/dist/engine/execution/validate-job-executor.d.ts +12 -1
- package/dist/engine/execution/validate-job-executor.js +549 -86
- package/dist/engine/execution/validate-job-payload.js +107 -50
- package/dist/engine/execution/validate-job-recovery.js +1 -1
- package/dist/engine/execution/validate-worker-runtime.d.ts +5 -0
- package/dist/engine/execution/validate-worker-runtime.js +90 -2
- package/dist/engine/execution/validate-worker-thread.js +17 -24
- package/dist/engine/handoff-artifacts/schemas.d.ts +2 -1
- package/dist/engine/handoff-artifacts/schemas.js +33 -0
- package/dist/engine/handoff-packager.d.ts +19 -0
- package/dist/engine/handoff-packager.js +415 -13
- package/dist/engine/hooks/effort-configurator.js +1 -1
- package/dist/engine/impact-detector/test-break-predictor.js +3 -3
- package/dist/engine/impact-detector/tool-registration.js +1 -1
- package/dist/engine/implementation-contract/renderer.js +23 -8
- package/dist/engine/lifecycle-reconciliation-io.d.ts +11 -0
- package/dist/engine/lifecycle-reconciliation-io.js +180 -0
- package/dist/engine/lifecycle-reconciliation.d.ts +16 -0
- package/dist/engine/lifecycle-reconciliation.js +406 -0
- package/dist/engine/local-first/tool-classification.js +2 -0
- package/dist/engine/macos-keychain-native-port.d.ts +5 -0
- package/dist/engine/macos-keychain-native-port.js +19 -7
- package/dist/engine/migrations/remove-commercial-state.d.ts +3 -0
- package/dist/engine/migrations/remove-commercial-state.js +343 -0
- package/dist/engine/minimality/policy-loader.js +247 -6
- package/dist/engine/network-policy.js +1 -0
- package/dist/engine/planu-core.darwin-arm64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-arm64.node.sbom.json +20 -20
- package/dist/engine/planu-core.darwin-x64.node.manifest.json +7 -7
- package/dist/engine/planu-core.darwin-x64.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-arm64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-gnu.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-arm64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-arm64-musl.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-x64-gnu.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-gnu.node.sbom.json +20 -20
- package/dist/engine/planu-core.linux-x64-musl.node.manifest.json +7 -7
- package/dist/engine/planu-core.linux-x64-musl.node.sbom.json +20 -20
- package/dist/engine/planu-core.win32-arm64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-arm64-msvc.node.sbom.json +20 -20
- package/dist/engine/planu-core.win32-x64-msvc.node.manifest.json +7 -7
- package/dist/engine/planu-core.win32-x64-msvc.node.sbom.json +20 -20
- package/dist/engine/readiness-checker.d.ts +1 -16
- package/dist/engine/readiness-checker.js +27 -88
- package/dist/engine/reverse-engineer/api-detector.js +2 -13
- package/dist/engine/reverse-engineer/complexity-analyzer.js +2 -13
- package/dist/engine/reverse-engineer/config-analyzer.js +2 -13
- package/dist/engine/reverse-engineer/dependency-graph.js +2 -13
- package/dist/engine/reverse-engineer/test-analyzer.js +2 -13
- package/dist/engine/reverse-engineer/walk-ignore.d.ts +3 -0
- package/dist/engine/reverse-engineer/walk-ignore.js +26 -0
- package/dist/engine/runtime-policy.d.ts +2 -0
- package/dist/engine/runtime-policy.js +42 -5
- package/dist/engine/runtime-security/rate-limiter.js +0 -1
- package/dist/engine/safety/contained-project-file.d.ts +3 -0
- package/dist/engine/safety/contained-project-file.js +23 -0
- package/dist/engine/scope-boundaries/contradiction-checker.js +63 -1
- package/dist/engine/scope-boundaries/scope-validator.js +45 -7
- package/dist/engine/session/checkpoint-writer.js +0 -9
- package/dist/engine/spec-format/acceptance-criteria.d.ts +6 -2
- package/dist/engine/spec-format/acceptance-criteria.js +82 -22
- package/dist/engine/spec-format/markdown-sections.d.ts +14 -0
- package/dist/engine/spec-format/markdown-sections.js +105 -0
- package/dist/engine/spec-format/read-technical-section.js +33 -5
- package/dist/engine/spec-format/technical-md-populator.js +3 -2
- package/dist/engine/spec-format/text-fences.js +20 -2
- package/dist/engine/spec-format/unified-spec-builder.d.ts +7 -0
- package/dist/engine/spec-format/unified-spec-builder.js +202 -0
- package/dist/engine/spec-migrator/canonical-deduplicator.d.ts +18 -0
- package/dist/engine/spec-migrator/canonical-deduplicator.js +479 -0
- package/dist/engine/spec-migrator/filesystem-import.d.ts +4 -8
- package/dist/engine/spec-migrator/filesystem-import.js +121 -14
- package/dist/engine/spec-migrator/frontmatter-parser.js +32 -15
- package/dist/engine/spec-migrator/index.d.ts +1 -0
- package/dist/engine/spec-migrator/index.js +1 -0
- package/dist/engine/spec-state-machine/transition-spec.d.ts +6 -1
- package/dist/engine/spec-state-machine/transition-spec.js +10 -1
- package/dist/engine/spec-state-syncer.js +1 -1
- package/dist/engine/technical-enricher/index.js +16 -8
- package/dist/engine/technical-enricher/render-enriched.d.ts +1 -0
- package/dist/engine/technical-enricher/render-enriched.js +42 -14
- package/dist/engine/telemetry/health-checker.js +53 -17
- package/dist/engine/telemetry/telemetry-client.js +26 -8
- package/dist/engine/text-signal-boundaries.d.ts +2 -0
- package/dist/engine/text-signal-boundaries.js +25 -2
- package/dist/engine/time/relative-date.d.ts +3 -0
- package/dist/engine/time/relative-date.js +16 -0
- package/dist/engine/timing/budget.d.ts +11 -0
- package/dist/engine/timing/budget.js +31 -9
- package/dist/engine/token-optimizer/analytics.d.ts +1 -1
- package/dist/engine/token-optimizer/analytics.js +5 -6
- package/dist/engine/usage-tracker/core.d.ts +2 -2
- package/dist/engine/usage-tracker/core.js +1 -2
- package/dist/engine/usage-tracker/index.d.ts +0 -3
- package/dist/engine/usage-tracker/index.js +0 -3
- package/dist/engine/usage-tracker/stats.d.ts +2 -2
- package/dist/engine/usage-tracker/stats.js +1 -28
- package/dist/engine/validation/durable-validation.d.ts +1 -1
- package/dist/engine/validation/durable-validation.js +3 -82
- package/dist/engine/validation/validation-freshness.d.ts +11 -1
- package/dist/engine/validation/validation-freshness.js +231 -91
- package/dist/engine/validation/validation-receipt.d.ts +9 -6
- package/dist/engine/validation/validation-receipt.js +84 -24
- package/dist/engine/validation/validation-source-digest.d.ts +2 -0
- package/dist/engine/validation/validation-source-digest.js +86 -0
- package/dist/engine/validation/validation-submission.d.ts +5 -4
- package/dist/engine/validation/validation-submission.js +25 -11
- package/dist/engine/validation/validation-worktree.d.ts +21 -0
- package/dist/engine/validation/validation-worktree.js +260 -0
- package/dist/engine/validation-impact-planner.d.ts +14 -2
- package/dist/engine/validation-impact-planner.js +0 -3
- package/dist/engine/validator/dor-dod.d.ts +1 -0
- package/dist/engine/validator/dor-dod.js +5 -3
- package/dist/engine/validator/extractors.d.ts +1 -5
- package/dist/engine/validator/extractors.js +24 -69
- package/dist/engine/validator/spec-compliance-runner.d.ts +12 -24
- package/dist/engine/validator/spec-compliance-runner.js +429 -211
- package/dist/engine/validator.js +35 -22
- package/dist/index.js +4 -16
- package/dist/resources/usage-stats-resource.js +2 -18
- package/dist/security/adapters/linux-secret-service.js +7 -3
- package/dist/security/adapters/windows-credential-manager.js +6 -4
- package/dist/server/routes/specs.js +13 -1
- package/dist/storage/base-store.d.ts +1 -1
- package/dist/storage/base-store.js +1 -1
- package/dist/storage/feedback-remote.d.ts +2 -3
- package/dist/storage/feedback-remote.js +45 -31
- package/dist/storage/global-store.d.ts +1 -17
- package/dist/storage/global-store.js +1 -42
- package/dist/storage/index.d.ts +0 -2
- package/dist/storage/index.js +0 -2
- package/dist/storage/migrations/canonical-storage.js +124 -11
- package/dist/storage/runtime-db.d.ts +9 -0
- package/dist/storage/runtime-db.js +64 -8
- package/dist/storage/spec-store.d.ts +14 -2
- package/dist/storage/spec-store.js +104 -14
- package/dist/storage/status-store/atomic-status-write.d.ts +5 -0
- package/dist/storage/status-store/atomic-status-write.js +57 -0
- package/dist/storage/status-store/file-lock.js +30 -11
- package/dist/storage/status-store/self-healing.js +3 -3
- package/dist/storage/status-store/version-sync.d.ts +2 -1
- package/dist/storage/status-store/version-sync.js +35 -40
- package/dist/storage/usage-store.d.ts +1 -5
- package/dist/storage/usage-store.js +0 -35
- package/dist/tools/auto-update-handler.d.ts +3 -3
- package/dist/tools/auto-update-handler.js +3 -3
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.d.ts +2 -1
- package/dist/tools/challenge-spec/resilience-challenge-scenarios.js +10 -7
- package/dist/tools/challenge-spec/scenario-collector.js +1 -1
- package/dist/tools/challenge-spec/scenarios-data.js +1 -1
- package/dist/tools/challenge-spec/scenarios-utils.d.ts +1 -1
- package/dist/tools/challenge-spec/scenarios-utils.js +35 -11
- package/dist/tools/challenge-spec-helpers.d.ts +10 -1
- package/dist/tools/challenge-spec-helpers.js +63 -22
- package/dist/tools/challenge-spec.js +23 -8
- package/dist/tools/check-readiness.js +38 -14
- package/dist/tools/configure-telemetry.js +30 -2
- package/dist/tools/create-spec/spec-builder.d.ts +7 -0
- package/dist/tools/create-spec/spec-builder.js +19 -15
- package/dist/tools/create-spec.d.ts +1 -0
- package/dist/tools/create-spec.js +584 -309
- package/dist/tools/git/branch-ops.d.ts +1 -1
- package/dist/tools/git/branch-ops.js +3 -2
- package/dist/tools/init-project/handler.js +10 -12
- package/dist/tools/init-project/host-assets-writer.js +26 -1
- package/dist/tools/init-project/lint-scaffolder.d.ts +3 -3
- package/dist/tools/init-project/migration-runner.d.ts +2 -4
- package/dist/tools/init-project/migration-runner.js +3 -2
- package/dist/tools/init-project/portable-index-reconciler.d.ts +4 -0
- package/dist/tools/init-project/portable-index-reconciler.js +14 -0
- package/dist/tools/init-project/result-builder.js +1 -3
- package/dist/tools/jobs/handlers.js +38 -6
- package/dist/tools/list-specs.js +5 -26
- package/dist/tools/merge-risk-handler.js +2 -2
- package/dist/tools/package-handoff.js +2 -0
- package/dist/tools/reconcile-spec.js +0 -27
- package/dist/tools/register-agent-squad-tools.js +2 -2
- package/dist/tools/register-platform-tools/design-stack-tools.js +11 -11
- package/dist/tools/register-platform-tools/lifecycle-infra-tools.js +7 -7
- package/dist/tools/register-sdd-tools.d.ts +1 -1
- package/dist/tools/register-sdd-tools.js +2 -29
- package/dist/tools/register-spec-tools/analysis-tools.js +8 -8
- package/dist/tools/register-spec-tools/core-spec-tools.js +29 -19
- package/dist/tools/safe-handler.d.ts +5 -13
- package/dist/tools/safe-handler.js +7 -23
- package/dist/tools/schemas/index.d.ts +1 -1
- package/dist/tools/schemas/index.js +1 -1
- package/dist/tools/schemas/output-schemas.d.ts +0 -23
- package/dist/tools/schemas/output-schemas.js +0 -28
- package/dist/tools/schemas/spec.d.ts +4 -0
- package/dist/tools/schemas/spec.js +3 -0
- package/dist/tools/schemas/validate-output-schema.d.ts +11 -0
- package/dist/tools/schemas/validate-output-schema.js +7 -0
- package/dist/tools/spec-prompt-handler.js +3 -3
- package/dist/tools/sync-spec-state-handler.d.ts +1 -1
- package/dist/tools/sync-spec-state-handler.js +50 -2
- package/dist/tools/tool-entry.d.ts +4 -4
- package/dist/tools/tool-entry.js +3 -3
- package/dist/tools/tool-registry/core-tools.js +31 -15
- package/dist/tools/tool-registry/group-infra.js +27 -110
- package/dist/tools/tool-registry/group-quality-compliance.js +26 -26
- package/dist/tools/tool-registry/inventory.d.ts +2 -0
- package/dist/tools/tool-registry/inventory.js +2 -0
- package/dist/tools/tool-registry-helpers.d.ts +3 -3
- package/dist/tools/tool-registry-helpers.js +3 -3
- package/dist/tools/tool-usage-report/registered-tools.d.ts +1 -1
- package/dist/tools/tool-usage-report/registered-tools.js +3 -15
- package/dist/tools/update-status/approval-gates.js +3 -0
- package/dist/tools/update-status/batch.d.ts +6 -2
- package/dist/tools/update-status/batch.js +58 -1
- package/dist/tools/update-status/dod-gates.d.ts +16 -1
- package/dist/tools/update-status/dod-gates.js +191 -1
- package/dist/tools/update-status/done-receipt-verifier.d.ts +8 -0
- package/dist/tools/update-status/done-receipt-verifier.js +75 -27
- package/dist/tools/update-status/evidence-gate.d.ts +4 -0
- package/dist/tools/update-status/evidence-gate.js +103 -3
- package/dist/tools/update-status/file-sync.d.ts +4 -3
- package/dist/tools/update-status/file-sync.js +57 -6
- package/dist/tools/update-status/index.d.ts +25 -1
- package/dist/tools/update-status/index.js +292 -78
- package/dist/tools/update-status/response-builder.js +3 -3
- package/dist/tools/update-status/side-effects.d.ts +2 -0
- package/dist/tools/update-status/side-effects.js +2 -2
- package/dist/tools/update-status/transition-guard.js +45 -16
- package/dist/tools/update-status-actions.d.ts +4 -2
- package/dist/tools/update-status-actions.js +16 -14
- package/dist/tools/usage-report.js +1 -16
- package/dist/tools/usage-stats.js +1 -18
- package/dist/tools/usage-tracking.d.ts +4 -0
- package/dist/tools/usage-tracking.js +20 -0
- package/dist/tools/validate-lint.d.ts +1 -0
- package/dist/tools/validate-lint.js +1 -1
- package/dist/tools/validate.d.ts +2 -1
- package/dist/tools/validate.js +114 -34
- package/dist/tools/workspace-dashboard-handler.js +38 -0
- package/dist/transports/http-transport.js +6 -8
- package/dist/transports/mcp-types.d.ts +0 -2
- package/dist/transports/session-context.js +1 -1
- package/dist/types/cascade-hooks.d.ts +1 -1
- package/dist/types/ci.d.ts +0 -4
- package/dist/types/clarification-token.d.ts +1 -1
- package/dist/types/claude-code-runtime.d.ts +0 -27
- package/dist/types/commercial-migration.d.ts +17 -0
- package/dist/types/commercial-migration.js +2 -0
- package/dist/types/common/primitives.d.ts +0 -2
- package/dist/types/core-bridge.d.ts +4 -10
- package/dist/types/dashboard.d.ts +3 -7
- package/dist/types/docs.d.ts +0 -1
- package/dist/types/durable-job.d.ts +4 -4
- package/dist/types/durable-validation.d.ts +100 -2
- package/dist/types/durable-validation.js +165 -1
- package/dist/types/errors/structured-error.d.ts +3 -3
- package/dist/types/estimation.d.ts +2 -0
- package/dist/types/evidence-autofill.d.ts +34 -0
- package/dist/types/evidence-autofill.js +2 -0
- package/dist/types/evidence-gates.d.ts +9 -1
- package/dist/types/execution.d.ts +2 -0
- package/dist/types/gemini-integration.d.ts +0 -11
- package/dist/types/handoff-artifacts.d.ts +41 -0
- package/dist/types/hooks-advanced.d.ts +0 -13
- package/dist/types/impact-detection.d.ts +2 -2
- package/dist/types/index.d.ts +3 -6
- package/dist/types/index.js +2 -5
- package/dist/types/kiro-integration.d.ts +0 -6
- package/dist/types/network-policy.d.ts +1 -1
- package/dist/types/project/lint-scaffolder.d.ts +1 -1
- package/dist/types/runtime-policy.d.ts +11 -0
- package/dist/types/session-safeguard.d.ts +0 -31
- package/dist/types/spec/canonical-repair.d.ts +81 -0
- package/dist/types/spec/canonical-repair.js +2 -0
- package/dist/types/spec/core.d.ts +20 -0
- package/dist/types/spec/index.d.ts +1 -0
- package/dist/types/spec/index.js +1 -0
- package/dist/types/spec/inputs.d.ts +35 -1
- package/dist/types/spec-format.d.ts +25 -1
- package/dist/types/telemetry.d.ts +4 -1
- package/dist/types/transition-log.d.ts +1 -1
- package/dist/types/transport.d.ts +0 -2
- package/dist/types/usage.d.ts +1 -36
- package/dist/types/usage.js +1 -1
- package/dist/types/validate-worker.d.ts +6 -0
- package/dist/types/validation-receipt.d.ts +1 -1
- package/dist/types/validation.d.ts +10 -4
- package/package.json +17 -12
- package/planu-native.json +1 -1
- package/planu-plugin.json +23 -40
- package/scripts/lib/pending-release-file.mjs +93 -0
- package/src/i18n/messages/en.json +0 -41
- package/src/i18n/messages/es.json +0 -41
- package/src/i18n/messages/pt.json +0 -41
- package/dist/cli/commands/activate.d.ts +0 -14
- package/dist/cli/commands/activate.js +0 -174
- package/dist/config/license-plans.json +0 -251
- package/dist/config/product-public.ts +0 -148
- package/dist/config/server-instructions.ts +0 -121
- package/dist/config/version-defaults.ts +0 -76
- package/dist/config/version.ts +0 -21
- package/dist/engine/ai-integration/gemini/settings-generator.d.ts +0 -4
- package/dist/engine/ai-integration/gemini/settings-generator.js +0 -195
- package/dist/engine/ai-integration/kiro/hooks-generator.d.ts +0 -6
- package/dist/engine/ai-integration/kiro/hooks-generator.js +0 -75
- package/dist/engine/hooks/full-spectrum-generator.d.ts +0 -32
- package/dist/engine/hooks/full-spectrum-generator.js +0 -117
- package/dist/engine/license-validator/config-loader.d.ts +0 -5
- package/dist/engine/license-validator/config-loader.js +0 -16
- package/dist/engine/license-validator/core.d.ts +0 -15
- package/dist/engine/license-validator/core.js +0 -151
- package/dist/engine/license-validator/fingerprint.d.ts +0 -3
- package/dist/engine/license-validator/fingerprint.js +0 -17
- package/dist/engine/license-validator/lemon-squeezy.d.ts +0 -5
- package/dist/engine/license-validator/lemon-squeezy.js +0 -55
- package/dist/engine/license-validator.d.ts +0 -5
- package/dist/engine/license-validator.js +0 -6
- package/dist/engine/product-intelligence/index.d.ts +0 -7
- package/dist/engine/product-intelligence/index.js +0 -211
- package/dist/engine/session/auto-save.d.ts +0 -18
- package/dist/engine/session/auto-save.js +0 -98
- package/dist/engine/session/context-snapshot.d.ts +0 -8
- package/dist/engine/session/context-snapshot.js +0 -49
- package/dist/engine/session/memory-sync.d.ts +0 -12
- package/dist/engine/session/memory-sync.js +0 -34
- package/dist/engine/session/session-diff.d.ts +0 -11
- package/dist/engine/session/session-diff.js +0 -42
- package/dist/engine/session/session-merge.d.ts +0 -12
- package/dist/engine/session/session-merge.js +0 -55
- package/dist/engine/session-safeguard/checkpoint-runner.d.ts +0 -4
- package/dist/engine/session-safeguard/checkpoint-runner.js +0 -70
- package/dist/engine/session-safeguard/learnings-buffer.d.ts +0 -15
- package/dist/engine/session-safeguard/learnings-buffer.js +0 -91
- package/dist/engine/session-safeguard/precompaction-drain.d.ts +0 -10
- package/dist/engine/session-safeguard/precompaction-drain.js +0 -82
- package/dist/engine/session-safeguard/unpushed-detector.d.ts +0 -7
- package/dist/engine/session-safeguard/unpushed-detector.js +0 -59
- package/dist/engine/spec-changelog/core.d.ts +0 -16
- package/dist/engine/spec-changelog/core.js +0 -176
- package/dist/engine/spec-changelog/diff.d.ts +0 -18
- package/dist/engine/spec-changelog/diff.js +0 -121
- package/dist/engine/spec-changelog/index.d.ts +0 -3
- package/dist/engine/spec-changelog/index.js +0 -4
- package/dist/engine/trial-engine.d.ts +0 -5
- package/dist/engine/trial-engine.js +0 -14
- package/dist/engine/usage-tracker/rate-check.d.ts +0 -7
- package/dist/engine/usage-tracker/rate-check.js +0 -18
- package/dist/engine/usage-tracker/rate-limiter.d.ts +0 -14
- package/dist/engine/usage-tracker/rate-limiter.js +0 -73
- package/dist/engine/usage-tracker/trial.d.ts +0 -27
- package/dist/engine/usage-tracker/trial.js +0 -49
- package/dist/engine/webhook/event-handlers.d.ts +0 -25
- package/dist/engine/webhook/event-handlers.js +0 -89
- package/dist/engine/webhook/index.d.ts +0 -4
- package/dist/engine/webhook/index.js +0 -5
- package/dist/engine/webhook/server.d.ts +0 -12
- package/dist/engine/webhook/server.js +0 -249
- package/dist/engine/webhook/signature.d.ts +0 -16
- package/dist/engine/webhook/signature.js +0 -49
- package/dist/storage/license-store.d.ts +0 -6
- package/dist/storage/license-store.js +0 -63
- package/dist/storage/session-store.d.ts +0 -20
- package/dist/storage/session-store.js +0 -136
- package/dist/tools/activate-license.d.ts +0 -6
- package/dist/tools/activate-license.js +0 -132
- package/dist/tools/checkpoint-handler.d.ts +0 -3
- package/dist/tools/checkpoint-handler.js +0 -130
- package/dist/tools/export-session.d.ts +0 -3
- package/dist/tools/export-session.js +0 -90
- package/dist/tools/license-gate.d.ts +0 -18
- package/dist/tools/license-gate.js +0 -222
- package/dist/tools/license-status.d.ts +0 -3
- package/dist/tools/license-status.js +0 -93
- package/dist/tools/list-sessions.d.ts +0 -3
- package/dist/tools/list-sessions.js +0 -46
- package/dist/tools/planu-session-checkpoint.d.ts +0 -6
- package/dist/tools/planu-session-checkpoint.js +0 -42
- package/dist/tools/restore-session.d.ts +0 -3
- package/dist/tools/restore-session.js +0 -71
- package/dist/tools/spec-history.d.ts +0 -3
- package/dist/tools/spec-history.js +0 -59
- package/dist/tools/webhook.d.ts +0 -6
- package/dist/tools/webhook.js +0 -150
- package/dist/types/changelog.d.ts +0 -49
- package/dist/types/changelog.js +0 -3
- package/dist/types/licensing.d.ts +0 -109
- package/dist/types/licensing.js +0 -4
- package/dist/types/product-intelligence.d.ts +0 -60
- package/dist/types/product-intelligence.js +0 -3
- package/dist/types/session.d.ts +0 -84
- package/dist/types/session.js +0 -3
- package/dist/types/webhook.d.ts +0 -62
- package/dist/types/webhook.js +0 -4
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
// engine/license-validator/lemon-squeezy.ts — HTTP client for license API.
|
|
2
|
-
// Supports Planu self-hosted (Supabase Edge Function) and Lemon Squeezy as fallback.
|
|
3
|
-
// Uses native fetch() (Node 18+). No external dependencies.
|
|
4
|
-
const DEFAULT_LICENSE_API = 'https://canusqigtzldstnjddio.supabase.co/functions/v1/license-api';
|
|
5
|
-
const TIMEOUT_MS = 10_000;
|
|
6
|
-
function getBaseUrl() {
|
|
7
|
-
return process.env.SDD_LICENSE_API_URL ?? DEFAULT_LICENSE_API;
|
|
8
|
-
}
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
// Internal helpers
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
async function post(endpoint, body) {
|
|
13
|
-
const controller = new AbortController();
|
|
14
|
-
const timer = setTimeout(() => {
|
|
15
|
-
controller.abort();
|
|
16
|
-
}, TIMEOUT_MS);
|
|
17
|
-
try {
|
|
18
|
-
const res = await fetch(`${getBaseUrl()}/${endpoint}`, {
|
|
19
|
-
method: 'POST',
|
|
20
|
-
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
|
|
21
|
-
body: JSON.stringify(body),
|
|
22
|
-
signal: controller.signal,
|
|
23
|
-
});
|
|
24
|
-
if (!res.ok) {
|
|
25
|
-
const text = await res.text();
|
|
26
|
-
throw new Error(`License API ${endpoint} failed (${String(res.status)}): ${text}`);
|
|
27
|
-
}
|
|
28
|
-
return (await res.json());
|
|
29
|
-
}
|
|
30
|
-
finally {
|
|
31
|
-
clearTimeout(timer);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
// ---------------------------------------------------------------------------
|
|
35
|
-
// Public API
|
|
36
|
-
// ---------------------------------------------------------------------------
|
|
37
|
-
export async function activateLicense(licenseKey, instanceName) {
|
|
38
|
-
return post('activate', {
|
|
39
|
-
licenseKey,
|
|
40
|
-
instanceName,
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
export async function validateLicense(licenseKey, instanceId) {
|
|
44
|
-
return post('validate', {
|
|
45
|
-
licenseKey,
|
|
46
|
-
instanceId,
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
export async function deactivateLicense(licenseKey, instanceId) {
|
|
50
|
-
return post('deactivate', {
|
|
51
|
-
licenseKey,
|
|
52
|
-
instanceId,
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
//# sourceMappingURL=lemon-squeezy.js.map
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { resolveCurrentTier, variantToTier, isToolAllowed, checkToolAccess, getTierLimits, checkLimits, isValidationFresh, isInGracePeriod, isOpenAccessActive, } from './license-validator/core.js';
|
|
2
|
-
export { loadLicensePlans, resetPlanCache } from './license-validator/config-loader.js';
|
|
3
|
-
export { activateLicense, validateLicense, deactivateLicense, } from './license-validator/lemon-squeezy.js';
|
|
4
|
-
export { computeMachineFingerprint, verifyMachineFingerprint, } from './license-validator/fingerprint.js';
|
|
5
|
-
//# sourceMappingURL=license-validator.d.ts.map
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
// engine/license-validator.ts — Barrel re-export for the license validator module.
|
|
2
|
-
export { resolveCurrentTier, variantToTier, isToolAllowed, checkToolAccess, getTierLimits, checkLimits, isValidationFresh, isInGracePeriod, isOpenAccessActive, } from './license-validator/core.js';
|
|
3
|
-
export { loadLicensePlans, resetPlanCache } from './license-validator/config-loader.js';
|
|
4
|
-
export { activateLicense, validateLicense, deactivateLicense, } from './license-validator/lemon-squeezy.js';
|
|
5
|
-
export { computeMachineFingerprint, verifyMachineFingerprint, } from './license-validator/fingerprint.js';
|
|
6
|
-
//# sourceMappingURL=license-validator.js.map
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { ProductInsightsReport, ProductInsightsReport_Report } from '../../types/product-intelligence.js';
|
|
2
|
-
/**
|
|
3
|
-
* Generates a product insights report by querying Supabase telemetry_events.
|
|
4
|
-
* Throws if the HTTP request fails — caller should handle and return isError.
|
|
5
|
-
*/
|
|
6
|
-
export declare function generateProductInsights(report: ProductInsightsReport_Report, periodDays?: number): Promise<ProductInsightsReport>;
|
|
7
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
// engine/product-intelligence/index.ts — SPEC-328: Product Intelligence Layer engine.
|
|
2
|
-
// Queries Supabase telemetry_events to generate product insights reports.
|
|
3
|
-
// Uses the same auth pattern as telemetry-client.ts (fire-and-forget-friendly).
|
|
4
|
-
import { PLANU_VERSION } from '../../config/version.js';
|
|
5
|
-
const SUPABASE_URL = process.env.PLANU_SUPABASE_URL ?? 'https://canusqigtzldstnjddio.supabase.co';
|
|
6
|
-
const SUPABASE_KEY = process.env.PLANU_SUPABASE_KEY ??
|
|
7
|
-
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImNhbnVzcWlndHpsZHN0bmpkZGlvIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NzI3NTk2MjgsImV4cCI6MjA4ODMzNTYyOH0.Thw1Xgf9_iabOD75J00u35d2k5NsIpUBU9PrqOShxMU';
|
|
8
|
-
const TELEMETRY_TABLE = `${SUPABASE_URL}/rest/v1/telemetry_events`;
|
|
9
|
-
/** Core tools expected to be active — used for dead-tool detection. */
|
|
10
|
-
const KNOWN_CORE_TOOLS = [
|
|
11
|
-
'create_spec',
|
|
12
|
-
'list_specs',
|
|
13
|
-
'update_status',
|
|
14
|
-
'validate',
|
|
15
|
-
'estimate',
|
|
16
|
-
'init_project',
|
|
17
|
-
'suggest_stack',
|
|
18
|
-
'generate_tests',
|
|
19
|
-
'generate_docs',
|
|
20
|
-
'challenge_spec',
|
|
21
|
-
'check_readiness',
|
|
22
|
-
'decompose_spec',
|
|
23
|
-
'scan_project',
|
|
24
|
-
'manage_git',
|
|
25
|
-
'product_insights',
|
|
26
|
-
];
|
|
27
|
-
function strProp(props, key) {
|
|
28
|
-
const val = props[key];
|
|
29
|
-
return typeof val === 'string' ? val : '';
|
|
30
|
-
}
|
|
31
|
-
async function fetchEvents(sinceIso) {
|
|
32
|
-
const url = new URL(TELEMETRY_TABLE);
|
|
33
|
-
url.searchParams.set('created_at', `gte.${sinceIso}`);
|
|
34
|
-
url.searchParams.set('select', 'event_name,properties,installation_id,created_at');
|
|
35
|
-
url.searchParams.set('limit', '50000');
|
|
36
|
-
const res = await fetch(url.toString(), {
|
|
37
|
-
headers: {
|
|
38
|
-
apikey: SUPABASE_KEY,
|
|
39
|
-
Authorization: `Bearer ${SUPABASE_KEY}`,
|
|
40
|
-
Accept: 'application/json',
|
|
41
|
-
},
|
|
42
|
-
signal: AbortSignal.timeout(15_000),
|
|
43
|
-
});
|
|
44
|
-
if (!res.ok) {
|
|
45
|
-
throw new Error(`Supabase query failed: ${res.status} ${res.statusText}`);
|
|
46
|
-
}
|
|
47
|
-
return (await res.json());
|
|
48
|
-
}
|
|
49
|
-
function buildAdoption(rows, sinceIso) {
|
|
50
|
-
const map = new Map();
|
|
51
|
-
for (const row of rows) {
|
|
52
|
-
const tool = strProp(row.properties, 'tool');
|
|
53
|
-
if (!tool) {
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
const event = row.event_name;
|
|
57
|
-
if (!['tool_used', 'tool_error', 'tool_blocked'].includes(event)) {
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
let stats = map.get(tool);
|
|
61
|
-
if (stats === undefined) {
|
|
62
|
-
stats = { total: 0, installs: new Set(), errors: 0, blocked: 0, lastSeen: sinceIso };
|
|
63
|
-
map.set(tool, stats);
|
|
64
|
-
}
|
|
65
|
-
stats.total += 1;
|
|
66
|
-
stats.installs.add(row.installation_id);
|
|
67
|
-
if (event === 'tool_error') {
|
|
68
|
-
stats.errors += 1;
|
|
69
|
-
}
|
|
70
|
-
if (event === 'tool_blocked') {
|
|
71
|
-
stats.blocked += 1;
|
|
72
|
-
}
|
|
73
|
-
if (row.created_at > stats.lastSeen) {
|
|
74
|
-
stats.lastSeen = row.created_at;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
return Array.from(map.entries()).map(([tool, s]) => ({
|
|
78
|
-
tool,
|
|
79
|
-
totalCalls: s.total,
|
|
80
|
-
uniqueInstalls: s.installs.size,
|
|
81
|
-
errorRate: s.total > 0 ? s.errors / s.total : 0,
|
|
82
|
-
blockedRate: s.total > 0 ? s.blocked / s.total : 0,
|
|
83
|
-
lastSeenAt: s.lastSeen,
|
|
84
|
-
trend: s.total === 1 ? 'new' : 'stable',
|
|
85
|
-
}));
|
|
86
|
-
}
|
|
87
|
-
function buildFriction(rows) {
|
|
88
|
-
const map = new Map();
|
|
89
|
-
for (const row of rows) {
|
|
90
|
-
const tool = strProp(row.properties, 'tool');
|
|
91
|
-
if (!tool) {
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
if (!['tool_used', 'tool_blocked'].includes(row.event_name)) {
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
let s = map.get(tool);
|
|
98
|
-
if (s === undefined) {
|
|
99
|
-
s = { blocked: 0, total: 0, messages: [] };
|
|
100
|
-
map.set(tool, s);
|
|
101
|
-
}
|
|
102
|
-
s.total += 1;
|
|
103
|
-
if (row.event_name === 'tool_blocked') {
|
|
104
|
-
s.blocked += 1;
|
|
105
|
-
const msg = strProp(row.properties, 'message');
|
|
106
|
-
if (msg) {
|
|
107
|
-
s.messages.push(msg);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return Array.from(map.entries())
|
|
112
|
-
.filter(([, s]) => s.blocked > 0)
|
|
113
|
-
.map(([tool, s]) => {
|
|
114
|
-
const msgCounts = new Map();
|
|
115
|
-
for (const m of s.messages) {
|
|
116
|
-
msgCounts.set(m, (msgCounts.get(m) ?? 0) + 1);
|
|
117
|
-
}
|
|
118
|
-
let topMessage = null;
|
|
119
|
-
let maxCount = 0;
|
|
120
|
-
for (const [m, c] of msgCounts.entries()) {
|
|
121
|
-
if (c > maxCount) {
|
|
122
|
-
maxCount = c;
|
|
123
|
-
topMessage = m;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
return {
|
|
127
|
-
tool,
|
|
128
|
-
blockedCount: s.blocked,
|
|
129
|
-
totalCalls: s.total,
|
|
130
|
-
blockedRate: s.total > 0 ? s.blocked / s.total : 0,
|
|
131
|
-
topMessage,
|
|
132
|
-
};
|
|
133
|
-
})
|
|
134
|
-
.sort((a, b) => b.blockedRate - a.blockedRate);
|
|
135
|
-
}
|
|
136
|
-
function buildVersionAdoption(rows) {
|
|
137
|
-
const map = new Map();
|
|
138
|
-
for (const row of rows) {
|
|
139
|
-
const ver = strProp(row.properties, 'planVersion');
|
|
140
|
-
if (!ver) {
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
let installs = map.get(ver);
|
|
144
|
-
if (installs === undefined) {
|
|
145
|
-
installs = new Set();
|
|
146
|
-
map.set(ver, installs);
|
|
147
|
-
}
|
|
148
|
-
installs.add(row.installation_id);
|
|
149
|
-
}
|
|
150
|
-
const total = Array.from(map.values()).reduce((sum, s) => sum + s.size, 0);
|
|
151
|
-
return Array.from(map.entries())
|
|
152
|
-
.map(([planVersion, installs]) => ({
|
|
153
|
-
planVersion,
|
|
154
|
-
userCount: installs.size,
|
|
155
|
-
pct: total > 0 ? installs.size / total : 0,
|
|
156
|
-
isLatest: planVersion === PLANU_VERSION,
|
|
157
|
-
}))
|
|
158
|
-
.sort((a, b) => b.userCount - a.userCount);
|
|
159
|
-
}
|
|
160
|
-
function buildDeadTools(adoption, sinceIso) {
|
|
161
|
-
const recentlyActive = new Set(adoption.filter((r) => r.lastSeenAt >= sinceIso).map((r) => r.tool));
|
|
162
|
-
return KNOWN_CORE_TOOLS.filter((t) => !recentlyActive.has(t));
|
|
163
|
-
}
|
|
164
|
-
function buildSummary(report) {
|
|
165
|
-
const topTool = report.adoption[0];
|
|
166
|
-
const topFriction = report.frictionPoints[0];
|
|
167
|
-
const lines = [
|
|
168
|
-
`Period: ${report.periodDays}d | Events: ${report.totalEvents} | Installs: ${report.uniqueInstalls}`,
|
|
169
|
-
];
|
|
170
|
-
if (topTool !== undefined) {
|
|
171
|
-
lines.push(`Most used: ${topTool.tool} (${topTool.totalCalls} calls)`);
|
|
172
|
-
}
|
|
173
|
-
if (topFriction !== undefined) {
|
|
174
|
-
lines.push(`Top friction: ${topFriction.tool} (${(topFriction.blockedRate * 100).toFixed(1)}% blocked)`);
|
|
175
|
-
}
|
|
176
|
-
if (report.deadTools.length > 0) {
|
|
177
|
-
lines.push(`Dead tools: ${report.deadTools.join(', ')}`);
|
|
178
|
-
}
|
|
179
|
-
return lines.join(' | ');
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Generates a product insights report by querying Supabase telemetry_events.
|
|
183
|
-
* Throws if the HTTP request fails — caller should handle and return isError.
|
|
184
|
-
*/
|
|
185
|
-
export async function generateProductInsights(report, periodDays = 30) {
|
|
186
|
-
const since = new Date(Date.now() - periodDays * 24 * 60 * 60 * 1000);
|
|
187
|
-
const sinceIso = since.toISOString();
|
|
188
|
-
const rows = await fetchEvents(sinceIso);
|
|
189
|
-
const uniqueInstalls = new Set(rows.map((r) => r.installation_id)).size;
|
|
190
|
-
const adoption = report === 'friction' ? [] : buildAdoption(rows, sinceIso);
|
|
191
|
-
const frictionPoints = report === 'versions' || report === 'dead_tools' ? [] : buildFriction(rows);
|
|
192
|
-
const versionAdoption = report === 'adoption' || report === 'friction' || report === 'dead_tools'
|
|
193
|
-
? []
|
|
194
|
-
: buildVersionAdoption(rows);
|
|
195
|
-
const baseAdoption = adoption.length > 0 ? adoption : buildAdoption(rows, sinceIso);
|
|
196
|
-
const deadTools = report === 'adoption' || report === 'friction' || report === 'versions'
|
|
197
|
-
? []
|
|
198
|
-
: buildDeadTools(baseAdoption, sinceIso);
|
|
199
|
-
const partial = {
|
|
200
|
-
generatedAt: new Date().toISOString(),
|
|
201
|
-
periodDays,
|
|
202
|
-
totalEvents: rows.length,
|
|
203
|
-
uniqueInstalls,
|
|
204
|
-
adoption,
|
|
205
|
-
frictionPoints,
|
|
206
|
-
versionAdoption,
|
|
207
|
-
deadTools,
|
|
208
|
-
};
|
|
209
|
-
return { ...partial, summary: buildSummary(partial) };
|
|
210
|
-
}
|
|
211
|
-
//# sourceMappingURL=index.js.map
|
|
@@ -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
|