@kynetic-ai/spec 0.1.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 (278) hide show
  1. package/README.md +263 -0
  2. package/dist/acp/client.d.ts +159 -0
  3. package/dist/acp/client.d.ts.map +1 -0
  4. package/dist/acp/client.js +255 -0
  5. package/dist/acp/client.js.map +1 -0
  6. package/dist/acp/framing.d.ts +119 -0
  7. package/dist/acp/framing.d.ts.map +1 -0
  8. package/dist/acp/framing.js +302 -0
  9. package/dist/acp/framing.js.map +1 -0
  10. package/dist/acp/index.d.ts +14 -0
  11. package/dist/acp/index.d.ts.map +1 -0
  12. package/dist/acp/index.js +13 -0
  13. package/dist/acp/index.js.map +1 -0
  14. package/dist/acp/types.d.ts +89 -0
  15. package/dist/acp/types.d.ts.map +1 -0
  16. package/dist/acp/types.js +99 -0
  17. package/dist/acp/types.js.map +1 -0
  18. package/dist/agents/adapters.d.ts +55 -0
  19. package/dist/agents/adapters.d.ts.map +1 -0
  20. package/dist/agents/adapters.js +84 -0
  21. package/dist/agents/adapters.js.map +1 -0
  22. package/dist/agents/index.d.ts +8 -0
  23. package/dist/agents/index.d.ts.map +1 -0
  24. package/dist/agents/index.js +10 -0
  25. package/dist/agents/index.js.map +1 -0
  26. package/dist/agents/spawner.d.ts +53 -0
  27. package/dist/agents/spawner.d.ts.map +1 -0
  28. package/dist/agents/spawner.js +83 -0
  29. package/dist/agents/spawner.js.map +1 -0
  30. package/dist/cli/batch.d.ts +82 -0
  31. package/dist/cli/batch.d.ts.map +1 -0
  32. package/dist/cli/batch.js +162 -0
  33. package/dist/cli/batch.js.map +1 -0
  34. package/dist/cli/commands/clone-for-testing.d.ts +6 -0
  35. package/dist/cli/commands/clone-for-testing.d.ts.map +1 -0
  36. package/dist/cli/commands/clone-for-testing.js +176 -0
  37. package/dist/cli/commands/clone-for-testing.js.map +1 -0
  38. package/dist/cli/commands/derive.d.ts +6 -0
  39. package/dist/cli/commands/derive.d.ts.map +1 -0
  40. package/dist/cli/commands/derive.js +450 -0
  41. package/dist/cli/commands/derive.js.map +1 -0
  42. package/dist/cli/commands/help.d.ts +6 -0
  43. package/dist/cli/commands/help.d.ts.map +1 -0
  44. package/dist/cli/commands/help.js +196 -0
  45. package/dist/cli/commands/help.js.map +1 -0
  46. package/dist/cli/commands/inbox.d.ts +6 -0
  47. package/dist/cli/commands/inbox.d.ts.map +1 -0
  48. package/dist/cli/commands/inbox.js +235 -0
  49. package/dist/cli/commands/inbox.js.map +1 -0
  50. package/dist/cli/commands/index.d.ts +20 -0
  51. package/dist/cli/commands/index.d.ts.map +1 -0
  52. package/dist/cli/commands/index.js +21 -0
  53. package/dist/cli/commands/index.js.map +1 -0
  54. package/dist/cli/commands/init.d.ts +6 -0
  55. package/dist/cli/commands/init.d.ts.map +1 -0
  56. package/dist/cli/commands/init.js +245 -0
  57. package/dist/cli/commands/init.js.map +1 -0
  58. package/dist/cli/commands/item.d.ts +6 -0
  59. package/dist/cli/commands/item.d.ts.map +1 -0
  60. package/dist/cli/commands/item.js +1311 -0
  61. package/dist/cli/commands/item.js.map +1 -0
  62. package/dist/cli/commands/link.d.ts +6 -0
  63. package/dist/cli/commands/link.d.ts.map +1 -0
  64. package/dist/cli/commands/link.js +288 -0
  65. package/dist/cli/commands/link.js.map +1 -0
  66. package/dist/cli/commands/log.d.ts +16 -0
  67. package/dist/cli/commands/log.d.ts.map +1 -0
  68. package/dist/cli/commands/log.js +291 -0
  69. package/dist/cli/commands/log.js.map +1 -0
  70. package/dist/cli/commands/meta.d.ts +15 -0
  71. package/dist/cli/commands/meta.d.ts.map +1 -0
  72. package/dist/cli/commands/meta.js +1378 -0
  73. package/dist/cli/commands/meta.js.map +1 -0
  74. package/dist/cli/commands/module.d.ts +6 -0
  75. package/dist/cli/commands/module.d.ts.map +1 -0
  76. package/dist/cli/commands/module.js +102 -0
  77. package/dist/cli/commands/module.js.map +1 -0
  78. package/dist/cli/commands/ralph.d.ts +9 -0
  79. package/dist/cli/commands/ralph.d.ts.map +1 -0
  80. package/dist/cli/commands/ralph.js +465 -0
  81. package/dist/cli/commands/ralph.js.map +1 -0
  82. package/dist/cli/commands/search.d.ts +6 -0
  83. package/dist/cli/commands/search.d.ts.map +1 -0
  84. package/dist/cli/commands/search.js +134 -0
  85. package/dist/cli/commands/search.js.map +1 -0
  86. package/dist/cli/commands/session.d.ts +164 -0
  87. package/dist/cli/commands/session.d.ts.map +1 -0
  88. package/dist/cli/commands/session.js +745 -0
  89. package/dist/cli/commands/session.js.map +1 -0
  90. package/dist/cli/commands/setup.d.ts +26 -0
  91. package/dist/cli/commands/setup.d.ts.map +1 -0
  92. package/dist/cli/commands/setup.js +586 -0
  93. package/dist/cli/commands/setup.js.map +1 -0
  94. package/dist/cli/commands/shadow.d.ts +6 -0
  95. package/dist/cli/commands/shadow.d.ts.map +1 -0
  96. package/dist/cli/commands/shadow.js +299 -0
  97. package/dist/cli/commands/shadow.js.map +1 -0
  98. package/dist/cli/commands/task.d.ts +6 -0
  99. package/dist/cli/commands/task.d.ts.map +1 -0
  100. package/dist/cli/commands/task.js +1514 -0
  101. package/dist/cli/commands/task.js.map +1 -0
  102. package/dist/cli/commands/tasks.d.ts +6 -0
  103. package/dist/cli/commands/tasks.d.ts.map +1 -0
  104. package/dist/cli/commands/tasks.js +347 -0
  105. package/dist/cli/commands/tasks.js.map +1 -0
  106. package/dist/cli/commands/trait.d.ts +10 -0
  107. package/dist/cli/commands/trait.d.ts.map +1 -0
  108. package/dist/cli/commands/trait.js +295 -0
  109. package/dist/cli/commands/trait.js.map +1 -0
  110. package/dist/cli/commands/validate.d.ts +6 -0
  111. package/dist/cli/commands/validate.d.ts.map +1 -0
  112. package/dist/cli/commands/validate.js +626 -0
  113. package/dist/cli/commands/validate.js.map +1 -0
  114. package/dist/cli/exit-codes.d.ts +62 -0
  115. package/dist/cli/exit-codes.d.ts.map +1 -0
  116. package/dist/cli/exit-codes.js +65 -0
  117. package/dist/cli/exit-codes.js.map +1 -0
  118. package/dist/cli/help/content.d.ts +35 -0
  119. package/dist/cli/help/content.d.ts.map +1 -0
  120. package/dist/cli/help/content.js +312 -0
  121. package/dist/cli/help/content.js.map +1 -0
  122. package/dist/cli/index.d.ts +5 -0
  123. package/dist/cli/index.d.ts.map +1 -0
  124. package/dist/cli/index.js +85 -0
  125. package/dist/cli/index.js.map +1 -0
  126. package/dist/cli/introspection.d.ts +87 -0
  127. package/dist/cli/introspection.d.ts.map +1 -0
  128. package/dist/cli/introspection.js +127 -0
  129. package/dist/cli/introspection.js.map +1 -0
  130. package/dist/cli/output.d.ts +56 -0
  131. package/dist/cli/output.d.ts.map +1 -0
  132. package/dist/cli/output.js +467 -0
  133. package/dist/cli/output.js.map +1 -0
  134. package/dist/cli/suggest.d.ts +16 -0
  135. package/dist/cli/suggest.d.ts.map +1 -0
  136. package/dist/cli/suggest.js +72 -0
  137. package/dist/cli/suggest.js.map +1 -0
  138. package/dist/index.d.ts +3 -0
  139. package/dist/index.d.ts.map +1 -0
  140. package/dist/index.js +5 -0
  141. package/dist/index.js.map +1 -0
  142. package/dist/parser/alignment.d.ts +113 -0
  143. package/dist/parser/alignment.d.ts.map +1 -0
  144. package/dist/parser/alignment.js +261 -0
  145. package/dist/parser/alignment.js.map +1 -0
  146. package/dist/parser/assess.d.ts +81 -0
  147. package/dist/parser/assess.d.ts.map +1 -0
  148. package/dist/parser/assess.js +197 -0
  149. package/dist/parser/assess.js.map +1 -0
  150. package/dist/parser/convention-validation.d.ts +48 -0
  151. package/dist/parser/convention-validation.d.ts.map +1 -0
  152. package/dist/parser/convention-validation.js +167 -0
  153. package/dist/parser/convention-validation.js.map +1 -0
  154. package/dist/parser/fix.d.ts +38 -0
  155. package/dist/parser/fix.d.ts.map +1 -0
  156. package/dist/parser/fix.js +185 -0
  157. package/dist/parser/fix.js.map +1 -0
  158. package/dist/parser/index.d.ts +12 -0
  159. package/dist/parser/index.d.ts.map +1 -0
  160. package/dist/parser/index.js +13 -0
  161. package/dist/parser/index.js.map +1 -0
  162. package/dist/parser/items.d.ts +138 -0
  163. package/dist/parser/items.d.ts.map +1 -0
  164. package/dist/parser/items.js +321 -0
  165. package/dist/parser/items.js.map +1 -0
  166. package/dist/parser/meta.d.ts +120 -0
  167. package/dist/parser/meta.d.ts.map +1 -0
  168. package/dist/parser/meta.js +441 -0
  169. package/dist/parser/meta.js.map +1 -0
  170. package/dist/parser/refs.d.ts +185 -0
  171. package/dist/parser/refs.d.ts.map +1 -0
  172. package/dist/parser/refs.js +404 -0
  173. package/dist/parser/refs.js.map +1 -0
  174. package/dist/parser/shadow.d.ts +253 -0
  175. package/dist/parser/shadow.d.ts.map +1 -0
  176. package/dist/parser/shadow.js +1053 -0
  177. package/dist/parser/shadow.js.map +1 -0
  178. package/dist/parser/traits.d.ts +72 -0
  179. package/dist/parser/traits.d.ts.map +1 -0
  180. package/dist/parser/traits.js +120 -0
  181. package/dist/parser/traits.js.map +1 -0
  182. package/dist/parser/validate.d.ts +89 -0
  183. package/dist/parser/validate.d.ts.map +1 -0
  184. package/dist/parser/validate.js +817 -0
  185. package/dist/parser/validate.js.map +1 -0
  186. package/dist/parser/yaml.d.ts +326 -0
  187. package/dist/parser/yaml.d.ts.map +1 -0
  188. package/dist/parser/yaml.js +1383 -0
  189. package/dist/parser/yaml.js.map +1 -0
  190. package/dist/ralph/cli-renderer.d.ts +20 -0
  191. package/dist/ralph/cli-renderer.d.ts.map +1 -0
  192. package/dist/ralph/cli-renderer.js +179 -0
  193. package/dist/ralph/cli-renderer.js.map +1 -0
  194. package/dist/ralph/events.d.ts +65 -0
  195. package/dist/ralph/events.d.ts.map +1 -0
  196. package/dist/ralph/events.js +397 -0
  197. package/dist/ralph/events.js.map +1 -0
  198. package/dist/ralph/index.d.ts +8 -0
  199. package/dist/ralph/index.d.ts.map +1 -0
  200. package/dist/ralph/index.js +10 -0
  201. package/dist/ralph/index.js.map +1 -0
  202. package/dist/schema/common.d.ts +46 -0
  203. package/dist/schema/common.d.ts.map +1 -0
  204. package/dist/schema/common.js +71 -0
  205. package/dist/schema/common.js.map +1 -0
  206. package/dist/schema/inbox.d.ts +90 -0
  207. package/dist/schema/inbox.d.ts.map +1 -0
  208. package/dist/schema/inbox.js +30 -0
  209. package/dist/schema/inbox.js.map +1 -0
  210. package/dist/schema/index.d.ts +6 -0
  211. package/dist/schema/index.d.ts.map +1 -0
  212. package/dist/schema/index.js +7 -0
  213. package/dist/schema/index.js.map +1 -0
  214. package/dist/schema/meta.d.ts +762 -0
  215. package/dist/schema/meta.d.ts.map +1 -0
  216. package/dist/schema/meta.js +144 -0
  217. package/dist/schema/meta.js.map +1 -0
  218. package/dist/schema/spec.d.ts +912 -0
  219. package/dist/schema/spec.d.ts.map +1 -0
  220. package/dist/schema/spec.js +104 -0
  221. package/dist/schema/spec.js.map +1 -0
  222. package/dist/schema/task.d.ts +664 -0
  223. package/dist/schema/task.d.ts.map +1 -0
  224. package/dist/schema/task.js +130 -0
  225. package/dist/schema/task.js.map +1 -0
  226. package/dist/sessions/index.d.ts +11 -0
  227. package/dist/sessions/index.d.ts.map +1 -0
  228. package/dist/sessions/index.js +13 -0
  229. package/dist/sessions/index.js.map +1 -0
  230. package/dist/sessions/store.d.ts +144 -0
  231. package/dist/sessions/store.d.ts.map +1 -0
  232. package/dist/sessions/store.js +325 -0
  233. package/dist/sessions/store.js.map +1 -0
  234. package/dist/sessions/types.d.ts +157 -0
  235. package/dist/sessions/types.d.ts.map +1 -0
  236. package/dist/sessions/types.js +90 -0
  237. package/dist/sessions/types.js.map +1 -0
  238. package/dist/strings/errors.d.ts +420 -0
  239. package/dist/strings/errors.d.ts.map +1 -0
  240. package/dist/strings/errors.js +282 -0
  241. package/dist/strings/errors.js.map +1 -0
  242. package/dist/strings/guidance.d.ts +65 -0
  243. package/dist/strings/guidance.d.ts.map +1 -0
  244. package/dist/strings/guidance.js +66 -0
  245. package/dist/strings/guidance.js.map +1 -0
  246. package/dist/strings/index.d.ts +12 -0
  247. package/dist/strings/index.d.ts.map +1 -0
  248. package/dist/strings/index.js +12 -0
  249. package/dist/strings/index.js.map +1 -0
  250. package/dist/strings/labels.d.ts +74 -0
  251. package/dist/strings/labels.d.ts.map +1 -0
  252. package/dist/strings/labels.js +75 -0
  253. package/dist/strings/labels.js.map +1 -0
  254. package/dist/strings/validation.d.ts +126 -0
  255. package/dist/strings/validation.d.ts.map +1 -0
  256. package/dist/strings/validation.js +135 -0
  257. package/dist/strings/validation.js.map +1 -0
  258. package/dist/utils/commit.d.ts +23 -0
  259. package/dist/utils/commit.d.ts.map +1 -0
  260. package/dist/utils/commit.js +67 -0
  261. package/dist/utils/commit.js.map +1 -0
  262. package/dist/utils/git.d.ts +57 -0
  263. package/dist/utils/git.d.ts.map +1 -0
  264. package/dist/utils/git.js +192 -0
  265. package/dist/utils/git.js.map +1 -0
  266. package/dist/utils/grep.d.ts +28 -0
  267. package/dist/utils/grep.d.ts.map +1 -0
  268. package/dist/utils/grep.js +86 -0
  269. package/dist/utils/grep.js.map +1 -0
  270. package/dist/utils/index.d.ts +8 -0
  271. package/dist/utils/index.d.ts.map +1 -0
  272. package/dist/utils/index.js +6 -0
  273. package/dist/utils/index.js.map +1 -0
  274. package/dist/utils/time.d.ts +18 -0
  275. package/dist/utils/time.d.ts.map +1 -0
  276. package/dist/utils/time.js +61 -0
  277. package/dist/utils/time.js.map +1 -0
  278. package/package.json +62 -0
