@alecsibilia/luca 13.1.0-alpha.0 → 14.0.0-alpha.1

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 (290) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +94 -24
  3. package/board/client/board-look.ts +292 -0
  4. package/board/client/board-panel.tsx +1355 -0
  5. package/board/client/engine-settings-screen.tsx +167 -0
  6. package/board/client/timeline-rows.tsx +402 -0
  7. package/board/index.client.tsx +109 -0
  8. package/board/index.server.ts +148 -0
  9. package/board/package.json +6 -0
  10. package/board/paseo-plugin.json +7 -0
  11. package/board/server/board-server.ts +988 -0
  12. package/board/server/board-vocabulary.ts +492 -0
  13. package/board/server/engine-launch.ts +193 -0
  14. package/board/server/engine-watch.ts +197 -0
  15. package/board/server/list-processes.ts +35 -0
  16. package/board/server/luca-version.ts +2 -0
  17. package/board/server/make-rows.ts +834 -0
  18. package/board/server/reduce-board.ts +1953 -0
  19. package/board/server/run-command.ts +54 -0
  20. package/board/server/run-journals.ts +120 -0
  21. package/board/server/run-registry.ts +171 -0
  22. package/board/server/spawn-detached.ts +45 -0
  23. package/board/server/usage-lines-file.ts +43 -0
  24. package/board/shared/board-rows.ts +127 -0
  25. package/board/shared/board-rpc.ts +131 -0
  26. package/board/shared/board-state.ts +683 -0
  27. package/board/shared/engine-settings.ts +36 -0
  28. package/engine/agents/agent-launcher.ts +188 -0
  29. package/engine/agents/claude-launcher.ts +781 -0
  30. package/engine/agents/claude-options.ts +239 -0
  31. package/engine/agents/message-tool.ts +124 -0
  32. package/engine/agents/role-instructions.ts +287 -0
  33. package/engine/agents/role-prompts.ts +224 -0
  34. package/engine/agents/role-results.ts +335 -0
  35. package/engine/agents/scripted-launcher.ts +227 -0
  36. package/engine/board/board-state-dir.ts +20 -0
  37. package/engine/board/board-sync.ts +145 -0
  38. package/engine/board/paseo-board-link.ts +125 -0
  39. package/engine/cli/board-in-paseo.ts +154 -0
  40. package/engine/cli/bunfig.toml +4 -0
  41. package/engine/cli/computer-adapters-real.ts +456 -0
  42. package/engine/cli/computer-adapters.ts +122 -0
  43. package/engine/cli/computer-checks.ts +404 -0
  44. package/engine/cli/doctor-checks.ts +171 -0
  45. package/engine/cli/doctor-command.ts +82 -0
  46. package/engine/cli/doctor.ts +369 -0
  47. package/engine/cli/going-runs.ts +130 -0
  48. package/engine/cli/init-command.ts +175 -0
  49. package/engine/cli/init.ts +367 -0
  50. package/engine/cli/luca-run.ts +189 -0
  51. package/engine/cli/luca.ts +63 -0
  52. package/engine/cli/muninn-entry.ts +87 -0
  53. package/engine/cli/repo-adapters-real.ts +87 -0
  54. package/engine/cli/run-args.ts +223 -0
  55. package/engine/cli/run-modes.ts +629 -0
  56. package/engine/cli/setup-command.ts +59 -0
  57. package/engine/cli/setup.ts +731 -0
  58. package/engine/cli/upgrade-command.ts +140 -0
  59. package/engine/cli/upgrade.ts +262 -0
  60. package/engine/cli/v13-leftovers.ts +694 -0
  61. package/engine/config/engine-config.ts +174 -0
  62. package/engine/config/luca-version.ts +47 -0
  63. package/engine/core/changeset.ts +139 -0
  64. package/engine/core/decide-build.ts +1368 -0
  65. package/engine/core/decide-crashes.ts +70 -0
  66. package/engine/core/decide-final-review.ts +416 -0
  67. package/engine/core/decide-memory.ts +667 -0
  68. package/engine/core/decide-plan.ts +87 -0
  69. package/engine/core/decide-run-budget.ts +76 -0
  70. package/engine/core/decide-stuck.ts +347 -0
  71. package/engine/core/decide-usage-line.ts +113 -0
  72. package/engine/core/decide-usage.ts +68 -0
  73. package/engine/core/decide.ts +200 -0
  74. package/engine/core/execute-build.ts +1150 -0
  75. package/engine/core/execute-changeset.ts +157 -0
  76. package/engine/core/execute-final-review.ts +324 -0
  77. package/engine/core/execute-memory.ts +475 -0
  78. package/engine/core/execute-stuck.ts +315 -0
  79. package/engine/core/execute.ts +1112 -0
  80. package/engine/core/final-review-text.ts +278 -0
  81. package/engine/core/fix-loop-text.ts +124 -0
  82. package/engine/core/learner-digest.ts +214 -0
  83. package/engine/core/loop-caps.ts +39 -0
  84. package/engine/core/memory-text.ts +132 -0
  85. package/engine/core/pull-request-text.ts +154 -0
  86. package/engine/core/review-text.ts +211 -0
  87. package/engine/core/session-close.ts +159 -0
  88. package/engine/core/stuck-text.ts +374 -0
  89. package/engine/doctor/v13-files.json +3948 -0
  90. package/engine/doctor/v13-manifest.ts +124 -0
  91. package/engine/gates/gate-runner.ts +129 -0
  92. package/engine/gates/gate-schemas.ts +70 -0
  93. package/engine/gates/leftover-scan.ts +110 -0
  94. package/engine/gates/lockfile-install.ts +109 -0
  95. package/engine/gates/red-check.ts +134 -0
  96. package/engine/gates/test-runner.ts +212 -0
  97. package/engine/git/git-adapter.ts +535 -0
  98. package/engine/guards/after-turn-check.ts +269 -0
  99. package/engine/guards/guard-hook.ts +63 -0
  100. package/engine/guards/role-rules.ts +704 -0
  101. package/engine/guards/sandbox-settings.ts +94 -0
  102. package/engine/guards/worktree-state.ts +959 -0
  103. package/engine/index.ts +297 -0
  104. package/engine/intake/intake-checks.ts +295 -0
  105. package/engine/intake/intake-schemas.ts +78 -0
  106. package/engine/jev/jev-client.ts +173 -0
  107. package/engine/jev/jev-jobs.ts +369 -0
  108. package/engine/jev/jev-schemas.ts +89 -0
  109. package/engine/jev/jev-shadow.ts +149 -0
  110. package/engine/journal/journal-record.ts +1340 -0
  111. package/engine/journal/journal.ts +115 -0
  112. package/engine/journal/replay.ts +2440 -0
  113. package/engine/journal/step-records.ts +142 -0
  114. package/engine/limits/limit-wait.ts +86 -0
  115. package/engine/limits/plan-signals.ts +122 -0
  116. package/engine/limits/plan-usage.ts +275 -0
  117. package/engine/limits/run-budget.ts +63 -0
  118. package/engine/limits/usage-line.ts +324 -0
  119. package/engine/memory/memory-client.ts +144 -0
  120. package/engine/memory/memory-recall.ts +62 -0
  121. package/engine/memory/memory-routing.ts +170 -0
  122. package/engine/memory/memory-schemas.ts +125 -0
  123. package/engine/memory/muninn-mcp-client.ts +390 -0
  124. package/engine/messages/agent-messages.ts +357 -0
  125. package/engine/messages/agent-messaging.ts +77 -0
  126. package/engine/shell/run-command.ts +86 -0
  127. package/engine/testing/build-fixtures.ts +912 -0
  128. package/engine/testing/fake-muninn.ts +219 -0
  129. package/engine/testing/final-review-fixtures.ts +223 -0
  130. package/engine/testing/intake-fixtures.ts +118 -0
  131. package/engine/testing/many-tickets.ts +739 -0
  132. package/engine/testing/memory-fixtures.ts +202 -0
  133. package/engine/testing/practice-repo.ts +475 -0
  134. package/engine/testing/practice-run.ts +182 -0
  135. package/engine/tracker/github-tracker.ts +262 -0
  136. package/engine/tracker/in-memory-tracker.ts +161 -0
  137. package/engine/tracker/post-comment-once.ts +69 -0
  138. package/engine/tracker/tracker.ts +119 -0
  139. package/package.json +57 -74
  140. package/bin/luca.js +0 -3
  141. package/dist/chunks/brain.mjs +0 -77
  142. package/dist/chunks/branch.mjs +0 -51
  143. package/dist/chunks/bun-runtime.mjs +0 -46
  144. package/dist/chunks/checks.mjs +0 -57
  145. package/dist/chunks/claim-verify.mjs +0 -70
  146. package/dist/chunks/classify.mjs +0 -105
  147. package/dist/chunks/confidence.mjs +0 -277
  148. package/dist/chunks/config-version-skew.mjs +0 -94
  149. package/dist/chunks/doctor.mjs +0 -176
  150. package/dist/chunks/graph.mjs +0 -162
  151. package/dist/chunks/hook.mjs +0 -850
  152. package/dist/chunks/init.mjs +0 -938
  153. package/dist/chunks/legacy-claude-artifacts.mjs +0 -105
  154. package/dist/chunks/legacy-package.mjs +0 -47
  155. package/dist/chunks/luca-gitignore.mjs +0 -94
  156. package/dist/chunks/muninn-mcp.mjs +0 -81
  157. package/dist/chunks/muninndb-health.mjs +0 -66
  158. package/dist/chunks/phase.mjs +0 -64
  159. package/dist/chunks/plan.mjs +0 -51
  160. package/dist/chunks/pr-review.mjs +0 -128
  161. package/dist/chunks/preferences.mjs +0 -66
  162. package/dist/chunks/repair.mjs +0 -111
  163. package/dist/chunks/repo.mjs +0 -58
  164. package/dist/chunks/retro.mjs +0 -87
  165. package/dist/chunks/roadmap.mjs +0 -63
  166. package/dist/chunks/rules.mjs +0 -524
  167. package/dist/chunks/runner.mjs +0 -289
  168. package/dist/chunks/shared-tmp-payloads.mjs +0 -72
  169. package/dist/chunks/stale-global-symlinks.mjs +0 -78
  170. package/dist/chunks/stale-mcp-server.mjs +0 -90
  171. package/dist/chunks/state.mjs +0 -119
  172. package/dist/chunks/statusline-registered.mjs +0 -145
  173. package/dist/chunks/statusline.mjs +0 -64
  174. package/dist/chunks/stray-local-install.mjs +0 -208
  175. package/dist/chunks/telemetry.mjs +0 -370
  176. package/dist/chunks/todo.mjs +0 -230
  177. package/dist/chunks/vault-config-location.mjs +0 -100
  178. package/dist/chunks/vault-init.mjs +0 -94
  179. package/dist/chunks/verification.mjs +0 -99
  180. package/dist/chunks/version.mjs +0 -70
  181. package/dist/chunks/workflow.mjs +0 -51
  182. package/dist/claude/.claude/agents/architect.md +0 -510
  183. package/dist/claude/.claude/agents/build.md +0 -117
  184. package/dist/claude/.claude/agents/debater.md +0 -95
  185. package/dist/claude/.claude/agents/discuss.md +0 -99
  186. package/dist/claude/.claude/agents/discussion.md +0 -143
  187. package/dist/claude/.claude/agents/execute.md +0 -448
  188. package/dist/claude/.claude/agents/executor.md +0 -187
  189. package/dist/claude/.claude/agents/fast.md +0 -90
  190. package/dist/claude/.claude/agents/finalize.md +0 -562
  191. package/dist/claude/.claude/agents/learner.md +0 -167
  192. package/dist/claude/.claude/agents/plan-reviewer.md +0 -137
  193. package/dist/claude/.claude/agents/plan.md +0 -102
  194. package/dist/claude/.claude/agents/research.md +0 -334
  195. package/dist/claude/.claude/agents/researcher.md +0 -81
  196. package/dist/claude/.claude/agents/review.md +0 -330
  197. package/dist/claude/.claude/agents/reviewer.md +0 -177
  198. package/dist/claude/.claude/agents/shadow-scanner.md +0 -261
  199. package/dist/claude/.claude/agents/test-writer.md +0 -96
  200. package/dist/claude/.claude/agents/triage.md +0 -230
  201. package/dist/claude/.claude/agents/verifier.md +0 -192
  202. package/dist/claude/.claude/commands/bug-diagnose.md +0 -12
  203. package/dist/claude/.claude/commands/gh-issue-triage.md +0 -14
  204. package/dist/claude/.claude/commands/gh-pr-address.md +0 -235
  205. package/dist/claude/.claude/commands/gh-prepare.md +0 -12
  206. package/dist/claude/.claude/commands/grill-me.md +0 -12
  207. package/dist/claude/.claude/commands/lu-review.md +0 -51
  208. package/dist/claude/.claude/commands/lu.md +0 -98
  209. package/dist/claude/.claude/commands/luca-init.md +0 -14
  210. package/dist/claude/.claude/commands/luca-telemetry-report.md +0 -12
  211. package/dist/claude/.claude/commands/memory-audit.md +0 -12
  212. package/dist/claude/.claude/commands/milestone-new.md +0 -122
  213. package/dist/claude/.claude/commands/phase-discuss.md +0 -45
  214. package/dist/claude/.claude/commands/phase-execute.md +0 -39
  215. package/dist/claude/.claude/commands/phase-plan.md +0 -57
  216. package/dist/claude/.claude/commands/repo-cleanup.md +0 -83
  217. package/dist/claude/.claude/commands/todo-add.md +0 -28
  218. package/dist/claude/.claude/commands/todo-check.md +0 -36
  219. package/dist/claude/.claude/hooks/context-refresher.ts +0 -18230
  220. package/dist/claude/.claude/hooks/continuation-messages.ts +0 -18205
  221. package/dist/claude/.claude/hooks/pipeline-guard.ts +0 -18192
  222. package/dist/claude/.claude/luca-statusline.ts +0 -159
  223. package/dist/claude/.claude/settings.json +0 -41
  224. package/dist/claude/skills/arch-audit/SKILL.md +0 -161
  225. package/dist/claude/skills/bug-diagnose/SKILL.md +0 -102
  226. package/dist/claude/skills/caveman/SKILL.md +0 -58
  227. package/dist/claude/skills/choose/SKILL.md +0 -124
  228. package/dist/claude/skills/gh-issue-triage/SKILL.md +0 -97
  229. package/dist/claude/skills/gh-pr-address/SKILL.md +0 -235
  230. package/dist/claude/skills/gh-prepare/SKILL.md +0 -209
  231. package/dist/claude/skills/grill-me/SKILL.md +0 -46
  232. package/dist/claude/skills/lu/SKILL.md +0 -262
  233. package/dist/claude/skills/lu-review/SKILL.md +0 -51
  234. package/dist/claude/skills/luca-init/SKILL.md +0 -91
  235. package/dist/claude/skills/luca-telemetry-report/SKILL.md +0 -210
  236. package/dist/claude/skills/luca-write-surface/SKILL.md +0 -229
  237. package/dist/claude/skills/memory-audit/SKILL.md +0 -217
  238. package/dist/claude/skills/milestone-audit/SKILL.md +0 -525
  239. package/dist/claude/skills/milestone-complete/SKILL.md +0 -179
  240. package/dist/claude/skills/milestone-gaps/SKILL.md +0 -60
  241. package/dist/claude/skills/milestone-new/SKILL.md +0 -125
  242. package/dist/claude/skills/note/SKILL.md +0 -162
  243. package/dist/claude/skills/phase-add/SKILL.md +0 -91
  244. package/dist/claude/skills/phase-assumptions/SKILL.md +0 -92
  245. package/dist/claude/skills/phase-discuss/SKILL.md +0 -175
  246. package/dist/claude/skills/phase-execute/SKILL.md +0 -1494
  247. package/dist/claude/skills/phase-insert/SKILL.md +0 -100
  248. package/dist/claude/skills/phase-plan/SKILL.md +0 -489
  249. package/dist/claude/skills/phase-remove/SKILL.md +0 -113
  250. package/dist/claude/skills/phase-research/SKILL.md +0 -88
  251. package/dist/claude/skills/post-init-tour/SKILL.md +0 -58
  252. package/dist/claude/skills/progress/SKILL.md +0 -271
  253. package/dist/claude/skills/project-new/SKILL.md +0 -564
  254. package/dist/claude/skills/quick/SKILL.md +0 -251
  255. package/dist/claude/skills/rename-audit/SKILL.md +0 -52
  256. package/dist/claude/skills/repo-audit/SKILL.md +0 -88
  257. package/dist/claude/skills/repo-cleanup/SKILL.md +0 -83
  258. package/dist/claude/skills/seed-memory/SKILL.md +0 -242
  259. package/dist/claude/skills/session-pause/SKILL.md +0 -126
  260. package/dist/claude/skills/session-plan/SKILL.md +0 -113
  261. package/dist/claude/skills/session-resume/SKILL.md +0 -111
  262. package/dist/claude/skills/todo-add/SKILL.md +0 -62
  263. package/dist/claude/skills/todo-check/SKILL.md +0 -81
  264. package/dist/claude/skills/trace-insights/SKILL.md +0 -317
  265. package/dist/claude/skills/workflow-save/SKILL.md +0 -277
  266. package/dist/index.d.mts +0 -33
  267. package/dist/index.d.ts +0 -33
  268. package/dist/index.mjs +0 -77
  269. package/dist/shared/luca.4GAIaUJ9.mjs +0 -52
  270. package/dist/shared/luca.B0-3raH6.mjs +0 -127
  271. package/dist/shared/luca.B2-XLiAh.mjs +0 -5603
  272. package/dist/shared/luca.BZc5veeE.mjs +0 -36
  273. package/dist/shared/luca.BfjhRHhj.mjs +0 -217
  274. package/dist/shared/luca.BiqdeEXi.mjs +0 -63
  275. package/dist/shared/luca.BpClq9Sj.mjs +0 -9
  276. package/dist/shared/luca.BqmgwLb7.mjs +0 -88
  277. package/dist/shared/luca.BvjJXX7X.mjs +0 -201
  278. package/dist/shared/luca.C-v36IzX.mjs +0 -102
  279. package/dist/shared/luca.CBjkiJav.mjs +0 -21
  280. package/dist/shared/luca.CPv3B14W.mjs +0 -116
  281. package/dist/shared/luca.CQ3g1xrD.mjs +0 -19
  282. package/dist/shared/luca.CUbGKcdY.mjs +0 -122
  283. package/dist/shared/luca.CpFpA7_C.mjs +0 -10
  284. package/dist/shared/luca.D0gueIEC.mjs +0 -2895
  285. package/dist/shared/luca.DJdV6_Fe.mjs +0 -333
  286. package/dist/shared/luca.DTomPq7I.mjs +0 -91
  287. package/dist/shared/luca.X1IuR7-Y.mjs +0 -361
  288. package/dist/shared/luca.dM-MKlNE.mjs +0 -25
  289. package/dist/shared/luca.naWEcQ4B.mjs +0 -7
  290. package/dist/shared/luca.pgUeD_0M.mjs +0 -249
