@alecsibilia/luca 14.0.0-alpha.2 → 14.0.0-alpha.21

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 (321) hide show
  1. package/CHANGELOG.md +76 -0
  2. package/README.md +7 -2
  3. package/board/client/board-look.ts +31 -1
  4. package/board/client/board-panel-parts.tsx +150 -0
  5. package/board/client/board-panel-stages.ts +99 -0
  6. package/board/client/board-panel-styles.ts +223 -0
  7. package/board/client/board-panel.tsx +77 -1275
  8. package/board/client/engine-life.ts +48 -0
  9. package/board/client/final-review-stack.tsx +144 -0
  10. package/board/client/heartbeat.tsx +61 -0
  11. package/board/client/helper-lines.tsx +69 -0
  12. package/board/client/live-feed.tsx +86 -0
  13. package/board/client/live-line.ts +73 -0
  14. package/board/client/model-line.tsx +178 -0
  15. package/board/client/needs-you-section.tsx +133 -0
  16. package/board/client/one-line.tsx +193 -0
  17. package/board/client/repo-wait-banner.tsx +69 -0
  18. package/board/client/run-footer.tsx +68 -0
  19. package/board/client/run-header.tsx +189 -0
  20. package/board/client/run-picker.tsx +98 -0
  21. package/board/client/status-bar.tsx +131 -0
  22. package/board/client/step-dots.tsx +127 -0
  23. package/board/client/stuck-actions.tsx +269 -0
  24. package/board/client/ticket-card-view.tsx +238 -0
  25. package/board/client/ticket-detail.tsx +87 -0
  26. package/board/client/ticket-stack.tsx +119 -0
  27. package/board/client/ticket-wait.ts +188 -0
  28. package/board/client/timeline-rows.tsx +41 -14
  29. package/board/client/usage-line.tsx +51 -0
  30. package/board/client/wait-line.tsx +39 -0
  31. package/board/index.client.tsx +1 -1
  32. package/board/index.server.ts +7 -1
  33. package/board/package.json +1 -1
  34. package/board/server/board-panel-state-helpers.ts +67 -0
  35. package/board/server/board-server-check.ts +294 -0
  36. package/board/server/board-server-engine.ts +129 -0
  37. package/board/server/board-server-events.ts +134 -0
  38. package/board/server/board-server-read.ts +190 -0
  39. package/board/server/board-server-resume.ts +164 -0
  40. package/board/server/board-server-start.ts +174 -0
  41. package/board/server/board-server-store.ts +281 -0
  42. package/board/server/board-server-types.ts +114 -0
  43. package/board/server/board-server-util.ts +4 -0
  44. package/board/server/board-server.ts +52 -943
  45. package/board/server/board-vocabulary-engine.ts +144 -0
  46. package/board/server/board-vocabulary-review.ts +115 -0
  47. package/board/server/board-vocabulary-run.ts +145 -0
  48. package/board/server/board-vocabulary-shapes.ts +153 -0
  49. package/board/server/board-vocabulary.ts +20 -375
  50. package/board/server/current-step-panel-helpers.ts +108 -0
  51. package/board/server/describe-record.ts +403 -0
  52. package/board/server/engine-launch.ts +20 -3
  53. package/board/server/engine-restart-helpers.ts +105 -0
  54. package/board/server/engine-watch.ts +45 -5
  55. package/board/server/journal-rebuild-helpers.ts +169 -0
  56. package/board/server/live-file.ts +130 -0
  57. package/board/server/luca-version.ts +1 -1
  58. package/board/server/make-rows.ts +14 -629
  59. package/board/server/record-texts.ts +350 -0
  60. package/board/server/reduce-board-agent-start.ts +224 -0
  61. package/board/server/reduce-board-agents.ts +160 -0
  62. package/board/server/reduce-board-counters.ts +138 -0
  63. package/board/server/reduce-board-create.ts +148 -0
  64. package/board/server/reduce-board-final-review.ts +174 -0
  65. package/board/server/reduce-board-needs-you.ts +283 -0
  66. package/board/server/reduce-board-reasons.ts +59 -0
  67. package/board/server/reduce-board-run.ts +255 -0
  68. package/board/server/reduce-board-settle.ts +88 -0
  69. package/board/server/reduce-board-steps.ts +226 -0
  70. package/board/server/reduce-board-text.ts +139 -0
  71. package/board/server/reduce-board-ticket-checks.ts +168 -0
  72. package/board/server/reduce-board-ticket-join.ts +144 -0
  73. package/board/server/reduce-board-ticket-start.ts +132 -0
  74. package/board/server/reduce-board-update.ts +117 -0
  75. package/board/server/reduce-board-usage.ts +247 -0
  76. package/board/server/reduce-board.ts +100 -1917
  77. package/board/server/reply-post.ts +407 -0
  78. package/board/server/run-registry.ts +8 -4
  79. package/board/server/ticket-stages-panel-helpers.ts +296 -0
  80. package/board/shared/board-rows.ts +9 -0
  81. package/board/shared/board-rpc.ts +42 -0
  82. package/board/shared/board-state-counts.ts +77 -0
  83. package/board/shared/board-state-live.ts +99 -0
  84. package/board/shared/board-state-review.ts +59 -0
  85. package/board/shared/board-state-run.ts +236 -0
  86. package/board/shared/board-state-ticket.ts +257 -0
  87. package/board/shared/board-state-usage.ts +107 -0
  88. package/board/shared/board-state.ts +97 -567
  89. package/board/shared/reply-actions.ts +207 -0
  90. package/engine/agents/agent-launcher.ts +27 -4
  91. package/engine/agents/claude-launcher-helpers.ts +233 -0
  92. package/engine/agents/claude-launcher.ts +28 -669
  93. package/engine/agents/claude-messages.ts +212 -0
  94. package/engine/agents/claude-options.ts +43 -8
  95. package/engine/agents/common-instructions.ts +138 -0
  96. package/engine/agents/input-channel.ts +36 -0
  97. package/engine/agents/launch-paths.ts +29 -0
  98. package/engine/agents/launch-session.ts +227 -0
  99. package/engine/agents/learner-instructions.ts +31 -0
  100. package/engine/agents/open-session.ts +210 -0
  101. package/engine/agents/prompt-sections.ts +95 -0
  102. package/engine/agents/rejoin-prompts.ts +135 -0
  103. package/engine/agents/reviewer-instructions.ts +99 -0
  104. package/engine/agents/role-instructions.ts +31 -244
  105. package/engine/agents/role-prompts.ts +39 -109
  106. package/engine/agents/role-results.ts +106 -7
  107. package/engine/agents/scripted-launcher.ts +21 -6
  108. package/engine/agents/session-pool.ts +124 -0
  109. package/engine/agents/turn-progress.ts +283 -0
  110. package/engine/agents/writer-instructions.ts +151 -0
  111. package/engine/cli/computer-adapters-real.ts +15 -3
  112. package/engine/cli/computer-adapters.ts +2 -0
  113. package/engine/cli/computer-checks.ts +87 -4
  114. package/engine/cli/config-reload-text.ts +39 -0
  115. package/engine/cli/decision-model-setup.ts +70 -0
  116. package/engine/cli/doctor-command.ts +1 -0
  117. package/engine/cli/doctor.ts +21 -3
  118. package/engine/cli/going-runs.ts +192 -36
  119. package/engine/cli/init-command.ts +1 -0
  120. package/engine/cli/init.ts +23 -1
  121. package/engine/cli/live-runs.ts +73 -0
  122. package/engine/cli/luca-run.ts +42 -7
  123. package/engine/cli/luca-skills.ts +183 -0
  124. package/engine/cli/luca.ts +8 -1
  125. package/engine/cli/models-command.ts +119 -0
  126. package/engine/cli/read-run.ts +81 -0
  127. package/engine/cli/run-args.ts +33 -6
  128. package/engine/cli/run-demo.ts +143 -0
  129. package/engine/cli/run-end.ts +184 -0
  130. package/engine/cli/run-modes-helpers.ts +81 -0
  131. package/engine/cli/run-modes.ts +62 -439
  132. package/engine/cli/setup.ts +5 -48
  133. package/engine/cli/unfinished-runs.ts +122 -0
  134. package/engine/cli/upgrade-command.ts +212 -30
  135. package/engine/cli/upgrade-finish.ts +149 -0
  136. package/engine/cli/upgrade.ts +112 -71
  137. package/engine/config/config-fields.ts +127 -0
  138. package/engine/config/config-reload.ts +250 -0
  139. package/engine/config/engine-config-schema.ts +235 -0
  140. package/engine/config/engine-config.ts +72 -142
  141. package/engine/config/test-commands.ts +102 -0
  142. package/engine/core/agent-guards-helpers.ts +84 -0
  143. package/engine/core/agent-turn.ts +395 -0
  144. package/engine/core/already-done.ts +44 -1
  145. package/engine/core/build-action.ts +214 -0
  146. package/engine/core/build-context.ts +135 -0
  147. package/engine/core/build-launch.ts +259 -0
  148. package/engine/core/commit-in.ts +282 -0
  149. package/engine/core/decide-build-early.ts +108 -0
  150. package/engine/core/decide-build-ending.ts +145 -0
  151. package/engine/core/decide-build-helpers.ts +87 -0
  152. package/engine/core/decide-build-tickets.ts +207 -0
  153. package/engine/core/decide-build-view.ts +103 -0
  154. package/engine/core/decide-build.ts +101 -1368
  155. package/engine/core/decide-final-fix.ts +203 -0
  156. package/engine/core/decide-final-review.ts +55 -310
  157. package/engine/core/decide-red-green.ts +398 -0
  158. package/engine/core/decide-rejoin.ts +259 -0
  159. package/engine/core/decide-repo-wait.ts +129 -0
  160. package/engine/core/decide-run-budget.ts +86 -12
  161. package/engine/core/decide-stuck-helpers.ts +127 -0
  162. package/engine/core/decide-stuck.ts +60 -8
  163. package/engine/core/decide-ticket-review.ts +95 -0
  164. package/engine/core/decide-ticket.ts +267 -0
  165. package/engine/core/decide-waits.ts +47 -0
  166. package/engine/core/decide.ts +74 -23
  167. package/engine/core/engine-chores.ts +163 -0
  168. package/engine/core/environment-rerun.ts +83 -0
  169. package/engine/core/evidence-text.ts +84 -0
  170. package/engine/core/execute-action.ts +303 -0
  171. package/engine/core/execute-already-done-check.ts +133 -0
  172. package/engine/core/execute-build.ts +68 -944
  173. package/engine/core/execute-changeset.ts +5 -7
  174. package/engine/core/execute-final-review.ts +125 -13
  175. package/engine/core/execute-gates.ts +182 -0
  176. package/engine/core/execute-intake.ts +130 -0
  177. package/engine/core/execute-join.ts +276 -0
  178. package/engine/core/execute-memory.ts +12 -0
  179. package/engine/core/execute-pull-request.ts +84 -0
  180. package/engine/core/execute-red-check.ts +219 -0
  181. package/engine/core/execute-repo-wait.ts +129 -0
  182. package/engine/core/execute-stuck.ts +25 -10
  183. package/engine/core/execute-waits.ts +158 -0
  184. package/engine/core/execute-with-jev.ts +118 -0
  185. package/engine/core/execute.ts +124 -831
  186. package/engine/core/final-failure-cap.ts +38 -0
  187. package/engine/core/final-review-action.ts +125 -0
  188. package/engine/core/final-review-text.ts +63 -17
  189. package/engine/core/final-stuck-text.ts +86 -0
  190. package/engine/core/fix-loop-text.ts +49 -2
  191. package/engine/core/left-out.ts +120 -0
  192. package/engine/core/live-file.ts +372 -0
  193. package/engine/core/loop-caps.ts +25 -2
  194. package/engine/core/not-in-run.ts +7 -3
  195. package/engine/core/pull-request-text.ts +255 -6
  196. package/engine/core/repo-wait-text.ts +81 -0
  197. package/engine/core/review-text.ts +55 -1
  198. package/engine/core/run-crash-recovery-helpers.ts +16 -0
  199. package/engine/core/run-session-close-helpers.ts +96 -0
  200. package/engine/core/run-start.ts +148 -0
  201. package/engine/core/run-stuck-text.ts +86 -0
  202. package/engine/core/schedule-rules.ts +193 -0
  203. package/engine/core/stuck-detail-text.ts +89 -0
  204. package/engine/core/stuck-format.ts +22 -0
  205. package/engine/core/stuck-text.ts +29 -332
  206. package/engine/core/ticket-stuck-text.ts +192 -0
  207. package/engine/core/worktree-changes.ts +106 -0
  208. package/engine/gates/already-done-check.ts +120 -0
  209. package/engine/gates/feature-map.ts +96 -0
  210. package/engine/gates/gate-runner.ts +108 -108
  211. package/engine/gates/gate-schemas.ts +61 -2
  212. package/engine/gates/leftover-scan.ts +154 -31
  213. package/engine/gates/new-tests.ts +45 -0
  214. package/engine/gates/own-files-check.ts +98 -0
  215. package/engine/gates/prepare-check.ts +60 -0
  216. package/engine/gates/prepare-slots.ts +99 -0
  217. package/engine/gates/red-check.ts +184 -16
  218. package/engine/gates/shell-check.ts +64 -0
  219. package/engine/gates/slot-waits.ts +55 -0
  220. package/engine/gates/slow-test-runner.ts +59 -0
  221. package/engine/gates/test-checks.ts +161 -0
  222. package/engine/gates/test-runner.ts +164 -5
  223. package/engine/gates/test-slots.ts +48 -0
  224. package/engine/git/git-adapter.ts +55 -396
  225. package/engine/git/git-commits.ts +132 -0
  226. package/engine/git/git-join.ts +139 -0
  227. package/engine/git/git-read.ts +123 -0
  228. package/engine/git/git-run.ts +32 -0
  229. package/engine/git/git-worktrees.ts +143 -0
  230. package/engine/git/outside-links.ts +55 -0
  231. package/engine/guards/after-turn-check.ts +31 -5
  232. package/engine/guards/guard-hook.ts +60 -12
  233. package/engine/guards/guard-roles.ts +68 -0
  234. package/engine/guards/helper-rules.ts +92 -0
  235. package/engine/guards/permission-rules.ts +161 -0
  236. package/engine/guards/role-rules-helpers.ts +48 -0
  237. package/engine/guards/role-rules.ts +34 -606
  238. package/engine/guards/shell-rules.ts +344 -0
  239. package/engine/guards/worktree-git.ts +208 -0
  240. package/engine/guards/worktree-snapshot.ts +412 -0
  241. package/engine/guards/worktree-state.ts +28 -825
  242. package/engine/guards/worktree-undo.ts +260 -0
  243. package/engine/guards/write-rules.ts +149 -0
  244. package/engine/index.ts +30 -9
  245. package/engine/intake/criteria-checks.ts +114 -0
  246. package/engine/intake/intake-checks.ts +164 -30
  247. package/engine/intake/intake-schemas.ts +37 -2
  248. package/engine/jev/clef-client.ts +259 -0
  249. package/engine/jev/decision-model-credentials.ts +212 -0
  250. package/engine/jev/jev-jobs.ts +144 -60
  251. package/engine/jev/jev-schemas.ts +86 -5
  252. package/engine/jev/jev-shadow-helpers.ts +218 -0
  253. package/engine/jev/jev-shadow.ts +109 -64
  254. package/engine/jev/model-pick.ts +275 -0
  255. package/engine/journal/agent-entries.ts +167 -0
  256. package/engine/journal/agent-message-entries.ts +72 -0
  257. package/engine/journal/agent-turn-replay.ts +203 -0
  258. package/engine/journal/already-done-entries.ts +55 -0
  259. package/engine/journal/commit-entries.ts +56 -0
  260. package/engine/journal/cross-ticket-replay.ts +222 -0
  261. package/engine/journal/decision-model-entries.ts +86 -0
  262. package/engine/journal/entry-fields.ts +10 -0
  263. package/engine/journal/final-review-entries.ts +128 -0
  264. package/engine/journal/final-review-replay.ts +324 -0
  265. package/engine/journal/final-review-round.ts +320 -0
  266. package/engine/journal/final-review-state.ts +180 -0
  267. package/engine/journal/gate-entries.ts +81 -0
  268. package/engine/journal/intake-entries.ts +87 -0
  269. package/engine/journal/join-entries.ts +126 -0
  270. package/engine/journal/journal-entry-schema.ts +218 -0
  271. package/engine/journal/journal-kinds.ts +97 -0
  272. package/engine/journal/journal-record-schema.ts +218 -0
  273. package/engine/journal/journal-record.ts +43 -1400
  274. package/engine/journal/journal.ts +6 -1
  275. package/engine/journal/limit-entries.ts +90 -0
  276. package/engine/journal/memory-entries.ts +124 -0
  277. package/engine/journal/memory-replay.ts +157 -0
  278. package/engine/journal/plan-replay.ts +139 -0
  279. package/engine/journal/pull-request-entries.ts +41 -0
  280. package/engine/journal/replay.ts +157 -2144
  281. package/engine/journal/reply-replay.ts +144 -0
  282. package/engine/journal/repo-wait-entries.ts +53 -0
  283. package/engine/journal/run-entries.ts +172 -0
  284. package/engine/journal/run-state.ts +264 -0
  285. package/engine/journal/shared-failure-replay.ts +133 -0
  286. package/engine/journal/stuck-entries.ts +193 -0
  287. package/engine/journal/ticket-progress.ts +392 -0
  288. package/engine/journal/ticket-replay.ts +411 -0
  289. package/engine/journal/ticket-result-replay.ts +364 -0
  290. package/engine/journal/ticket-retry-replay.ts +142 -0
  291. package/engine/journal/worktree-entries.ts +122 -0
  292. package/engine/models/model-score.ts +512 -0
  293. package/engine/shell/run-command.ts +187 -18
  294. package/engine/testing/agent-turn-fixtures.ts +287 -0
  295. package/engine/testing/already-done-fixtures.ts +97 -0
  296. package/engine/testing/build-fixtures.ts +68 -973
  297. package/engine/testing/checkouts-fixtures.ts +48 -0
  298. package/engine/testing/final-review-fixtures.ts +62 -1
  299. package/engine/testing/final-review-steps.ts +143 -0
  300. package/engine/testing/limit-fixtures.ts +85 -0
  301. package/engine/testing/live-file-fixtures.ts +57 -0
  302. package/engine/testing/practice-repo.ts +10 -4
  303. package/engine/testing/practice-run.ts +1 -1
  304. package/engine/testing/reply-fixtures.ts +88 -0
  305. package/engine/testing/run-budget-fixtures.ts +165 -0
  306. package/engine/testing/run-fixtures.ts +219 -0
  307. package/engine/testing/sdk-play.ts +177 -0
  308. package/engine/testing/setup-repo.ts +194 -0
  309. package/engine/testing/step-record-fixtures.ts +55 -0
  310. package/engine/testing/ticket-step-fixtures.ts +272 -0
  311. package/engine/testing/wait-scenarios.ts +186 -0
  312. package/engine/tracker/gh-retry.ts +217 -0
  313. package/engine/tracker/github-tracker.ts +310 -90
  314. package/engine/tracker/in-memory-tracker.ts +8 -4
  315. package/engine/tracker/tracker.ts +131 -6
  316. package/package.json +2 -1
  317. package/skills/luca-retro/SKILL.md +74 -0
  318. package/skills/luca-retro/scripts/retro-summary.ts +1356 -0
  319. package/skills/luca-unstick/SKILL.md +153 -0
  320. package/skills/luca-unstick/scripts/stuck-summary.ts +1063 -0
  321. package/engine/jev/jev-client.ts +0 -173
