@kynetic-ai/spec 0.9.0 → 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 (291) hide show
  1. package/README.md +2 -1
  2. package/dist/acp/client.d.ts +13 -1
  3. package/dist/acp/client.d.ts.map +1 -1
  4. package/dist/acp/client.js +17 -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 +183 -81
  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/agents.d.ts +1 -1
  41. package/dist/cli/commands/agents.d.ts.map +1 -1
  42. package/dist/cli/commands/agents.js +2 -1
  43. package/dist/cli/commands/agents.js.map +1 -1
  44. package/dist/cli/commands/batch.js +1 -1
  45. package/dist/cli/commands/batch.js.map +1 -1
  46. package/dist/cli/commands/inbox.d.ts.map +1 -1
  47. package/dist/cli/commands/inbox.js +46 -22
  48. package/dist/cli/commands/inbox.js.map +1 -1
  49. package/dist/cli/commands/index.d.ts +1 -0
  50. package/dist/cli/commands/index.d.ts.map +1 -1
  51. package/dist/cli/commands/index.js +1 -0
  52. package/dist/cli/commands/index.js.map +1 -1
  53. package/dist/cli/commands/init.d.ts.map +1 -1
  54. package/dist/cli/commands/init.js +4 -6
  55. package/dist/cli/commands/init.js.map +1 -1
  56. package/dist/cli/commands/item.d.ts.map +1 -1
  57. package/dist/cli/commands/item.js +34 -17
  58. package/dist/cli/commands/item.js.map +1 -1
  59. package/dist/cli/commands/log.js +1 -1
  60. package/dist/cli/commands/log.js.map +1 -1
  61. package/dist/cli/commands/merge-driver.d.ts.map +1 -1
  62. package/dist/cli/commands/merge-driver.js +8 -3
  63. package/dist/cli/commands/merge-driver.js.map +1 -1
  64. package/dist/cli/commands/meta.d.ts.map +1 -1
  65. package/dist/cli/commands/meta.js +159 -6
  66. package/dist/cli/commands/meta.js.map +1 -1
  67. package/dist/cli/commands/module.d.ts.map +1 -1
  68. package/dist/cli/commands/module.js +2 -1
  69. package/dist/cli/commands/module.js.map +1 -1
  70. package/dist/cli/commands/plan-import.js +19 -3
  71. package/dist/cli/commands/plan-import.js.map +1 -1
  72. package/dist/cli/commands/plan.d.ts.map +1 -1
  73. package/dist/cli/commands/plan.js +87 -43
  74. package/dist/cli/commands/plan.js.map +1 -1
  75. package/dist/cli/commands/ralph.d.ts +5 -51
  76. package/dist/cli/commands/ralph.d.ts.map +1 -1
  77. package/dist/cli/commands/ralph.js +52 -1462
  78. package/dist/cli/commands/ralph.js.map +1 -1
  79. package/dist/cli/commands/search.d.ts.map +1 -1
  80. package/dist/cli/commands/search.js +22 -13
  81. package/dist/cli/commands/search.js.map +1 -1
  82. package/dist/cli/commands/serve.d.ts.map +1 -1
  83. package/dist/cli/commands/serve.js +70 -11
  84. package/dist/cli/commands/serve.js.map +1 -1
  85. package/dist/cli/commands/session/checkpoint.d.ts.map +1 -1
  86. package/dist/cli/commands/session/checkpoint.js +7 -2
  87. package/dist/cli/commands/session/checkpoint.js.map +1 -1
  88. package/dist/cli/commands/session/commands.d.ts.map +1 -1
  89. package/dist/cli/commands/session/commands.js +15 -0
  90. package/dist/cli/commands/session/commands.js.map +1 -1
  91. package/dist/cli/commands/session/context.d.ts.map +1 -1
  92. package/dist/cli/commands/session/context.js +10 -5
  93. package/dist/cli/commands/session/context.js.map +1 -1
  94. package/dist/cli/commands/session/log.d.ts +1 -0
  95. package/dist/cli/commands/session/log.d.ts.map +1 -1
  96. package/dist/cli/commands/session/log.js +124 -8
  97. package/dist/cli/commands/session/log.js.map +1 -1
  98. package/dist/cli/commands/session/stale-close.d.ts +17 -0
  99. package/dist/cli/commands/session/stale-close.d.ts.map +1 -0
  100. package/dist/cli/commands/session/stale-close.js +378 -0
  101. package/dist/cli/commands/session/stale-close.js.map +1 -0
  102. package/dist/cli/commands/setup.d.ts +4 -0
  103. package/dist/cli/commands/setup.d.ts.map +1 -1
  104. package/dist/cli/commands/setup.js +150 -6
  105. package/dist/cli/commands/setup.js.map +1 -1
  106. package/dist/cli/commands/skill-crud.d.ts.map +1 -1
  107. package/dist/cli/commands/skill-crud.js +4 -3
  108. package/dist/cli/commands/skill-crud.js.map +1 -1
  109. package/dist/cli/commands/skill-diff.d.ts.map +1 -1
  110. package/dist/cli/commands/skill-diff.js +15 -0
  111. package/dist/cli/commands/skill-diff.js.map +1 -1
  112. package/dist/cli/commands/skill-install.d.ts.map +1 -1
  113. package/dist/cli/commands/skill-install.js +50 -18
  114. package/dist/cli/commands/skill-install.js.map +1 -1
  115. package/dist/cli/commands/task.d.ts.map +1 -1
  116. package/dist/cli/commands/task.js +552 -323
  117. package/dist/cli/commands/task.js.map +1 -1
  118. package/dist/cli/commands/tasks.js +1 -1
  119. package/dist/cli/commands/tasks.js.map +1 -1
  120. package/dist/cli/commands/triage.d.ts.map +1 -1
  121. package/dist/cli/commands/triage.js +37 -13
  122. package/dist/cli/commands/triage.js.map +1 -1
  123. package/dist/cli/commands/validate.d.ts.map +1 -1
  124. package/dist/cli/commands/validate.js +99 -50
  125. package/dist/cli/commands/validate.js.map +1 -1
  126. package/dist/cli/help/content.d.ts.map +1 -1
  127. package/dist/cli/help/content.js +5 -0
  128. package/dist/cli/help/content.js.map +1 -1
  129. package/dist/cli/index.d.ts.map +1 -1
  130. package/dist/cli/index.js +2 -1
  131. package/dist/cli/index.js.map +1 -1
  132. package/dist/cli/output.d.ts.map +1 -1
  133. package/dist/cli/output.js +5 -1
  134. package/dist/cli/output.js.map +1 -1
  135. package/dist/cli/validators.d.ts +4 -0
  136. package/dist/cli/validators.d.ts.map +1 -1
  137. package/dist/cli/validators.js +12 -0
  138. package/dist/cli/validators.js.map +1 -1
  139. package/dist/daemon/project-context.ts +22 -0
  140. package/dist/daemon/routes/agent-dispatch.ts +272 -0
  141. package/dist/daemon/server.ts +55 -20
  142. package/dist/daemon/websocket/handler.ts +67 -6
  143. package/dist/daemon/websocket/lifecycle.ts +19 -0
  144. package/dist/daemon/websocket/pubsub.ts +74 -3
  145. package/dist/export/html.d.ts.map +1 -1
  146. package/dist/export/html.js +5 -2
  147. package/dist/export/html.js.map +1 -1
  148. package/dist/export/triage.d.ts +1 -1
  149. package/dist/export/triage.d.ts.map +1 -1
  150. package/dist/export/triage.js +5 -3
  151. package/dist/export/triage.js.map +1 -1
  152. package/dist/parser/alignment.d.ts.map +1 -1
  153. package/dist/parser/alignment.js +6 -3
  154. package/dist/parser/alignment.js.map +1 -1
  155. package/dist/parser/assess.js +1 -1
  156. package/dist/parser/assess.js.map +1 -1
  157. package/dist/parser/config.d.ts +6 -6
  158. package/dist/parser/meta.d.ts.map +1 -1
  159. package/dist/parser/meta.js +9 -8
  160. package/dist/parser/meta.js.map +1 -1
  161. package/dist/parser/plan-document.d.ts +12 -12
  162. package/dist/parser/plans.d.ts +7 -0
  163. package/dist/parser/plans.d.ts.map +1 -1
  164. package/dist/parser/plans.js +100 -15
  165. package/dist/parser/plans.js.map +1 -1
  166. package/dist/parser/refs.d.ts +5 -0
  167. package/dist/parser/refs.d.ts.map +1 -1
  168. package/dist/parser/refs.js +17 -12
  169. package/dist/parser/refs.js.map +1 -1
  170. package/dist/parser/shadow.d.ts +1 -1
  171. package/dist/parser/shadow.d.ts.map +1 -1
  172. package/dist/parser/shadow.js +241 -76
  173. package/dist/parser/shadow.js.map +1 -1
  174. package/dist/parser/skill-render.d.ts.map +1 -1
  175. package/dist/parser/skill-render.js +6 -3
  176. package/dist/parser/skill-render.js.map +1 -1
  177. package/dist/parser/validate.d.ts.map +1 -1
  178. package/dist/parser/validate.js +70 -108
  179. package/dist/parser/validate.js.map +1 -1
  180. package/dist/parser/yaml.d.ts +24 -5
  181. package/dist/parser/yaml.d.ts.map +1 -1
  182. package/dist/parser/yaml.js +228 -66
  183. package/dist/parser/yaml.js.map +1 -1
  184. package/dist/schema/meta.d.ts +442 -119
  185. package/dist/schema/meta.d.ts.map +1 -1
  186. package/dist/schema/meta.js +55 -0
  187. package/dist/schema/meta.js.map +1 -1
  188. package/dist/schema/plan.d.ts +22 -22
  189. package/dist/schema/spec.d.ts +39 -39
  190. package/dist/schema/task.d.ts +43 -32
  191. package/dist/schema/task.d.ts.map +1 -1
  192. package/dist/schema/task.js +5 -0
  193. package/dist/schema/task.js.map +1 -1
  194. package/dist/sessions/store.d.ts +112 -0
  195. package/dist/sessions/store.d.ts.map +1 -1
  196. package/dist/sessions/store.js +414 -22
  197. package/dist/sessions/store.js.map +1 -1
  198. package/dist/sessions/types.d.ts +75 -17
  199. package/dist/sessions/types.d.ts.map +1 -1
  200. package/dist/sessions/types.js +51 -1
  201. package/dist/sessions/types.js.map +1 -1
  202. package/dist/triage/actions.d.ts +1 -0
  203. package/dist/triage/actions.d.ts.map +1 -1
  204. package/dist/triage/actions.js +34 -7
  205. package/dist/triage/actions.js.map +1 -1
  206. package/dist/utils/commit.js +1 -1
  207. package/dist/utils/commit.js.map +1 -1
  208. package/dist/web-ui/_app/env.js +1 -0
  209. package/dist/web-ui/_app/immutable/assets/0.BxCxvrZR.css +1 -0
  210. package/dist/web-ui/_app/immutable/assets/select-trigger.CV-KWLNP.css +1 -0
  211. package/dist/web-ui/_app/immutable/chunks/B-CZR0q8.js +1 -0
  212. package/dist/web-ui/_app/immutable/chunks/B1IR5Su5.js +1 -0
  213. package/dist/web-ui/_app/immutable/chunks/BCkp8Hs8.js +1 -0
  214. package/dist/web-ui/_app/immutable/chunks/B_Cvvtc4.js +1 -0
  215. package/dist/web-ui/_app/immutable/chunks/BtFaGGII.js +1 -0
  216. package/dist/web-ui/_app/immutable/chunks/Bu8JVsCH.js +1 -0
  217. package/dist/web-ui/_app/immutable/chunks/C87u-CNA.js +1 -0
  218. package/dist/web-ui/_app/immutable/chunks/CrFkBTYp.js +1 -0
  219. package/dist/web-ui/_app/immutable/chunks/D1ArdqNb.js +1 -0
  220. package/dist/web-ui/_app/immutable/chunks/D28BF5MJ.js +1 -0
  221. package/dist/web-ui/_app/immutable/chunks/D6RtLpzL.js +1 -0
  222. package/dist/web-ui/_app/immutable/chunks/D7FHSgx2.js +1 -0
  223. package/dist/web-ui/_app/immutable/chunks/DBXrsxZQ.js +2 -0
  224. package/dist/web-ui/_app/immutable/chunks/Da_hHMuA.js +1 -0
  225. package/dist/web-ui/_app/immutable/chunks/Do6LchSF.js +1 -0
  226. package/dist/web-ui/_app/immutable/chunks/DoNPtcAw.js +1 -0
  227. package/dist/web-ui/_app/immutable/chunks/DtUbXRZz.js +1 -0
  228. package/dist/web-ui/_app/immutable/chunks/DyFPRlLl.js +1 -0
  229. package/dist/web-ui/_app/immutable/chunks/DzAP8lRM.js +1 -0
  230. package/dist/web-ui/_app/immutable/chunks/DzVXElzN.js +2 -0
  231. package/dist/web-ui/_app/immutable/chunks/aoPBFken.js +1 -0
  232. package/dist/web-ui/_app/immutable/chunks/i-XnOIX0.js +1 -0
  233. package/dist/web-ui/_app/immutable/chunks/laxtrUO3.js +1 -0
  234. package/dist/web-ui/_app/immutable/chunks/q1nIWgqB.js +1 -0
  235. package/dist/web-ui/_app/immutable/chunks/sTLbk5Nm.js +1 -0
  236. package/dist/web-ui/_app/immutable/chunks/vwKgQu5P.js +5 -0
  237. package/dist/web-ui/_app/immutable/entry/app.BCwMcqnT.js +2 -0
  238. package/dist/web-ui/_app/immutable/entry/start.wKCQH-tt.js +1 -0
  239. package/dist/web-ui/_app/immutable/nodes/0.CjGVMG74.js +1 -0
  240. package/dist/web-ui/_app/immutable/nodes/1.B6_AIPan.js +1 -0
  241. package/dist/web-ui/_app/immutable/nodes/2.q4oCS7Ws.js +1 -0
  242. package/dist/web-ui/_app/immutable/nodes/3.rTKZf9o2.js +1 -0
  243. package/dist/web-ui/_app/immutable/nodes/4.DVIDRu1d.js +1 -0
  244. package/dist/web-ui/_app/immutable/nodes/5.8PtPXIOd.js +1 -0
  245. package/dist/web-ui/_app/immutable/nodes/6.ZZrTemy_.js +1 -0
  246. package/dist/web-ui/_app/immutable/nodes/7.IP-gxCxi.js +1 -0
  247. package/dist/web-ui/_app/version.json +1 -0
  248. package/dist/web-ui/index.html +36 -0
  249. package/dist/web-ui/robots.txt +3 -0
  250. package/package.json +3 -2
  251. package/plugin/.claude-plugin/marketplace.json +1 -1
  252. package/plugin/.claude-plugin/plugin.json +1 -1
  253. package/plugin/plugins/kspec/skills/create-workflow/SKILL.md +1 -1
  254. package/plugin/plugins/kspec/skills/{observations → observe}/SKILL.md +1 -1
  255. package/plugin/plugins/kspec/skills/plan/SKILL.md +1 -1
  256. package/plugin/plugins/kspec/skills/task-work/SKILL.md +26 -3
  257. package/plugin/plugins/kspec/skills/triage-inbox/SKILL.md +1 -1
  258. package/plugin/plugins/kspec/skills/writing-specs/SKILL.md +1 -1
  259. package/templates/agents-sections/01-quick-start.md +1 -0
  260. package/templates/agents-sections/06-ralph-loop.md +64 -11
  261. package/templates/skills/create-workflow/SKILL.md +1 -1
  262. package/templates/skills/manifest.yaml +1 -1
  263. package/templates/skills/plan/SKILL.md +1 -1
  264. package/templates/skills/task-work/SKILL.md +26 -3
  265. package/templates/skills/triage-inbox/SKILL.md +1 -1
  266. package/templates/skills/writing-specs/SKILL.md +1 -1
  267. package/dist/ralph/cli-renderer.d.ts +0 -27
  268. package/dist/ralph/cli-renderer.d.ts.map +0 -1
  269. package/dist/ralph/cli-renderer.js +0 -250
  270. package/dist/ralph/cli-renderer.js.map +0 -1
  271. package/dist/ralph/events.d.ts +0 -65
  272. package/dist/ralph/events.d.ts.map +0 -1
  273. package/dist/ralph/events.js +0 -600
  274. package/dist/ralph/events.js.map +0 -1
  275. package/dist/ralph/index.d.ts +0 -11
  276. package/dist/ralph/index.d.ts.map +0 -1
  277. package/dist/ralph/index.js +0 -16
  278. package/dist/ralph/index.js.map +0 -1
  279. package/dist/ralph/loop-errors.d.ts +0 -83
  280. package/dist/ralph/loop-errors.d.ts.map +0 -1
  281. package/dist/ralph/loop-errors.js +0 -150
  282. package/dist/ralph/loop-errors.js.map +0 -1
  283. package/dist/ralph/subagent.d.ts +0 -96
  284. package/dist/ralph/subagent.d.ts.map +0 -1
  285. package/dist/ralph/subagent.js +0 -195
  286. package/dist/ralph/subagent.js.map +0 -1
  287. package/dist/ralph/wrap-up.d.ts +0 -127
  288. package/dist/ralph/wrap-up.d.ts.map +0 -1
  289. package/dist/ralph/wrap-up.js +0 -271
  290. package/dist/ralph/wrap-up.js.map +0 -1
  291. /package/templates/skills/{observations → observe}/SKILL.md +0 -0
