@kynetic-ai/spec 0.9.1 → 0.10.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.
Files changed (262) hide show
  1. package/README.md +2 -1
  2. package/dist/acp/client.d.ts +6 -1
  3. package/dist/acp/client.d.ts.map +1 -1
  4. package/dist/acp/client.js +7 -2
  5. package/dist/acp/client.js.map +1 -1
  6. package/dist/acp/framing.d.ts +12 -1
  7. package/dist/acp/framing.d.ts.map +1 -1
  8. package/dist/acp/framing.js +27 -4
  9. package/dist/acp/framing.js.map +1 -1
  10. package/dist/agent-runtime/dispatch.d.ts +261 -0
  11. package/dist/agent-runtime/dispatch.d.ts.map +1 -0
  12. package/dist/agent-runtime/dispatch.js +791 -0
  13. package/dist/agent-runtime/dispatch.js.map +1 -0
  14. package/dist/agent-runtime/index.d.ts +11 -0
  15. package/dist/agent-runtime/index.d.ts.map +1 -0
  16. package/dist/agent-runtime/index.js +11 -0
  17. package/dist/agent-runtime/index.js.map +1 -0
  18. package/dist/agent-runtime/invocation.d.ts +86 -0
  19. package/dist/agent-runtime/invocation.d.ts.map +1 -0
  20. package/dist/agent-runtime/invocation.js +442 -0
  21. package/dist/agent-runtime/invocation.js.map +1 -0
  22. package/dist/agent-runtime/prompts.d.ts +50 -0
  23. package/dist/agent-runtime/prompts.d.ts.map +1 -0
  24. package/dist/agent-runtime/prompts.js +108 -0
  25. package/dist/agent-runtime/prompts.js.map +1 -0
  26. package/dist/agents/spawner.d.ts.map +1 -1
  27. package/dist/agents/spawner.js +60 -4
  28. package/dist/agents/spawner.js.map +1 -1
  29. package/dist/cli/batch-exec.d.ts.map +1 -1
  30. package/dist/cli/batch-exec.js +140 -62
  31. package/dist/cli/batch-exec.js.map +1 -1
  32. package/dist/cli/batch-write-buffer.d.ts +141 -0
  33. package/dist/cli/batch-write-buffer.d.ts.map +1 -0
  34. package/dist/cli/batch-write-buffer.js +400 -0
  35. package/dist/cli/batch-write-buffer.js.map +1 -0
  36. package/dist/cli/commands/agent.d.ts +20 -0
  37. package/dist/cli/commands/agent.d.ts.map +1 -0
  38. package/dist/cli/commands/agent.js +831 -0
  39. package/dist/cli/commands/agent.js.map +1 -0
  40. package/dist/cli/commands/inbox.d.ts.map +1 -1
  41. package/dist/cli/commands/inbox.js +46 -22
  42. package/dist/cli/commands/inbox.js.map +1 -1
  43. package/dist/cli/commands/index.d.ts +1 -0
  44. package/dist/cli/commands/index.d.ts.map +1 -1
  45. package/dist/cli/commands/index.js +1 -0
  46. package/dist/cli/commands/index.js.map +1 -1
  47. package/dist/cli/commands/item.d.ts.map +1 -1
  48. package/dist/cli/commands/item.js +22 -16
  49. package/dist/cli/commands/item.js.map +1 -1
  50. package/dist/cli/commands/log.js +1 -1
  51. package/dist/cli/commands/log.js.map +1 -1
  52. package/dist/cli/commands/meta.d.ts.map +1 -1
  53. package/dist/cli/commands/meta.js +159 -6
  54. package/dist/cli/commands/meta.js.map +1 -1
  55. package/dist/cli/commands/module.d.ts.map +1 -1
  56. package/dist/cli/commands/module.js +2 -1
  57. package/dist/cli/commands/module.js.map +1 -1
  58. package/dist/cli/commands/plan-import.js +19 -3
  59. package/dist/cli/commands/plan-import.js.map +1 -1
  60. package/dist/cli/commands/plan.d.ts.map +1 -1
  61. package/dist/cli/commands/plan.js +87 -43
  62. package/dist/cli/commands/plan.js.map +1 -1
  63. package/dist/cli/commands/ralph.d.ts +5 -56
  64. package/dist/cli/commands/ralph.d.ts.map +1 -1
  65. package/dist/cli/commands/ralph.js +52 -1502
  66. package/dist/cli/commands/ralph.js.map +1 -1
  67. package/dist/cli/commands/search.d.ts.map +1 -1
  68. package/dist/cli/commands/search.js +22 -13
  69. package/dist/cli/commands/search.js.map +1 -1
  70. package/dist/cli/commands/serve.d.ts.map +1 -1
  71. package/dist/cli/commands/serve.js +70 -11
  72. package/dist/cli/commands/serve.js.map +1 -1
  73. package/dist/cli/commands/session/checkpoint.d.ts.map +1 -1
  74. package/dist/cli/commands/session/checkpoint.js +7 -2
  75. package/dist/cli/commands/session/checkpoint.js.map +1 -1
  76. package/dist/cli/commands/session/commands.d.ts.map +1 -1
  77. package/dist/cli/commands/session/commands.js +15 -0
  78. package/dist/cli/commands/session/commands.js.map +1 -1
  79. package/dist/cli/commands/session/context.d.ts.map +1 -1
  80. package/dist/cli/commands/session/context.js +10 -5
  81. package/dist/cli/commands/session/context.js.map +1 -1
  82. package/dist/cli/commands/session/log.d.ts +1 -0
  83. package/dist/cli/commands/session/log.d.ts.map +1 -1
  84. package/dist/cli/commands/session/log.js +124 -8
  85. package/dist/cli/commands/session/log.js.map +1 -1
  86. package/dist/cli/commands/session/stale-close.d.ts +17 -0
  87. package/dist/cli/commands/session/stale-close.d.ts.map +1 -0
  88. package/dist/cli/commands/session/stale-close.js +378 -0
  89. package/dist/cli/commands/session/stale-close.js.map +1 -0
  90. package/dist/cli/commands/setup.d.ts.map +1 -1
  91. package/dist/cli/commands/setup.js +95 -0
  92. package/dist/cli/commands/setup.js.map +1 -1
  93. package/dist/cli/commands/skill-crud.d.ts.map +1 -1
  94. package/dist/cli/commands/skill-crud.js +4 -3
  95. package/dist/cli/commands/skill-crud.js.map +1 -1
  96. package/dist/cli/commands/skill-diff.d.ts.map +1 -1
  97. package/dist/cli/commands/skill-diff.js +15 -0
  98. package/dist/cli/commands/skill-diff.js.map +1 -1
  99. package/dist/cli/commands/skill-install.d.ts.map +1 -1
  100. package/dist/cli/commands/skill-install.js +50 -18
  101. package/dist/cli/commands/skill-install.js.map +1 -1
  102. package/dist/cli/commands/task.d.ts.map +1 -1
  103. package/dist/cli/commands/task.js +536 -310
  104. package/dist/cli/commands/task.js.map +1 -1
  105. package/dist/cli/commands/tasks.js +1 -1
  106. package/dist/cli/commands/tasks.js.map +1 -1
  107. package/dist/cli/commands/triage.d.ts.map +1 -1
  108. package/dist/cli/commands/triage.js +37 -13
  109. package/dist/cli/commands/triage.js.map +1 -1
  110. package/dist/cli/commands/validate.d.ts.map +1 -1
  111. package/dist/cli/commands/validate.js +65 -25
  112. package/dist/cli/commands/validate.js.map +1 -1
  113. package/dist/cli/help/content.d.ts.map +1 -1
  114. package/dist/cli/help/content.js +5 -0
  115. package/dist/cli/help/content.js.map +1 -1
  116. package/dist/cli/index.d.ts.map +1 -1
  117. package/dist/cli/index.js +2 -1
  118. package/dist/cli/index.js.map +1 -1
  119. package/dist/cli/output.d.ts.map +1 -1
  120. package/dist/cli/output.js +5 -1
  121. package/dist/cli/output.js.map +1 -1
  122. package/dist/daemon/project-context.ts +22 -0
  123. package/dist/daemon/routes/agent-dispatch.ts +272 -0
  124. package/dist/daemon/server.ts +55 -20
  125. package/dist/daemon/websocket/handler.ts +67 -6
  126. package/dist/daemon/websocket/lifecycle.ts +19 -0
  127. package/dist/daemon/websocket/pubsub.ts +74 -3
  128. package/dist/export/html.d.ts.map +1 -1
  129. package/dist/export/html.js +5 -2
  130. package/dist/export/html.js.map +1 -1
  131. package/dist/export/triage.d.ts +1 -1
  132. package/dist/export/triage.d.ts.map +1 -1
  133. package/dist/export/triage.js +5 -3
  134. package/dist/export/triage.js.map +1 -1
  135. package/dist/parser/alignment.d.ts.map +1 -1
  136. package/dist/parser/alignment.js +6 -3
  137. package/dist/parser/alignment.js.map +1 -1
  138. package/dist/parser/assess.js +1 -1
  139. package/dist/parser/assess.js.map +1 -1
  140. package/dist/parser/config.d.ts +6 -6
  141. package/dist/parser/meta.d.ts.map +1 -1
  142. package/dist/parser/meta.js +9 -8
  143. package/dist/parser/meta.js.map +1 -1
  144. package/dist/parser/plan-document.d.ts +12 -12
  145. package/dist/parser/plans.d.ts +7 -0
  146. package/dist/parser/plans.d.ts.map +1 -1
  147. package/dist/parser/plans.js +100 -15
  148. package/dist/parser/plans.js.map +1 -1
  149. package/dist/parser/refs.d.ts +5 -0
  150. package/dist/parser/refs.d.ts.map +1 -1
  151. package/dist/parser/refs.js +17 -12
  152. package/dist/parser/refs.js.map +1 -1
  153. package/dist/parser/shadow.d.ts +1 -1
  154. package/dist/parser/shadow.d.ts.map +1 -1
  155. package/dist/parser/shadow.js +71 -4
  156. package/dist/parser/shadow.js.map +1 -1
  157. package/dist/parser/skill-render.d.ts.map +1 -1
  158. package/dist/parser/skill-render.js +6 -3
  159. package/dist/parser/skill-render.js.map +1 -1
  160. package/dist/parser/validate.d.ts.map +1 -1
  161. package/dist/parser/validate.js +35 -76
  162. package/dist/parser/validate.js.map +1 -1
  163. package/dist/parser/yaml.d.ts +24 -5
  164. package/dist/parser/yaml.d.ts.map +1 -1
  165. package/dist/parser/yaml.js +224 -64
  166. package/dist/parser/yaml.js.map +1 -1
  167. package/dist/schema/meta.d.ts +442 -119
  168. package/dist/schema/meta.d.ts.map +1 -1
  169. package/dist/schema/meta.js +55 -0
  170. package/dist/schema/meta.js.map +1 -1
  171. package/dist/schema/plan.d.ts +22 -22
  172. package/dist/schema/spec.d.ts +39 -39
  173. package/dist/schema/task.d.ts +43 -32
  174. package/dist/schema/task.d.ts.map +1 -1
  175. package/dist/schema/task.js +5 -0
  176. package/dist/schema/task.js.map +1 -1
  177. package/dist/sessions/store.d.ts +112 -0
  178. package/dist/sessions/store.d.ts.map +1 -1
  179. package/dist/sessions/store.js +414 -22
  180. package/dist/sessions/store.js.map +1 -1
  181. package/dist/sessions/types.d.ts +75 -17
  182. package/dist/sessions/types.d.ts.map +1 -1
  183. package/dist/sessions/types.js +51 -1
  184. package/dist/sessions/types.js.map +1 -1
  185. package/dist/triage/actions.d.ts +1 -0
  186. package/dist/triage/actions.d.ts.map +1 -1
  187. package/dist/triage/actions.js +34 -7
  188. package/dist/triage/actions.js.map +1 -1
  189. package/dist/utils/commit.js +1 -1
  190. package/dist/utils/commit.js.map +1 -1
  191. package/dist/web-ui/_app/env.js +1 -0
  192. package/dist/web-ui/_app/immutable/assets/0.BxCxvrZR.css +1 -0
  193. package/dist/web-ui/_app/immutable/assets/select-trigger.CV-KWLNP.css +1 -0
  194. package/dist/web-ui/_app/immutable/chunks/B-CZR0q8.js +1 -0
  195. package/dist/web-ui/_app/immutable/chunks/B1IR5Su5.js +1 -0
  196. package/dist/web-ui/_app/immutable/chunks/BCkp8Hs8.js +1 -0
  197. package/dist/web-ui/_app/immutable/chunks/B_Cvvtc4.js +1 -0
  198. package/dist/web-ui/_app/immutable/chunks/BtFaGGII.js +1 -0
  199. package/dist/web-ui/_app/immutable/chunks/Bu8JVsCH.js +1 -0
  200. package/dist/web-ui/_app/immutable/chunks/C87u-CNA.js +1 -0
  201. package/dist/web-ui/_app/immutable/chunks/CrFkBTYp.js +1 -0
  202. package/dist/web-ui/_app/immutable/chunks/D1ArdqNb.js +1 -0
  203. package/dist/web-ui/_app/immutable/chunks/D28BF5MJ.js +1 -0
  204. package/dist/web-ui/_app/immutable/chunks/D6RtLpzL.js +1 -0
  205. package/dist/web-ui/_app/immutable/chunks/D7FHSgx2.js +1 -0
  206. package/dist/web-ui/_app/immutable/chunks/DBXrsxZQ.js +2 -0
  207. package/dist/web-ui/_app/immutable/chunks/Da_hHMuA.js +1 -0
  208. package/dist/web-ui/_app/immutable/chunks/Do6LchSF.js +1 -0
  209. package/dist/web-ui/_app/immutable/chunks/DoNPtcAw.js +1 -0
  210. package/dist/web-ui/_app/immutable/chunks/DtUbXRZz.js +1 -0
  211. package/dist/web-ui/_app/immutable/chunks/DyFPRlLl.js +1 -0
  212. package/dist/web-ui/_app/immutable/chunks/DzAP8lRM.js +1 -0
  213. package/dist/web-ui/_app/immutable/chunks/DzVXElzN.js +2 -0
  214. package/dist/web-ui/_app/immutable/chunks/aoPBFken.js +1 -0
  215. package/dist/web-ui/_app/immutable/chunks/i-XnOIX0.js +1 -0
  216. package/dist/web-ui/_app/immutable/chunks/laxtrUO3.js +1 -0
  217. package/dist/web-ui/_app/immutable/chunks/q1nIWgqB.js +1 -0
  218. package/dist/web-ui/_app/immutable/chunks/sTLbk5Nm.js +1 -0
  219. package/dist/web-ui/_app/immutable/chunks/vwKgQu5P.js +5 -0
  220. package/dist/web-ui/_app/immutable/entry/app.BCwMcqnT.js +2 -0
  221. package/dist/web-ui/_app/immutable/entry/start.wKCQH-tt.js +1 -0
  222. package/dist/web-ui/_app/immutable/nodes/0.CjGVMG74.js +1 -0
  223. package/dist/web-ui/_app/immutable/nodes/1.B6_AIPan.js +1 -0
  224. package/dist/web-ui/_app/immutable/nodes/2.q4oCS7Ws.js +1 -0
  225. package/dist/web-ui/_app/immutable/nodes/3.rTKZf9o2.js +1 -0
  226. package/dist/web-ui/_app/immutable/nodes/4.DVIDRu1d.js +1 -0
  227. package/dist/web-ui/_app/immutable/nodes/5.8PtPXIOd.js +1 -0
  228. package/dist/web-ui/_app/immutable/nodes/6.ZZrTemy_.js +1 -0
  229. package/dist/web-ui/_app/immutable/nodes/7.IP-gxCxi.js +1 -0
  230. package/dist/web-ui/_app/version.json +1 -0
  231. package/dist/web-ui/index.html +36 -0
  232. package/dist/web-ui/robots.txt +3 -0
  233. package/package.json +3 -2
  234. package/plugin/.claude-plugin/marketplace.json +1 -1
  235. package/plugin/.claude-plugin/plugin.json +1 -1
  236. package/plugin/plugins/kspec/skills/task-work/SKILL.md +25 -2
  237. package/templates/agents-sections/06-ralph-loop.md +64 -11
  238. package/templates/skills/task-work/SKILL.md +25 -2
  239. package/dist/ralph/cli-renderer.d.ts +0 -27
  240. package/dist/ralph/cli-renderer.d.ts.map +0 -1
  241. package/dist/ralph/cli-renderer.js +0 -250
  242. package/dist/ralph/cli-renderer.js.map +0 -1
  243. package/dist/ralph/events.d.ts +0 -65
  244. package/dist/ralph/events.d.ts.map +0 -1
  245. package/dist/ralph/events.js +0 -600
  246. package/dist/ralph/events.js.map +0 -1
  247. package/dist/ralph/index.d.ts +0 -11
  248. package/dist/ralph/index.d.ts.map +0 -1
  249. package/dist/ralph/index.js +0 -16
  250. package/dist/ralph/index.js.map +0 -1
  251. package/dist/ralph/loop-errors.d.ts +0 -83
  252. package/dist/ralph/loop-errors.d.ts.map +0 -1
  253. package/dist/ralph/loop-errors.js +0 -150
  254. package/dist/ralph/loop-errors.js.map +0 -1
  255. package/dist/ralph/subagent.d.ts +0 -127
  256. package/dist/ralph/subagent.d.ts.map +0 -1
  257. package/dist/ralph/subagent.js +0 -268
  258. package/dist/ralph/subagent.js.map +0 -1
  259. package/dist/ralph/wrap-up.d.ts +0 -127
  260. package/dist/ralph/wrap-up.d.ts.map +0 -1
  261. package/dist/ralph/wrap-up.js +0 -271
  262. package/dist/ralph/wrap-up.js.map +0 -1