@@ -15,7 +15,7 @@ export type InMemoryPullRequest = PullRequestRequest & OpenedPullRequest
15
15
 
16
16
  /** An in-memory tracker, plus what tests need to look inside it. */
17
17
  export type InMemoryTracker = Tracker & {
18
- /** Every comment's body on an issue, oldest first. */
18
+ /** Every comment's body on an issue or a pull request, oldest first. */
19
19
  commentsOn: (args: { number: number }) => string[]
20
20
  /** A person comments on an issue, as on the tracker; returns the comment's id. */
21
21
  addComment: (args: {
@@ -84,7 +84,8 @@ export const createInMemoryTracker = ({
84
84
  author: string
85
85
  body: string
86
86
  }): number => {
87
- find(number)
87
+ // A pull request takes comments too, as on GitHub.
88
+ if (!pulls.some((pull) => pull.number === number)) find(number)
88
89
  lastCommentId += 1
89
90
  const comment = { id: lastCommentId, author, body }
90
91
  comments.set(number, [...(comments.get(number) ?? []), comment])
@@ -110,8 +111,11 @@ export const createInMemoryTracker = ({
110
111
  (comments.get(number) ?? []).filter(({ id }) => id > since_id)
111
112
  ),
112
113
  addComment: (args) => post(args),
113
- addLabel: async ({ number, label }) =>
114
- setLabels(number, uniq([...find(number).labels, label])),
114
+ // A label the repo lacks is created first, as on GitHub (#500).
115
+ addLabel: async ({ number, label }) => {
116
+ if (!labels.includes(label)) labels.push(label)
117
+ setLabels(number, uniq([...find(number).labels, label]))
118
+ },
115
119
  removeLabel: async ({ number, label }) =>
116
120
  setLabels(
117
121
  number,
@@ -57,27 +57,43 @@ export type Tracker = {
57
57
  listSubTickets: (args: { spec_number: number }) => Promise<TrackerIssue[]>
58
58
  /** Reads any issue, such as a blocker outside the spec. `null` if missing. */
59
59
  readIssue: (args: { number: number }) => Promise<TrackerIssue | null>
60
- /** Posts a comment on an issue, and returns the new comment's id. */
60
+ /**
61
+ * Posts a comment on an issue or a pull request, and returns the new
62
+ * comment's id.
63
+ */
61
64
  comment: (args: { number: number; body: string }) => Promise<{ id: number }>
62
65
  /** An issue's comments with an id above `since_id`, oldest first. */
63
66
  listComments: (args: {
64
67
  number: number
65
68
  since_id: number
66
69
  }) => Promise<TrackerComment[]>
67
- /** Adds a label to an issue. Adding a label it already has does nothing. */
70
+ /**
71
+ * Adds a label to an issue. Adding a label it already has does nothing. A
72
+ * label the repo lacks is created first, as `labelDefinition` describes
73
+ * it (#500).
74
+ */
68
75
  addLabel: (args: { number: number; label: string }) => Promise<void>
69
- /** Removes a label from an issue. Removing a missing label does nothing. */
76
+ /**
77
+ * Removes a label from an issue. Removing a label the issue or the repo
78
+ * lacks does nothing.
79
+ */
70
80
  removeLabel: (args: { number: number; label: string }) => Promise<void>
71
81
  /**
72
82
  * Closes an issue as completed, such as a ticket whose work was already
73
83
  * done (#484). Closing a closed issue does nothing.
74
84
  */
75
85
  closeIssue: (args: { number: number }) => Promise<void>
76
- /** Opens a pull request from `head` into `base`. */
86
+ /**
87
+ * Opens a pull request from `head` into `base`. Throws a `TrackerError`
88
+ * when the tracker couldn't open it (such as a failed `gh pr create`),
89
+ * which the PR step makes a stuck run the owner can `retry` (#508).
90
+ */
77
91
  openPullRequest: (args: PullRequestRequest) => Promise<OpenedPullRequest>
78
92
  /**
79
- * The open pull request from branch `head`, or `null`: a redo after a
80
- * crash adopts the PR its first try opened.
93
+ * The open pull request from branch `head` of the repo itself (never a
94
+ * fork's), or `null`: the PR step reuses one, such as the PR a try
95
+ * opened before a crash or a failure. Throws a `TrackerError` when the
96
+ * tracker couldn't list them.
81
97
  */
82
98
  findOpenPullRequest: (args: {
83
99
  head: string
@@ -97,9 +113,41 @@ export type Tracker = {
97
113
  issueLinks: () => Promise<{ sub_issues: boolean; dependencies: boolean }>
98
114
  }
99
115
 
116
+ /**
117
+ * A tracker call that failed, such as a `gh` command that exited non-zero.
118
+ * The PR step makes one a stuck run (#508); any other error is a crash.
119
+ */
120
+ export class TrackerError extends Error {
121
+ override name = 'TrackerError'
122
+ }
123
+
124
+ /** A failed `gh` call, in the words `TrackerError`s from `gh` use. */
125
+ const GH_FAILED = /\bgh \w+ \w+`? failed\b/
126
+
127
+ /**
128
+ * Whether `error` is a failed tracker call: a `TrackerError`, or a plain
129
+ * error worded like one from `gh` ("gh pr create failed ..."), as a tracker
130
+ * wrapped around the GitHub one may throw.
131
+ *
132
+ * @example
133
+ * isTrackerFailure(new TrackerError('gh pr create failed')) // true
134
+ * isTrackerFailure(new Error('The engine crashed.')) // false
135
+ */
136
+ export const isTrackerFailure = (error: unknown): boolean =>
137
+ error instanceof TrackerError ||
138
+ (error instanceof Error && GH_FAILED.test(error.message))
139
+
100
140
  /** The label a ticket needs before intake lets a run build it. */
101
141
  export const READY_LABEL = 'ready-for-agent'
102
142
 
143
+ /**
144
+ * The label on a ticket only a person can do (#499), such as renaming the
145
+ * repo or shipping after a hands-on check. Intake leaves it out of the run,
146
+ * with the tickets that wait on it, and never comments on it or relabels
147
+ * it. A ticket with both this and `READY_LABEL` counts as for a person.
148
+ */
149
+ export const HUMAN_LABEL = 'ready-for-human'
150
+
103
151
  /**
104
152
  * The label that makes a ticket a refactor ticket: it changes how the code is
105
153
  * shaped, not what it does, so it skips the test-writer and the red check.
@@ -122,3 +170,80 @@ export const RELEASE_LABELS = [
122
170
  'release:major',
123
171
  'release:none',
124
172
  ] as const
173
+
174
+ /**
175
+ * A label as the engine creates it in a repo: `luca setup` does, and so
176
+ * does `addLabel` when the repo lacks it.
177
+ */
178
+ export type LabelDefinition = {
179
+ name: string
180
+ /** Six hex digits, without `#`. */
181
+ color: string
182
+ description: string
183
+ }
184
+
185
+ /** The labels a run needs, with what they're for. */
186
+ export const RUN_LABELS: LabelDefinition[] = [
187
+ {
188
+ name: READY_LABEL,
189
+ color: '0e8a16',
190
+ description: 'Ready for a Luca run',
191
+ },
192
+ {
193
+ // A run leaves these, and the tickets waiting on them, out (#499).
194
+ name: HUMAN_LABEL,
195
+ color: 'c5def5',
196
+ description: 'Needs a person, not an agent',
197
+ },
198
+ {
199
+ name: REFACTOR_LABEL,
200
+ color: '5319e7',
201
+ description: 'Changes shape, not behavior: no new tests',
202
+ },
203
+ {
204
+ name: NEEDS_INFO_LABEL,
205
+ color: 'd93f0b',
206
+ description: 'Luca needs more detail before it can build this',
207
+ },
208
+ ]
209
+
210
+ /** The version-bump labels a repo with changesets gets, one per bump. */
211
+ export const RELEASE_LABEL_DEFINITIONS: Record<
212
+ (typeof RELEASE_LABELS)[number],
213
+ LabelDefinition
214
+ > = {
215
+ 'release:patch': {
216
+ name: 'release:patch',
217
+ color: 'c2e0c6',
218
+ description: "A patch bump for this spec's changeset (the default)",
219
+ },
220
+ 'release:minor': {
221
+ name: 'release:minor',
222
+ color: 'fbca04',
223
+ description: "A minor bump for this spec's changeset",
224
+ },
225
+ 'release:major': {
226
+ name: 'release:major',
227
+ color: 'b60205',
228
+ description: "A major bump for this spec's changeset",
229
+ },
230
+ 'release:none': {
231
+ name: 'release:none',
232
+ color: 'ededed',
233
+ description: 'No version bump: an empty changeset',
234
+ },
235
+ }
236
+
237
+ /**
238
+ * How the engine creates the label `name` in a repo that lacks it: as
239
+ * `luca setup` would, or plain grey with no description for a label Luca
240
+ * doesn't define.
241
+ *
242
+ * @example
243
+ * labelDefinition({ name: 'needs-info' }).color // 'd93f0b'
244
+ * labelDefinition({ name: 'odd' }) // { name: 'odd', color: 'ededed', description: '' }
245
+ */
246
+ export const labelDefinition = ({ name }: { name: string }): LabelDefinition =>
247
+ [...RUN_LABELS, ...Object.values(RELEASE_LABEL_DEFINITIONS)].find(
248
+ (label) => label.name === name
249
+ ) ?? { name, color: 'ededed', description: '' }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@alecsibilia/luca",
3
3
  "description": "Luca: turns a spec on GitHub Issues into a reviewed pull request, run from Paseo with Claude Code",
4
- "version": "14.0.0-alpha.2",
4
+ "version": "14.0.0-alpha.21",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Alec Sibilia <sibilia.alec@gmail.com>",
7
7
  "homepage": "https://github.com/asibilia/luca-framework#readme",
@@ -24,6 +24,7 @@
24
24
  "files": [
25
25
  "engine/",
26
26
  "board/",
27
+ "skills/",
27
28
  "README.md",
28
29
  "LICENSE",
29
30
  "CHANGELOG.md"
@@ -0,0 +1,74 @@
1
+ ---
2
+ name: luca-retro
3
+ description: Looks back at a finished Luca run and suggests changes to the agents' environment, not the code, so the next run goes better. It reads the run's journal, ranks what went wrong (most serious first), and says for each one the change to make and where: a check to add, a line for the repo's rules file, an instruction to delete, missing information, waste, or a Luca bug. Once the owner picks findings by number, it opens a GitHub issue for each, after a yes. Use it for `/luca-retro [run id ...]`, and whenever someone asks for a retro, what went wrong in the run, how to stop this happening again, or the lessons from a run, even if they don't name the skill.
4
+ argument-hint: "[run id ...]"
5
+ ---
6
+
7
+ # Look back at a Luca run
8
+
9
+ A retro changes the agents' environment, not the code: when an agent got something wrong, ask what would have stopped it. A mistake a machine can spot gets a check (a lint rule, a gate, a guard, a CI job). A judgement call gets one line in the repo's rules file. An instruction that changed nothing gets deleted. Run by hand after a run, so the rules get shorter over time, not longer.
10
+
11
+ You were given: $ARGUMENTS
12
+
13
+ That is zero or more run ids. Talk to the owner in plain words: short sentences, no jargon they didn't use first.
14
+
15
+ ## 1. Read the run
16
+
17
+ Run the helper from the repo's folder. It only reads.
18
+
19
+ ```bash
20
+ bun ~/.claude/skills/luca-retro/scripts/retro-summary.ts [run id ...]
21
+ ```
22
+
23
+ - No run id: it sums up this repo's newest finished run (one that opened its PR, was stopped, or had nothing to do), found from the main checkout, any of its worktrees, or a subfolder. If that isn't the one the owner means, ask.
24
+ - Several run ids: it sums up each, then lists the patterns that repeat across them. A repeat ranks higher.
25
+ - It prints the run's spec, repo, Luca versions, and how it ended; then what got stuck and how long the owner took to reply, fix loops that hit their cap, leftover scan hits, agents out of turns, "No open agent session" failures, decision model calls that failed, checks and tests that failed again and again, setup changes agents asked for, joins that clashed, replies, the agents' assumptions, the findings fixers declined, slow steps, and tokens. Every line names its journal seq (`seq 123`).
26
+
27
+ The journal is all there is: agents run without saved sessions, so there are no transcripts. To read one record in full: `jq -c 'select(.seq == 123)' ~/.local/state/luca/runs/<run id>/journal.jsonl` (or under `$LUCA_RUNS_DIR`). The records are JSON lines: `seq`, `time`, `kind`, `ticket`, `role`, `content`.
28
+
29
+ When a finding needs it, look (read only) at what the agents were given in the run's repo: the rule files listed in `.luca/config.json` (`rule_files`, also `test_file_patterns` and `test_setup_files`), `AGENTS.md` or `CLAUDE.md`, the glossary and ADRs, the lint config, and the CI config. Check whether a rule already covers the mistake before suggesting one.
30
+
31
+ ## 2. Rank the findings
32
+
33
+ List them most serious first: what cost the most time, tokens, or owner replies, and what repeats. For each:
34
+
35
+ 1. **What happened**, with evidence: seqs, tickets, counts. Say it plainly. Cite a journal record as `seq <n>`, never `#<n>`: on GitHub, `#<n>` links to an unrelated issue. Tickets, PRs, and issues keep `#<n>`.
36
+ 2. **Its bucket**, one of six:
37
+ - **(a) Check to add**: a lint rule, a gate, a guard, or a CI job, for a mistake a machine can spot.
38
+ - **(b) Rules line**: one line for the repo's rules file, for a judgement call.
39
+ - **(c) Delete**: an instruction that changed nothing, or one so long it hid the rest.
40
+ - **(d) Missing information**: a glossary word, an ADR, a setup step the agents had to guess (their assumptions show these).
41
+ - **(e) Waste**: tools or tokens spent for nothing, such as agents out of turns, steps far slower than the rest, or calls that always fail.
42
+ - **(f) Luca bug**: the engine itself went wrong. It goes to `asibilia/luca-framework`, not the repo.
43
+ 3. **The change**, and where: the file and the words, or the check and what it catches.
44
+
45
+ Prefer (a) over (b) when a check can catch it: a check works every time, a rule only when read. Prefer deleting over adding. Leave out what happened once and can't happen again.
46
+
47
+ Some signs, from the helper's sections:
48
+
49
+ - The same stuck reason (such as `leftovers_found`) again and again: a rule or a check, or a Luca bug when the engine was wrong to block it.
50
+ - A `setup_change_needed`: the repo's setup was missing something every ticket like it will need.
51
+ - Agents out of turns, or "No open agent session" failures: often (e) or (f).
52
+ - A `jev_failed` on every call, or a `decision_model_off`: missing or turned-down Cloudflare credentials in `~/.config/luca/.env`, (e).
53
+ - One test failing in many gates: a flaky or build-bound test, (a) or (f).
54
+ - Many assumptions about the same thing: (d).
55
+ - A finding declined with `wont_fix` for a reason the run can't change (a role can't write a file): (f) or (b).
56
+
57
+ ## 3. Stop
58
+
59
+ Show the ranked list, numbered, and stop. Nothing happens until the owner picks findings by number.
60
+
61
+ ## 4. Open an issue for each pick
62
+
63
+ For each finding the owner picked:
64
+
65
+ 1. Check for one already open or closed: `gh issue list --repo <owner/repo> --search "<a few words>" --state all`. If one fits, link it instead of opening a new one.
66
+ 2. Otherwise show the issue's exact title and body, and the repo it goes to: Luca bugs to `asibilia/luca-framework`, the rest to the run's repo (the "Repo" line). Put the evidence in the body: the run id, the seqs (as `seq <n>`), the Luca version. Cite a ticket, PR, or issue of another repo as `owner/repo#<n>`, so it links to the right place; a bare `#<n>` links to the repo the issue is in.
67
+ 3. Wait for a yes, then open it: `gh issue create --repo <owner/repo> --title "<title>" --body "<body>"`. Say the link.
68
+
69
+ ## What not to do
70
+
71
+ - Never edit code or rule files, and never commit. The issue says what to change; a person or a later run does it.
72
+ - Never open an issue without the owner's yes.
73
+ - Never run on your own: only when the owner asks.
74
+ - Never edit the journal. It is the engine's.