@sienklogic/plan-build-run 2.0.0 → 2.0.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/CHANGELOG.md +56 -56
- package/CLAUDE.md +149 -149
- package/LICENSE +21 -21
- package/README.md +247 -247
- package/dashboard/bin/cli.js +25 -25
- package/dashboard/package.json +34 -34
- package/dashboard/public/css/layout.css +406 -406
- package/dashboard/public/css/status-colors.css +98 -98
- package/dashboard/public/js/htmx-title.js +5 -5
- package/dashboard/public/js/sidebar-toggle.js +20 -20
- package/dashboard/src/app.js +78 -78
- package/dashboard/src/middleware/errorHandler.js +52 -52
- package/dashboard/src/middleware/notFoundHandler.js +9 -9
- package/dashboard/src/repositories/planning.repository.js +128 -128
- package/dashboard/src/routes/events.routes.js +40 -40
- package/dashboard/src/routes/index.routes.js +31 -31
- package/dashboard/src/routes/pages.routes.js +245 -195
- package/dashboard/src/server.js +42 -42
- package/dashboard/src/services/dashboard.service.js +222 -222
- package/dashboard/src/services/phase.service.js +220 -167
- package/dashboard/src/services/project.service.js +57 -57
- package/dashboard/src/services/roadmap.service.js +171 -171
- package/dashboard/src/services/sse.service.js +58 -58
- package/dashboard/src/services/todo.service.js +254 -254
- package/dashboard/src/services/watcher.service.js +48 -48
- package/dashboard/src/views/coming-soon.ejs +11 -11
- package/dashboard/src/views/error.ejs +13 -13
- package/dashboard/src/views/index.ejs +5 -5
- package/dashboard/src/views/layout.ejs +1 -1
- package/dashboard/src/views/partials/dashboard-content.ejs +77 -77
- package/dashboard/src/views/partials/footer.ejs +3 -3
- package/dashboard/src/views/partials/head.ejs +21 -21
- package/dashboard/src/views/partials/header.ejs +12 -12
- package/dashboard/src/views/partials/layout-bottom.ejs +15 -15
- package/dashboard/src/views/partials/layout-top.ejs +8 -8
- package/dashboard/src/views/partials/phase-content.ejs +188 -181
- package/dashboard/src/views/partials/phase-doc-content.ejs +38 -0
- package/dashboard/src/views/partials/phases-content.ejs +117 -117
- package/dashboard/src/views/partials/roadmap-content.ejs +142 -142
- package/dashboard/src/views/partials/sidebar.ejs +38 -38
- package/dashboard/src/views/partials/todo-create-content.ejs +53 -53
- package/dashboard/src/views/partials/todo-detail-content.ejs +38 -38
- package/dashboard/src/views/partials/todos-content.ejs +53 -53
- package/dashboard/src/views/phase-detail.ejs +5 -5
- package/dashboard/src/views/phase-doc.ejs +5 -0
- package/dashboard/src/views/phases.ejs +5 -5
- package/dashboard/src/views/roadmap.ejs +5 -5
- package/dashboard/src/views/todo-create.ejs +5 -5
- package/dashboard/src/views/todo-detail.ejs +5 -5
- package/dashboard/src/views/todos.ejs +5 -5
- package/package.json +57 -57
- package/plugins/pbr/.claude-plugin/plugin.json +13 -13
- package/plugins/pbr/UI-CONSISTENCY-GAPS.md +61 -61
- package/plugins/pbr/agents/codebase-mapper.md +279 -271
- package/plugins/pbr/agents/debugger.md +281 -281
- package/plugins/pbr/agents/executor.md +428 -407
- package/plugins/pbr/agents/general.md +164 -164
- package/plugins/pbr/agents/integration-checker.md +169 -141
- package/plugins/pbr/agents/plan-checker.md +296 -280
- package/plugins/pbr/agents/planner.md +358 -358
- package/plugins/pbr/agents/researcher.md +363 -363
- package/plugins/pbr/agents/synthesizer.md +230 -230
- package/plugins/pbr/agents/verifier.md +489 -454
- package/plugins/pbr/commands/begin.md +5 -5
- package/plugins/pbr/commands/build.md +5 -5
- package/plugins/pbr/commands/config.md +5 -5
- package/plugins/pbr/commands/continue.md +5 -5
- package/plugins/pbr/commands/debug.md +5 -5
- package/plugins/pbr/commands/discuss.md +5 -5
- package/plugins/pbr/commands/explore.md +5 -5
- package/plugins/pbr/commands/health.md +5 -5
- package/plugins/pbr/commands/help.md +5 -5
- package/plugins/pbr/commands/import.md +5 -5
- package/plugins/pbr/commands/milestone.md +5 -5
- package/plugins/pbr/commands/note.md +5 -5
- package/plugins/pbr/commands/pause.md +5 -5
- package/plugins/pbr/commands/plan.md +5 -5
- package/plugins/pbr/commands/quick.md +5 -5
- package/plugins/pbr/commands/resume.md +5 -5
- package/plugins/pbr/commands/review.md +5 -5
- package/plugins/pbr/commands/scan.md +5 -5
- package/plugins/pbr/commands/setup.md +5 -5
- package/plugins/pbr/commands/status.md +5 -5
- package/plugins/pbr/commands/todo.md +5 -5
- package/plugins/pbr/contexts/dev.md +27 -27
- package/plugins/pbr/contexts/research.md +28 -28
- package/plugins/pbr/contexts/review.md +36 -36
- package/plugins/pbr/hooks/hooks.json +183 -183
- package/plugins/pbr/references/agent-anti-patterns.md +24 -24
- package/plugins/pbr/references/agent-interactions.md +134 -134
- package/plugins/pbr/references/agent-teams.md +54 -54
- package/plugins/pbr/references/checkpoints.md +157 -157
- package/plugins/pbr/references/common-bug-patterns.md +13 -13
- package/plugins/pbr/references/config-reference.md +441 -0
- package/plugins/pbr/references/continuation-format.md +212 -212
- package/plugins/pbr/references/deviation-rules.md +112 -112
- package/plugins/pbr/references/git-integration.md +226 -226
- package/plugins/pbr/references/integration-patterns.md +117 -117
- package/plugins/pbr/references/model-profiles.md +99 -99
- package/plugins/pbr/references/model-selection.md +31 -31
- package/plugins/pbr/references/pbr-rules.md +193 -193
- package/plugins/pbr/references/plan-authoring.md +181 -181
- package/plugins/pbr/references/plan-format.md +287 -283
- package/plugins/pbr/references/planning-config.md +213 -213
- package/plugins/pbr/references/questioning.md +214 -214
- package/plugins/pbr/references/reading-verification.md +127 -127
- package/plugins/pbr/references/stub-patterns.md +160 -160
- package/plugins/pbr/references/subagent-coordination.md +119 -119
- package/plugins/pbr/references/ui-formatting.md +461 -399
- package/plugins/pbr/references/verification-patterns.md +198 -198
- package/plugins/pbr/references/wave-execution.md +95 -95
- package/plugins/pbr/scripts/auto-continue.js +80 -80
- package/plugins/pbr/scripts/check-dangerous-commands.js +136 -136
- package/plugins/pbr/scripts/check-doc-sprawl.js +102 -102
- package/plugins/pbr/scripts/check-phase-boundary.js +196 -196
- package/plugins/pbr/scripts/check-plan-format.js +270 -270
- package/plugins/pbr/scripts/check-roadmap-sync.js +322 -252
- package/plugins/pbr/scripts/check-skill-workflow.js +262 -262
- package/plugins/pbr/scripts/check-state-sync.js +476 -476
- package/plugins/pbr/scripts/check-subagent-output.js +144 -144
- package/plugins/pbr/scripts/config-schema.json +251 -251
- package/plugins/pbr/scripts/context-budget-check.js +287 -287
- package/plugins/pbr/scripts/event-handler.js +151 -151
- package/plugins/pbr/scripts/event-logger.js +92 -92
- package/plugins/pbr/scripts/hook-logger.js +80 -76
- package/plugins/pbr/scripts/hooks-schema.json +79 -79
- package/plugins/pbr/scripts/log-subagent.js +164 -152
- package/plugins/pbr/scripts/log-tool-failure.js +88 -88
- package/plugins/pbr/scripts/pbr-tools.js +1378 -1301
- package/plugins/pbr/scripts/post-write-dispatch.js +66 -66
- package/plugins/pbr/scripts/post-write-quality.js +207 -207
- package/plugins/pbr/scripts/pre-bash-dispatch.js +86 -56
- package/plugins/pbr/scripts/pre-write-dispatch.js +97 -62
- package/plugins/pbr/scripts/progress-tracker.js +281 -228
- package/plugins/pbr/scripts/run-hook.js +92 -0
- package/plugins/pbr/scripts/session-cleanup.js +254 -254
- package/plugins/pbr/scripts/status-line.js +288 -285
- package/plugins/pbr/scripts/suggest-compact.js +119 -119
- package/plugins/pbr/scripts/task-completed.js +45 -45
- package/plugins/pbr/scripts/track-context-budget.js +149 -119
- package/plugins/pbr/scripts/validate-commit.js +200 -200
- package/plugins/pbr/scripts/validate-plugin-structure.js +183 -172
- package/plugins/pbr/scripts/validate-task.js +106 -0
- package/plugins/pbr/skills/begin/SKILL.md +594 -545
- package/plugins/pbr/skills/begin/templates/PROJECT.md.tmpl +33 -33
- package/plugins/pbr/skills/begin/templates/REQUIREMENTS.md.tmpl +18 -18
- package/plugins/pbr/skills/begin/templates/STATE.md.tmpl +49 -49
- package/plugins/pbr/skills/begin/templates/config.json.tmpl +64 -63
- package/plugins/pbr/skills/begin/templates/researcher-prompt.md.tmpl +19 -19
- package/plugins/pbr/skills/begin/templates/roadmap-prompt.md.tmpl +30 -30
- package/plugins/pbr/skills/begin/templates/synthesis-prompt.md.tmpl +16 -16
- package/plugins/pbr/skills/build/SKILL.md +943 -962
- package/plugins/pbr/skills/config/SKILL.md +256 -241
- package/plugins/pbr/skills/continue/SKILL.md +164 -127
- package/plugins/pbr/skills/debug/SKILL.md +515 -489
- package/plugins/pbr/skills/debug/templates/continuation-prompt.md.tmpl +16 -16
- package/plugins/pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +27 -27
- package/plugins/pbr/skills/discuss/SKILL.md +347 -338
- package/plugins/pbr/skills/discuss/templates/CONTEXT.md.tmpl +61 -61
- package/plugins/pbr/skills/discuss/templates/decision-categories.md +9 -9
- package/plugins/pbr/skills/explore/SKILL.md +378 -362
- package/plugins/pbr/skills/health/SKILL.md +221 -186
- package/plugins/pbr/skills/health/templates/check-pattern.md.tmpl +30 -30
- package/plugins/pbr/skills/health/templates/output-format.md.tmpl +63 -63
- package/plugins/pbr/skills/help/SKILL.md +155 -140
- package/plugins/pbr/skills/import/SKILL.md +504 -490
- package/plugins/pbr/skills/milestone/SKILL.md +704 -673
- package/plugins/pbr/skills/milestone/templates/audit-report.md.tmpl +48 -48
- package/plugins/pbr/skills/milestone/templates/stats-file.md.tmpl +30 -30
- package/plugins/pbr/skills/note/SKILL.md +231 -212
- package/plugins/pbr/skills/pause/SKILL.md +249 -235
- package/plugins/pbr/skills/pause/templates/continue-here.md.tmpl +71 -71
- package/plugins/pbr/skills/plan/SKILL.md +685 -628
- package/plugins/pbr/skills/plan/decimal-phase-calc.md +98 -98
- package/plugins/pbr/skills/plan/templates/checker-prompt.md.tmpl +21 -21
- package/plugins/pbr/skills/plan/templates/gap-closure-prompt.md.tmpl +32 -32
- package/plugins/pbr/skills/plan/templates/planner-prompt.md.tmpl +38 -38
- package/plugins/pbr/skills/plan/templates/researcher-prompt.md.tmpl +19 -19
- package/plugins/pbr/skills/plan/templates/revision-prompt.md.tmpl +23 -23
- package/plugins/pbr/skills/quick/SKILL.md +354 -335
- package/plugins/pbr/skills/resume/SKILL.md +402 -388
- package/plugins/pbr/skills/review/SKILL.md +686 -652
- package/plugins/pbr/skills/review/templates/debugger-prompt.md.tmpl +60 -60
- package/plugins/pbr/skills/review/templates/gap-planner-prompt.md.tmpl +40 -40
- package/plugins/pbr/skills/review/templates/verifier-prompt.md.tmpl +115 -115
- package/plugins/pbr/skills/scan/SKILL.md +304 -269
- package/plugins/pbr/skills/scan/templates/mapper-prompt.md.tmpl +201 -201
- package/plugins/pbr/skills/setup/SKILL.md +253 -227
- package/plugins/pbr/skills/shared/commit-planning-docs.md +35 -35
- package/plugins/pbr/skills/shared/config-loading.md +102 -102
- package/plugins/pbr/skills/shared/context-budget.md +40 -40
- package/plugins/pbr/skills/shared/context-loader-task.md +86 -86
- package/plugins/pbr/skills/shared/digest-select.md +79 -79
- package/plugins/pbr/skills/shared/domain-probes.md +125 -125
- package/plugins/pbr/skills/shared/error-reporting.md +79 -79
- package/plugins/pbr/skills/shared/gate-prompts.md +388 -388
- package/plugins/pbr/skills/shared/phase-argument-parsing.md +45 -45
- package/plugins/pbr/skills/shared/progress-display.md +53 -53
- package/plugins/pbr/skills/shared/revision-loop.md +81 -81
- package/plugins/pbr/skills/shared/state-loading.md +62 -62
- package/plugins/pbr/skills/shared/state-update.md +161 -161
- package/plugins/pbr/skills/shared/universal-anti-patterns.md +33 -33
- package/plugins/pbr/skills/status/SKILL.md +367 -353
- package/plugins/pbr/skills/todo/SKILL.md +198 -181
- package/plugins/pbr/templates/CONTEXT.md.tmpl +52 -52
- package/plugins/pbr/templates/INTEGRATION-REPORT.md.tmpl +151 -151
- package/plugins/pbr/templates/RESEARCH-SUMMARY.md.tmpl +97 -97
- package/plugins/pbr/templates/ROADMAP.md.tmpl +40 -40
- package/plugins/pbr/templates/SUMMARY.md.tmpl +81 -81
- package/plugins/pbr/templates/VERIFICATION-DETAIL.md.tmpl +116 -116
- package/plugins/pbr/templates/codebase/ARCHITECTURE.md.tmpl +98 -98
- package/plugins/pbr/templates/codebase/CONCERNS.md.tmpl +93 -93
- package/plugins/pbr/templates/codebase/CONVENTIONS.md.tmpl +104 -104
- package/plugins/pbr/templates/codebase/INTEGRATIONS.md.tmpl +78 -78
- package/plugins/pbr/templates/codebase/STACK.md.tmpl +78 -78
- package/plugins/pbr/templates/codebase/STRUCTURE.md.tmpl +80 -80
- package/plugins/pbr/templates/codebase/TESTING.md.tmpl +107 -107
- package/plugins/pbr/templates/continue-here.md.tmpl +73 -73
- package/plugins/pbr/templates/prompt-partials/phase-project-context.md.tmpl +37 -37
- package/plugins/pbr/templates/research/ARCHITECTURE.md.tmpl +124 -124
- package/plugins/pbr/templates/research/STACK.md.tmpl +71 -71
- package/plugins/pbr/templates/research/SUMMARY.md.tmpl +112 -112
- package/plugins/pbr/templates/research-outputs/phase-research.md.tmpl +81 -81
- package/plugins/pbr/templates/research-outputs/project-research.md.tmpl +99 -99
- package/plugins/pbr/templates/research-outputs/synthesis.md.tmpl +36 -36
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
-
"title": "Plan-Build-Run Hooks",
|
|
4
|
-
"description": "Schema for Claude Code hooks.json configuration",
|
|
5
|
-
"type": "object",
|
|
6
|
-
"properties": {
|
|
7
|
-
"$schema": { "type": "string" },
|
|
8
|
-
"description": { "type": "string" },
|
|
9
|
-
"hooks": {
|
|
10
|
-
"type": "object",
|
|
11
|
-
"properties": {
|
|
12
|
-
"SessionStart": { "$ref": "#/definitions/hookEntryList" },
|
|
13
|
-
"PreToolUse": { "$ref": "#/definitions/hookEntryList" },
|
|
14
|
-
"PostToolUse": { "$ref": "#/definitions/hookEntryList" },
|
|
15
|
-
"PostToolUseFailure": { "$ref": "#/definitions/hookEntryList" },
|
|
16
|
-
"PreCompact": { "$ref": "#/definitions/hookEntryList" },
|
|
17
|
-
"Stop": { "$ref": "#/definitions/hookEntryList" },
|
|
18
|
-
"SubagentStart": { "$ref": "#/definitions/hookEntryList" },
|
|
19
|
-
"SubagentStop": { "$ref": "#/definitions/hookEntryList" },
|
|
20
|
-
"TaskCompleted": { "$ref": "#/definitions/hookEntryList" },
|
|
21
|
-
"SessionEnd": { "$ref": "#/definitions/hookEntryList" }
|
|
22
|
-
},
|
|
23
|
-
"additionalProperties": false
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"required": ["hooks"],
|
|
27
|
-
"additionalProperties": true,
|
|
28
|
-
"definitions": {
|
|
29
|
-
"hookEntryList": {
|
|
30
|
-
"type": "array",
|
|
31
|
-
"items": { "$ref": "#/definitions/hookEntry" }
|
|
32
|
-
},
|
|
33
|
-
"hookEntry": {
|
|
34
|
-
"type": "object",
|
|
35
|
-
"properties": {
|
|
36
|
-
"matcher": {
|
|
37
|
-
"type": "string",
|
|
38
|
-
"description": "Regex tested against the tool name (e.g. 'Write|Edit', 'Bash', 'Task')"
|
|
39
|
-
},
|
|
40
|
-
"hooks": {
|
|
41
|
-
"type": "array",
|
|
42
|
-
"items": { "$ref": "#/definitions/hookCommand" }
|
|
43
|
-
}
|
|
44
|
-
},
|
|
45
|
-
"required": ["hooks"],
|
|
46
|
-
"additionalProperties": false
|
|
47
|
-
},
|
|
48
|
-
"hookCommand": {
|
|
49
|
-
"type": "object",
|
|
50
|
-
"properties": {
|
|
51
|
-
"type": {
|
|
52
|
-
"type": "string",
|
|
53
|
-
"enum": ["command"],
|
|
54
|
-
"description": "Hook type — currently only 'command' is supported"
|
|
55
|
-
},
|
|
56
|
-
"command": {
|
|
57
|
-
"type": "string",
|
|
58
|
-
"description": "Shell command to execute (use ${CLAUDE_PLUGIN_ROOT} for script paths)"
|
|
59
|
-
},
|
|
60
|
-
"statusMessage": {
|
|
61
|
-
"type": "string",
|
|
62
|
-
"description": "Status message shown in Claude Code UI while hook runs"
|
|
63
|
-
},
|
|
64
|
-
"async": {
|
|
65
|
-
"type": "boolean",
|
|
66
|
-
"description": "Run in background without blocking (stdout not captured)",
|
|
67
|
-
"default": false
|
|
68
|
-
},
|
|
69
|
-
"timeout": {
|
|
70
|
-
"type": "number",
|
|
71
|
-
"minimum": 1,
|
|
72
|
-
"description": "Maximum seconds before hook is killed (required when async: true)"
|
|
73
|
-
}
|
|
74
|
-
},
|
|
75
|
-
"required": ["type", "command"],
|
|
76
|
-
"additionalProperties": false
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "Plan-Build-Run Hooks",
|
|
4
|
+
"description": "Schema for Claude Code hooks.json configuration",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"$schema": { "type": "string" },
|
|
8
|
+
"description": { "type": "string" },
|
|
9
|
+
"hooks": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"SessionStart": { "$ref": "#/definitions/hookEntryList" },
|
|
13
|
+
"PreToolUse": { "$ref": "#/definitions/hookEntryList" },
|
|
14
|
+
"PostToolUse": { "$ref": "#/definitions/hookEntryList" },
|
|
15
|
+
"PostToolUseFailure": { "$ref": "#/definitions/hookEntryList" },
|
|
16
|
+
"PreCompact": { "$ref": "#/definitions/hookEntryList" },
|
|
17
|
+
"Stop": { "$ref": "#/definitions/hookEntryList" },
|
|
18
|
+
"SubagentStart": { "$ref": "#/definitions/hookEntryList" },
|
|
19
|
+
"SubagentStop": { "$ref": "#/definitions/hookEntryList" },
|
|
20
|
+
"TaskCompleted": { "$ref": "#/definitions/hookEntryList" },
|
|
21
|
+
"SessionEnd": { "$ref": "#/definitions/hookEntryList" }
|
|
22
|
+
},
|
|
23
|
+
"additionalProperties": false
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"required": ["hooks"],
|
|
27
|
+
"additionalProperties": true,
|
|
28
|
+
"definitions": {
|
|
29
|
+
"hookEntryList": {
|
|
30
|
+
"type": "array",
|
|
31
|
+
"items": { "$ref": "#/definitions/hookEntry" }
|
|
32
|
+
},
|
|
33
|
+
"hookEntry": {
|
|
34
|
+
"type": "object",
|
|
35
|
+
"properties": {
|
|
36
|
+
"matcher": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"description": "Regex tested against the tool name (e.g. 'Write|Edit', 'Bash', 'Task')"
|
|
39
|
+
},
|
|
40
|
+
"hooks": {
|
|
41
|
+
"type": "array",
|
|
42
|
+
"items": { "$ref": "#/definitions/hookCommand" }
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"required": ["hooks"],
|
|
46
|
+
"additionalProperties": false
|
|
47
|
+
},
|
|
48
|
+
"hookCommand": {
|
|
49
|
+
"type": "object",
|
|
50
|
+
"properties": {
|
|
51
|
+
"type": {
|
|
52
|
+
"type": "string",
|
|
53
|
+
"enum": ["command"],
|
|
54
|
+
"description": "Hook type — currently only 'command' is supported"
|
|
55
|
+
},
|
|
56
|
+
"command": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"description": "Shell command to execute (use ${CLAUDE_PLUGIN_ROOT} for script paths)"
|
|
59
|
+
},
|
|
60
|
+
"statusMessage": {
|
|
61
|
+
"type": "string",
|
|
62
|
+
"description": "Status message shown in Claude Code UI while hook runs"
|
|
63
|
+
},
|
|
64
|
+
"async": {
|
|
65
|
+
"type": "boolean",
|
|
66
|
+
"description": "Run in background without blocking (stdout not captured)",
|
|
67
|
+
"default": false
|
|
68
|
+
},
|
|
69
|
+
"timeout": {
|
|
70
|
+
"type": "number",
|
|
71
|
+
"minimum": 1,
|
|
72
|
+
"description": "Maximum seconds before hook is killed (required when async: true)"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"required": ["type", "command"],
|
|
76
|
+
"additionalProperties": false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
@@ -1,152 +1,164 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* SubagentStart / SubagentStop logging hook.
|
|
5
|
-
*
|
|
6
|
-
* Usage:
|
|
7
|
-
* node log-subagent.js start — called on SubagentStart
|
|
8
|
-
* node log-subagent.js stop — called on SubagentStop
|
|
9
|
-
*
|
|
10
|
-
* On start: logs spawn event and injects project context via additionalContext.
|
|
11
|
-
* On stop: logs completion event.
|
|
12
|
-
*
|
|
13
|
-
* Non-blocking — exits 0 always.
|
|
14
|
-
*/
|
|
15
|
-
|
|
16
|
-
const fs = require('fs');
|
|
17
|
-
const path = require('path');
|
|
18
|
-
const { logHook } = require('./hook-logger');
|
|
19
|
-
const { logEvent } = require('./event-logger');
|
|
20
|
-
const { configLoad } = require('./pbr-tools');
|
|
21
|
-
|
|
22
|
-
function readStdin() {
|
|
23
|
-
try {
|
|
24
|
-
const input = fs.readFileSync(0, 'utf8').trim();
|
|
25
|
-
if (input) return JSON.parse(input);
|
|
26
|
-
} catch (_e) {
|
|
27
|
-
// empty or non-JSON stdin
|
|
28
|
-
}
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
//
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
function
|
|
93
|
-
try {
|
|
94
|
-
const cwd = process.cwd();
|
|
95
|
-
const filePath = path.join(cwd, '.planning', '.active-agent');
|
|
96
|
-
if (fs.existsSync(
|
|
97
|
-
fs.
|
|
98
|
-
}
|
|
99
|
-
} catch (_e) {
|
|
100
|
-
// Best-effort
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
if (
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SubagentStart / SubagentStop logging hook.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* node log-subagent.js start — called on SubagentStart
|
|
8
|
+
* node log-subagent.js stop — called on SubagentStop
|
|
9
|
+
*
|
|
10
|
+
* On start: logs spawn event and injects project context via additionalContext.
|
|
11
|
+
* On stop: logs completion event.
|
|
12
|
+
*
|
|
13
|
+
* Non-blocking — exits 0 always.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const fs = require('fs');
|
|
17
|
+
const path = require('path');
|
|
18
|
+
const { logHook } = require('./hook-logger');
|
|
19
|
+
const { logEvent } = require('./event-logger');
|
|
20
|
+
const { configLoad } = require('./pbr-tools');
|
|
21
|
+
|
|
22
|
+
function readStdin() {
|
|
23
|
+
try {
|
|
24
|
+
const input = fs.readFileSync(0, 'utf8').trim();
|
|
25
|
+
if (input) return JSON.parse(input);
|
|
26
|
+
} catch (_e) {
|
|
27
|
+
// empty or non-JSON stdin
|
|
28
|
+
}
|
|
29
|
+
return {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Extract agent type from hook data, checking multiple possible field locations.
|
|
34
|
+
* Returns the first non-empty value found, or null if no type info is available.
|
|
35
|
+
*/
|
|
36
|
+
function resolveAgentType(data) {
|
|
37
|
+
return data.agent_type
|
|
38
|
+
|| data.subagent_type
|
|
39
|
+
|| (data.tool_input && (data.tool_input.subagent_type || data.tool_input.agent_type))
|
|
40
|
+
|| null;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function main() {
|
|
44
|
+
const action = process.argv[2]; // 'start' or 'stop'
|
|
45
|
+
const data = readStdin();
|
|
46
|
+
const agentType = resolveAgentType(data);
|
|
47
|
+
|
|
48
|
+
if (action === 'start') {
|
|
49
|
+
logHook('log-subagent', 'SubagentStart', 'spawned', {
|
|
50
|
+
agent_id: data.agent_id || null,
|
|
51
|
+
agent_type: agentType,
|
|
52
|
+
description: data.description || null
|
|
53
|
+
});
|
|
54
|
+
logEvent('agent', 'spawn', {
|
|
55
|
+
agent_id: data.agent_id || null,
|
|
56
|
+
agent_type: agentType,
|
|
57
|
+
description: data.description || null
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// Write .active-agent signal so other hooks know a subagent is running
|
|
61
|
+
writeActiveAgent(agentType || 'unknown');
|
|
62
|
+
|
|
63
|
+
// Inject project context into subagent
|
|
64
|
+
const context = buildAgentContext();
|
|
65
|
+
if (context) {
|
|
66
|
+
const output = {
|
|
67
|
+
hookSpecificOutput: {
|
|
68
|
+
hookEventName: 'SubagentStart',
|
|
69
|
+
additionalContext: context
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
process.stdout.write(JSON.stringify(output));
|
|
73
|
+
}
|
|
74
|
+
} else if (action === 'stop') {
|
|
75
|
+
// Remove .active-agent signal
|
|
76
|
+
removeActiveAgent();
|
|
77
|
+
logHook('log-subagent', 'SubagentStop', 'completed', {
|
|
78
|
+
agent_id: data.agent_id || null,
|
|
79
|
+
agent_type: agentType,
|
|
80
|
+
duration_ms: data.duration_ms || null
|
|
81
|
+
});
|
|
82
|
+
logEvent('agent', 'complete', {
|
|
83
|
+
agent_id: data.agent_id || null,
|
|
84
|
+
agent_type: agentType,
|
|
85
|
+
duration_ms: data.duration_ms || null
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
process.exit(0);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function writeActiveAgent(agentType) {
|
|
93
|
+
try {
|
|
94
|
+
const cwd = process.cwd();
|
|
95
|
+
const filePath = path.join(cwd, '.planning', '.active-agent');
|
|
96
|
+
if (fs.existsSync(path.join(cwd, '.planning'))) {
|
|
97
|
+
fs.writeFileSync(filePath, agentType, 'utf8');
|
|
98
|
+
}
|
|
99
|
+
} catch (_e) {
|
|
100
|
+
// Best-effort
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function removeActiveAgent() {
|
|
105
|
+
try {
|
|
106
|
+
const cwd = process.cwd();
|
|
107
|
+
const filePath = path.join(cwd, '.planning', '.active-agent');
|
|
108
|
+
if (fs.existsSync(filePath)) {
|
|
109
|
+
fs.unlinkSync(filePath);
|
|
110
|
+
}
|
|
111
|
+
} catch (_e) {
|
|
112
|
+
// Best-effort
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function buildAgentContext() {
|
|
117
|
+
const cwd = process.cwd();
|
|
118
|
+
const planningDir = path.join(cwd, '.planning');
|
|
119
|
+
|
|
120
|
+
if (!fs.existsSync(planningDir)) return '';
|
|
121
|
+
|
|
122
|
+
const parts = [];
|
|
123
|
+
|
|
124
|
+
// Current phase and status from STATE.md
|
|
125
|
+
const stateFile = path.join(planningDir, 'STATE.md');
|
|
126
|
+
if (fs.existsSync(stateFile)) {
|
|
127
|
+
try {
|
|
128
|
+
const state = fs.readFileSync(stateFile, 'utf8');
|
|
129
|
+
const phaseMatch = state.match(/Phase:\s*(\d+)\s+of\s+(\d+)/);
|
|
130
|
+
const statusMatch = state.match(/\*{0,2}(?:Phase\s+)?Status\*{0,2}:\s*["']?(\w+)["']?/i);
|
|
131
|
+
if (phaseMatch) {
|
|
132
|
+
parts.push(`Phase ${phaseMatch[1]} of ${phaseMatch[2]}${statusMatch ? ' (' + statusMatch[1] + ')' : ''}`);
|
|
133
|
+
}
|
|
134
|
+
} catch (_e) {
|
|
135
|
+
// skip
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// Active skill context
|
|
140
|
+
const activeSkillFile = path.join(planningDir, '.active-skill');
|
|
141
|
+
if (fs.existsSync(activeSkillFile)) {
|
|
142
|
+
try {
|
|
143
|
+
const skill = fs.readFileSync(activeSkillFile, 'utf8').trim();
|
|
144
|
+
if (skill) parts.push(`Active skill: /pbr:${skill}`);
|
|
145
|
+
} catch (_e) {
|
|
146
|
+
// skip
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Config highlights
|
|
151
|
+
const config = configLoad(planningDir);
|
|
152
|
+
if (config) {
|
|
153
|
+
const configParts = [];
|
|
154
|
+
if (config.depth) configParts.push(`depth=${config.depth}`);
|
|
155
|
+
if (config.git && config.git.auto_commit !== undefined) configParts.push(`auto_commit=${config.git.auto_commit}`);
|
|
156
|
+
if (configParts.length > 0) parts.push(`Config: ${configParts.join(', ')}`);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (parts.length === 0) return '';
|
|
160
|
+
return '[Plan-Build-Run Project Context] ' + parts.join(' | ');
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
module.exports = { buildAgentContext, resolveAgentType };
|
|
164
|
+
if (require.main === module) { main(); }
|
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* PostToolUseFailure hook: Logs tool failures to events.jsonl
|
|
5
|
-
* and provides recovery hints via additionalContext.
|
|
6
|
-
*
|
|
7
|
-
* Fires when any tool execution fails. Captures tool name, error,
|
|
8
|
-
* and session context for debugging.
|
|
9
|
-
*
|
|
10
|
-
* Exit codes:
|
|
11
|
-
* 0 = always (informational hook, never blocks)
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
const { logHook } = require('./hook-logger');
|
|
15
|
-
const { logEvent } = require('./event-logger');
|
|
16
|
-
|
|
17
|
-
function readStdin() {
|
|
18
|
-
return new Promise((resolve) => {
|
|
19
|
-
let input = '';
|
|
20
|
-
process.stdin.setEncoding('utf8');
|
|
21
|
-
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
22
|
-
process.stdin.on('end', () => {
|
|
23
|
-
try {
|
|
24
|
-
resolve(JSON.parse(input));
|
|
25
|
-
} catch (_e) {
|
|
26
|
-
resolve({});
|
|
27
|
-
}
|
|
28
|
-
});
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
async function main() {
|
|
33
|
-
const data = await readStdin();
|
|
34
|
-
|
|
35
|
-
const toolName = data.tool_name || 'unknown';
|
|
36
|
-
const error = data.error || 'unknown error';
|
|
37
|
-
const isInterrupt = data.is_interrupt || false;
|
|
38
|
-
const toolInput = data.tool_input || {};
|
|
39
|
-
|
|
40
|
-
// Log to hooks.jsonl
|
|
41
|
-
logHook('log-tool-failure', 'PostToolUseFailure', 'logged', {
|
|
42
|
-
tool: toolName,
|
|
43
|
-
error: typeof error === 'string' ? error.substring(0, 200) : JSON.stringify(error).substring(0, 200),
|
|
44
|
-
interrupt: isInterrupt
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Log to events.jsonl with more detail
|
|
48
|
-
logEvent('tool', 'failure', {
|
|
49
|
-
tool: toolName,
|
|
50
|
-
error: typeof error === 'string' ? error.substring(0, 500) : JSON.stringify(error).substring(0, 500),
|
|
51
|
-
interrupt: isInterrupt,
|
|
52
|
-
input_summary: summarizeInput(toolName, toolInput)
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// Provide recovery hints for Bash failures (most common actionable failure)
|
|
56
|
-
if (toolName === 'Bash' && !isInterrupt) {
|
|
57
|
-
const output = {
|
|
58
|
-
hookSpecificOutput: {
|
|
59
|
-
hookEventName: 'PostToolUseFailure',
|
|
60
|
-
additionalContext: 'Bash command failed. If this is a recurring issue, consider using /pbr:debug for systematic investigation.'
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
process.stdout.write(JSON.stringify(output));
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
process.exit(0);
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function summarizeInput(toolName, toolInput) {
|
|
70
|
-
switch (toolName) {
|
|
71
|
-
case 'Bash':
|
|
72
|
-
return (toolInput.command || '').substring(0, 100);
|
|
73
|
-
case 'Write':
|
|
74
|
-
case 'Read':
|
|
75
|
-
case 'Edit':
|
|
76
|
-
return toolInput.file_path || '';
|
|
77
|
-
case 'Glob':
|
|
78
|
-
return toolInput.pattern || '';
|
|
79
|
-
case 'Grep':
|
|
80
|
-
return toolInput.pattern || '';
|
|
81
|
-
case 'Task':
|
|
82
|
-
return (toolInput.description || '').substring(0, 100);
|
|
83
|
-
default:
|
|
84
|
-
return '';
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
main();
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* PostToolUseFailure hook: Logs tool failures to events.jsonl
|
|
5
|
+
* and provides recovery hints via additionalContext.
|
|
6
|
+
*
|
|
7
|
+
* Fires when any tool execution fails. Captures tool name, error,
|
|
8
|
+
* and session context for debugging.
|
|
9
|
+
*
|
|
10
|
+
* Exit codes:
|
|
11
|
+
* 0 = always (informational hook, never blocks)
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
const { logHook } = require('./hook-logger');
|
|
15
|
+
const { logEvent } = require('./event-logger');
|
|
16
|
+
|
|
17
|
+
function readStdin() {
|
|
18
|
+
return new Promise((resolve) => {
|
|
19
|
+
let input = '';
|
|
20
|
+
process.stdin.setEncoding('utf8');
|
|
21
|
+
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
22
|
+
process.stdin.on('end', () => {
|
|
23
|
+
try {
|
|
24
|
+
resolve(JSON.parse(input));
|
|
25
|
+
} catch (_e) {
|
|
26
|
+
resolve({});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function main() {
|
|
33
|
+
const data = await readStdin();
|
|
34
|
+
|
|
35
|
+
const toolName = data.tool_name || 'unknown';
|
|
36
|
+
const error = data.error || 'unknown error';
|
|
37
|
+
const isInterrupt = data.is_interrupt || false;
|
|
38
|
+
const toolInput = data.tool_input || {};
|
|
39
|
+
|
|
40
|
+
// Log to hooks.jsonl
|
|
41
|
+
logHook('log-tool-failure', 'PostToolUseFailure', 'logged', {
|
|
42
|
+
tool: toolName,
|
|
43
|
+
error: typeof error === 'string' ? error.substring(0, 200) : JSON.stringify(error).substring(0, 200),
|
|
44
|
+
interrupt: isInterrupt
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
// Log to events.jsonl with more detail
|
|
48
|
+
logEvent('tool', 'failure', {
|
|
49
|
+
tool: toolName,
|
|
50
|
+
error: typeof error === 'string' ? error.substring(0, 500) : JSON.stringify(error).substring(0, 500),
|
|
51
|
+
interrupt: isInterrupt,
|
|
52
|
+
input_summary: summarizeInput(toolName, toolInput)
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
// Provide recovery hints for Bash failures (most common actionable failure)
|
|
56
|
+
if (toolName === 'Bash' && !isInterrupt) {
|
|
57
|
+
const output = {
|
|
58
|
+
hookSpecificOutput: {
|
|
59
|
+
hookEventName: 'PostToolUseFailure',
|
|
60
|
+
additionalContext: 'Bash command failed. If this is a recurring issue, consider using /pbr:debug for systematic investigation.'
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
process.stdout.write(JSON.stringify(output));
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function summarizeInput(toolName, toolInput) {
|
|
70
|
+
switch (toolName) {
|
|
71
|
+
case 'Bash':
|
|
72
|
+
return (toolInput.command || '').substring(0, 100);
|
|
73
|
+
case 'Write':
|
|
74
|
+
case 'Read':
|
|
75
|
+
case 'Edit':
|
|
76
|
+
return toolInput.file_path || '';
|
|
77
|
+
case 'Glob':
|
|
78
|
+
return toolInput.pattern || '';
|
|
79
|
+
case 'Grep':
|
|
80
|
+
return toolInput.pattern || '';
|
|
81
|
+
case 'Task':
|
|
82
|
+
return (toolInput.description || '').substring(0, 100);
|
|
83
|
+
default:
|
|
84
|
+
return '';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
main();
|