@pareto4/pp-core 1.11.1 → 1.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +31 -0
- package/agents/pp-code-fixer.md +1 -1
- package/agents/pp-debug-session-manager.md +1 -1
- package/agents/pp-debugger.md +1 -1
- package/agents/pp-executor.md +20 -10
- package/agents/pp-intel-updater.md +1 -1
- package/agents/pp-phase-researcher.md +1 -1
- package/agents/pp-plan-checker.md +5 -5
- package/agents/pp-planner.md +10 -24
- package/agents/pp-project-researcher.md +1 -1
- package/agents/pp-research-synthesizer.md +1 -1
- package/agents/pp-ui-researcher.md +1 -1
- package/agents/pp-verifier.md +8 -4
- package/bin/install.js +429 -82
- package/commands/pp-autonomous.md +8 -6
- package/commands/pp-discovery-to-build.md +1 -1
- package/commands/pp-discovery.md +3 -2
- package/commands/pp-discuss-phase.md +2 -2
- package/commands/pp-execute-phase.md +3 -1
- package/commands/pp-graphify.md +5 -5
- package/commands/pp-import.md +1 -1
- package/commands/pp-map-codebase.md +1 -1
- package/commands/pp-ns-project.md +2 -3
- package/commands/pp-ns-workflow.md +1 -1
- package/commands/pp-plan-phase.md +2 -1
- package/commands/pp-verify-work.md +2 -1
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-cursor-session-start.js +2 -2
- package/hooks/dist/pp-session-state.sh +1 -1
- package/hooks/dist/pp-statusline.js +21 -2
- package/hooks/pp-cursor-session-start.js +2 -2
- package/hooks/pp-session-state.sh +1 -1
- package/hooks/pp-statusline.js +21 -2
- package/package.json +18 -5
- package/pareto-skills/pp-project-setup/SKILL.md +5 -63
- package/pp-core/bin/detect-build-commands.sh +182 -0
- package/pp-core/bin/lib/capability-activation.cjs +19 -9
- package/pp-core/bin/lib/capability-registry.cjs +65 -7
- package/pp-core/bin/lib/check-command-router.cjs +79 -38
- package/pp-core/bin/lib/clusters.cjs +2 -3
- package/pp-core/bin/lib/command-aliases.cjs +36 -0
- package/pp-core/bin/lib/command-arg-projection.cjs +99 -1
- package/pp-core/bin/lib/commands.cjs +21 -6
- package/pp-core/bin/lib/compose-bindings.cjs +70 -6
- package/pp-core/bin/lib/config-loader.cjs +151 -8
- package/pp-core/bin/lib/config-schema.cjs +16 -0
- package/pp-core/bin/lib/config.cjs +142 -27
- package/pp-core/bin/lib/core-utils.cjs +43 -7
- package/pp-core/bin/lib/discovery-input-check.cjs +218 -0
- package/pp-core/bin/lib/discovery-rebaseline.cjs +1372 -0
- package/pp-core/bin/lib/discovery-research-track.cjs +979 -0
- package/pp-core/bin/lib/discovery-rollup.cjs +476 -0
- package/pp-core/bin/lib/discovery-screens.cjs +1995 -0
- package/pp-core/bin/lib/discovery-sweep.cjs +390 -0
- package/pp-core/bin/lib/discovery-table.cjs +98 -0
- package/pp-core/bin/lib/dispatch-plan.cjs +472 -0
- package/pp-core/bin/lib/frontmatter.cjs +17 -2
- package/pp-core/bin/lib/init-command-router.cjs +8 -5
- package/pp-core/bin/lib/init-contract.cjs +93 -4
- package/pp-core/bin/lib/init.cjs +124 -134
- package/pp-core/bin/lib/install-profiles.cjs +5 -0
- package/pp-core/bin/lib/install-run.cjs +536 -0
- package/pp-core/bin/lib/io.cjs +15 -0
- package/pp-core/bin/lib/loop-resolver.cjs +40 -2
- package/pp-core/bin/lib/milestone.cjs +345 -48
- package/pp-core/bin/lib/phase-command-router.cjs +23 -1
- package/pp-core/bin/lib/phase-locator.cjs +15 -6
- package/pp-core/bin/lib/phase-scope.cjs +91 -0
- package/pp-core/bin/lib/phase-tier.cjs +467 -0
- package/pp-core/bin/lib/phase.cjs +247 -21
- package/pp-core/bin/lib/phases-command-router.cjs +2 -0
- package/pp-core/bin/lib/plan-graph.cjs +368 -0
- package/pp-core/bin/lib/planning-workspace.cjs +53 -0
- package/pp-core/bin/lib/platform-bindings.cjs +32 -2
- package/pp-core/bin/lib/profile-output.cjs +11 -3
- package/pp-core/bin/lib/prohibition-enforcement.cjs +112 -0
- package/pp-core/bin/lib/roadmap-parser.cjs +366 -99
- package/pp-core/bin/lib/roadmap.cjs +141 -39
- package/pp-core/bin/lib/runtime-hooks-surface.cjs +1 -1
- package/pp-core/bin/lib/shell-command-projection.cjs +24 -0
- package/pp-core/bin/lib/state-command-router.cjs +82 -13
- package/pp-core/bin/lib/state-document.cjs +124 -7
- package/pp-core/bin/lib/state.cjs +784 -257
- package/pp-core/bin/lib/template.cjs +22 -6
- package/pp-core/bin/lib/vault-command-router.cjs +57 -6
- package/pp-core/bin/lib/vault-practices.cjs +6 -36
- package/pp-core/bin/lib/vault-write-back.cjs +20 -4
- package/pp-core/bin/lib/vault.cjs +592 -23
- package/pp-core/bin/lib/verify.cjs +53 -31
- package/pp-core/bin/lib/workstream.cjs +1 -1
- package/pp-core/bin/lib/worktree-safety.cjs +26 -15
- package/pp-core/bin/portable-timeout.sh +89 -0
- package/pp-core/bin/pp-tools.cjs +149 -9
- package/pp-core/bin/shared/config-defaults.manifest.json +7 -0
- package/pp-core/bin/shared/config-schema.manifest.json +3 -0
- package/pp-core/references/autonomous-best-effort.md +461 -0
- package/pp-core/references/autonomous-lifecycle.md +146 -0
- package/pp-core/references/autonomous-smart-discuss.md +16 -12
- package/pp-core/references/checkpoints.md +1 -1
- package/pp-core/references/discovery-id-conventions.md +202 -0
- package/pp-core/references/discovery-rebaseline.md +254 -0
- package/pp-core/references/discovery-research-track.md +283 -0
- package/pp-core/references/discovery-traceability.md +400 -0
- package/pp-core/references/loop-hook-dispatch.md +14 -0
- package/pp-core/references/mandatory-initial-read.md +1 -1
- package/pp-core/references/planner-gap-closure.md +1 -0
- package/pp-core/references/planner-human-verify-mode.md +1 -1
- package/pp-core/references/planner-load-graph-context.md +1 -1
- package/pp-core/references/planner-plan-graph.md +66 -0
- package/pp-core/references/planner-tdd.md +1 -0
- package/pp-core/references/planning-config.md +8 -0
- package/pp-core/references/sketch-tooling.md +4 -0
- package/pp-core/references/tdd.md +1 -0
- package/pp-core/templates/claude-md.md +1 -1
- package/pp-core/templates/phase-prompt.md +6 -2
- package/pp-core/templates/prototype-review/review.js +303 -0
- package/pp-core/templates/state.md +6 -0
- package/pp-core/workflows/_runtime-launcher.snippet.sh +1 -1
- package/pp-core/workflows/add-backlog.md +1 -1
- package/pp-core/workflows/add-phase.md +1 -1
- package/pp-core/workflows/add-tests.md +1 -1
- package/pp-core/workflows/add-todo.md +1 -1
- package/pp-core/workflows/ai-integration-phase.md +2 -2
- package/pp-core/workflows/audit-fix.md +12 -16
- package/pp-core/workflows/audit-milestone.md +2 -2
- package/pp-core/workflows/audit-uat.md +1 -1
- package/pp-core/workflows/autonomous.md +68 -306
- package/pp-core/workflows/check-todos.md +1 -1
- package/pp-core/workflows/cleanup.md +1 -1
- package/pp-core/workflows/code-review-fix.md +2 -2
- package/pp-core/workflows/code-review.md +20 -8
- package/pp-core/workflows/complete-milestone.md +41 -60
- package/pp-core/workflows/debug.md +1 -1
- package/pp-core/workflows/diagnose-issues.md +1 -1
- package/pp-core/workflows/discovery-sprint/gap-analysis.md +140 -0
- package/pp-core/workflows/discovery-sprint/input-package.md +140 -0
- package/pp-core/workflows/discovery-sprint/prefill.md +92 -0
- package/pp-core/workflows/discovery-sprint/prototype.md +257 -0
- package/pp-core/workflows/discovery-sprint/rebaseline.md +276 -0
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +24 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +92 -0
- package/pp-core/workflows/discovery-sprint/sessions/02-as-is.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +215 -0
- package/pp-core/workflows/discovery-sprint/sessions/04-ux-design.md +146 -0
- package/pp-core/workflows/discovery-sprint/sessions/05-architecture.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/06-security.md +107 -0
- package/pp-core/workflows/discovery-sprint/sessions/07-identity.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/08-integration.md +85 -0
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +109 -0
- package/pp-core/workflows/discovery-sprint/sessions/10-infrastructure.md +119 -0
- package/pp-core/workflows/discovery-sprint/sessions/11-roadmap.md +92 -0
- package/pp-core/workflows/discovery-sprint/sessions/12-delivery-model.md +98 -0
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +205 -0
- package/pp-core/workflows/discovery-sprint/templates/context-template.md +266 -0
- package/pp-core/workflows/discovery-sprint.md +79 -1714
- package/pp-core/workflows/discovery-to-build/steps/architecture-deliverables.md +5 -5
- package/pp-core/workflows/discovery-to-build/steps/screen-inventory-gate.md +70 -0
- package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +54 -0
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +184 -0
- package/pp-core/workflows/discovery-to-build.md +21 -238
- package/pp-core/workflows/discuss-phase/modes/advisor.md +1 -1
- package/pp-core/workflows/discuss-phase/modes/auto.md +1 -1
- package/pp-core/workflows/discuss-phase/modes/chain.md +1 -1
- package/pp-core/workflows/discuss-phase-assumptions.md +1 -1
- package/pp-core/workflows/discuss-phase.md +11 -4
- package/pp-core/workflows/do.md +4 -4
- package/pp-core/workflows/docs-update.md +1 -1
- package/pp-core/workflows/edit-phase.md +1 -1
- package/pp-core/workflows/eval-review.md +1 -1
- package/pp-core/workflows/execute-phase/steps/checkpoint-handling.md +45 -0
- package/pp-core/workflows/execute-phase/steps/client-context-gate.md +1 -1
- package/pp-core/workflows/execute-phase/steps/codebase-drift-gate.md +1 -1
- package/pp-core/workflows/execute-phase/steps/cross-ai-delegation.md +90 -0
- package/pp-core/workflows/execute-phase/steps/install-run.md +29 -0
- package/pp-core/workflows/execute-phase/steps/phase-close-rebaseline.md +23 -0
- package/pp-core/workflows/execute-phase/steps/post-merge-gate.md +76 -77
- package/pp-core/workflows/execute-phase/steps/serial-group-dispatch.md +72 -0
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +5 -5
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +19 -112
- package/pp-core/workflows/execute-phase.md +104 -218
- package/pp-core/workflows/execute-plan.md +6 -2
- package/pp-core/workflows/explore.md +1 -1
- package/pp-core/workflows/extract-learnings.md +1 -1
- package/pp-core/workflows/forensics.md +4 -4
- package/pp-core/workflows/graduation.md +1 -1
- package/pp-core/workflows/health.md +1 -1
- package/pp-core/workflows/help/modes/brief.md +1 -0
- package/pp-core/workflows/help/modes/default.md +2 -1
- package/pp-core/workflows/help/modes/full.md +12 -5
- package/pp-core/workflows/import.md +1 -1
- package/pp-core/workflows/ingest-docs.md +1 -1
- package/pp-core/workflows/init.md +18 -2
- package/pp-core/workflows/insert-phase.md +1 -1
- package/pp-core/workflows/list-workspaces.md +1 -1
- package/pp-core/workflows/manager.md +3 -3
- package/pp-core/workflows/map-codebase.md +2 -2
- package/pp-core/workflows/milestone-summary.md +4 -4
- package/pp-core/workflows/mvp-phase.md +1 -1
- package/pp-core/workflows/new-milestone.md +7 -8
- package/pp-core/workflows/new-project.md +6 -1
- package/pp-core/workflows/new-workspace.md +1 -1
- package/pp-core/workflows/next.md +2 -2
- package/pp-core/workflows/note.md +2 -2
- package/pp-core/workflows/pause-work.md +1 -1
- package/pp-core/workflows/plan-milestone-gaps.md +1 -1
- package/pp-core/workflows/plan-phase/steps/chunked-planning.md +111 -0
- package/pp-core/workflows/plan-phase/steps/phase-tier.md +34 -0
- package/pp-core/workflows/plan-phase.md +43 -167
- package/pp-core/workflows/plan-review-convergence.md +2 -2
- package/pp-core/workflows/plant-seed.md +1 -1
- package/pp-core/workflows/pr-branch.md +1 -1
- package/pp-core/workflows/profile-user.md +1 -1
- package/pp-core/workflows/progress.md +3 -3
- package/pp-core/workflows/quick.md +4 -2
- package/pp-core/workflows/remove-phase.md +1 -1
- package/pp-core/workflows/remove-workspace.md +1 -1
- package/pp-core/workflows/resume-project.md +6 -12
- package/pp-core/workflows/review.md +1 -1
- package/pp-core/workflows/scan.md +1 -1
- package/pp-core/workflows/secure-phase.md +2 -2
- package/pp-core/workflows/settings-advanced.md +1 -1
- package/pp-core/workflows/settings-integrations.md +1 -1
- package/pp-core/workflows/settings.md +1 -1
- package/pp-core/workflows/ship.md +26 -9
- package/pp-core/workflows/sketch-wrap-up.md +1 -1
- package/pp-core/workflows/sketch.md +2 -1
- package/pp-core/workflows/spec-phase.md +1 -1
- package/pp-core/workflows/spike-wrap-up.md +1 -1
- package/pp-core/workflows/spike.md +1 -1
- package/pp-core/workflows/stats.md +2 -2
- package/pp-core/workflows/thread.md +1 -1
- package/pp-core/workflows/transition.md +5 -9
- package/pp-core/workflows/ui-phase.md +23 -2
- package/pp-core/workflows/ui-review.md +1 -1
- package/pp-core/workflows/ultraplan-phase.md +2 -2
- package/pp-core/workflows/validate-phase.md +2 -2
- package/pp-core/workflows/vault-write-back.md +1 -1
- package/pp-core/workflows/verify-phase.md +29 -26
- package/pp-core/workflows/verify-work.md +14 -10
- package/scripts/base64-scan.sh +7 -41
- package/scripts/changeset/cli.cjs +25 -5
- package/scripts/dev-env.cjs +462 -0
- package/scripts/lib/allowlist-ratchet.cjs +103 -1
- package/scripts/lib/size-budget.cjs +311 -0
- package/scripts/lint-neutrality-names.cjs +694 -0
- package/scripts/lint-org-coordinates.allowlist.json +35 -0
- package/scripts/lint-org-coordinates.cjs +426 -0
- package/scripts/lint-skill-deps.cjs +48 -9
- package/scripts/lint-test-file-count.cjs +17 -2
- package/scripts/prompt-injection-scan.sh +41 -20
- package/scripts/sync-manifest-versions.cjs +41 -7
- package/scripts/sync-runtime-launcher.cjs +106 -1
- package/scripts/update-size-baseline.cjs +274 -30
- package/scripts/workflow-size.cjs +61 -9
- package/commands/pp-build-handoff.md +0 -46
- package/pp-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +0 -94
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Prototype review toolbar — copied verbatim into every discovery prototype by prototype.md Step 4.
|
|
3
|
+
* Stories overlay and element feedback; the export is a round of _feedback.md rows.
|
|
4
|
+
*/
|
|
5
|
+
(function () {
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
var VERDICTS = ['change', 'keep', 'drop', 'question'];
|
|
9
|
+
var SCREEN_ANCHOR = 'screen';
|
|
10
|
+
|
|
11
|
+
function cell(text) {
|
|
12
|
+
return String(text == null ? '' : text).replace(/\r?\n+/g, ' ').replace(/\|/g, '\\|').trim();
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function anchorOf(item) {
|
|
16
|
+
return item.screen + ' · #' + item.anchor;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function toMarkdown(data, items) {
|
|
20
|
+
var L = [];
|
|
21
|
+
L.push('# Prototype feedback — ' + data.project + ' — ' + data.version);
|
|
22
|
+
L.push('');
|
|
23
|
+
L.push('> **For Claude:** record the rows below as a new round in `.planning/discovery/_feedback.md`');
|
|
24
|
+
L.push('> through `/pp-discovery prototype` Step 6, then process every row in Step 7: each ends as a');
|
|
25
|
+
L.push('> requirement change, a UI decision, a `DG-`/`RS-` item or `No change`. Do not rebuild the');
|
|
26
|
+
L.push('> prototype before the round is processed.');
|
|
27
|
+
L.push('');
|
|
28
|
+
L.push('| Anchor | Verdict | Feedback | Processing |');
|
|
29
|
+
L.push('|--------|---------|----------|------------|');
|
|
30
|
+
items.forEach(function (it) {
|
|
31
|
+
L.push('| ' + cell(anchorOf(it)) + ' | ' + it.verdict + ' | ' + cell(it.comment) + ' | Open |');
|
|
32
|
+
});
|
|
33
|
+
L.push('');
|
|
34
|
+
L.push('<!-- machine data for re-import; do not edit -->');
|
|
35
|
+
L.push('```json');
|
|
36
|
+
L.push(JSON.stringify({ tool: 'pp-prototype-review', version: 1, project: data.project, round: data.version, items: items }));
|
|
37
|
+
L.push('```');
|
|
38
|
+
return L.join('\n') + '\n';
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function parseImport(text) {
|
|
42
|
+
var m = String(text).match(/```json\s*([\s\S]*?)```/);
|
|
43
|
+
var d = JSON.parse(m ? m[1] : text);
|
|
44
|
+
var items = Array.isArray(d) ? d : d.items;
|
|
45
|
+
if (!Array.isArray(items)) throw new Error('no items');
|
|
46
|
+
return items.filter(function (it) {
|
|
47
|
+
return it && /^SCR-\d{2,}$/.test(it.screen) && it.anchor && VERDICTS.indexOf(it.verdict) !== -1;
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
var api = { VERDICTS: VERDICTS, cell: cell, anchorOf: anchorOf, toMarkdown: toMarkdown, parseImport: parseImport };
|
|
52
|
+
if (typeof module !== 'undefined' && module.exports) module.exports = api;
|
|
53
|
+
if (typeof document === 'undefined') return;
|
|
54
|
+
|
|
55
|
+
var DATA = window.PP_REVIEW || {};
|
|
56
|
+
DATA.project = DATA.project || 'prototype';
|
|
57
|
+
DATA.version = DATA.version || 'Prototype v1';
|
|
58
|
+
DATA.requirements = DATA.requirements || {};
|
|
59
|
+
DATA.stories = DATA.stories || [];
|
|
60
|
+
var KEY = 'pp-review:' + DATA.project + ':' + DATA.version;
|
|
61
|
+
var FB = [];
|
|
62
|
+
|
|
63
|
+
function $(s, r) { return (r || document).querySelector(s); }
|
|
64
|
+
function $$(s, r) { return Array.prototype.slice.call((r || document).querySelectorAll(s)); }
|
|
65
|
+
function esc(s) { return String(s == null ? '' : s).replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"'); }
|
|
66
|
+
function el(tag, cls, html) { var e = document.createElement(tag); if (cls) e.className = cls; if (html != null) e.innerHTML = html; return e; }
|
|
67
|
+
function page() { return location.pathname.split('/').pop() || 'index.html'; }
|
|
68
|
+
|
|
69
|
+
function load() { try { FB = JSON.parse(localStorage.getItem(KEY) || '[]') || []; } catch (e) { FB = []; } }
|
|
70
|
+
function save() { try { localStorage.setItem(KEY, JSON.stringify(FB)); } catch (e) { /* export still works */ } }
|
|
71
|
+
|
|
72
|
+
var CSS = [
|
|
73
|
+
'#ppr-bar{position:fixed;top:8px;right:8px;z-index:2147483000;display:flex;gap:4px;font:600 12px/1 system-ui,sans-serif}',
|
|
74
|
+
'#ppr-bar button{border:1px solid #c9c9d1;background:#fff;color:#333;border-radius:6px;padding:6px 9px;cursor:pointer;box-shadow:0 1px 3px rgba(0,0,0,.15)}',
|
|
75
|
+
'#ppr-bar button.on{background:#7b2cbf;border-color:#7b2cbf;color:#fff}',
|
|
76
|
+
'body.ppr-req [data-req]{outline:1px dashed rgba(123,44,191,.6);outline-offset:2px}',
|
|
77
|
+
'.ppr-badge{display:none}',
|
|
78
|
+
'body.ppr-req .ppr-badge{display:inline-block;margin-left:6px;padding:1px 5px;border-radius:4px;background:#7b2cbf;color:#fff;font:700 9px/1.4 ui-monospace,monospace;vertical-align:1px}',
|
|
79
|
+
'body.ppr-fb [data-req][id]{outline:2px solid #7b2cbf;outline-offset:2px;cursor:crosshair}',
|
|
80
|
+
'#ppr-tip{position:fixed;z-index:2147483001;max-width:340px;background:#1f1f29;color:#fff;font:12px/1.45 system-ui,sans-serif;padding:9px 11px;border-radius:6px;pointer-events:none;display:none}',
|
|
81
|
+
'#ppr-tip b{color:#d0a8f5}#ppr-tip ul{margin:4px 0 0 16px;padding:0}#ppr-tip .s{margin-top:7px;padding-top:6px;border-top:1px solid #444}',
|
|
82
|
+
'.ppr-pin{position:absolute;top:-8px;right:-8px;z-index:20;min-width:18px;height:18px;padding:0 5px;border-radius:9px;background:#7b2cbf;color:#fff;font:700 10px/18px ui-monospace,monospace;text-align:center;cursor:pointer}',
|
|
83
|
+
'#ppr-pop,#ppr-page{font:13px/1.4 system-ui,sans-serif;color:#222}',
|
|
84
|
+
'#ppr-pop{position:fixed;z-index:2147483002;width:300px;background:#fff;border:1px solid #c9c9d1;border-radius:8px;box-shadow:0 14px 40px rgba(0,0,0,.25);padding:12px}',
|
|
85
|
+
'#ppr-pop .a{font:11px ui-monospace,monospace;color:#666;margin-bottom:8px;word-break:break-all}',
|
|
86
|
+
'.ppr-v{display:flex;gap:4px;margin-bottom:8px}.ppr-v button{flex:1;padding:5px 2px;border:1px solid #c9c9d1;border-radius:4px;background:#fff;cursor:pointer;font:600 11px system-ui}',
|
|
87
|
+
'.ppr-v button.on{background:#7b2cbf;border-color:#7b2cbf;color:#fff}',
|
|
88
|
+
'#ppr-pop textarea,#ppr-page textarea{width:100%;box-sizing:border-box;min-height:70px;font:13px system-ui;padding:6px 8px;border:1px solid #c9c9d1;border-radius:6px}',
|
|
89
|
+
'.ppr-row{display:flex;gap:6px;margin-top:8px;align-items:center}.ppr-row button{padding:5px 10px;border:1px solid #c9c9d1;border-radius:5px;background:#fff;cursor:pointer}',
|
|
90
|
+
'.ppr-row button.p{background:#7b2cbf;border-color:#7b2cbf;color:#fff}.ppr-sp{flex:1}',
|
|
91
|
+
'#ppr-page{position:fixed;inset:0;z-index:2147483002;background:#f6f6f8;overflow:auto}',
|
|
92
|
+
'#ppr-page header{position:sticky;top:0;display:flex;gap:8px;align-items:center;padding:12px 18px;background:#fff;border-bottom:1px solid #ddd}',
|
|
93
|
+
'#ppr-page .body{max-width:900px;margin:0 auto;padding:18px}',
|
|
94
|
+
'#ppr-page h3{font:700 11px ui-monospace,monospace;letter-spacing:.06em;color:#666;margin:18px 0 8px}',
|
|
95
|
+
'.ppr-item{background:#fff;border:1px solid #ddd;border-radius:6px;padding:10px;margin-bottom:8px}',
|
|
96
|
+
'.ppr-hide{display:none!important}'
|
|
97
|
+
].join('\n');
|
|
98
|
+
|
|
99
|
+
function screenOf(node) {
|
|
100
|
+
var root = node && node.closest ? node.closest('[data-screen]') : null;
|
|
101
|
+
return root ? root.getAttribute('data-screen') : null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function visibleScreen() {
|
|
105
|
+
var roots = $$('[data-screen]').filter(function (r) { return r.offsetParent !== null || r === document.body; });
|
|
106
|
+
return roots.length ? roots[0].getAttribute('data-screen') : null;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function reqIds(node) {
|
|
110
|
+
var v = node.getAttribute('data-req') || '';
|
|
111
|
+
var i = v.indexOf('·');
|
|
112
|
+
return { ids: (i === -1 ? v : v.slice(0, i)).split(',').map(function (s) { return s.trim(); }).filter(Boolean), what: i === -1 ? '' : v.slice(i + 1).trim() };
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/* ---------- Stories overlay ---------- */
|
|
116
|
+
function decorate() {
|
|
117
|
+
$$('[data-req]').forEach(function (n) {
|
|
118
|
+
if (n.querySelector(':scope > .ppr-badge')) return;
|
|
119
|
+
n.appendChild(el('span', 'ppr-badge', esc(reqIds(n).ids.join(', '))));
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function tipHtml(n) {
|
|
124
|
+
var r = reqIds(n);
|
|
125
|
+
var h = r.ids.map(function (id) {
|
|
126
|
+
return '<b>' + esc(id) + '</b> ' + esc(DATA.requirements[id] || '');
|
|
127
|
+
}).join('<br>');
|
|
128
|
+
if (r.what) h += '<br><i>' + esc(r.what) + '</i>';
|
|
129
|
+
DATA.stories.filter(function (s) {
|
|
130
|
+
return (s.reqs || []).some(function (id) { return r.ids.indexOf(id) !== -1; });
|
|
131
|
+
}).forEach(function (s) {
|
|
132
|
+
h += '<div class="s"><b>' + esc(s.id) + '</b> ' + esc(s.text) +
|
|
133
|
+
((s.criteria || []).length ? '<ul>' + s.criteria.map(function (c) { return '<li>' + esc(c) + '</li>'; }).join('') + '</ul>' : '') + '</div>';
|
|
134
|
+
});
|
|
135
|
+
return h;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/* ---------- Feedback ---------- */
|
|
139
|
+
function repin() {
|
|
140
|
+
$$('.ppr-pin').forEach(function (p) { p.remove(); });
|
|
141
|
+
var by = {};
|
|
142
|
+
FB.forEach(function (it) { if (it.page === page()) (by[it.anchor] = by[it.anchor] || []).push(it); });
|
|
143
|
+
Object.keys(by).forEach(function (a) {
|
|
144
|
+
if (a === SCREEN_ANCHOR) return;
|
|
145
|
+
var t = document.getElementById(a);
|
|
146
|
+
if (!t) return;
|
|
147
|
+
if (getComputedStyle(t).position === 'static') t.style.position = 'relative';
|
|
148
|
+
var p = el('span', 'ppr-pin', String(by[a].length));
|
|
149
|
+
p.title = by[a].map(function (i) { return '[' + i.verdict + '] ' + i.comment; }).join('\n');
|
|
150
|
+
p.addEventListener('click', function (e) { e.stopPropagation(); e.preventDefault(); openPage(); });
|
|
151
|
+
t.appendChild(p);
|
|
152
|
+
});
|
|
153
|
+
$('#ppr-count').textContent = '☰ ' + FB.length;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
var target = null, verdict = 'change';
|
|
157
|
+
function openPop(screen, anchor, label, x, y) {
|
|
158
|
+
target = { screen: screen, anchor: anchor, label: label };
|
|
159
|
+
verdict = 'change';
|
|
160
|
+
var pop = $('#ppr-pop');
|
|
161
|
+
$('.a', pop).textContent = screen + ' · #' + anchor + (label ? ' — ' + label : '');
|
|
162
|
+
$$('.ppr-v button', pop).forEach(function (b) { b.classList.toggle('on', b.getAttribute('data-v') === verdict); });
|
|
163
|
+
$('textarea', pop).value = '';
|
|
164
|
+
pop.classList.remove('ppr-hide');
|
|
165
|
+
pop.style.left = Math.max(10, Math.min(x, innerWidth - 312)) + 'px';
|
|
166
|
+
pop.style.top = Math.max(10, Math.min(y, innerHeight - 240)) + 'px';
|
|
167
|
+
$('textarea', pop).focus();
|
|
168
|
+
}
|
|
169
|
+
function closePop() { $('#ppr-pop').classList.add('ppr-hide'); target = null; }
|
|
170
|
+
function savePop() {
|
|
171
|
+
var txt = $('#ppr-pop textarea').value.trim();
|
|
172
|
+
if (target && txt) {
|
|
173
|
+
FB.push({ id: 'c' + Date.now() + Math.floor(Math.random() * 1e4), screen: target.screen, anchor: target.anchor,
|
|
174
|
+
label: target.label, page: page(), verdict: verdict, comment: txt });
|
|
175
|
+
save(); repin();
|
|
176
|
+
}
|
|
177
|
+
closePop();
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function openPage() {
|
|
181
|
+
var g = {};
|
|
182
|
+
FB.forEach(function (it) { (g[it.screen] = g[it.screen] || []).push(it); });
|
|
183
|
+
var body = $('#ppr-page .body');
|
|
184
|
+
body.innerHTML = FB.length ? Object.keys(g).sort().map(function (s) {
|
|
185
|
+
return '<h3>' + esc(s) + '</h3>' + g[s].map(function (it) {
|
|
186
|
+
return '<div class="ppr-item"><div class="ppr-row" style="margin-top:0">' +
|
|
187
|
+
'<select data-cid="' + it.id + '">' + VERDICTS.map(function (v) { return '<option' + (v === it.verdict ? ' selected' : '') + '>' + v + '</option>'; }).join('') + '</select>' +
|
|
188
|
+
'<code>#' + esc(it.anchor) + '</code> ' + esc(it.label || '') + '<span class="ppr-sp"></span>' +
|
|
189
|
+
'<button data-go="' + it.id + '" title="Go to element">↗</button><button data-del="' + it.id + '" title="Delete">✕</button></div>' +
|
|
190
|
+
'<textarea data-cid="' + it.id + '">' + esc(it.comment) + '</textarea></div>';
|
|
191
|
+
}).join('');
|
|
192
|
+
}).join('') : '<p>No feedback yet. Turn on <b>✎ Feedback</b> and click an element, or comment on the whole screen.</p>';
|
|
193
|
+
$('#ppr-page').classList.remove('ppr-hide');
|
|
194
|
+
}
|
|
195
|
+
function closePage() { $('#ppr-page').classList.add('ppr-hide'); }
|
|
196
|
+
|
|
197
|
+
function download() {
|
|
198
|
+
var a = document.createElement('a');
|
|
199
|
+
a.href = 'data:text/markdown;charset=utf-8,' + encodeURIComponent(toMarkdown(DATA, FB));
|
|
200
|
+
a.download = 'prototype-feedback-' + DATA.version.replace(/[^A-Za-z0-9]+/g, '-').toLowerCase() + '.md';
|
|
201
|
+
document.body.appendChild(a); a.click(); a.remove();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function build() {
|
|
205
|
+
var style = el('style'); style.textContent = CSS; document.head.appendChild(style);
|
|
206
|
+
var bar = el('div'); bar.id = 'ppr-bar';
|
|
207
|
+
bar.innerHTML = '<button id="sketch-req-overlay" title="Show requirements and user stories">ⓘ Stories</button>' +
|
|
208
|
+
'<button id="ppr-fb" title="Feedback mode: click an element to comment">✎ Feedback</button>' +
|
|
209
|
+
'<button id="ppr-screen" class="ppr-hide" title="Comment on this whole screen">▭ Screen</button>' +
|
|
210
|
+
'<button id="ppr-count" title="Feedback list, export and import">☰ 0</button>';
|
|
211
|
+
document.body.appendChild(bar);
|
|
212
|
+
var tip = el('div'); tip.id = 'ppr-tip'; document.body.appendChild(tip);
|
|
213
|
+
var pop = el('div', 'ppr-hide'); pop.id = 'ppr-pop';
|
|
214
|
+
pop.innerHTML = '<div class="a"></div><div class="ppr-v">' + VERDICTS.map(function (v) { return '<button data-v="' + v + '">' + v + '</button>'; }).join('') +
|
|
215
|
+
'</div><textarea placeholder="Your feedback…"></textarea><div class="ppr-row"><button class="p" data-act="save">Save</button><button data-act="cancel">Cancel</button></div>';
|
|
216
|
+
document.body.appendChild(pop);
|
|
217
|
+
var pg = el('div', 'ppr-hide'); pg.id = 'ppr-page';
|
|
218
|
+
pg.innerHTML = '<header><b>Feedback — ' + esc(DATA.version) + '</b><span class="ppr-sp"></span>' +
|
|
219
|
+
'<button data-act="import">Import</button><button data-act="clear">Clear</button><button data-act="export">Export</button><button data-act="close">Close</button></header>' +
|
|
220
|
+
'<div class="body"></div><input type="file" accept=".md,.json" class="ppr-hide">';
|
|
221
|
+
document.body.appendChild(pg);
|
|
222
|
+
|
|
223
|
+
$('#sketch-req-overlay').addEventListener('click', function () {
|
|
224
|
+
var on = document.body.classList.toggle('ppr-req'); this.classList.toggle('on', on); decorate();
|
|
225
|
+
if (!on) tip.style.display = 'none';
|
|
226
|
+
});
|
|
227
|
+
$('#ppr-fb').addEventListener('click', function () {
|
|
228
|
+
var on = document.body.classList.toggle('ppr-fb'); this.classList.toggle('on', on);
|
|
229
|
+
$('#ppr-screen').classList.toggle('ppr-hide', !on);
|
|
230
|
+
});
|
|
231
|
+
$('#ppr-screen').addEventListener('click', function (e) {
|
|
232
|
+
var s = visibleScreen();
|
|
233
|
+
if (s) openPop(s, SCREEN_ANCHOR, 'whole screen', e.clientX - 300, e.clientY + 16);
|
|
234
|
+
});
|
|
235
|
+
$('#ppr-count').addEventListener('click', openPage);
|
|
236
|
+
|
|
237
|
+
document.addEventListener('click', function (e) {
|
|
238
|
+
if (!document.body.classList.contains('ppr-fb') || e.target.closest('#ppr-bar,#ppr-pop,#ppr-page')) return;
|
|
239
|
+
var t = e.target.closest('[data-req][id]');
|
|
240
|
+
var s = t && screenOf(t);
|
|
241
|
+
if (!s) return;
|
|
242
|
+
e.preventDefault(); e.stopPropagation();
|
|
243
|
+
openPop(s, t.id, reqIds(t).what, e.clientX, e.clientY);
|
|
244
|
+
}, true);
|
|
245
|
+
|
|
246
|
+
document.addEventListener('mouseover', function (e) {
|
|
247
|
+
if (!document.body.classList.contains('ppr-req')) return;
|
|
248
|
+
var t = e.target.closest('[data-req]');
|
|
249
|
+
if (!t || e.target.closest('#ppr-bar')) { tip.style.display = 'none'; return; }
|
|
250
|
+
tip.innerHTML = tipHtml(t); tip.style.display = 'block';
|
|
251
|
+
});
|
|
252
|
+
document.addEventListener('mousemove', function (e) {
|
|
253
|
+
if (tip.style.display !== 'block') return;
|
|
254
|
+
var x = e.clientX + 14, y = e.clientY + 16;
|
|
255
|
+
if (x > innerWidth - 360) x = e.clientX - 354;
|
|
256
|
+
if (y > innerHeight - tip.offsetHeight - 10) y = e.clientY - tip.offsetHeight - 10;
|
|
257
|
+
tip.style.left = x + 'px'; tip.style.top = y + 'px';
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
pop.addEventListener('click', function (e) {
|
|
261
|
+
var b = e.target.closest('button'); if (!b) return;
|
|
262
|
+
if (b.getAttribute('data-v')) { verdict = b.getAttribute('data-v'); $$('.ppr-v button', pop).forEach(function (x) { x.classList.toggle('on', x === b); }); }
|
|
263
|
+
else if (b.getAttribute('data-act') === 'save') savePop();
|
|
264
|
+
else closePop();
|
|
265
|
+
});
|
|
266
|
+
|
|
267
|
+
var file = $('input[type=file]', pg);
|
|
268
|
+
pg.addEventListener('click', function (e) {
|
|
269
|
+
var b = e.target.closest('button'); if (!b) return;
|
|
270
|
+
var act = b.getAttribute('data-act'), del = b.getAttribute('data-del'), go = b.getAttribute('data-go');
|
|
271
|
+
if (act === 'close') closePage();
|
|
272
|
+
else if (act === 'export') download();
|
|
273
|
+
else if (act === 'import') file.click();
|
|
274
|
+
else if (act === 'clear' && confirm('Clear all feedback for ' + DATA.version + '?')) { FB = []; save(); repin(); openPage(); }
|
|
275
|
+
else if (del) { FB = FB.filter(function (i) { return i.id !== del; }); save(); repin(); openPage(); }
|
|
276
|
+
else if (go) {
|
|
277
|
+
var it = FB.filter(function (i) { return i.id === go; })[0]; if (!it) return;
|
|
278
|
+
if (it.page !== page()) { location.href = it.page + (it.anchor === SCREEN_ANCHOR ? '' : '#' + it.anchor); return; }
|
|
279
|
+
closePage();
|
|
280
|
+
var t = document.getElementById(it.anchor); if (t) t.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
pg.addEventListener('input', function (e) {
|
|
284
|
+
var id = e.target.getAttribute('data-cid'); if (!id) return;
|
|
285
|
+
FB.forEach(function (i) { if (i.id === id) { if (e.target.tagName === 'SELECT') i.verdict = e.target.value; else i.comment = e.target.value; } });
|
|
286
|
+
save(); repin();
|
|
287
|
+
});
|
|
288
|
+
file.addEventListener('change', function () {
|
|
289
|
+
var f = file.files[0]; if (!f) return;
|
|
290
|
+
var r = new FileReader();
|
|
291
|
+
r.onload = function () {
|
|
292
|
+
try { FB = parseImport(r.result); save(); repin(); openPage(); }
|
|
293
|
+
catch (err) { alert('Could not read this file — use an exported feedback file.'); }
|
|
294
|
+
};
|
|
295
|
+
r.readAsText(f); file.value = '';
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
load(); repin();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', build);
|
|
302
|
+
else build();
|
|
303
|
+
})();
|
|
@@ -49,6 +49,11 @@ Progress: [░░░░░░░░░░] 0%
|
|
|
49
49
|
|-------|-------|-------|----------|
|
|
50
50
|
| - | - | - | - |
|
|
51
51
|
|
|
52
|
+
**By Plan:**
|
|
53
|
+
|
|
54
|
+
| Plan | Duration | Tasks | Files |
|
|
55
|
+
|------|----------|-------|-------|
|
|
56
|
+
|
|
52
57
|
**Recent Trend:**
|
|
53
58
|
- Last 5 plans: [durations]
|
|
54
59
|
- Trend: [Improving / Stable / Degrading]
|
|
@@ -156,6 +161,7 @@ Track velocity to understand execution patterns:
|
|
|
156
161
|
- Total plans completed
|
|
157
162
|
- Average duration per plan
|
|
158
163
|
- Per-phase breakdown
|
|
164
|
+
- Per-plan rows (`state record-metric` appends them to the By Plan table)
|
|
159
165
|
- Recent trend (improving/stable/degrading)
|
|
160
166
|
|
|
161
167
|
Updated after each plan completion.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
_PP_SHIM_NAME="pp-tools.cjs";
|
|
1
|
+
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; 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}"; 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}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v 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
|
|
@@ -19,7 +19,7 @@ cat .planning/ROADMAP.md
|
|
|
19
19
|
## Step 2: Find next backlog number
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
_PP_SHIM_NAME="pp-tools.cjs";
|
|
22
|
+
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; 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}"; 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}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v 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
|
|
23
23
|
NEXT=$(pp_run query phase.next-decimal 999 --raw)
|
|
24
24
|
```
|
|
25
25
|
|
|
@@ -29,7 +29,7 @@ Exit.
|
|
|
29
29
|
Load phase operation context:
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
_PP_SHIM_NAME="pp-tools.cjs";
|
|
32
|
+
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; 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}"; 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}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v 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
|
|
33
33
|
INIT=$(pp_run query init.phase-op "0")
|
|
34
34
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
35
35
|
```
|
|
@@ -33,7 +33,7 @@ Exit.
|
|
|
33
33
|
Load phase operation context:
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
_PP_SHIM_NAME="pp-tools.cjs";
|
|
36
|
+
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; 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}"; 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}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v 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
|
|
37
37
|
INIT=$(pp_run query init.phase-op "${PHASE_ARG}")
|
|
38
38
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
39
39
|
```
|
|
@@ -12,7 +12,7 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
12
12
|
Load todo context:
|
|
13
13
|
|
|
14
14
|
```bash
|
|
15
|
-
_PP_SHIM_NAME="pp-tools.cjs";
|
|
15
|
+
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; 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}"; 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}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v 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
|
|
16
16
|
INIT=$(pp_run query init.todos)
|
|
17
17
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
18
18
|
```
|
|
@@ -20,7 +20,7 @@ This prevents the two most common AI development failures: choosing the wrong fr
|
|
|
20
20
|
## 1. Initialize
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
_PP_SHIM_NAME="pp-tools.cjs";
|
|
23
|
+
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; 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}"; 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}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v 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
|
|
24
24
|
INIT=$(pp_run query init.plan-phase "$PHASE")
|
|
25
25
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
26
26
|
```
|
|
@@ -48,7 +48,7 @@ AI phase is disabled in config. Enable via /pp:settings.
|
|
|
48
48
|
```
|
|
49
49
|
Exit workflow.
|
|
50
50
|
|
|
51
|
-
**If `planning_exists` is false:** Error — run `/pp:
|
|
51
|
+
**If `planning_exists` is false:** Error — run `/pp:init` first.
|
|
52
52
|
|
|
53
53
|
## 2. Parse and Validate Phase
|
|
54
54
|
|
|
@@ -32,7 +32,7 @@ Invoke the source audit command and capture output.
|
|
|
32
32
|
|
|
33
33
|
For `audit-uat` source:
|
|
34
34
|
```bash
|
|
35
|
-
_PP_SHIM_NAME="pp-tools.cjs";
|
|
35
|
+
_PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_[A-Za-z0-9_]*\)=.*/\1/p'); do unset "$_v"; done; _c=$(git rev-parse --git-common-dir 2>/dev/null); if [ "${_c##*/}" = .git ] && cd "$_c/.." 2>/dev/null; then pwd -P; else git rev-parse --show-toplevel 2>/dev/null || pwd; fi ); }; pp_run() { case "$PP_TOOLS" in *.cjs) node "$PP_TOOLS" "$@";; *) "$PP_TOOLS" "$@";; esac; }; _PP_RUNTIME_ROOT="${RUNTIME_DIR:-$(_pp_root)}"; PP_TOOLS="${_PP_RUNTIME_ROOT}/pp-core/bin/${_PP_SHIM_NAME}"; if [ -f "$PP_TOOLS" ]; then :; 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}"; 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}"; elif [ -f "$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}" ]; then PP_TOOLS="$HOME/.claude/pp-core/bin/${_PP_SHIM_NAME}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; 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}"; elif command -v pp-tools >/dev/null 2>&1; then PP_TOOLS="$(command -v 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
|
|
36
36
|
INIT=$(pp_run query audit-uat 2>/dev/null || echo "{}")
|
|
37
37
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
38
38
|
```
|
|
@@ -106,25 +106,21 @@ Agent(
|
|
|
106
106
|
|
|
107
107
|
**b. Run tests:**
|
|
108
108
|
```bash
|
|
109
|
-
|
|
109
|
+
# Test command: project config first, else the shared sniff ladder
|
|
110
|
+
PP_GATE_BIN=$(printf '%s\n' "${PP_TOOLS:+${PP_TOOLS%/*}:}$PATH" | tr : '\n' | while IFS= read -r d; do if [ -r "$d/detect-build-commands.sh" ]; then printf %s "$d"; break; fi; done)
|
|
111
|
+
AUDIT_TEST_CMD=$(pp_run query config-get workflow.test_command --default "" --raw 2>/dev/null || true)
|
|
110
112
|
if [ -z "$AUDIT_TEST_CMD" ]; then
|
|
111
|
-
if [ -
|
|
112
|
-
|
|
113
|
-
elif [ -f "Justfile" ] || [ -f "justfile" ]; then
|
|
114
|
-
AUDIT_TEST_CMD="just test"
|
|
115
|
-
elif [ -f "package.json" ]; then
|
|
116
|
-
AUDIT_TEST_CMD="npm test"
|
|
117
|
-
elif [ -f "Cargo.toml" ]; then
|
|
118
|
-
AUDIT_TEST_CMD="cargo test"
|
|
119
|
-
elif [ -f "go.mod" ]; then
|
|
120
|
-
AUDIT_TEST_CMD="go test ./..."
|
|
121
|
-
elif [ -f "pyproject.toml" ] || [ -f "requirements.txt" ]; then
|
|
122
|
-
AUDIT_TEST_CMD="python -m pytest -x -q --tb=short"
|
|
113
|
+
if [ -r "$PP_GATE_BIN/detect-build-commands.sh" ]; then
|
|
114
|
+
. "$PP_GATE_BIN/detect-build-commands.sh"; AUDIT_TEST_CMD=$(pp_detect_test_cmd)
|
|
123
115
|
else
|
|
124
|
-
|
|
116
|
+
echo "✗ pp-core sniff ladder not found beside pp-tools — cannot detect a test command"
|
|
125
117
|
fi
|
|
126
118
|
fi
|
|
127
|
-
|
|
119
|
+
if [ -z "$AUDIT_TEST_CMD" ]; then
|
|
120
|
+
echo "⚠ Audit tests NOT RUN — no test runner detected (not a pass, not a failure)"
|
|
121
|
+
else
|
|
122
|
+
eval "$AUDIT_TEST_CMD" 2>&1 | tail -20
|
|
123
|
+
fi
|
|
128
124
|
```
|
|
129
125
|
|
|
130
126
|
**c. If tests pass** — commit atomically:
|