@@ -1,83 +0,0 @@
1
- /**
2
- * Loop mode error handling utilities.
3
- *
4
- * Tracks per-task failures with [LOOP-FAIL:N] prefix in notes.
5
- * Escalates to automation:needs_review after 3 failures.
6
- */
7
- import type { Task } from "../schema/task.js";
8
- /**
9
- * Parse the failure count from a [LOOP-FAIL:N] prefixed note.
10
- * Returns 0 if no match found.
11
- *
12
- * AC: @loop-mode-error-handling ac-4
13
- */
14
- export declare function parseFailureCount(noteContent: string): number;
15
- /**
16
- * Get the current failure count for a task by examining its notes.
17
- * Returns the highest failure count found, or 0 if no failures recorded.
18
- *
19
- * AC: @loop-mode-error-handling ac-4
20
- */
21
- export declare function getTaskFailureCount(task: Task): number;
22
- /**
23
- * Create a failure note with [LOOP-FAIL:N] prefix.
24
- * Increments N based on prior failure count.
25
- *
26
- * AC: @loop-mode-error-handling ac-1, ac-3, ac-4
27
- */
28
- export declare function createFailureNote(taskRef: string, errorDescription: string, priorFailureCount: number): string;
29
- /**
30
- * Check if failure count has reached the escalation threshold.
31
- * Threshold is 3 failures.
32
- *
33
- * AC: @loop-mode-error-handling ac-5
34
- */
35
- export declare function shouldEscalate(failureCount: number): boolean;
36
- /**
37
- * Determine if an iteration result represents a failure.
38
- *
39
- * Failures include:
40
- * - Tests fail
41
- * - PR blocked
42
- * - Exception thrown
43
- * - Agent reports cannot complete
44
- *
45
- * AC: @loop-mode-error-handling ac-7
46
- */
47
- export declare function isIterationFailure(result: {
48
- succeeded?: boolean;
49
- error?: Error;
50
- stopReason?: string;
51
- }): boolean;
52
- /**
53
- * Check if an in_progress task has made progress in this iteration.
54
- * Progress is indicated by new notes added after the startTime.
55
- *
56
- * AC: @loop-mode-error-handling ac-8
57
- */
58
- export declare function hasTaskProgress(task: Task, iterationStartTime: Date): boolean;
59
- /**
60
- * Result of processing a failed iteration for a task.
61
- */
62
- export interface TaskFailureResult {
63
- taskRef: string;
64
- failureCount: number;
65
- escalated: boolean;
66
- noteAdded: boolean;
67
- }
68
- /**
69
- * Process failed iteration for tasks that were in progress.
70
- * Adds LOOP-FAIL notes for tasks without progress and escalates at threshold.
71
- *
72
- * This function should be called after an iteration fails to track per-task failures.
73
- *
74
- * AC: @loop-mode-error-handling ac-1, ac-2, ac-3, ac-4, ac-5, ac-8
75
- *
76
- * @param tasksInProgress - Tasks that were in_progress at iteration start
77
- * @param currentTasks - Current state of all tasks (after iteration)
78
- * @param iterationStartTime - When the iteration started
79
- * @param errorDescription - Description of what went wrong
80
- * @returns Array of results for each processed task
81
- */
82
- export declare function processFailedIteration(tasksInProgress: Task[], currentTasks: Task[], iterationStartTime: Date, errorDescription: string): TaskFailureResult[];
83
- //# sourceMappingURL=loop-errors.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loop-errors.d.ts","sourceRoot":"","sources":["../../src/ralph/loop-errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAE9C;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CActD;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,gBAAgB,EAAE,MAAM,EACxB,iBAAiB,EAAE,MAAM,GACxB,MAAM,CAGR;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,GAAG,OAAO,CAiBV;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,kBAAkB,EAAE,IAAI,GACvB,OAAO,CAiBT;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,eAAe,EAAE,IAAI,EAAE,EACvB,YAAY,EAAE,IAAI,EAAE,EACpB,kBAAkB,EAAE,IAAI,EACxB,gBAAgB,EAAE,MAAM,GACvB,iBAAiB,EAAE,CAuCrB"}
@@ -1,150 +0,0 @@
1
- /**
2
- * Loop mode error handling utilities.
3
- *
4
- * Tracks per-task failures with [LOOP-FAIL:N] prefix in notes.
5
- * Escalates to automation:needs_review after 3 failures.
6
- */
7
- /**
8
- * Parse the failure count from a [LOOP-FAIL:N] prefixed note.
9
- * Returns 0 if no match found.
10
- *
11
- * AC: @loop-mode-error-handling ac-4
12
- */
13
- export function parseFailureCount(noteContent) {
14
- const match = noteContent.match(/^\[LOOP-FAIL:(\d+)\]/);
15
- return match ? Number.parseInt(match[1], 10) : 0;
16
- }
17
- /**
18
- * Get the current failure count for a task by examining its notes.
19
- * Returns the highest failure count found, or 0 if no failures recorded.
20
- *
21
- * AC: @loop-mode-error-handling ac-4
22
- */
23
- export function getTaskFailureCount(task) {
24
- if (!task.notes || task.notes.length === 0) {
25
- return 0;
26
- }
27
- let maxCount = 0;
28
- for (const note of task.notes) {
29
- const count = parseFailureCount(note.content);
30
- if (count > maxCount) {
31
- maxCount = count;
32
- }
33
- }
34
- return maxCount;
35
- }
36
- /**
37
- * Create a failure note with [LOOP-FAIL:N] prefix.
38
- * Increments N based on prior failure count.
39
- *
40
- * AC: @loop-mode-error-handling ac-1, ac-3, ac-4
41
- */
42
- export function createFailureNote(taskRef, errorDescription, priorFailureCount) {
43
- const newCount = priorFailureCount + 1;
44
- return `[LOOP-FAIL:${newCount}] Task ${taskRef} failed: ${errorDescription}`;
45
- }
46
- /**
47
- * Check if failure count has reached the escalation threshold.
48
- * Threshold is 3 failures.
49
- *
50
- * AC: @loop-mode-error-handling ac-5
51
- */
52
- export function shouldEscalate(failureCount) {
53
- return failureCount >= 3;
54
- }
55
- /**
56
- * Determine if an iteration result represents a failure.
57
- *
58
- * Failures include:
59
- * - Tests fail
60
- * - PR blocked
61
- * - Exception thrown
62
- * - Agent reports cannot complete
63
- *
64
- * AC: @loop-mode-error-handling ac-7
65
- */
66
- export function isIterationFailure(result) {
67
- // Explicit success flag
68
- if (result.succeeded === false) {
69
- return true;
70
- }
71
- // Error was thrown
72
- if (result.error) {
73
- return true;
74
- }
75
- // Agent cancelled (stopped working)
76
- if (result.stopReason === "cancelled") {
77
- return true;
78
- }
79
- return false;
80
- }
81
- /**
82
- * Check if an in_progress task has made progress in this iteration.
83
- * Progress is indicated by new notes added after the startTime.
84
- *
85
- * AC: @loop-mode-error-handling ac-8
86
- */
87
- export function hasTaskProgress(task, iterationStartTime) {
88
- if (!task.notes || task.notes.length === 0) {
89
- return false;
90
- }
91
- // Check if any notes were created after iteration start
92
- for (const note of task.notes) {
93
- const noteTime = new Date(note.created_at);
94
- if (noteTime > iterationStartTime) {
95
- // Exclude LOOP-FAIL notes from progress check
96
- if (!note.content.startsWith("[LOOP-FAIL:")) {
97
- return true;
98
- }
99
- }
100
- }
101
- return false;
102
- }
103
- /**
104
- * Process failed iteration for tasks that were in progress.
105
- * Adds LOOP-FAIL notes for tasks without progress and escalates at threshold.
106
- *
107
- * This function should be called after an iteration fails to track per-task failures.
108
- *
109
- * AC: @loop-mode-error-handling ac-1, ac-2, ac-3, ac-4, ac-5, ac-8
110
- *
111
- * @param tasksInProgress - Tasks that were in_progress at iteration start
112
- * @param currentTasks - Current state of all tasks (after iteration)
113
- * @param iterationStartTime - When the iteration started
114
- * @param errorDescription - Description of what went wrong
115
- * @returns Array of results for each processed task
116
- */
117
- export function processFailedIteration(tasksInProgress, currentTasks, iterationStartTime, errorDescription) {
118
- const results = [];
119
- // Create a map of current task state for quick lookup
120
- const currentTaskMap = new Map();
121
- for (const task of currentTasks) {
122
- currentTaskMap.set(task._ulid, task);
123
- }
124
- // Process each task that was in progress
125
- for (const originalTask of tasksInProgress) {
126
- const currentTask = currentTaskMap.get(originalTask._ulid);
127
- // Skip if task no longer exists or is no longer in_progress
128
- // (it may have been completed/cancelled/submitted during the iteration)
129
- if (!currentTask || currentTask.status !== "in_progress") {
130
- continue;
131
- }
132
- // Check if task made progress
133
- const madeProgress = hasTaskProgress(currentTask, iterationStartTime);
134
- // AC: @loop-mode-error-handling ac-8
135
- // If task is still in_progress but made no progress, count as implicit failure
136
- if (!madeProgress) {
137
- const priorCount = getTaskFailureCount(currentTask);
138
- const newCount = priorCount + 1;
139
- const escalate = shouldEscalate(newCount);
140
- results.push({
141
- taskRef: currentTask._ulid,
142
- failureCount: newCount,
143
- escalated: escalate,
144
- noteAdded: true, // Note will be added by caller
145
- });
146
- }
147
- }
148
- return results;
149
- }
150
- //# sourceMappingURL=loop-errors.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"loop-errors.js","sourceRoot":"","sources":["../../src/ralph/loop-errors.ts"],"names":[],"mappings":"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"}
@@ -1,127 +0,0 @@
1
- /**
2
- * Ralph Subagent Module
3
- *
4
- * Handles spawning and running subagents for dedicated tasks like PR review.
5
- * Subagents run sequentially - ralph waits for completion before continuing.
6
- */
7
- import type { AgentAdapter } from "../agents/adapters.js";
8
- import { type SpawnedAgent } from "../agents/spawner.js";
9
- /**
10
- * Context provided to a subagent for its task.
11
- * AC: @ralph-subagent-spawning ac-10
12
- */
13
- export interface SubagentContext {
14
- /** Task reference (e.g., @task-slug) */
15
- taskRef: string;
16
- /** Full task details from kspec task get */
17
- taskDetails: Record<string, unknown>;
18
- /** Linked spec with acceptance criteria, if spec_ref exists */
19
- specWithACs: Record<string, unknown> | null;
20
- /** Current git branch */
21
- gitBranch: string;
22
- }
23
- /**
24
- * Configuration for subagent execution.
25
- */
26
- export interface SubagentConfig {
27
- /** Timeout in milliseconds (default: 20 minutes) */
28
- timeout: number;
29
- /** Output prefix for distinguishing subagent output */
30
- outputPrefix: string;
31
- /** Skill invocation name for PR review (from config, defaults to SKILL_PR_REVIEW) */
32
- skillName?: string;
33
- }
34
- /**
35
- * Result of running a subagent.
36
- */
37
- export interface SubagentResult {
38
- /** Whether the subagent completed successfully */
39
- success: boolean;
40
- /** Whether the subagent timed out */
41
- timedOut: boolean;
42
- /** Error message if failed */
43
- error?: string;
44
- }
45
- /**
46
- * Options for running a subagent.
47
- */
48
- export interface SubagentOptions {
49
- /** Whether to auto-approve tool requests */
50
- yolo: boolean;
51
- /** Working directory */
52
- cwd: string;
53
- /** Extra arguments to append to adapter args (e.g., auto-approve flags) */
54
- extraArgs?: string[];
55
- /** Tool request handler */
56
- handleRequest: (client: SpawnedAgent["client"], reqId: string | number, method: string, params: unknown) => Promise<void>;
57
- }
58
- /** Default subagent timeout: 20 minutes */
59
- export declare const DEFAULT_SUBAGENT_TIMEOUT: number;
60
- /** Maximum prompt size in bytes before truncation kicks in.
61
- * 32KB prompt ≈ 35-40KB on the wire (JSON-RPC envelope + escaping),
62
- * well under the 64KB Linux pipe buffer. */
63
- export declare const SUBAGENT_PROMPT_MAX_BYTES: number;
64
- /** Default output prefix for subagent */
65
- export declare const DEFAULT_SUBAGENT_PREFIX = "[REVIEW SUBAGENT]";
66
- /** Default skill invocation for task-work in ralph worker prompt */
67
- export declare const SKILL_TASK_WORK = "/kspec:task-work";
68
- /** Default skill invocation for reflect in ralph reflect prompt */
69
- export declare const SKILL_REFLECT = "/kspec:reflect";
70
- /** Default skill invocation for PR review in ralph subagent prompt */
71
- export declare const SKILL_PR_REVIEW = "/kspec:review";
72
- /**
73
- * Default ACP prompt timeout for ralph agents: 30 minutes.
74
- * The framing layer default (5 min) is too aggressive — API slowness,
75
- * extended thinking, and large context processing can exceed it even
76
- * with the keepalive mechanism (which resets on tool calls/notifications).
77
- */
78
- export declare const RALPH_PROMPT_TIMEOUT: number;
79
- /**
80
- * Represents a replaceable JSON section within a prompt.
81
- */
82
- export interface PromptSection {
83
- /** Marker string that appears in the prompt (the full formatted section) */
84
- marker: string;
85
- /** Replacement text if this section is truncated */
86
- truncated: string;
87
- /** Byte size of the marker */
88
- size: number;
89
- }
90
- /**
91
- * Format a data object as a labeled markdown JSON section.
92
- * Returns the formatted string and a PromptSection for potential truncation.
93
- *
94
- * When not truncated: heading + ```json fence + pretty-printed JSON
95
- * When truncated: heading + blockquote with compact summary + CLI fetch command
96
- */
97
- export declare function formatJsonSection(data: Record<string, unknown>, label: string, fetchCmd: string): {
98
- text: string;
99
- section: PromptSection;
100
- };
101
- /**
102
- * If the assembled prompt exceeds the byte budget, truncate the largest
103
- * section(s) until it fits. Sections are replaced largest-first.
104
- */
105
- export declare function truncatePromptIfNeeded(prompt: string, sections: PromptSection[], maxBytes?: number): string;
106
- /**
107
- * Build the prompt for a PR review subagent.
108
- * AC: @ralph-subagent-spawning ac-2, ac-10, ac-12
109
- *
110
- * @param context - Task context for the subagent
111
- * @param skillName - Skill invocation name for PR review (from config or default)
112
- */
113
- export declare function buildSubagentPrompt(context: SubagentContext, skillName?: string): string;
114
- /**
115
- * Run a subagent for a dedicated task.
116
- *
117
- * AC: @ralph-subagent-spawning ac-1 (spawn), ac-3 (sequential), ac-4 (output),
118
- * ac-9 (timeout), ac-11 (prefix)
119
- *
120
- * @param adapter - Agent adapter to use for spawning
121
- * @param context - Task context for the subagent
122
- * @param config - Subagent configuration (timeout, prefix)
123
- * @param options - Runtime options (cwd, request handler)
124
- * @returns Result indicating success/failure/timeout
125
- */
126
- export declare function runSubagent(adapter: AgentAdapter, context: SubagentContext, config: SubagentConfig, options: SubagentOptions): Promise<SubagentResult>;
127
- //# sourceMappingURL=subagent.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subagent.d.ts","sourceRoot":"","sources":["../../src/ralph/subagent.ts"],"names":[],"mappings":"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"}
@@ -1,268 +0,0 @@
1
- /**
2
- * Ralph Subagent Module
3
- *
4
- * Handles spawning and running subagents for dedicated tasks like PR review.
5
- * Subagents run sequentially - ralph waits for completion before continuing.
6
- */
7
- import { spawnAndInitialize } from "../agents/spawner.js";
8
- import { createTranslator } from "./events.js";
9
- import { createPrefixedRenderer } from "./cli-renderer.js";
10
- // ============================================================================
11
- // Default Configuration
12
- // ============================================================================
13
- /** Default subagent timeout: 20 minutes */
14
- export const DEFAULT_SUBAGENT_TIMEOUT = 20 * 60 * 1000;
15
- /** Maximum prompt size in bytes before truncation kicks in.
16
- * 32KB prompt ≈ 35-40KB on the wire (JSON-RPC envelope + escaping),
17
- * well under the 64KB Linux pipe buffer. */
18
- export const SUBAGENT_PROMPT_MAX_BYTES = 32 * 1024;
19
- /** Default output prefix for subagent */
20
- export const DEFAULT_SUBAGENT_PREFIX = "[REVIEW SUBAGENT]";
21
- // ============================================================================
22
- // Skill Invocation Names (Defaults)
23
- // ============================================================================
24
- // Ralph prompts reference skills by invocation name. Defaults use the kspec:
25
- // namespace (core skills). Projects can override via kspec.config.yaml:
26
- // ralph:
27
- // skills:
28
- // task_work: "/my-task-work"
29
- // reflect: "/my-reflect"
30
- // pr_review: "/my-review"
31
- /** Default skill invocation for task-work in ralph worker prompt */
32
- export const SKILL_TASK_WORK = "/kspec:task-work";
33
- /** Default skill invocation for reflect in ralph reflect prompt */
34
- export const SKILL_REFLECT = "/kspec:reflect";
35
- /** Default skill invocation for PR review in ralph subagent prompt */
36
- export const SKILL_PR_REVIEW = "/kspec:review";
37
- /**
38
- * Default ACP prompt timeout for ralph agents: 30 minutes.
39
- * The framing layer default (5 min) is too aggressive — API slowness,
40
- * extended thinking, and large context processing can exceed it even
41
- * with the keepalive mechanism (which resets on tool calls/notifications).
42
- */
43
- export const RALPH_PROMPT_TIMEOUT = 30 * 60 * 1000;
44
- // ============================================================================
45
- // Prompt Truncation
46
- // ============================================================================
47
- /**
48
- * Build a compact summary stub for truncated sections.
49
- * Provides enough identity context to avoid a CLI call for basic triage.
50
- */
51
- function compactSummary(data) {
52
- const summary = {};
53
- if (data._ulid != null)
54
- summary._ulid = data._ulid;
55
- if (data.ulid != null)
56
- summary._ulid = data.ulid;
57
- if (data.title != null)
58
- summary.title = data.title;
59
- if (data.status != null)
60
- summary.status = data.status;
61
- if (data.spec_ref != null)
62
- summary.spec_ref = data.spec_ref;
63
- if (data.slug != null)
64
- summary.slug = data.slug;
65
- if (Array.isArray(data.acceptance_criteria)) {
66
- summary.ac_count = data.acceptance_criteria.length;
67
- }
68
- return summary;
69
- }
70
- /**
71
- * Format a data object as a labeled markdown JSON section.
72
- * Returns the formatted string and a PromptSection for potential truncation.
73
- *
74
- * When not truncated: heading + ```json fence + pretty-printed JSON
75
- * When truncated: heading + blockquote with compact summary + CLI fetch command
76
- */
77
- export function formatJsonSection(data, label, fetchCmd) {
78
- const json = JSON.stringify(data, null, 2);
79
- const text = `### ${label}\n\n\`\`\`json\n${json}\n\`\`\``;
80
- const summary = JSON.stringify(compactSummary(data));
81
- const truncated = `### ${label}\n\n> **Truncated** (${Buffer.byteLength(json, "utf8")} bytes). Fetch full data:\n> \`\`\`\n> ${fetchCmd}\n> \`\`\`\n>\n> Summary: \`${summary}\``;
82
- return {
83
- text,
84
- section: {
85
- marker: text,
86
- truncated,
87
- size: Buffer.byteLength(text, "utf8"),
88
- },
89
- };
90
- }
91
- /**
92
- * If the assembled prompt exceeds the byte budget, truncate the largest
93
- * section(s) until it fits. Sections are replaced largest-first.
94
- */
95
- export function truncatePromptIfNeeded(prompt, sections, maxBytes = SUBAGENT_PROMPT_MAX_BYTES) {
96
- let totalBytes = Buffer.byteLength(prompt, "utf8");
97
- if (totalBytes <= maxBytes)
98
- return prompt;
99
- // Sort sections largest-first for greedy truncation
100
- const sorted = [...sections].sort((a, b) => b.size - a.size);
101
- let result = prompt;
102
- for (const section of sorted) {
103
- if (totalBytes <= maxBytes)
104
- break;
105
- // Only truncate if this section hasn't already been truncated
106
- if (!result.includes(section.marker))
107
- continue;
108
- const savedBytes = Buffer.byteLength(section.marker, "utf8") -
109
- Buffer.byteLength(section.truncated, "utf8");
110
- result = result.replace(section.marker, section.truncated);
111
- totalBytes -= savedBytes;
112
- }
113
- return result;
114
- }
115
- // ============================================================================
116
- // Prompt Builder
117
- // ============================================================================
118
- /**
119
- * Build the prompt for a PR review subagent.
120
- * AC: @ralph-subagent-spawning ac-2, ac-10, ac-12
121
- *
122
- * @param context - Task context for the subagent
123
- * @param skillName - Skill invocation name for PR review (from config or default)
124
- */
125
- export function buildSubagentPrompt(context, skillName = SKILL_PR_REVIEW) {
126
- // Build replaceable JSON sections
127
- const taskSection = formatJsonSection(context.taskDetails, "Task Details", `kspec task get ${context.taskRef} --json`);
128
- const sections = [taskSection.section];
129
- let specBlock = "";
130
- let specSection = null;
131
- if (context.specWithACs) {
132
- const specRef = context.taskDetails.spec_ref || "@spec";
133
- const formatted = formatJsonSection(context.specWithACs, "Linked Spec with Acceptance Criteria", `kspec item get ${specRef} --json`);
134
- specBlock = `\n${formatted.text}\n\n**Verify all ACs have test coverage before merging.**\n`;
135
- specSection = formatted.section;
136
- sections.push(specSection);
137
- }
138
- const prompt = `# PR Review Subagent
139
-
140
- You are a subagent spawned by ralph to REVIEW a PR and merge it only if clean.
141
-
142
- ## Role Boundary
143
-
144
- You are a REVIEWER, not a fixer. Your responsibilities:
145
- - Review code quality, AC coverage (own + trait), spec alignment
146
- - Post findings as inline PR comments with severity (MUST-FIX:, SHOULD-FIX:, SUGGESTION:)
147
- - Merge the PR ONLY if all quality gates pass (no MUST-FIX or SHOULD-FIX items)
148
- - Complete the task after merge
149
-
150
- You MUST NOT:
151
- - Fix code issues yourself
152
- - Push commits to the PR branch
153
- - Add or modify tests
154
- - Make any code changes
155
-
156
- If you find issues:
157
- 1. Post them as inline PR comments with severity prefix
158
- 2. Transition the task to needs_work: \`kspec task needs-work ${context.taskRef} --reason "findings..."\`
159
- 3. Exit — the worker agent will fix issues in the next iteration
160
-
161
- ## Context
162
-
163
- - **Task:** \`${context.taskRef}\`
164
- - **Branch:** \`${context.gitBranch}\`
165
-
166
- ${taskSection.text}
167
- ${specBlock}
168
- ## Instructions
169
-
170
- Run the PR review skill:
171
-
172
- \`\`\`
173
- ${skillName} ${context.taskRef}
174
- \`\`\`
175
-
176
- The skill defines all review steps, quality gates, and merge criteria. Follow it completely.
177
-
178
- Do NOT start new work. Do NOT fix code. Your only job is reviewing this task's PR, posting findings, and merging if clean.
179
- `;
180
- return truncatePromptIfNeeded(prompt, sections);
181
- }
182
- // ============================================================================
183
- // Subagent Runner
184
- // ============================================================================
185
- /**
186
- * Run a subagent for a dedicated task.
187
- *
188
- * AC: @ralph-subagent-spawning ac-1 (spawn), ac-3 (sequential), ac-4 (output),
189
- * ac-9 (timeout), ac-11 (prefix)
190
- *
191
- * @param adapter - Agent adapter to use for spawning
192
- * @param context - Task context for the subagent
193
- * @param config - Subagent configuration (timeout, prefix)
194
- * @param options - Runtime options (cwd, request handler)
195
- * @returns Result indicating success/failure/timeout
196
- */
197
- export async function runSubagent(adapter, context, config, options) {
198
- const prompt = buildSubagentPrompt(context, config.skillName);
199
- let agent = null;
200
- try {
201
- // AC: @ralph-subagent-spawning ac-1 - Spawn new ACP process
202
- // AC: @ralph-adapter-auto-approve ac-4
203
- agent = await spawnAndInitialize(adapter, {
204
- cwd: options.cwd,
205
- extraArgs: options.extraArgs,
206
- clientOptions: {
207
- clientInfo: {
208
- name: "kspec-ralph-subagent",
209
- version: "1.0.0",
210
- },
211
- methodTimeouts: {
212
- "session/prompt": RALPH_PROMPT_TIMEOUT,
213
- "session/resume": RALPH_PROMPT_TIMEOUT,
214
- },
215
- },
216
- });
217
- // AC: @ralph-subagent-spawning ac-4, ac-11 - Prefixed renderer for output
218
- const translator = createTranslator();
219
- const renderer = createPrefixedRenderer(config.outputPrefix);
220
- // Set up streaming update handler
221
- agent.client.on("update", (_sid, update) => {
222
- const event = translator.translate(update);
223
- if (event) {
224
- renderer.render(event);
225
- }
226
- });
227
- // Set up tool request handler
228
- agent.client.on("request", (reqId, method, params) => {
229
- options
230
- .handleRequest(agent.client, reqId, method, params)
231
- .catch((err) => {
232
- agent.client.respondError(reqId, -32000, err.message);
233
- });
234
- });
235
- // Create ACP session
236
- const acpSessionId = await agent.client.newSession({
237
- cwd: options.cwd,
238
- mcpServers: [],
239
- });
240
- // AC: @ralph-subagent-spawning ac-9 - Timeout handling
241
- const timeoutPromise = new Promise((_, reject) => {
242
- setTimeout(() => reject(new Error("SUBAGENT_TIMEOUT")), config.timeout);
243
- });
244
- // AC: @ralph-subagent-spawning ac-3 - Ralph waits for completion
245
- const promptPromise = agent.client.prompt({
246
- sessionId: acpSessionId,
247
- prompt: [{ type: "text", text: prompt }],
248
- });
249
- // Race between completion and timeout
250
- await Promise.race([promptPromise, timeoutPromise]);
251
- return { success: true, timedOut: false };
252
- }
253
- catch (err) {
254
- const error = err;
255
- // AC: @ralph-subagent-spawning ac-9 - Timeout detection
256
- if (error.message === "SUBAGENT_TIMEOUT") {
257
- return { success: false, timedOut: true };
258
- }
259
- return { success: false, timedOut: false, error: error.message };
260
- }
261
- finally {
262
- // Always clean up the agent process
263
- if (agent) {
264
- agent.kill();
265
- }
266
- }
267
- }
268
- //# sourceMappingURL=subagent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"subagent.js","sourceRoot":"","sources":["../../src/ralph/subagent.ts"],"names":[],"mappings":"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"}