devrites 5.7.2 → 5.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/docs/command-map.md +1 -1
- package/docs/engine/commands.md +1 -0
- package/docs/orchestration.md +2 -2
- package/engine/internal/parallel/cli.go +69 -0
- package/engine/internal/parallel/select.go +76 -0
- package/engine/internal/parallel/select_test.go +95 -0
- package/pack/.claude/settings.json +1 -0
- package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +2 -1
- package/pack/.claude/skills/rite-autocomplete/SKILL.md +4 -3
- package/pack/.claude/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/.claude/skills/rite-build/SKILL.md +2 -1
- package/pack/.claude/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +1 -1
- package/pack/.claude/skills/rite-build/reference/parallel-batch.md +17 -13
- package/pack/generated/claude/settings.json +1 -0
- package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +2 -1
- package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +4 -3
- package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/claude/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +1 -1
- package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +17 -13
- package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +2 -1
- package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +4 -3
- package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/codex/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +1 -1
- package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +17 -13
- package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +2 -1
- package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +4 -3
- package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/omp/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/generated/omp/skills/rite-build/reference/one-slice-cycle.md +1 -1
- package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +17 -13
- package/pack/generated/pi/agents/devrites-code-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-devex-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-doubt-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-evidence-scout.md +1 -1
- package/pack/generated/pi/agents/devrites-frontend-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-performance-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-plan-drafter.md +1 -1
- package/pack/generated/pi/agents/devrites-plan-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-proof-runner.md +1 -1
- package/pack/generated/pi/agents/devrites-retrospector.md +1 -1
- package/pack/generated/pi/agents/devrites-security-auditor.md +1 -1
- package/pack/generated/pi/agents/devrites-simplifier-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-slice-wright.md +1 -1
- package/pack/generated/pi/agents/devrites-spec-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-strategy-reviewer.md +1 -1
- package/pack/generated/pi/agents/devrites-test-analyst.md +1 -1
- package/pack/generated/pi/agents/devrites-upgrade-planner.md +1 -1
- package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +2 -1
- package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +4 -3
- package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +1 -1
- package/pack/generated/pi/skills/rite-build/SKILL.md +2 -1
- package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +3 -1
- package/pack/generated/pi/skills/rite-build/reference/one-slice-cycle.md +1 -1
- package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +17 -13
- package/package.json +1 -1
- package/scripts/pi-generate.sh +52 -1
|
@@ -65,7 +65,7 @@ Workspace files carry state; chat does not. Read and execute each phase skill:
|
|
|
65
65
|
| 3 | `$rite-temper` | harden or reduce; expansion and irreversible risk pause |
|
|
66
66
|
| 4 | `$rite-define` | approved plan/tasks/traceability |
|
|
67
67
|
| 5 | `$rite-vet` | every plan; derive mutable budget after READY |
|
|
68
|
-
| 6 | `$rite-build` batch loop | largest eligible path-disjoint set (cap 10;
|
|
68
|
+
| 6 | `$rite-build` batch loop | largest eligible path-disjoint set (cap 10; one-slice round when <2 eligible); recompute after each round; charge once per green built slice |
|
|
69
69
|
| 7 | `$rite-prove` | all slices built; approved proof; recovery on red |
|
|
70
70
|
| 8 | `$rite-polish` | re-prove after code edits |
|
|
71
71
|
| 9 | `$rite-review` | in-scope correction then fresh proof |
|
|
@@ -60,7 +60,8 @@ Wright applies anti-slop; root verifies returns and never patches source.
|
|
|
60
60
|
|
|
61
61
|
Omitted/`1` ≡ serial; `2`–`10` is a **cap** — the root runs the largest eligible
|
|
62
62
|
path-disjoint set it can start now (`N_eff`), takes fewer when the cap cannot be
|
|
63
|
-
filled, and recomputes after every
|
|
63
|
+
filled, and recomputes after every completed round (serial slice or parallel
|
|
64
|
+
integrate) until no pending slice remains
|
|
64
65
|
([`parallel-batch.md` § Dynamic selection](reference/parallel-batch.md#dynamic-selection-and-re-batching)).
|
|
65
66
|
Unattended runs (`$rite-autocomplete`, `.devrites/AFK` `max_parallel`) repeat batches
|
|
66
67
|
inside the same run; HITL stops after each batch. Non-integer/`N≤0`/`N>10` hard refuse.
|
|
@@ -16,7 +16,9 @@ control; irreversible work (destructive/auth/public API) always pauses.
|
|
|
16
16
|
The controlling root owns the cap:
|
|
17
17
|
|
|
18
18
|
1. **Before every dispatch**, re-read `.devrites/AFK`, `state.md`, and the
|
|
19
|
-
selected slice.
|
|
19
|
+
selected slice. When `--parallel N` or sentinel `max_parallel` is greater than
|
|
20
|
+
1, recompute `N_eff` via `parallel select` before the next dispatch — a prior
|
|
21
|
+
one-slice round does not keep the run serial. A configured `max_slices` and any existing
|
|
20
22
|
`afk_slices_remaining` value, including its released bullet form, must each
|
|
21
23
|
be a decimal nonnegative integer. A missing
|
|
22
24
|
`state.md` or malformed configured value fails closed; an omitted cap is the
|
|
@@ -26,7 +26,7 @@ RECORD → orchestrator: after green verification, update state.md/evidence.m
|
|
|
26
26
|
upsert the authoritative candidate manifest from the actual scoped diff
|
|
27
27
|
(CHECKPOINT) → orchestrator: commit the proven slice local-only as WIP(<slug>)
|
|
28
28
|
with a [devrites-context] body → clean tree, survives a crash (checkpoint.md)
|
|
29
|
-
NEXT → HITL root reports and stops
|
|
29
|
+
NEXT → HITL root reports and stops. AFK with parallel cap>1: return to parallel-batch selection and run the new N_eff; otherwise repeat under afk-discipline.md
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## Why the boundary matters
|
|
@@ -28,18 +28,20 @@ N_eff = min(
|
|
|
28
28
|
)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Select **greedily in plan order**:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
nothing pending → Prove. A cap that cannot be filled
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
Select **greedily in plan order**: pass every currently dependency-ready pending slice
|
|
32
|
+
(plan order, `Files likely touched`) to
|
|
33
|
+
`devrites-engine parallel select --cap N [--root <dir>]`. `N_eff ≥ 2` → parallel batch;
|
|
34
|
+
`N_eff = 1` → one serial round; nothing pending → Prove. A cap that cannot be filled
|
|
35
|
+
is normal: take fewer. Serial is this round's size, not the rest of the run.
|
|
36
|
+
|
|
37
|
+
**Re-batch automatically after every completed round** (parallel integrate+cleanup or
|
|
38
|
+
a serial slice). Re-read `state.md`, pending slices, and the tree, then run
|
|
39
|
+
`parallel select` again: finished work leaves the pending set, and satisfied
|
|
40
|
+
dependencies unlock new slices. Under `.devrites/AFK` and `$rite-autocomplete` the
|
|
41
|
+
repeat is the same run — HITL stops after each batch. `--parallel 5` with one eligible
|
|
42
|
+
slice runs that one; when two to five then become eligible, the next round takes that
|
|
43
|
+
many. **Failing case:** the run stays one-by-one after a serial round even though more
|
|
44
|
+
slices are now eligible under the same cap.
|
|
43
45
|
|
|
44
46
|
## Path-disjoint
|
|
45
47
|
|
|
@@ -71,7 +73,8 @@ Lease: `batch_id`, `created_at`, `base_sha`, `n`,
|
|
|
71
73
|
1. Orient/gate; parse the cap; compute `N_eff` and select the eligible set
|
|
72
74
|
([Dynamic selection and re-batching](#dynamic-selection-and-re-batching)) —
|
|
73
75
|
candidates from `orient` `task_graph.slices` + built list, each candidate's
|
|
74
|
-
`Files likely touched` via `observe slice`,
|
|
76
|
+
`Files likely touched` via `observe slice`, then
|
|
77
|
+
`parallel select --cap N` (pairwise disjointness is inside that verb).
|
|
75
78
|
2. Write lease; freeze `B=HEAD`; `parallel create` worktrees.
|
|
76
79
|
3. Dispatch ≤10 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
|
|
77
80
|
4. Inspect each returned path list, cumulative diff from `B`, transfer identity,
|
|
@@ -163,6 +166,7 @@ Repair rejected work in place; never discard/rebuild while budget remains.
|
|
|
163
166
|
## Engine verbs
|
|
164
167
|
|
|
165
168
|
```text
|
|
169
|
+
devrites-engine parallel select --cap <1-10> [--root <dir>] [<json-file>|-]
|
|
166
170
|
devrites-engine parallel create --root <repo> --slug <slug> --batch <id> --base <B> --json <file>|-
|
|
167
171
|
devrites-engine parallel record-green --root <repo> --slug <slug> --slice <id> --commit <sha>
|
|
168
172
|
devrites-engine parallel integrate --root <repo> --slug <slug> --apply-to-control
|
|
@@ -120,7 +120,8 @@ candidate manifest to cover the whole recorded chain — run
|
|
|
120
120
|
run exactly as without this field.
|
|
121
121
|
|
|
122
122
|
`max_parallel` caps a Build batch for unattended runs; `1` forces the serial cycle.
|
|
123
|
-
Unattended runs take the largest eligible set ≤ cap and recompute after every
|
|
123
|
+
Unattended runs take the largest eligible set ≤ cap and recompute after every completed
|
|
124
|
+
round (serial slice or parallel integrate)
|
|
124
125
|
([parallel-batch.md § Dynamic selection and re-batching](../../../rite-build/reference/parallel-batch.md#dynamic-selection-and-re-batching));
|
|
125
126
|
an explicit `/rite-build --parallel N` cap wins for that invocation.
|
|
126
127
|
|
|
@@ -94,9 +94,10 @@ executable controller/harness/bundle bytes or a missing writer, read
|
|
|
94
94
|
`/rite-review` → `/rite-seal`. Read and execute each skill; durable files, not
|
|
95
95
|
chat, carry state. Apply the mutable post-vet budget before first Build.
|
|
96
96
|
Build runs the largest eligible path-disjoint batch (cap: `--parallel N`, else
|
|
97
|
-
sentinel `max_parallel`, else 10) and recomputes after every
|
|
98
|
-
pending slice remains;
|
|
99
|
-
host
|
|
97
|
+
sentinel `max_parallel`, else 10) and recomputes after every completed round until no
|
|
98
|
+
pending slice remains; a one-slice round is serial for that round only, then
|
|
99
|
+
selection runs again (host isolation still forces serial when concurrent writers
|
|
100
|
+
cannot be separated).
|
|
100
101
|
**Completion:** loop reaches Seal GO or persists a valid stop before any later phase.
|
|
101
102
|
5. **Apply stops.** At every gate use
|
|
102
103
|
[stop-conditions.md](reference/stop-conditions.md). A `blocked` label alone is not a stop condition:
|
|
@@ -65,7 +65,7 @@ Workspace files carry state; chat does not. Read and execute each phase skill:
|
|
|
65
65
|
| 3 | `/rite-temper` | harden or reduce; expansion and irreversible risk pause |
|
|
66
66
|
| 4 | `/rite-define` | approved plan/tasks/traceability |
|
|
67
67
|
| 5 | `/rite-vet` | every plan; derive mutable budget after READY |
|
|
68
|
-
| 6 | `/rite-build` batch loop | largest eligible path-disjoint set (cap 10;
|
|
68
|
+
| 6 | `/rite-build` batch loop | largest eligible path-disjoint set (cap 10; one-slice round when <2 eligible); recompute after each round; charge once per green built slice |
|
|
69
69
|
| 7 | `/rite-prove` | all slices built; approved proof; recovery on red |
|
|
70
70
|
| 8 | `/rite-polish` | re-prove after code edits |
|
|
71
71
|
| 9 | `/rite-review` | in-scope correction then fresh proof |
|
|
@@ -60,7 +60,8 @@ Wright applies anti-slop; root verifies returns and never patches source.
|
|
|
60
60
|
|
|
61
61
|
Omitted/`1` ≡ serial; `2`–`10` is a **cap** — the root runs the largest eligible
|
|
62
62
|
path-disjoint set it can start now (`N_eff`), takes fewer when the cap cannot be
|
|
63
|
-
filled, and recomputes after every
|
|
63
|
+
filled, and recomputes after every completed round (serial slice or parallel
|
|
64
|
+
integrate) until no pending slice remains
|
|
64
65
|
([`parallel-batch.md` § Dynamic selection](reference/parallel-batch.md#dynamic-selection-and-re-batching)).
|
|
65
66
|
Unattended runs (`/rite-autocomplete`, `.devrites/AFK` `max_parallel`) repeat batches
|
|
66
67
|
inside the same run; HITL stops after each batch. Non-integer/`N≤0`/`N>10` hard refuse.
|
|
@@ -16,7 +16,9 @@ control; irreversible work (destructive/auth/public API) always pauses.
|
|
|
16
16
|
The controlling root owns the cap:
|
|
17
17
|
|
|
18
18
|
1. **Before every dispatch**, re-read `.devrites/AFK`, `state.md`, and the
|
|
19
|
-
selected slice.
|
|
19
|
+
selected slice. When `--parallel N` or sentinel `max_parallel` is greater than
|
|
20
|
+
1, recompute `N_eff` via `parallel select` before the next dispatch — a prior
|
|
21
|
+
one-slice round does not keep the run serial. A configured `max_slices` and any existing
|
|
20
22
|
`afk_slices_remaining` value, including its released bullet form, must each
|
|
21
23
|
be a decimal nonnegative integer. A missing
|
|
22
24
|
`state.md` or malformed configured value fails closed; an omitted cap is the
|
|
@@ -26,7 +26,7 @@ RECORD → orchestrator: after green verification, update state.md/evidence.m
|
|
|
26
26
|
upsert the authoritative candidate manifest from the actual scoped diff
|
|
27
27
|
(CHECKPOINT) → orchestrator: commit the proven slice local-only as WIP(<slug>)
|
|
28
28
|
with a [devrites-context] body → clean tree, survives a crash (checkpoint.md)
|
|
29
|
-
NEXT → HITL root reports and stops
|
|
29
|
+
NEXT → HITL root reports and stops. AFK with parallel cap>1: return to parallel-batch selection and run the new N_eff; otherwise repeat under afk-discipline.md
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## Why the boundary matters
|
|
@@ -28,18 +28,20 @@ N_eff = min(
|
|
|
28
28
|
)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Select **greedily in plan order**:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
nothing pending → Prove. A cap that cannot be filled
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
Select **greedily in plan order**: pass every currently dependency-ready pending slice
|
|
32
|
+
(plan order, `Files likely touched`) to
|
|
33
|
+
`devrites-engine parallel select --cap N [--root <dir>]`. `N_eff ≥ 2` → parallel batch;
|
|
34
|
+
`N_eff = 1` → one serial round; nothing pending → Prove. A cap that cannot be filled
|
|
35
|
+
is normal: take fewer. Serial is this round's size, not the rest of the run.
|
|
36
|
+
|
|
37
|
+
**Re-batch automatically after every completed round** (parallel integrate+cleanup or
|
|
38
|
+
a serial slice). Re-read `state.md`, pending slices, and the tree, then run
|
|
39
|
+
`parallel select` again: finished work leaves the pending set, and satisfied
|
|
40
|
+
dependencies unlock new slices. Under `.devrites/AFK` and `/rite-autocomplete` the
|
|
41
|
+
repeat is the same run — HITL stops after each batch. `--parallel 5` with one eligible
|
|
42
|
+
slice runs that one; when two to five then become eligible, the next round takes that
|
|
43
|
+
many. **Failing case:** the run stays one-by-one after a serial round even though more
|
|
44
|
+
slices are now eligible under the same cap.
|
|
43
45
|
|
|
44
46
|
## Path-disjoint
|
|
45
47
|
|
|
@@ -71,7 +73,8 @@ Lease: `batch_id`, `created_at`, `base_sha`, `n`,
|
|
|
71
73
|
1. Orient/gate; parse the cap; compute `N_eff` and select the eligible set
|
|
72
74
|
([Dynamic selection and re-batching](#dynamic-selection-and-re-batching)) —
|
|
73
75
|
candidates from `orient` `task_graph.slices` + built list, each candidate's
|
|
74
|
-
`Files likely touched` via `observe slice`,
|
|
76
|
+
`Files likely touched` via `observe slice`, then
|
|
77
|
+
`parallel select --cap N` (pairwise disjointness is inside that verb).
|
|
75
78
|
2. Write lease; freeze `B=HEAD`; `parallel create` worktrees.
|
|
76
79
|
3. Dispatch ≤10 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
|
|
77
80
|
4. Inspect each returned path list, cumulative diff from `B`, transfer identity,
|
|
@@ -163,6 +166,7 @@ Repair rejected work in place; never discard/rebuild while budget remains.
|
|
|
163
166
|
## Engine verbs
|
|
164
167
|
|
|
165
168
|
```text
|
|
169
|
+
devrites-engine parallel select --cap <1-10> [--root <dir>] [<json-file>|-]
|
|
166
170
|
devrites-engine parallel create --root <repo> --slug <slug> --batch <id> --base <B> --json <file>|-
|
|
167
171
|
devrites-engine parallel record-green --root <repo> --slug <slug> --slice <id> --commit <sha>
|
|
168
172
|
devrites-engine parallel integrate --root <repo> --slug <slug> --apply-to-control
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-code-reviewer
|
|
3
3
|
description: "Reviews a full DevRites feature diff once for /rite-review and /rite-seal. Checks tests, correctness, readability, architecture, maintainability, and standards; returns every supported finding."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-devex-reviewer
|
|
3
3
|
description: "Reviews developer experience for one DevRites feature in fresh context. Predicts at /rite-vet and measures at /rite-seal for public APIs, CLIs, SDKs, libraries, webhooks, configuration, errors, and onboarding; reports where the next developer gets stuck."
|
|
4
|
-
tools: read, grep, find
|
|
4
|
+
tools: read, grep, find, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-doubt-reviewer
|
|
3
3
|
description: "Stress-tests one claim or decision for the devrites-doubt loop from a fresh context. Tries to break the claim rather than validate it."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-evidence-scout
|
|
3
3
|
description: "Answers one bounded evidence question for spec, clarify, converge, or external-fact work from a fresh, read-only context. Returns a cited dossier from live code, project records, installed source, or authoritative versioned documentation. Never asks the user, chooses scope, edits artifacts, or advances a phase."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-frontend-reviewer
|
|
3
3
|
description: "Reviews one DevRites UI feature for /rite-seal from a fresh context. Checks UX flow, accessibility, responsive behavior, design-system alignment, and AI slop independently and adversarially."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
skills: devrites-frontend-craft
|
|
7
7
|
---
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-performance-reviewer
|
|
3
3
|
description: "Reviews one DevRites feature's performance for /rite-seal in fresh context. Uses source mode for potential static findings or measured mode for Lighthouse, PSI, CrUX, and traces; reports source-labeled numbers without presenting lab data as field data."
|
|
4
|
-
tools: read, grep, find
|
|
4
|
+
tools: read, grep, find, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-plan-drafter
|
|
3
3
|
description: "Read-only planning drafter for /rite-define and /rite-plan repair. From a fresh context, produces one consistent candidate bundle covering architecture, plan, vertical slices, traceability, and proof mapping. Proposes the technical approach, flags user-owned choices, and never edits workspace artifacts or source."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-plan-reviewer
|
|
3
3
|
description: "Read-only /rite-vet reviewer for engineering plans before code. Checks plan.md and tasks.md against spec.md for architecture, quality, tests, performance, scope, reversibility, and failure modes; reports high-confidence, line-supported findings and gates on the weakest axis."
|
|
4
|
-
tools: read, grep, find
|
|
4
|
+
tools: read, grep, find, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-proof-runner
|
|
3
3
|
description: "Validates root-produced test, build, lint, typecheck, and browser evidence for /rite-prove and affected re-proof; maps it to acceptance and reports gaps. Never executes gates or edits code or evidence."
|
|
4
|
-
tools: read, grep, find
|
|
4
|
+
tools: read, grep, find, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-retrospector
|
|
3
3
|
description: "Read-only analyst of recurring cross-feature lessons in reviewed Markdown."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-security-auditor
|
|
3
3
|
description: "Audits one DevRites feature for /rite-seal from a fresh context. Checks the diff independently for OWASP Top 10 issues, trust-boundary violations, secrets, and dependency risk. For model calls, agents, RAG, or tool use, also checks the OWASP LLM Top 10. Assumes all input is hostile."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-simplifier-reviewer
|
|
3
3
|
description: "Read-only simplification reviewer for /rite-polish Phase 1. From a fresh context, finds measured, behavior-preserving ways to reduce complexity in one DevRites feature diff, using guard clauses, Extract Method, simpler conditionals, and Chesterton's Fence. Returns findings only for the caller to apply in feature scope."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-slice-wright
|
|
3
3
|
description: "Sole source/test writer for one /rite-build slice or accepted prove, polish, or review correction. Executes a fresh path-bounded contract, proves the smallest complete change, returns evidence, and never plans, reviews, or writes workspace bookkeeping."
|
|
4
|
-
tools: read, edit, write, bash, find, grep
|
|
4
|
+
tools: read, edit, write, bash, find, grep, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_edit, ctx_patch, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-spec-reviewer
|
|
3
3
|
description: "Independently checks one feature candidate against its spec for /rite-review and /rite-seal. Finds missing or wrong acceptance coverage, preservation regressions, scope creep, placement drift, and design-reference mismatches. Never edits."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-strategy-reviewer
|
|
3
3
|
description: "Read-only /rite-temper reviewer for a hardened spec before planning or code. Tests ambition, scope, premise, pre-mortem risk, over-engineering, testability, irreversibility, cross-cutting concerns, and convention fit; scores from evidence and reports defects without editing."
|
|
4
|
-
tools: read, grep, find
|
|
4
|
+
tools: read, grep, find, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-test-analyst
|
|
3
3
|
description: "Reviews test quality for /rite-seal from a fresh context. Independently checks whether a DevRites feature's tests prove its acceptance criteria and flags missing, assertion-free, or tautological tests."
|
|
4
|
-
tools: read, grep, find, bash
|
|
4
|
+
tools: read, grep, find, bash, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics, ctx_shell
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: devrites-upgrade-planner
|
|
3
3
|
description: "Read-only /rite-upgrade assessor returning a cited current, repairable, unsupported, or gap outcome; never writes/delegates."
|
|
4
|
-
tools: read, grep, find
|
|
4
|
+
tools: read, grep, find, ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics
|
|
5
5
|
inheritProjectContext: true
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -120,7 +120,8 @@ candidate manifest to cover the whole recorded chain — run
|
|
|
120
120
|
run exactly as without this field.
|
|
121
121
|
|
|
122
122
|
`max_parallel` caps a Build batch for unattended runs; `1` forces the serial cycle.
|
|
123
|
-
Unattended runs take the largest eligible set ≤ cap and recompute after every
|
|
123
|
+
Unattended runs take the largest eligible set ≤ cap and recompute after every completed
|
|
124
|
+
round (serial slice or parallel integrate)
|
|
124
125
|
([parallel-batch.md § Dynamic selection and re-batching](../../../rite-build/reference/parallel-batch.md#dynamic-selection-and-re-batching));
|
|
125
126
|
an explicit `/rite-build --parallel N` cap wins for that invocation.
|
|
126
127
|
|
|
@@ -94,9 +94,10 @@ executable controller/harness/bundle bytes or a missing writer, read
|
|
|
94
94
|
`/rite-review` → `/rite-seal`. Read and execute each skill; durable files, not
|
|
95
95
|
chat, carry state. Apply the mutable post-vet budget before first Build.
|
|
96
96
|
Build runs the largest eligible path-disjoint batch (cap: `--parallel N`, else
|
|
97
|
-
sentinel `max_parallel`, else 10) and recomputes after every
|
|
98
|
-
pending slice remains;
|
|
99
|
-
host
|
|
97
|
+
sentinel `max_parallel`, else 10) and recomputes after every completed round until no
|
|
98
|
+
pending slice remains; a one-slice round is serial for that round only, then
|
|
99
|
+
selection runs again (host isolation still forces serial when concurrent writers
|
|
100
|
+
cannot be separated).
|
|
100
101
|
**Completion:** loop reaches Seal GO or persists a valid stop before any later phase.
|
|
101
102
|
5. **Apply stops.** At every gate use
|
|
102
103
|
[stop-conditions.md](reference/stop-conditions.md). A `blocked` label alone is not a stop condition:
|
|
@@ -65,7 +65,7 @@ Workspace files carry state; chat does not. Read and execute each phase skill:
|
|
|
65
65
|
| 3 | `/rite-temper` | harden or reduce; expansion and irreversible risk pause |
|
|
66
66
|
| 4 | `/rite-define` | approved plan/tasks/traceability |
|
|
67
67
|
| 5 | `/rite-vet` | every plan; derive mutable budget after READY |
|
|
68
|
-
| 6 | `/rite-build` batch loop | largest eligible path-disjoint set (cap 10;
|
|
68
|
+
| 6 | `/rite-build` batch loop | largest eligible path-disjoint set (cap 10; one-slice round when <2 eligible); recompute after each round; charge once per green built slice |
|
|
69
69
|
| 7 | `/rite-prove` | all slices built; approved proof; recovery on red |
|
|
70
70
|
| 8 | `/rite-polish` | re-prove after code edits |
|
|
71
71
|
| 9 | `/rite-review` | in-scope correction then fresh proof |
|
|
@@ -60,7 +60,8 @@ Wright applies anti-slop; root verifies returns and never patches source.
|
|
|
60
60
|
|
|
61
61
|
Omitted/`1` ≡ serial; `2`–`10` is a **cap** — the root runs the largest eligible
|
|
62
62
|
path-disjoint set it can start now (`N_eff`), takes fewer when the cap cannot be
|
|
63
|
-
filled, and recomputes after every
|
|
63
|
+
filled, and recomputes after every completed round (serial slice or parallel
|
|
64
|
+
integrate) until no pending slice remains
|
|
64
65
|
([`parallel-batch.md` § Dynamic selection](reference/parallel-batch.md#dynamic-selection-and-re-batching)).
|
|
65
66
|
Unattended runs (`/rite-autocomplete`, `.devrites/AFK` `max_parallel`) repeat batches
|
|
66
67
|
inside the same run; HITL stops after each batch. Non-integer/`N≤0`/`N>10` hard refuse.
|
|
@@ -16,7 +16,9 @@ control; irreversible work (destructive/auth/public API) always pauses.
|
|
|
16
16
|
The controlling root owns the cap:
|
|
17
17
|
|
|
18
18
|
1. **Before every dispatch**, re-read `.devrites/AFK`, `state.md`, and the
|
|
19
|
-
selected slice.
|
|
19
|
+
selected slice. When `--parallel N` or sentinel `max_parallel` is greater than
|
|
20
|
+
1, recompute `N_eff` via `parallel select` before the next dispatch — a prior
|
|
21
|
+
one-slice round does not keep the run serial. A configured `max_slices` and any existing
|
|
20
22
|
`afk_slices_remaining` value, including its released bullet form, must each
|
|
21
23
|
be a decimal nonnegative integer. A missing
|
|
22
24
|
`state.md` or malformed configured value fails closed; an omitted cap is the
|
|
@@ -26,7 +26,7 @@ RECORD → orchestrator: after green verification, update state.md/evidence.m
|
|
|
26
26
|
upsert the authoritative candidate manifest from the actual scoped diff
|
|
27
27
|
(CHECKPOINT) → orchestrator: commit the proven slice local-only as WIP(<slug>)
|
|
28
28
|
with a [devrites-context] body → clean tree, survives a crash (checkpoint.md)
|
|
29
|
-
NEXT → HITL root reports and stops
|
|
29
|
+
NEXT → HITL root reports and stops. AFK with parallel cap>1: return to parallel-batch selection and run the new N_eff; otherwise repeat under afk-discipline.md
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## Why the boundary matters
|
|
@@ -28,18 +28,20 @@ N_eff = min(
|
|
|
28
28
|
)
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
-
Select **greedily in plan order**:
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
nothing pending → Prove. A cap that cannot be filled
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
31
|
+
Select **greedily in plan order**: pass every currently dependency-ready pending slice
|
|
32
|
+
(plan order, `Files likely touched`) to
|
|
33
|
+
`devrites-engine parallel select --cap N [--root <dir>]`. `N_eff ≥ 2` → parallel batch;
|
|
34
|
+
`N_eff = 1` → one serial round; nothing pending → Prove. A cap that cannot be filled
|
|
35
|
+
is normal: take fewer. Serial is this round's size, not the rest of the run.
|
|
36
|
+
|
|
37
|
+
**Re-batch automatically after every completed round** (parallel integrate+cleanup or
|
|
38
|
+
a serial slice). Re-read `state.md`, pending slices, and the tree, then run
|
|
39
|
+
`parallel select` again: finished work leaves the pending set, and satisfied
|
|
40
|
+
dependencies unlock new slices. Under `.devrites/AFK` and `/rite-autocomplete` the
|
|
41
|
+
repeat is the same run — HITL stops after each batch. `--parallel 5` with one eligible
|
|
42
|
+
slice runs that one; when two to five then become eligible, the next round takes that
|
|
43
|
+
many. **Failing case:** the run stays one-by-one after a serial round even though more
|
|
44
|
+
slices are now eligible under the same cap.
|
|
43
45
|
|
|
44
46
|
## Path-disjoint
|
|
45
47
|
|
|
@@ -71,7 +73,8 @@ Lease: `batch_id`, `created_at`, `base_sha`, `n`,
|
|
|
71
73
|
1. Orient/gate; parse the cap; compute `N_eff` and select the eligible set
|
|
72
74
|
([Dynamic selection and re-batching](#dynamic-selection-and-re-batching)) —
|
|
73
75
|
candidates from `orient` `task_graph.slices` + built list, each candidate's
|
|
74
|
-
`Files likely touched` via `observe slice`,
|
|
76
|
+
`Files likely touched` via `observe slice`, then
|
|
77
|
+
`parallel select --cap N` (pairwise disjointness is inside that verb).
|
|
75
78
|
2. Write lease; freeze `B=HEAD`; `parallel create` worktrees.
|
|
76
79
|
3. Dispatch ≤10 wrights in parallel (cwd=worktree; allowlist; prove `HEAD==B`).
|
|
77
80
|
4. Inspect each returned path list, cumulative diff from `B`, transfer identity,
|
|
@@ -163,6 +166,7 @@ Repair rejected work in place; never discard/rebuild while budget remains.
|
|
|
163
166
|
## Engine verbs
|
|
164
167
|
|
|
165
168
|
```text
|
|
169
|
+
devrites-engine parallel select --cap <1-10> [--root <dir>] [<json-file>|-]
|
|
166
170
|
devrites-engine parallel create --root <repo> --slug <slug> --batch <id> --base <B> --json <file>|-
|
|
167
171
|
devrites-engine parallel record-green --root <repo> --slug <slug> --slice <id> --commit <sha>
|
|
168
172
|
devrites-engine parallel integrate --root <repo> --slug <slug> --apply-to-control
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devrites",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.8.0",
|
|
4
4
|
"description": "DevRites: a disciplined senior-engineer workflow pack for Claude Code, Codex, omp, and pi",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"homepage": "https://github.com/ViktorsBaikers/DevRites#readme",
|
package/scripts/pi-generate.sh
CHANGED
|
@@ -111,6 +111,57 @@ _pi_map_tools() {
|
|
|
111
111
|
printf '%s' "$_out"
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
# pi-subagents treats frontmatter tools: as a strict allowlist, so ambient
|
|
115
|
+
# pi-lean-ctx / pi-lens tools are dropped unless named. Append those names
|
|
116
|
+
# after the mapped builtins (preserve base order). Unknown names are pruned
|
|
117
|
+
# non-fatally by pi-subagents. Read-only agents stay read-only: ctx_edit /
|
|
118
|
+
# ctx_patch only when the base already has edit or write; ctx_shell only
|
|
119
|
+
# when the base already has bash.
|
|
120
|
+
_PI_EXTENSION_NAV_TOOLS="ctx_read, ctx_ls, ctx_find, ctx_grep, ctx_glob, ctx_search, ctx_compose, ctx_callgraph, ctx_tree, symbol_search, project_report, module_report, read_symbol, read_enclosing, lens_diagnostics"
|
|
121
|
+
|
|
122
|
+
_pi_csv_has() {
|
|
123
|
+
case ", ${1}, " in
|
|
124
|
+
*", ${2}, "*) return 0 ;;
|
|
125
|
+
*) return 1 ;;
|
|
126
|
+
esac
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
_pi_csv_append() {
|
|
130
|
+
local _list="$1" _name="$2"
|
|
131
|
+
if [ -z "$_name" ]; then
|
|
132
|
+
printf '%s' "$_list"
|
|
133
|
+
return
|
|
134
|
+
fi
|
|
135
|
+
if [ -z "$_list" ]; then
|
|
136
|
+
printf '%s' "$_name"
|
|
137
|
+
return
|
|
138
|
+
fi
|
|
139
|
+
if _pi_csv_has "$_list" "$_name"; then
|
|
140
|
+
printf '%s' "$_list"
|
|
141
|
+
return
|
|
142
|
+
fi
|
|
143
|
+
printf '%s, %s' "$_list" "$_name"
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
_pi_append_extension_tools() {
|
|
147
|
+
local _base="$1"
|
|
148
|
+
local _out="$_base" _tok
|
|
149
|
+
while IFS= read -r _tok; do
|
|
150
|
+
_tok="${_tok#"${_tok%%[![:space:]]*}"}"
|
|
151
|
+
_tok="${_tok%"${_tok##*[![:space:]]}"}"
|
|
152
|
+
[ -z "$_tok" ] && continue
|
|
153
|
+
_out="$(_pi_csv_append "$_out" "$_tok")"
|
|
154
|
+
done < <(printf '%s\n' "$_PI_EXTENSION_NAV_TOOLS" | tr ',' '\n')
|
|
155
|
+
if _pi_csv_has "$_base" "edit" || _pi_csv_has "$_base" "write"; then
|
|
156
|
+
_out="$(_pi_csv_append "$_out" "ctx_edit")"
|
|
157
|
+
_out="$(_pi_csv_append "$_out" "ctx_patch")"
|
|
158
|
+
fi
|
|
159
|
+
if _pi_csv_has "$_base" "bash"; then
|
|
160
|
+
_out="$(_pi_csv_append "$_out" "ctx_shell")"
|
|
161
|
+
fi
|
|
162
|
+
printf '%s' "$_out"
|
|
163
|
+
}
|
|
164
|
+
|
|
114
165
|
# Generate a pi-subagents Markdown agent from a Claude Code markdown agent.
|
|
115
166
|
# pi-subagents loads project agents from .pi/agents/**/*.md (YAML frontmatter +
|
|
116
167
|
# body). The tools allowlist carries the Claude permission boundary: only
|
|
@@ -126,7 +177,7 @@ gen_pi_agent() {
|
|
|
126
177
|
_skills="$(awk 'NR==1 && $0=="---"{fm=1; next} fm && $0=="---"{exit} fm && /^skills:[[:space:]]*$/{list=1; next} list && /^[[:space:]]*-[[:space:]]*/{sub(/^[[:space:]]*-[[:space:]]*/, ""); print; next} list{exit}' "$_src" | tr '\n' ' ' | sed 's/ $//; s/ /, /g')"
|
|
127
178
|
[ -n "$_name" ] || _name="$(basename "$_src" .md)"
|
|
128
179
|
[ -n "$_desc" ] || _desc="DevRites custom agent."
|
|
129
|
-
_tools="$(_pi_map_tools "$_tools_raw" "$_name")"
|
|
180
|
+
_tools="$(_pi_append_extension_tools "$(_pi_map_tools "$_tools_raw" "$_name")")"
|
|
130
181
|
_desc_tmp="$TMP_GEN_DIR/pi-agent-desc-$(basename "$_src").txt"
|
|
131
182
|
_desc_pi="$TMP_GEN_DIR/pi-agent-desc-$(basename "$_src").pi.txt"
|
|
132
183
|
printf '%s' "$_desc" >"$_desc_tmp"
|