@@ -0,0 +1,465 @@
1
+ /**
2
+ * Ralph command - automated task loop via ACP.
3
+ *
4
+ * Runs an ACP-compliant agent in a loop to process tasks autonomously.
5
+ * Uses session event storage for full audit trail and streaming output.
6
+ */
7
+ import chalk from 'chalk';
8
+ import { ulid } from 'ulid';
9
+ import * as fs from 'node:fs/promises';
10
+ import * as path from 'node:path';
11
+ import { spawn, spawnSync } from 'node:child_process';
12
+ import { initContext } from '../../parser/index.js';
13
+ import { error, info, success } from '../output.js';
14
+ import { gatherSessionContext } from './session.js';
15
+ import { resolveAdapter, registerAdapter } from '../../agents/index.js';
16
+ import { spawnAndInitialize } from '../../agents/spawner.js';
17
+ import { createSession, updateSessionStatus, appendEvent, saveSessionContext, } from '../../sessions/index.js';
18
+ import { createTranslator, createCliRenderer } from '../../ralph/index.js';
19
+ import { errors } from '../../strings/index.js';
20
+ import { EXIT_CODES } from '../exit-codes.js';
21
+ // ─── Prompt Template ─────────────────────────────────────────────────────────
22
+ function buildPrompt(sessionCtx, iteration, maxLoops, focus) {
23
+ const isFinal = iteration === maxLoops;
24
+ const focusSection = focus ? `
25
+ ## Session Focus (applies to ALL iterations)
26
+
27
+ > **${focus}**
28
+
29
+ Keep this focus in mind throughout your work. It takes priority over default task selection.
30
+ ` : '';
31
+ return `# Kspec Automation Session
32
+
33
+ You are running as part of a kspec automation loop. This is iteration ${iteration} of ${maxLoops}.
34
+ ${focusSection}
35
+
36
+ ## Current State
37
+ \`\`\`json
38
+ ${JSON.stringify(sessionCtx, null, 2)}
39
+ \`\`\`
40
+
41
+ ## Working Procedure
42
+
43
+ 1. **Pick a task**: Review ready_tasks above. Pick the highest priority task (lowest number = higher priority). If there's an active (in_progress) task, continue that instead.
44
+
45
+ 2. **Start the task** (if not already in_progress):
46
+ \`\`\`bash
47
+ kspec task start @task-ref
48
+ \`\`\`
49
+
50
+ 3. **Do the work**:
51
+ - Read relevant files to understand the task
52
+ - Make changes as needed
53
+ - Run tests if applicable
54
+ - Document as you go with task notes
55
+
56
+ 4. **Document progress**:
57
+ \`\`\`bash
58
+ kspec task note @task-ref "What you did, decisions made, etc."
59
+ \`\`\`
60
+
61
+ 5. **Submit or checkpoint**:
62
+ - If code is DONE (ready for PR):
63
+ \`\`\`bash
64
+ kspec task submit @task-ref
65
+ \`\`\`
66
+ - If task is NOT done (WIP):
67
+ \`\`\`bash
68
+ kspec task note @task-ref "WIP: What's done, what remains..."
69
+ \`\`\`
70
+
71
+ 6. **Commit your work**:
72
+ \`\`\`bash
73
+ git add -A && git commit -m "feat/fix/chore: description
74
+
75
+ Task: @task-ref"
76
+ \`\`\`
77
+
78
+ 7. **Reflect on this iteration**:
79
+ Think about what you learned, any friction points, or patterns worth remembering.
80
+
81
+ For **systemic patterns** (friction or success worth documenting):
82
+ \`\`\`bash
83
+ kspec meta observe friction "Description of systemic issue..."
84
+ kspec meta observe success "Pattern worth replicating..."
85
+ \`\`\`
86
+
87
+ For **actionable improvements** (specific ideas that could become tasks):
88
+ \`\`\`bash
89
+ kspec inbox add "Improvement idea..." --tag reflection
90
+ \`\`\`
91
+
92
+ ## Important Notes
93
+ - Stay focused on ONE task per iteration
94
+ - The loop continues automatically - don't worry about picking the next task
95
+ - kspec tracks state across iterations via task status and notes
96
+ - Always commit before the iteration ends
97
+ - Always reflect and capture at least one observation
98
+ ${isFinal ? `
99
+ ## FINAL ITERATION
100
+ This is the last iteration of the loop. After completing your work:
101
+ 1. Commit any remaining changes
102
+ 2. Reflect on the overall session
103
+ 3. Capture any final insights as observations
104
+ ` : ''}`;
105
+ }
106
+ // ─── Streaming Output ────────────────────────────────────────────────────────
107
+ // Translator and renderer are created per-session in the action handler.
108
+ // This allows the architecture to be reused by future TUI renderers.
109
+ // ─── Adapter Validation ──────────────────────────────────────────────────────
110
+ // AC: @ralph-adapter-validation valid-adapter-proceeds, invalid-adapter-error, validation-before-spawn
111
+ /**
112
+ * Validate that the specified ACP adapter package exists.
113
+ * Uses npx --no-install to check both global and local node_modules.
114
+ *
115
+ * @throws {Error} Never throws - exits process with code 3 if validation fails
116
+ */
117
+ function validateAdapter(adapterPackage) {
118
+ // Use npx --no-install with --version to check if package exists
119
+ // This checks both global and local node_modules, handles scoped packages
120
+ const result = spawnSync('npx', ['--no-install', adapterPackage, '--version'], {
121
+ encoding: 'utf-8',
122
+ stdio: 'pipe',
123
+ });
124
+ if (result.status !== 0) {
125
+ error(`Adapter package not found: ${adapterPackage}. Install with: npm install -g ${adapterPackage}`);
126
+ process.exit(EXIT_CODES.NOT_FOUND);
127
+ }
128
+ }
129
+ // ─── Tool Request Handler ────────────────────────────────────────────────────
130
+ /**
131
+ * Handle tool requests from ACP agent.
132
+ * Implements file operations, terminal commands, and permission handling.
133
+ */
134
+ async function handleRequest(client, id, method, params, yolo) {
135
+ const p = params;
136
+ try {
137
+ switch (method) {
138
+ case 'session/request_permission': {
139
+ // In yolo mode, auto-approve all permissions
140
+ // In normal mode, would need to implement permission UI
141
+ const options = p.options || [];
142
+ if (yolo) {
143
+ // Find an "allow" option (prefer allow_always, then allow_once)
144
+ const allowOption = options.find(o => o.kind === 'allow_always')
145
+ || options.find(o => o.kind === 'allow_once');
146
+ if (allowOption) {
147
+ client.respondPermission(id, {
148
+ outcome: { outcome: 'selected', optionId: allowOption.optionId },
149
+ });
150
+ }
151
+ else {
152
+ // No allow option available - cancel
153
+ client.respondPermission(id, { outcome: { outcome: 'cancelled' } });
154
+ }
155
+ }
156
+ else {
157
+ // TODO: Implement permission prompting
158
+ client.respondPermission(id, { outcome: { outcome: 'cancelled' } });
159
+ }
160
+ break;
161
+ }
162
+ case 'file/read': {
163
+ const filePath = p.path;
164
+ const content = await fs.readFile(filePath, 'utf-8');
165
+ client.respond(id, { content });
166
+ break;
167
+ }
168
+ case 'file/write': {
169
+ const filePath = p.path;
170
+ const content = p.content;
171
+ await fs.mkdir(path.dirname(filePath), { recursive: true });
172
+ await fs.writeFile(filePath, content, 'utf-8');
173
+ client.respond(id, {});
174
+ break;
175
+ }
176
+ case 'terminal/run': {
177
+ const command = p.command;
178
+ const cwd = p.cwd || process.cwd();
179
+ const timeout = p.timeout || 60000;
180
+ const result = await new Promise((resolve) => {
181
+ const child = spawn(command, [], {
182
+ cwd,
183
+ shell: true,
184
+ timeout,
185
+ });
186
+ let stdout = '';
187
+ let stderr = '';
188
+ child.stdout?.on('data', (data) => {
189
+ stdout += data.toString();
190
+ });
191
+ child.stderr?.on('data', (data) => {
192
+ stderr += data.toString();
193
+ });
194
+ child.on('close', (code) => {
195
+ resolve({ stdout, stderr, exitCode: code ?? 1 });
196
+ });
197
+ child.on('error', (err) => {
198
+ resolve({ stdout, stderr: err.message, exitCode: 1 });
199
+ });
200
+ });
201
+ client.respond(id, result);
202
+ break;
203
+ }
204
+ default:
205
+ // Unknown method - return error
206
+ client.respondError(id, -32601, `Method not found: ${method}`);
207
+ }
208
+ }
209
+ catch (err) {
210
+ const message = err instanceof Error ? err.message : String(err);
211
+ client.respondError(id, -32000, message);
212
+ }
213
+ }
214
+ // ─── Command Registration ────────────────────────────────────────────────────
215
+ export function registerRalphCommand(program) {
216
+ program
217
+ .command('ralph')
218
+ .description('Run ACP agent in a loop to process ready tasks')
219
+ .option('--max-loops <n>', 'Maximum iterations', '5')
220
+ .option('--max-retries <n>', 'Max retries per iteration on error', '3')
221
+ .option('--max-failures <n>', 'Max consecutive failed iterations before exit', '3')
222
+ .option('--dry-run', 'Show prompt without executing')
223
+ .option('--yolo', 'Use dangerously-skip-permissions (default)', true)
224
+ .option('--no-yolo', 'Require normal permission prompts')
225
+ .option('--adapter <id>', 'Agent adapter to use', 'claude-code-acp')
226
+ .option('--adapter-cmd <cmd>', 'Custom adapter command (for testing)')
227
+ .option('--focus <instructions>', 'Focus instructions included in every iteration prompt')
228
+ .action(async (options) => {
229
+ try {
230
+ const maxLoops = parseInt(options.maxLoops, 10);
231
+ const maxRetries = parseInt(options.maxRetries, 10);
232
+ const maxFailures = parseInt(options.maxFailures, 10);
233
+ if (isNaN(maxLoops) || maxLoops < 1) {
234
+ error(errors.usage.maxLoopsPositive);
235
+ process.exit(EXIT_CODES.ERROR);
236
+ }
237
+ if (isNaN(maxRetries) || maxRetries < 0) {
238
+ error(errors.usage.maxRetriesNonNegative);
239
+ process.exit(EXIT_CODES.ERROR);
240
+ }
241
+ if (isNaN(maxFailures) || maxFailures < 1) {
242
+ error(errors.usage.maxFailuresPositive);
243
+ process.exit(EXIT_CODES.ERROR);
244
+ }
245
+ // Handle custom adapter command for testing
246
+ if (options.adapterCmd) {
247
+ const parts = options.adapterCmd.split(/\s+/);
248
+ const customAdapter = {
249
+ command: parts[0],
250
+ args: parts.slice(1),
251
+ description: 'Custom adapter via --adapter-cmd',
252
+ };
253
+ registerAdapter('custom', customAdapter);
254
+ options.adapter = 'custom';
255
+ }
256
+ // Resolve adapter
257
+ const adapter = resolveAdapter(options.adapter);
258
+ // Validate adapter package exists before proceeding
259
+ // Skip validation for custom adapters (--adapter-cmd) and non-npx adapters
260
+ if (!options.adapterCmd && adapter.command === 'npx' && adapter.args[0]) {
261
+ validateAdapter(adapter.args[0]);
262
+ }
263
+ // Add yolo flag to adapter args if needed
264
+ if (options.yolo && options.adapter === 'claude-code-acp') {
265
+ adapter.args = [...adapter.args, '--dangerously-skip-permissions'];
266
+ }
267
+ info(`Starting ralph loop (adapter=${options.adapter}, max ${maxLoops} iterations, ${maxRetries} retries, ${maxFailures} max failures)`);
268
+ if (options.focus) {
269
+ info(`Focus: ${options.focus}`);
270
+ }
271
+ // Initialize kspec context
272
+ const ctx = await initContext();
273
+ const specDir = ctx.specDir;
274
+ // Create session for event tracking
275
+ const sessionId = ulid();
276
+ await createSession(specDir, {
277
+ id: sessionId,
278
+ agent_type: options.adapter,
279
+ task_id: undefined, // Will be determined per iteration
280
+ });
281
+ // Log session start
282
+ await appendEvent(specDir, {
283
+ session_id: sessionId,
284
+ type: 'session.start',
285
+ data: {
286
+ adapter: options.adapter,
287
+ maxLoops,
288
+ maxRetries,
289
+ maxFailures,
290
+ yolo: options.yolo,
291
+ focus: options.focus,
292
+ },
293
+ });
294
+ let consecutiveFailures = 0;
295
+ let agent = null;
296
+ let acpSessionId = null;
297
+ // Create translator and renderer for this session
298
+ const translator = createTranslator();
299
+ const renderer = createCliRenderer();
300
+ try {
301
+ for (let iteration = 1; iteration <= maxLoops; iteration++) {
302
+ renderer.newSection?.(`Iteration ${iteration}/${maxLoops}`);
303
+ // Gather fresh context each iteration (only automation-eligible tasks)
304
+ // AC: @cli-ralph ac-16
305
+ const sessionCtx = await gatherSessionContext(ctx, { limit: '10', eligible: true });
306
+ // Check for ready tasks or active tasks
307
+ const hasActiveTasks = sessionCtx.active_tasks.length > 0;
308
+ const hasReadyTasks = sessionCtx.ready_tasks.length > 0;
309
+ if (!hasActiveTasks && !hasReadyTasks) {
310
+ info('No active or eligible ready tasks. Exiting loop.');
311
+ break;
312
+ }
313
+ // Build prompt
314
+ const prompt = buildPrompt(sessionCtx, iteration, maxLoops, options.focus);
315
+ if (options.dryRun) {
316
+ console.log(chalk.yellow('=== DRY RUN - Prompt that would be sent ===\n'));
317
+ console.log(prompt);
318
+ console.log(chalk.yellow('\n=== END DRY RUN ==='));
319
+ break;
320
+ }
321
+ // Log prompt
322
+ await appendEvent(specDir, {
323
+ session_id: sessionId,
324
+ type: 'prompt.sent',
325
+ data: {
326
+ iteration,
327
+ prompt,
328
+ tasks: {
329
+ active: sessionCtx.active_tasks.map(t => t.ref),
330
+ ready: sessionCtx.ready_tasks.map(t => t.ref),
331
+ },
332
+ },
333
+ });
334
+ // Retry loop for this iteration
335
+ let lastError = null;
336
+ let succeeded = false;
337
+ for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
338
+ if (attempt > 1) {
339
+ console.log(chalk.yellow(`\nRetry attempt ${attempt - 1}/${maxRetries}...`));
340
+ }
341
+ try {
342
+ // Spawn agent if not already running
343
+ if (!agent) {
344
+ info('Spawning ACP agent...');
345
+ agent = await spawnAndInitialize(adapter, {
346
+ cwd: process.cwd(),
347
+ clientOptions: {
348
+ clientInfo: {
349
+ name: 'kspec-ralph',
350
+ version: '0.1.0',
351
+ },
352
+ },
353
+ });
354
+ // Set up streaming update handler with translator + renderer
355
+ agent.client.on('update', (_sid, update) => {
356
+ // Translate ACP event to RalphEvent and render
357
+ const event = translator.translate(update);
358
+ if (event) {
359
+ renderer.render(event);
360
+ }
361
+ // Log raw update event (async, non-blocking)
362
+ appendEvent(specDir, {
363
+ session_id: sessionId,
364
+ type: 'session.update',
365
+ data: { iteration, update },
366
+ }).catch(() => {
367
+ // Ignore logging errors during streaming
368
+ });
369
+ });
370
+ // Set up tool request handler
371
+ agent.client.on('request', (reqId, method, params) => {
372
+ handleRequest(agent.client, reqId, method, params, options.yolo).catch((err) => {
373
+ agent.client.respondError(reqId, -32000, err.message);
374
+ });
375
+ });
376
+ }
377
+ // Create fresh ACP session per iteration to keep context clean
378
+ info('Creating ACP session...');
379
+ acpSessionId = await agent.client.newSession({
380
+ cwd: process.cwd(),
381
+ mcpServers: [], // No MCP servers for now
382
+ });
383
+ info('Sending prompt to agent...');
384
+ // Send prompt and wait for completion
385
+ const response = await agent.client.prompt({
386
+ sessionId: acpSessionId,
387
+ prompt: [{ type: 'text', text: prompt }],
388
+ });
389
+ // Log completion
390
+ await appendEvent(specDir, {
391
+ session_id: sessionId,
392
+ type: 'session.update',
393
+ data: {
394
+ iteration,
395
+ stopReason: response.stopReason,
396
+ completed: true,
397
+ },
398
+ });
399
+ // Check stop reason
400
+ if (response.stopReason === 'cancelled') {
401
+ throw new Error(errors.usage.agentPromptCancelled);
402
+ }
403
+ succeeded = true;
404
+ break;
405
+ }
406
+ catch (err) {
407
+ lastError = err;
408
+ error(errors.failures.iterationFailed(lastError.message));
409
+ // Clean up agent on error - will respawn next attempt
410
+ if (agent) {
411
+ agent.kill();
412
+ agent = null;
413
+ acpSessionId = null;
414
+ }
415
+ }
416
+ }
417
+ if (succeeded) {
418
+ console.log(); // Newline after streaming output
419
+ // Save session context snapshot for audit trail
420
+ await saveSessionContext(specDir, sessionId, iteration, sessionCtx);
421
+ success(`Completed iteration ${iteration}`);
422
+ consecutiveFailures = 0;
423
+ }
424
+ else {
425
+ consecutiveFailures++;
426
+ error(errors.failures.iterationFailedAfterRetries(iteration, maxRetries, consecutiveFailures, maxFailures));
427
+ if (lastError) {
428
+ error(errors.failures.lastError(lastError.message));
429
+ }
430
+ if (consecutiveFailures >= maxFailures) {
431
+ error(errors.failures.reachedMaxFailures(maxFailures));
432
+ break;
433
+ }
434
+ info('Continuing to next iteration...');
435
+ }
436
+ }
437
+ }
438
+ finally {
439
+ // Clean up agent
440
+ if (agent) {
441
+ agent.kill();
442
+ }
443
+ // Log session end
444
+ const status = consecutiveFailures >= maxFailures ? 'abandoned' : 'completed';
445
+ await appendEvent(specDir, {
446
+ session_id: sessionId,
447
+ type: 'session.end',
448
+ data: {
449
+ status,
450
+ consecutiveFailures,
451
+ },
452
+ });
453
+ await updateSessionStatus(specDir, sessionId, status);
454
+ }
455
+ console.log(chalk.green(`\n${'─'.repeat(60)}`));
456
+ success('Ralph loop completed');
457
+ console.log(chalk.green(`${'─'.repeat(60)}\n`));
458
+ }
459
+ catch (err) {
460
+ error(errors.failures.ralphLoop, err);
461
+ process.exit(EXIT_CODES.ERROR);
462
+ }
463
+ });
464
+ }
465
+ //# sourceMappingURL=ralph.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ralph.js","sourceRoot":"","sources":["../../../src/cli/commands/ralph.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Register the search command
4
+ */
5
+ export declare function registerSearchCommand(program: Command): void;
6
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmEpC;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwF5D"}
@@ -0,0 +1,134 @@
1
+ import chalk from 'chalk';
2
+ import { initContext, buildIndexes, } from '../../parser/index.js';
3
+ import { output, error } from '../output.js';
4
+ import { grepItem, formatMatchedFields } from '../../utils/grep.js';
5
+ import { errors } from '../../strings/index.js';
6
+ import { EXIT_CODES } from '../exit-codes.js';
7
+ /**
8
+ * Format a spec item for search results
9
+ */
10
+ function formatSearchItem(item, matchedFields) {
11
+ const shortId = item._ulid.slice(0, 8);
12
+ const slugStr = item.slugs.length > 0 ? chalk.cyan(`@${item.slugs[0]}`) : '';
13
+ const typeStr = chalk.gray(`[${item.type}]`);
14
+ let status = '';
15
+ if (item.status && typeof item.status === 'object') {
16
+ const s = item.status;
17
+ if (s.implementation) {
18
+ const implColor = s.implementation === 'verified' ? chalk.green
19
+ : s.implementation === 'implemented' ? chalk.cyan
20
+ : s.implementation === 'in_progress' ? chalk.yellow
21
+ : chalk.gray;
22
+ status = implColor(s.implementation);
23
+ }
24
+ }
25
+ let line = `${chalk.gray(shortId)} ${typeStr} ${item.title}`;
26
+ if (slugStr)
27
+ line += ` ${slugStr}`;
28
+ if (status)
29
+ line += ` ${status}`;
30
+ console.log(line);
31
+ console.log(chalk.gray(` matched: ${formatMatchedFields(matchedFields)}`));
32
+ }
33
+ /**
34
+ * Format a task for search results
35
+ */
36
+ function formatSearchTask(task, matchedFields) {
37
+ const shortId = task._ulid.slice(0, 8);
38
+ const slugStr = task.slugs.length > 0 ? chalk.cyan(`@${task.slugs[0]}`) : '';
39
+ const statusColor = task.status === 'completed' ? chalk.green
40
+ : task.status === 'in_progress' ? chalk.blue
41
+ : task.status === 'blocked' ? chalk.red
42
+ : chalk.gray;
43
+ const priority = task.priority <= 2 ? chalk.red(`P${task.priority}`) : chalk.gray(`P${task.priority}`);
44
+ let line = `${chalk.gray(shortId)} ${statusColor(`[${task.status}]`)} ${priority} ${task.title}`;
45
+ if (slugStr)
46
+ line += ` ${slugStr}`;
47
+ console.log(line);
48
+ console.log(chalk.gray(` matched: ${formatMatchedFields(matchedFields)}`));
49
+ }
50
+ /**
51
+ * Register the search command
52
+ */
53
+ export function registerSearchCommand(program) {
54
+ program
55
+ .command('search <pattern>')
56
+ .description('Search across all items and tasks with regex pattern')
57
+ .option('-t, --type <type>', 'Filter by item type')
58
+ .option('-s, --status <status>', 'Filter by task status')
59
+ .option('--items-only', 'Search only spec items')
60
+ .option('--tasks-only', 'Search only tasks')
61
+ .option('--limit <n>', 'Limit results', '50')
62
+ .action(async (pattern, options) => {
63
+ try {
64
+ const ctx = await initContext();
65
+ const { itemIndex, tasks, items, refIndex } = await buildIndexes(ctx);
66
+ const results = [];
67
+ const limit = parseInt(options.limit, 10) || 50;
68
+ // Search spec items
69
+ if (!options.tasksOnly) {
70
+ for (const item of items) {
71
+ // Apply type filter
72
+ if (options.type && item.type !== options.type)
73
+ continue;
74
+ const match = grepItem(item, pattern);
75
+ if (match) {
76
+ results.push({
77
+ type: 'item',
78
+ item,
79
+ matchedFields: match.matchedFields,
80
+ });
81
+ }
82
+ }
83
+ }
84
+ // Search tasks
85
+ if (!options.itemsOnly) {
86
+ for (const task of tasks) {
87
+ // Apply status filter
88
+ if (options.status && task.status !== options.status)
89
+ continue;
90
+ const match = grepItem(task, pattern);
91
+ if (match) {
92
+ results.push({
93
+ type: 'task',
94
+ item: task,
95
+ matchedFields: match.matchedFields,
96
+ });
97
+ }
98
+ }
99
+ }
100
+ // Limit results
101
+ const limitedResults = results.slice(0, limit);
102
+ output({
103
+ pattern,
104
+ results: limitedResults.map(r => ({
105
+ type: r.type,
106
+ ulid: r.item._ulid,
107
+ title: r.item.title,
108
+ matchedFields: r.matchedFields,
109
+ })),
110
+ total: results.length,
111
+ showing: limitedResults.length,
112
+ }, () => {
113
+ if (limitedResults.length === 0) {
114
+ console.log(chalk.gray(`No matches found for "${pattern}"`));
115
+ return;
116
+ }
117
+ for (const result of limitedResults) {
118
+ if (result.type === 'item') {
119
+ formatSearchItem(result.item, result.matchedFields);
120
+ }
121
+ else {
122
+ formatSearchTask(result.item, result.matchedFields);
123
+ }
124
+ }
125
+ console.log(chalk.gray(`\n${limitedResults.length} result(s)${results.length > limit ? ` (showing first ${limit})` : ''}`));
126
+ });
127
+ }
128
+ catch (err) {
129
+ error(errors.failures.search, err);
130
+ process.exit(EXIT_CODES.ERROR);
131
+ }
132
+ });
133
+ }
134
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../../src/cli/commands/search.ts"],"names":[],"mappings":"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"}