@@ -0,0 +1,378 @@
1
+ /**
2
+ * Session stale close command.
3
+ *
4
+ * Orchestrates stale-session candidate selection + auto-abandon metadata apply.
5
+ */
6
+ import { initContext } from "../../../parser/index.js";
7
+ import { applyAutoAbandonMetadata, getSession, resolveSessionId, resolveStaleSessionCriteria, selectStaleActiveSessions, } from "../../../sessions/store.js";
8
+ import { EXIT_CODES } from "../../exit-codes.js";
9
+ import { error, isJsonMode, output } from "../../output.js";
10
+ function normalizeSessionRef(ref) {
11
+ return ref.startsWith("@") ? ref.slice(1) : ref;
12
+ }
13
+ function describeNotCandidate(evaluation) {
14
+ if (evaluation.blockedByLivenessGuard) {
15
+ return "Session has recent activity inside liveness guard window";
16
+ }
17
+ if (!evaluation.meetsAgeThreshold && !evaluation.meetsInactivityThreshold) {
18
+ return "Session does not meet older-than or inactive-for thresholds";
19
+ }
20
+ if (!evaluation.meetsAgeThreshold) {
21
+ return "Session does not meet older-than threshold";
22
+ }
23
+ if (!evaluation.meetsInactivityThreshold) {
24
+ return "Session does not meet inactive-for threshold";
25
+ }
26
+ return "Session is not eligible for stale auto-close";
27
+ }
28
+ async function promptConfirmation(question) {
29
+ const readline = await import("node:readline");
30
+ const rl = readline.createInterface({
31
+ input: process.stdin,
32
+ output: process.stdout,
33
+ });
34
+ const answer = await new Promise((resolve) => {
35
+ rl.question(question, resolve);
36
+ });
37
+ rl.close();
38
+ return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
39
+ }
40
+ function buildConfirmationQuestion(mode, candidates) {
41
+ if (mode === "single") {
42
+ return "Auto-abandon this stale session? [y/N] ";
43
+ }
44
+ if (mode === "refs") {
45
+ return `Auto-abandon ${candidates} stale session(s) from --refs? [y/N] `;
46
+ }
47
+ return `Auto-abandon ${candidates} stale active session(s)? [y/N] `;
48
+ }
49
+ export async function sessionStaleCloseAction(sessionIdOrPrefix, options) {
50
+ try {
51
+ const ctx = await initContext();
52
+ const refs = options.refs ?? [];
53
+ const hasRefs = refs.length > 0;
54
+ const hasSingleTarget = typeof sessionIdOrPrefix === "string";
55
+ const allMode = options.all === true;
56
+ const dryRun = options.dryRun === true;
57
+ if (!allMode && !hasSingleTarget && !hasRefs) {
58
+ error("Missing target. Provide <session-id>, --refs, or --all.", "Try: kspec session stale close <session-id> | --refs <session-id...> | --all");
59
+ process.exit(EXIT_CODES.USAGE_ERROR);
60
+ }
61
+ if (allMode && hasSingleTarget) {
62
+ error("Cannot use <session-id> together with --all");
63
+ process.exit(EXIT_CODES.USAGE_ERROR);
64
+ }
65
+ if (allMode && hasRefs) {
66
+ error("Cannot use --refs together with --all");
67
+ process.exit(EXIT_CODES.USAGE_ERROR);
68
+ }
69
+ if (hasSingleTarget && hasRefs) {
70
+ error("Cannot use <session-id> together with --refs");
71
+ process.exit(EXIT_CODES.USAGE_ERROR);
72
+ }
73
+ const resolvedCriteria = resolveStaleSessionCriteria({
74
+ olderThan: options.olderThan,
75
+ inactiveFor: options.inactiveFor,
76
+ livenessGuard: options.livenessGuard,
77
+ });
78
+ if (!resolvedCriteria.ok) {
79
+ error(resolvedCriteria.message, {
80
+ field: resolvedCriteria.field,
81
+ value: resolvedCriteria.value,
82
+ guidance: resolvedCriteria.guidance,
83
+ });
84
+ process.exit(EXIT_CODES.USAGE_ERROR);
85
+ }
86
+ const selection = await selectStaleActiveSessions(ctx.specDir, {
87
+ olderThan: options.olderThan,
88
+ inactiveFor: options.inactiveFor,
89
+ livenessGuard: options.livenessGuard,
90
+ });
91
+ const evaluationById = new Map(selection.evaluations.map((evaluation) => [evaluation.sessionId, evaluation]));
92
+ const skippedById = new Map(selection.skipped.map((skipped) => [skipped.sessionId, skipped]));
93
+ const results = [];
94
+ const targetCandidates = [];
95
+ let failures = 0;
96
+ let mode;
97
+ let targetSessionId;
98
+ const targetRefs = [];
99
+ if (allMode) {
100
+ mode = "all";
101
+ for (const skipped of selection.skipped) {
102
+ results.push({
103
+ session_id: skipped.sessionId,
104
+ status: "skipped_error",
105
+ reason: skipped.detail,
106
+ });
107
+ }
108
+ for (const evaluation of selection.evaluations) {
109
+ if (evaluation.eligible) {
110
+ targetCandidates.push(evaluation);
111
+ results.push({
112
+ session_id: evaluation.sessionId,
113
+ status: dryRun ? "would_abandon" : "abandoned",
114
+ reason: "Session meets stale criteria and is eligible for auto-close",
115
+ started_at: evaluation.startedAt,
116
+ last_activity_at: evaluation.lastActivityAt,
117
+ last_activity_source: evaluation.lastActivitySource,
118
+ meets_age_threshold: evaluation.meetsAgeThreshold,
119
+ meets_inactivity_threshold: evaluation.meetsInactivityThreshold,
120
+ blocked_by_liveness_guard: evaluation.blockedByLivenessGuard,
121
+ });
122
+ }
123
+ else {
124
+ results.push({
125
+ session_id: evaluation.sessionId,
126
+ status: "not_candidate",
127
+ reason: describeNotCandidate(evaluation),
128
+ started_at: evaluation.startedAt,
129
+ last_activity_at: evaluation.lastActivityAt,
130
+ last_activity_source: evaluation.lastActivitySource,
131
+ meets_age_threshold: evaluation.meetsAgeThreshold,
132
+ meets_inactivity_threshold: evaluation.meetsInactivityThreshold,
133
+ blocked_by_liveness_guard: evaluation.blockedByLivenessGuard,
134
+ });
135
+ }
136
+ }
137
+ failures = selection.failureCount;
138
+ }
139
+ else {
140
+ mode = hasRefs ? "refs" : "single";
141
+ const resolvedTargets = [];
142
+ if (hasRefs) {
143
+ const seenSessionIds = new Set();
144
+ for (const rawRef of refs) {
145
+ const normalized = normalizeSessionRef(rawRef);
146
+ const resolution = await resolveSessionId(ctx.specDir, normalized);
147
+ if (!resolution.ok) {
148
+ failures += 1;
149
+ if (resolution.error === "not_found") {
150
+ results.push({
151
+ session_id: normalized,
152
+ input_ref: rawRef,
153
+ status: "resolution_error",
154
+ reason: `Session not found: ${rawRef}. Try: kspec session list --status active`,
155
+ });
156
+ }
157
+ else {
158
+ results.push({
159
+ session_id: normalized,
160
+ input_ref: rawRef,
161
+ status: "resolution_error",
162
+ reason: `Ambiguous session ref ${rawRef}: ${resolution.matches.join(", ")}. ` +
163
+ "Try: kspec session list --status active and use a longer ref.",
164
+ });
165
+ }
166
+ continue;
167
+ }
168
+ if (seenSessionIds.has(resolution.id)) {
169
+ continue;
170
+ }
171
+ seenSessionIds.add(resolution.id);
172
+ resolvedTargets.push({
173
+ inputRef: rawRef,
174
+ sessionId: resolution.id,
175
+ });
176
+ targetRefs.push(resolution.id);
177
+ }
178
+ }
179
+ else {
180
+ const normalized = normalizeSessionRef(sessionIdOrPrefix);
181
+ const resolution = await resolveSessionId(ctx.specDir, normalized);
182
+ if (!resolution.ok) {
183
+ if (resolution.error === "not_found") {
184
+ error(`Session not found: ${sessionIdOrPrefix}`, "Try: kspec session list --status active");
185
+ process.exit(EXIT_CODES.NOT_FOUND);
186
+ }
187
+ error(`Session prefix "${sessionIdOrPrefix}" is ambiguous: ${resolution.matches.join(", ")}`, "Try: kspec session list --status active and use a longer ref");
188
+ process.exit(EXIT_CODES.NOT_FOUND);
189
+ }
190
+ targetSessionId = resolution.id;
191
+ resolvedTargets.push({
192
+ inputRef: sessionIdOrPrefix,
193
+ sessionId: resolution.id,
194
+ });
195
+ }
196
+ for (const target of resolvedTargets) {
197
+ const metadata = await getSession(ctx.specDir, target.sessionId);
198
+ if (!metadata) {
199
+ failures += 1;
200
+ results.push({
201
+ session_id: target.sessionId,
202
+ input_ref: target.inputRef,
203
+ status: "resolution_error",
204
+ reason: `Session metadata missing for ${target.sessionId}`,
205
+ });
206
+ continue;
207
+ }
208
+ if (metadata.status !== "active") {
209
+ results.push({
210
+ session_id: target.sessionId,
211
+ input_ref: target.inputRef,
212
+ status: "not_active",
213
+ reason: `Session status is ${metadata.status}; only active sessions are eligible`,
214
+ });
215
+ continue;
216
+ }
217
+ const skipped = skippedById.get(target.sessionId);
218
+ if (skipped) {
219
+ failures += 1;
220
+ results.push({
221
+ session_id: target.sessionId,
222
+ input_ref: target.inputRef,
223
+ status: "skipped_error",
224
+ reason: skipped.detail,
225
+ });
226
+ continue;
227
+ }
228
+ const evaluation = evaluationById.get(target.sessionId);
229
+ if (!evaluation) {
230
+ failures += 1;
231
+ results.push({
232
+ session_id: target.sessionId,
233
+ input_ref: target.inputRef,
234
+ status: "skipped_error",
235
+ reason: "Session evaluation unavailable",
236
+ });
237
+ continue;
238
+ }
239
+ if (!evaluation.eligible) {
240
+ results.push({
241
+ session_id: target.sessionId,
242
+ input_ref: target.inputRef,
243
+ status: "not_candidate",
244
+ reason: describeNotCandidate(evaluation),
245
+ started_at: evaluation.startedAt,
246
+ last_activity_at: evaluation.lastActivityAt,
247
+ last_activity_source: evaluation.lastActivitySource,
248
+ meets_age_threshold: evaluation.meetsAgeThreshold,
249
+ meets_inactivity_threshold: evaluation.meetsInactivityThreshold,
250
+ blocked_by_liveness_guard: evaluation.blockedByLivenessGuard,
251
+ });
252
+ continue;
253
+ }
254
+ targetCandidates.push(evaluation);
255
+ results.push({
256
+ session_id: target.sessionId,
257
+ input_ref: target.inputRef,
258
+ status: dryRun ? "would_abandon" : "abandoned",
259
+ reason: "Session meets stale criteria and is eligible for auto-close",
260
+ started_at: evaluation.startedAt,
261
+ last_activity_at: evaluation.lastActivityAt,
262
+ last_activity_source: evaluation.lastActivitySource,
263
+ meets_age_threshold: evaluation.meetsAgeThreshold,
264
+ meets_inactivity_threshold: evaluation.meetsInactivityThreshold,
265
+ blocked_by_liveness_guard: evaluation.blockedByLivenessGuard,
266
+ });
267
+ }
268
+ }
269
+ if (!dryRun && targetCandidates.length > 0 && !options.force) {
270
+ if (isJsonMode()) {
271
+ error("Confirmation required. Use --force with --json");
272
+ process.exit(EXIT_CODES.USAGE_ERROR);
273
+ }
274
+ const isTTY = process.env.KSPEC_TEST_TTY === "1" ||
275
+ process.env.KSPEC_TEST_TTY === "true" ||
276
+ process.stdin.isTTY;
277
+ if (!isTTY) {
278
+ error("Non-interactive environment. Use --force to proceed");
279
+ process.exit(EXIT_CODES.USAGE_ERROR);
280
+ }
281
+ const confirmed = await promptConfirmation(buildConfirmationQuestion(mode, targetCandidates.length));
282
+ if (!confirmed) {
283
+ error("Operation cancelled");
284
+ process.exit(EXIT_CODES.USAGE_ERROR);
285
+ }
286
+ }
287
+ const applyResult = await applyAutoAbandonMetadata(ctx.specDir, {
288
+ criteria: selection.criteria,
289
+ candidates: targetCandidates,
290
+ }, {
291
+ dryRun,
292
+ shadowCommitMessage: !dryRun && targetCandidates.length > 0
293
+ ? `session stale close: ${mode} (${targetCandidates.length} candidate${targetCandidates.length === 1 ? "" : "s"})`
294
+ : undefined,
295
+ });
296
+ const updatesBySessionId = new Map(applyResult.updates.map((update) => [update.sessionId, update]));
297
+ for (const result of results) {
298
+ if (result.status !== "would_abandon" && result.status !== "abandoned") {
299
+ continue;
300
+ }
301
+ const update = updatesBySessionId.get(result.session_id);
302
+ if (!update) {
303
+ failures += 1;
304
+ result.status = "skipped_error";
305
+ result.reason = "Failed to generate close metadata update";
306
+ continue;
307
+ }
308
+ result.close_reason = update.closeReason;
309
+ if (!dryRun) {
310
+ result.status = "abandoned";
311
+ result.reason = "Session was auto-abandoned";
312
+ }
313
+ else {
314
+ result.status = "would_abandon";
315
+ result.reason = "Session would be auto-abandoned (dry run)";
316
+ }
317
+ }
318
+ const candidatesCount = targetCandidates.length;
319
+ const changedSessions = dryRun ? 0 : applyResult.updatedCount;
320
+ const skippedSessions = results.filter((result) => result.status === "not_candidate" ||
321
+ result.status === "not_active" ||
322
+ result.status === "skipped_error" ||
323
+ result.status === "resolution_error").length;
324
+ const payload = {
325
+ dry_run: dryRun,
326
+ mode,
327
+ criteria: {
328
+ older_than: selection.criteria.olderThan,
329
+ inactive_for: selection.criteria.inactiveFor,
330
+ liveness_guard: selection.criteria.livenessGuard,
331
+ },
332
+ targets: {
333
+ session_id: targetSessionId,
334
+ refs: targetRefs.length > 0 ? targetRefs : undefined,
335
+ all: allMode,
336
+ },
337
+ sessions: results,
338
+ totals: {
339
+ active_sessions_total: selection.totalActiveSessions,
340
+ sessions_evaluated: results.filter((result) => result.status !== "resolution_error").length,
341
+ candidates: candidatesCount,
342
+ changed_sessions: changedSessions,
343
+ skipped_sessions: skippedSessions,
344
+ failures,
345
+ },
346
+ };
347
+ output(payload, () => {
348
+ if (dryRun) {
349
+ console.log("Dry run preview - no session files were modified.");
350
+ }
351
+ console.log("Stale session close results:");
352
+ for (const result of results) {
353
+ const shortId = result.session_id.slice(0, 8);
354
+ console.log(`[${shortId}] ${result.status} - ${result.reason}`);
355
+ if (result.close_reason) {
356
+ console.log(` close_reason: ${result.close_reason}`);
357
+ }
358
+ }
359
+ const totals = payload.totals;
360
+ console.log("");
361
+ console.log("Summary:");
362
+ console.log(` Active sessions: ${totals.active_sessions_total}`);
363
+ console.log(` Evaluated: ${totals.sessions_evaluated}`);
364
+ console.log(` Candidates: ${totals.candidates}`);
365
+ console.log(` Changed: ${totals.changed_sessions}`);
366
+ console.log(` Skipped: ${totals.skipped_sessions}`);
367
+ console.log(` Failures: ${totals.failures}`);
368
+ });
369
+ if (failures > 0) {
370
+ process.exit(EXIT_CODES.ERROR);
371
+ }
372
+ }
373
+ catch (err) {
374
+ error("Failed to close stale sessions", err);
375
+ process.exit(EXIT_CODES.ERROR);
376
+ }
377
+ }
378
+ //# sourceMappingURL=stale-close.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stale-close.js","sourceRoot":"","sources":["../../../../src/cli/commands/session/stale-close.ts"],"names":[],"mappings":"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"}
@@ -32,6 +32,8 @@ export interface DetectedAgent {
32
32
  configPath?: string;
33
33
  envVars?: Record<string, string>;
34
34
  }
