@proletariat/cli 0.3.105 → 0.3.110

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.
Files changed (240) hide show
  1. package/dist/commands/agent/cleanup.js +13 -1
  2. package/dist/commands/agent/cleanup.js.map +1 -1
  3. package/dist/commands/claude/index.js +2 -2
  4. package/dist/commands/claude/index.js.map +1 -1
  5. package/dist/commands/feedback/list.js +4 -9
  6. package/dist/commands/feedback/list.js.map +1 -1
  7. package/dist/commands/feedback/submit.js +4 -9
  8. package/dist/commands/feedback/submit.js.map +1 -1
  9. package/dist/commands/feedback/view.js +4 -9
  10. package/dist/commands/feedback/view.js.map +1 -1
  11. package/dist/commands/gc.d.ts +1 -0
  12. package/dist/commands/gc.js +34 -1
  13. package/dist/commands/gc.js.map +1 -1
  14. package/dist/commands/notify/connect.d.ts +34 -0
  15. package/dist/commands/notify/connect.js +166 -0
  16. package/dist/commands/notify/connect.js.map +1 -0
  17. package/dist/commands/notify/disconnect.d.ts +16 -0
  18. package/dist/commands/notify/disconnect.js +45 -0
  19. package/dist/commands/notify/disconnect.js.map +1 -0
  20. package/dist/commands/notify/list.d.ts +15 -0
  21. package/dist/commands/notify/list.js +101 -0
  22. package/dist/commands/notify/list.js.map +1 -0
  23. package/dist/commands/notify/rules/add.d.ts +26 -0
  24. package/dist/commands/notify/rules/add.js +95 -0
  25. package/dist/commands/notify/rules/add.js.map +1 -0
  26. package/dist/commands/notify/rules/list.d.ts +14 -0
  27. package/dist/commands/notify/rules/list.js +82 -0
  28. package/dist/commands/notify/rules/list.js.map +1 -0
  29. package/dist/commands/notify/rules/remove.d.ts +16 -0
  30. package/dist/commands/notify/rules/remove.js +44 -0
  31. package/dist/commands/notify/rules/remove.js.map +1 -0
  32. package/dist/commands/notify/test.d.ts +16 -0
  33. package/dist/commands/notify/test.js +63 -0
  34. package/dist/commands/notify/test.js.map +1 -0
  35. package/dist/commands/orchestrate/index.js +11 -6
  36. package/dist/commands/orchestrate/index.js.map +1 -1
  37. package/dist/commands/orchestrate/machine.d.ts +29 -0
  38. package/dist/commands/orchestrate/machine.js +230 -0
  39. package/dist/commands/orchestrate/machine.js.map +1 -0
  40. package/dist/commands/pr/checks.js +4 -8
  41. package/dist/commands/pr/checks.js.map +1 -1
  42. package/dist/commands/pr/close.js +4 -8
  43. package/dist/commands/pr/close.js.map +1 -1
  44. package/dist/commands/pr/create.js +4 -8
  45. package/dist/commands/pr/create.js.map +1 -1
  46. package/dist/commands/pr/index.js +1 -1
  47. package/dist/commands/pr/index.js.map +1 -1
  48. package/dist/commands/pr/link.js +4 -8
  49. package/dist/commands/pr/link.js.map +1 -1
  50. package/dist/commands/pr/list.js +5 -9
  51. package/dist/commands/pr/list.js.map +1 -1
  52. package/dist/commands/pr/merge.d.ts +5 -0
  53. package/dist/commands/pr/merge.js +35 -11
  54. package/dist/commands/pr/merge.js.map +1 -1
  55. package/dist/commands/pr/status.js +5 -4
  56. package/dist/commands/pr/status.js.map +1 -1
  57. package/dist/commands/qa/index.js +2 -2
  58. package/dist/commands/qa/index.js.map +1 -1
  59. package/dist/commands/repo/create.js +4 -8
  60. package/dist/commands/repo/create.js.map +1 -1
  61. package/dist/commands/session/list.js +81 -41
  62. package/dist/commands/session/list.js.map +1 -1
  63. package/dist/commands/session/poke.d.ts +1 -11
  64. package/dist/commands/session/poke.js +20 -78
  65. package/dist/commands/session/poke.js.map +1 -1
  66. package/dist/commands/session/prune.js +3 -0
  67. package/dist/commands/session/prune.js.map +1 -1
  68. package/dist/commands/ticket/move.d.ts +12 -0
  69. package/dist/commands/ticket/move.js +75 -2
  70. package/dist/commands/ticket/move.js.map +1 -1
  71. package/dist/commands/work/drop.js +2 -2
  72. package/dist/commands/work/drop.js.map +1 -1
  73. package/dist/commands/work/ready.js +3 -3
  74. package/dist/commands/work/ready.js.map +1 -1
  75. package/dist/commands/work/rebase.js +4 -8
  76. package/dist/commands/work/rebase.js.map +1 -1
  77. package/dist/commands/work/run.d.ts +58 -0
  78. package/dist/commands/work/run.js +411 -0
  79. package/dist/commands/work/run.js.map +1 -0
  80. package/dist/commands/work/ship.d.ts +6 -0
  81. package/dist/commands/work/ship.js +93 -51
  82. package/dist/commands/work/ship.js.map +1 -1
  83. package/dist/commands/work/start.d.ts +1 -0
  84. package/dist/commands/work/start.js +126 -13
  85. package/dist/commands/work/start.js.map +1 -1
  86. package/dist/lib/agents/commands.d.ts +6 -0
  87. package/dist/lib/agents/commands.js +55 -2
  88. package/dist/lib/agents/commands.js.map +1 -1
  89. package/dist/lib/database/credential-store.js +2 -3
  90. package/dist/lib/database/credential-store.js.map +1 -1
  91. package/dist/lib/database/db-safety.d.ts +25 -0
  92. package/dist/lib/database/db-safety.js +35 -0
  93. package/dist/lib/database/db-safety.js.map +1 -1
  94. package/dist/lib/database/driver.js +6 -12
  95. package/dist/lib/database/driver.js.map +1 -1
  96. package/dist/lib/database/drizzle-schema.d.ts +3 -3
  97. package/dist/lib/database/drizzle.js +3 -3
  98. package/dist/lib/database/drizzle.js.map +1 -1
  99. package/dist/lib/database/index.d.ts +1 -1
  100. package/dist/lib/database/index.js +1 -1
  101. package/dist/lib/database/index.js.map +1 -1
  102. package/dist/lib/database/migrations/0021_notification_system.d.ts +2 -0
  103. package/dist/lib/database/migrations/0021_notification_system.js +39 -0
  104. package/dist/lib/database/migrations/0021_notification_system.js.map +1 -0
  105. package/dist/lib/database/migrations/0022_hook_mode_tiers.d.ts +11 -0
  106. package/dist/lib/database/migrations/0022_hook_mode_tiers.js +53 -0
  107. package/dist/lib/database/migrations/0022_hook_mode_tiers.js.map +1 -0
  108. package/dist/lib/database/migrations/index.js +4 -0
  109. package/dist/lib/database/migrations/index.js.map +1 -1
  110. package/dist/lib/database/pmo-bootstrap.js +6 -2
  111. package/dist/lib/database/pmo-bootstrap.js.map +1 -1
  112. package/dist/lib/database/workspace.js +5 -13
  113. package/dist/lib/database/workspace.js.map +1 -1
  114. package/dist/lib/events/emitting-runner.js +10 -0
  115. package/dist/lib/events/emitting-runner.js.map +1 -1
  116. package/dist/lib/execution/cc-version.d.ts +62 -0
  117. package/dist/lib/execution/cc-version.js +103 -0
  118. package/dist/lib/execution/cc-version.js.map +1 -0
  119. package/dist/lib/execution/devcontainer.js +2 -1
  120. package/dist/lib/execution/devcontainer.js.map +1 -1
  121. package/dist/lib/execution/runners/devcontainer.js +4 -1
  122. package/dist/lib/execution/runners/devcontainer.js.map +1 -1
  123. package/dist/lib/execution/runners/docker-management.js +10 -46
  124. package/dist/lib/execution/runners/docker-management.js.map +1 -1
  125. package/dist/lib/execution/runners/orchestrator.js +13 -39
  126. package/dist/lib/execution/runners/orchestrator.js.map +1 -1
  127. package/dist/lib/execution/session-utils.d.ts +88 -1
  128. package/dist/lib/execution/session-utils.js +120 -46
  129. package/dist/lib/execution/session-utils.js.map +1 -1
  130. package/dist/lib/execution/storage.js +20 -2
  131. package/dist/lib/execution/storage.js.map +1 -1
  132. package/dist/lib/flags/resolver.d.ts +8 -1
  133. package/dist/lib/flags/resolver.js +35 -2
  134. package/dist/lib/flags/resolver.js.map +1 -1
  135. package/dist/lib/gc/cascade.d.ts +99 -0
  136. package/dist/lib/gc/cascade.js +357 -0
  137. package/dist/lib/gc/cascade.js.map +1 -0
  138. package/dist/lib/gc/config.d.ts +69 -0
  139. package/dist/lib/gc/config.js +134 -0
  140. package/dist/lib/gc/config.js.map +1 -0
  141. package/dist/lib/gc/index.d.ts +36 -0
  142. package/dist/lib/gc/index.js +209 -1
  143. package/dist/lib/gc/index.js.map +1 -1
  144. package/dist/lib/init/index.js +10 -1
  145. package/dist/lib/init/index.js.map +1 -1
  146. package/dist/lib/machine-db.d.ts +144 -0
  147. package/dist/lib/machine-db.js +338 -0
  148. package/dist/lib/machine-db.js.map +1 -0
  149. package/dist/lib/machine-orchestrator.d.ts +35 -0
  150. package/dist/lib/machine-orchestrator.js +139 -0
  151. package/dist/lib/machine-orchestrator.js.map +1 -0
  152. package/dist/lib/notifications/dispatcher.d.ts +29 -0
  153. package/dist/lib/notifications/dispatcher.js +281 -0
  154. package/dist/lib/notifications/dispatcher.js.map +1 -0
  155. package/dist/lib/notifications/index.d.ts +13 -0
  156. package/dist/lib/notifications/index.js +18 -0
  157. package/dist/lib/notifications/index.js.map +1 -0
  158. package/dist/lib/notifications/manager.d.ts +46 -0
  159. package/dist/lib/notifications/manager.js +200 -0
  160. package/dist/lib/notifications/manager.js.map +1 -0
  161. package/dist/lib/notifications/storage.d.ts +60 -0
  162. package/dist/lib/notifications/storage.js +182 -0
  163. package/dist/lib/notifications/storage.js.map +1 -0
  164. package/dist/lib/notifications/types.d.ts +126 -0
  165. package/dist/lib/notifications/types.js +16 -0
  166. package/dist/lib/notifications/types.js.map +1 -0
  167. package/dist/lib/orchestrate/actions.d.ts +8 -0
  168. package/dist/lib/orchestrate/actions.js +339 -88
  169. package/dist/lib/orchestrate/actions.js.map +1 -1
  170. package/dist/lib/orchestrate/config-loader.js +9 -35
  171. package/dist/lib/orchestrate/config-loader.js.map +1 -1
  172. package/dist/lib/orchestrate/engine.d.ts +53 -1
  173. package/dist/lib/orchestrate/engine.js +74 -3
  174. package/dist/lib/orchestrate/engine.js.map +1 -1
  175. package/dist/lib/orchestrate/escalation.d.ts +87 -0
  176. package/dist/lib/orchestrate/escalation.js +63 -0
  177. package/dist/lib/orchestrate/escalation.js.map +1 -0
  178. package/dist/lib/orchestrate/index.d.ts +2 -0
  179. package/dist/lib/orchestrate/index.js +1 -0
  180. package/dist/lib/orchestrate/index.js.map +1 -1
  181. package/dist/lib/orchestrate/llm-agent.d.ts +101 -0
  182. package/dist/lib/orchestrate/llm-agent.js +295 -0
  183. package/dist/lib/orchestrate/llm-agent.js.map +1 -0
  184. package/dist/lib/orchestrate/presets.d.ts +4 -3
  185. package/dist/lib/orchestrate/presets.js +13 -8
  186. package/dist/lib/orchestrate/presets.js.map +1 -1
  187. package/dist/lib/orchestrate/prompt-chain.d.ts +166 -0
  188. package/dist/lib/orchestrate/prompt-chain.js +308 -0
  189. package/dist/lib/orchestrate/prompt-chain.js.map +1 -0
  190. package/dist/lib/orchestrate/types.d.ts +7 -1
  191. package/dist/lib/orchestrate/types.js +1 -0
  192. package/dist/lib/orchestrate/types.js.map +1 -1
  193. package/dist/lib/pmo/base-command.js +1 -1
  194. package/dist/lib/pmo/base-command.js.map +1 -1
  195. package/dist/lib/pmo/find-pmo.d.ts +8 -0
  196. package/dist/lib/pmo/find-pmo.js +63 -2
  197. package/dist/lib/pmo/find-pmo.js.map +1 -1
  198. package/dist/lib/pmo/index.d.ts +1 -1
  199. package/dist/lib/pmo/index.js +1 -1
  200. package/dist/lib/pmo/index.js.map +1 -1
  201. package/dist/lib/pmo/pmo-context.js +1 -1
  202. package/dist/lib/pmo/pmo-context.js.map +1 -1
  203. package/dist/lib/pmo/storage/index.js +2 -1
  204. package/dist/lib/pmo/storage/index.js.map +1 -1
  205. package/dist/lib/pr/index.d.ts +32 -0
  206. package/dist/lib/pr/index.js +45 -0
  207. package/dist/lib/pr/index.js.map +1 -1
  208. package/dist/lib/prompt-command.d.ts +61 -1
  209. package/dist/lib/prompt-command.js +167 -1
  210. package/dist/lib/prompt-command.js.map +1 -1
  211. package/dist/lib/prompt-json.d.ts +129 -2
  212. package/dist/lib/prompt-json.js +157 -0
  213. package/dist/lib/prompt-json.js.map +1 -1
  214. package/dist/lib/registry/index.js +0 -1
  215. package/dist/lib/registry/index.js.map +1 -1
  216. package/dist/lib/runtime-command.d.ts +3 -1
  217. package/dist/lib/runtime-command.js +4 -2
  218. package/dist/lib/runtime-command.js.map +1 -1
  219. package/dist/lib/signal-handler.d.ts +8 -0
  220. package/dist/lib/signal-handler.js +33 -0
  221. package/dist/lib/signal-handler.js.map +1 -1
  222. package/dist/lib/themes.js +8 -1
  223. package/dist/lib/themes.js.map +1 -1
  224. package/dist/lib/work-lifecycle/container-cleanup-hook.d.ts +17 -7
  225. package/dist/lib/work-lifecycle/container-cleanup-hook.js +64 -11
  226. package/dist/lib/work-lifecycle/container-cleanup-hook.js.map +1 -1
  227. package/dist/lib/work-lifecycle/hooks/executor.d.ts +22 -2
  228. package/dist/lib/work-lifecycle/hooks/executor.js +46 -8
  229. package/dist/lib/work-lifecycle/hooks/executor.js.map +1 -1
  230. package/dist/lib/work-lifecycle/hooks/manager.d.ts +62 -3
  231. package/dist/lib/work-lifecycle/hooks/manager.js +285 -4
  232. package/dist/lib/work-lifecycle/hooks/manager.js.map +1 -1
  233. package/dist/lib/work-lifecycle/hooks/types.d.ts +36 -5
  234. package/dist/lib/work-lifecycle/hooks/types.js +1 -1
  235. package/dist/lib/work-lifecycle/hooks/types.js.map +1 -1
  236. package/dist/lib/workspace-resolution.d.ts +73 -0
  237. package/dist/lib/workspace-resolution.js +188 -0
  238. package/dist/lib/workspace-resolution.js.map +1 -0
  239. package/oclif.manifest.json +1787 -1099
  240. package/package.json +1 -1
