@pareto4/pp-core 1.5.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/.claude-plugin/plugin.json +23 -0
- package/GEMINI.md +53 -0
- package/LICENSE +22 -0
- package/README.md +100 -0
- package/agents/pp-advisor-researcher.md +108 -0
- package/agents/pp-ai-researcher.md +114 -0
- package/agents/pp-assumptions-analyzer.md +105 -0
- package/agents/pp-code-fixer.md +669 -0
- package/agents/pp-code-reviewer.md +387 -0
- package/agents/pp-codebase-mapper.md +853 -0
- package/agents/pp-debug-session-manager.md +315 -0
- package/agents/pp-debugger.md +1453 -0
- package/agents/pp-doc-classifier.md +168 -0
- package/agents/pp-doc-synthesizer.md +204 -0
- package/agents/pp-doc-verifier.md +217 -0
- package/agents/pp-doc-writer.md +616 -0
- package/agents/pp-domain-researcher.md +147 -0
- package/agents/pp-eval-auditor.md +191 -0
- package/agents/pp-eval-planner.md +154 -0
- package/agents/pp-executor.md +808 -0
- package/agents/pp-framework-selector.md +160 -0
- package/agents/pp-integration-checker.md +470 -0
- package/agents/pp-intel-updater.md +339 -0
- package/agents/pp-mempalace-curator.md +47 -0
- package/agents/pp-nyquist-auditor.md +204 -0
- package/agents/pp-pattern-mapper.md +335 -0
- package/agents/pp-phase-researcher.md +867 -0
- package/agents/pp-plan-checker.md +988 -0
- package/agents/pp-planner.md +1052 -0
- package/agents/pp-project-researcher.md +612 -0
- package/agents/pp-research-synthesizer.md +260 -0
- package/agents/pp-roadmapper.md +741 -0
- package/agents/pp-security-auditor.md +156 -0
- package/agents/pp-ui-auditor.md +495 -0
- package/agents/pp-ui-checker.md +309 -0
- package/agents/pp-ui-researcher.md +375 -0
- package/agents/pp-user-profiler.md +171 -0
- package/agents/pp-verifier.md +967 -0
- package/assets/gsd-logo-2000-transparent.png +0 -0
- package/assets/gsd-logo-2000-transparent.svg +17 -0
- package/assets/gsd-logo-2000.png +0 -0
- package/assets/gsd-logo-2000.svg +21 -0
- package/assets/terminal.svg +68 -0
- package/bin/install.js +12370 -0
- package/bin/lib/ui-safety-gate.cjs +107 -0
- package/commands/pp-add-tests.md +42 -0
- package/commands/pp-ai-integration-phase.md +37 -0
- package/commands/pp-audit-fix.md +34 -0
- package/commands/pp-audit-milestone.md +37 -0
- package/commands/pp-audit-uat.md +24 -0
- package/commands/pp-autonomous.md +51 -0
- package/commands/pp-capture.md +62 -0
- package/commands/pp-cleanup.md +24 -0
- package/commands/pp-code-review.md +59 -0
- package/commands/pp-complete-milestone.md +143 -0
- package/commands/pp-config.md +56 -0
- package/commands/pp-debug.md +52 -0
- package/commands/pp-discovery.md +34 -0
- package/commands/pp-discuss-phase.md +77 -0
- package/commands/pp-docs-update.md +49 -0
- package/commands/pp-eval-review.md +33 -0
- package/commands/pp-execute-phase.md +65 -0
- package/commands/pp-explore.md +27 -0
- package/commands/pp-extract-learnings.md +23 -0
- package/commands/pp-fast.md +31 -0
- package/commands/pp-forensics.md +57 -0
- package/commands/pp-graphify.md +204 -0
- package/commands/pp-health.md +31 -0
- package/commands/pp-help.md +28 -0
- package/commands/pp-import.md +45 -0
- package/commands/pp-inbox.md +39 -0
- package/commands/pp-ingest-docs.md +42 -0
- package/commands/pp-manager.md +45 -0
- package/commands/pp-map-codebase.md +83 -0
- package/commands/pp-mempalace-capture.md +71 -0
- package/commands/pp-mempalace-recall.md +102 -0
- package/commands/pp-milestone-summary.md +51 -0
- package/commands/pp-mvp-phase.md +45 -0
- package/commands/pp-new-milestone.md +45 -0
- package/commands/pp-new-project.md +47 -0
- package/commands/pp-ns-context.md +25 -0
- package/commands/pp-ns-ideate.md +24 -0
- package/commands/pp-ns-manage.md +36 -0
- package/commands/pp-ns-project.md +27 -0
- package/commands/pp-ns-review.md +29 -0
- package/commands/pp-ns-workflow.md +35 -0
- package/commands/pp-pause-work.md +43 -0
- package/commands/pp-phase.md +56 -0
- package/commands/pp-plan-phase.md +63 -0
- package/commands/pp-plan-review-convergence.md +60 -0
- package/commands/pp-pr-branch.md +26 -0
- package/commands/pp-profile-user.md +46 -0
- package/commands/pp-progress.md +49 -0
- package/commands/pp-quick.md +174 -0
- package/commands/pp-resume-work.md +30 -0
- package/commands/pp-review-backlog.md +63 -0
- package/commands/pp-review.md +42 -0
- package/commands/pp-secure-phase.md +36 -0
- package/commands/pp-settings.md +29 -0
- package/commands/pp-ship.md +24 -0
- package/commands/pp-sketch.md +60 -0
- package/commands/pp-spec-phase.md +63 -0
- package/commands/pp-spike.md +57 -0
- package/commands/pp-stats.md +20 -0
- package/commands/pp-surface.md +162 -0
- package/commands/pp-thread.md +24 -0
- package/commands/pp-ui-phase.md +35 -0
- package/commands/pp-ui-review.md +33 -0
- package/commands/pp-ultraplan-phase.md +34 -0
- package/commands/pp-undo.md +35 -0
- package/commands/pp-update.md +49 -0
- package/commands/pp-validate-phase.md +36 -0
- package/commands/pp-verify-work.md +39 -0
- package/commands/pp-workspace.md +52 -0
- package/commands/pp-workstreams.md +70 -0
- package/gemini-extension.json +6 -0
- package/hooks/dist/lib/git-cmd.js +150 -0
- package/hooks/dist/lib/pp-graphify-rebuild.sh +65 -0
- package/hooks/dist/managed-hooks-registry.cjs +39 -0
- package/hooks/dist/pp-check-update-worker.js +108 -0
- package/hooks/dist/pp-check-update.js +66 -0
- package/hooks/dist/pp-config-reload.js +133 -0
- package/hooks/dist/pp-context-monitor.js +196 -0
- package/hooks/dist/pp-cursor-post-tool.js +75 -0
- package/hooks/dist/pp-cursor-session-start.js +52 -0
- package/hooks/dist/pp-ensure-canonical-path.js +305 -0
- package/hooks/dist/pp-graphify-update.sh +158 -0
- package/hooks/dist/pp-phase-boundary.sh +47 -0
- package/hooks/dist/pp-prompt-guard.js +97 -0
- package/hooks/dist/pp-read-guard.js +101 -0
- package/hooks/dist/pp-read-injection-scanner.js +203 -0
- package/hooks/dist/pp-session-state.sh +59 -0
- package/hooks/dist/pp-statusline.js +566 -0
- package/hooks/dist/pp-update-banner.js +138 -0
- package/hooks/dist/pp-validate-commit.sh +57 -0
- package/hooks/dist/pp-workflow-guard.js +167 -0
- package/hooks/dist/pp-worktree-path-guard.js +185 -0
- package/hooks/hooks.json +70 -0
- package/hooks/lib/git-cmd.js +150 -0
- package/hooks/lib/pp-graphify-rebuild.sh +65 -0
- package/hooks/managed-hooks-registry.cjs +39 -0
- package/hooks/pp-check-update-worker.js +108 -0
- package/hooks/pp-check-update.js +66 -0
- package/hooks/pp-config-reload.js +133 -0
- package/hooks/pp-context-monitor.js +196 -0
- package/hooks/pp-cursor-post-tool.js +75 -0
- package/hooks/pp-cursor-session-start.js +52 -0
- package/hooks/pp-ensure-canonical-path.js +305 -0
- package/hooks/pp-graphify-update.sh +158 -0
- package/hooks/pp-phase-boundary.sh +47 -0
- package/hooks/pp-prompt-guard.js +97 -0
- package/hooks/pp-read-guard.js +101 -0
- package/hooks/pp-read-injection-scanner.js +203 -0
- package/hooks/pp-session-state.sh +59 -0
- package/hooks/pp-statusline.js +566 -0
- package/hooks/pp-update-banner.js +138 -0
- package/hooks/pp-validate-commit.sh +57 -0
- package/hooks/pp-workflow-guard.js +167 -0
- package/hooks/pp-worktree-path-guard.js +185 -0
- package/package.json +125 -0
- package/pp-core/bin/check-latest-version.cjs +161 -0
- package/pp-core/bin/lib/active-workstream-store.cjs +297 -0
- package/pp-core/bin/lib/adr-parser.cjs +399 -0
- package/pp-core/bin/lib/agent-command-router.cjs +68 -0
- package/pp-core/bin/lib/agent-install-check.cjs +143 -0
- package/pp-core/bin/lib/artifacts.cjs +51 -0
- package/pp-core/bin/lib/audit-command-router.cjs +61 -0
- package/pp-core/bin/lib/audit.cjs +743 -0
- package/pp-core/bin/lib/capability-activation.cjs +113 -0
- package/pp-core/bin/lib/capability-registry.cjs +3727 -0
- package/pp-core/bin/lib/capability-state.cjs +497 -0
- package/pp-core/bin/lib/capability-writer.cjs +355 -0
- package/pp-core/bin/lib/check-command-router.cjs +800 -0
- package/pp-core/bin/lib/cjs-command-router-adapter.cjs +81 -0
- package/pp-core/bin/lib/cli-exit.cjs +61 -0
- package/pp-core/bin/lib/clock.cjs +95 -0
- package/pp-core/bin/lib/clusters.cjs +131 -0
- package/pp-core/bin/lib/code-review-flags.cjs +59 -0
- package/pp-core/bin/lib/command-aliases.cjs +809 -0
- package/pp-core/bin/lib/command-arg-projection.cjs +55 -0
- package/pp-core/bin/lib/command-roster.cjs +19 -0
- package/pp-core/bin/lib/command-routing-hub.cjs +300 -0
- package/pp-core/bin/lib/commands.cjs +1244 -0
- package/pp-core/bin/lib/config-loader.cjs +714 -0
- package/pp-core/bin/lib/config-schema.cjs +58 -0
- package/pp-core/bin/lib/config-types.cjs +20 -0
- package/pp-core/bin/lib/config.cjs +796 -0
- package/pp-core/bin/lib/configuration.cjs +209 -0
- package/pp-core/bin/lib/context-utilization.cjs +48 -0
- package/pp-core/bin/lib/core-utils.cjs +198 -0
- package/pp-core/bin/lib/decisions.cjs +136 -0
- package/pp-core/bin/lib/docs.cjs +264 -0
- package/pp-core/bin/lib/drift.cjs +364 -0
- package/pp-core/bin/lib/edge-probe.cjs +196 -0
- package/pp-core/bin/lib/fallow-runner.cjs +153 -0
- package/pp-core/bin/lib/federated-config.cjs +182 -0
- package/pp-core/bin/lib/frontmatter.cjs +494 -0
- package/pp-core/bin/lib/gap-checker.cjs +260 -0
- package/pp-core/bin/lib/git-base-branch.cjs +220 -0
- package/pp-core/bin/lib/graphify-command-router.cjs +72 -0
- package/pp-core/bin/lib/graphify.cjs +472 -0
- package/pp-core/bin/lib/gsd2-import.cjs +456 -0
- package/pp-core/bin/lib/init-command-router.cjs +62 -0
- package/pp-core/bin/lib/init.cjs +1912 -0
- package/pp-core/bin/lib/install-profiles.cjs +814 -0
- package/pp-core/bin/lib/installer-migration-authoring.cjs +122 -0
- package/pp-core/bin/lib/installer-migration-report.cjs +351 -0
- package/pp-core/bin/lib/installer-migrations/000-first-time-baseline.cjs +225 -0
- package/pp-core/bin/lib/installer-migrations/001-legacy-orphan-files.cjs +48 -0
- package/pp-core/bin/lib/installer-migrations/002-codex-legacy-hooks-json.cjs +94 -0
- package/pp-core/bin/lib/installer-migrations/003-rename-get-shit-done-to-gsd-core.cjs +108 -0
- package/pp-core/bin/lib/installer-migrations/004-prune-stale-pristine-snapshots.cjs +123 -0
- package/pp-core/bin/lib/installer-migrations/005-rename-gsd-core-to-pp-core.cjs +109 -0
- package/pp-core/bin/lib/installer-migrations/006-rename-gsd-command-namespace.cjs +135 -0
- package/pp-core/bin/lib/installer-migrations.cjs +823 -0
- package/pp-core/bin/lib/intel-command-router.cjs +119 -0
- package/pp-core/bin/lib/intel.cjs +584 -0
- package/pp-core/bin/lib/io.cjs +220 -0
- package/pp-core/bin/lib/learnings.cjs +270 -0
- package/pp-core/bin/lib/legacy-cleanup.cjs +253 -0
- package/pp-core/bin/lib/loop-host-contract.cjs +105 -0
- package/pp-core/bin/lib/loop-resolver.cjs +479 -0
- package/pp-core/bin/lib/milestone.cjs +381 -0
- package/pp-core/bin/lib/model-catalog.cjs +154 -0
- package/pp-core/bin/lib/model-profiles.cjs +24 -0
- package/pp-core/bin/lib/model-resolver.cjs +467 -0
- package/pp-core/bin/lib/observability/event.cjs +51 -0
- package/pp-core/bin/lib/observability/logger.cjs +146 -0
- package/pp-core/bin/lib/observability/redaction.cjs +48 -0
- package/pp-core/bin/lib/package-identity.cjs +35 -0
- package/pp-core/bin/lib/package-legitimacy.cjs +368 -0
- package/pp-core/bin/lib/phase-command-router.cjs +209 -0
- package/pp-core/bin/lib/phase-id.cjs +213 -0
- package/pp-core/bin/lib/phase-lifecycle.cjs +74 -0
- package/pp-core/bin/lib/phase-locator.cjs +145 -0
- package/pp-core/bin/lib/phase.cjs +1446 -0
- package/pp-core/bin/lib/phases-command-router.cjs +43 -0
- package/pp-core/bin/lib/plan-drift-guard.cjs +117 -0
- package/pp-core/bin/lib/plan-scan.cjs +91 -0
- package/pp-core/bin/lib/planning-workspace.cjs +245 -0
- package/pp-core/bin/lib/probe-core.cjs +402 -0
- package/pp-core/bin/lib/profile-output.cjs +1164 -0
- package/pp-core/bin/lib/profile-pipeline-command-router.cjs +138 -0
- package/pp-core/bin/lib/profile-pipeline.cjs +519 -0
- package/pp-core/bin/lib/prohibition-enforcement.cjs +660 -0
- package/pp-core/bin/lib/project-root.cjs +119 -0
- package/pp-core/bin/lib/prompt-budget.cjs +305 -0
- package/pp-core/bin/lib/research-provider.cjs +137 -0
- package/pp-core/bin/lib/research-store.cjs +167 -0
- package/pp-core/bin/lib/review-reviewer-selection.cjs +121 -0
- package/pp-core/bin/lib/roadmap-command-router.cjs +166 -0
- package/pp-core/bin/lib/roadmap-parser.cjs +456 -0
- package/pp-core/bin/lib/roadmap-upgrade.cjs +476 -0
- package/pp-core/bin/lib/roadmap.cjs +738 -0
- package/pp-core/bin/lib/runtime-artifact-conversion.cjs +1966 -0
- package/pp-core/bin/lib/runtime-artifact-layout.cjs +342 -0
- package/pp-core/bin/lib/runtime-config-adapter-registry.cjs +103 -0
- package/pp-core/bin/lib/runtime-homes.cjs +272 -0
- package/pp-core/bin/lib/runtime-hooks-surface.cjs +1460 -0
- package/pp-core/bin/lib/runtime-name-policy.cjs +97 -0
- package/pp-core/bin/lib/runtime-slash.cjs +137 -0
- package/pp-core/bin/lib/schema-detect.cjs +159 -0
- package/pp-core/bin/lib/secrets.cjs +34 -0
- package/pp-core/bin/lib/security.cjs +480 -0
- package/pp-core/bin/lib/semver-compare.cjs +42 -0
- package/pp-core/bin/lib/shell-command-projection.cjs +550 -0
- package/pp-core/bin/lib/state-command-router.cjs +172 -0
- package/pp-core/bin/lib/state-document.cjs +312 -0
- package/pp-core/bin/lib/state.cjs +2587 -0
- package/pp-core/bin/lib/surface.cjs +505 -0
- package/pp-core/bin/lib/task-command-router.cjs +85 -0
- package/pp-core/bin/lib/teams-status.cjs +74 -0
- package/pp-core/bin/lib/template.cjs +246 -0
- package/pp-core/bin/lib/uat-predicate.cjs +329 -0
- package/pp-core/bin/lib/uat.cjs +359 -0
- package/pp-core/bin/lib/ui-safety-gate.cjs +98 -0
- package/pp-core/bin/lib/update-context.cjs +221 -0
- package/pp-core/bin/lib/validate-command-router.cjs +91 -0
- package/pp-core/bin/lib/validate.cjs +122 -0
- package/pp-core/bin/lib/verification-command-router.cjs +31 -0
- package/pp-core/bin/lib/verification.cjs +196 -0
- package/pp-core/bin/lib/verify-command-router.cjs +44 -0
- package/pp-core/bin/lib/verify.cjs +1932 -0
- package/pp-core/bin/lib/workstream-inventory-builder.cjs +81 -0
- package/pp-core/bin/lib/workstream-inventory.cjs +147 -0
- package/pp-core/bin/lib/workstream-name-policy.cjs +91 -0
- package/pp-core/bin/lib/workstream.cjs +386 -0
- package/pp-core/bin/lib/worktree-base-ref.cjs +350 -0
- package/pp-core/bin/lib/worktree-safety.cjs +985 -0
- package/pp-core/bin/pp-tools.cjs +2239 -0
- package/pp-core/bin/pp_run +20 -0
- package/pp-core/bin/shared/config-defaults.manifest.json +97 -0
- package/pp-core/bin/shared/config-schema.manifest.json +176 -0
- package/pp-core/bin/shared/model-catalog.json +160 -0
- package/pp-core/bin/shared/runtime-aliases.manifest.json +79 -0
- package/pp-core/bin/verify-reapply-patches.cjs +400 -0
- package/pp-core/contexts/dev.md +21 -0
- package/pp-core/contexts/research.md +22 -0
- package/pp-core/contexts/review.md +23 -0
- package/pp-core/references/agent-contracts.md +79 -0
- package/pp-core/references/ai-evals.md +156 -0
- package/pp-core/references/ai-frameworks.md +186 -0
- package/pp-core/references/artifact-types.md +131 -0
- package/pp-core/references/autonomous-smart-discuss.md +277 -0
- package/pp-core/references/checkpoints.md +814 -0
- package/pp-core/references/common-bug-patterns.md +114 -0
- package/pp-core/references/context-budget.md +85 -0
- package/pp-core/references/continuation-format.md +253 -0
- package/pp-core/references/debugger-philosophy.md +76 -0
- package/pp-core/references/decimal-phase-calculation.md +64 -0
- package/pp-core/references/doc-conflict-engine.md +91 -0
- package/pp-core/references/domain-probes.md +125 -0
- package/pp-core/references/edge-probe-fixtures/01-round-half-even/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/01-round-half-even/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/02-merge-intervals/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/02-merge-intervals/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/03-truncate-graphemes/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/04-money-rounding/expected-coverage.json +7 -0
- package/pp-core/references/edge-probe-fixtures/04-money-rounding/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/05-list-dedupe/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/05-list-dedupe/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/expected-coverage.json +8 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/requirements.json +1 -0
- package/pp-core/references/edge-probe-fixtures/06-resolved-mixed/resolutions.json +4 -0
- package/pp-core/references/edge-probe.md +272 -0
- package/pp-core/references/execute-mvp-tdd.md +81 -0
- package/pp-core/references/executor-examples.md +110 -0
- package/pp-core/references/few-shot-examples/plan-checker.md +73 -0
- package/pp-core/references/few-shot-examples/verifier.md +109 -0
- package/pp-core/references/gate-prompts.md +100 -0
- package/pp-core/references/gates.md +70 -0
- package/pp-core/references/git-integration.md +298 -0
- package/pp-core/references/git-planning-commit.md +40 -0
- package/pp-core/references/ios-scaffold.md +123 -0
- package/pp-core/references/loop-hook-dispatch.md +61 -0
- package/pp-core/references/mandatory-initial-read.md +2 -0
- package/pp-core/references/model-profile-resolution.md +38 -0
- package/pp-core/references/model-profiles.md +245 -0
- package/pp-core/references/mvp-concepts.md +49 -0
- package/pp-core/references/phase-argument-parsing.md +61 -0
- package/pp-core/references/planner-antipatterns.md +176 -0
- package/pp-core/references/planner-chunked.md +49 -0
- package/pp-core/references/planner-gap-closure.md +62 -0
- package/pp-core/references/planner-graphify-auto-update.md +67 -0
- package/pp-core/references/planner-guidance.md +186 -0
- package/pp-core/references/planner-human-verify-mode.md +57 -0
- package/pp-core/references/planner-interface-context.md +62 -0
- package/pp-core/references/planner-load-graph-context.md +36 -0
- package/pp-core/references/planner-mvp-mode.md +53 -0
- package/pp-core/references/planner-reviews.md +42 -0
- package/pp-core/references/planner-revision.md +87 -0
- package/pp-core/references/planner-source-audit.md +73 -0
- package/pp-core/references/planning-config.md +477 -0
- package/pp-core/references/prohibition-probe-fixtures/01-streak-reminder/expected.json +14 -0
- package/pp-core/references/prohibition-probe-fixtures/02-clean-utility/expected.json +4 -0
- package/pp-core/references/prohibition-probe-fixtures/03-multi-prohibition/expected.json +32 -0
- package/pp-core/references/prohibition-probe.md +326 -0
- package/pp-core/references/project-skills-discovery.md +19 -0
- package/pp-core/references/questioning.md +162 -0
- package/pp-core/references/research-documentation-lookup.md +29 -0
- package/pp-core/references/research-philosophy.md +29 -0
- package/pp-core/references/research-verification-protocol.md +27 -0
- package/pp-core/references/revision-loop.md +97 -0
- package/pp-core/references/scout-codebase.md +51 -0
- package/pp-core/references/skeleton-template.md +48 -0
- package/pp-core/references/sketch-interactivity.md +41 -0
- package/pp-core/references/sketch-theme-system.md +94 -0
- package/pp-core/references/sketch-tooling.md +45 -0
- package/pp-core/references/sketch-variant-patterns.md +81 -0
- package/pp-core/references/spidr-splitting.md +69 -0
- package/pp-core/references/tdd.md +330 -0
- package/pp-core/references/thinking-models-debug.md +44 -0
- package/pp-core/references/thinking-models-execution.md +50 -0
- package/pp-core/references/thinking-models-planning.md +62 -0
- package/pp-core/references/thinking-models-research.md +50 -0
- package/pp-core/references/thinking-models-verification.md +55 -0
- package/pp-core/references/thinking-partner.md +96 -0
- package/pp-core/references/ui-brand.md +162 -0
- package/pp-core/references/universal-anti-patterns.md +63 -0
- package/pp-core/references/user-profiling.md +681 -0
- package/pp-core/references/user-story-template.md +58 -0
- package/pp-core/references/verification-overrides.md +227 -0
- package/pp-core/references/verification-patterns.md +612 -0
- package/pp-core/references/verify-mvp-mode.md +85 -0
- package/pp-core/references/workstream-flag.md +111 -0
- package/pp-core/references/worktree-branch-check.md +44 -0
- package/pp-core/references/worktree-path-safety.md +67 -0
- package/pp-core/templates/AI-SPEC.md +246 -0
- package/pp-core/templates/DEBUG.md +169 -0
- package/pp-core/templates/README.md +77 -0
- package/pp-core/templates/SECURITY.md +61 -0
- package/pp-core/templates/UAT.md +265 -0
- package/pp-core/templates/UI-SPEC.md +100 -0
- package/pp-core/templates/VALIDATION.md +76 -0
- package/pp-core/templates/claude-md.md +145 -0
- package/pp-core/templates/codebase/architecture.md +255 -0
- package/pp-core/templates/codebase/concerns.md +310 -0
- package/pp-core/templates/codebase/conventions.md +307 -0
- package/pp-core/templates/codebase/integrations.md +280 -0
- package/pp-core/templates/codebase/stack.md +186 -0
- package/pp-core/templates/codebase/structure.md +285 -0
- package/pp-core/templates/codebase/testing.md +480 -0
- package/pp-core/templates/config.json +62 -0
- package/pp-core/templates/context.md +352 -0
- package/pp-core/templates/continue-here.md +78 -0
- package/pp-core/templates/copilot-instructions.md +7 -0
- package/pp-core/templates/debug-subagent-prompt.md +91 -0
- package/pp-core/templates/dev-preferences.md +21 -0
- package/pp-core/templates/discovery.md +146 -0
- package/pp-core/templates/discussion-log.md +63 -0
- package/pp-core/templates/milestone-archive.md +123 -0
- package/pp-core/templates/milestone.md +115 -0
- package/pp-core/templates/phase-prompt.md +610 -0
- package/pp-core/templates/planner-subagent-prompt.md +117 -0
- package/pp-core/templates/project.md +203 -0
- package/pp-core/templates/requirements.md +231 -0
- package/pp-core/templates/research-project/ARCHITECTURE.md +204 -0
- package/pp-core/templates/research-project/FEATURES.md +147 -0
- package/pp-core/templates/research-project/PITFALLS.md +200 -0
- package/pp-core/templates/research-project/STACK.md +120 -0
- package/pp-core/templates/research-project/SUMMARY.md +170 -0
- package/pp-core/templates/research.md +592 -0
- package/pp-core/templates/retrospective.md +54 -0
- package/pp-core/templates/roadmap.md +202 -0
- package/pp-core/templates/spec.md +333 -0
- package/pp-core/templates/state.md +195 -0
- package/pp-core/templates/summary-complex.md +60 -0
- package/pp-core/templates/summary-minimal.md +42 -0
- package/pp-core/templates/summary-standard.md +49 -0
- package/pp-core/templates/summary.md +249 -0
- package/pp-core/templates/user-profile.md +146 -0
- package/pp-core/templates/user-setup.md +311 -0
- package/pp-core/templates/verification-report.md +335 -0
- package/pp-core/workflows/_runtime-launcher.snippet.sh +1 -0
- package/pp-core/workflows/add-backlog.md +91 -0
- package/pp-core/workflows/add-phase.md +113 -0
- package/pp-core/workflows/add-tests.md +355 -0
- package/pp-core/workflows/add-todo.md +161 -0
- package/pp-core/workflows/ai-integration-phase.md +295 -0
- package/pp-core/workflows/analyze-dependencies.md +96 -0
- package/pp-core/workflows/audit-fix.md +178 -0
- package/pp-core/workflows/audit-milestone.md +362 -0
- package/pp-core/workflows/audit-uat.md +110 -0
- package/pp-core/workflows/autonomous.md +886 -0
- package/pp-core/workflows/check-todos.md +180 -0
- package/pp-core/workflows/cleanup.md +195 -0
- package/pp-core/workflows/code-review-fix.md +506 -0
- package/pp-core/workflows/code-review.md +696 -0
- package/pp-core/workflows/complete-milestone.md +857 -0
- package/pp-core/workflows/debug.md +237 -0
- package/pp-core/workflows/diagnose-issues.md +245 -0
- package/pp-core/workflows/discovery-phase.md +291 -0
- package/pp-core/workflows/discovery-sprint.md +1546 -0
- package/pp-core/workflows/discuss-phase/modes/advisor.md +176 -0
- package/pp-core/workflows/discuss-phase/modes/all.md +28 -0
- package/pp-core/workflows/discuss-phase/modes/analyze.md +44 -0
- package/pp-core/workflows/discuss-phase/modes/auto.md +57 -0
- package/pp-core/workflows/discuss-phase/modes/batch.md +52 -0
- package/pp-core/workflows/discuss-phase/modes/chain.md +98 -0
- package/pp-core/workflows/discuss-phase/modes/default.md +141 -0
- package/pp-core/workflows/discuss-phase/modes/power.md +44 -0
- package/pp-core/workflows/discuss-phase/modes/text.md +55 -0
- package/pp-core/workflows/discuss-phase/templates/checkpoint.json +18 -0
- package/pp-core/workflows/discuss-phase/templates/context.md +136 -0
- package/pp-core/workflows/discuss-phase/templates/discussion-log.md +50 -0
- package/pp-core/workflows/discuss-phase-assumptions.md +675 -0
- package/pp-core/workflows/discuss-phase-power.md +291 -0
- package/pp-core/workflows/discuss-phase.md +520 -0
- package/pp-core/workflows/do.md +111 -0
- package/pp-core/workflows/docs-update.md +1168 -0
- package/pp-core/workflows/edit-phase.md +295 -0
- package/pp-core/workflows/eval-review.md +159 -0
- package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +95 -0
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +94 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +117 -0
- package/pp-core/workflows/execute-phase/steps/worktree-recovery-policy.md +9 -0
- package/pp-core/workflows/execute-phase.md +1707 -0
- package/pp-core/workflows/execute-plan.md +541 -0
- package/pp-core/workflows/explore.md +146 -0
- package/pp-core/workflows/extract-learnings.md +243 -0
- package/pp-core/workflows/fast.md +124 -0
- package/pp-core/workflows/forensics.md +279 -0
- package/pp-core/workflows/graduation.md +196 -0
- package/pp-core/workflows/health.md +224 -0
- package/pp-core/workflows/help/modes/brief.md +22 -0
- package/pp-core/workflows/help/modes/default.md +50 -0
- package/pp-core/workflows/help/modes/full.md +791 -0
- package/pp-core/workflows/help/modes/topic.md +74 -0
- package/pp-core/workflows/help.md +24 -0
- package/pp-core/workflows/import.md +256 -0
- package/pp-core/workflows/inbox.md +387 -0
- package/pp-core/workflows/ingest-docs.md +340 -0
- package/pp-core/workflows/insert-phase.md +152 -0
- package/pp-core/workflows/list-phase-assumptions.md +178 -0
- package/pp-core/workflows/list-workspaces.md +57 -0
- package/pp-core/workflows/manager.md +435 -0
- package/pp-core/workflows/map-codebase.md +444 -0
- package/pp-core/workflows/milestone-summary.md +224 -0
- package/pp-core/workflows/mvp-phase.md +222 -0
- package/pp-core/workflows/new-milestone.md +643 -0
- package/pp-core/workflows/new-project.md +1563 -0
- package/pp-core/workflows/new-workspace.md +240 -0
- package/pp-core/workflows/next.md +347 -0
- package/pp-core/workflows/node-repair.md +92 -0
- package/pp-core/workflows/note.md +158 -0
- package/pp-core/workflows/pause-work.md +250 -0
- package/pp-core/workflows/plan-milestone-gaps.md +281 -0
- package/pp-core/workflows/plan-phase.md +1755 -0
- package/pp-core/workflows/plan-review-convergence.md +369 -0
- package/pp-core/workflows/plant-seed.md +230 -0
- package/pp-core/workflows/pr-branch.md +159 -0
- package/pp-core/workflows/profile-user.md +455 -0
- package/pp-core/workflows/progress.md +756 -0
- package/pp-core/workflows/quick.md +1045 -0
- package/pp-core/workflows/reapply-patches.md +443 -0
- package/pp-core/workflows/remove-phase.md +156 -0
- package/pp-core/workflows/remove-workspace.md +108 -0
- package/pp-core/workflows/resume-project.md +348 -0
- package/pp-core/workflows/review.md +765 -0
- package/pp-core/workflows/scan.md +107 -0
- package/pp-core/workflows/secure-phase.md +184 -0
- package/pp-core/workflows/session-report.md +146 -0
- package/pp-core/workflows/settings-advanced.md +816 -0
- package/pp-core/workflows/settings-integrations.md +312 -0
- package/pp-core/workflows/settings.md +592 -0
- package/pp-core/workflows/ship.md +465 -0
- package/pp-core/workflows/sketch-wrap-up.md +286 -0
- package/pp-core/workflows/sketch.md +361 -0
- package/pp-core/workflows/spec-phase.md +495 -0
- package/pp-core/workflows/spike-wrap-up.md +307 -0
- package/pp-core/workflows/spike.md +453 -0
- package/pp-core/workflows/stats.md +80 -0
- package/pp-core/workflows/sync-skills.md +182 -0
- package/pp-core/workflows/thread.md +222 -0
- package/pp-core/workflows/transition.md +694 -0
- package/pp-core/workflows/ui-phase.md +328 -0
- package/pp-core/workflows/ui-review.md +193 -0
- package/pp-core/workflows/ultraplan-phase.md +199 -0
- package/pp-core/workflows/undo.md +314 -0
- package/pp-core/workflows/update.md +501 -0
- package/pp-core/workflows/validate-phase.md +183 -0
- package/pp-core/workflows/verify-phase.md +569 -0
- package/pp-core/workflows/verify-work.md +804 -0
- package/scripts/affected-tests-lib.cjs +554 -0
- package/scripts/audit-workflow-script-paths.cjs +73 -0
- package/scripts/base64-scan.sh +351 -0
- package/scripts/build-hooks.js +254 -0
- package/scripts/changeset/README.md +129 -0
- package/scripts/changeset/cli.cjs +597 -0
- package/scripts/changeset/github-release-notes.cjs +199 -0
- package/scripts/changeset/lint.cjs +147 -0
- package/scripts/changeset/new.cjs +151 -0
- package/scripts/changeset/parse.cjs +114 -0
- package/scripts/changeset/render.cjs +34 -0
- package/scripts/changeset/serialize.cjs +130 -0
- package/scripts/check-alias-drift.cjs +114 -0
- package/scripts/check-env.cjs +312 -0
- package/scripts/check-npm-integrity.cjs +215 -0
- package/scripts/ci-guard-runner.cjs +22 -0
- package/scripts/ci-prepare-test-scope.cjs +93 -0
- package/scripts/ci-rebase-check.cjs +86 -0
- package/scripts/ci-test-scope.cjs +441 -0
- package/scripts/command-contract-helpers.cjs +64 -0
- package/scripts/diff-touches-shipped-paths.cjs +149 -0
- package/scripts/fix-slash-commands.cjs +161 -0
- package/scripts/gen-capability-registry.cjs +2646 -0
- package/scripts/gen-commands-reference.cjs +139 -0
- package/scripts/gen-inventory-manifest.cjs +114 -0
- package/scripts/gen-loop-host-contract.cjs +526 -0
- package/scripts/gen-research-agents.cjs +276 -0
- package/scripts/generate-package-identity.cjs +134 -0
- package/scripts/issue-dedupe.cjs +278 -0
- package/scripts/issue-version-gate.cjs +140 -0
- package/scripts/lib/allowlist-ratchet.cjs +236 -0
- package/scripts/lib/cli-exit.cjs +56 -0
- package/scripts/lint-allow-test-rule-refs.allowlist.json +328 -0
- package/scripts/lint-allow-test-rule-refs.cjs +162 -0
- package/scripts/lint-command-contract.cjs +118 -0
- package/scripts/lint-descriptions.cjs +87 -0
- package/scripts/lint-docs-required.cjs +222 -0
- package/scripts/lint-legacy-dir-name.cjs +166 -0
- package/scripts/lint-package-identity-drift.cjs +141 -0
- package/scripts/lint-pr-check-project-dir.cjs +99 -0
- package/scripts/lint-regression-test-names.allowlist.json +269 -0
- package/scripts/lint-regression-test-names.cjs +117 -0
- package/scripts/lint-shell-command-projection-drift.cjs +62 -0
- package/scripts/lint-skill-deps.cjs +185 -0
- package/scripts/lint-test-file-count.allowlist.json +181 -0
- package/scripts/lint-test-file-count.cjs +246 -0
- package/scripts/lint-windows-test-portability.cjs +178 -0
- package/scripts/mutation-matrix.cjs +323 -0
- package/scripts/pr-target-policy.cjs +63 -0
- package/scripts/pr-template-policy.cjs +268 -0
- package/scripts/prompt-injection-scan.sh +207 -0
- package/scripts/registry-smoke.cjs +337 -0
- package/scripts/release-notes/discord-release-summary.cjs +373 -0
- package/scripts/release-notes/format-github-release-notes.cjs +261 -0
- package/scripts/release-tarball-smoke.cjs +763 -0
- package/scripts/research-profiles.cjs +149 -0
- package/scripts/run-affected-tests.cjs +7 -0
- package/scripts/run-tests.cjs +589 -0
- package/scripts/secret-scan-lint.sh +231 -0
- package/scripts/secret-scan.sh +358 -0
- package/scripts/setup-branch-protection.sh +234 -0
- package/scripts/strip-prose-atrefs.cjs +106 -0
- package/scripts/sync-manifest-versions.cjs +119 -0
- package/scripts/sync-next-version.cjs +133 -0
- package/scripts/sync-rulesets.sh +34 -0
- package/scripts/sync-runtime-launcher.cjs +425 -0
- package/scripts/test-failure-reasons.cjs +34 -0
- package/scripts/update-size-baseline.cjs +68 -0
- package/scripts/verify-npm-publish.cjs +240 -0
- package/scripts/verify-opengsd-sweep.cjs +288 -0
- package/scripts/verify-phase-02-rename.sh +258 -0
- package/scripts/verify-phase-03-rename.sh +376 -0
- package/scripts/workflow-policy.cjs +483 -0
- package/scripts/workflow-size.cjs +90 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
/**
|
|
3
|
+
* Profile-pipeline command router — CLI dispatcher for gsd-tools profiling commands.
|
|
4
|
+
*
|
|
5
|
+
* ADR-857 phase 6 / ADR-959: profile-pipeline capability command cutover.
|
|
6
|
+
* Extracted from hardcoded case arms in gsd-tools.cjs (lines 1324-1410).
|
|
7
|
+
* Dispatch path: default → dispatchCapabilityCommand →
|
|
8
|
+
* require(profile-pipeline-command-router.cjs) → route<X>.
|
|
9
|
+
*
|
|
10
|
+
* Router signature: { args, cwd, raw, error } — identical to existing routers.
|
|
11
|
+
* Test seams: _pipeline / _output inject mock modules; _core injects mock core.
|
|
12
|
+
*
|
|
13
|
+
* Async note: cmdExtractMessages and cmdProfileSample are async functions.
|
|
14
|
+
* dispatchCapabilityCommand (gsd-tools.cjs:366-371) explicitly errors if a
|
|
15
|
+
* router returns a Promise. Therefore these router functions call the async
|
|
16
|
+
* function WITHOUT await and WITHOUT returning the Promise. The async functions
|
|
17
|
+
* end with output() or process.exit() so the process terminates correctly once
|
|
18
|
+
* the event loop drains. Unhandled rejections are caught by the .catch() wrapper
|
|
19
|
+
* to surface errors via the error() callback.
|
|
20
|
+
*/
|
|
21
|
+
const { ERROR_REASON } = require('./io.cjs');
|
|
22
|
+
|
|
23
|
+
// ─── Pipeline phase commands ───────────────────────────────────────────────────
|
|
24
|
+
|
|
25
|
+
function routeScanSessions({ args, cwd, raw, error, _pipeline }) {
|
|
26
|
+
void cwd; void error;
|
|
27
|
+
const p = _pipeline ?? require('./profile-pipeline.cjs');
|
|
28
|
+
const pathIdx = args.indexOf('--path');
|
|
29
|
+
const sessionsPath = pathIdx !== -1 ? args[pathIdx + 1] : null;
|
|
30
|
+
const verboseFlag = args.includes('--verbose');
|
|
31
|
+
const jsonFlag = args.includes('--json');
|
|
32
|
+
// cmdScanSessions is synchronous — call directly.
|
|
33
|
+
p.cmdScanSessions(sessionsPath, { verbose: verboseFlag, json: jsonFlag }, raw);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function routeExtractMessages({ args, cwd, raw, error, _pipeline }) {
|
|
37
|
+
const p = _pipeline ?? require('./profile-pipeline.cjs');
|
|
38
|
+
const sessionIdx = args.indexOf('--session');
|
|
39
|
+
const sessionId = sessionIdx !== -1 ? args[sessionIdx + 1] : null;
|
|
40
|
+
const limitIdx = args.indexOf('--limit');
|
|
41
|
+
const limit = limitIdx !== -1 ? parseInt(args[limitIdx + 1], 10) : null;
|
|
42
|
+
const pathIdx = args.indexOf('--path');
|
|
43
|
+
const sessionsPath = pathIdx !== -1 ? args[pathIdx + 1] : null;
|
|
44
|
+
// args[0] = 'extract-messages' (family name), args[1] = project positional
|
|
45
|
+
const projectArg = args[1];
|
|
46
|
+
if (!projectArg || projectArg.startsWith('--')) {
|
|
47
|
+
error('Usage: gsd-tools extract-messages <project> [--session <id>] [--limit N] [--path <dir>]\nRun scan-sessions first to see available projects.', ERROR_REASON.USAGE);
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
// cmdExtractMessages is async — do NOT return the Promise.
|
|
51
|
+
// The function ends with output() or process.exit(); the event loop will drain.
|
|
52
|
+
void cwd;
|
|
53
|
+
p.cmdExtractMessages(projectArg, { sessionId, limit }, raw, sessionsPath)
|
|
54
|
+
.catch(e => { error(e && e.message ? e.message : String(e)); });
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function routeProfileSample({ args, cwd, raw, error, _pipeline }) {
|
|
58
|
+
void cwd; void error;
|
|
59
|
+
const p = _pipeline ?? require('./profile-pipeline.cjs');
|
|
60
|
+
const pathIdx = args.indexOf('--path');
|
|
61
|
+
const sessionsPath = pathIdx !== -1 ? args[pathIdx + 1] : null;
|
|
62
|
+
const limitIdx = args.indexOf('--limit');
|
|
63
|
+
const limit = limitIdx !== -1 ? parseInt(args[limitIdx + 1], 10) : 150;
|
|
64
|
+
const maxPerIdx = args.indexOf('--max-per-project');
|
|
65
|
+
const maxPerProject = maxPerIdx !== -1 ? parseInt(args[maxPerIdx + 1], 10) : null;
|
|
66
|
+
const maxCharsIdx = args.indexOf('--max-chars');
|
|
67
|
+
const maxChars = maxCharsIdx !== -1 ? parseInt(args[maxCharsIdx + 1], 10) : 500;
|
|
68
|
+
// cmdProfileSample is async — do NOT return the Promise.
|
|
69
|
+
p.cmdProfileSample(sessionsPath, { limit, maxPerProject, maxChars }, raw)
|
|
70
|
+
.catch(e => { error(e && e.message ? e.message : String(e)); });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ─── Output phase commands ─────────────────────────────────────────────────────
|
|
74
|
+
|
|
75
|
+
function routeWriteProfile({ args, cwd, raw, error, _output }) {
|
|
76
|
+
const o = _output ?? require('./profile-output.cjs');
|
|
77
|
+
const inputIdx = args.indexOf('--input');
|
|
78
|
+
const inputPath = inputIdx !== -1 ? args[inputIdx + 1] : null;
|
|
79
|
+
if (!inputPath) {
|
|
80
|
+
error('--input <analysis-json-path> is required', ERROR_REASON.USAGE);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const outputIdx = args.indexOf('--output');
|
|
84
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
85
|
+
o.cmdWriteProfile(cwd, { input: inputPath, output: outputPath }, raw);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function routeProfileQuestionnaire({ args, cwd, raw, error, _output }) {
|
|
89
|
+
void cwd; void error;
|
|
90
|
+
const o = _output ?? require('./profile-output.cjs');
|
|
91
|
+
const answersIdx = args.indexOf('--answers');
|
|
92
|
+
const answers = answersIdx !== -1 ? args[answersIdx + 1] : null;
|
|
93
|
+
o.cmdProfileQuestionnaire({ answers }, raw);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function routeGenerateDevPreferences({ args, cwd, raw, error, _output }) {
|
|
97
|
+
void error;
|
|
98
|
+
const o = _output ?? require('./profile-output.cjs');
|
|
99
|
+
const analysisIdx = args.indexOf('--analysis');
|
|
100
|
+
const analysisPath = analysisIdx !== -1 ? args[analysisIdx + 1] : null;
|
|
101
|
+
const outputIdx = args.indexOf('--output');
|
|
102
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
103
|
+
const stackIdx = args.indexOf('--stack');
|
|
104
|
+
const stack = stackIdx !== -1 ? args[stackIdx + 1] : null;
|
|
105
|
+
o.cmdGenerateDevPreferences(cwd, { analysis: analysisPath, output: outputPath, stack }, raw);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function routeGenerateClaudeProfile({ args, cwd, raw, error, _output }) {
|
|
109
|
+
void error;
|
|
110
|
+
const o = _output ?? require('./profile-output.cjs');
|
|
111
|
+
const analysisIdx = args.indexOf('--analysis');
|
|
112
|
+
const analysisPath = analysisIdx !== -1 ? args[analysisIdx + 1] : null;
|
|
113
|
+
const outputIdx = args.indexOf('--output');
|
|
114
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
115
|
+
const globalFlag = args.includes('--global');
|
|
116
|
+
o.cmdGenerateClaudeProfile(cwd, { analysis: analysisPath, output: outputPath, global: globalFlag }, raw);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function routeGenerateClaudeMd({ args, cwd, raw, error, _output }) {
|
|
120
|
+
void error;
|
|
121
|
+
const o = _output ?? require('./profile-output.cjs');
|
|
122
|
+
const outputIdx = args.indexOf('--output');
|
|
123
|
+
const outputPath = outputIdx !== -1 ? args[outputIdx + 1] : null;
|
|
124
|
+
const autoFlag = args.includes('--auto');
|
|
125
|
+
const forceFlag = args.includes('--force');
|
|
126
|
+
o.cmdGenerateClaudeMd(cwd, { output: outputPath, auto: autoFlag, force: forceFlag }, raw);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
module.exports = {
|
|
130
|
+
routeScanSessions,
|
|
131
|
+
routeExtractMessages,
|
|
132
|
+
routeProfileSample,
|
|
133
|
+
routeWriteProfile,
|
|
134
|
+
routeProfileQuestionnaire,
|
|
135
|
+
routeGenerateDevPreferences,
|
|
136
|
+
routeGenerateClaudeProfile,
|
|
137
|
+
routeGenerateClaudeMd,
|
|
138
|
+
};
|
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Profile Pipeline — session scanning, message extraction, and sampling
|
|
4
|
+
*
|
|
5
|
+
* Reads Claude Code session history (read-only) to extract user messages
|
|
6
|
+
* for behavioral profiling. Three commands:
|
|
7
|
+
* - scan-sessions: list all projects and sessions
|
|
8
|
+
* - extract-messages: extract user messages from a specific project
|
|
9
|
+
* - profile-sample: multi-project sampling with recency weighting
|
|
10
|
+
*
|
|
11
|
+
* ADR-457 build-at-publish: the hand-written bin/lib/profile-pipeline.cjs collapsed
|
|
12
|
+
* to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
|
|
13
|
+
* from the prior hand-written .cjs; only strict types are added.
|
|
14
|
+
*/
|
|
15
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
16
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
17
|
+
};
|
|
18
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
19
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
20
|
+
const node_os_1 = __importDefault(require("node:os"));
|
|
21
|
+
const node_readline_1 = __importDefault(require("node:readline"));
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
23
|
+
const ioModule = require("./io.cjs");
|
|
24
|
+
const { output, error, reapStaleTempFiles, ensureGsdTempDir, GSD_TEMP_DIR } = ioModule;
|
|
25
|
+
// ─── Session I/O Helpers ──────────────────────────────────────────────────────
|
|
26
|
+
function getSessionsDir(overridePath) {
|
|
27
|
+
const dir = overridePath || node_path_1.default.join(node_os_1.default.homedir(), '.claude', 'projects');
|
|
28
|
+
if (!node_fs_1.default.existsSync(dir))
|
|
29
|
+
return null;
|
|
30
|
+
return dir;
|
|
31
|
+
}
|
|
32
|
+
function scanProjectDir(projectDirPath) {
|
|
33
|
+
const entries = node_fs_1.default.readdirSync(projectDirPath);
|
|
34
|
+
const sessions = [];
|
|
35
|
+
for (const entry of entries) {
|
|
36
|
+
if (!entry.endsWith('.jsonl'))
|
|
37
|
+
continue;
|
|
38
|
+
const sessionId = entry.replace('.jsonl', '');
|
|
39
|
+
const filePath = node_path_1.default.join(projectDirPath, entry);
|
|
40
|
+
const stat = node_fs_1.default.statSync(filePath);
|
|
41
|
+
sessions.push({
|
|
42
|
+
sessionId,
|
|
43
|
+
filePath,
|
|
44
|
+
size: stat.size,
|
|
45
|
+
modified: stat.mtime,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
sessions.sort((a, b) => b.modified.getTime() - a.modified.getTime());
|
|
49
|
+
return sessions;
|
|
50
|
+
}
|
|
51
|
+
function readSessionIndex(projectDirPath) {
|
|
52
|
+
try {
|
|
53
|
+
const indexPath = node_path_1.default.join(projectDirPath, 'sessions-index.json');
|
|
54
|
+
const raw = node_fs_1.default.readFileSync(indexPath, 'utf-8');
|
|
55
|
+
const parsed = JSON.parse(raw);
|
|
56
|
+
const entries = new Map();
|
|
57
|
+
for (const entry of (parsed.entries || [])) {
|
|
58
|
+
if (entry.sessionId) {
|
|
59
|
+
entries.set(entry.sessionId, entry);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
return { originalPath: parsed.originalPath || null, entries };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return { originalPath: null, entries: new Map() };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function getProjectName(projectDirName, indexData, firstRecordCwd) {
|
|
69
|
+
if (indexData && indexData.originalPath) {
|
|
70
|
+
return node_path_1.default.basename(indexData.originalPath);
|
|
71
|
+
}
|
|
72
|
+
if (firstRecordCwd) {
|
|
73
|
+
return node_path_1.default.basename(firstRecordCwd);
|
|
74
|
+
}
|
|
75
|
+
return projectDirName;
|
|
76
|
+
}
|
|
77
|
+
function formatBytes(bytes) {
|
|
78
|
+
if (bytes < 1024)
|
|
79
|
+
return `${bytes} B`;
|
|
80
|
+
if (bytes < 1048576)
|
|
81
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
82
|
+
if (bytes < 1073741824)
|
|
83
|
+
return `${(bytes / 1048576).toFixed(1)} MB`;
|
|
84
|
+
return `${(bytes / 1073741824).toFixed(1)} GB`;
|
|
85
|
+
}
|
|
86
|
+
function formatProjectTable(projects) {
|
|
87
|
+
let out = '';
|
|
88
|
+
out += 'Project'.padEnd(35) + 'Sessions'.padEnd(10) + 'Size'.padEnd(10) + 'Last Active\n';
|
|
89
|
+
out += '-'.repeat(75) + '\n';
|
|
90
|
+
for (const p of projects) {
|
|
91
|
+
const name = p.name.length > 33 ? p.name.substring(0, 30) + '...' : p.name;
|
|
92
|
+
out += name.padEnd(35) + String(p.sessionCount).padEnd(10) +
|
|
93
|
+
p.totalSizeHuman.padEnd(10) + p.lastActive + '\n';
|
|
94
|
+
}
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
function formatSessionTable(sessions) {
|
|
98
|
+
let out = '';
|
|
99
|
+
out += ' Session ID'.padEnd(42) + 'Size'.padEnd(10) + 'Modified\n';
|
|
100
|
+
out += ' ' + '-'.repeat(70) + '\n';
|
|
101
|
+
for (const s of sessions) {
|
|
102
|
+
const id = s.sessionId.length > 38 ? s.sessionId.substring(0, 35) + '...' : s.sessionId;
|
|
103
|
+
out += ' ' + id.padEnd(40) + formatBytes(s.size).padEnd(10) +
|
|
104
|
+
new Date(s.modified).toISOString().replace('T', ' ').substring(0, 19) + '\n';
|
|
105
|
+
}
|
|
106
|
+
return out;
|
|
107
|
+
}
|
|
108
|
+
// ─── Message Extraction Helpers ───────────────────────────────────────────────
|
|
109
|
+
function isGenuineUserMessage(record) {
|
|
110
|
+
if (record.type !== 'user')
|
|
111
|
+
return false;
|
|
112
|
+
if (record.userType !== 'external')
|
|
113
|
+
return false;
|
|
114
|
+
if (record.isMeta === true)
|
|
115
|
+
return false;
|
|
116
|
+
if (record.isSidechain === true)
|
|
117
|
+
return false;
|
|
118
|
+
const content = record.message?.content;
|
|
119
|
+
if (typeof content !== 'string')
|
|
120
|
+
return false;
|
|
121
|
+
if (content.length === 0)
|
|
122
|
+
return false;
|
|
123
|
+
if (content.startsWith('<local-command'))
|
|
124
|
+
return false;
|
|
125
|
+
if (content.startsWith('<command-'))
|
|
126
|
+
return false;
|
|
127
|
+
if (content.startsWith('<task-notification'))
|
|
128
|
+
return false;
|
|
129
|
+
if (content.startsWith('<local-command-stdout'))
|
|
130
|
+
return false;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
function truncateContent(content, maxLen = 2000) {
|
|
134
|
+
if (content.length <= maxLen)
|
|
135
|
+
return content;
|
|
136
|
+
return content.substring(0, maxLen) + '... [truncated]';
|
|
137
|
+
}
|
|
138
|
+
async function streamExtractMessages(filePath, filterFn, maxMessages = 300) {
|
|
139
|
+
const rl = node_readline_1.default.createInterface({
|
|
140
|
+
input: node_fs_1.default.createReadStream(filePath),
|
|
141
|
+
crlfDelay: Infinity,
|
|
142
|
+
terminal: false,
|
|
143
|
+
});
|
|
144
|
+
const messages = [];
|
|
145
|
+
const sessionId = node_path_1.default.basename(filePath, '.jsonl');
|
|
146
|
+
for await (const line of rl) {
|
|
147
|
+
if (messages.length >= maxMessages)
|
|
148
|
+
break;
|
|
149
|
+
let record;
|
|
150
|
+
try {
|
|
151
|
+
record = JSON.parse(line);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
if (!filterFn(record))
|
|
157
|
+
continue;
|
|
158
|
+
messages.push({
|
|
159
|
+
sessionId,
|
|
160
|
+
projectPath: record.cwd || null,
|
|
161
|
+
timestamp: record.timestamp || null,
|
|
162
|
+
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
163
|
+
content: truncateContent(String(record.message?.content ?? '')),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
return messages;
|
|
167
|
+
}
|
|
168
|
+
// ─── Commands ─────────────────────────────────────────────────────────────────
|
|
169
|
+
function cmdScanSessions(overridePath, options, raw) {
|
|
170
|
+
const sessionsDir = getSessionsDir(overridePath);
|
|
171
|
+
if (!sessionsDir) {
|
|
172
|
+
const searchedPath = overridePath || '~/.claude/projects';
|
|
173
|
+
error(`No Claude Code sessions found at ${searchedPath}.${overridePath ? '' : ' Is Claude Code installed?'}`);
|
|
174
|
+
}
|
|
175
|
+
process.stderr.write('Reading your session history (read-only, nothing is modified or sent anywhere)...\n');
|
|
176
|
+
let projectDirs;
|
|
177
|
+
try {
|
|
178
|
+
projectDirs = node_fs_1.default.readdirSync(sessionsDir).filter(entry => {
|
|
179
|
+
const fullPath = node_path_1.default.join(sessionsDir, entry);
|
|
180
|
+
try {
|
|
181
|
+
return node_fs_1.default.statSync(fullPath).isDirectory();
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
catch (err) {
|
|
189
|
+
error(`Cannot read sessions directory: ${err.message}`);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const projects = [];
|
|
193
|
+
for (const dirName of projectDirs) {
|
|
194
|
+
const projectPath = node_path_1.default.join(sessionsDir, dirName);
|
|
195
|
+
const sessions = scanProjectDir(projectPath);
|
|
196
|
+
if (sessions.length === 0)
|
|
197
|
+
continue;
|
|
198
|
+
const indexData = readSessionIndex(projectPath);
|
|
199
|
+
const projectName = getProjectName(dirName, indexData);
|
|
200
|
+
if (indexData.entries.size === 0 && !options.json) {
|
|
201
|
+
process.stderr.write(`Index not found for ${projectName}, scanning directory...\n`);
|
|
202
|
+
}
|
|
203
|
+
const totalSize = sessions.reduce((sum, s) => sum + s.size, 0);
|
|
204
|
+
const lastActive = sessions[0].modified.toISOString();
|
|
205
|
+
const oldest = sessions[sessions.length - 1].modified.toISOString();
|
|
206
|
+
const newest = sessions[0].modified.toISOString();
|
|
207
|
+
const project = {
|
|
208
|
+
name: projectName,
|
|
209
|
+
directory: dirName,
|
|
210
|
+
sessionCount: sessions.length,
|
|
211
|
+
totalSize,
|
|
212
|
+
totalSizeHuman: formatBytes(totalSize),
|
|
213
|
+
lastActive: lastActive.replace('T', ' ').substring(0, 19),
|
|
214
|
+
dateRange: { first: oldest, last: newest },
|
|
215
|
+
};
|
|
216
|
+
if (options.verbose) {
|
|
217
|
+
project.sessions = sessions.map(s => {
|
|
218
|
+
const indexed = indexData.entries.get(s.sessionId);
|
|
219
|
+
const session = {
|
|
220
|
+
sessionId: s.sessionId,
|
|
221
|
+
size: s.size,
|
|
222
|
+
sizeHuman: formatBytes(s.size),
|
|
223
|
+
modified: s.modified.toISOString(),
|
|
224
|
+
};
|
|
225
|
+
if (indexed) {
|
|
226
|
+
if (indexed.summary)
|
|
227
|
+
session.summary = indexed.summary;
|
|
228
|
+
if (indexed.messageCount !== undefined)
|
|
229
|
+
session.messageCount = indexed.messageCount;
|
|
230
|
+
if (indexed.created)
|
|
231
|
+
session.created = indexed.created;
|
|
232
|
+
}
|
|
233
|
+
return session;
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
projects.push(project);
|
|
237
|
+
}
|
|
238
|
+
projects.sort((a, b) => b.dateRange.last.localeCompare(a.dateRange.last));
|
|
239
|
+
if (options.json || raw) {
|
|
240
|
+
output(projects, raw, undefined);
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
process.stdout.write('\n' + formatProjectTable(projects));
|
|
244
|
+
if (options.verbose) {
|
|
245
|
+
for (const p of projects) {
|
|
246
|
+
process.stdout.write(`\n ${p.name} (${p.sessionCount} sessions):\n`);
|
|
247
|
+
if (p.sessions) {
|
|
248
|
+
process.stdout.write(formatSessionTable(p.sessions));
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
process.stdout.write(`\nTotal: ${projects.length} projects\n`);
|
|
253
|
+
process.exit(0);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
async function cmdExtractMessages(projectArg, options, raw, overridePath) {
|
|
257
|
+
const sessionsDir = getSessionsDir(overridePath);
|
|
258
|
+
if (!sessionsDir) {
|
|
259
|
+
const searchedPath = overridePath || '~/.claude/projects';
|
|
260
|
+
error(`No Claude Code sessions found at ${searchedPath}.${overridePath ? '' : ' Is Claude Code installed?'}`);
|
|
261
|
+
}
|
|
262
|
+
let projectDirs;
|
|
263
|
+
try {
|
|
264
|
+
projectDirs = node_fs_1.default.readdirSync(sessionsDir).filter(entry => {
|
|
265
|
+
const fullPath = node_path_1.default.join(sessionsDir, entry);
|
|
266
|
+
try {
|
|
267
|
+
return node_fs_1.default.statSync(fullPath).isDirectory();
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
error(`Cannot read sessions directory: ${err.message}`);
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
let matchedDir = null;
|
|
279
|
+
let matchedName = null;
|
|
280
|
+
for (const dirName of projectDirs) {
|
|
281
|
+
if (dirName === projectArg) {
|
|
282
|
+
matchedDir = dirName;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (!matchedDir) {
|
|
287
|
+
const lowerArg = projectArg.toLowerCase();
|
|
288
|
+
const matches = projectDirs.filter(d => d.toLowerCase().includes(lowerArg));
|
|
289
|
+
if (matches.length === 1) {
|
|
290
|
+
matchedDir = matches[0];
|
|
291
|
+
}
|
|
292
|
+
else if (matches.length > 1) {
|
|
293
|
+
const exactNameMatches = [];
|
|
294
|
+
for (const dirName of matches) {
|
|
295
|
+
const indexData = readSessionIndex(node_path_1.default.join(sessionsDir, dirName));
|
|
296
|
+
const pName = getProjectName(dirName, indexData);
|
|
297
|
+
if (pName.toLowerCase() === lowerArg) {
|
|
298
|
+
exactNameMatches.push({ dirName, name: pName });
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
if (exactNameMatches.length === 1) {
|
|
302
|
+
matchedDir = exactNameMatches[0].dirName;
|
|
303
|
+
matchedName = exactNameMatches[0].name;
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
const names = matches.map(d => {
|
|
307
|
+
const idx = readSessionIndex(node_path_1.default.join(sessionsDir, d));
|
|
308
|
+
return ` - ${getProjectName(d, idx)} (${d})`;
|
|
309
|
+
});
|
|
310
|
+
error(`Multiple projects match "${projectArg}":\n${names.join('\n')}\nBe more specific.`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (!matchedDir) {
|
|
315
|
+
const available = projectDirs.map(d => {
|
|
316
|
+
const idx = readSessionIndex(node_path_1.default.join(sessionsDir, d));
|
|
317
|
+
return ` - ${getProjectName(d, idx)}`;
|
|
318
|
+
});
|
|
319
|
+
error(`No project matching "${projectArg}". Available projects:\n${available.join('\n')}`);
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
const projectPath = node_path_1.default.join(sessionsDir, matchedDir);
|
|
323
|
+
const indexData = readSessionIndex(projectPath);
|
|
324
|
+
const projectName = matchedName || getProjectName(matchedDir, indexData);
|
|
325
|
+
process.stderr.write('Reading your session history (read-only, nothing is modified or sent anywhere)...\n');
|
|
326
|
+
let sessions = scanProjectDir(projectPath);
|
|
327
|
+
if (options.sessionId) {
|
|
328
|
+
sessions = sessions.filter(s => s.sessionId === options.sessionId);
|
|
329
|
+
if (sessions.length === 0) {
|
|
330
|
+
error(`Session "${options.sessionId}" not found in project "${projectName}".`);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (options.limit && options.limit > 0) {
|
|
334
|
+
sessions = sessions.slice(0, options.limit);
|
|
335
|
+
}
|
|
336
|
+
reapStaleTempFiles('gsd-pipeline-', { dirsOnly: true });
|
|
337
|
+
ensureGsdTempDir();
|
|
338
|
+
const tmpDir = node_fs_1.default.mkdtempSync(node_path_1.default.join(GSD_TEMP_DIR, 'gsd-pipeline-'));
|
|
339
|
+
const outputPath = node_path_1.default.join(tmpDir, 'extracted-messages.jsonl');
|
|
340
|
+
let sessionsProcessed = 0;
|
|
341
|
+
let sessionsSkipped = 0;
|
|
342
|
+
let messagesExtracted = 0;
|
|
343
|
+
let messagesTruncated = 0;
|
|
344
|
+
const total = sessions.length;
|
|
345
|
+
const batchLimit = 300;
|
|
346
|
+
for (let i = 0; i < sessions.length; i++) {
|
|
347
|
+
if (messagesExtracted >= batchLimit)
|
|
348
|
+
break;
|
|
349
|
+
const session = sessions[i];
|
|
350
|
+
process.stderr.write(`\rProcessing session ${i + 1}/${total}...`);
|
|
351
|
+
try {
|
|
352
|
+
const remaining = batchLimit - messagesExtracted;
|
|
353
|
+
const msgs = await streamExtractMessages(session.filePath, isGenuineUserMessage, remaining);
|
|
354
|
+
for (const msg of msgs) {
|
|
355
|
+
node_fs_1.default.appendFileSync(outputPath, JSON.stringify(msg) + '\n');
|
|
356
|
+
messagesExtracted++;
|
|
357
|
+
if (msg.content.endsWith('... [truncated]')) {
|
|
358
|
+
messagesTruncated++;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
sessionsProcessed++;
|
|
362
|
+
}
|
|
363
|
+
catch (err) {
|
|
364
|
+
sessionsSkipped++;
|
|
365
|
+
process.stderr.write(`\nWarning: Skipped session ${session.sessionId}: ${err.message}\n`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
process.stderr.write('\r' + ' '.repeat(60) + '\r');
|
|
369
|
+
const result = {
|
|
370
|
+
output_file: outputPath,
|
|
371
|
+
project: projectName,
|
|
372
|
+
sessions_processed: sessionsProcessed,
|
|
373
|
+
sessions_skipped: sessionsSkipped,
|
|
374
|
+
messages_extracted: messagesExtracted,
|
|
375
|
+
messages_truncated: messagesTruncated,
|
|
376
|
+
};
|
|
377
|
+
if (sessionsSkipped > 0 && sessionsProcessed > 0) {
|
|
378
|
+
process.stdout.write(JSON.stringify(result, null, 2));
|
|
379
|
+
process.exit(2);
|
|
380
|
+
}
|
|
381
|
+
else if (sessionsProcessed === 0 && sessionsSkipped > 0) {
|
|
382
|
+
process.stdout.write(JSON.stringify(result, null, 2));
|
|
383
|
+
process.exit(1);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
output(result, raw, undefined);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
async function cmdProfileSample(overridePath, options, raw) {
|
|
390
|
+
const sessionsDir = getSessionsDir(overridePath);
|
|
391
|
+
if (!sessionsDir) {
|
|
392
|
+
const searchedPath = overridePath || '~/.claude/projects';
|
|
393
|
+
error(`No Claude Code sessions found at ${searchedPath}.${overridePath ? '' : ' Is Claude Code installed?'}`);
|
|
394
|
+
}
|
|
395
|
+
process.stderr.write('Reading your session history (read-only, nothing is modified or sent anywhere)...\n');
|
|
396
|
+
const limit = options.limit || 150;
|
|
397
|
+
const maxChars = options.maxChars || 500;
|
|
398
|
+
let projectDirs;
|
|
399
|
+
try {
|
|
400
|
+
projectDirs = node_fs_1.default.readdirSync(sessionsDir).filter(entry => {
|
|
401
|
+
const fullPath = node_path_1.default.join(sessionsDir, entry);
|
|
402
|
+
try {
|
|
403
|
+
return node_fs_1.default.statSync(fullPath).isDirectory();
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
return false;
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
catch (err) {
|
|
411
|
+
error(`Cannot read sessions directory: ${err.message}`);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (projectDirs.length === 0) {
|
|
415
|
+
error('No project directories found in sessions directory.');
|
|
416
|
+
}
|
|
417
|
+
const projectMeta = [];
|
|
418
|
+
for (const dirName of projectDirs) {
|
|
419
|
+
const projectPath = node_path_1.default.join(sessionsDir, dirName);
|
|
420
|
+
const sessions = scanProjectDir(projectPath);
|
|
421
|
+
if (sessions.length === 0)
|
|
422
|
+
continue;
|
|
423
|
+
const indexData = readSessionIndex(projectPath);
|
|
424
|
+
const projectName = getProjectName(dirName, indexData);
|
|
425
|
+
const lastActive = sessions[0].modified;
|
|
426
|
+
projectMeta.push({ dirName, projectPath, sessions, projectName, lastActive });
|
|
427
|
+
}
|
|
428
|
+
projectMeta.sort((a, b) => b.lastActive.getTime() - a.lastActive.getTime());
|
|
429
|
+
const projectCount = projectMeta.length;
|
|
430
|
+
if (projectCount === 0) {
|
|
431
|
+
error('No projects with sessions found.');
|
|
432
|
+
}
|
|
433
|
+
const perProjectCap = options.maxPerProject || Math.max(5, Math.floor(limit / projectCount));
|
|
434
|
+
const recencyThreshold = Date.now() - 30 * 24 * 60 * 60 * 1000;
|
|
435
|
+
const allMessages = [];
|
|
436
|
+
let skippedContextDumps = 0;
|
|
437
|
+
const projectBreakdown = [];
|
|
438
|
+
for (const proj of projectMeta) {
|
|
439
|
+
if (allMessages.length >= limit)
|
|
440
|
+
break;
|
|
441
|
+
const cappedSessions = proj.sessions.slice(0, perProjectCap);
|
|
442
|
+
let projectMessages = 0;
|
|
443
|
+
let projectSessionsUsed = 0;
|
|
444
|
+
for (const session of cappedSessions) {
|
|
445
|
+
if (allMessages.length >= limit)
|
|
446
|
+
break;
|
|
447
|
+
const isRecent = session.modified.getTime() >= recencyThreshold;
|
|
448
|
+
const perSessionMax = isRecent ? 10 : 3;
|
|
449
|
+
const remaining = Math.min(perSessionMax, limit - allMessages.length);
|
|
450
|
+
try {
|
|
451
|
+
const msgs = await streamExtractMessages(session.filePath, isGenuineUserMessage, remaining);
|
|
452
|
+
let sessionUsed = false;
|
|
453
|
+
for (const msg of msgs) {
|
|
454
|
+
if (allMessages.length >= limit)
|
|
455
|
+
break;
|
|
456
|
+
const content = msg.content || '';
|
|
457
|
+
if (content.startsWith('This session is being continued')) {
|
|
458
|
+
skippedContextDumps++;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
const lines = content.split('\n').filter(l => l.trim().length > 0);
|
|
462
|
+
if (lines.length > 3) {
|
|
463
|
+
const logPattern = /^\[?(DEBUG|INFO|WARN|ERROR|LOG)\]?/i;
|
|
464
|
+
const timestampPattern = /^\d{4}-\d{2}-\d{2}/;
|
|
465
|
+
const logLines = lines.filter(l => logPattern.test(l.trim()) || timestampPattern.test(l.trim()));
|
|
466
|
+
if (logLines.length / lines.length > 0.8) {
|
|
467
|
+
skippedContextDumps++;
|
|
468
|
+
continue;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
const truncated = truncateContent(content, maxChars);
|
|
472
|
+
allMessages.push({
|
|
473
|
+
sessionId: msg.sessionId,
|
|
474
|
+
projectName: proj.projectName,
|
|
475
|
+
projectPath: msg.projectPath,
|
|
476
|
+
timestamp: msg.timestamp,
|
|
477
|
+
content: truncated,
|
|
478
|
+
});
|
|
479
|
+
projectMessages++;
|
|
480
|
+
sessionUsed = true;
|
|
481
|
+
}
|
|
482
|
+
if (sessionUsed)
|
|
483
|
+
projectSessionsUsed++;
|
|
484
|
+
}
|
|
485
|
+
catch {
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
if (projectMessages > 0) {
|
|
490
|
+
projectBreakdown.push({
|
|
491
|
+
project: proj.projectName,
|
|
492
|
+
messages: projectMessages,
|
|
493
|
+
sessions: projectSessionsUsed,
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
reapStaleTempFiles('gsd-profile-', { dirsOnly: true });
|
|
498
|
+
ensureGsdTempDir();
|
|
499
|
+
const tmpDir = node_fs_1.default.mkdtempSync(node_path_1.default.join(GSD_TEMP_DIR, 'gsd-profile-'));
|
|
500
|
+
const outputPath = node_path_1.default.join(tmpDir, 'profile-sample.jsonl');
|
|
501
|
+
for (const msg of allMessages) {
|
|
502
|
+
node_fs_1.default.appendFileSync(outputPath, JSON.stringify(msg) + '\n');
|
|
503
|
+
}
|
|
504
|
+
const result = {
|
|
505
|
+
output_file: outputPath,
|
|
506
|
+
projects_sampled: projectBreakdown.length,
|
|
507
|
+
messages_sampled: allMessages.length,
|
|
508
|
+
per_project_cap: perProjectCap,
|
|
509
|
+
message_char_limit: maxChars,
|
|
510
|
+
skipped_context_dumps: skippedContextDumps,
|
|
511
|
+
project_breakdown: projectBreakdown,
|
|
512
|
+
};
|
|
513
|
+
output(result, raw, undefined);
|
|
514
|
+
}
|
|
515
|
+
module.exports = {
|
|
516
|
+
cmdScanSessions,
|
|
517
|
+
cmdExtractMessages,
|
|
518
|
+
cmdProfileSample,
|
|
519
|
+
};
|