@pareto4/pp-core 1.6.0 → 1.6.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.
Files changed (48) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/agents/pp-code-fixer.md +3 -3
  3. package/bin/install.js +0 -6
  4. package/gemini-extension.json +1 -1
  5. package/package.json +1 -1
  6. package/pp-core/bin/lib/agent-install-check.cjs +1 -1
  7. package/pp-core/bin/lib/audit-command-router.cjs +3 -3
  8. package/pp-core/bin/lib/audit.cjs +1 -1
  9. package/pp-core/bin/lib/capability-activation.cjs +1 -1
  10. package/pp-core/bin/lib/capability-registry.cjs +3 -3
  11. package/pp-core/bin/lib/capability-state.cjs +1 -1
  12. package/pp-core/bin/lib/capability-writer.cjs +1 -1
  13. package/pp-core/bin/lib/check-command-router.cjs +7 -7
  14. package/pp-core/bin/lib/cjs-command-router-adapter.cjs +1 -1
  15. package/pp-core/bin/lib/code-review-flags.cjs +1 -1
  16. package/pp-core/bin/lib/config-loader.cjs +1 -1
  17. package/pp-core/bin/lib/config.cjs +1 -1
  18. package/pp-core/bin/lib/context-utilization.cjs +1 -1
  19. package/pp-core/bin/lib/docs.cjs +1 -1
  20. package/pp-core/bin/lib/frontmatter.cjs +1 -1
  21. package/pp-core/bin/lib/git-base-branch.cjs +2 -2
  22. package/pp-core/bin/lib/graphify-command-router.cjs +4 -4
  23. package/pp-core/bin/lib/graphify.cjs +1 -1
  24. package/pp-core/bin/lib/gsd2-import.cjs +1 -1
  25. package/pp-core/bin/lib/init-command-router.cjs +1 -1
  26. package/pp-core/bin/lib/init.cjs +1 -1
  27. package/pp-core/bin/lib/intel-command-router.cjs +5 -5
  28. package/pp-core/bin/lib/intel.cjs +1 -1
  29. package/pp-core/bin/lib/io.cjs +2 -2
  30. package/pp-core/bin/lib/loop-resolver.cjs +1 -1
  31. package/pp-core/bin/lib/phase-command-router.cjs +1 -1
  32. package/pp-core/bin/lib/phases-command-router.cjs +1 -1
  33. package/pp-core/bin/lib/plan-drift-guard.cjs +1 -1
  34. package/pp-core/bin/lib/prohibition-enforcement.cjs +2 -2
  35. package/pp-core/bin/lib/roadmap-command-router.cjs +2 -2
  36. package/pp-core/bin/lib/roadmap-parser.cjs +1 -1
  37. package/pp-core/bin/lib/state-command-router.cjs +1 -1
  38. package/pp-core/bin/lib/state.cjs +2 -2
  39. package/pp-core/bin/lib/validate-command-router.cjs +1 -1
  40. package/pp-core/bin/lib/verify-command-router.cjs +1 -1
  41. package/pp-core/bin/lib/verify.cjs +1 -1
  42. package/pp-core/bin/lib/worktree-base-ref.cjs +2 -2
  43. package/pp-core/bin/lib/worktree-safety.cjs +1 -1
  44. package/pp-core/bin/pp-tools.cjs +21 -21
  45. package/assets/gsd-logo-2000-transparent.png +0 -0
  46. package/assets/gsd-logo-2000-transparent.svg +0 -17
  47. package/assets/gsd-logo-2000.png +0 -0
  48. package/assets/gsd-logo-2000.svg +0 -21
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "pp-core",
3
3
  "displayName": "PP Core",
4
- "version": "1.6.0",
4
+ "version": "1.6.1",
5
5
  "description": "PP Core is a meta-prompting, context engineering, and spec-driven development system for AI coding agents.",
