@pareto4/pp-core 1.21.1 → 1.23.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/bin/install.js +205 -28
- package/commands/pp-help.md +2 -1
- package/gemini-extension.json +1 -1
- package/hooks/dist/pp-check-update-worker.js +1 -1
- package/hooks/dist/pp-context-monitor.js +3 -3
- package/hooks/dist/pp-statusline.js +88 -14
- package/hooks/dist/pp-update-banner.js +44 -4
- package/hooks/dist/pp-workflow-guard.js +3 -3
- package/hooks/pp-check-update-worker.js +1 -1
- package/hooks/pp-context-monitor.js +3 -3
- package/hooks/pp-statusline.js +88 -14
- package/hooks/pp-update-banner.js +44 -4
- package/hooks/pp-workflow-guard.js +3 -3
- package/package.json +2 -2
- package/pp-core/bin/lib/audience-command.cjs +271 -0
- package/pp-core/bin/lib/audience.cjs +293 -0
- package/pp-core/bin/lib/commands.cjs +26 -17
- package/pp-core/bin/lib/discovery-charter.cjs +13 -1
- package/pp-core/bin/lib/discovery-flow-page.cjs +191 -0
- package/pp-core/bin/lib/discovery-for-phase.cjs +33 -5
- package/pp-core/bin/lib/discovery-input-check.cjs +11 -11
- package/pp-core/bin/lib/discovery-processes.cjs +97 -4
- package/pp-core/bin/lib/discovery-session-check.cjs +7 -7
- package/pp-core/bin/lib/discovery-status.cjs +419 -0
- package/pp-core/bin/lib/discovery-stories.cjs +36 -5
- package/pp-core/bin/lib/discovery-tests.cjs +398 -0
- package/pp-core/bin/lib/explain-command.cjs +48 -0
- package/pp-core/bin/lib/gate-card.cjs +97 -0
- package/pp-core/bin/lib/hook-messages.cjs +132 -0
- package/pp-core/bin/lib/init-contract.cjs +116 -76
- package/pp-core/bin/lib/init-interactive.cjs +110 -49
- package/pp-core/bin/lib/init.cjs +44 -3
- package/pp-core/bin/lib/io.cjs +38 -0
- package/pp-core/bin/lib/message-labels.cjs +75 -0
- package/pp-core/bin/lib/messages/core.cjs +20 -0
- package/pp-core/bin/lib/messages/discovery.cjs +267 -0
- package/pp-core/bin/lib/messages/gate.cjs +257 -0
- package/pp-core/bin/lib/messages/hook.cjs +114 -0
- package/pp-core/bin/lib/messages/init.cjs +513 -0
- package/pp-core/bin/lib/messages/progress.cjs +110 -0
- package/pp-core/bin/lib/messages.cjs +208 -0
- package/pp-core/bin/lib/vault-command-router.cjs +16 -3
- package/pp-core/bin/lib/violation-render.cjs +78 -0
- package/pp-core/bin/pp-tools.cjs +92 -23
- package/pp-core/bin/shared/config-schema.manifest.json +1 -0
- package/pp-core/references/audience-moments.md +119 -0
- package/pp-core/references/audience.md +114 -0
- package/pp-core/references/discovery-build-consumption.md +5 -2
- package/pp-core/references/discovery-charter.md +2 -2
- package/pp-core/references/discovery-id-conventions.md +1 -1
- package/pp-core/references/discovery-processes.md +31 -7
- package/pp-core/references/discovery-session-output.md +1 -1
- package/pp-core/references/discovery-tests.md +186 -0
- package/pp-core/templates/project-charter.md +3 -4
- package/pp-core/workflows/add-phase.md +2 -0
- package/pp-core/workflows/add-tests.md +2 -0
- package/pp-core/workflows/add-todo.md +2 -0
- package/pp-core/workflows/ai-integration-phase.md +2 -0
- package/pp-core/workflows/audit-milestone.md +2 -0
- package/pp-core/workflows/autonomous.md +2 -0
- package/pp-core/workflows/check-todos.md +2 -0
- package/pp-core/workflows/code-review-fix.md +2 -0
- package/pp-core/workflows/code-review.md +2 -0
- package/pp-core/workflows/complete-milestone.md +10 -1
- package/pp-core/workflows/discovery-sprint/charter.md +3 -2
- package/pp-core/workflows/discovery-sprint/prefill.md +3 -0
- package/pp-core/workflows/discovery-sprint/prototype.md +14 -0
- package/pp-core/workflows/discovery-sprint/session-13-gates.md +2 -0
- package/pp-core/workflows/discovery-sprint/sessions/01-kick-off.md +4 -1
- package/pp-core/workflows/discovery-sprint/sessions/03-to-be.md +135 -76
- package/pp-core/workflows/discovery-sprint/sessions/09-qa.md +94 -64
- package/pp-core/workflows/discovery-sprint/sessions/13-wrap-up.md +3 -2
- package/pp-core/workflows/discovery-sprint/vault-context.md +15 -0
- package/pp-core/workflows/discovery-sprint.md +16 -2
- package/pp-core/workflows/discovery-to-build/steps/handoff-gates.md +16 -9
- package/pp-core/workflows/discovery-to-build/templates/discovery-references.md +1 -1
- package/pp-core/workflows/discovery-to-build/templates/pp-handoff.md +9 -1
- package/pp-core/workflows/discovery-to-build.md +10 -4
- package/pp-core/workflows/discuss-phase/discovery.md +2 -2
- package/pp-core/workflows/discuss-phase-assumptions.md +2 -0
- package/pp-core/workflows/discuss-phase.md +1 -1
- package/pp-core/workflows/edit-phase.md +2 -0
- package/pp-core/workflows/eval-review.md +2 -0
- package/pp-core/workflows/execute-phase/steps/check-query-gate.md +25 -1
- package/pp-core/workflows/execute-phase/steps/vault-fetch.md +1 -0
- package/pp-core/workflows/execute-phase/steps/vault-load-gate.md +2 -0
- package/pp-core/workflows/execute-phase.md +1 -1
- package/pp-core/workflows/execute-plan.md +2 -0
- package/pp-core/workflows/extract-learnings.md +2 -0
- package/pp-core/workflows/help/modes/business.md +56 -0
- package/pp-core/workflows/help.md +12 -2
- package/pp-core/workflows/import.md +10 -1
- package/pp-core/workflows/ingest-docs.md +2 -0
- package/pp-core/workflows/init.md +17 -1
- package/pp-core/workflows/insert-phase.md +2 -0
- package/pp-core/workflows/list-workspaces.md +2 -0
- package/pp-core/workflows/manager.md +2 -0
- package/pp-core/workflows/map-codebase.md +2 -0
- package/pp-core/workflows/milestone-summary.md +2 -0
- package/pp-core/workflows/new-milestone.md +10 -1
- package/pp-core/workflows/new-project.md +12 -2
- package/pp-core/workflows/new-workspace.md +2 -0
- package/pp-core/workflows/next.md +8 -0
- package/pp-core/workflows/plan-milestone-gaps.md +10 -1
- package/pp-core/workflows/plan-phase.md +2 -1
- package/pp-core/workflows/plan-review-convergence.md +1 -1
- package/pp-core/workflows/progress.md +10 -0
- package/pp-core/workflows/quick.md +11 -1
- package/pp-core/workflows/remove-phase.md +2 -0
- package/pp-core/workflows/remove-workspace.md +2 -0
- package/pp-core/workflows/resume-project.md +25 -0
- package/pp-core/workflows/review.md +2 -0
- package/pp-core/workflows/scan.md +2 -0
- package/pp-core/workflows/secure-phase.md +2 -0
- package/pp-core/workflows/settings.md +41 -0
- package/pp-core/workflows/ship.md +2 -0
- package/pp-core/workflows/spec-phase.md +1 -1
- package/pp-core/workflows/ui-phase.md +2 -0
- package/pp-core/workflows/ui-review.md +2 -0
- package/pp-core/workflows/ultraplan-phase.md +2 -0
- package/pp-core/workflows/validate-phase.md +2 -0
- package/pp-core/workflows/vault-review.md +2 -0
- package/pp-core/workflows/verify-phase.md +2 -0
- package/pp-core/workflows/verify-work.md +2 -0
- package/scripts/affected-tests-lib.cjs +26 -12
- package/scripts/ci-release-only.cjs +158 -0
- package/scripts/live-runs/driver.cjs +326 -0
- package/scripts/live-runs/run.cjs +906 -0
- package/scripts/live-runs/scenarios.cjs +326 -0
- package/scripts/live-runs/scratch-project.cjs +132 -0
- package/scripts/live-runs/scrub.cjs +291 -0
- package/scripts/live-runs/turn-guard.cjs +107 -0
- package/scripts/live-runs/walk-setup.cjs +198 -0
- package/scripts/run-tests.cjs +151 -132
- package/scripts/test-env.cjs +64 -0
|
@@ -102,13 +102,16 @@ _PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_
|
|
|
102
102
|
[ -z "${ZSH_VERSION:-}" ] || emulate -R sh
|
|
103
103
|
GATE_RESULT=$(pp_run check "${GATE_QUERY}" ${GATE_POSITIONAL_ARG:+"${GATE_POSITIONAL_ARG}"} ${GATE_POSITIONAL_ARG_2:+"${GATE_POSITIONAL_ARG_2}"} ${GATE_WS:+--ws} ${GATE_WS:+"${GATE_WS}"} ${GATE_STAGE:+--stage} ${GATE_STAGE:+"${GATE_STAGE}"} ${GATE_UNPAIRED:+--unpaired} ${GATE_UNPAIRED:+"${GATE_UNPAIRED}"} --raw)
|
|
104
104
|
CHECK_EXIT=$?
|
|
105
|
+
GATE_CARDS=$(pp_run gate-card "${GATE_QUERY}" 2>/dev/null | node -e "const d=require('fs').readFileSync(0,'utf-8');const c=String.fromCharCode;try{const j=JSON.parse(d);if(j&&typeof j==='object'&&Array.isArray(j)===false)process.stdout.write(JSON.stringify(j).replace(new RegExp('['+c(127)+'-'+c(159)+c(8232,8233)+']','g'),(x)=>'\\\\u'+('000'+x.charCodeAt(0).toString(16)).slice(-4)));}catch{}" || true)
|
|
105
106
|
if [ "$CHECK_EXIT" -ne 0 ] || [ -z "$GATE_RESULT" ] || ! printf '%s' "$GATE_RESULT" | node -e "const j=JSON.parse(require('fs').readFileSync(0,'utf-8'));if(j===null||typeof j!=='object')process.exit(1)" 2>/dev/null; then
|
|
106
107
|
echo "GATE_CHECK=failed"
|
|
108
|
+
if [ -n "$GATE_CARDS" ]; then printf 'GATE_CARDS=%s\n' "$GATE_CARDS"; fi
|
|
107
109
|
else
|
|
108
110
|
GATE_BLOCK=$(printf '%s' "$GATE_RESULT" | node -e "const d=require('fs').readFileSync(0,'utf-8');try{process.stdout.write(String(JSON.parse(d).block===true));}catch{process.stdout.write('true');}")
|
|
109
111
|
GATE_MESSAGE=$(printf '%s' "$GATE_RESULT" | node -e "const d=require('fs').readFileSync(0,'utf-8');const c=String.fromCharCode;const r=(a,b)=>c(a)+'-'+c(b);try{const m=JSON.parse(d).message;process.stdout.write(typeof m==='string'?m.replace(new RegExp('['+r(0,8)+c(11,12)+r(14,31)+r(127,132)+r(134,159)+']','g'),' ').replace(new RegExp(c(13,10)+'|['+c(13,10,133,8232,8233)+']','g'),c(10)+' '):'');}catch{process.stdout.write('');}")
|
|
110
112
|
echo "GATE_CHECK=ok"
|
|
111
113
|
echo "GATE_BLOCK=$GATE_BLOCK"
|
|
114
|
+
if [ -n "$GATE_CARDS" ]; then printf 'GATE_CARDS=%s\n' "$GATE_CARDS"; fi
|
|
112
115
|
if [ -n "$GATE_MESSAGE" ]; then printf 'GATE_MESSAGE=%s\n' "$GATE_MESSAGE"; fi
|
|
113
116
|
fi
|
|
114
117
|
```
|
|
@@ -128,6 +131,16 @@ routes on** (16 review W-1, D-97). It prints exactly one of two shapes:
|
|
|
128
131
|
verdict is the one `GATE_BLOCK=` line at column 0, and a message cannot print a second one (16
|
|
129
132
|
review iteration 3 WR-01).
|
|
130
133
|
|
|
134
|
+
**The audience card line (Phase 43, D-11).** For a business user or business engineer, either shape
|
|
135
|
+
carries one more line, `GATE_CARDS=` followed by one line of JSON from `pp_run gate-card`: the cards
|
|
136
|
+
for this query by state, each with a `code` and a `text`. It comes before any `GATE_MESSAGE=` line,
|
|
137
|
+
so the message is still last. The fence prints the line only when the verb's output parses as one
|
|
138
|
+
JSON object, and it re-serialises that object with DEL, the C1 controls (NEL among them) and the
|
|
139
|
+
Unicode line separators escaped, so the line is always exactly one line and can never begin a
|
|
140
|
+
verdict line of its own (43 review WR-02). For a developer the verb prints nothing and no such line appears; an
|
|
141
|
+
engine without the verb prints nothing either, and the lines below apply as written. The call stays
|
|
142
|
+
in this fence because it is the only one with the launcher.
|
|
143
|
+
|
|
131
144
|
The verdict is computed here, in the shell that ran the check, for two measured reasons. **The
|
|
132
145
|
engine:** this is the only fence in this file that carries the launcher preamble (the launcher
|
|
133
146
|
generator keeps ONE preamble per file, in its first `pp_run` fence, and strips any other), so a
|
|
@@ -200,6 +213,9 @@ engine): with nothing printed there is no verdict to read. Route it by the hook'
|
|
|
200
213
|
hook, and — this is an imperative, not a preference — **do NOT read a verdict.** The fence
|
|
201
214
|
prints none on this path, and none may be inferred.
|
|
202
215
|
|
|
216
|
+
When step 1 printed a `GATE_CARDS=` line, print the `error` card's `text` and then `Ref: ` with its
|
|
217
|
+
`code` instead of the ⚠ line on either path. Nothing else changes: the halt block on `halt`, the next hook on `skip`, and no verdict read.
|
|
218
|
+
|
|
203
219
|
Merging these two steps is the fail-open this gate exists to close: if a non-zero exit were read as
|
|
204
220
|
a verdict, `onError: skip` would swallow a genuine block as a command warning.
|
|
205
221
|
|
|
@@ -233,6 +249,12 @@ behind the command-error test; it exists so that a future edit which removes tha
|
|
|
233
249
|
|
|
234
250
|
- **`GATE_BLOCK` is `false` → continue.** No status line.
|
|
235
251
|
|
|
252
|
+
When step 1 printed a `GATE_CARDS=` line, print instead of the ⚠ or ℹ line the matching card's `text`
|
|
253
|
+
(`blocked` on the halt, `advisory` for the advisory line), then `Ref: ` with its `code`, then — when
|
|
254
|
+
step 1 printed a `GATE_MESSAGE=` — `Details:` followed by that message (D-10, D-12). The halt block
|
|
255
|
+
below runs unchanged. The output-independence rule applies to the card exactly as to the lines it
|
|
256
|
+
replaces.
|
|
257
|
+
|
|
236
258
|
**Output-independence rule (a later plan's byte-identical regression pin depends on this).** On
|
|
237
259
|
every NON-halting path, the enforcer's printed output must be **identical** whether `GATE_BLOCKING`
|
|
238
260
|
is `true` or `false`. `blocking` decides one thing only: whether a `true` block halts. It must never
|
|
@@ -276,7 +298,9 @@ of step 1's output, its later lines indented by two spaces — it is already ope
|
|
|
276
298
|
multi-line text. A gate that has
|
|
277
299
|
something to tell the operator says it on every run, not only when its verdict is bad. This rule is
|
|
278
300
|
preserved word-for-word in effect from the ship.md loop this file replaced; a later plan makes both
|
|
279
|
-
the vault gate's actionable block text and its success-path observability ride on it.
|
|
301
|
+
the vault gate's actionable block text and its success-path observability ride on it. On a run
|
|
302
|
+
that printed a card under step 2, its `Details:` text is this passthrough, so
|
|
303
|
+
do not print the message a second time.
|
|
280
304
|
|
|
281
305
|
## Direct-query mode
|
|
282
306
|
|
|
@@ -105,6 +105,7 @@ if [ "$VAULT_REQUIRED" = "true" ] && [ "$VAULT_LOAD_OK" = "false" ]; then
|
|
|
105
105
|
# summary all hard-stop (D-VH-4). Print the failure verbatim, then the named
|
|
106
106
|
# halt token and a non-zero exit — the same two halves the extracted enforcer
|
|
107
107
|
# uses, so an agent stops and an unattended runner sees the exit code.
|
|
108
|
+
{ pp_run gate-card vault.fetch --state blocked --details 2>/dev/null || true; } >&2
|
|
108
109
|
echo "✗ vault could not be loaded and vault.required is true (STRICT-03)" >&2
|
|
109
110
|
if [ -n "$VAULT_FETCH_REASON" ]; then echo " fetch: $VAULT_FETCH_REASON" >&2; fi
|
|
110
111
|
if [ -n "$VAULT_SUMMARY_ERROR" ]; then echo " summary: $VAULT_SUMMARY_ERROR" >&2; fi
|
|
@@ -107,6 +107,8 @@ Invocation mode never changes any of the above. `--auto` / `--chain` selects how
|
|
|
107
107
|
surfaced, never whether the run proceeds. Mode-dependent gate behaviour was the precise shape of the
|
|
108
108
|
hole this phase closes, so it is stated here rather than left to be re-derived.
|
|
109
109
|
|
|
110
|
+
When the payload carries `audience` (business or engineer), ask the fallback question below in the form `${PP_TOOLS%/bin/pp-tools.cjs}/references/audience-moments.md` gives for that audience (§ Vault fallback question); the explicit typed `confirmed` acknowledgment stays exactly as each column requires.
|
|
111
|
+
|
|
110
112
|
---
|
|
111
113
|
|
|
112
114
|
## §8 Message table — plan:pre column (`VAULT_GATE_POINT` == `plan`)
|
|
@@ -91,7 +91,7 @@ Parse JSON for: `executor_model`, `verifier_model`, `commit_docs`, `parallelizat
|
|
|
91
91
|
|
|
92
92
|
**Model resolution:** If `executor_model` is `"inherit"`, omit the `model=` parameter from all `Agent()` calls — do NOT pass `model="inherit"` to Agent. Omitting the `model=` parameter causes Claude Code to inherit the current orchestrator model automatically. Only set `model=` when `executor_model` is an explicit model name (e.g., `"claude-sonnet-4-6"`, `"claude-opus-4-7"`).
|
|
93
93
|
|
|
94
|
-
**
|
|
94
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
95
95
|
|
|
96
96
|
Read runtime/worktree config and fail closed before any executor dispatch:
|
|
97
97
|
|
|
@@ -48,6 +48,8 @@ INIT=$(pp_run query init.execute-phase "${PHASE}")
|
|
|
48
48
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
52
|
+
|
|
51
53
|
Extract from init JSON: `executor_model`, `commit_docs`, `sub_repos`, `phase_dir`, `phase_number`, `plans`, `summaries`, `incomplete_plans`, `state_path`, `config_path`.
|
|
52
54
|
|
|
53
55
|
If `.planning/` missing: error.
|
|
@@ -21,6 +21,8 @@ INIT=$(pp_run query init.phase-op "${PHASE_ARG}")
|
|
|
21
21
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
25
|
+
|
|
24
26
|
Parse from init JSON: `phase_found`, `phase_dir`, `phase_number`, `phase_name`, `padded_phase`.
|
|
25
27
|
|
|
26
28
|
If phase not found, exit with error: "Phase {PHASE_ARG} not found."
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
<purpose>
|
|
2
|
+
Help page for a business user, shown for `/pp:help` and `/pp:help --brief`. Output ONLY the `<reference>` content below, after the audience header line help.md prints. No other additions.
|
|
3
|
+
</purpose>
|
|
4
|
+
|
|
5
|
+
<reference>
|
|
6
|
+
# pp-core — your project, step by step
|
|
7
|
+
|
|
8
|
+
Start with the Discovery Sprint. When its Project Charter is signed, the build begins, and you test the result yourself.
|
|
9
|
+
|
|
10
|
+
## 1. The Discovery Sprint
|
|
11
|
+
|
|
12
|
+
| Command | What it does |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `/pp:discovery` | See where the sprint stands and which session comes next |
|
|
15
|
+
| `/pp:discovery <n>` | Hold session `<n>` (1 to 13), or carry on with it |
|
|
16
|
+
| `/pp:discovery prototype` | Build the clickable prototype from sessions 1 to 4 |
|
|
17
|
+
| `/pp:discovery charter` | Record the signatures on the Project Charter, or redraft it |
|
|
18
|
+
| `/pp:discovery-to-build` | Once the Project Charter is signed, start the build from what the sprint agreed |
|
|
19
|
+
|
|
20
|
+
## 2. Where things stand
|
|
21
|
+
|
|
22
|
+
| Command | What it does |
|
|
23
|
+
|---|---|
|
|
24
|
+
| `/pp:progress` | Where the project stands and what comes next |
|
|
25
|
+
| `/pp:resume-work` | Pick up where you left off |
|
|
26
|
+
|
|
27
|
+
## 3. Your acceptance test
|
|
28
|
+
|
|
29
|
+
| Command | What it does |
|
|
30
|
+
|---|---|
|
|
31
|
+
| `/pp:verify-work <N>` | Try out a finished stage yourself and say whether it does what was agreed |
|
|
32
|
+
|
|
33
|
+
## Other commands
|
|
34
|
+
|
|
35
|
+
The build team uses these. You can use them too.
|
|
36
|
+
|
|
37
|
+
| Command | What it does |
|
|
38
|
+
|---|---|
|
|
39
|
+
| `/pp:init` | Set up a new project: repository, remote and the link to your organisation's standards |
|
|
40
|
+
| `/pp:new-project` | Start a project from scratch: questions, research, requirements and a plan of stages |
|
|
41
|
+
| `/pp:map-codebase` | Read an existing codebase so the work fits it |
|
|
42
|
+
| `/pp:discuss-phase <N>` | Talk through what stage `<N>` should do before it is planned |
|
|
43
|
+
| `/pp:plan-phase <N>` | Write the detailed plan for stage `<N>` |
|
|
44
|
+
| `/pp:execute-phase <N>` | Build stage `<N>` |
|
|
45
|
+
| `/pp:quick` | A small one-off task, tracked and saved |
|
|
46
|
+
| `/pp:fast "<task>"` | A tiny change, done straight away |
|
|
47
|
+
| `/pp:debug "<symptom>"` | Track down a problem step by step; it picks up again after a break |
|
|
48
|
+
| `/pp:capture` | Save an idea, a to-do or a note |
|
|
49
|
+
| `/pp:ship <N>` | Open a review request for a finished stage |
|
|
50
|
+
| `/pp:help --full` | Every command and every option |
|
|
51
|
+
| `/pp:help <topic>` | One section only |
|
|
52
|
+
| `/pp:help --brief <topic>` | A short summary of one topic |
|
|
53
|
+
| `npx @pareto4/pp-core@latest` | Update pp-core |
|
|
54
|
+
|
|
55
|
+
Topics: `workflow` · `planning` · `execute` · `quick` · `debug` · `capture` · `ship` · `config` · `milestones` · `spike` · `sketch` · `review` · `audit` · `progress`
|
|
56
|
+
</reference>
|
|
@@ -1,7 +1,17 @@
|
|
|
1
1
|
<purpose>
|
|
2
|
-
Display pp-core command help at the tier the user asked for. Output ONLY the reference content of the chosen mode. Do NOT add project-specific analysis, git status, next-step suggestions, or any commentary beyond the reference.
|
|
2
|
+
Display pp-core command help at the tier the user asked for. Output ONLY the reference content of the chosen mode, preceded by the one audience header line from `<audience>` when that section calls for it. Do NOT add project-specific analysis, git status, next-step suggestions, or any commentary beyond the reference.
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
|
+
<audience>
|
|
6
|
+
```bash
|
|
7
|
+
_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
|
|
8
|
+
pp_run query audience fields 2>/dev/null
|
|
9
|
+
```
|
|
10
|
+
Run the block above once, before routing. It prints one JSON object for a business user or a business engineer and nothing for a developer. If it printed nothing, or failed in any way, say nothing about it and route exactly as below. If it printed JSON, output the line for its `"audience"` value first, then a blank line:
|
|
11
|
+
- `"business"`: You're using pp-core as a business user. To change this, run `/pp:settings`.
|
|
12
|
+
- `"engineer"`: You're using pp-core as a business engineer. To change this, run `/pp:settings`.
|
|
13
|
+
For `"business"` only, the empty / unset row and the `--brief` alone row read `workflows/help/modes/business.md` instead of the file the table names. Every other row, every row for `"engineer"`, and any other value read the file the table names, unchanged.
|
|
14
|
+
</audience>
|
|
5
15
|
<progressive_disclosure>
|
|
6
16
|
**Mode files are lazy-loaded.** Read only the one mode file that matches `$ARGUMENTS`, then output its `<reference>` body verbatim.
|
|
7
17
|
|
|
@@ -20,5 +30,5 @@ Argument parsing rules:
|
|
|
20
30
|
- Multiple flags: `--brief` and `--full` are mutually exclusive — if both appear *without* a topic, prefer `--full`.
|
|
21
31
|
- `--brief` combined with a topic invokes `topic.md` in compact scope; `--full` combined with a topic invokes `topic.md` in full scope (the default topic behavior). When passing arguments through to `topic.md`, retain the `--brief` flag so the mode can pick the right scope.
|
|
22
32
|
|
|
23
|
-
After loading the chosen mode, emit its `<reference>` block content directly. No additions, no project context, no suggestions.
|
|
33
|
+
After loading the chosen mode, emit its `<reference>` block content directly, after the audience header line if `<audience>` printed one. No other additions, no project context, no suggestions.
|
|
24
34
|
</progressive_disclosure>
|
|
@@ -8,6 +8,13 @@ Future: `--prd` mode (PRD extraction into PROJECT.md + REQUIREMENTS.md + ROADMAP
|
|
|
8
8
|
|
|
9
9
|
---
|
|
10
10
|
|
|
11
|
+
```bash
|
|
12
|
+
_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
|
|
13
|
+
pp_run query audience fields
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Audience, before any question:** run the block above. If it prints `pp-tools.cjs not found`, show that error and stop. If it exits non-zero for any other reason, tell the person the audience setting could not be read (show the error) and continue; if it prints JSON, apply the **Audience** line below to it now.
|
|
17
|
+
|
|
11
18
|
<step name="banner">
|
|
12
19
|
|
|
13
20
|
Display the stage banner:
|
|
@@ -177,12 +184,14 @@ Apply pp-core naming convention for the output filename:
|
|
|
177
184
|
Determine the target directory by querying `init.phase-op` for the phase number extracted in `plan_read_input`. This ensures the `project_code` prefix from `.planning/config.json` is applied:
|
|
178
185
|
|
|
179
186
|
```bash
|
|
180
|
-
|
|
187
|
+
command -v pp_run >/dev/null 2>&1 || { echo "ERROR: pp_run is not on PATH; prepend the resolver line from the top block to this block and run it again" >&2; exit 1; }
|
|
181
188
|
INIT=$(pp_run query init.phase-op "{NN}")
|
|
182
189
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
183
190
|
expected_phase_dir=$(echo "$INIT" | node -e "process.stdout.write(JSON.parse(require('fs').readFileSync('/dev/stdin','utf8')).expected_phase_dir)")
|
|
184
191
|
```
|
|
185
192
|
|
|
193
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
194
|
+
|
|
186
195
|
If the directory does not exist, create it:
|
|
187
196
|
```bash
|
|
188
197
|
mkdir -p "${expected_phase_dir}"
|
|
@@ -58,6 +58,8 @@ INIT=$(pp_run init ingest-docs)
|
|
|
58
58
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
62
|
+
|
|
61
63
|
Parse `project_exists`, `planning_exists`, `has_git`, `git_worktree_root`, `in_nested_subdir`, `project_path` from INIT.
|
|
62
64
|
|
|
63
65
|
**Auto-detect MODE** if not set:
|
|
@@ -31,6 +31,13 @@ Read all files referenced by the invoking prompt's execution_context before star
|
|
|
31
31
|
|
|
32
32
|
<process>
|
|
33
33
|
|
|
34
|
+
```bash
|
|
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
|
+
pp_run query audience fields
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Audience, before any question:** run the block above. If it prints `pp-tools.cjs not found`, show that error and stop. If it exits non-zero for any other reason, tell the person the audience setting could not be read (show the error) and continue; if it prints JSON, apply the **Audience** line below to it now.
|
|
40
|
+
|
|
34
41
|
## Text mode (resolve before any prompt — WR-02)
|
|
35
42
|
|
|
36
43
|
Resolve `TEXT_MODE` here, **before Step 0**, because the Step 0 drift prompt is the first
|
|
@@ -53,7 +60,7 @@ the app is on the **latest** platform before any building starts — bumping aft
|
|
|
53
60
|
milestone is built is far more expensive.
|
|
54
61
|
|
|
55
62
|
```bash
|
|
56
|
-
|
|
63
|
+
command -v pp_run >/dev/null 2>&1 || { echo "ERROR: pp_run is not on PATH; prepend the resolver line from the top block to this block and run it again" >&2; exit 1; }
|
|
57
64
|
# Gate on presence via reader — absent file → {present:false} exit 0 (inert, step skipped, no jq)
|
|
58
65
|
if [ "$(pp_run query platform-bindings --pick present 2>/dev/null)" = "true" ]; then
|
|
59
66
|
PINNED=$(pp_run query platform-bindings --pick platform.tag)
|
|
@@ -82,6 +89,12 @@ step is skipped entirely.
|
|
|
82
89
|
|
|
83
90
|
---
|
|
84
91
|
|
|
92
|
+
## 0.5. Who you are (first run only — D-06)
|
|
93
|
+
|
|
94
|
+
Run `pp_run query audience status --raw`. If `needs_choice` is `true`, show its `prompt` exactly as printed and wait for the reply. Then run `pp_run query audience answer '<reply>'` (the reply in single quotes, with any single quote in it removed) and show its output. If that fails, show the prompt once more, then continue either way. Never write `~/.gsd/person.json` yourself. With nobody to answer (a headless run), skip this step and save nothing.
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
85
98
|
## 1. Worktree-aware git init
|
|
86
99
|
|
|
87
100
|
Parse the init signals by running the query below. `init.ingest-docs` takes no argument
|
|
@@ -90,10 +103,13 @@ and emits the git-state signals this step needs (`has_git`, `in_nested_subdir`,
|
|
|
90
103
|
`init.execute-phase ""`: it refuses an empty phase, and the `{}` fallback would disable the guard.
|
|
91
104
|
|
|
92
105
|
```bash
|
|
106
|
+
command -v pp_run >/dev/null 2>&1 || { echo "ERROR: pp_run is not on PATH; prepend the resolver line from the top block to this block and run it again" >&2; exit 1; }
|
|
93
107
|
INIT=$(pp_run query init.ingest-docs 2>/dev/null || echo '{}')
|
|
94
108
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
95
109
|
```
|
|
96
110
|
|
|
111
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
112
|
+
|
|
97
113
|
Extract from the JSON: `has_git`, `in_nested_subdir`, `git_worktree_root`.
|
|
98
114
|
|
|
99
115
|
Apply the `#3491` guard (never nest `.git` inside an existing worktree):
|
|
@@ -39,6 +39,8 @@ INIT=$(pp_run query init.phase-op "${after_phase}")
|
|
|
39
39
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
43
|
+
|
|
42
44
|
Check `roadmap_exists` from init JSON. If false:
|
|
43
45
|
```
|
|
44
46
|
ERROR: No roadmap found (.planning/ROADMAP.md)
|
|
@@ -16,6 +16,8 @@ INIT=$(pp_run query init.list-workspaces)
|
|
|
16
16
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
20
|
+
|
|
19
21
|
Parse JSON for: `workspace_base`, `workspaces`, `workspace_count`.
|
|
20
22
|
|
|
21
23
|
## 2. Display
|
|
@@ -24,6 +24,8 @@ INIT=$(pp_run query init.manager)
|
|
|
24
24
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
28
|
+
|
|
27
29
|
Parse JSON for: `milestone_version`, `milestone_name`, `phase_count`, `completed_count`, `in_progress_count`, `phases`, `recommended_actions`, `all_complete`, `waiting_signal`, `manager_flags`, and the optional trio `queued_milestone_version`, `queued_milestone_name`, `queued_phases` (added in SDK fix `2495-2496-2497` — may be absent on older SDK versions, treat missing as empty).
|
|
28
30
|
|
|
29
31
|
`manager_flags` contains per-step passthrough flags from config:
|
|
@@ -75,6 +75,8 @@ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
|
75
75
|
AGENT_SKILLS_MAPPER=$(pp_run query agent-skills pp-codebase-mapper)
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
79
|
+
|
|
78
80
|
Extract from init JSON: `mapper_model`, `commit_docs`, `codebase_dir`, `existing_maps`, `has_maps`, `codebase_dir_exists`, `subagent_timeout`, `date`.
|
|
79
81
|
</step>
|
|
80
82
|
|
|
@@ -57,6 +57,8 @@ _PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_
|
|
|
57
57
|
pp_run query init.progress
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
61
|
+
|
|
60
62
|
This returns phase metadata. For each phase in the milestone scope:
|
|
61
63
|
|
|
62
64
|
- Read `{phase_dir}/{padded}-SUMMARY.md` if it exists — extract `one_liner`, `accomplishments`, `decisions`
|
|
@@ -23,6 +23,13 @@ Valid pp-core subagent types (use exact names — do not fall back to 'general-p
|
|
|
23
23
|
|
|
24
24
|
<process>
|
|
25
25
|
|
|
26
|
+
```bash
|
|
27
|
+
_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
|
|
28
|
+
pp_run query audience fields
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Audience, before any question:** run the block above. If it prints `pp-tools.cjs not found`, show that error and stop. If it exits non-zero for any other reason, tell the person the audience setting could not be read (show the error) and continue; if it prints JSON, apply the **Audience** line below to it now.
|
|
32
|
+
|
|
26
33
|
## 1. Load Context
|
|
27
34
|
|
|
28
35
|
Parse `$ARGUMENTS` before doing anything else:
|
|
@@ -186,7 +193,6 @@ blockers, todos) is preserved across the switch — symmetric with
|
|
|
186
193
|
`milestone.complete`.
|
|
187
194
|
|
|
188
195
|
```bash
|
|
189
|
-
_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
|
|
190
196
|
pp_run query state.milestone-switch --milestone "v[X.Y]" --name "[Name]"
|
|
191
197
|
```
|
|
192
198
|
|
|
@@ -224,6 +230,7 @@ pp_run query commit "docs(planning): start milestone v[X.Y] [Name]" --files .pla
|
|
|
224
230
|
## 7. Load Context and Resolve Models
|
|
225
231
|
|
|
226
232
|
```bash
|
|
233
|
+
command -v pp_run >/dev/null 2>&1 || { echo "ERROR: pp_run is not on PATH; prepend the resolver line from the top block to this block and run it again" >&2; exit 1; }
|
|
227
234
|
INIT=$(pp_run query init.new-milestone)
|
|
228
235
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
229
236
|
AGENT_SKILLS_RESEARCHER=$(pp_run query agent-skills pp-project-researcher)
|
|
@@ -231,6 +238,8 @@ AGENT_SKILLS_SYNTHESIZER=$(pp_run query agent-skills pp-research-synthesizer)
|
|
|
231
238
|
AGENT_SKILLS_ROADMAPPER=$(pp_run query agent-skills pp-roadmapper)
|
|
232
239
|
```
|
|
233
240
|
|
|
241
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
242
|
+
|
|
234
243
|
Extract from init JSON: `researcher_model`, `synthesizer_model`, `roadmapper_model`, `commit_docs`, `research_enabled`, `current_milestone`, `project_exists`, `roadmap_exists`, `latest_completed_milestone`, `phase_dir_count`, `phase_archive_path`, `agents_installed`, `missing_agents`.
|
|
235
244
|
|
|
236
245
|
**If `agents_installed` is false:** Display a warning before proceeding:
|
|
@@ -52,6 +52,13 @@ The document should describe what you want to build.
|
|
|
52
52
|
|
|
53
53
|
<process>
|
|
54
54
|
|
|
55
|
+
```bash
|
|
56
|
+
_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
|
|
57
|
+
pp_run query audience fields
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Audience, before any question:** run the block above. If it prints `pp-tools.cjs not found`, show that error and stop. If it exits non-zero for any other reason, tell the person the audience setting could not be read (show the error) and continue; if it prints JSON, apply the **Audience** line below to it now.
|
|
61
|
+
|
|
55
62
|
## 0. Platform-version preflight (Pareto satellite repos)
|
|
56
63
|
|
|
57
64
|
**Runs before Setup. Inert for non-Pareto projects** — gated entirely on
|
|
@@ -64,8 +71,8 @@ moment to confirm the app is on the **latest** platform before any building
|
|
|
64
71
|
starts — bumping after a milestone is built is far more expensive.
|
|
65
72
|
|
|
66
73
|
```bash
|
|
67
|
-
|
|
68
|
-
|
|
74
|
+
# pp_run comes from PATH (the audience block above exports it through CLAUDE_ENV_FILE) — reader required for platform-bindings preflight (BIND-04)
|
|
75
|
+
command -v pp_run >/dev/null 2>&1 || { echo "ERROR: pp_run is not on PATH; prepend the resolver line from the top block to this block and run it again" >&2; exit 1; }
|
|
69
76
|
|
|
70
77
|
# Gate on presence via reader — absent file → {present:false} exit 0 (inert, step skipped, no jq)
|
|
71
78
|
if [ "$(pp_run query platform-bindings --pick present 2>/dev/null)" = "true" ]; then
|
|
@@ -99,6 +106,7 @@ a no-op and this step is skipped entirely.
|
|
|
99
106
|
**MANDATORY FIRST STEP — Execute these checks before ANY user interaction:**
|
|
100
107
|
|
|
101
108
|
```bash
|
|
109
|
+
command -v pp_run >/dev/null 2>&1 || { echo "ERROR: pp_run is not on PATH; prepend the resolver line from the top block to this block and run it again" >&2; exit 1; }
|
|
102
110
|
INIT=$(pp_run query init.new-project)
|
|
103
111
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
104
112
|
AGENT_SKILLS_RESEARCHER=$(pp_run query agent-skills pp-project-researcher)
|
|
@@ -106,6 +114,8 @@ AGENT_SKILLS_SYNTHESIZER=$(pp_run query agent-skills pp-research-synthesizer)
|
|
|
106
114
|
AGENT_SKILLS_ROADMAPPER=$(pp_run query agent-skills pp-roadmapper)
|
|
107
115
|
```
|
|
108
116
|
|
|
117
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
118
|
+
|
|
109
119
|
Parse JSON for: `researcher_model`, `synthesizer_model`, `roadmapper_model`, `commit_docs`, `project_exists`, `has_codebase_map`, `planning_exists`, `has_existing_code`, `has_package_file`, `is_brownfield`, `needs_codebase_map`, `has_git`, `git_worktree_root`, `in_nested_subdir`, `project_path`, `agents_installed`, `missing_agents`, `agent_runtime`, `agents_dir`, `required_agents`, `required_agents_installed`, `missing_required_agents`, `agent_skill_payloads_available`, `agent_skill_payload_agents`.
|
|
110
120
|
|
|
111
121
|
**If `agents_installed` is false:** Display a warning before proceeding:
|
|
@@ -18,6 +18,8 @@ INIT=$(pp_run query init.new-workspace)
|
|
|
18
18
|
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
**Audience:** if `audience` is set, Read and follow `{audience_ref}`. Reply in any `response_language` and pass it to subagents; code and paths stay as is.
|
|
22
|
+
|
|
21
23
|
Parse JSON for: `default_workspace_base`, `child_repos`, `child_repo_count`, `worktree_available`, `is_git_repo`, `cwd_repo_name`, `project_root`.
|
|
22
24
|
|
|
23
25
|
## 2. Parse Arguments
|
|
@@ -18,6 +18,14 @@ _PP_SHIM_NAME="pp-tools.cjs"; _pp_root() { ( for _v in $(env | sed -n 's/^\(GIT_
|
|
|
18
18
|
pp_run query state.json 2>/dev/null || echo "{}"
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
+
**Discovery Sprint only:** before reading anything else, run:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
pp_run query discovery.status --raw
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
If it prints JSON with `"discovery_only": true`, run `pp_run query discovery.status`, show its output exactly as printed, and stop. Do not start a session: a Discovery Sprint session is a live workshop with the client, so the person starts it with the command the view names. Skip the safety gates and the routing below and re-invoke nothing; this holds for `--auto` and `--force` too. If it prints `"discovery_only": false`, or the command fails, continue below exactly as before.
|
|
28
|
+
|
|
21
29
|
Also read:
|
|
22
30
|
- `.planning/STATE.md` — current phase, progress, plan counts
|
|
23
31
|
- `.planning/ROADMAP.md` — milestone structure and phase list
|