@@ -0,0 +1,295 @@
1
+ /**
2
+ * LLM Orchestrator Agent (Tier 2)
3
+ *
4
+ * Implements the onLlmDecision callback for the 3-tier supervision tree.
5
+ * When the daemon encounters a hook with mode=llm, this agent:
6
+ *
7
+ * 1. Gathers rich context — PR diff, ticket description, test output
8
+ * 2. Builds a structured decision prompt
9
+ * 3. Calls claude -p (print mode) to get a judgment
10
+ * 4. Parses the response to return approve/deny/escalate
11
+ *
12
+ * This is the bridge between the deterministic daemon (tier 1) and
13
+ * human escalation (tier 3). Without it, tier 2 is a pass-through.
14
+ */
15
+ import { execSync } from 'node:child_process';
16
+ // =============================================================================
17
+ // Constants
18
+ // =============================================================================
19
+ const DEFAULT_MAX_DIFF_CHARS = 8000;
20
+ const DEFAULT_MAX_TEST_OUTPUT_CHARS = 4000;
21
+ const DEFAULT_LLM_CALL_TIMEOUT_MS = 60_000;
22
+ // =============================================================================
23
+ // Context Gathering (pure functions, individually testable)
24
+ // =============================================================================
25
+ /**
26
+ * Fetch the PR diff via `gh pr diff`.
27
+ * Returns undefined if no PR number is available or the command fails.
28
+ */
29
+ export function fetchPrDiff(prNumber, maxChars) {
30
+ if (!prNumber)
31
+ return undefined;
32
+ try {
33
+ const diff = execSync(`gh pr diff ${prNumber} --color=never`, {
34
+ timeout: 15_000,
35
+ stdio: ['pipe', 'pipe', 'pipe'],
36
+ encoding: 'utf-8',
37
+ });
38
+ if (diff.length > maxChars) {
39
+ return diff.slice(0, maxChars) + `\n\n... [diff truncated at ${maxChars} chars, ${diff.length} total]`;
40
+ }
41
+ return diff || undefined;
42
+ }
43
+ catch {
44
+ return undefined;
45
+ }
46
+ }
47
+ /**
48
+ * Fetch the ticket description via `prlt ticket show`.
49
+ * Returns undefined if no ticket ID is available or the command fails.
50
+ */
51
+ export function fetchTicketDescription(ticketId) {
52
+ if (!ticketId)
53
+ return undefined;
54
+ try {
55
+ const output = execSync(`prlt ticket show ${ticketId} --json`, {
56
+ timeout: 10_000,
57
+ stdio: ['pipe', 'pipe', 'pipe'],
58
+ encoding: 'utf-8',
59
+ });
60
+ try {
61
+ const parsed = JSON.parse(output);
62
+ const parts = [];
63
+ if (parsed.result?.title)
64
+ parts.push(`Title: ${parsed.result.title}`);
65
+ if (parsed.result?.description)
66
+ parts.push(`Description: ${parsed.result.description}`);
67
+ if (parsed.result?.acceptanceCriteria?.length) {
68
+ parts.push(`Acceptance Criteria:\n${parsed.result.acceptanceCriteria.map((ac) => ` - ${ac}`).join('\n')}`);
69
+ }
70
+ return parts.length > 0 ? parts.join('\n') : output;
71
+ }
72
+ catch {
73
+ return output || undefined;
74
+ }
75
+ }
76
+ catch {
77
+ return undefined;
78
+ }
79
+ }
80
+ /**
81
+ * Fetch recent CI/test output via `gh pr checks` or `gh run list`.
82
+ * Returns undefined if unavailable.
83
+ */
84
+ export function fetchTestOutput(prNumber, maxChars) {
85
+ if (!prNumber)
86
+ return undefined;
87
+ try {
88
+ const output = execSync(`gh pr checks ${prNumber}`, {
89
+ timeout: 15_000,
90
+ stdio: ['pipe', 'pipe', 'pipe'],
91
+ encoding: 'utf-8',
92
+ });
93
+ if (output.length > maxChars) {
94
+ return output.slice(0, maxChars) + `\n\n... [output truncated at ${maxChars} chars]`;
95
+ }
96
+ return output || undefined;
97
+ }
98
+ catch {
99
+ return undefined;
100
+ }
101
+ }
102
+ /**
103
+ * Gather enriched context from all available sources.
104
+ */
105
+ export function gatherDecisionContext(escalation, options) {
106
+ const prNumber = escalation.ctx.pr;
107
+ const ticketId = escalation.ctx.ticket;
108
+ const branch = escalation.ctx.branch;
109
+ return {
110
+ escalation,
111
+ prDiff: fetchPrDiff(prNumber, options.maxDiffChars),
112
+ ticketDescription: fetchTicketDescription(ticketId),
113
+ testOutput: fetchTestOutput(prNumber, options.maxTestOutputChars),
114
+ branch,
115
+ };
116
+ }
117
+ // =============================================================================
118
+ // Prompt Construction (pure function, testable)
119
+ // =============================================================================
120
+ /**
121
+ * Build the decision prompt for the LLM.
122
+ *
123
+ * The prompt is structured to get a clear approve/deny/escalate response
124
+ * with reasoning.
125
+ */
126
+ export function buildDecisionPrompt(context) {
127
+ const { escalation, prDiff, ticketDescription, testOutput, branch } = context;
128
+ const sections = [];
129
+ sections.push(`# Orchestrator Decision Required
130
+
131
+ You are an autonomous orchestrator agent making a tier-2 decision in a 3-tier supervision tree.
132
+ Your role: review the context and decide whether to APPROVE, DENY, or ESCALATE this action.
133
+
134
+ ## Decision
135
+
136
+ - **Hook:** ${escalation.hookName}
137
+ - **Event:** ${escalation.event}
138
+ - **Action:** ${escalation.action}
139
+ ${branch ? `- **Branch:** ${branch}` : ''}
140
+ ${escalation.config ? `- **Config:** ${JSON.stringify(escalation.config)}` : ''}`);
141
+ if (ticketDescription) {
142
+ sections.push(`## Ticket Context
143
+
144
+ ${ticketDescription}`);
145
+ }
146
+ if (prDiff) {
147
+ sections.push(`## PR Diff
148
+
149
+ \`\`\`diff
150
+ ${prDiff}
151
+ \`\`\``);
152
+ }
153
+ if (testOutput) {
154
+ sections.push(`## CI/Test Status
155
+
156
+ \`\`\`
157
+ ${testOutput}
158
+ \`\`\``);
159
+ }
160
+ sections.push(`## Decision Guidelines
161
+
162
+ Consider these factors:
163
+ 1. **Safety** — Does the action risk data loss, downtime, or breaking changes?
164
+ 2. **Context match** — Does the action align with the event and ticket context?
165
+ 3. **CI status** — Are tests passing? Is the diff reasonable?
166
+ 4. **Scope** — Is the action proportional to the event?
167
+
168
+ ### When to APPROVE
169
+ - CI is green and the action is a natural next step (e.g., merge after green CI)
170
+ - Agent spawn for a ticket that's ready and has clear requirements
171
+ - Respawn of a died agent with retries remaining
172
+
173
+ ### When to DENY
174
+ - CI is failing and the action would advance the pipeline (e.g., merge a failing PR)
175
+ - The diff contains suspicious changes (secrets, large deletions, unrelated files)
176
+ - The action doesn't match the event context
177
+
178
+ ### When to ESCALATE
179
+ - The situation is ambiguous or high-stakes (production deployments, large refactors)
180
+ - You lack sufficient context to make a confident decision
181
+ - The action involves irreversible operations on shared resources
182
+
183
+ ## Response Format
184
+
185
+ Respond with EXACTLY one of these words on the first line, followed by your reasoning:
186
+
187
+ APPROVE
188
+ DENY
189
+ ESCALATE
190
+
191
+ Then explain your reasoning briefly.`);
192
+ return sections.join('\n\n');
193
+ }
194
+ // =============================================================================
195
+ // Response Parsing (pure function, testable)
196
+ // =============================================================================
197
+ /**
198
+ * Parse the LLM response to extract the decision.
199
+ *
200
+ * Looks for APPROVE, DENY, or ESCALATE as the first meaningful word.
201
+ * Falls back to 'escalate' if the response is ambiguous.
202
+ */
203
+ export function parseDecisionResponse(response) {
204
+ const trimmed = response.trim();
205
+ if (!trimmed)
206
+ return 'escalate';
207
+ // Check the first non-empty line for the decision keyword
208
+ const lines = trimmed.split('\n');
209
+ for (const line of lines) {
210
+ const cleaned = line.trim().toUpperCase();
211
+ if (!cleaned)
212
+ continue;
213
+ if (cleaned.startsWith('APPROVE'))
214
+ return 'approve';
215
+ if (cleaned.startsWith('DENY'))
216
+ return 'deny';
217
+ if (cleaned.startsWith('ESCALATE'))
218
+ return 'escalate';
219
+ // Only check the first non-empty line
220
+ break;
221
+ }
222
+ // Fallback: scan the full response for keywords (less reliable)
223
+ const upper = trimmed.toUpperCase();
224
+ if (upper.includes('APPROVE') && !upper.includes('DENY') && !upper.includes('ESCALATE')) {
225
+ return 'approve';
226
+ }
227
+ if (upper.includes('DENY') && !upper.includes('APPROVE') && !upper.includes('ESCALATE')) {
228
+ return 'deny';
229
+ }
230
+ // When in doubt, escalate to human
231
+ return 'escalate';
232
+ }
233
+ // =============================================================================
234
+ // LLM Invocation
235
+ // =============================================================================
236
+ /**
237
+ * Invoke the LLM via `claude -p` (print mode).
238
+ * Returns the raw response text.
239
+ */
240
+ export function invokeClaudeLlm(prompt, timeoutMs) {
241
+ return execSync(`claude -p --output-format text`, {
242
+ input: prompt,
243
+ timeout: timeoutMs,
244
+ stdio: ['pipe', 'pipe', 'pipe'],
245
+ encoding: 'utf-8',
246
+ maxBuffer: 10 * 1024 * 1024,
247
+ });
248
+ }
249
+ // =============================================================================
250
+ // Factory: onLlmDecision callback
251
+ // =============================================================================
252
+ /**
253
+ * Create an onLlmDecision callback for the OrchestrateEngine.
254
+ *
255
+ * This is the main entry point — wire this into the engine to activate tier 2.
256
+ *
257
+ * @example
258
+ * ```ts
259
+ * const engine = new OrchestrateEngine({
260
+ * db,
261
+ * onLlmDecision: createLlmDecisionHandler({ log: console.log }),
262
+ * })
263
+ * ```
264
+ */
265
+ export function createLlmDecisionHandler(options = {}) {
266
+ const log = options.log ?? (() => { });
267
+ const maxDiffChars = options.maxDiffChars ?? DEFAULT_MAX_DIFF_CHARS;
268
+ const maxTestOutputChars = options.maxTestOutputChars ?? DEFAULT_MAX_TEST_OUTPUT_CHARS;
269
+ const llmCallTimeoutMs = options.llmCallTimeoutMs ?? DEFAULT_LLM_CALL_TIMEOUT_MS;
270
+ const callLlm = options.invokeLlm ?? ((prompt) => invokeClaudeLlm(prompt, llmCallTimeoutMs));
271
+ return async (context) => {
272
+ log(`[llm-agent] Decision requested: ${context.hookName} → ${context.action} (event: ${context.event})`);
273
+ try {
274
+ // 1. Gather enriched context
275
+ const enriched = gatherDecisionContext(context, { maxDiffChars, maxTestOutputChars });
276
+ // 2. Build the prompt
277
+ const prompt = buildDecisionPrompt(enriched);
278
+ log(`[llm-agent] Prompt built (${prompt.length} chars)`);
279
+ // 3. Call the LLM
280
+ const response = callLlm(prompt);
281
+ log(`[llm-agent] Response received (${response.length} chars)`);
282
+ // 4. Parse the decision
283
+ const decision = parseDecisionResponse(response);
284
+ log(`[llm-agent] Decision: ${decision} for ${context.hookName} → ${context.action}`);
285
+ return decision;
286
+ }
287
+ catch (err) {
288
+ // On any error, escalate to human rather than silently approving/denying
289
+ const errMsg = err instanceof Error ? err.message : String(err);
290
+ log(`[llm-agent] Error during decision — escalating to human: ${errMsg}`);
291
+ return 'escalate';
292
+ }
293
+ };
294
+ }
295
+ //# sourceMappingURL=llm-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-agent.js","sourceRoot":"","sources":["../../../src/lib/orchestrate/llm-agent.ts"],"names":[],"mappings":"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"}
@@ -2,10 +2,11 @@
2
2
  * Orchestrate Presets