35
+ declare const SETUP_AGENT_OVERRIDES: readonly ["claude-code", "cline", "cursor", "windsurf", "unknown"];
36
+ type SetupAgentOverride = (typeof SETUP_AGENT_OVERRIDES)[number];
35
37
  /**
36
38
  * Detect which agent environment we're running in.
37
39
  * Returns the detected agent type and confidence level.
@@ -81,6 +83,8 @@ export interface SetupPipelineOptions {
81
83
  skipSkills?: boolean;
82
84
  installHooks?: boolean;
83
85
  force?: boolean;
86
+ /** Explicit agent override (bypasses auto-detection) */
87
+ agent?: SetupAgentOverride;
84
88
  /** Custom author string (overrides auto-detected default) */
85
89
  author?: string;
86
90
  /** Whether to configure author (only in command handler, not init) */
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAOH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AAmBzC;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,OAAO,GACP,UAAU,GACV,aAAa,GACb,YAAY,GACZ,WAAW,GACX,OAAO,GACP,UAAU,GACV,KAAK,GACL,QAAQ,GACR,UAAU,GACV,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,aAAa,CAE3C;AAwCD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AA4cD;;GAEG;AACH,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAmlBD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAmT9B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuN3D"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAQH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOzC,OAAO,EAEL,KAAK,eAAe,EACrB,MAAM,iCAAiC,CAAC;AAmBzC;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,OAAO,GACP,UAAU,GACV,aAAa,GACb,YAAY,GACZ,WAAW,GACX,OAAO,GACP,UAAU,GACV,KAAK,GACL,QAAQ,GACR,UAAU,GACV,SAAS,CAAC;AAEd;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,SAAS,CAAC;IAChB,UAAU,EAAE,eAAe,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,QAAA,MAAM,qBAAqB,oEAMjB,CAAC;AAEX,KAAK,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AA2BjE;;;;;GAKG;AACH,wBAAgB,WAAW,IAAI,aAAa,CAgB3C;AAwCD;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,OAAO,CAAC;IACrB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AA4cD;;GAEG;AACH,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,QAAQ,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,eAAe,EAAE,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAyrBD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAuU9B;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiO3D"}
@@ -18,6 +18,7 @@
18
18
  * AC: @enhanced-setup ac-9 - skills referenced by ralph (task-work, reflect) are present