6
6
  "author": {
7
7
  "name": "pareto4",
@@ -271,7 +271,7 @@ wt=$(mktemp -d "/tmp/sv-${padded_phase}-reviewfix-XXXXXX")
271
271
  # failed before the agent could do any work). The temp branch shares
272
272
  # history with $branch up to the moment of creation, so commits made
273
273
  # inside the worktree fast-forward $branch on cleanup.
274
- reviewfix_branch="gsd-reviewfix/${padded_phase}-$$"
274
+ reviewfix_branch="pp-reviewfix/${padded_phase}-$$"
275
275
  git worktree add -b "$reviewfix_branch" "$wt" "$branch"
276
276
 
277
277
  # Write the recovery sentinel ONLY AFTER `git worktree add` succeeds.
@@ -297,7 +297,7 @@ Concrete steps:
297
297
  2. Resolve the current branch: `branch=$(git branch --show-current)`. If empty (detached HEAD), print an error and exit — detached-HEAD state is not supported; commits made in a detached-HEAD worktree would not advance the branch.
298
298
  3. **Recovery check (#2839, #2990):** If `${phase_dir}/.review-fix-recovery-pending.json` already exists, a prior run was interrupted. Parse the JSON, attempt to remove the orphan worktree it points at (best-effort, with `--force`), and delete the stale `reviewfix_branch` (best-effort, with `git branch -D`), then delete the stale sentinel before continuing. This makes a re-run of `/pp:code-review --fix` self-healing.
299
299
  4. Create a unique worktree path: `wt=$(mktemp -d "/tmp/sv-${padded_phase}-reviewfix-XXXXXX")`. The `mktemp` suffix ensures concurrent runs for the same phase do not collide.
300
- 5. Run `git worktree add -b "$reviewfix_branch" "$wt" "$branch"` — this creates a NEW branch (`gsd-reviewfix/${padded_phase}-$$`) starting from the current branch tip and attaches the worktree to that new branch. Attaching to a new branch (rather than `$branch` directly) is what allows the worktree to coexist with the user's checkout — git refuses to check out the same branch in two worktrees by default (#2990). Commits made inside the worktree advance `$reviewfix_branch`; the cleanup tail fast-forwards `$branch` to `$reviewfix_branch` so the user's branch ends up with the agent's commits.
300
+ 5. Run `git worktree add -b "$reviewfix_branch" "$wt" "$branch"` — this creates a NEW branch (`pp-reviewfix/${padded_phase}-$$`) starting from the current branch tip and attaches the worktree to that new branch. Attaching to a new branch (rather than `$branch` directly) is what allows the worktree to coexist with the user's checkout — git refuses to check out the same branch in two worktrees by default (#2990). Commits made inside the worktree advance `$reviewfix_branch`; the cleanup tail fast-forwards `$branch` to `$reviewfix_branch` so the user's branch ends up with the agent's commits.
301
301
  6. **Write the recovery sentinel** at `${phase_dir}/.review-fix-recovery-pending.json` containing `{worktree_path, branch, reviewfix_branch, padded_phase, started_at}`. Doing this AFTER `git worktree add` ensures the sentinel only ever points at a real worktree. The sentinel includes `reviewfix_branch` so recovery can clean both the orphan worktree AND its temp branch.
302
302
  7. All subsequent file reads, edits, and commits happen inside `$wt` (which is on `$reviewfix_branch`, not `$branch`).
303
303
 
@@ -454,7 +454,7 @@ For each finding in sorted order:
454
454
 
455
455
  **If verification passed:**
456
456
 
457
- Use `pp-tools query commit` with conventional format (message first, then every staged file path):
457
+ Use `pp_run query commit` with conventional format (message first, then every staged file path):
458
458
  ```bash
459
459
  _PP_SHIM_NAME="pp-tools.cjs"; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.claude/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${_PP_RUNTIME_ROOT}/.codex/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v pp-tools)"; pp_run() { "$PP_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${HERMES_HOME:-$HOME/.hermes}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CURSOR_CONFIG_DIR:-$HOME/.cursor}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEX_HOME:-$HOME/.codex}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GEMINI_CONFIG_DIR:-$HOME/.gemini}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${COPILOT_CONFIG_DIR:-$HOME/.copilot}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${WINDSURF_CONFIG_DIR:-$HOME/.codeium/windsurf}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${AUGMENT_CONFIG_DIR:-$HOME/.augment}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${TRAE_CONFIG_DIR:-$HOME/.trae}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${QWEN_CONFIG_DIR:-$HOME/.qwen}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CODEBUDDY_CONFIG_DIR:-$HOME/.codebuddy}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${CLINE_CONFIG_DIR:-$HOME/.cline}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${GROK_AGENTS_HOME:-$HOME/.agents}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${ANTIGRAVITY_CONFIG_DIR:-$HOME/.gemini/antigravity}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${OPENCODE_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/opencode}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; elif [ -f "${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="${KILO_CONFIG_DIR:-${XDG_CONFIG_HOME:-$HOME/.config}/kilo}/pp-core/bin/${_PP_SHIM_NAME}"; pp_run() { node "$PP_TOOLS" "$@"; }; else echo "ERROR: pp-tools.cjs not found at $PP_TOOLS and pp-tools is not on PATH. Run: npx -y @pareto4/pp-core@latest --claude --local" >&2; exit 1; fi; if [ -n "${CLAUDE_ENV_FILE:-}" ] && [ -n "${PP_TOOLS:-}" ]; then printf "export PATH='%s':\"\$PATH\"\n" "${PP_TOOLS%/*}" >> "$CLAUDE_ENV_FILE" 2>/dev/null || true; fi
460
460
  pp_run query commit \
package/bin/install.js CHANGED
@@ -11504,8 +11504,6 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS
11504
11504
  if (runtime === 'claude' && isGlobal) {
11505
11505
  console.log(`
11506
11506
  ${green}Done!${reset} Restart ${program}, then in any directory either type ${cyan}${command}${reset} or ask Claude to run the ${cyan}pp-new-project${reset} skill.
11507
-
11508
- ${cyan}Join the community:${reset} https://discord.gg/mYgfVNfA2r
11509
11507
  `);
11510
11508
  return;
11511
11509
  }
@@ -11514,16 +11512,12 @@ function finishInstall(settingsPath, settings, statuslineCommand, shouldInstallS
11514
11512
  const agentPath = configDir ? path.join(configDir, 'agents', 'gsd.yaml') : 'agents/gsd.yaml';
11515
11513
  console.log(`
11516
11514
  ${green}Done!${reset} Start ${program} with ${cyan}kimi --agent-file ${agentPath}${reset}, then run ${cyan}${command}${reset}.
11517
-
11518
- ${cyan}Join the community:${reset} https://discord.gg/mYgfVNfA2r
11519
11515
  `);
11520
11516
  return;
11521
11517
  }
11522
11518
 
11523
11519
  console.log(`
11524
11520
  ${green}Done!${reset} Open a blank directory in ${program} and run ${cyan}${command}${reset}.
11525
-
11526
- ${cyan}Join the community:${reset} https://discord.gg/mYgfVNfA2r
11527
11521
  `);
11528
11522
  }
11529
11523
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pp-core",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "PP Core — a meta-prompting, context engineering, and spec-driven development system for AI coding agents. Loads pp-core's operating context into every Gemini CLI session.",
5
5
  "contextFileName": "GEMINI.md"
6
6
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pareto4/pp-core",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Pareto pp-core — The Pareto Project's AI-assisted engineering framework: meta-prompting, context engineering, and spec-driven development for AI coding agents.",
5
5
  "bin": {
6
6
  "pp-core": "bin/install.js",
@@ -25,7 +25,7 @@ const runtime_homes_cjs_1 = require("./runtime-homes.cjs");
25
25
  * 1. GSD_AGENTS_DIR env var (explicit override, any runtime)
26
26
  * 2. For claude runtime: __dirname-relative path (agents/ sibling of gsd-core/)
27
27
  * This is correct for both repo runs and real installs (the runtime config dir's
28
- * agents/ folder) because gsd-tools.cjs lives inside gsd-core/bin/ in both cases.
28
+ * agents/ folder) because pp-tools.cjs lives inside gsd-core/bin/ in both cases.
29
29
  * 3. For non-claude runtimes: getGlobalConfigDir(runtime)/agents
30
30
  *
31
31
  * @param runtime - the active runtime name; defaults to GSD_RUNTIME env, then 'claude'
@@ -1,11 +1,11 @@
1
1
  'use strict';
2
2
  /**
3
- * Audit command routers — CLI dispatchers for `gsd-tools audit-uat` and
4
- * `gsd-tools audit-open`.
3
+ * Audit command routers — CLI dispatchers for `pp-tools audit-uat` and
4
+ * `pp-tools audit-open`.
5
5
  *
6
6
  * ADR-959 (phase 4d-impl-3): audit command family cutover.
7
7
  * Extracted from the hardcoded `case 'audit-uat':` and `case 'audit-open':`
8
- * arms in gsd-tools.cjs. Behaviour is preserved byte-for-behaviour from the
8
+ * arms in pp-tools.cjs. Behaviour is preserved byte-for-behaviour from the
9
9
  * prior inline cases; the dispatch path now flows:
10
10
  * default → dispatchCapabilityCommand →
11
11
  * require(audit-command-router.cjs) → routeAuditUat | routeAuditOpen.
@@ -4,7 +4,7 @@
4
4
  *
5
5
  * Scans all .planning/ artifact categories for items with open/unresolved state.
6
6
  * Returns structured JSON for workflow consumption.
7
- * Called by: gsd-tools.cjs audit-open
7
+ * Called by: pp-tools.cjs audit-open
8
8
  * Used by: /gsd:complete-milestone pre-close gate
9
9
  *
10
10
  * ADR-457 build-at-publish: the hand-written bin/lib/audit.cjs collapsed
@@ -43,7 +43,7 @@ function _readRawConfigKey(filePath, dotKey) {
43
43
  if (!_warnedRawConfigPaths.has(filePath)) {
44
44
  _warnedRawConfigPaths.add(filePath);
45
45
  try {
46
- process.stderr.write(`gsd-tools: warning: failed to parse ${filePath} as JSON — skipping for activation resolution\n`);
46
+ process.stderr.write(`pp-tools: warning: failed to parse ${filePath} as JSON — skipping for activation resolution\n`);
47
47
  }
48
48
  catch { /* stderr might be closed */ }
49
49
  }
@@ -115,7 +115,7 @@ const capabilities = {
115
115
  "id": "audit",
116
116
  "role": "feature",
117
117
  "title": "Audit",
118
- "description": "Open-artifact audit and UAT-gap audit for milestone close gates; exposes `gsd-tools audit-uat` (cross-phase UAT outstanding items) and `gsd-tools audit-open` (structured open-artifact scan across debug, tasks, threads, todos, seeds, UAT, verification, context-questions).",
118
+ "description": "Open-artifact audit and UAT-gap audit for milestone close gates; exposes `pp-tools audit-uat` (cross-phase UAT outstanding items) and `pp-tools audit-open` (structured open-artifact scan across debug, tasks, threads, todos, seeds, UAT, verification, context-questions).",
119
119
  "tier": "full",
120
120
  "requires": [],
121
121
  "runtimeCompat": {
@@ -858,7 +858,7 @@ const capabilities = {
858
858
  "id": "intel",
859
859
  "role": "feature",
860
860
  "title": "Codebase intelligence",
861
- "description": "Code-intelligence store for codebase querying, diff, snapshot, and API-surface extraction; exposes `gsd-tools intel` subcommands (query, status, update, diff, snapshot, patch-meta, validate, extract-exports, api-surface) and backs `/gsd-map-codebase` and `gsd-intel-updater`.",
861
+ "description": "Code-intelligence store for codebase querying, diff, snapshot, and API-surface extraction; exposes `pp-tools intel` subcommands (query, status, update, diff, snapshot, patch-meta, validate, extract-exports, api-surface) and backs `/pp-map-codebase` and `pp-intel-updater`.",
862
862
  "tier": "full",
863
863
  "requires": [],
864
864
  "runtimeCompat": {
@@ -1432,7 +1432,7 @@ const capabilities = {
1432
1432
  "id": "profile-pipeline",
1433
1433
  "role": "feature",
1434
1434
  "title": "Developer profiling pipeline",
1435
- "description": "Developer behavioral profiling from Claude Code session history; scans session JSONL files, extracts and samples user messages, and generates profile artifacts (USER-PROFILE.md, dev-preferences.md, CLAUDE.md sections). Exposes eight `gsd-tools` commands: scan-sessions, extract-messages, profile-sample (pipeline phase) and write-profile, profile-questionnaire, generate-dev-preferences, generate-claude-profile, generate-claude-md (output phase). Backs the /gsd-profile-user skill and gsd-user-profiler agent.",
1435
+ "description": "Developer behavioral profiling from Claude Code session history; scans session JSONL files, extracts and samples user messages, and generates profile artifacts (USER-PROFILE.md, dev-preferences.md, CLAUDE.md sections). Exposes eight `pp-tools` commands: scan-sessions, extract-messages, profile-sample (pipeline phase) and write-profile, profile-questionnaire, generate-dev-preferences, generate-claude-profile, generate-claude-md (output phase). Backs the /pp-profile-user skill and pp-user-profiler agent.",
1436
1436
  "tier": "full",
1437
1437
  "requires": [],
1438
1438
  "runtimeCompat": {
@@ -5,7 +5,7 @@
5
5
  * Unified capability-state resolver that composes the three toggle systems
6
6
  * (install profile, runtime surface, config activation) into one per-capability
7
7
  * view. The loop resolver consumes this state so workflow dispatch and the
8
- * `gsd-tools capability state` diagnostic share the same enablement answer.
8
+ * `pp-tools capability state` diagnostic share the same enablement answer.
9
9
  *
10
10
  * Exports (three things, mirroring loop-resolver):
11
11
  * resolveCapabilityState({ registry, installedSkills, surfacedSkills, config, cwd })
@@ -299,7 +299,7 @@ function setCapabilityState(cwd, runtimeConfigDir, desired, opts) {
299
299
  };
300
300
  }
301
301
  /**
302
- * CLI command entry point for `gsd-tools capability set`.
302
+ * CLI command entry point for `pp-tools capability set`.
303
303
  *
304
304
  * Builds one DesiredCapability from the provided options, calls setCapabilityState,
305
305
  * then prints the result. When raw=true emits JSON; else emits a human summary.
@@ -349,7 +349,7 @@ function cmdDecisionCoverageVerify(projectDir, args, raw) {
349
349
  * Returns JSON: { frontend: boolean, hasUiSpec: boolean, block: boolean }
350
350
  * block = frontend && !hasUiSpec (gate fires when UI work is detected but no spec exists)
351
351
  *
352
- * Invocable as: gsd_run check ui-plan-gate <phase>
352
+ * Invocable as: pp_run check ui-plan-gate <phase>
353
353
  *
354
354
  * Uses checkUiPresence from ui-safety-gate.cjs — does NOT reimplement frontend detection.
355
355
  * Uses getRoadmapPhaseWithFallback + findPhaseInternal from leaf modules for phase data.
@@ -459,8 +459,8 @@ function cmdUiPlanGate(projectDir, args, raw) {
459
459
  * block = frontend && hasUiFiles && !hasUiSpec
460
460
  *
461
461
  * Args: check ui-safety-gate <phase>
462
- * Invocable as: gsd_run check ui-safety-gate <phase>
463
- * or gsd_run check ui.safety-gate <phase> (dots normalized to hyphens)
462
+ * Invocable as: pp_run check ui-safety-gate <phase>
463
+ * or pp_run check ui.safety-gate <phase> (dots normalized to hyphens)
464
464
  *
465
465
  * Uses checkUiPresence from ui-safety-gate.cjs — does NOT reimplement frontend detection.
466
466
  * Checks whether any files changed in recent git history match frontend file patterns.
@@ -705,7 +705,7 @@ function cmdTddReviewCheckpoint(projectDir, args, raw) {
705
705
  * This gate is always advisory (passed: true) — it never blocks phase advancement.
706
706
  *
707
707
  * Args: check gap-analysis.plan-post <phase-dir> [phase-req-ids]
708
- * Invocable as: gsd_run check gap-analysis.plan-post <phase-dir> [phase-req-ids]
708
+ * Invocable as: pp_run check gap-analysis.plan-post <phase-dir> [phase-req-ids]
709
709
  */
710
710
  function cmdGapAnalysisPlanPost(projectDir, args, raw) {
711
711
  // args[0] = 'check', args[1] = 'gap-analysis-plan-post' (normalized), args[2] = phaseDir, args[3] = phaseReqIds
@@ -904,9 +904,9 @@ function cmdShipPlatformDrift(cwd, args, raw) {
904
904
  function routeCheckCommand({ args, cwd, raw }) {
905
905
  // Normalize dots to hyphens in the subcommand so both forms are accepted.
906
906
  // This makes `check.query = "ui.plan-gate"` (dotted form in capability.json gates)
907
- // directly runnable as `gsd_run check ui.plan-gate` — the dot is normalized to
907
+ // directly runnable as `pp_run check ui.plan-gate` — the dot is normalized to
908
908
  // `ui-plan-gate` before routing. The generic gate-dispatch in §5.6 reads
909
- // `check.query` from the active gate hook and runs `gsd_run check ${hook.check.query}`,
909
+ // `check.query` from the active gate hook and runs `pp_run check ${hook.check.query}`,
910
910
  // so the declared query must be dispatchable exactly as declared.
911
911
  const rawSubcommand = args[1];
912
912
  const subcommand = typeof rawSubcommand === 'string' ? rawSubcommand.replace(/\./g, '-') : rawSubcommand;
@@ -964,7 +964,7 @@ function routeCheckCommand({ args, cwd, raw }) {
964
964
  // The deterministic test-tier prohibition PRODUCER/gate (#1259, ADR-550 D5d). Locates the
965
965
  // wired mechanical check (node-test or lint-rule), confirms fail-first, runs it, builds
966
966
  // enforcementEvidence, and emits the dispositionForProhibition verdict. Invocable as
967
- // `gsd_run check prohibition-enforcement <request.json>`.
967
+ // `pp_run check prohibition-enforcement <request.json>`.
968
968
  (0, prohibition_enforcement_cjs_1.routeProhibitionEnforcement)(args, raw);
969
969
  return;
970
970
  }
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * CJS Command Router Adapter Module
4
4
  *
5
- * Compatibility routing for gsd-tools.cjs command families. Uses generated
5
+ * Compatibility routing for pp-tools.cjs command families. Uses generated
6
6
  * command metadata for availability and small family-local argument shapers for
7
7
  * CJS handler calls.
8
8
  *
@@ -16,7 +16,7 @@ exports.resolveCodeReviewWorkflow = resolveCodeReviewWorkflow;
16
16
  /**
17
17
  * Parse code-review flags from an argv array. The first positional argument
18
18
  * (phase number) is ignored — phase validation is handled by
19
- * `gsd-tools query init.phase-op`. Unknown flags are silently ignored.
19
+ * `pp-tools query init.phase-op`. Unknown flags are silently ignored.
20
20
  */
21
21
  function parseCodeReviewFlags(argv) {
22
22
  const flags = {
@@ -502,7 +502,7 @@ function loadConfig(cwd, options = {}) {
502
502
  const warnKey = unknownKeys.join(',');
503
503
  if (!_warnedUnknownConfigKeys.has(warnKey)) {
504
504
  _warnedUnknownConfigKeys.add(warnKey);
505
- process.stderr.write(`gsd-tools: warning: unknown config key(s) in .planning/config.json: ${unknownKeys.join(', ')} — these will be ignored\n`);
505
+ process.stderr.write(`pp-tools: warning: unknown config key(s) in .planning/config.json: ${unknownKeys.join(', ')} — these will be ignored\n`);
506
506
  }
507
507
  }
508
508
  // #2517 — Validate runtime/tier values
@@ -749,7 +749,7 @@ function cmdConfigPath(cwd, _raw, workstreamContext = null) {
749
749
  *
750
750
  * Wraps the Configuration Module's migrateOnDisk() for the CLI surface. This
751
751
  * is the Phase 2 acceptance-criteria deliverable for opt-in migration (#3536):
752
- * users can run `gsd-tools migrate-config` to apply all four legacy-key
752
+ * users can run `pp-tools migrate-config` to apply all four legacy-key
753
753
  * migrations to their .planning/config.json without having to load any config
754
754
  * implicitly via another command.
755
755
  *
@@ -8,7 +8,7 @@
8
8
  * Pure function. Callers pass tokensUsed + contextWindow; the
9
9
  * classifier returns the percent and one of three states. Recommendation
10
10
  * strings are NOT in this module — formatting is the renderer's job
11
- * (see `validate context` in gsd-tools.cjs). That separation lets the
11
+ * (see `validate context` in pp-tools.cjs). That separation lets the
12
12
  * copy change without touching this module's tests.
13
13
  *
14
14
  * Thresholds:
@@ -241,7 +241,7 @@ function detectMonorepoWorkspaces(cwd) {
241
241
  * resolution. Follows the cmdInitMapCodebase pattern.
242
242
  *
243
243
  * @example
244
- * node gsd-tools.cjs docs-init --raw
244
+ * node pp-tools.cjs docs-init --raw
245
245
  */
246
246
  function cmdDocsInit(cwd, raw) {
247
247
  const config = loadConfig(cwd);
@@ -367,7 +367,7 @@ function parseMustHavesBlock(content, blockName) {
367
367
  if (items.length === 0 && blockLines.length > 0) {
368
368
  const nonEmptyLines = blockLines.filter(l => l.trim() !== '').length;
369
369
  if (nonEmptyLines > 0) {
370
- process.stderr.write(`[gsd-tools] WARNING: must_haves.${blockName} block has ${nonEmptyLines} content lines but parsed 0 items. ` +
370
+ process.stderr.write(`[pp-tools] WARNING: must_haves.${blockName} block has ${nonEmptyLines} content lines but parsed 0 items. ` +
371
371
  `Possible YAML formatting issue — verification will fall back to LLM-derived truths.\n`);
372
372
  }
373
373
  }
@@ -208,9 +208,9 @@ function gitWorktreeInfoInternal(cwd) {
208
208
  }
209
209
  // ─── CLI entry point ──────────────────────────────────────────────────────────
210
210
  /**
211
- * CLI command: `gsd-tools git base-branch`
211
+ * CLI command: `pp-tools git base-branch`
212
212
  * Resolves the default branch and writes it to stdout (raw string, newline-terminated).
213
- * Called by workflows via `gsd_run query git.base-branch`.
213
+ * Called by workflows via `pp_run query git.base-branch`.
214
214
  */
215
215
  function cmdGitBaseBranch(cwd, _args, deps) {
216
216
  const branch = resolveBaseBranch(cwd, deps);
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
  /**
3
- * Graphify command router — CLI subcommand dispatcher for `gsd-tools graphify`.
3
+ * Graphify command router — CLI subcommand dispatcher for `pp-tools graphify`.
4
4
  *
5
5
  * ADR-959 (phase 4d-impl-2) pilot: first real capability command cutover.
6
- * Extracted from the hardcoded `case 'graphify':` arm in gsd-tools.cjs.
6
+ * Extracted from the hardcoded `case 'graphify':` arm in pp-tools.cjs.
7
7
  * Behaviour is preserved byte-for-behaviour from the prior inline case;
8
8
  * the dispatch path now flows: default → dispatchCapabilityCommand →
9
9
  * require(graphify-command-router.cjs) → routeGraphifyCommand.
@@ -34,7 +34,7 @@ function routeGraphifyCommand({ args, cwd, raw, error, _graphify }) {
34
34
  if (subcommand === 'query') {
35
35
  const term = args[2];
36
36
  if (!term) {
37
- error('Usage: gsd-tools graphify query <term>', ERROR_REASON.USAGE);
37
+ error('Usage: pp-tools graphify query <term>', ERROR_REASON.USAGE);
38
38
  return;
39
39
  }
40
40
  const budgetIdx = args.indexOf('--budget');
@@ -42,7 +42,7 @@ function routeGraphifyCommand({ args, cwd, raw, error, _graphify }) {
42
42
  if (budgetIdx !== -1) {
43
43
  const rawBudget = args[budgetIdx + 1];
44
44
  if (rawBudget === undefined || Number.isNaN(parseInt(rawBudget, 10))) {
45
- error('Usage: gsd-tools graphify query <term> [--budget <N>]', ERROR_REASON.USAGE);
45
+ error('Usage: pp-tools graphify query <term> [--budget <N>]', ERROR_REASON.USAGE);
46
46
  return;
47
47
  }
48
48
  budget = parseInt(rawBudget, 10);
@@ -20,7 +20,7 @@ const { isCapabilityActive } = capabilityStateMod;
20
20
  * Return the standard disabled response object.
21
21
  */
22
22
  function disabledResponse() {
23
- return { disabled: true, message: 'graphify is not enabled. Enable with: gsd-tools config-set graphify.enabled true' };
23
+ return { disabled: true, message: 'graphify is not enabled. Enable with: pp-tools config-set graphify.enabled true' };
24
24
  }
25
25
  // ─── Subprocess Helper ───────────────────────────────────────────────────────
26
26
  /**
@@ -392,7 +392,7 @@ function writePlanningDir(artifacts, planningRoot) {
392
392
  }
393
393
  // ─── Command Handler ──────────────────────────────────────────────────────────
394
394
  /**
395
- * Entry point called from gsd-tools.cjs.
395
+ * Entry point called from pp-tools.cjs.
396
396
  * Supports: --force, --dry-run, --path <dir>
397
397
  */
398
398
  function cmdFromGsd2(args, cwd, raw) {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed init subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Phase 6: all init.* subcommands have SDK equivalents and are dispatched
7
7
  * via executeForCjs (the sync bridge). CJS fallback retained when:
@@ -1218,7 +1218,7 @@ function cmdInitManager(cwd, raw) {
1218
1218
  const safe = tokens.every((t) => /^--[a-zA-Z0-9][-a-zA-Z0-9]*$/.test(t) ||
1219
1219
  /^[a-zA-Z0-9][-a-zA-Z0-9_.]*$/.test(t));
1220
1220
  if (!safe) {
1221
- process.stderr.write(`gsd-tools: warning: manager.flags contains invalid tokens, ignoring: ${val}\n`);
1221
+ process.stderr.write(`pp-tools: warning: manager.flags contains invalid tokens, ignoring: ${val}\n`);
1222
1222
  return '';
1223
1223
  }
1224
1224
  return val;
@@ -1,10 +1,10 @@
1
1
  'use strict';
2
2
  /**
3
- * Intel command router — CLI subcommand dispatcher for `gsd-tools intel`.
3
+ * Intel command router — CLI subcommand dispatcher for `pp-tools intel`.
4
4
  *
5
5
  * ADR-959 (phase 4d-impl-4): intel command family cutover — last first-party
6
6
  * command cutover in the initial capability rollout.
7
- * Extracted from the hardcoded `case 'intel':` arm in gsd-tools.cjs.
7
+ * Extracted from the hardcoded `case 'intel':` arm in pp-tools.cjs.
8
8
  * Behaviour is preserved byte-for-behaviour from the prior inline case;
9
9
  * the dispatch path now flows: default → dispatchCapabilityCommand →
10
10
  * require(intel-command-router.cjs) → routeIntelCommand.
@@ -56,7 +56,7 @@ function routeIntelCommand({ args, cwd, raw, error, _intel, _core }) {
56
56
  if (subcommand === 'query') {
57
57
  const term = args[2];
58
58
  if (!term) {
59
- error('Usage: gsd-tools intel query <term>', ERROR_REASON.USAGE);
59
+ error('Usage: pp-tools intel query <term>', ERROR_REASON.USAGE);
60
60
  return;
61
61
  }
62
62
  const planningDir = path.join(cwd, '.planning');
@@ -85,7 +85,7 @@ function routeIntelCommand({ args, cwd, raw, error, _intel, _core }) {
85
85
  else if (subcommand === 'patch-meta') {
86
86
  const filePath = args[2];
87
87
  if (!filePath) {
88
- error('Usage: gsd-tools intel patch-meta <file-path>', ERROR_REASON.USAGE);
88
+ error('Usage: pp-tools intel patch-meta <file-path>', ERROR_REASON.USAGE);
89
89
  return;
90
90
  }
91
91
  c.output(intel.intelPatchMeta(path.resolve(cwd, filePath)), raw);
@@ -97,7 +97,7 @@ function routeIntelCommand({ args, cwd, raw, error, _intel, _core }) {
97
97
  else if (subcommand === 'extract-exports') {
98
98
  const filePath = args[2];
99
99
  if (!filePath) {
100
- error('Usage: gsd-tools intel extract-exports <file-path>', ERROR_REASON.USAGE);
100
+ error('Usage: pp-tools intel extract-exports <file-path>', ERROR_REASON.USAGE);
101
101
  return;
102
102
  }
103
103
  c.output(intel.intelExtractExports(path.resolve(cwd, filePath)), raw);
@@ -240,7 +240,7 @@ function intelUpdate(planningDir) {
240
240
  return disabledResponse();
241
241
  return {
242
242
  action: 'spawn_agent',
243
- message: 'Run gsd-tools intel update or spawn gsd-intel-updater agent for full refresh',
243
+ message: 'Run pp-tools intel update or spawn gsd-intel-updater agent for full refresh',
244
244
  };
245
245
  }
246
246
  /**
@@ -161,7 +161,7 @@ const ERROR_REASON = Object.freeze({
161
161
  CONFIG_NO_FILE: 'config_no_file',
162
162
  CONFIG_PARSE_FAILED: 'config_parse_failed',
163
163
  CONFIG_INVALID_KEY: 'config_invalid_key',
164
- // SDK / gsd-tools dispatch
164
+ // SDK / pp-tools dispatch
165
165
  SDK_FAIL_FAST: 'sdk_fail_fast',
166
166
  SDK_UNKNOWN_COMMAND: 'sdk_unknown_command',
167
167
  SDK_MISSING_ARG: 'sdk_missing_arg',
@@ -183,7 +183,7 @@ const ERROR_REASON = Object.freeze({
183
183
  });
184
184
  /**
185
185
  * Process-level flag: when true, error() emits structured JSON to stderr
186
- * instead of plain "Error: <message>" text. Set by gsd-tools.cjs when the
186
+ * instead of plain "Error: <message>" text. Set by pp-tools.cjs when the
187
187
  * CLI is invoked with `--json-errors`. Tests opt in to typed-IR error
188
188
  * assertions by passing that flag and parsing the JSON.
189
189
  *
@@ -10,7 +10,7 @@
10
10
  * at plan:pre (ui-phase) and autonomous.md at verify:post (ui-review). Further per-feature
11
11
  * cutovers are ongoing.
12
12
  *
13
- * Command surface: gsd-tools loop render-hooks <point>
13
+ * Command surface: pp-tools loop render-hooks <point>
14
14
  *
15
15
  * Exports (three things):
16
16
  * resolveLoopHooks({ point, registry, config }) → { point, activeHooks }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed phase subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Unsupported in this router:
7
7
  * - scaffold: routed through top-level scaffold command.
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed phases subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving current CJS semantics.
4
+ * Keeps pp-tools.cjs thin while preserving current CJS semantics.
5
5
  *
6
6
  * Unsupported in this router (treated as unknown):
7
7
  * - archive: `phases archive` is excluded from the subcommands list so it
@@ -8,7 +8,7 @@
8
8
  * Design constraints:
9
9
  * - Pure module: no I/O, no require() calls, no side effects.
10
10
  * - All inputs are validated; unknown values throw a TypeError.
11
- * - Consumed by the `gsd-tools drift-guard` CLI seam and by tests.
11
+ * - Consumed by the `pp-tools drift-guard` CLI seam and by tests.
12
12
  *
13
13
  * Authority ladder (rung values determine MISSING severity):
14
14
  * grep=0 intel=1 treesitter=2 lsp=3 scip=4
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * prohibition-enforcement — the deterministic PRODUCER for test-tier prohibition verification
4
- * (#1259, ADR-550 Decision 5d "heavy half"; the D1 seam — a NEW deterministic gsd-tools
4
+ * (#1259, ADR-550 Decision 5d "heavy half"; the D1 seam — a NEW deterministic pp-tools
5
5
  * sub-command, NOT free-form workflow prose).
6
6
  *
7
7
  * Today `dispositionForProhibition()` (src/probe-core.cts) already carries the POLICY seam: with
@@ -645,7 +645,7 @@ function parseRequest(args) {
645
645
  }
646
646
  }
647
647
  /**
648
- * CLI surface: `gsd_run check prohibition-enforcement <request.json>` (or `--json '<inline>'`).
648
+ * CLI surface: `pp_run check prohibition-enforcement <request.json>` (or `--json '<inline>'`).
649
649
  * Parses the request, runs the producer, and emits the result as JSON. Honors the no-throw
650
650
  * contract: malformed input -> structured `error(...)`, never an uncaught throw.
651
651
  */
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed roadmap subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * ADR-457 build-at-publish: the hand-written bin/lib/roadmap-command-router.cjs
7
7
  * collapsed to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
@@ -40,7 +40,7 @@ function checkW021(content) {
40
40
  const warnings = [];
41
41
  // Sentinel milestone integers exempt from W021
42
42
  const SENTINELS = new Set([0, 999]);
43
- const MIGRATION_CMD = 'gsd-tools roadmap upgrade --convention milestone-prefixed';
43
+ const MIGRATION_CMD = 'pp-tools roadmap upgrade --convention milestone-prefixed';
44
44
  // Milestone section heading: ## [GSD] v2.0 — Label OR ## v2.0: Label OR ## Roadmap v2.0
45
45
  // OR ## ✅ v2.0 OR ## 🚧 v2.0 (emoji-prefixed variants used by roadmap templates)
46
46
  // Capture the major integer.
@@ -346,7 +346,7 @@ function getMilestonePhaseFilter(cwd, versionOverride, phaseIdConvention) {
346
346
  if (!hasVersionedMilestonesGlobal && hasPhaseHeadings && phaseIdConvention === 'milestone-prefixed') {
347
347
  console.warn('[gsd] Deprecated: free-form ROADMAP.md detected (no versioned milestone headings). ' +
348
348
  'The project has phase_id_convention set to "milestone-prefixed" in config.json but the ' +
349
- 'ROADMAP does not use versioned milestone headings. Run `gsd-tools roadmap upgrade --convention milestone-prefixed` to migrate (dry-run by default).');
349
+ 'ROADMAP does not use versioned milestone headings. Run `pp-tools roadmap upgrade --convention milestone-prefixed` to migrate (dry-run by default).');
350
350
  }
351
351
  if (versionOverride) {
352
352
  const escapedVersion = escapeRegex(versionOverride);
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed state subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Phase 5.1: handlers that have SDK equivalents are dispatched via
7
7
  * executeForCjs (the sync bridge). CJS fallback is retained for:
@@ -50,7 +50,7 @@ function shouldResyncStateProgress(fields) {
50
50
  // ─── Cache ────────────────────────────────────────────────────────────────────
51
51
  // Cache disk scan results from buildStateFrontmatter per cwd per process (#1967).
52
52
  // Avoids re-reading N+1 directories on every state write when the phase structure
53
- // hasn't changed within the same gsd-tools invocation.
53
+ // hasn't changed within the same pp-tools invocation.
54
54
  const _diskScanCache = new Map();
55
55
  // Track all lock files held by this process so they can be removed on exit.
56
56
  // process.on('exit') fires even on process.exit(1), unlike try/finally which is
@@ -250,7 +250,7 @@ function stateReplaceFieldWithFallback(content, primary, fallback, value) {
250
250
  }
251
251
  // Neither pattern matched — field may have been reformatted or removed.
252
252
  // Log diagnostic so template drift is detected early rather than silently swallowed.
253
- process.stderr.write(`[gsd-tools] WARNING: STATE.md field "${primary}"${fallback ? ` (fallback: "${fallback}")` : ''} not found — update skipped. ` +
253
+ process.stderr.write(`[pp-tools] WARNING: STATE.md field "${primary}"${fallback ? ` (fallback: "${fallback}")` : ''} not found — update skipped. ` +
254
254
  `This may indicate STATE.md was externally modified or uses an unexpected format.\n`);
255
255
  return content;
256
256
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed validate subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * Phase 6: validate.consistency, validate.health, validate.agents are
7
7
  * dispatched via executeForCjs when the SDK is available. CJS fallback
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  /**
3
3
  * Manifest-backed verify subcommand router.
4
- * Keeps gsd-tools.cjs thin while preserving existing command semantics.
4
+ * Keeps pp-tools.cjs thin while preserving existing command semantics.
5
5
  *
6
6
  * ADR-457 build-at-publish: the hand-written bin/lib/verify-command-router.cjs
7
7
  * collapsed to a TypeScript source of truth. Behaviour is preserved byte-for-behaviour
@@ -1432,7 +1432,7 @@ function cmdValidateHealth(cwd, options, raw) {
1432
1432
  getMilestoneFromPhaseId: getMilestoneFromPhaseId,
1433
1433
  });
1434
1434
  for (const mm of mismatches) {
1435
- addIssue('warning', 'W021', `Phase ${mm.phaseId}: integer prefix implies ${mm.expectedMilestone} but listed under ${mm.foundInMilestone}`, 'Run `gsd-tools roadmap upgrade --convention milestone-prefixed` to migrate (dry-run by default)');
1435
+ addIssue('warning', 'W021', `Phase ${mm.phaseId}: integer prefix implies ${mm.expectedMilestone} but listed under ${mm.foundInMilestone}`, 'Run `pp-tools roadmap upgrade --convention milestone-prefixed` to migrate (dry-run by default)');
1436
1436
  }
1437
1437
  }
1438
1438
  }
@@ -94,9 +94,9 @@ function parseJsonc(text) {
94
94
  }
95
95
  // ─── Message constants (verbatim — downstream docs/tests depend on these) ─────
96
96
  function buildMsgDiverged(headSha, forkRef, forkSha) {
97
- return `⚠ Worktree base mismatch: HEAD (${shortSha(headSha)}) differs from ${forkRef} (${shortSha(forkSha)}). Running this phase sequentially on the main working tree. To keep parallel worktrees, set worktree.baseRef:"head" in .claude/settings.local.json (or run: gsd-tools worktree set-baseref). See #683.`;
97
+ return `⚠ Worktree base mismatch: HEAD (${shortSha(headSha)}) differs from ${forkRef} (${shortSha(forkSha)}). Running this phase sequentially on the main working tree. To keep parallel worktrees, set worktree.baseRef:"head" in .claude/settings.local.json (or run: pp-tools worktree set-baseref). See #683.`;
98
98
  }
99
- const MSG_UNKNOWN = `⚠ Cannot determine the worktree fork base (origin/HEAD unresolved). Running this phase sequentially on the main working tree to avoid a base mismatch. To keep parallel worktrees, set worktree.baseRef:"head" in .claude/settings.local.json (or run: gsd-tools worktree set-baseref). See #683.`;
99
+ const MSG_UNKNOWN = `⚠ Cannot determine the worktree fork base (origin/HEAD unresolved). Running this phase sequentially on the main working tree to avoid a base mismatch. To keep parallel worktrees, set worktree.baseRef:"head" in .claude/settings.local.json (or run: pp-tools worktree set-baseref). See #683.`;
100
100
  // ─── Exports ──────────────────────────────────────────────────────────────────
101
101
  /**
102
102
  * Returns the first 8 characters of a SHA, or '' if null/empty.
@@ -958,7 +958,7 @@ function pruneOrphanedWorktrees(repoRoot) {
958
958
  const plan = planWorktreePrune(repoRoot, { allowDestructive: false }, { parseWorktreePorcelain });
959
959
  const pruneResult = executeWorktreePrunePlan(plan);
960
960
  if (pruneResult && pruneResult.timedOut) {
961
- process.stderr.write('[gsd-tools] WARNING: worktree health check degraded' +
961
+ process.stderr.write('[pp-tools] WARNING: worktree health check degraded' +
962
962
  ' — git worktree prune timed out after 10s.' +
963
963
  ' Orphaned worktree metadata may remain until the next successful run.\n');
964
964
  }
@@ -6,7 +6,7 @@
6
6
  * Replaces repetitive inline bash patterns across ~50 GSD command/workflow/agent files.
7
7
  * Centralizes: config parsing, model resolution, phase lookup, git commits, summary verification.
8
8
  *
9
- * Usage: node gsd-tools.cjs <command> [args] [--raw] [--pick <field>]
9
+ * Usage: node pp-tools.cjs <command> [args] [--raw] [--pick <field>]
10
10
  *
11
11
  * Atomic Commands:
12
12
  * state load Load project config + state
@@ -253,7 +253,7 @@ const profileOutput = require('./lib/profile-output.cjs');
253
253
  * @param {object} opts
254
254
  * @param {string} opts.registryCommand - legacy bridge placeholder
255
255
  * @param {string[]} opts.registryArgs - legacy bridge placeholder
256
- * @param {string} opts.legacyCommand - original gsd-tools command name
256
+ * @param {string} opts.legacyCommand - original pp-tools command name
257
257
  * @param {string[]} opts.legacyArgs - original args
258
258
  * @param {string} opts.cwd - project dir
259
259
  * @param {boolean} opts.raw - raw output mode
@@ -293,7 +293,7 @@ function _dispatchNonFamily({ registryCommand, registryArgs, legacyCommand, lega
293
293
  * before requiring — defense-in-depth against corrupted/hand-edited registry entries.
294
294
  *
295
295
  * @param {object} opts
296
- * @param {string} opts.command The command name (top-level gsd-tools command)
296
+ * @param {string} opts.command The command name (top-level pp-tools command)
297
297
  * @param {string[]} opts.args Remaining args passed to the router
298
298
  * @param {string} opts.cwd Project working directory
299
299
  * @param {boolean} opts.raw Raw output mode flag
@@ -487,7 +487,7 @@ async function main() {
487
487
  let command = args[0];
488
488
 
489
489
  // Accept `query` as a meta-prefix for canonical dotted/spaced commands.
490
- // Workflows may call `node gsd-tools.cjs query <command>` directly.
490
+ // Workflows may call `node pp-tools.cjs query <command>` directly.
491
491
  if (command === 'query') {
492
492
  args.shift();
493
493
  command = args[0];
@@ -512,13 +512,13 @@ async function main() {
512
512
  }
513
513
  }
514
514
 
515
- // Top-level usage string — emitted by `gsd-tools` (no args) and by
516
- // `gsd-tools --help` / any `--help` request below.
515
+ // Top-level usage string — emitted by `pp-tools` (no args) and by
516
+ // `pp-tools --help` / any `--help` request below.
517
517
  // CR feedback: the command list must enumerate every top-level command
518
518
  // supported by the dispatcher so `--help` is actually useful for
519
519
  // discovery; previously it was a partial subset that didn't include
520
520
  // phase / roadmap / milestone / progress / etc.
521
- const TOP_LEVEL_USAGE = 'Usage: gsd-tools <command> [args] [--raw] [--pick <field>] [--cwd <path>] [--ws <name>] [--json-errors]\n' +
521
+ const TOP_LEVEL_USAGE = 'Usage: pp-tools <command> [args] [--raw] [--pick <field>] [--cwd <path>] [--ws <name>] [--json-errors]\n' +
522
522
  'Commands: agent, agent-skills, audit-open, audit-uat, check, check-commit, commit, commit-to-subrepo, ' +
523
523
  'config-ensure-section, config-get, config-new-project, config-path, config-set, migrate-config, ' +
524
524
  'current-timestamp, detect-custom-files, docs-init, drift-guard, effort, extract-messages, find-phase, ' +
@@ -534,7 +534,7 @@ async function main() {
534
534
  ' --ws <name> Override active workstream (or set GSD_WORKSTREAM)\n' +
535
535
  ' --json-errors Emit structured JSON error objects on stderr (or set GSD_JSON_ERRORS=1)\n\n' +
536
536
  'For command-specific argument requirements, invoke the command without args ' +
537
- '(e.g. `gsd-tools phase add`) — the resulting error lists what is required.';
537
+ '(e.g. `pp-tools phase add`) — the resulting error lists what is required.';
538
538
 
539
539
  if (!command) {
540
540
  error(TOP_LEVEL_USAGE);
@@ -558,7 +558,7 @@ async function main() {
558
558
  const NEVER_VALID_FLAGS = new Set(['--version', '-v']);
559
559
  for (const arg of args) {
560
560
  if (NEVER_VALID_FLAGS.has(arg)) {
561
- error(`Unknown flag: ${arg}\ngsd-tools does not accept version flags. Run "gsd-tools" with no arguments for usage.`, ERROR_REASON.USAGE);
561
+ error(`Unknown flag: ${arg}\npp-tools does not accept version flags. Run "pp-tools" with no arguments for usage.`, ERROR_REASON.USAGE);
562
562
  }
563
563
  }
564
564
 
@@ -1537,18 +1537,18 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1537
1537
  } else if (subcommand === 'query') {
1538
1538
  const tagIdx = args.indexOf('--tag');
1539
1539
  const tag = tagIdx !== -1 ? args[tagIdx + 1] : null;
1540
- if (!tag) error('Usage: gsd-tools learnings query --tag <tag>', ERROR_REASON.USAGE);
1540
+ if (!tag) error('Usage: pp-tools learnings query --tag <tag>', ERROR_REASON.USAGE);
1541
1541
  learnings.cmdLearningsQuery(tag, raw);
1542
1542
  } else if (subcommand === 'copy') {
1543
1543
  learnings.cmdLearningsCopy(cwd, raw);
1544
1544
  } else if (subcommand === 'prune') {
1545
1545
  const olderIdx = args.indexOf('--older-than');
1546
1546
  const olderThan = olderIdx !== -1 ? args[olderIdx + 1] : null;
1547
- if (!olderThan) error('Usage: gsd-tools learnings prune --older-than <duration>', ERROR_REASON.USAGE);
1547
+ if (!olderThan) error('Usage: pp-tools learnings prune --older-than <duration>', ERROR_REASON.USAGE);
1548
1548
  learnings.cmdLearningsPrune(olderThan, raw);
1549
1549
  } else if (subcommand === 'delete') {
1550
1550
  const id = args[2];
1551
- if (!id) error('Usage: gsd-tools learnings delete <id>', ERROR_REASON.USAGE);
1551
+ if (!id) error('Usage: pp-tools learnings delete <id>', ERROR_REASON.USAGE);
1552
1552
  learnings.cmdLearningsDelete(id, raw);
1553
1553
  } else {
1554
1554
  error('Unknown learnings subcommand. Available: list, query, copy, prune, delete', ERROR_REASON.SDK_UNKNOWN_COMMAND);
@@ -1587,7 +1587,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1587
1587
  const configDirIdx = args.indexOf('--config-dir');
1588
1588
  const configDir = configDirIdx !== -1 ? args[configDirIdx + 1] : null;
1589
1589
  if (!configDir) {
1590
- error('Usage: gsd-tools detect-custom-files --config-dir <path>', ERROR_REASON.USAGE);
1590
+ error('Usage: pp-tools detect-custom-files --config-dir <path>', ERROR_REASON.USAGE);
1591
1591
  }
1592
1592
  const resolvedConfigDir = path.resolve(configDir);
1593
1593
  if (!fs.existsSync(resolvedConfigDir)) {
@@ -1896,7 +1896,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1896
1896
  if (subcommand === 'get') {
1897
1897
  const key = args[2];
1898
1898
  if (!key || key.startsWith('--')) {
1899
- error('Usage: gsd-tools research-store get <key> [--kind <k>]', ERROR_REASON.USAGE);
1899
+ error('Usage: pp-tools research-store get <key> [--kind <k>]', ERROR_REASON.USAGE);
1900
1900
  }
1901
1901
  if (!researchStore.isValidResearchKey(key)) {
1902
1902
  error('research-store: <key> must be a 64-char sha256 hex (use research-plan to obtain keys)', ERROR_REASON.USAGE);
@@ -1907,7 +1907,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1907
1907
  } else if (subcommand === 'put') {
1908
1908
  const key = args[2];
1909
1909
  if (!key || key.startsWith('--')) {
1910
- error('Usage: gsd-tools research-store put <key> --content <str> --source <s> --provider <p> --confidence <c> --kind <k>', ERROR_REASON.USAGE);
1910
+ error('Usage: pp-tools research-store put <key> --content <str> --source <s> --provider <p> --confidence <c> --kind <k>', ERROR_REASON.USAGE);
1911
1911
  }
1912
1912
  if (!researchStore.isValidResearchKey(key)) {
1913
1913
  error('research-store: <key> must be a 64-char sha256 hex (use research-plan to obtain keys)', ERROR_REASON.USAGE);
@@ -1932,7 +1932,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1932
1932
  const confidence = getFlagValue(confidenceIdx, '--confidence');
1933
1933
  const kind = getFlagValue(kindIdx, '--kind');
1934
1934
  if (!content || !source || !provider || !confidence || !kind) {
1935
- error('Usage: gsd-tools research-store put <key> --content <str> --source <s> --provider <p> --confidence <c> --kind <k>', ERROR_REASON.USAGE);
1935
+ error('Usage: pp-tools research-store put <key> --content <str> --source <s> --provider <p> --confidence <c> --kind <k>', ERROR_REASON.USAGE);
1936
1936
  }
1937
1937
  const entry = researchStore.putResearch(cwd, key, { content, source, provider, confidence, kind }, { homeDir });
1938
1938
  output(entry, raw);
@@ -1953,7 +1953,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1953
1953
  const inputIdx = args.indexOf('--input');
1954
1954
  const inputPath = inputIdx !== -1 ? args[inputIdx + 1] : null;
1955
1955
  if (!inputPath || inputPath.startsWith('--')) {
1956
- error('Usage: gsd-tools research-plan --input <path>', ERROR_REASON.USAGE);
1956
+ error('Usage: pp-tools research-plan --input <path>', ERROR_REASON.USAGE);
1957
1957
  }
1958
1958
  let planInput;
1959
1959
  try {
@@ -1987,7 +1987,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1987
1987
  const providerIdx = args.indexOf('--provider');
1988
1988
  const provider = providerIdx !== -1 ? args[providerIdx + 1] : null;
1989
1989
  if (!provider || provider.startsWith('--')) {
1990
- error('Usage: gsd-tools query classify-confidence --provider <id> [--package <name> --ecosystem <npm|pypi|crates>] [--verified]', ERROR_REASON.USAGE);
1990
+ error('Usage: pp-tools query classify-confidence --provider <id> [--package <name> --ecosystem <npm|pypi|crates>] [--verified]', ERROR_REASON.USAGE);
1991
1991
  }
1992
1992
  const verified = args.includes('--verified');
1993
1993
  const pkgIdx = args.indexOf('--package');
@@ -1998,7 +1998,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
1998
1998
  if (pkg && (!pkg.startsWith('--'))) {
1999
1999
  const VALID_ECOSYSTEMS = new Set(['npm', 'pypi', 'crates']);
2000
2000
  if (!ecosystem || ecosystem.startsWith('--') || !VALID_ECOSYSTEMS.has(ecosystem)) {
2001
- error('Usage: gsd-tools query classify-confidence --provider <id> [--package <name> --ecosystem <npm|pypi|crates>] [--verified]', ERROR_REASON.USAGE);
2001
+ error('Usage: pp-tools query classify-confidence --provider <id> [--package <name> --ecosystem <npm|pypi|crates>] [--verified]', ERROR_REASON.USAGE);
2002
2002
  }
2003
2003
  const pkgLegitimacy = require('./lib/package-legitimacy.cjs');
2004
2004
  const results = await pkgLegitimacy.checkPackages({ ecosystem, packages: [pkg] }, {});
@@ -2026,7 +2026,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
2026
2026
  const ecosystem = ecoIdx !== -1 ? args[ecoIdx + 1] : null;
2027
2027
  const VALID_ECOSYSTEMS = new Set(['npm', 'pypi', 'crates']);
2028
2028
  if (!ecosystem || !VALID_ECOSYSTEMS.has(ecosystem)) {
2029
- error('Usage: gsd-tools package-legitimacy check --ecosystem <npm|pypi|crates> <pkg1> ...', ERROR_REASON.USAGE);
2029
+ error('Usage: pp-tools package-legitimacy check --ecosystem <npm|pypi|crates> <pkg1> ...', ERROR_REASON.USAGE);
2030
2030
  }
2031
2031
  // Collect positional package names.
2032
2032
  // Only --ecosystem takes a value. Every non-flag arg is a package name.
@@ -2041,7 +2041,7 @@ async function runCommand(command, args, cwd, raw, defaultValue, originalCommand
2041
2041
  packages.push(a);
2042
2042
  }
2043
2043
  if (packages.length === 0) {
2044
- error('Usage: gsd-tools package-legitimacy check --ecosystem <eco> <pkg1> <pkg2> ...', ERROR_REASON.USAGE);
2044
+ error('Usage: pp-tools package-legitimacy check --ecosystem <eco> <pkg1> <pkg2> ...', ERROR_REASON.USAGE);
2045
2045
  }
2046
2046
  let pkgResults;
2047
2047
  try {
@@ -1,17 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2000" width="2000" height="2000">
2
- <defs>
3
- <style>
4
- .logo { font-family: 'SF Mono', 'Fira Code', 'JetBrains Mono', 'Courier New', monospace; fill: #7dcfff; }
5
- </style>
6
- </defs>
7
-
8
- <!-- GSD ASCII Logo - centered -->
9
- <g transform="translate(1000, 1000)">
10
- <text class="logo" font-size="108" text-anchor="middle" y="-225" xml:space="preserve"> ██████╗ ███████╗██████╗ </text>
11
- <text class="logo" font-size="108" text-anchor="middle" y="-105" xml:space="preserve"> ██╔════╝ ██╔════╝██╔══██╗</text>
12
- <text class="logo" font-size="108" text-anchor="middle" y="15" xml:space="preserve"> ██║ ███╗███████╗██║ ██║</text>
13
- <text class="logo" font-size="108" text-anchor="middle" y="135" xml:space="preserve"> ██║ ██║╚════██║██║ ██║</text>
14
- <text class="logo" font-size="108" text-anchor="middle" y="255" xml:space="preserve"> ╚██████╔╝███████║██████╔╝</text>
15
- <text class="logo" font-size="108" text-anchor="middle" y="375" xml:space="preserve"> ╚═════╝ ╚══════╝╚═════╝ </text>
16
- </g>
17
- </svg>
Binary file
@@ -1,21 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 2000 2000" width="2000" height="2000">
2
- <defs>
3
- <style>
4
- .bg { fill: #1a1b26; }
5
- .logo { font-family: 'SF Mono', 'Fira Code', 'JetBrains Mono', 'Courier New', monospace; fill: #7dcfff; }
6
- </style>
7
- </defs>
8
-
9
- <!-- Background -->
10
- <rect class="bg" width="2000" height="2000"/>
11
-
12
- <!-- GSD ASCII Logo - centered -->
13
- <g transform="translate(1000, 1000)">
14
- <text class="logo" font-size="108" text-anchor="middle" y="-225" xml:space="preserve"> ██████╗ ███████╗██████╗ </text>
15
- <text class="logo" font-size="108" text-anchor="middle" y="-105" xml:space="preserve"> ██╔════╝ ██╔════╝██╔══██╗</text>
16
- <text class="logo" font-size="108" text-anchor="middle" y="15" xml:space="preserve"> ██║ ███╗███████╗██║ ██║</text>
17
- <text class="logo" font-size="108" text-anchor="middle" y="135" xml:space="preserve"> ██║ ██║╚════██║██║ ██║</text>
18
- <text class="logo" font-size="108" text-anchor="middle" y="255" xml:space="preserve"> ╚██████╔╝███████║██████╔╝</text>
19
- <text class="logo" font-size="108" text-anchor="middle" y="375" xml:space="preserve"> ╚═════╝ ╚══════╝╚═════╝ </text>
20
- </g>
21
- </svg>