3
3
  *
4
4
  * Pre-configured hook sets for common automation levels.
5
+ * Maps to the 3-tier supervision tree:
5
6
  *
6
- * - aggressive: auto-everything — no human needed
7
- * - conservative: confirm everything human approves all
8
- * - supervised: auto for safe ops, confirm for destructive
7
+ * - aggressive: all auto (Tier 1) — no decision needed
8
+ * - supervised: safe=auto (Tier 1), destructive=llm (Tier 2)
9
+ * - conservative: safe=auto (Tier 1), destructive=human (Tier 3)
9
10
  */
10
11
  import type { HookMode, OrchestrateEvent, PresetName } from './types.js';
11
12
  interface PresetHook {
@@ -2,10 +2,11 @@
2
2
  * Orchestrate Presets
3
3
  *
4
4
  * Pre-configured hook sets for common automation levels.
5
+ * Maps to the 3-tier supervision tree:
5
6
  *
6
- * - aggressive: auto-everything — no human needed
7
- * - conservative: confirm everything human approves all
8
- * - supervised: auto for safe ops, confirm for destructive
7
+ * - aggressive: all auto (Tier 1) — no decision needed
8
+ * - supervised: safe=auto (Tier 1), destructive=llm (Tier 2)
9
+ * - conservative: safe=auto (Tier 1), destructive=human (Tier 3)
9
10
  */
10
11
  const SHARED_HOOKS = [
11
12
  // PR lifecycle
@@ -25,6 +26,7 @@ const SHARED_HOOKS = [
25
26
  { event: 'on_agent_died', action: 'respawn', config: { max_retries: 2 } },
26
27
  { event: 'on_agent_died', action: 'notify' },
27
28
  { event: 'on_agent_idle', action: 'health-check' },
29
+ { event: 'on_agent_idle', action: 'gc-sweep' },
28
30
  // Review lifecycle
29
31
  { event: 'on_review_approved', action: 'notify' },
30
32
  { event: 'on_changes_requested', action: 'spawn-fix-agent' },
@@ -32,6 +34,8 @@ const SHARED_HOOKS = [
32
34
  // CI lifecycle
33
35
  { event: 'on_ci_failed', action: 'notify' },
34
36
  { event: 'on_ci_failed', action: 'spawn-fix-agent' },
37
+ // Periodic cleanup
38
+ { event: 'on_agent_completed', action: 'gc-sweep' },
35
39
  ];
36
40
  /**
37
41
  * Safe actions that can be auto-executed even in supervised mode.
@@ -50,11 +54,12 @@ const SAFE_ACTIONS = new Set([
50
54
  'health-check',
51
55
  'rebase-conflicting-prs',
52
56
  'spawn-review-agent',
57
+ 'gc-sweep',
53
58
  ]);
54
59
  export const PRESETS = {
55
60
  aggressive: {
56
61
  name: 'aggressive',
57
- description: 'Auto everything — no human needed',
62
+ description: 'Auto everything — Tier 1 only, no decisions needed',
58
63
  hooks: SHARED_HOOKS.map(h => ({
59
64
  ...h,
60
65
  mode: 'auto',
@@ -62,18 +67,18 @@ export const PRESETS = {
62
67
  },
63
68
  conservative: {
64
69
  name: 'conservative',
65
- description: 'Confirm everything human approves all actions',
70
+ description: 'Safe=auto (Tier 1), destructive=human (Tier 3)',
66
71
  hooks: SHARED_HOOKS.map(h => ({
67
72
  ...h,
68
- mode: 'confirm',
73
+ mode: (SAFE_ACTIONS.has(h.action) ? 'auto' : 'human'),
69
74
  })),
70
75
  },
71
76
  supervised: {
72
77
  name: 'supervised',
73
- description: 'Auto for safe ops, confirm for destructive actions',
78
+ description: 'Safe=auto (Tier 1), destructive=llm (Tier 2)',
74
79
  hooks: SHARED_HOOKS.map(h => ({
75
80
  ...h,
76
- mode: (SAFE_ACTIONS.has(h.action) ? 'auto' : 'confirm'),
81
+ mode: (SAFE_ACTIONS.has(h.action) ? 'auto' : 'llm'),
77
82
  })),
78
83
  },
79
84
  };
@@ -1 +1 @@
1
- {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../src/lib/orchestrate/presets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../src/lib/orchestrate/presets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,166 @@
1
+ /**
2
+ * walkPromptChain — drive prlt CLI commands non-interactively by walking JSON prompts.
3
+ *
4
+ * Background (PRLT-1268):
5
+ * Action handlers used to hardcode flag combinations like
6
+ * `prlt work start <ticket> --yes --display background`
7
+ * which broke as soon as a command emitted a JSON prompt that wasn't covered
8
+ * by those flags (e.g. environment selection). `--yes` does not bypass JSON
9
+ * prompts.
10
+ *
11
+ * The right approach is to walk the JSON prompt chain. Every prlt command in
12
+ * JSON mode emits one of:
13
+ * - { type: 'prompt', prompt: { name, choices: [{ value, command, ... }, ...] } }
14
+ * - { type: 'success', ... }
15
+ * - { type: 'execution_result', ... }
16
+ * - { type: 'error', ... }
17
+ *
18
+ * For prompt responses, each choice already carries a fully constructed
19
+ * follow-up `command` field. The walker:
20
+ * 1. Runs the current command with --json
21
+ * 2. If response is type=prompt, picks a default choice by name from the
22
+ * defaults map, then runs choice.command
23
+ * 3. Repeats until success/error/iteration cap
24
+ *
25
+ * Per-action default choices live in the action handler and may be overridden
26
+ * by hook config so users can customize behavior without code changes.
27
+ */
28
+ /**
29
+ * Result of executing a single command in the chain.
30
+ */
31
+ export interface ChainExecutorResult {
32
+ /** stdout from the command (where prlt writes JSON) */
33
+ stdout: string;
34
+ /** stderr from the command (for diagnostics on failure) */
35
+ stderr: string;
36
+ /** Exit status — prompts emit with status=2, success with 0 */
37
+ status: number;
38
+ /** Spawn error if the process couldn't be started */
39
+ error?: string;
40
+ }
41
+ /**
42
+ * Function used to execute a command in the chain.
43
+ * Default implementation shells out via spawnSync; tests can inject a mock.
44
+ */
45
+ export type ChainExecutor = (command: string, timeoutMs: number) => ChainExecutorResult;
46
+ /**
47
+ * Default executor — runs the command via spawnSync with a shell.
48
+ */
49
+ export declare const defaultChainExecutor: ChainExecutor;
50
+ /**
51
+ * Options for walkPromptChain.
52
+ */
53
+ export interface WalkPromptChainOptions {
54
+ /** The initial prlt command (with or without --json) */
55
+ baseCommand: string;
56
+ /**
57
+ * Map of prompt name → choice value to pick when that prompt is encountered.
58
+ * The prompt's `name` is the flagName the FlagResolver registered (e.g.,
59
+ * 'environment', 'display', 'permission-mode').
60
+ */
61
+ defaults: Record<string, string>;
62
+ /** Per-command timeout. Defaults to 180s (matches AGENT_SPAWN_TIMEOUT_MS). */
63
+ timeoutMs?: number;
64
+ /** Hard cap on iterations to avoid infinite loops on misconfigured chains. */
65
+ maxIterations?: number;
66
+ /** Custom executor — primarily for tests. */
67
+ executor?: ChainExecutor;
68
+ }
69
+ /**
70
+ * Result of walking the chain.
71
+ */
72
+ export interface WalkPromptChainResult {
73
+ /** Whether the chain reached a success terminal state. */
74
+ success: boolean;
75
+ /** Number of commands executed. */
76
+ iterations: number;
77
+ /** The final command that produced the terminal response. */
78
+ finalCommand: string;
79
+ /** Sequence of commands run, oldest first. Useful for debugging/logging. */
80
+ commandTrail: string[];
81
+ /** Error message if walking failed. */
82
+ error?: string;
83
+ /** Result body from a terminal success/execution_result envelope. */
84
+ result?: Record<string, unknown>;
85
+ }
86
+ /**
87
+ * Walk a JSON prompt chain to completion.
88
+ *
89
+ * Each iteration runs the current command, parses its JSON envelope, and:
90
+ * - On terminal success/execution_result, returns success.
91
+ * - On error, returns failure with the error code/message.
92
+ * - On prompt, picks the default for that prompt's name and runs the
93
+ * corresponding choice's `command`.
94
+ *
95
+ * If a prompt's name has no entry in `defaults`, the walk fails — this is a
96
+ * configuration bug, not something to silently swallow.
97
+ */
98
+ export declare function walkPromptChain(opts: WalkPromptChainOptions): WalkPromptChainResult;
99
+ /**
100
+ * Built-in default choice maps per action. Hook config can shallow-merge
101
+ * over these to override individual prompt defaults.
102
+ *
103
+ * Keys are prompt names (FlagResolver flagName). Values are the choice value
104
+ * to pick. See `apps/cli/src/commands/work/start.ts` for the prompts a
105
+ * `prlt work start` chain may emit.
106
+ */
107
+ export declare const DEFAULT_PROMPT_CHOICES: {
108
+ readonly 'spawn-agent': {
109
+ readonly environment: "devcontainer";
110
+ readonly display: "background";
111
+ readonly selectedDisplay: "background";
112
+ readonly 'permission-mode': "danger";
113
+ readonly tokenAction: "continue";
114
+ readonly dockerAction: "host";
115
+ readonly prChoice: "create";
116
+ readonly saveDefault: "true";
117
+ readonly authAction: "oauth";
118
+ };
119
+ readonly 'spawn-review-agent': {
120
+ readonly environment: "host";
121
+ readonly display: "background";
122
+ readonly selectedDisplay: "background";
123
+ readonly 'permission-mode': "safe";
124
+ readonly prChoice: "no-pr";
125
+ readonly saveDefault: "true";
126
+ };
127
+ readonly 'spawn-fix-agent': {
128
+ readonly environment: "devcontainer";
129
+ readonly display: "background";
130
+ readonly selectedDisplay: "background";
131
+ readonly 'permission-mode': "danger";
132
+ readonly tokenAction: "continue";
133
+ readonly dockerAction: "host";
134
+ readonly prChoice: "create";
135
+ readonly saveDefault: "true";
136
+ readonly authAction: "oauth";
137
+ };
138
+ readonly 'resolve-conflict': {
139
+ readonly environment: "devcontainer";
140
+ readonly display: "background";
141
+ readonly selectedDisplay: "background";
142
+ readonly 'permission-mode': "danger";
143
+ readonly tokenAction: "continue";
144
+ readonly dockerAction: "host";
145
+ readonly prChoice: "create";
146
+ readonly saveDefault: "true";
147
+ readonly authAction: "oauth";
148
+ };
149
+ readonly 'merge-pr': {
150
+ readonly method: "squash";
151
+ readonly 'delete-branch': "true";
152
+ };
153
+ readonly 'move-ticket': {
154
+ readonly target: "done";
155
+ };
156
+ };
157
+ /**
158
+ * Resolve effective defaults for an action by overlaying hook config on top
159
+ * of the built-in defaults. Hook config shape:
160
+ *
161
+ * { defaults: { promptName: 'value', ... } }
162
+ *
163
+ * Unknown keys in hook config are passed through verbatim — there is no
164
+ * allow-list because new prlt prompts get added all the time.
165
+ */
166
+ export declare function resolveActionDefaults(action: keyof typeof DEFAULT_PROMPT_CHOICES, config?: Record<string, unknown>): Record<string, string>;