19
19
  */
20
20
  import * as fs from "node:fs/promises";
21
+ import { existsSync } from "node:fs";
21
22
  import * as os from "node:os";
22
23
  import * as path from "node:path";
23
24
  import * as readline from "node:readline/promises";
@@ -41,6 +42,31 @@ function debugLog(message, detail) {
41
42
  }
42
43
  }
43
44
  }
45
+ const SETUP_AGENT_OVERRIDES = [
46
+ "claude-code",
47
+ "cline",
48
+ "cursor",
49
+ "windsurf",
50
+ "unknown",
51
+ ];
52
+ function parseSetupAgentOverride(value) {
53
+ const normalized = value.trim().toLowerCase();
54
+ if (SETUP_AGENT_OVERRIDES.includes(normalized)) {
55
+ return normalized;
56
+ }
57
+ const allowed = SETUP_AGENT_OVERRIDES.join(", ");
58
+ throw new Error(`Invalid --agent value "${value}". Supported values: ${allowed}`);
59
+ }
60
+ function buildDetectedAgent(type) {
61
+ if (type === "claude-code") {
62
+ return {
63
+ type,
64
+ confidence: "high",
65
+ configPath: path.join(os.homedir(), ".claude", "settings.json"),
66
+ };
67
+ }
68
+ return { type, confidence: "high" };
69
+ }
44
70
  /**
45
71
  * Detect which agent environment we're running in.
46
72
  * Returns the detected agent type and confidence level.
@@ -48,7 +74,19 @@ function debugLog(message, detail) {
48
74
  * Detection priority matters - more specific markers checked first.
49
75
  */
