@sienklogic/plan-build-run 2.9.1 → 2.11.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 +44 -0
- package/package.json +1 -1
- package/plugins/copilot-pbr/agents/codebase-mapper.agent.md +42 -0
- package/plugins/copilot-pbr/agents/debugger.agent.md +4 -1
- package/plugins/copilot-pbr/agents/executor.agent.md +31 -1
- package/plugins/copilot-pbr/agents/integration-checker.agent.md +33 -2
- package/plugins/copilot-pbr/agents/planner.agent.md +58 -1
- package/plugins/copilot-pbr/agents/researcher.agent.md +23 -0
- package/plugins/copilot-pbr/agents/synthesizer.agent.md +24 -0
- package/plugins/copilot-pbr/agents/verifier.agent.md +35 -1
- package/plugins/copilot-pbr/plugin.json +1 -1
- package/plugins/copilot-pbr/references/agent-contracts.md +297 -0
- package/plugins/copilot-pbr/references/pbr-rules.md +1 -0
- package/plugins/copilot-pbr/references/pbr-tools-cli.md +285 -0
- package/plugins/copilot-pbr/references/ui-formatting.md +38 -56
- package/plugins/copilot-pbr/skills/begin/SKILL.md +30 -7
- package/plugins/copilot-pbr/skills/build/SKILL.md +28 -31
- package/plugins/copilot-pbr/skills/config/SKILL.md +9 -12
- package/plugins/copilot-pbr/skills/continue/SKILL.md +6 -6
- package/plugins/copilot-pbr/skills/dashboard/SKILL.md +12 -0
- package/plugins/copilot-pbr/skills/debug/SKILL.md +23 -26
- package/plugins/copilot-pbr/skills/discuss/SKILL.md +20 -10
- package/plugins/copilot-pbr/skills/do/SKILL.md +3 -3
- package/plugins/copilot-pbr/skills/explore/SKILL.md +11 -14
- package/plugins/copilot-pbr/skills/health/SKILL.md +75 -19
- package/plugins/copilot-pbr/skills/help/SKILL.md +6 -6
- package/plugins/copilot-pbr/skills/import/SKILL.md +22 -18
- package/plugins/copilot-pbr/skills/milestone/SKILL.md +90 -48
- package/plugins/copilot-pbr/skills/note/SKILL.md +3 -3
- package/plugins/copilot-pbr/skills/pause/SKILL.md +11 -10
- package/plugins/copilot-pbr/skills/plan/SKILL.md +22 -9
- package/plugins/copilot-pbr/skills/plan/templates/planner-prompt.md.tmpl +1 -1
- package/plugins/copilot-pbr/skills/quick/SKILL.md +9 -12
- package/plugins/copilot-pbr/skills/resume/SKILL.md +9 -9
- package/plugins/copilot-pbr/skills/review/SKILL.md +17 -12
- package/plugins/copilot-pbr/skills/scan/SKILL.md +9 -11
- package/plugins/copilot-pbr/skills/setup/SKILL.md +54 -8
- package/plugins/copilot-pbr/skills/shared/error-reporting.md +2 -1
- package/plugins/copilot-pbr/skills/shared/progress-display.md +0 -1
- package/plugins/copilot-pbr/skills/shared/universal-anti-patterns.md +10 -6
- package/plugins/copilot-pbr/skills/status/SKILL.md +3 -3
- package/plugins/copilot-pbr/skills/statusline/SKILL.md +12 -8
- package/plugins/copilot-pbr/skills/todo/SKILL.md +51 -28
- package/plugins/cursor-pbr/.cursor-plugin/plugin.json +1 -1
- package/plugins/cursor-pbr/agents/codebase-mapper.md +42 -0
- package/plugins/cursor-pbr/agents/debugger.md +4 -1
- package/plugins/cursor-pbr/agents/executor.md +31 -1
- package/plugins/cursor-pbr/agents/integration-checker.md +33 -2
- package/plugins/cursor-pbr/agents/planner.md +58 -1
- package/plugins/cursor-pbr/agents/researcher.md +23 -0
- package/plugins/cursor-pbr/agents/synthesizer.md +24 -0
- package/plugins/cursor-pbr/agents/verifier.md +35 -1
- package/plugins/cursor-pbr/references/agent-contracts.md +297 -0
- package/plugins/cursor-pbr/references/pbr-rules.md +1 -0
- package/plugins/cursor-pbr/references/pbr-tools-cli.md +285 -0
- package/plugins/cursor-pbr/references/ui-formatting.md +38 -56
- package/plugins/cursor-pbr/skills/begin/SKILL.md +30 -7
- package/plugins/cursor-pbr/skills/build/SKILL.md +28 -31
- package/plugins/cursor-pbr/skills/config/SKILL.md +9 -10
- package/plugins/cursor-pbr/skills/continue/SKILL.md +6 -6
- package/plugins/cursor-pbr/skills/dashboard/SKILL.md +12 -0
- package/plugins/cursor-pbr/skills/debug/SKILL.md +23 -23
- package/plugins/cursor-pbr/skills/discuss/SKILL.md +20 -10
- package/plugins/cursor-pbr/skills/do/SKILL.md +3 -3
- package/plugins/cursor-pbr/skills/explore/SKILL.md +11 -12
- package/plugins/cursor-pbr/skills/health/SKILL.md +75 -19
- package/plugins/cursor-pbr/skills/help/SKILL.md +6 -6
- package/plugins/cursor-pbr/skills/import/SKILL.md +22 -16
- package/plugins/cursor-pbr/skills/milestone/SKILL.md +90 -48
- package/plugins/cursor-pbr/skills/note/SKILL.md +3 -3
- package/plugins/cursor-pbr/skills/pause/SKILL.md +11 -9
- package/plugins/cursor-pbr/skills/plan/SKILL.md +22 -9
- package/plugins/cursor-pbr/skills/plan/templates/planner-prompt.md.tmpl +1 -1
- package/plugins/cursor-pbr/skills/quick/SKILL.md +9 -12
- package/plugins/cursor-pbr/skills/resume/SKILL.md +9 -9
- package/plugins/cursor-pbr/skills/review/SKILL.md +17 -12
- package/plugins/cursor-pbr/skills/scan/SKILL.md +9 -10
- package/plugins/cursor-pbr/skills/setup/SKILL.md +54 -8
- package/plugins/cursor-pbr/skills/shared/error-reporting.md +2 -1
- package/plugins/cursor-pbr/skills/shared/progress-display.md +0 -1
- package/plugins/cursor-pbr/skills/shared/universal-anti-patterns.md +10 -6
- package/plugins/cursor-pbr/skills/status/SKILL.md +3 -3
- package/plugins/cursor-pbr/skills/statusline/SKILL.md +12 -8
- package/plugins/cursor-pbr/skills/todo/SKILL.md +51 -28
- package/plugins/pbr/.claude-plugin/plugin.json +1 -1
- package/plugins/pbr/agents/codebase-mapper.md +42 -0
- package/plugins/pbr/agents/debugger.md +4 -1
- package/plugins/pbr/agents/executor.md +31 -1
- package/plugins/pbr/agents/integration-checker.md +34 -2
- package/plugins/pbr/agents/planner.md +58 -1
- package/plugins/pbr/agents/researcher.md +23 -0
- package/plugins/pbr/agents/synthesizer.md +24 -0
- package/plugins/pbr/agents/verifier.md +36 -1
- package/plugins/pbr/references/agent-contracts.md +297 -0
- package/plugins/pbr/references/pbr-rules.md +1 -0
- package/plugins/pbr/references/pbr-tools-cli.md +285 -0
- package/plugins/pbr/references/ui-formatting.md +37 -54
- package/plugins/pbr/scripts/check-skill-workflow.js +11 -0
- package/plugins/pbr/scripts/check-state-sync.js +58 -0
- package/plugins/pbr/scripts/check-subagent-output.js +43 -4
- package/plugins/pbr/scripts/validate-task.js +69 -17
- package/plugins/pbr/skills/begin/SKILL.md +36 -11
- package/plugins/pbr/skills/build/SKILL.md +37 -25
- package/plugins/pbr/skills/config/SKILL.md +12 -10
- package/plugins/pbr/skills/continue/SKILL.md +11 -9
- package/plugins/pbr/skills/dashboard/SKILL.md +12 -0
- package/plugins/pbr/skills/debug/SKILL.md +29 -23
- package/plugins/pbr/skills/discuss/SKILL.md +20 -10
- package/plugins/pbr/skills/do/SKILL.md +3 -3
- package/plugins/pbr/skills/explore/SKILL.md +14 -12
- package/plugins/pbr/skills/health/SKILL.md +76 -20
- package/plugins/pbr/skills/help/SKILL.md +8 -6
- package/plugins/pbr/skills/import/SKILL.md +25 -16
- package/plugins/pbr/skills/milestone/SKILL.md +88 -45
- package/plugins/pbr/skills/note/SKILL.md +3 -3
- package/plugins/pbr/skills/pause/SKILL.md +13 -9
- package/plugins/pbr/skills/plan/SKILL.md +28 -13
- package/plugins/pbr/skills/plan/templates/planner-prompt.md.tmpl +1 -1
- package/plugins/pbr/skills/quick/SKILL.md +12 -10
- package/plugins/pbr/skills/resume/SKILL.md +11 -9
- package/plugins/pbr/skills/review/SKILL.md +35 -24
- package/plugins/pbr/skills/scan/SKILL.md +12 -10
- package/plugins/pbr/skills/setup/SKILL.md +53 -7
- package/plugins/pbr/skills/shared/error-reporting.md +2 -0
- package/plugins/pbr/skills/shared/universal-anti-patterns.md +10 -6
- package/plugins/pbr/skills/status/SKILL.md +8 -6
- package/plugins/pbr/skills/statusline/SKILL.md +12 -8
- package/plugins/pbr/skills/todo/SKILL.md +51 -28
|
@@ -7,9 +7,9 @@ Consistent output formatting for all Plan-Build-Run skills. Every skill that pro
|
|
|
7
7
|
Use for major workflow transitions. Always use `PLAN-BUILD-RUN` prefix.
|
|
8
8
|
|
|
9
9
|
```
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
11
|
+
║ PLAN-BUILD-RUN ► {STAGE NAME} ║
|
|
12
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
**Stage names (uppercase):**
|
|
@@ -21,7 +21,7 @@ Use for major workflow transitions. Always use `PLAN-BUILD-RUN` prefix.
|
|
|
21
21
|
- `EXECUTING WAVE {N}`
|
|
22
22
|
- `VERIFYING`
|
|
23
23
|
- `PHASE {N} COMPLETE ✓`
|
|
24
|
-
- `MILESTONE COMPLETE
|
|
24
|
+
- `MILESTONE COMPLETE`
|
|
25
25
|
- `SCANNING CODEBASE`
|
|
26
26
|
- `DEBUGGING`
|
|
27
27
|
|
|
@@ -33,9 +33,9 @@ Use for major workflow transitions. Always use `PLAN-BUILD-RUN` prefix.
|
|
|
33
33
|
|
|
34
34
|
Format:
|
|
35
35
|
```
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
37
|
+
║ PLAN-BUILD-RUN ► {SKILL NAME} ║
|
|
38
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
**Skill names (uppercase):**
|
|
@@ -155,7 +155,7 @@ For research agents:
|
|
|
155
155
|
|
|
156
156
|
## Checkpoint Boxes
|
|
157
157
|
|
|
158
|
-
User action required. Use double-line box drawing, 62-character width.
|
|
158
|
+
User action required. Use double-line box drawing, 62-character inner width.
|
|
159
159
|
|
|
160
160
|
```
|
|
161
161
|
╔══════════════════════════════════════════════════════════════╗
|
|
@@ -164,9 +164,7 @@ User action required. Use double-line box drawing, 62-character width.
|
|
|
164
164
|
|
|
165
165
|
{Content}
|
|
166
166
|
|
|
167
|
-
──────────────────────────────────────────────────────────────
|
|
168
167
|
→ {ACTION PROMPT}
|
|
169
|
-
──────────────────────────────────────────────────────────────
|
|
170
168
|
```
|
|
171
169
|
|
|
172
170
|
**Types:**
|
|
@@ -260,25 +258,21 @@ Use plain conversational prompts for these cases instead.
|
|
|
260
258
|
Always present at end of major completions (phase complete, milestone complete, project init).
|
|
261
259
|
|
|
262
260
|
```
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
261
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
262
|
+
║ ▶ NEXT UP ║
|
|
263
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
266
264
|
|
|
267
265
|
**{Identifier}: {Name}** — {one-line description}
|
|
268
266
|
|
|
269
267
|
`{copy-paste command}`
|
|
270
268
|
|
|
271
269
|
<sub>`/clear` first → fresh context window</sub>
|
|
272
|
-
|
|
273
|
-
───────────────────────────────────────────────────────────────
|
|
270
|
+
```
|
|
274
271
|
|
|
275
272
|
**Also available:**
|
|
276
273
|
- `/pbr:alternative-1` — description
|
|
277
274
|
- `/pbr:alternative-2` — description
|
|
278
275
|
|
|
279
|
-
───────────────────────────────────────────────────────────────
|
|
280
|
-
```
|
|
281
|
-
|
|
282
276
|
**Shorter routing (for minor completions):**
|
|
283
277
|
```
|
|
284
278
|
What's next?
|
|
@@ -333,18 +327,18 @@ Use tables for structured data:
|
|
|
333
327
|
### Phase Complete
|
|
334
328
|
|
|
335
329
|
```
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
330
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
331
|
+
║ PLAN-BUILD-RUN ► PHASE {N} COMPLETE ✓ ║
|
|
332
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
339
333
|
|
|
340
334
|
**Phase {N}: {Name}**
|
|
341
335
|
|
|
342
336
|
{X} plans executed
|
|
343
337
|
Goal verified ✓
|
|
344
338
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
339
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
340
|
+
║ ▶ NEXT UP ║
|
|
341
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
348
342
|
|
|
349
343
|
**Phase {N+1}: {Name}** — {Goal from ROADMAP.md}
|
|
350
344
|
|
|
@@ -352,30 +346,26 @@ Goal verified ✓
|
|
|
352
346
|
|
|
353
347
|
<sub>/clear first → fresh context window</sub>
|
|
354
348
|
|
|
355
|
-
───────────────────────────────────────────────────────────────
|
|
356
|
-
|
|
357
349
|
**Also available:**
|
|
358
350
|
- /pbr:plan {N+1} — skip discussion, plan directly
|
|
359
351
|
- /pbr:review {N} — manual acceptance testing before continuing
|
|
360
|
-
|
|
361
|
-
───────────────────────────────────────────────────────────────
|
|
362
352
|
```
|
|
363
353
|
|
|
364
354
|
### Milestone Complete
|
|
365
355
|
|
|
366
356
|
```
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
357
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
358
|
+
║ PLAN-BUILD-RUN ► MILESTONE COMPLETE ║
|
|
359
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
370
360
|
|
|
371
361
|
**{version}**
|
|
372
362
|
|
|
373
363
|
{N} phases completed
|
|
374
364
|
All phase goals verified ✓
|
|
375
365
|
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
366
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
367
|
+
║ ▶ NEXT UP ║
|
|
368
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
379
369
|
|
|
380
370
|
**Audit milestone** — verify requirements, cross-phase integration, E2E flows
|
|
381
371
|
|
|
@@ -383,21 +373,17 @@ All phase goals verified ✓
|
|
|
383
373
|
|
|
384
374
|
<sub>/clear first → fresh context window</sub>
|
|
385
375
|
|
|
386
|
-
───────────────────────────────────────────────────────────────
|
|
387
|
-
|
|
388
376
|
**Also available:**
|
|
389
377
|
- /pbr:review — manual acceptance testing
|
|
390
378
|
- /pbr:milestone complete — archive milestone after audit passes
|
|
391
|
-
|
|
392
|
-
───────────────────────────────────────────────────────────────
|
|
393
379
|
```
|
|
394
380
|
|
|
395
381
|
### Gaps Found
|
|
396
382
|
|
|
397
383
|
```
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
384
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
385
|
+
║ PLAN-BUILD-RUN ► PHASE {N} GAPS FOUND ⚠ ║
|
|
386
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
401
387
|
|
|
402
388
|
**Phase {N}: {Name}**
|
|
403
389
|
|
|
@@ -408,9 +394,9 @@ Report: .planning/phases/{phase_dir}/VERIFICATION.md
|
|
|
408
394
|
|
|
409
395
|
{Extract gap summaries from VERIFICATION.md}
|
|
410
396
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
397
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
398
|
+
║ ▶ NEXT UP ║
|
|
399
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
414
400
|
|
|
415
401
|
**Plan gap closure** — create additional plans to complete the phase
|
|
416
402
|
|
|
@@ -418,13 +404,9 @@ Report: .planning/phases/{phase_dir}/VERIFICATION.md
|
|
|
418
404
|
|
|
419
405
|
<sub>/clear first → fresh context window</sub>
|
|
420
406
|
|
|
421
|
-
───────────────────────────────────────────────────────────────
|
|
422
|
-
|
|
423
407
|
**Also available:**
|
|
424
408
|
- cat .planning/phases/{phase_dir}/VERIFICATION.md — see full report
|
|
425
409
|
- /pbr:review {N} — manual testing before planning
|
|
426
|
-
|
|
427
|
-
───────────────────────────────────────────────────────────────
|
|
428
410
|
```
|
|
429
411
|
|
|
430
412
|
---
|
|
@@ -434,9 +416,9 @@ Report: .planning/phases/{phase_dir}/VERIFICATION.md
|
|
|
434
416
|
Use for session lifecycle transitions (pause/resume):
|
|
435
417
|
|
|
436
418
|
```
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
419
|
+
╔══════════════════════════════════════════════════════════════╗
|
|
420
|
+
║ PLAN-BUILD-RUN ► SESSION RESTORED ✓ ║
|
|
421
|
+
╚══════════════════════════════════════════════════════════════╝
|
|
440
422
|
|
|
441
423
|
Position: Phase {N} — {phase name}, Plan {M}
|
|
442
424
|
Paused: {ISO datetime}
|
|
@@ -452,10 +434,11 @@ Other session banners: `SESSION SAVED ✓` (pause), `RESUMING SESSION` (resume s
|
|
|
452
434
|
## Anti-Patterns
|
|
453
435
|
|
|
454
436
|
Do NOT:
|
|
455
|
-
- Use varying box/banner widths
|
|
456
|
-
-
|
|
437
|
+
- Use varying box/banner widths — always 62-character inner width
|
|
438
|
+
- Use `━━━` heavy bars or `───` thin dividers for banners/sections — use `╔═╗║╚═╝` boxes
|
|
439
|
+
- Mix banner styles (`===`, `---`, `***`) with double-line boxes
|
|
457
440
|
- Skip `PLAN-BUILD-RUN ►` prefix in stage banners
|
|
458
|
-
- Use random emoji (only
|
|
441
|
+
- Use random emoji (only for milestone complete, `✓` for phase complete)
|
|
459
442
|
- Skip the "Next Up" block after major completions
|
|
460
443
|
- Reference non-Plan-Build-Run commands (always use `/pbr:*` commands)
|
|
461
444
|
- Use non-Plan-Build-Run branding in banners
|
|
@@ -113,6 +113,7 @@ function checkSkillRules(skill, filePath, planningDir) {
|
|
|
113
113
|
|
|
114
114
|
switch (skill) {
|
|
115
115
|
case 'quick':
|
|
116
|
+
case 'do':
|
|
116
117
|
return checkQuickRules(filePath, isInPlanning, planningDir);
|
|
117
118
|
case 'build':
|
|
118
119
|
return checkBuildRules(filePath, isInPlanning, planningDir);
|
|
@@ -126,6 +127,16 @@ function checkSkillRules(skill, filePath, planningDir) {
|
|
|
126
127
|
case 'explore':
|
|
127
128
|
case 'import':
|
|
128
129
|
case 'scan':
|
|
130
|
+
case 'note':
|
|
131
|
+
case 'todo':
|
|
132
|
+
case 'health':
|
|
133
|
+
case 'help':
|
|
134
|
+
case 'config':
|
|
135
|
+
case 'continue':
|
|
136
|
+
case 'resume':
|
|
137
|
+
case 'pause':
|
|
138
|
+
case 'status':
|
|
139
|
+
case 'dashboard':
|
|
129
140
|
return checkReadOnlySkillRules(skill, filePath, isInPlanning);
|
|
130
141
|
default:
|
|
131
142
|
return null;
|
|
@@ -161,6 +161,10 @@ function updateStatePosition(content, updates) {
|
|
|
161
161
|
for (let i = 0; i < lines.length; i++) {
|
|
162
162
|
const line = lines[i];
|
|
163
163
|
|
|
164
|
+
if (updates.phaseLine !== undefined && /^Phase:\s/.test(line)) {
|
|
165
|
+
lines[i] = `Phase: ${updates.phaseLine}`;
|
|
166
|
+
}
|
|
167
|
+
|
|
164
168
|
if (updates.planLine !== undefined && /^Plan:\s/.test(line)) {
|
|
165
169
|
lines[i] = `Plan: ${updates.planLine}`;
|
|
166
170
|
}
|
|
@@ -185,6 +189,18 @@ function updateStatePosition(content, updates) {
|
|
|
185
189
|
let fm = content.substring(0, fmEnd + 3);
|
|
186
190
|
const body = content.substring(fmEnd + 3);
|
|
187
191
|
|
|
192
|
+
if (updates.fmCurrentPhase !== undefined) {
|
|
193
|
+
fm = fm.replace(/^(current_phase:\s*).*/m, `$1${updates.fmCurrentPhase}`);
|
|
194
|
+
}
|
|
195
|
+
if (updates.fmTotalPhases !== undefined) {
|
|
196
|
+
fm = fm.replace(/^(total_phases:\s*).*/m, `$1${updates.fmTotalPhases}`);
|
|
197
|
+
}
|
|
198
|
+
if (updates.fmPhaseSlug !== undefined) {
|
|
199
|
+
fm = fm.replace(/^(phase_slug:\s*).*/m, `$1"${updates.fmPhaseSlug}"`);
|
|
200
|
+
}
|
|
201
|
+
if (updates.fmPhaseName !== undefined) {
|
|
202
|
+
fm = fm.replace(/^(phase_name:\s*).*/m, `$1"${updates.fmPhaseName}"`);
|
|
203
|
+
}
|
|
188
204
|
if (updates.fmPlansComplete !== undefined) {
|
|
189
205
|
fm = fm.replace(/^(plans_complete:\s*).*/m, `$1${updates.fmPlansComplete}`);
|
|
190
206
|
}
|
|
@@ -216,6 +232,9 @@ function updateStatePositionBody(body, updates) {
|
|
|
216
232
|
for (let i = 0; i < lines.length; i++) {
|
|
217
233
|
const line = lines[i];
|
|
218
234
|
|
|
235
|
+
if (updates.phaseLine !== undefined && /^Phase:\s/.test(line)) {
|
|
236
|
+
lines[i] = `Phase: ${updates.phaseLine}`;
|
|
237
|
+
}
|
|
219
238
|
if (updates.planLine !== undefined && /^Plan:\s/.test(line)) {
|
|
220
239
|
lines[i] = `Plan: ${updates.planLine}`;
|
|
221
240
|
}
|
|
@@ -323,6 +342,17 @@ function checkStateSync(data) {
|
|
|
323
342
|
const today = new Date().toISOString().slice(0, 10);
|
|
324
343
|
const messages = [];
|
|
325
344
|
|
|
345
|
+
// Derive phase metadata for potential phase-line sync
|
|
346
|
+
const phaseNumInt = parseInt(phaseNum, 10);
|
|
347
|
+
const phaseSlug = phaseDirName.replace(/^\d+-/, '');
|
|
348
|
+
const phaseName = phaseSlug.replace(/-/g, ' ')
|
|
349
|
+
.replace(/\b\w/g, c => c.toUpperCase());
|
|
350
|
+
let totalPhases = 0;
|
|
351
|
+
try {
|
|
352
|
+
totalPhases = fs.readdirSync(phasesDir, { withFileTypes: true })
|
|
353
|
+
.filter(e => e.isDirectory() && /^\d+-/.test(e.name)).length;
|
|
354
|
+
} catch (_e) { /* leave as 0 */ }
|
|
355
|
+
|
|
326
356
|
if (isSummary) {
|
|
327
357
|
const plansComplete = `${artifacts.completeSummaries}/${artifacts.plans}`;
|
|
328
358
|
const allComplete = artifacts.completeSummaries >= artifacts.plans;
|
|
@@ -358,6 +388,20 @@ function checkStateSync(data) {
|
|
|
358
388
|
fmLastActivity: today,
|
|
359
389
|
fmProgressPct: overallPct
|
|
360
390
|
};
|
|
391
|
+
|
|
392
|
+
// Detect phase mismatch and add phase updates
|
|
393
|
+
const currentPhaseMatch = stateContent.match(/^current_phase:\s*(\d+)/m)
|
|
394
|
+
|| stateContent.match(/^Phase:\s*(\d+)\s/m);
|
|
395
|
+
const currentPhase = currentPhaseMatch ? parseInt(currentPhaseMatch[1], 10) : null;
|
|
396
|
+
if (currentPhase !== null && currentPhase !== phaseNumInt) {
|
|
397
|
+
stateUpdates.phaseLine = `${phaseNumInt} of ${totalPhases} (${phaseName})`;
|
|
398
|
+
stateUpdates.fmCurrentPhase = phaseNumInt;
|
|
399
|
+
stateUpdates.fmTotalPhases = totalPhases;
|
|
400
|
+
stateUpdates.fmPhaseSlug = phaseSlug;
|
|
401
|
+
stateUpdates.fmPhaseName = phaseName;
|
|
402
|
+
messages.push(`STATE.md: Phase ${currentPhase} → ${phaseNumInt}`);
|
|
403
|
+
}
|
|
404
|
+
|
|
361
405
|
const updatedState = updateStatePosition(stateContent, stateUpdates);
|
|
362
406
|
if (updatedState !== stateContent) {
|
|
363
407
|
atomicWrite(statePath, updatedState);
|
|
@@ -422,6 +466,20 @@ function checkStateSync(data) {
|
|
|
422
466
|
fmLastActivity: today,
|
|
423
467
|
fmProgressPct: overallPct
|
|
424
468
|
};
|
|
469
|
+
|
|
470
|
+
// Detect phase mismatch and add phase updates
|
|
471
|
+
const currentPhaseMatch = stateContent.match(/^current_phase:\s*(\d+)/m)
|
|
472
|
+
|| stateContent.match(/^Phase:\s*(\d+)\s/m);
|
|
473
|
+
const currentPhase = currentPhaseMatch ? parseInt(currentPhaseMatch[1], 10) : null;
|
|
474
|
+
if (currentPhase !== null && currentPhase !== phaseNumInt) {
|
|
475
|
+
stateUpdates.phaseLine = `${phaseNumInt} of ${totalPhases} (${phaseName})`;
|
|
476
|
+
stateUpdates.fmCurrentPhase = phaseNumInt;
|
|
477
|
+
stateUpdates.fmTotalPhases = totalPhases;
|
|
478
|
+
stateUpdates.fmPhaseSlug = phaseSlug;
|
|
479
|
+
stateUpdates.fmPhaseName = phaseName;
|
|
480
|
+
messages.push(`STATE.md: Phase ${currentPhase} → ${phaseNumInt}`);
|
|
481
|
+
}
|
|
482
|
+
|
|
425
483
|
const updatedState = updateStatePosition(stateContent, stateUpdates);
|
|
426
484
|
if (updatedState !== stateContent) {
|
|
427
485
|
atomicWrite(statePath, updatedState);
|
|
@@ -21,6 +21,19 @@ const fs = require('fs');
|
|
|
21
21
|
const path = require('path');
|
|
22
22
|
const { logHook } = require('./hook-logger');
|
|
23
23
|
|
|
24
|
+
/**
|
|
25
|
+
* Check if a file was modified recently (within thresholdMs).
|
|
26
|
+
* Returns false if file doesn't exist or on error.
|
|
27
|
+
*/
|
|
28
|
+
function isRecent(filePath, thresholdMs = 300000) {
|
|
29
|
+
try {
|
|
30
|
+
const stat = fs.statSync(filePath);
|
|
31
|
+
return (Date.now() - stat.mtimeMs) < thresholdMs;
|
|
32
|
+
} catch (_e) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
24
37
|
// Agent type → expected output patterns
|
|
25
38
|
const AGENT_OUTPUTS = {
|
|
26
39
|
'pbr:executor': {
|
|
@@ -46,9 +59,16 @@ const AGENT_OUTPUTS = {
|
|
|
46
59
|
const researchDir = path.join(planningDir, 'research');
|
|
47
60
|
if (!fs.existsSync(researchDir)) return [];
|
|
48
61
|
try {
|
|
49
|
-
|
|
62
|
+
const allFiles = fs.readdirSync(researchDir)
|
|
50
63
|
.filter(f => f.endsWith('.md'))
|
|
51
64
|
.map(f => path.join('research', f));
|
|
65
|
+
if (allFiles.length === 0) return [];
|
|
66
|
+
const recentFiles = allFiles.filter(f => isRecent(path.join(planningDir, f)));
|
|
67
|
+
if (recentFiles.length === 0) {
|
|
68
|
+
// Files exist but none are recent — return them but flag staleness
|
|
69
|
+
allFiles._stale = true;
|
|
70
|
+
}
|
|
71
|
+
return allFiles;
|
|
52
72
|
} catch (_e) {
|
|
53
73
|
return [];
|
|
54
74
|
}
|
|
@@ -61,14 +81,27 @@ const AGENT_OUTPUTS = {
|
|
|
61
81
|
if (fs.existsSync(researchDir)) {
|
|
62
82
|
try {
|
|
63
83
|
const files = fs.readdirSync(researchDir).filter(f => f.endsWith('.md'));
|
|
64
|
-
if (files.length > 0)
|
|
84
|
+
if (files.length > 0) {
|
|
85
|
+
const allFiles = files.map(f => path.join('research', f));
|
|
86
|
+
const recentFiles = allFiles.filter(f => isRecent(path.join(planningDir, f)));
|
|
87
|
+
if (recentFiles.length === 0) {
|
|
88
|
+
allFiles._stale = true;
|
|
89
|
+
}
|
|
90
|
+
return allFiles;
|
|
91
|
+
}
|
|
65
92
|
} catch (_e) { /* best-effort */ }
|
|
66
93
|
}
|
|
67
94
|
const contextFile = path.join(planningDir, 'CONTEXT.md');
|
|
68
95
|
if (fs.existsSync(contextFile)) {
|
|
69
96
|
try {
|
|
70
97
|
const stat = fs.statSync(contextFile);
|
|
71
|
-
if (stat.size > 0)
|
|
98
|
+
if (stat.size > 0) {
|
|
99
|
+
const result = ['CONTEXT.md'];
|
|
100
|
+
if (!isRecent(contextFile)) {
|
|
101
|
+
result._stale = true;
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
72
105
|
} catch (_e) { /* best-effort */ }
|
|
73
106
|
}
|
|
74
107
|
return [];
|
|
@@ -255,6 +288,12 @@ function main() {
|
|
|
255
288
|
// Skill-specific post-completion validation
|
|
256
289
|
const skillWarnings = [];
|
|
257
290
|
|
|
291
|
+
// Mtime-based recency check for researcher and synthesizer
|
|
292
|
+
if (found._stale && (agentType === 'pbr:researcher' || agentType === 'pbr:synthesizer')) {
|
|
293
|
+
const label = agentType === 'pbr:researcher' ? 'Researcher' : 'Synthesizer';
|
|
294
|
+
skillWarnings.push(`${label} output may be stale — no recent output files detected.`);
|
|
295
|
+
}
|
|
296
|
+
|
|
258
297
|
// GAP-04: Begin planner must produce core files
|
|
259
298
|
if (activeSkill === 'begin' && agentType === 'pbr:planner') {
|
|
260
299
|
const coreFiles = ['REQUIREMENTS.md', 'ROADMAP.md', 'STATE.md'];
|
|
@@ -317,5 +356,5 @@ function main() {
|
|
|
317
356
|
process.exit(0);
|
|
318
357
|
}
|
|
319
358
|
|
|
320
|
-
module.exports = { AGENT_OUTPUTS, findInPhaseDir, findInQuickDir, checkSummaryCommits };
|
|
359
|
+
module.exports = { AGENT_OUTPUTS, findInPhaseDir, findInQuickDir, checkSummaryCommits, isRecent };
|
|
321
360
|
if (require.main === module || process.argv[1] === __filename) { main(); }
|
|
@@ -114,7 +114,8 @@ function checkQuickExecutorGate(data) {
|
|
|
114
114
|
return {
|
|
115
115
|
block: true,
|
|
116
116
|
reason: 'Cannot spawn executor: .planning/quick/ directory does not exist. ' +
|
|
117
|
-
'You must create the quick task directory and PLAN.md first (Steps 4-6).'
|
|
117
|
+
'You must create the quick task directory and PLAN.md first (Steps 4-6). ' +
|
|
118
|
+
'To fix: Re-run /pbr:quick to create the quick task directory and PLAN.md.'
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
121
|
|
|
@@ -138,13 +139,15 @@ function checkQuickExecutorGate(data) {
|
|
|
138
139
|
return {
|
|
139
140
|
block: true,
|
|
140
141
|
reason: 'Cannot spawn executor: no PLAN.md found in any .planning/quick/*/ directory. ' +
|
|
141
|
-
'You must create .planning/quick/{NNN}-{slug}/PLAN.md first (Steps 4-6).'
|
|
142
|
+
'You must create .planning/quick/{NNN}-{slug}/PLAN.md first (Steps 4-6). ' +
|
|
143
|
+
'To fix: Re-run /pbr:quick to create the quick task directory and PLAN.md.'
|
|
142
144
|
};
|
|
143
145
|
}
|
|
144
146
|
} catch (_e) {
|
|
145
147
|
return {
|
|
146
148
|
block: true,
|
|
147
|
-
reason: 'Cannot spawn executor: failed to read .planning/quick/ directory.'
|
|
149
|
+
reason: 'Cannot spawn executor: failed to read .planning/quick/ directory. ' +
|
|
150
|
+
'To fix: Re-run /pbr:quick to create the quick task directory and PLAN.md.'
|
|
148
151
|
};
|
|
149
152
|
}
|
|
150
153
|
|
|
@@ -187,7 +190,7 @@ function checkBuildExecutorGate(data) {
|
|
|
187
190
|
if (!fs.existsSync(phasesDir)) {
|
|
188
191
|
return {
|
|
189
192
|
block: true,
|
|
190
|
-
reason: 'Cannot spawn executor: .planning/phases/ directory does not exist. Run /pbr:plan first.'
|
|
193
|
+
reason: 'Cannot spawn executor: .planning/phases/ directory does not exist. To fix: Run /pbr:plan {N} to create plans first.'
|
|
191
194
|
};
|
|
192
195
|
}
|
|
193
196
|
|
|
@@ -195,7 +198,7 @@ function checkBuildExecutorGate(data) {
|
|
|
195
198
|
if (dirs.length === 0) {
|
|
196
199
|
return {
|
|
197
200
|
block: true,
|
|
198
|
-
reason: `Cannot spawn executor: no phase directory found for phase ${currentPhase}. Run /pbr:plan first.`
|
|
201
|
+
reason: `Cannot spawn executor: no phase directory found for phase ${currentPhase}. To fix: Run /pbr:plan ${currentPhase} to create plans first.`
|
|
199
202
|
};
|
|
200
203
|
}
|
|
201
204
|
|
|
@@ -213,7 +216,7 @@ function checkBuildExecutorGate(data) {
|
|
|
213
216
|
if (!hasPlan) {
|
|
214
217
|
return {
|
|
215
218
|
block: true,
|
|
216
|
-
reason: `Cannot spawn executor: no PLAN.md found in .planning/phases/${dirs[0]}/. Run /pbr:plan first.`
|
|
219
|
+
reason: `Cannot spawn executor: no PLAN.md found in .planning/phases/${dirs[0]}/. To fix: Run /pbr:plan ${currentPhase} to create plans first.`
|
|
217
220
|
};
|
|
218
221
|
}
|
|
219
222
|
} catch (_e) {
|
|
@@ -248,7 +251,7 @@ function checkPlanExecutorGate(data) {
|
|
|
248
251
|
|
|
249
252
|
return {
|
|
250
253
|
block: true,
|
|
251
|
-
reason: 'Plan skill should not spawn executors.
|
|
254
|
+
reason: 'Plan skill should not spawn executors. To fix: Run /pbr:build to execute plans. The plan skill creates plans; the build skill executes them.'
|
|
252
255
|
};
|
|
253
256
|
}
|
|
254
257
|
|
|
@@ -296,7 +299,7 @@ function checkReviewPlannerGate(data) {
|
|
|
296
299
|
if (!hasVerification) {
|
|
297
300
|
return {
|
|
298
301
|
block: true,
|
|
299
|
-
reason: 'Review planner gate: Cannot spawn planner for gap closure without a VERIFICATION.md. Run /pbr:review
|
|
302
|
+
reason: 'Review planner gate: Cannot spawn planner for gap closure without a VERIFICATION.md. To fix: Run /pbr:review {N} to create VERIFICATION.md first.'
|
|
300
303
|
};
|
|
301
304
|
}
|
|
302
305
|
} catch (_e) {
|
|
@@ -358,7 +361,7 @@ function checkReviewVerifierGate(data) {
|
|
|
358
361
|
if (!hasSummary) {
|
|
359
362
|
return {
|
|
360
363
|
block: true,
|
|
361
|
-
reason: 'Review verifier gate: Cannot spawn verifier without SUMMARY.md in phase directory. Run /pbr:build first.'
|
|
364
|
+
reason: 'Review verifier gate: Cannot spawn verifier without SUMMARY.md in phase directory. To fix: Run /pbr:build {N} to create SUMMARY.md first.'
|
|
362
365
|
};
|
|
363
366
|
}
|
|
364
367
|
} catch (_e) {
|
|
@@ -443,14 +446,22 @@ function checkMilestoneCompleteGate(data) {
|
|
|
443
446
|
if (pDirs.length === 0) {
|
|
444
447
|
return {
|
|
445
448
|
block: true,
|
|
446
|
-
reason: `Milestone complete gate: Phase ${paddedPhase} directory not found. All milestone phases must be verified before completing milestone.`
|
|
449
|
+
reason: `Milestone complete gate: Phase ${paddedPhase} directory not found. All milestone phases must be verified before completing milestone. To fix: Run /pbr:review ${paddedPhase} — phase must have status: passed.`
|
|
447
450
|
};
|
|
448
451
|
}
|
|
449
|
-
const
|
|
452
|
+
const verificationFile = path.join(phasesDir, pDirs[0], 'VERIFICATION.md');
|
|
453
|
+
const hasVerification = fs.existsSync(verificationFile);
|
|
450
454
|
if (!hasVerification) {
|
|
451
455
|
return {
|
|
452
456
|
block: true,
|
|
453
|
-
reason: `Milestone complete gate: Phase ${paddedPhase} (${pDirs[0]}) lacks VERIFICATION.md. All milestone phases must be verified before completing milestone.`
|
|
457
|
+
reason: `Milestone complete gate: Phase ${paddedPhase} (${pDirs[0]}) lacks VERIFICATION.md. All milestone phases must be verified before completing milestone. To fix: Run /pbr:review ${paddedPhase} — phase must have status: passed.`
|
|
458
|
+
};
|
|
459
|
+
}
|
|
460
|
+
const verStatus = getVerificationStatus(verificationFile);
|
|
461
|
+
if (verStatus === 'gaps_found') {
|
|
462
|
+
return {
|
|
463
|
+
block: true,
|
|
464
|
+
reason: `Milestone complete gate: Phase ${paddedPhase} VERIFICATION.md has status: gaps_found. Close all gaps before completing milestone. To fix: Run /pbr:review ${paddedPhase} — phase must have status: passed.`
|
|
454
465
|
};
|
|
455
466
|
}
|
|
456
467
|
}
|
|
@@ -538,14 +549,14 @@ function checkBuildDependencyGate(data) {
|
|
|
538
549
|
if (pDirs.length === 0) {
|
|
539
550
|
return {
|
|
540
551
|
block: true,
|
|
541
|
-
reason: `Build dependency gate: Dependent phase ${paddedPhase} lacks VERIFICATION.md. Run /pbr:review on
|
|
552
|
+
reason: `Build dependency gate: Dependent phase ${paddedPhase} lacks VERIFICATION.md. To fix: Run /pbr:review on the dependency phase first.`
|
|
542
553
|
};
|
|
543
554
|
}
|
|
544
555
|
const hasVerification = fs.existsSync(path.join(phasesDir, pDirs[0], 'VERIFICATION.md'));
|
|
545
556
|
if (!hasVerification) {
|
|
546
557
|
return {
|
|
547
558
|
block: true,
|
|
548
|
-
reason: `Build dependency gate: Dependent phase ${paddedPhase} lacks VERIFICATION.md. Run /pbr:review on
|
|
559
|
+
reason: `Build dependency gate: Dependent phase ${paddedPhase} lacks VERIFICATION.md. To fix: Run /pbr:review on the dependency phase first.`
|
|
549
560
|
};
|
|
550
561
|
}
|
|
551
562
|
}
|
|
@@ -561,6 +572,45 @@ function checkBuildDependencyGate(data) {
|
|
|
561
572
|
* spawned, warn if .checkpoint-manifest.json is missing in the phase dir.
|
|
562
573
|
* Returns a warning string or null.
|
|
563
574
|
*/
|
|
575
|
+
/**
|
|
576
|
+
* Parse VERIFICATION.md frontmatter to extract status field.
|
|
577
|
+
* Returns the status string or 'unknown' if not parseable.
|
|
578
|
+
*/
|
|
579
|
+
function getVerificationStatus(filePath) {
|
|
580
|
+
try {
|
|
581
|
+
const content = fs.readFileSync(filePath, 'utf8');
|
|
582
|
+
const fmMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
583
|
+
if (!fmMatch) return 'unknown';
|
|
584
|
+
const statusMatch = fmMatch[1].match(/^status:\s*(\S+)/m);
|
|
585
|
+
return statusMatch ? statusMatch[1] : 'unknown';
|
|
586
|
+
} catch (_e) {
|
|
587
|
+
return 'unknown';
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
/**
|
|
592
|
+
* Advisory check: when pbr:debugger is spawned and .active-skill is 'debug',
|
|
593
|
+
* warn if .planning/debug/ directory does not exist.
|
|
594
|
+
* Returns a warning string or null.
|
|
595
|
+
*/
|
|
596
|
+
function checkDebuggerAdvisory(data) {
|
|
597
|
+
const subagentType = data.tool_input?.subagent_type || '';
|
|
598
|
+
if (subagentType !== 'pbr:debugger') return null;
|
|
599
|
+
// Only advise when spawned from the debug skill
|
|
600
|
+
const activeSkillPath = path.join(process.cwd(), '.planning', '.active-skill');
|
|
601
|
+
try {
|
|
602
|
+
const activeSkill = fs.readFileSync(activeSkillPath, 'utf8').trim();
|
|
603
|
+
if (activeSkill !== 'debug') return null;
|
|
604
|
+
} catch (_e) {
|
|
605
|
+
return null; // No .active-skill file — skip advisory
|
|
606
|
+
}
|
|
607
|
+
const debugDir = path.join(process.cwd(), '.planning', 'debug');
|
|
608
|
+
if (!fs.existsSync(debugDir)) {
|
|
609
|
+
return 'Debugger advisory: .planning/debug/ does not exist. Create it before spawning the debugger so output has a target location.';
|
|
610
|
+
}
|
|
611
|
+
return null;
|
|
612
|
+
}
|
|
613
|
+
|
|
564
614
|
function checkCheckpointManifest(data) {
|
|
565
615
|
const toolInput = data.tool_input || {};
|
|
566
616
|
const subagentType = toolInput.subagent_type || '';
|
|
@@ -595,7 +645,7 @@ function checkCheckpointManifest(data) {
|
|
|
595
645
|
const phaseDir = path.join(phasesDir, dirs[0]);
|
|
596
646
|
const manifestFile = path.join(phaseDir, '.checkpoint-manifest.json');
|
|
597
647
|
if (!fs.existsSync(manifestFile)) {
|
|
598
|
-
return 'Build advisory: .checkpoint-manifest.json not found in phase directory. The build skill should write this before spawning executors.';
|
|
648
|
+
return 'Build advisory: .checkpoint-manifest.json not found in phase directory. The build skill should write this before spawning executors. To fix: Run /pbr:health to regenerate checkpoint manifest.';
|
|
599
649
|
}
|
|
600
650
|
} catch (_e) {
|
|
601
651
|
return null;
|
|
@@ -624,7 +674,7 @@ function checkActiveSkillIntegrity(data) {
|
|
|
624
674
|
|
|
625
675
|
const activeSkillFile = path.join(planningDir, '.active-skill');
|
|
626
676
|
if (!fs.existsSync(activeSkillFile)) {
|
|
627
|
-
return 'Active-skill integrity: .planning/.active-skill not found. Skill-specific enforcement is disabled. The invoking skill should write this file.';
|
|
677
|
+
return 'Active-skill integrity: .planning/.active-skill not found. Skill-specific enforcement is disabled. The invoking skill should write this file. To fix: Wait for the current skill to finish, or delete .planning/.active-skill if stale.';
|
|
628
678
|
}
|
|
629
679
|
|
|
630
680
|
return null;
|
|
@@ -727,6 +777,8 @@ function main() {
|
|
|
727
777
|
const warnings = checkTask(data);
|
|
728
778
|
const manifestWarning = checkCheckpointManifest(data);
|
|
729
779
|
if (manifestWarning) warnings.push(manifestWarning);
|
|
780
|
+
const debuggerWarning = checkDebuggerAdvisory(data);
|
|
781
|
+
if (debuggerWarning) warnings.push(debuggerWarning);
|
|
730
782
|
const activeSkillWarning = checkActiveSkillIntegrity(data);
|
|
731
783
|
if (activeSkillWarning) warnings.push(activeSkillWarning);
|
|
732
784
|
|
|
@@ -747,5 +799,5 @@ function main() {
|
|
|
747
799
|
});
|
|
748
800
|
}
|
|
749
801
|
|
|
750
|
-
module.exports = { checkTask, checkQuickExecutorGate, checkBuildExecutorGate, checkPlanExecutorGate, checkReviewPlannerGate, checkReviewVerifierGate, checkMilestoneCompleteGate, checkBuildDependencyGate, checkCheckpointManifest, checkActiveSkillIntegrity, KNOWN_AGENTS, MAX_DESCRIPTION_LENGTH };
|
|
802
|
+
module.exports = { checkTask, checkQuickExecutorGate, checkBuildExecutorGate, checkPlanExecutorGate, checkReviewPlannerGate, checkReviewVerifierGate, checkMilestoneCompleteGate, checkBuildDependencyGate, checkCheckpointManifest, checkDebuggerAdvisory, getVerificationStatus, checkActiveSkillIntegrity, KNOWN_AGENTS, MAX_DESCRIPTION_LENGTH };
|
|
751
803
|
if (require.main === module || process.argv[1] === __filename) { main(); }
|