package/CHANGELOG.md ADDED
@@ -0,0 +1,13 @@
1
+ # @alecsibilia/luca
2
+
3
+ ## 14.0.0-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 8a58510: Spec: Luca v14 fixes: no empty changesets, board version, init sets up the repo ([#480](https://github.com/asibilia/luca-framework/issues/480))
8
+
9
+ ## 14.0.0-alpha.0
10
+
11
+ ### Major Changes
12
+
13
+ - f732641: Luca v14: new Luca on npm
package/README.md CHANGED
@@ -1,47 +1,117 @@
1
1
  # @alecsibilia/luca
2
2
 
3
- Luca — spec-driven agentic development workflow for [Claude Code](https://claude.com/claude-code).
3
+ Luca turns a spec on GitHub Issues into a reviewed pull request. A run takes the spec's tickets through the engine, plain code that picks every next step, while Claude agents write the tests and the code and a fresh reviewer checks each ticket. The board shows the run live in Paseo.
4
4
 
5
- The `luca` CLI bootstraps [MuninnDB](https://github.com/asibilia/muninn) for long-term memory, installs the Luca skill/command/agent set into your global Claude home, and writes the per-project `.luca/` skeleton that drives the autonomous pipeline.
5
+ This is Luca v14, in alpha. Old Luca (v13) is still on npm; see [Coming from v13](#coming-from-v13).
6
6
 
7
- ## What's in the box
7
+ ## What you need
8
8
 
9
- This package is an umbrella: at build time it inlines three private workspace packages into a single self-contained tarball.
9
+ - macOS
10
+ - the Paseo desktop app, 0.9.1 or newer
11
+ - Claude Code 2.1.280 or newer, signed in with a Claude **Pro or Max** plan (not the Free plan, and not an API key)
12
+ - [Bun](https://bun.sh)
13
+ - git
14
+ - the GitHub CLI, `gh`, signed in (`gh auth login`)
15
+ - GitHub Issues as your repo's tracker
10
16
 
11
- | Sub-package | Role |
12
- |---|---|
13
- | `@alecsibilia/luca-cli` | The `luca` command surface (init, doctor, state, phase, todo, telemetry, …) |
14
- | `@alecsibilia/luca-core` | Deterministic logic — state machine, `.luca/` contract, telemetry, complexity routing, verification, confidence journal |
15
- | `@alecsibilia/luca-tools` | Artifact definitions (agents, skills, commands, rules, hooks) + the compiler that emits them to the Claude Code shape |
17
+ ## First run
16
18
 
17
- You do not depend on those names. Just `@alecsibilia/luca`.
19
+ 1. Install Luca:
18
20
 
19
- ## Installation
21
+ ```bash
22
+ bun add -g @alecsibilia/luca
23
+ ```
24
+
25
+ While v14 is in alpha, npm's `latest` is still v13, so install `@alecsibilia/luca@alpha` for now.
26
+
27
+ 2. Set up this computer and your repo, once, from inside your repo:
28
+
29
+ ```bash
30
+ luca init
31
+ ```
32
+
33
+ Run inside a git repo, `luca init` sets up this computer, then runs `luca setup` to set up that repo too. Run outside a repo, it sets up only this computer. For another repo later, run `luca setup` from inside it.
34
+
35
+ 3. Check what `luca setup` wrote to `.luca/config.json`. It names your repo's GitHub name (like `tmnb`) as its memory vault in `muninn.vault`; change it if you want another.
36
+
37
+ 4. In Claude Code, in your repo, run `/setup-matt-pocock-skills` so the planning skills know your repo.
38
+ 5. Write a spec with `/to-spec`, then split it into tickets with `/to-tickets`.
39
+ 6. In a Paseo chat, type `/luca-run <spec number>`. The board shows the run in the side panel, and the run ends in one pull request.
40
+
41
+ ## Commands
42
+
43
+ | Command | What it does |
44
+ | ------- | ------------ |
45
+ | `luca init` | Sets up this computer, once (safe to run again): MuninnDB and its Claude Code entry, the board in Paseo with its engine and Bun paths, and the planning skills (`to-spec`, `to-tickets`, `setup-matt-pocock-skills`, `grilling`, `domain-modeling`). It asks before turning on Paseo's plugins, and leaves skills you already have alone. `--skip-skills` skips the skills. Inside a git repo, it then runs `luca setup` for that repo. |
46
+ | `luca setup` | Gets the repo in this folder ready: the labels a run needs (and the `release:*` labels when the repo uses changesets), `.luca/config.json` (a new one gets the repo's GitHub name as its vault; an existing vault is kept), and a check of GitHub sub-issues and dependencies. `--base <branch>` names the base branch. |
47
+ | `luca doctor` | Checks this computer, this repo when you're in one, and what v13 left behind. Each problem comes with its exact fix. `luca doctor --fix` fixes what's safe without asking: it never deletes (v13 files go to a dated backup folder) and never commits, and it lists the repo files to commit. |
48
+ | `luca upgrade` | Moves to the newest Luca on your channel: `alpha` stays on `alpha`, and it never goes back to v13. It refuses while any run is going (stuck runs and limit waits count) and lists them. Then it reloads the board and says when to run `/reload-skills`. |
49
+ | `luca upgrade --to <version>` | Installs that exact version, an older one too, to go back when a version breaks. |
50
+
51
+ `init`, `setup`, and `upgrade` end with their part of `luca doctor`'s checks.
52
+
53
+ ## Memory
54
+
55
+ Luca's runs remember what they learn with MuninnDB. `luca init` installs and starts it, adds it to Claude Code as the user-scope `muninn` server, and adds a login item that starts it again after a reboot.
56
+
57
+ If you run MuninnDB your own way, or want no memory, skip that step:
20
58
 
21
59
  ```bash
22
- bun add -g @alecsibilia/luca
23
- # or
24
- npm install -g @alecsibilia/luca
60
+ luca init --skip-muninndb
25
61
  ```
26
62
 
27
- ## Quickstart
63
+ A run with no `muninn` server in Claude Code has memory off, and `luca doctor` warns "memory off" rather than failing.
64
+
65
+ ## Coming from v13
66
+
67
+ v14 is a new Luca: `/lu`, `/luca-init`, v13's skills, agents, commands, hooks, and status line are gone. Matt Pocock's skills do the planning, and `/luca-run` does the building. Run `luca doctor --fix` to move what v13 left behind to a backup folder. See the [migration guide](https://github.com/asibilia/luca-framework/blob/main/docs/migrating-to-v14.md).
68
+
69
+ To stay on v13, don't install v14: v13 stays on npm. One computer holds one global `luca`.
70
+
71
+ ## For maintainers
72
+
73
+ ### Releasing
74
+
75
+ This package is released with changesets and the [`release.yml`](https://github.com/asibilia/luca-framework/blob/main/.github/workflows/release.yml) workflow. The repo is in changesets' pre mode `alpha`, so only `14.0.0-alpha.N` versions go out, under npm's `alpha` tag, and `latest` stays on `13.0.1`.
76
+
77
+ 1. Merge a PR with a changeset (`bunx changeset`). On the push to `main`, the workflow opens or updates the Version PR, "chore(release): version packages (...)". This package, `@luca/engine`, and `@luca/board` are one `fixed` group in `.changeset/config.json`: this package ships the engine's and board's files without depending on them, so a changeset that names only the private engine or board (as the engine's own changesets on its runs' PRs do) still bumps this package.
78
+ 2. The Version PR is opened by the bot, so its checks don't start on their own: on the PR, click **Approve workflows to run**.
79
+ 3. Merge the Version PR. The workflow sees no pending changesets and a version that isn't on npm yet, so it publishes: the PR checks, `bun pm pack`, an install of the tarball with `luca-run --demo`, a guard that fails unless the version is `-alpha.N`, `npm publish --tag alpha` over npm trusted publishing (no token), and a GitHub release marked as a prerelease.
80
+
81
+ Switch on `latest` later, after a real `tmnb` run works, with one reviewed PR that runs `changeset pre exit` and changes the `-alpha.N` guard (and the `--tag alpha`) in `release.yml` together.
82
+
83
+ ### What's in the package
84
+
85
+ This is the one package that goes to npm. It's TypeScript source with no build and no bundle, because the engine only runs on Bun. It has two commands: `luca`, for people, and `luca-run`, the engine, which the board starts. At pack time it copies in:
86
+
87
+ | Folder | What it is |
88
+ | ------ | ---------- |
89
+ | `engine/` | The engine's source, from [`packages/engine/src`](../engine/src). Both bins point into it. |
90
+ | `board/` | The board plugin's folder, from [`packages/board`](../board): `paseo-plugin.json`, its entry points, its client, server, and shared code, and its own `package.json`, so Paseo can install it as a folder source. |
91
+ | `LICENSE` | The repo's license. |
92
+
93
+ Test files and test helpers stay out. The engine and the board stay private workspace packages, and this package lists every package they import at runtime as its own dependency.
94
+
95
+ ### Pack it
96
+
97
+ Pack it with Bun, from this folder:
28
98
 
29
99
  ```bash
30
- luca init # Bootstrap MuninnDB + install Claude skills/commands/agents globally
31
- luca vault:init # Configure the per-project MuninnDB vault
32
- luca doctor # Environment diagnostics
100
+ bun pm pack
33
101
  ```
34
102
 
35
- Then, inside Claude Code, run the `/lu` slash command to drive the autonomous pipeline.
103
+ `bun pm pack` runs the `prepack` script ([`scripts/copy-sources.ts`](scripts/copy-sources.ts)), which copies the engine and the board in, then packs, then runs `postpack`, which removes the copies again.
36
104
 
37
- ## CLI reference
105
+ `bun pm pack` leaves out every `bunfig.toml` by default, even one named in `files`. The engine needs its own `cli/bunfig.toml`, because the board starts it with `--config` pointing there. So the script writes an `.npmignore` into `engine/` that puts it back.
38
106
 
39
- Use `luca --help` for the full surface, and `luca <command> --help` per noun group.
107
+ It must be packed with Bun. The manifest uses the workspace's `catalog:` and `workspace:` versions, and `bun pm pack` turns them into real versions in the packed `package.json`. A plain `npm pack` ships them unchanged, and an install from that tarball fails. Publish the tarball Bun made:
40
108
 
41
- Lifecycle: `init`, `vault:init`, `doctor`, `retro`, `claim-verify`, `telemetry`, `rules`, `classify`, `hook`, `repair`, `version`.
109
+ ```bash
110
+ npm publish <tarball> --tag alpha
111
+ ```
42
112
 
43
- Write surface (structured mutations of `.luca/`): `state`, `phase`, `roadmap`, `preferences`, `todo`, `pr-review`, `repo`, `checks`, `branch`, `workflow`, `confidence`, `verification`.
113
+ npm does the publishing because Bun can't publish over npm's trusted publishing (OIDC) yet.
44
114
 
45
115
  ## License
46
116
 
47
- MIT — see [LICENSE](./LICENSE).
117
+ Apache License 2.0. See [LICENSE](https://github.com/asibilia/luca-framework/blob/main/LICENSE).
@@ -0,0 +1,292 @@
1
+ import { useEffect, useState } from 'react'
2
+
3
+ import type { PluginTheme } from '@getpaseo/plugin'
4
+ import { Platform } from 'react-native'
5
+
6
+ import type { Tone } from '../shared/board-rows'
7
+ import type {
8
+ LensState,
9
+ RunStatus,
10
+ TicketStage,
11
+ UsageLevel,
12
+ } from '../shared/board-state'
13
+
14
+ /**
15
+ * Colors and words shared by the side panel and the chat rows, so both views
16
+ * match. Every color comes from the host theme.
17
+ */
18
+
19
+ export const MONO = Platform.select({ ios: 'Menlo', default: 'monospace' })
20
+
21
+ /** How often a running step's time counts up. */
22
+ const TICK_MS = 1000
23
+
24
+ /**
25
+ * The clock, ticking every second, so a running step's time counts up
26
+ * even when no new record redraws the view.
27
+ *
28
+ * @example
29
+ * const now = useNow()
30
+ * currentStepText({ step, now })
31
+ */
32
+ export const useNow = (): number => {
33
+ const [now, setNow] = useState(() => Date.now())
34
+ useEffect(() => {
35
+ const timer = setInterval(() => setNow(Date.now()), TICK_MS)
36
+ return () => clearInterval(timer)
37
+ }, [])
38
+ return now
39
+ }
40
+
41
+ /** Opacity for dimmed parts: empty stages, the final review before it starts. */
42
+ export const DIMMED = 0.45
43
+
44
+ /**
45
+ * Plan usage color: green below 60%, yellow 60–85%, red above 85%, muted
46
+ * with no reading.
47
+ */
48
+ export const usageColor = ({
49
+ level,
50
+ theme,
51
+ }: {
52
+ level: UsageLevel | null
53
+ theme: PluginTheme
54
+ }): string => {
55
+ if (level === null) return theme.colors.foregroundMuted
56
+ switch (level) {
57
+ case 'ok':
58
+ return theme.colors.statusSuccess
59
+ case 'warn':
60
+ return theme.colors.statusWarning
61
+ case 'high':
62
+ return theme.colors.statusDanger
63
+ }
64
+ }
65
+
66
+ export const stageColor = ({
67
+ stage,
68
+ theme,
69
+ }: {
70
+ stage: TicketStage
71
+ theme: PluginTheme
72
+ }): string => {
73
+ switch (stage) {
74
+ case 'building':
75
+ case 'reviewing':
76
+ return theme.colors.accent
77
+ case 'stuck':
78
+ return theme.colors.statusDanger
79
+ case 'done':
80
+ return theme.colors.statusSuccess
81
+ case 'blocked':
82
+ case 'skipped':
83
+ return theme.colors.foregroundMuted
84
+ }
85
+ }
86
+
87
+ export const lensColor = ({
88
+ state,
89
+ theme,
90
+ }: {
91
+ state: LensState
92
+ theme: PluginTheme
93
+ }): string => {
94
+ switch (state) {
95
+ case 'waiting':
96
+ return theme.colors.foregroundMuted
97
+ case 'reviewing':
98
+ return theme.colors.accent
99
+ case 'fixing':
100
+ return theme.colors.statusWarning
101
+ case 'clean':
102
+ return theme.colors.statusSuccess
103
+ }
104
+ }
105
+
106
+ export const toneColor = ({
107
+ tone,
108
+ theme,
109
+ }: {
110
+ tone: Tone
111
+ theme: PluginTheme
112
+ }): string => {
113
+ switch (tone) {
114
+ case 'info':
115
+ return theme.colors.accent
116
+ case 'success':
117
+ return theme.colors.statusSuccess
118
+ case 'warning':
119
+ return theme.colors.statusWarning
120
+ case 'danger':
121
+ return theme.colors.statusDanger
122
+ }
123
+ }
124
+
125
+ export const statusColor = ({
126
+ status,
127
+ theme,
128
+ }: {
129
+ status: RunStatus
130
+ theme: PluginTheme
131
+ }): string => {
132
+ switch (status) {
133
+ case 'done':
134
+ return theme.colors.statusSuccess
135
+ case 'stuck':
136
+ case 'stopped':
137
+ case 'refused':
138
+ case 'ended_with_error':
139
+ return theme.colors.statusDanger
140
+ case 'limit_wait':
141
+ case 'usage_line_wait':
142
+ return theme.colors.statusWarning
143
+ case 'starting':
144
+ case 'intake':
145
+ case 'building':
146
+ case 'final_review':
147
+ return theme.colors.accent
148
+ case 'nothing_to_do':
149
+ return theme.colors.foregroundMuted
150
+ }
151
+ }
152
+
153
+ /** A run status in words. */
154
+ export const statusText = ({ status }: { status: RunStatus }): string => {
155
+ switch (status) {
156
+ case 'starting':
157
+ return 'starting'
158
+ case 'intake':
159
+ return 'intake'
160
+ case 'building':
161
+ return 'building'
162
+ case 'final_review':
163
+ return 'final review'
164
+ case 'limit_wait':
165
+ return 'limit wait'
166
+ case 'usage_line_wait':
167
+ return 'paused at the usage line'
168
+ case 'done':
169
+ return 'done'
170
+ case 'refused':
171
+ return 'refused'
172
+ case 'nothing_to_do':
173
+ return 'nothing to do'
174
+ case 'stuck':
175
+ return 'stuck'
176
+ case 'stopped':
177
+ return 'run stopped'
178
+ case 'ended_with_error':
179
+ return 'engine stopped'
180
+ }
181
+ }
182
+
183
+ /** A usage percent, or "–" for a window with no reading yet. */
184
+ export const percentText = ({ percent }: { percent: number | null }): string =>
185
+ percent === null ? '–' : `${percent}%`
186
+
187
+ /** 1234 → "1.2k"; 9000000 → "9.0M". */
188
+ export const tokensText = ({ tokens }: { tokens: number }): string => {
189
+ if (tokens >= 1_000_000) return `${(tokens / 1_000_000).toFixed(1)}M`
190
+ return tokens >= 1000 ? `${(tokens / 1000).toFixed(1)}k` : String(tokens)
191
+ }
192
+
193
+ const two = ({ value }: { value: number }) => String(value).padStart(2, '0')
194
+
195
+ /** An ISO time as local "hh:mm", or the text itself when it isn't a time. */
196
+ export const clockText = ({ iso }: { iso: string }): string => {
197
+ const date = new Date(iso)
198
+ if (Number.isNaN(date.getTime())) return iso
199
+ return `${two({ value: date.getHours() })}:${two({ value: date.getMinutes() })}`
200
+ }
201
+
202
+ /** When a limit resets, e.g. "17:00 (in 1h 20m)". */
203
+ export const resetsText = ({
204
+ resets_at,
205
+ now,
206
+ }: {
207
+ resets_at: string | null
208
+ now: number
209
+ }): string => {
210
+ if (!resets_at) return 'unknown'
211
+ const at = new Date(resets_at).getTime()
212
+ if (Number.isNaN(at)) return resets_at
213
+ const minutes = Math.max(0, Math.round((at - now) / 60_000))
214
+ const left =
215
+ minutes >= 60
216
+ ? `${Math.floor(minutes / 60)}h ${minutes % 60}m`
217
+ : `${minutes}m`
218
+ return `${clockText({ iso: resets_at })} (in ${left})`
219
+ }
220
+
221
+ /**
222
+ * A limit wait's headline, e.g. "Plan limit hit (five-hour window)". `window`
223
+ * is already in words; without one it's just "Plan limit hit".
224
+ */
225
+ export const limitHitText = ({ window }: { window: string | null }): string =>
226
+ window === null ? 'Plan limit hit' : `Plan limit hit (${window} window)`
227
+
228
+ /** "The run waits until 17:00 (in 1h 20m) and then carries on by itself." */
229
+ export const limitUntilText = ({
230
+ resets_at,
231
+ now,
232
+ }: {
233
+ resets_at: string | null
234
+ now: number
235
+ }): string =>
236
+ `The run waits until ${resetsText({ resets_at, now })} and then carries on by itself.`
237
+
238
+ /**
239
+ * What a limit wait means, e.g. "Plan limit hit (weekly window). The run
240
+ * waits until 17:00 (in 1h 20m) and then carries on by itself."
241
+ */
242
+ export const limitWaitText = ({
243
+ window,
244
+ resets_at,
245
+ now,
246
+ }: {
247
+ window: string | null
248
+ resets_at: string | null
249
+ now: number
250
+ }): string =>
251
+ `${limitHitText({ window })}. ${limitUntilText({ resets_at, now })}`
252
+
253
+ /**
254
+ * What a pause at the usage line means, e.g. "Paused at the weekly usage
255
+ * line: the account's weekly window is at 82% (line 80%). The run waits
256
+ * until 11:00 (in 3h 5m), or until the line is raised, and then carries on
257
+ * by itself."
258
+ */
259
+ export const usageLineWaitText = ({
260
+ window,
261
+ line,
262
+ percent,
263
+ resets_at,
264
+ now,
265
+ }: {
266
+ window: string
267
+ line: number
268
+ percent: number
269
+ resets_at: string
270
+ now: number
271
+ }): string =>
272
+ `Paused at the ${window} usage line: the account's ${window} window is at ${percent}% (line ${line}%). ` +
273
+ `The run waits until ${resetsText({ resets_at, now })}, or until the line is raised, and then carries on by itself.`
274
+
275
+ /** "Spec #10 · Add CSV export", or "Demo run" before the engine names one. */
276
+ export const runTitle = ({
277
+ spec_number,
278
+ spec_title,
279
+ demo,
280
+ }: {
281
+ spec_number: number | null
282
+ spec_title: string | null
283
+ demo: boolean
284
+ }): string => {
285
+ const spec =
286
+ spec_number === null
287
+ ? demo
288
+ ? 'Demo run'
289
+ : 'Run'
290
+ : `${demo ? 'Demo · ' : ''}Spec #${spec_number}`
291
+ return spec_title ? `${spec} · ${spec_title}` : spec
292
+ }