50
76
  export function detectAgent() {
51
- return detectAgentFromEnv();
77
+ const detected = detectAgentFromEnv();
78
+ if (detected.type !== "unknown") {
79
+ return detected;
80
+ }
81
+ // Fallback for non-interactive contexts where env markers may be absent.
82
+ if (existsSync(path.join(os.homedir(), ".claude"))) {
83
+ return {
84
+ type: "claude-code",
85
+ confidence: "low",
86
+ configPath: path.join(os.homedir(), ".claude", "settings.json"),
87
+ };
88
+ }
89
+ return detected;
52
90
  }
53
91
  /**
54
92
  * Install KSPEC_AUTHOR config for Claude Code (global settings)
@@ -460,8 +498,10 @@ function printManualInstructions(agentType) {
460
498
  * Check the current setup status
461
499
  * AC: @enhanced-setup ac-7, ac-8
462
500
  */
463
- async function getSetupStatus(projectDir) {
464
- const detected = detectAgent();
501
+ async function getSetupStatus(projectDir, agentOverride) {
502
+ const detected = agentOverride
503
+ ? buildDetectedAgent(agentOverride)
504
+ : detectAgent();
465
505
  const configPath = path.join(projectDir, ".claude", "settings.json");
466
506
  const hooksDir = path.join(projectDir, ".claude", "hooks");
467
507
  const agentsMdPath = path.join(projectDir, "kspec-agents.md");
@@ -721,6 +761,85 @@ async function renderSkillsForSetup(projectDir, dryRun) {
721
761
  return { rendered: 0, skipped: 0, pluginProvided: 0, skillIds: [] };
722
762
  }
723
763
  }
764
+ /**
765
+ * Ensure built-in worker and reviewer agent definitions exist in the project meta.
766
+ *
767
+ * Creates task-worker and pr-reviewer agents with dispatch rules that match
768
+ * ralph's behavior. Skips creation if agents already exist (idempotent).
769
+ *
770
+ * AC: @ralph-replacement ac-2 — built-in worker and reviewer agent definitions
771
+ * created in kynetic.meta.yaml with default dispatch rules matching ralph's behavior
772
+ */
773
+ async function ensureBuiltInAgents(projectDir, dryRun) {
774
+ const { initContext } = await import("../../parser/index.js");
775
+ const { loadMetaContext, saveMetaItem } = await import("../../parser/meta.js");
776
+ const { ulid } = await import("ulid");
777
+ const created = [];
778
+ const skipped = [];
779
+ try {
780
+ const ctx = await initContext();
781
+ if (!ctx.manifestPath) {
782
+ return { created, skipped };
783
+ }
784
+ const meta = await loadMetaContext(ctx);
785
+ const existingIds = new Set((meta.agents || []).map((a) => a.id));
786
+ // Built-in agent definitions — match ralph's dispatch behavior
787
+ const builtInAgents = [
788
+ {
789
+ id: "task-worker",
790
+ name: "Task Worker",
791
+ description: "Autonomous task worker. Picks up automation-eligible ready and needs_work tasks.",
792
+ capabilities: ["code", "test", "refactor"],
793
+ tools: ["kspec", "git", "npm"],
794
+ dispatch: [
795
+ { on: "task.in_progress", filter: { automation: "eligible" } },
796
+ { on: "task.ready", filter: { automation: "eligible" } },
797
+ { on: "task.needs_work", filter: { automation: "eligible" } },
798
+ ],
799
+ skills: ["task-work"],
800
+ concurrency: { max_concurrent: 1 },
801
+ auto_approve: true,
802
+ },
803
+ {
804
+ id: "pr-reviewer",
805
+ name: "PR Reviewer",
806
+ description: "Automated PR reviewer. Reviews pending_review tasks and merges when quality gates pass.",
807
+ capabilities: ["review"],
808
+ tools: ["kspec", "git", "gh"],
809
+ dispatch: [{ on: "task.pending_review" }],
810
+ skills: ["pr-review"],
811
+ concurrency: { max_concurrent: 1 },
812
+ auto_approve: false,
813
+ },
814
+ ];
815
+ for (const def of builtInAgents) {
816
+ if (existingIds.has(def.id)) {
817
+ skipped.push(def.id);
818
+ continue;
819
+ }
820
+ if (!dryRun) {
821
+ await saveMetaItem(ctx, {
822
+ _ulid: ulid(),
823
+ id: def.id,
824
+ name: def.name,
825
+ description: def.description,
826
+ capabilities: [...def.capabilities],
827
+ tools: [...def.tools],
828
+ conventions: [],
829
+ dispatch: def.dispatch.map((r) => ({ ...r })),
830
+ skills: [...def.skills],
831
+ concurrency: { ...def.concurrency },
832
+ auto_approve: def.auto_approve,
833
+ }, "agent");
834
+ }
835
+ created.push(def.id);
836
+ }
837
+ }
838
+ catch (err) {
839
+ debugLog("ensureBuiltInAgents failed", err);
840
+ }
841
+ return { created, skipped };
842
+ }
724
843
  /**
725
844
  * Generate kspec-agents.md using the canonical implementation from agents.ts
726
845
  * AC: @setup-pipeline-unification ac-1 - calls generateAgentsContent() from agents.ts
@@ -895,7 +1014,9 @@ export async function runSetupPipeline(projectDir, options) {
895
1014
  let permissionsSeeded = false;
896
1015
  let memorySeeded = false;
897
1016
  try {
898
- const detected = detectAgent();
1017
+ const detected = options.agent
1018
+ ? buildDetectedAgent(options.agent)
1019
+ : detectAgent();
899
1020
  // Step 1: Agent detection
900
1021
  steps.push({
901
1022
  name: "Agent detection",
@@ -1074,6 +1195,22 @@ export async function runSetupPipeline(projectDir, options) {
1074
1195
  message: "--skip-skills flag",
1075
1196
  });
1076
1197
  }
1198
+ // Step 4b: Ensure built-in worker and reviewer agent definitions exist
1199
+ // AC: @ralph-replacement ac-2 — built-in agents created in kynetic.meta.yaml
1200
+ {
1201
+ const agentsBuiltIn = await ensureBuiltInAgents(projectDir, dryRun);
1202
+ const totalNew = agentsBuiltIn.created.length;
1203
+ const totalSkipped = agentsBuiltIn.skipped.length;
1204
+ if (totalNew > 0 || totalSkipped > 0) {
1205
+ steps.push({
1206
+ name: "Ensure built-in agents",
1207
+ status: "done",
1208
+ message: totalNew > 0
1209
+ ? `created: ${agentsBuiltIn.created.join(", ")}`
1210
+ : `already exist: ${agentsBuiltIn.skipped.join(", ")}`,
1211
+ });
1212
+ }
1213
+ }
1077
1214
  // Step 5: Generate kspec-agents.md
1078
1215
  // AC: @init-setup-integration ac-3 - kspec-agents.md present
1079
1216
  const agentsResult = await generateAgentInstructions(projectDir, dryRun);
@@ -1189,6 +1326,7 @@ export function registerSetupCommand(program) {
1189
1326
  program
1190
1327
  .command("setup")
1191
1328
  .description("Configure agent environment for kspec (orchestrated pipeline)")
1329
+ .option("--agent <type>", "Explicit agent type override (claude-code|cline|cursor|windsurf|unknown)")
1192
1330
  .option("--dry-run", "Show what would be done without making changes")
1193
1331
  .option("--author <author>", "Custom author string (default: auto-detected based on agent)")
1194
1332
  .option("--no-hooks", "Skip installing hooks")
@@ -1199,9 +1337,12 @@ export function registerSetupCommand(program) {
1199
1337
  .action(async (options) => {
1200
1338
  try {
1201
1339
  const projectDir = process.cwd();
1340
+ const agentOverride = options.agent
1341
+ ? parseSetupAgentOverride(options.agent)
1342
+ : undefined;
1202
1343
  // AC: @enhanced-setup ac-7, ac-8 - --status mode
1203
1344
  if (options.status) {
1204
- const status = await getSetupStatus(projectDir);
1345
+ const status = await getSetupStatus(projectDir, agentOverride);
1205
1346
  output(status, () => {
1206
1347
  console.log(chalk.bold("kspec Setup Status\n"));
1207
1348
  // Agent detection
@@ -1274,7 +1415,9 @@ export function registerSetupCommand(program) {
1274
1415
  // User declined worktree creation or it failed
1275
1416
  process.exit(EXIT_CODES.ERROR);
1276
1417
  }
1277
- const detected = detectAgent();
1418
+ const detected = agentOverride
1419
+ ? buildDetectedAgent(agentOverride)
1420
+ : detectAgent();
1278
1421
  const dryRun = options.dryRun || false;
1279
1422
  if (detected.type === "unknown") {
1280
1423
  warn("Could not auto-detect agent environment");
@@ -1288,6 +1431,7 @@ export function registerSetupCommand(program) {
1288
1431
  skipSkills: options.skipSkills || false,
1289
1432
  installHooks: options.hooks !== false,
1290
1433
  force: options.force || false,
1434
+ agent: agentOverride,
1291
1435
  author: options.author,
1292
1436
  configureAuthor: true,
1293
1437
  });