@protoboxai/codeloop 0.3.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 (290) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +589 -0
  3. package/dist/commands/adopt.d.ts +2 -0
  4. package/dist/commands/adopt.js +26 -0
  5. package/dist/commands/adopt.js.map +1 -0
  6. package/dist/commands/brief.d.ts +2 -0
  7. package/dist/commands/brief.js +22 -0
  8. package/dist/commands/brief.js.map +1 -0
  9. package/dist/commands/card.d.ts +6 -0
  10. package/dist/commands/card.js +159 -0
  11. package/dist/commands/card.js.map +1 -0
  12. package/dist/commands/check.d.ts +4 -0
  13. package/dist/commands/check.js +76 -0
  14. package/dist/commands/check.js.map +1 -0
  15. package/dist/commands/cloud.d.ts +8 -0
  16. package/dist/commands/cloud.js +123 -0
  17. package/dist/commands/cloud.js.map +1 -0
  18. package/dist/commands/guard.d.ts +2 -0
  19. package/dist/commands/guard.js +26 -0
  20. package/dist/commands/guard.js.map +1 -0
  21. package/dist/commands/import.d.ts +2 -0
  22. package/dist/commands/import.js +24 -0
  23. package/dist/commands/import.js.map +1 -0
  24. package/dist/commands/inbox.d.ts +2 -0
  25. package/dist/commands/inbox.js +48 -0
  26. package/dist/commands/inbox.js.map +1 -0
  27. package/dist/commands/init.d.ts +2 -0
  28. package/dist/commands/init.js +142 -0
  29. package/dist/commands/init.js.map +1 -0
  30. package/dist/commands/install.d.ts +2 -0
  31. package/dist/commands/install.js +125 -0
  32. package/dist/commands/install.js.map +1 -0
  33. package/dist/commands/lane.d.ts +2 -0
  34. package/dist/commands/lane.js +100 -0
  35. package/dist/commands/lane.js.map +1 -0
  36. package/dist/commands/list.d.ts +2 -0
  37. package/dist/commands/list.js +35 -0
  38. package/dist/commands/list.js.map +1 -0
  39. package/dist/commands/login.d.ts +2 -0
  40. package/dist/commands/login.js +77 -0
  41. package/dist/commands/login.js.map +1 -0
  42. package/dist/commands/mock.d.ts +3 -0
  43. package/dist/commands/mock.js +22 -0
  44. package/dist/commands/mock.js.map +1 -0
  45. package/dist/commands/pack.d.ts +2 -0
  46. package/dist/commands/pack.js +19 -0
  47. package/dist/commands/pack.js.map +1 -0
  48. package/dist/commands/publish.d.ts +2 -0
  49. package/dist/commands/publish.js +125 -0
  50. package/dist/commands/publish.js.map +1 -0
  51. package/dist/commands/remove.d.ts +2 -0
  52. package/dist/commands/remove.js +31 -0
  53. package/dist/commands/remove.js.map +1 -0
  54. package/dist/commands/render.d.ts +5 -0
  55. package/dist/commands/render.js +47 -0
  56. package/dist/commands/render.js.map +1 -0
  57. package/dist/commands/run.d.ts +2 -0
  58. package/dist/commands/run.js +45 -0
  59. package/dist/commands/run.js.map +1 -0
  60. package/dist/commands/scan.d.ts +2 -0
  61. package/dist/commands/scan.js +26 -0
  62. package/dist/commands/scan.js.map +1 -0
  63. package/dist/commands/schedule.d.ts +2 -0
  64. package/dist/commands/schedule.js +51 -0
  65. package/dist/commands/schedule.js.map +1 -0
  66. package/dist/commands/search.d.ts +2 -0
  67. package/dist/commands/search.js +85 -0
  68. package/dist/commands/search.js.map +1 -0
  69. package/dist/commands/serve.d.ts +7 -0
  70. package/dist/commands/serve.js +126 -0
  71. package/dist/commands/serve.js.map +1 -0
  72. package/dist/commands/spec.d.ts +3 -0
  73. package/dist/commands/spec.js +64 -0
  74. package/dist/commands/spec.js.map +1 -0
  75. package/dist/commands/status.d.ts +3 -0
  76. package/dist/commands/status.js +251 -0
  77. package/dist/commands/status.js.map +1 -0
  78. package/dist/commands/update.d.ts +2 -0
  79. package/dist/commands/update.js +83 -0
  80. package/dist/commands/update.js.map +1 -0
  81. package/dist/commands/verify.d.ts +3 -0
  82. package/dist/commands/verify.js +75 -0
  83. package/dist/commands/verify.js.map +1 -0
  84. package/dist/commands/watch.d.ts +6 -0
  85. package/dist/commands/watch.js +111 -0
  86. package/dist/commands/watch.js.map +1 -0
  87. package/dist/commands/wiki.d.ts +3 -0
  88. package/dist/commands/wiki.js +85 -0
  89. package/dist/commands/wiki.js.map +1 -0
  90. package/dist/index.d.ts +2 -0
  91. package/dist/index.js +86 -0
  92. package/dist/index.js.map +1 -0
  93. package/dist/lib/agent.d.ts +27 -0
  94. package/dist/lib/agent.js +178 -0
  95. package/dist/lib/agent.js.map +1 -0
  96. package/dist/lib/board.d.ts +38 -0
  97. package/dist/lib/board.js +86 -0
  98. package/dist/lib/board.js.map +1 -0
  99. package/dist/lib/cards.d.ts +82 -0
  100. package/dist/lib/cards.js +107 -0
  101. package/dist/lib/cards.js.map +1 -0
  102. package/dist/lib/clock.d.ts +5 -0
  103. package/dist/lib/clock.js +14 -0
  104. package/dist/lib/clock.js.map +1 -0
  105. package/dist/lib/cloud.d.ts +122 -0
  106. package/dist/lib/cloud.js +580 -0
  107. package/dist/lib/cloud.js.map +1 -0
  108. package/dist/lib/competitors.d.ts +28 -0
  109. package/dist/lib/competitors.js +90 -0
  110. package/dist/lib/competitors.js.map +1 -0
  111. package/dist/lib/config.d.ts +7 -0
  112. package/dist/lib/config.js +25 -0
  113. package/dist/lib/config.js.map +1 -0
  114. package/dist/lib/cron.d.ts +5 -0
  115. package/dist/lib/cron.js +82 -0
  116. package/dist/lib/cron.js.map +1 -0
  117. package/dist/lib/detect.d.ts +13 -0
  118. package/dist/lib/detect.js +60 -0
  119. package/dist/lib/detect.js.map +1 -0
  120. package/dist/lib/engine.d.ts +88 -0
  121. package/dist/lib/engine.js +435 -0
  122. package/dist/lib/engine.js.map +1 -0
  123. package/dist/lib/flow.d.ts +44 -0
  124. package/dist/lib/flow.js +121 -0
  125. package/dist/lib/flow.js.map +1 -0
  126. package/dist/lib/glob.d.ts +2 -0
  127. package/dist/lib/glob.js +10 -0
  128. package/dist/lib/glob.js.map +1 -0
  129. package/dist/lib/import.d.ts +13 -0
  130. package/dist/lib/import.js +127 -0
  131. package/dist/lib/import.js.map +1 -0
  132. package/dist/lib/inbox.d.ts +42 -0
  133. package/dist/lib/inbox.js +65 -0
  134. package/dist/lib/inbox.js.map +1 -0
  135. package/dist/lib/lane.d.ts +71 -0
  136. package/dist/lib/lane.js +105 -0
  137. package/dist/lib/lane.js.map +1 -0
  138. package/dist/lib/lock.d.ts +6 -0
  139. package/dist/lib/lock.js +64 -0
  140. package/dist/lib/lock.js.map +1 -0
  141. package/dist/lib/mcp.d.ts +2 -0
  142. package/dist/lib/mcp.js +57 -0
  143. package/dist/lib/mcp.js.map +1 -0
  144. package/dist/lib/mock.d.ts +17 -0
  145. package/dist/lib/mock.js +137 -0
  146. package/dist/lib/mock.js.map +1 -0
  147. package/dist/lib/pack.d.ts +24 -0
  148. package/dist/lib/pack.js +77 -0
  149. package/dist/lib/pack.js.map +1 -0
  150. package/dist/lib/proposals.d.ts +48 -0
  151. package/dist/lib/proposals.js +240 -0
  152. package/dist/lib/proposals.js.map +1 -0
  153. package/dist/lib/render.d.ts +7 -0
  154. package/dist/lib/render.js +84 -0
  155. package/dist/lib/render.js.map +1 -0
  156. package/dist/lib/research.d.ts +8 -0
  157. package/dist/lib/research.js +39 -0
  158. package/dist/lib/research.js.map +1 -0
  159. package/dist/lib/run.d.ts +38 -0
  160. package/dist/lib/run.js +215 -0
  161. package/dist/lib/run.js.map +1 -0
  162. package/dist/lib/scaffold.d.ts +16 -0
  163. package/dist/lib/scaffold.js +175 -0
  164. package/dist/lib/scaffold.js.map +1 -0
  165. package/dist/lib/scan.d.ts +22 -0
  166. package/dist/lib/scan.js +85 -0
  167. package/dist/lib/scan.js.map +1 -0
  168. package/dist/lib/schedule.d.ts +20 -0
  169. package/dist/lib/schedule.js +66 -0
  170. package/dist/lib/schedule.js.map +1 -0
  171. package/dist/lib/server.d.ts +68 -0
  172. package/dist/lib/server.js +235 -0
  173. package/dist/lib/server.js.map +1 -0
  174. package/dist/lib/shell.d.ts +1 -0
  175. package/dist/lib/shell.js +25 -0
  176. package/dist/lib/shell.js.map +1 -0
  177. package/dist/lib/skills.d.ts +20 -0
  178. package/dist/lib/skills.js +92 -0
  179. package/dist/lib/skills.js.map +1 -0
  180. package/dist/lib/spec.d.ts +24 -0
  181. package/dist/lib/spec.js +102 -0
  182. package/dist/lib/spec.js.map +1 -0
  183. package/dist/lib/stats.d.ts +13 -0
  184. package/dist/lib/stats.js +43 -0
  185. package/dist/lib/stats.js.map +1 -0
  186. package/dist/lib/verify.d.ts +25 -0
  187. package/dist/lib/verify.js +135 -0
  188. package/dist/lib/verify.js.map +1 -0
  189. package/dist/lib/version.d.ts +10 -0
  190. package/dist/lib/version.js +27 -0
  191. package/dist/lib/version.js.map +1 -0
  192. package/dist/lib/wiki.d.ts +51 -0
  193. package/dist/lib/wiki.js +164 -0
  194. package/dist/lib/wiki.js.map +1 -0
  195. package/dist/registry/index.d.ts +7 -0
  196. package/dist/registry/index.js +8 -0
  197. package/dist/registry/index.js.map +1 -0
  198. package/dist/registry/installer.d.ts +30 -0
  199. package/dist/registry/installer.js +133 -0
  200. package/dist/registry/installer.js.map +1 -0
  201. package/dist/registry/local-index.d.ts +32 -0
  202. package/dist/registry/local-index.js +58 -0
  203. package/dist/registry/local-index.js.map +1 -0
  204. package/dist/registry/lockfile.d.ts +40 -0
  205. package/dist/registry/lockfile.js +85 -0
  206. package/dist/registry/lockfile.js.map +1 -0
  207. package/dist/registry/security.d.ts +25 -0
  208. package/dist/registry/security.js +100 -0
  209. package/dist/registry/security.js.map +1 -0
  210. package/dist/registry/skill-schema.d.ts +30 -0
  211. package/dist/registry/skill-schema.js +95 -0
  212. package/dist/registry/skill-schema.js.map +1 -0
  213. package/dist/ui/404.html +1 -0
  214. package/dist/ui/_next/static/6wzGE5sCtbYkSyhMWxL32/_buildManifest.js +1 -0
  215. package/dist/ui/_next/static/6wzGE5sCtbYkSyhMWxL32/_ssgManifest.js +1 -0
  216. package/dist/ui/_next/static/chunks/255-54d3085ce94738a4.js +1 -0
  217. package/dist/ui/_next/static/chunks/423-bb541b7ae2733575.js +1 -0
  218. package/dist/ui/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
  219. package/dist/ui/_next/static/chunks/app/_not-found/page-d6bc774f7acb716e.js +1 -0
  220. package/dist/ui/_next/static/chunks/app/layout-e5fc8e78e1c8da95.js +1 -0
  221. package/dist/ui/_next/static/chunks/app/page-0c34b6e119cef236.js +1 -0
  222. package/dist/ui/_next/static/chunks/framework-de98b93a850cfc71.js +1 -0
  223. package/dist/ui/_next/static/chunks/main-49fd204fc9037ea3.js +1 -0
  224. package/dist/ui/_next/static/chunks/main-app-c46afa2f48f3aaef.js +1 -0
  225. package/dist/ui/_next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
  226. package/dist/ui/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
  227. package/dist/ui/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  228. package/dist/ui/_next/static/chunks/webpack-4a462cecab786e93.js +1 -0
  229. package/dist/ui/_next/static/css/1bf01240dbfd6088.css +1 -0
  230. package/dist/ui/index.html +1 -0
  231. package/dist/ui/index.txt +19 -0
  232. package/dist/watch/index.d.ts +21 -0
  233. package/dist/watch/index.js +88 -0
  234. package/dist/watch/index.js.map +1 -0
  235. package/dist/watch/reporter.d.ts +11 -0
  236. package/dist/watch/reporter.js +44 -0
  237. package/dist/watch/reporter.js.map +1 -0
  238. package/dist/watch/signals.d.ts +38 -0
  239. package/dist/watch/signals.js +119 -0
  240. package/dist/watch/signals.js.map +1 -0
  241. package/dist/watch/triggers.d.ts +10 -0
  242. package/dist/watch/triggers.js +67 -0
  243. package/dist/watch/triggers.js.map +1 -0
  244. package/package.json +64 -0
  245. package/registry/index.json +106 -0
  246. package/starters/generic.yaml +95 -0
  247. package/starters/go.yaml +99 -0
  248. package/starters/node-typescript.yaml +108 -0
  249. package/starters/python.yaml +105 -0
  250. package/templates/ci/codeloop-pr.yml +29 -0
  251. package/templates/ci/codeloop-prod.yml +27 -0
  252. package/templates/ci/codeloop-staging.yml +34 -0
  253. package/templates/codeloop/board.json +5 -0
  254. package/templates/codeloop/gotchas.md +13 -0
  255. package/templates/codeloop/patterns.md +15 -0
  256. package/templates/codeloop/principles.md +49 -0
  257. package/templates/codeloop/rules.md +23 -0
  258. package/templates/commands/commit.md +255 -0
  259. package/templates/commands/debug.md +142 -0
  260. package/templates/commands/deploy.md +144 -0
  261. package/templates/commands/design.md +102 -0
  262. package/templates/commands/manage.md +77 -0
  263. package/templates/commands/plan.md +84 -0
  264. package/templates/commands/qa.md +155 -0
  265. package/templates/commands/reflect.md +93 -0
  266. package/templates/commands/ship.md +187 -0
  267. package/templates/commands/test.md +133 -0
  268. package/templates/hooks/commit-msg +8 -0
  269. package/templates/lanes/analyze.yaml +25 -0
  270. package/templates/lanes/build.yaml +45 -0
  271. package/templates/lanes/deploy.yaml +24 -0
  272. package/templates/lanes/learn.yaml +20 -0
  273. package/templates/lanes/market.yaml +25 -0
  274. package/templates/lanes/plan.yaml +24 -0
  275. package/templates/lanes/scan.yaml +11 -0
  276. package/templates/lanes/triage.yaml +24 -0
  277. package/templates/mock/template.html +82 -0
  278. package/templates/seeds/go-gotchas.md +28 -0
  279. package/templates/seeds/go-patterns.md +22 -0
  280. package/templates/seeds/node-typescript-gotchas.md +30 -0
  281. package/templates/seeds/node-typescript-patterns.md +27 -0
  282. package/templates/seeds/python-gotchas.md +30 -0
  283. package/templates/seeds/python-patterns.md +19 -0
  284. package/templates/seeds/universal-gotchas.md +11 -0
  285. package/templates/seeds/universal-patterns.md +11 -0
  286. package/templates/spec/plan.md +7 -0
  287. package/templates/spec/research.md +19 -0
  288. package/templates/spec/spec.md +14 -0
  289. package/templates/spec/tasks.md +10 -0
  290. package/templates/tasks/todo.md +3 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Dean Grover
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,589 @@
1
+ # codeloop
2
+
3
+ **The full dev lifecycle for AI coding agents.**
4
+
5
+ Your AI agent plans the work, tests it, reviews its own commits, deploys to staging, debugs production, and learns from every mistake — across sessions, across tools, without you babysitting it.
6
+
7
+ ![Codeloop Board](https://codeloop.protobox.ai/board.png)
8
+
9
+ ## The Problem
10
+
11
+ AI coding tools (Claude Code, Cursor, Codex) are stateless. Every session starts from zero. You've explained that `doc.save()` has race conditions six times. You've caught `console.log` in production code on every PR. The agent never learns, because it can't remember.
12
+
13
+ Worse — the agent can write code, but it can't test, deploy, or debug. You're still the glue between "code complete" and "live in production." That's where most of the time goes.
14
+
15
+ ## The Pipeline
16
+
17
+ codeloop gives your project ten slash commands that cover the full development lifecycle:
18
+
19
+ ```
20
+ /design → /plan → /manage → /test → /commit → /qa → /deploy → /debug → /reflect → /ship
21
+ ```
22
+
23
+ | Command | What it does |
24
+ |---------|-------------|
25
+ | `/design` | Analyze the codebase, generate a lightweight architectural spec |
26
+ | `/plan` | Write a task plan with acceptance criteria, enter plan mode |
27
+ | `/manage` | Track steps, check off progress, manage the task board |
28
+ | `/test` | Run your test suite, parse results, track coverage over time |
29
+ | `/commit` | Three-phase commit: review diff against learned rubrics → reflect on session → commit |
30
+ | `/qa` | Quality gate: static analysis + tests + coverage threshold + integrity checks |
31
+ | `/deploy` | Deploy to staging or production with verification gates |
32
+ | `/debug` | Search production logs, check health, cross-reference with recent commits |
33
+ | `/reflect` | Deep session review: scan all work, propose lessons to save |
34
+ | `/ship` | Close the loop: QA → staging → production → verify → done |
35
+
36
+ Each command reads your project's config and knowledge files. No runtime, no server — just markdown and YAML that the LLM reads directly.
37
+
38
+ ## How Knowledge Compounds
39
+
40
+ Every gotcha has a frequency counter:
41
+
42
+ ```
43
+ Session 1: You discover that boolean query params need Transform decorators.
44
+ /commit saves it → gotchas.md [freq:1]
45
+ Next review: appears as a WARNING (non-blocking)
46
+
47
+ Session 4: It comes up again. /reflect increments → [freq:2]
48
+
49
+ Session 7: Third time. → [freq:3]
50
+ Now it's CRITICAL. /commit blocks until you confirm it's handled.
51
+
52
+ Session 20: [freq:10+]
53
+ codeloop status says: "promote this to rules.md?"
54
+ It graduates from gotcha to non-negotiable rule.
55
+ ```
56
+
57
+ **Frequency = severity.** The more something bites you, the harder the system fights to prevent it. No configuration needed — it emerges from use.
58
+
59
+ The review is scoped too. Changed a backend file? It loads backend gotchas. Frontend only? It skips database warnings. Scopes in your config control what's relevant:
60
+
61
+ ```yaml
62
+ scopes:
63
+ backend:
64
+ paths: ["src/**", "lib/**"]
65
+ gotcha_sections: ["Backend", "Database"]
66
+ frontend:
67
+ paths: ["app/**", "components/**"]
68
+ gotcha_sections: ["Frontend", "React"]
69
+ ```
70
+
71
+ ## Quick Start
72
+
73
+ ```bash
74
+ npm install -g @protoboxai/codeloop
75
+ cd your-project
76
+ codeloop init
77
+ ```
78
+
79
+ It asks which AI tools you use, detects your tech stack, and scaffolds:
80
+
81
+ ```
82
+ .codeloop/
83
+ config.yaml ← Scopes, quality checks, deploy/test/debug config
84
+ rules.md ← Non-negotiable rules (always CRITICAL in review)
85
+ gotchas.md ← Discovered gotchas with frequency tracking
86
+ patterns.md ← Proven patterns with confidence levels
87
+ principles.md ← How you want the AI to operate
88
+
89
+ .claude/commands/ ← 10 slash commands (Claude Code)
90
+ .cursor/commands/ ← 10 slash commands (Cursor)
91
+ .agents/skills/ ← 10 skills (Codex)
92
+
93
+ tasks/todo.md ← Current task plan
94
+ ```
95
+
96
+ The knowledge base (`.codeloop/`) is shared across all tools. Doesn't matter if you use Claude Code on Monday and Cursor on Tuesday — same gotchas, same rules.
97
+
98
+ ## The Config
99
+
100
+ `.codeloop/config.yaml` controls everything. The AI reads it directly. `.codeloop/local.yaml` (gitignored) overrides it on one machine and is where keys, tokens and machine paths go.
101
+
102
+ ```yaml
103
+ project:
104
+ name: "my-api"
105
+
106
+ # Map file paths to knowledge sections
107
+ scopes:
108
+ backend:
109
+ paths: ["src/**"]
110
+ gotcha_sections: ["Backend", "Database", "API"]
111
+ tests:
112
+ paths: ["**/*.test.*"]
113
+ gotcha_sections: ["Testing"]
114
+
115
+ # Build/lint checks run during /commit and /qa
116
+ quality_checks:
117
+ backend:
118
+ - name: "Typecheck"
119
+ command: "npx tsc --noEmit 2>&1 | tail -20"
120
+
121
+ # Patterns banned in diffs
122
+ diff_scan:
123
+ - pattern: "console\\.log"
124
+ files: "*.ts,*.js"
125
+ exclude: "*.test.*"
126
+ severity: CRITICAL
127
+ message: "console.log in production code"
128
+
129
+ # Test runner config (used by /test and /qa)
130
+ test:
131
+ command: "npm test"
132
+ coverage_threshold: 80
133
+ integrity_checks: true
134
+
135
+ # Deployment gates (used by /deploy and /ship)
136
+ deploy:
137
+ staging:
138
+ command: "make deploy-staging"
139
+ verify: "curl -sf https://staging.example.com/health"
140
+ production:
141
+ command: "make deploy-prod"
142
+ verify: "curl -sf https://example.com/health"
143
+ requires: staging
144
+
145
+ # Production debugging (used by /debug)
146
+ debug:
147
+ logs: "fly logs --app myapp"
148
+ health: "curl -sf https://example.com/health"
149
+
150
+ # Frequency thresholds
151
+ codeloop:
152
+ critical_frequency: 3
153
+ promote_frequency: 10
154
+ ```
155
+
156
+ ## The Commit Flow
157
+
158
+ When you type `/commit`:
159
+
160
+ ```
161
+ Phase 1: Review
162
+ ├─ Map changed files → scopes
163
+ ├─ Load gotchas (freq ≥ 3 = CRITICAL, 1-2 = WARNING)
164
+ ├─ Load patterns (HIGH confidence = expected)
165
+ ├─ Run quality checks for active scopes
166
+ ├─ Scan diff for violations
167
+ └─ Verdict: CLEAN / WARNINGS / BLOCKED
168
+
169
+ Phase 2: Reflect (lightweight)
170
+ ├─ Scan session for new gotchas or patterns
171
+ ├─ Propose saves (you pick what to keep)
172
+ └─ Write to gotchas.md or patterns.md
173
+
174
+ Phase 3: Commit
175
+ ├─ Stage files
176
+ ├─ Generate conventional commit message
177
+ └─ Create commit
178
+ ```
179
+
180
+ If the review finds CRITICAL issues, it blocks. You can fix them, override, or abort.
181
+
182
+ ## The Deployment Pipeline
183
+
184
+ `/qa` → `/deploy staging` → `/deploy prod` forms a gate chain:
185
+
186
+ ```
187
+ /qa passes → sets env:local-pass → unlocks staging
188
+ /deploy staging → sets env:staging-pass → unlocks production
189
+ /deploy prod → sets env:prod-pass → task is done
190
+ ```
191
+
192
+ `/ship` runs the full chain in one command. If any gate fails, it stops and creates a regression task on the board.
193
+
194
+ ## Lanes
195
+
196
+ A lane is one YAML file in `.codeloop/lanes/`. It lists the stages a card moves through, the skill each stage runs, the command that decides whether the stage is finished, and the gates where a person has to say yes. `codeloop init` installs eight: build, market, analyze, triage, plan, deploy, learn, scan.
197
+
198
+ ```bash
199
+ codeloop start "Add CSV export" # a card in the build lane, plus its spec folder
200
+ codeloop next # run the current stage's check; move the card if it passes
201
+ codeloop inbox # what is waiting for you, what to read, what shipped
202
+ codeloop approve 1 # approve the gate and move the card on
203
+ codeloop reject 1 "no proof for the claim"
204
+ codeloop run # start lanes that are due, advance every card not waiting for you
205
+ ```
206
+
207
+ Every command that changes a card ends with a `Next:` line saying what to do. A card id can be typed as `1`, `001`, `c-001` or `C-001`. The long forms (`codeloop card new|show|list|advance|approve|reject`) do the same things.
208
+
209
+ | Who you are | How it is decided |
210
+ |---|---|
211
+ | owner | You are typing at a terminal and `CODELOOP_ROLE` is unset. |
212
+ | agent | Input is piped or spawned: an agent, CI, the MCP server. |
213
+ | either, explicitly | `--as owner|reviewer|agent`, or `CODELOOP_ROLE`. |
214
+
215
+ | Behaviour | Rule |
216
+ |---|---|
217
+ | Check fails | The card stays in its stage. After `retries` failures (default 3) it is marked `stuck` with the command output attached. `codeloop run` does not count a failure again while the stage's output file is unchanged. |
218
+ | Approval | An approval covers the stage output and check as they were when it was given. If either changes before the card advances, the card waits for you again. |
219
+ | Gate | The card waits for you after the stage's check passes. `codeloop approve` approves and advances it once. A waiting card cannot advance. |
220
+ | Gate with `outward: true` | The stage changes something public (publish, prod deploy), so the card waits when it enters the stage, before any work or check runs. Approving does not run it; after approval the check still has to pass. |
221
+ | `trigger: { on: lane.done, lane: build }` | A card starts when a card finishes that lane. Same as the other lane's `on_done.start`; declaring both starts one card. |
222
+ | `trigger: { cron: "0 9-17 * * MON-FRI" }` | Five fields in local time: `*`, `*/n`, `a`, `a-b`, `a-b/n`, comma lists, day names. `lane lint` rejects anything else; `codeloop run` reports a lane it cannot parse and carries on. |
223
+ | `trigger: { on: git.commit }` or `git.tag` | `codeloop run --due` starts one card per new HEAD sha or newest tag. |
224
+ | `gates.mode: trusted` in `config.yaml` | Gates auto-approve, except outward gates, which always stop. |
225
+ | `wip` on a lane | New cards are refused once that many are unfinished. Proposals do not count. |
226
+ | `capacity.gates_per_day` | New cards are refused while more cards than this are parked. Proposals do not count. |
227
+ | Proposed card | `codeloop card propose <lane> "<title>"` creates a card at stage `proposed`, waiting at gate `proposal`. It takes no place in the lane and no run starts it. `codeloop approve` (owner) puts it in the lane's first stage without running that stage's check; `codeloop reject` drops it. |
228
+ | A check that writes the board | A stage's command may propose cards (the scan stage does). `codeloop verify` records its evidence on its own card the same way. The advance is then written on the board the check left, unless the card was moved or parked meanwhile, which is exit 3. |
229
+ | Exit codes | 2 = a check, gate or permission refused. 3 = `cards.json` changed since it was read; re-read and retry. |
230
+
231
+ Cards live in `.codeloop/cards.json`, separate from the task board in `board.json`.
232
+
233
+ **Roles are not authentication.** Locally the role is whatever the caller says it is: `--as owner` and `CODELOOP_ROLE=owner` are open to any agent or script on the machine. Gates stop a cooperating agent from moving on by accident; they do not stop one that claims to be the owner. Each event records the claimed role. `codeloop gate check` prints a warning for an approval that is only a local event, so CI should not treat it as proof that a person approved. `lane promote` and `lane rollback` need the owner role under the same caveat.
234
+
235
+ ### Running unattended
236
+
237
+ `codeloop run` on its own only checks work that already exists. With an agent configured it also does the work: for each card that is not waiting for you and whose stage check does not pass yet, it starts a headless coding agent on that stage, then runs the check and moves the card, parks it at its gate, or counts a failed try.
238
+
239
+ ```yaml
240
+ # .codeloop/config.yaml
241
+ agents:
242
+ default: claude
243
+ claude:
244
+ cmd: "claude -p --permission-mode acceptEdits < {brief}"
245
+ timeout_minutes: 20 # default 20
246
+ max_runs_per_day: 20 # default 20
247
+ codex:
248
+ cmd: "codex exec - < {brief}"
249
+ run:
250
+ agent: true # optional: plain `codeloop run` starts agents too
251
+ ```
252
+
253
+ ```bash
254
+ codeloop brief 1 # what the agent is given for the card's current stage
255
+ codeloop run --agent # agents.default; `--agent codex` names another
256
+ codeloop run --agent --dry-run # which cards would get an agent; starts and changes nothing
257
+ codeloop schedule install --every 30m # a crontab entry that runs `codeloop run --agent` here
258
+ codeloop schedule status | remove
259
+ ```
260
+
261
+ `{brief}` becomes the shell-quoted path of `.codeloop/state/briefs/<card>-<stage>.md`. The brief holds the card, the stage's skill text from the skills index, the output path, the check command, rejection notes and the last failing check output for the stage, the wiki pages whose scope matches the files in play, and the rules: do this stage only, write the output, do not approve or advance, do not edit `cards.json` or lane files. The agent's output is kept in `.codeloop/state/agent-runs/<card>-<stage>-<n>.log` and each run is recorded on the card as `agent-start` and `agent-run` events (agent, exit code, duration, log path).
262
+
263
+ | Limit | Rule |
264
+ |---|---|
265
+ | One stage per card per run | After the agent finishes, the check runs once. The card moves one stage at most. |
266
+ | Waiting on a person | No agent starts for a card at a gate or marked stuck. |
267
+ | After a rejection | The stage is given back to the agent on the next run, with the note in its brief, even though the check that passed before still passes. Once per rejection; the card then waits at the gate again. |
268
+ | Public steps | No agent starts for a stage with `outward: true` until its gate is approved. |
269
+ | `wip` on a lane | Agents work on the first `wip` unfinished cards of the lane; the rest wait their turn. |
270
+ | `capacity.gates_per_day` | No agent starts while that many cards are waiting on you. |
271
+ | `max_runs_per_day` | Agent starts across the project in any 24 hours, counted from card events. The run says so when it is reached. |
272
+ | `timeout_minutes` | The agent and its child processes are killed. |
273
+ | Failed agent | An agent that exits non-zero or times out leaves the check to decide. A failed check after an agent run always counts toward `retries`, so a stage gets at most `retries` agent attempts before the card is stuck and waits for you. The `Next:` line names the log. |
274
+ | Overlapping runs | A card whose agent is still running from an earlier run is skipped. |
275
+ | Role | The agent runs with `CODELOOP_ROLE=agent`. `codeloop approve` and `reject` from inside it are refused, with or without `--as owner`. An agent that clears its own environment can still claim another role; see "Roles are not authentication" above. |
276
+
277
+ `schedule install` takes `--every` (minutes that divide the hour such as `30m`, or hours that divide the day such as `6h`; default `30m`) or `--cron "<five fields>"`, and `--agent <name>`. The entry carries the PATH of the shell that installed it, because cron starts with a bare one, and appends output to `.codeloop/state/run.log`. `--print` prints the line and installs nothing. Only this repo's entry is replaced or removed; other crontab lines are kept. `bash scripts/e2e-agent-real.sh` runs one stage with a real `claude -p` when `CODELOOP_E2E_REAL_AGENT=1` is set, and prints `SKIP` otherwise.
278
+
279
+ ### A founder's week, as a script
280
+
281
+ ```bash
282
+ npm run build && bash scripts/demo-founder-week.sh
283
+ ```
284
+
285
+ The script sets up a fresh temp project with the eight shipped lanes and a scripted stand-in for the coding agent, then drives a week and checks every step it claims (it exits 1 on the first mismatch). Sunday night triage proposes cards from an issues file; Monday the scan proposes a card from a competitor's changelog, the founder promotes it, plan ranks it, and a build card goes research, mock, spec gate, build, verify, review, release and live; finishing it starts a market card whose copy is rejected once, redone from the note and published; Friday the growth review opens a plan card; a third rejection at the copy gate becomes a lane proposal, an eval and market version 2. It ends with the inbox, the stats and a summary of cards, approvals, agent runs and lane versions. When a local Protobox answers on port 4002 the project is connected to it and the run ends with `cloud status`; otherwise it runs on local files and says so. A saved run is in [docs/artifacts/demo-founder-week.txt](docs/artifacts/demo-founder-week.txt).
286
+
287
+ The week is simulated with `CODELOOP_NOW=<time>`, which replaces the clock for any codeloop command, so every event carries that time and the cron lanes come due. `codeloop run --now <time>` does the same for a single run.
288
+
289
+ ### Inbox
290
+
291
+ `codeloop inbox` (or `--json`) opens with one line such as `2 shipped this week, 3 waiting on you, oldest 2 days`. For each waiting card it names the file to read and the last check result. It prints three lists: the gates waiting on you, the cards finished since you last ran `codeloop inbox --seen`, and per-lane numbers (active, parked, done, human turns per card, first-pass rate).
292
+
293
+ ### Adopt existing skills
294
+
295
+ The shipped lanes name only the ten skills codeloop installs, and `codeloop init` writes `.codeloop/skills.index.yaml` itself, so `lane lint` and `pack build` pass in a fresh repo. `codeloop adopt` rescans `.claude/skills`, `.claude/commands`, `.cursor/commands` and `.agents/skills` in the project and the `.claude` folders in your home directory (or `--from <dir>...`) and replaces the index. Once the index exists, `codeloop lane lint` rejects a stage that names a skill missing from it. `--gaps` lists stages with no mechanical done check. `codeloop pack build` compiles the lanes and the skills they name into a Protobox skills-only manifest.
296
+
297
+ ### Changing a lane
298
+
299
+ Lanes change through proposals, and a proposal has to pass an eval before it can be installed.
300
+
301
+ ```bash
302
+ codeloop lane propose # a gate rejected 3 times, or a stage stuck twice, writes .codeloop/proposals/<id>/
303
+ codeloop lane eval market-draft-1 # lint, fixtures, replay; writes eval-result.json
304
+ codeloop lane promote market-draft-1 --as owner
305
+ codeloop lane rollback market --as owner
306
+ ```
307
+
308
+ `eval` exits 4 when a changed done check has no `expect: fail` fixture in `eval.yaml`, or passes on one: a check that cannot fail is refused. It exits 1 when the proposal weakens the lane: it removes a gate, changes a gate's approver, removes `outward`, removes a stage that finished cards passed, or lowers `retries` to 0. Each one must be listed under `accept_weakening:` in `eval.yaml` as `{ change, reason }`, and `promote` prints the reasons. It also exits 1 when a changed check, re-run in the project against the last 10 finished cards, fails one of them. List a card under `accept_regressions:` in `eval.yaml` to accept that. Per-card results are in `eval-result.json`. `promote` keeps the previous file in `.codeloop/lanes/.history/`.
309
+
310
+ ### Specs and tasks
311
+
312
+ ```bash
313
+ codeloop spec new c-001 # specs/001-<slug>/{research,spec,plan,tasks}.md, recorded on the card
314
+ codeloop spec check 001 # exit 2 until the spec is traceable
315
+ codeloop task list 001 --layer api # one builder's tasks
316
+ codeloop task done 001 T003
317
+ codeloop task check 001 --all-done # exit 1 while any task is open
318
+ ```
319
+
320
+ `spec.md` holds acceptance lines `- US1 Given ..., when ..., then ...`. `tasks.md` holds one line per task: `- [ ] T003 [P] [US1] [api] text`, where the layer is `api`, `sdk`, `ui`, `test` or `docs`. `spec check` exits 2 on an untagged task, an acceptance line with no task, a task citing a missing `USn`, and more than five acceptance lines ("split the card"). The build lane's spec stage runs it, and its build stage requires every task ticked.
321
+
322
+ `codeloop import speckit [dir]` creates one build-lane card per `specs/NNN*/` feature and rewrites tasks with a layer tag. The layer is inferred from file paths in the task text, using `scopes` in `config.yaml` that are named after a layer; tasks it cannot place are marked `[?]` and listed. `codeloop import bmad [dir]` reads `sprint-status.yaml` and creates one card per story at the stage its status maps to. Both only read the source files; copies go to `specs/<card-id>-<slug>/`. Imported cards do not count against `wip` when they are created.
323
+
324
+ ### Competitor scan
325
+
326
+ ```bash
327
+ codeloop scan competitors # fetch each competitor page's changelog link
328
+ codeloop scan competitors --from-file notes.md # use a file as the page text (tests, pasted changelogs)
329
+ codeloop scan competitors --only acme
330
+ ```
331
+
332
+ For each page in `.codeloop/wiki/competitors/` with a `changelog` link, the scan fetches the URL (10 second limit; a failure is reported as skipped and the scan carries on), turns HTML into lines of text, and compares it with the text stored from the last scan in `.codeloop/state/scan/<name>.txt`. When lines appeared that were not there before, it proposes one card in the plan lane for that competitor, titled `<name> shipped: <first new heading, or first new line>`, with the new lines and the source URL in the card's description. The first scan of a competitor only stores the baseline. The card is a proposal: it waits in `codeloop inbox` until the owner promotes it with `codeloop approve`, and nothing starts it. The same new text never produces a second card, even if the stored text is lost.
333
+
334
+ The shipped `scan` lane runs this weekly (`0 7 * * MON`): its one stage's check is `codeloop scan competitors`, so `codeloop run` does the scan with or without an agent.
335
+
336
+ ### Research and competitor pages
337
+
338
+ ```bash
339
+ codeloop wiki competitor add acme --docs https://acme.example/docs --changelog https://acme.example/changelog
340
+ codeloop wiki competitor list
341
+ codeloop check research c-001 --min-sources 3 # exit 1 without a verdict line and three source lines
342
+ codeloop check research c-001 --online # also asks each source URL; 2xx or 3xx passes
343
+ ```
344
+
345
+ Each competitor is one wiki page, `.codeloop/wiki/competitors/<name>.md`, with `title`, `docs` and `changelog` in its front matter and a `## Findings` list below. The brief for a stage named `research` includes every competitor page. The shipped build lane checks the research stage with `codeloop check research {id} --min-sources 3`: `research.md` needs a line starting `verdict:` and at least three lines of the form `- source: <url> — <note>` (a spaced hyphen also works). The check is offline by default so it gives the same answer every time; `--online` adds a HEAD request per URL, falling back to GET, with a 10 second limit.
346
+
347
+ When a research stage passes, each row of `research.md` that starts with a competitor's name (a table row or a `- name: ...` list item) is appended to that competitor's page as `- <card-id> <card title>: <the row>`. A page that already has rows from the card is left alone, and the card gets a `findings` event naming the page.
348
+
349
+ ### Mocks
350
+
351
+ ```bash
352
+ codeloop mock new c-001 --topic exports # docs/mocks/<project>/<topic>/c-001.html from the shared template
353
+ codeloop check mock c-001 # exit 1 until the mock passes
354
+ codeloop mocks index # docs/mocks/index.html: project, topic, cards, newest first
355
+ ```
356
+
357
+ Every mock starts from `templates/mock/template.html`: one page shell and one tokens block (light and dark colours, spacing, radius), the system font stack, flex and grid with `minmax`, and no pixel sizes. `<project>` is `project.name` from `config.yaml`. `check mock` fails when the file is missing, when it lacks the template's marker comment, when its tokens block differs from the template's, when it uses a hex colour or a colour function outside the tokens block, or when a screen named under `screens:` in the card's `spec.md` has no `<section data-screen="name">`. A spec that names no screens fails too; a card with nothing to draw says `screens: none` and passes without a mock, which is what makes the stage optional per card.
358
+
359
+ The shipped build lane runs `mock` between `research` and `spec`, so the spec gate shows a picture and a story together: `codeloop inbox` prints the mock path under the waiting card, and `codeloop serve` serves the gallery at `/mocks/` and links the card's mock from its detail panel. Projects set up before this keep their own `build.yaml`; add the stage by hand through a lane proposal.
360
+
361
+ ### Verify
362
+
363
+ A use case lives in `usecases/<nnn>/<name>.yaml`:
364
+
365
+ ```yaml
366
+ id: uc-001-02
367
+ accept: US2
368
+ failure_mode: "two writers who read the same version both land"
369
+ layers:
370
+ cli: { run: "bash usecases/001/uc.sh us2", expect: { exit: 0, stdout: "conflict" } }
371
+ api: { request: { method: PATCH, path: /api/tasks/t-1, body: { stage: live } }, expect: { status: 403 } }
372
+ ```
373
+
374
+ `codeloop verify <nnn>` runs every layer, writes `evidence/<nnn>/<uc>.json` (sha, layer, pass, output tail) and `evidence/<nnn>/verify.md` with `result: pass|fail`, and adds the evidence to the card (`--no-record` skips that).
375
+
376
+ | Exit | Meaning |
377
+ |---|---|
378
+ | 2 | An acceptance line has no use case. |
379
+ | 1 | A use case failed, or has no runnable layer. |
380
+ | 2 | Also: the spec has no acceptance lines, or there are no use cases. Nothing to check is not a pass. |
381
+ | 4 | `--mutate`: a use case still passes on the commit before the card's first `Feature: <card-id>` commit, so it cannot fail. |
382
+ | 5 | `--mutate` could not run: no commit carries that trailer, or the setup command failed in the old commit ("environment differs"). No verdict is given. |
383
+
384
+ `--mutate` checks the old commit out in a temporary worktree and runs `verify.setup` from `config.yaml` there first (default `npm ci && npm run build` when the worktree has a `package.json`; set it to `""` to skip). When the project itself ships the `codeloop` binary, use cases drive the worktree's build. `--env <name>` points api use cases at `deploy.<name>.base_url` from `config.yaml`. `codeloop init --hooks` installs a commit-msg hook that adds the `Feature:` trailer from a branch name containing a card id.
385
+
386
+ Not built: the `ui` layer. There is no Playwright runner, and a use case with only a `ui` layer counts as a failure rather than a pass.
387
+
388
+ ### Stats
389
+
390
+ `codeloop stats [--card <id>] [--lane <id>] [--compare v1 v2] [--json]` computes, from card events only: human turns per card, the longest unattended span, cycle time, rework (rejections ÷ approvals), stuck rate, and first-pass rate per gate. `--compare` splits by the lane version each card was created under.
391
+
392
+ ### Wiki
393
+
394
+ ```bash
395
+ codeloop wiki capture --title "Rename is not atomic across devices" --scope "src/lib/**" --body "..."
396
+ codeloop wiki inject --files src/lib/cards.ts # pages whose scope globs match
397
+ codeloop wiki list | lint
398
+ codeloop learn # apply the frequency thresholds
399
+ codeloop check gotchas --files <changed files> # exit 1 on an unacknowledged critical page
400
+ ```
401
+
402
+ Pages live in `.codeloop/wiki/{gotchas,decisions,concepts}/` with frontmatter `title, scope, freq, severity, cards, updated`. Capturing a title that exists raises its `freq`. At `codeloop.critical_frequency` (default 3) the page becomes critical and `check gotchas` blocks matching files until `--ack "<title>"`; `/commit` runs that check. At `codeloop.promote_frequency` (default 10) `codeloop learn` appends the page to `rules.md` once. `wiki lint` exits 1 on a broken relative link and reports pages older than 90 days and duplicate titles.
403
+
404
+ ### Other hosts, MCP and CI
405
+
406
+ - `codeloop render [--host claude|cursor|codex|all]` writes each lane stage as `.claude/agents/codeloop-<lane>-<stage>.md`, each lane as `.cursor/rules/codeloop-<lane>.mdc` and `.agents/skills/codeloop-<lane>/SKILL.md`, and a block in `AGENTS.md` between `<!-- codeloop:start -->` and `<!-- codeloop:end -->`. A second run changes nothing.
407
+ - `codeloop mcp` serves the engine over stdio with the tools `inbox`, `next_up`, `get_card`, `advance`, `approve`, `reject`, `task_done`, `wiki_inject`, `wiki_capture`. `approve` and `reject` take the role from `CODELOOP_ROLE` in the server's environment and are refused for an agent.
408
+ - `codeloop init --ci github` writes three workflows. The PR one runs build, test, `lane lint` and fails a commit with no `Feature:` trailer. The staging one runs `deploy.staging.command` on a push to main and then verifies the shipped cards with `--env staging`; it does nothing while that command is unset. The prod one runs on a `v*` tag under `environment: production`, which waits for a reviewer once the environment has required reviewers.
409
+ - `codeloop gate check <id> --require <gate>` exits 2 unless the card has an approval for that gate.
410
+
411
+ ### The board in a browser
412
+
413
+ `codeloop serve` prints a URL such as `http://127.0.0.1:4040/?token=…` and opens on a Cards view: one column per stage of the selected lane, a "waiting for you" badge with the gate name, and a detail panel with events, evidence, the spec path and a link to the card's mock. The mock gallery is at `/mocks/`. It starts without a `board.json`; the old task board is the Tasks tab. Approve and Reject on the page work only when the server was started with `codeloop serve --owner`; otherwise those requests return 403.
414
+
415
+ The server has no login. It listens on 127.0.0.1 only (`--host` changes that and exposes the board to the network), answers only to a localhost host name, sends no CORS headers, and requires the token from the printed URL, a JSON content type and a same-origin request for every change. Anyone who has the URL with its token can make changes, including approvals on an `--owner` board.
416
+
417
+ ### Cloud store (optional)
418
+
419
+ Local files are the default and nothing below is needed. A Protobox workspace can hold a second copy of the board, the wiki, `config.yaml` and the lanes so several checkouts share them. Only codeloop is installed; there is no Protobox CLI.
420
+
421
+ | Command | What it does |
422
+ |---|---|
423
+ | `codeloop cloud connect --url <mcp url> --key <api key> [--folder <name>]` | Saves the connection in `.codeloop/cloud.json` (gitignored; the key is never printed). Uploads the board to a page titled "codeloop board", `config.yaml` to "codeloop board: config.yaml", each lane to "codeloop board: lanes/<lane>.yaml" and each wiki page under its own title. Pages go in folder `codeloop` (or `--folder`), lanes in `codeloop/codeloop-lanes`, wiki pages in `codeloop/codeloop-wiki`. A board page that already exists is adopted, not overwritten. |
424
+ | `codeloop cloud status` | Workspace URL, board revision against the local version, and every document as `in-sync`, `local-ahead`, `cloud-ahead` or `both-changed`. |
425
+ | `codeloop cloud pull [--force]` | Takes the cloud board, and every other cloud copy whose local file was not edited here. `--force` takes the cloud copy of everything. |
426
+ | `codeloop cloud push [--force]` | Writes the board, wiki pages and config that changed here. `--force` also replaces pages that changed in the cloud. Lanes are never pushed this way. |
427
+ | `codeloop cloud disconnect` | Pushes pending writes, pulls everything back into the repo, then removes `cloud.json` and the sync record. |
428
+
429
+ `.codeloop/state/sync.json` (gitignored) records, for each document, its page id, the revision this checkout last saw and a hash of the content at that moment. That is how a change here is told apart from a change in the cloud.
430
+
431
+ While connected, every command starts by syncing, and says what it did on stderr. That is one request to the workspace per command and one per card write; the endpoint allows 60 a minute and codeloop waits when it is told to slow down. `CODELOOP_NO_SYNC=1` skips the sync step for a command (a script that only reads, many times in a row); writes still go to the cloud first.
432
+
433
+ | Case | What happens |
434
+ |---|---|
435
+ | A page changed only in the cloud | The local file is updated before the command runs. This covers the board, config, lanes and wiki. |
436
+ | A wiki page or `config.yaml` was edited only here | Pushed before the command runs. |
437
+ | A lane file was edited here | Reported and not pushed. A lane reaches the cloud only through `codeloop lane promote` (or `lane rollback`). |
438
+ | A wiki page changed on both sides | Yours is kept and the cloud version is written beside it as `<name>.cloud.md`. `codeloop inbox` lists it under what is waiting for you. Merge it into your page and delete the copy; the next command pushes the merge. |
439
+ | The board changed on both sides | The command is refused with exit 3 and the local file is unchanged. `codeloop cloud pull`, then run it again. |
440
+ | `config.yaml` or a lane changed on both sides | Yours is kept and the command says so. `cloud pull --force` takes the cloud copy, `cloud push --force` replaces it. |
441
+ | The cloud cannot be reached | The command runs on the local files. A write is kept locally and marked `pending` in `sync.json`; the next command that reaches the cloud pushes pending writes first, with the same revision check. |
442
+
443
+ Every card write goes to the cloud page first with the revision this checkout last saw, so two checkouts cannot both land a write made from the same board. `wiki capture` also writes the page; `wiki inject` stays local.
444
+
445
+ **Keys, tokens and machine paths belong in `.codeloop/local.yaml`.** `config.yaml` is uploaded as it is, so it should hold only switches the whole team shares: approval mode, work limits, deploy commands. `local.yaml` has the same shape, is laid over `config.yaml` on this machine (maps merge key by key), is gitignored by `codeloop init`, and is never uploaded. codeloop does not move anything there for you.
446
+
447
+ ```yaml
448
+ # .codeloop/local.yaml
449
+ agents:
450
+ claude: { cmd: "/Users/me/bin/claude -p --permission-mode acceptEdits < {brief}" }
451
+ deploy:
452
+ staging: { base_url: "http://localhost:8080" }
453
+ ```
454
+
455
+ The workspace's MCP endpoint has to serve `KNOWLEDGE_WRITE_PAGE`, `KNOWLEDGE_READ_PAGE`, `KNOWLEDGE_LIST_PAGES` and `KNOWLEDGE_SEARCH`. `bash scripts/e2e-cloud.sh` proves all of the above against a local Protobox and prints `SKIP` when none is running.
456
+
457
+ `bash scripts/e2e-founder-loop.sh` runs all of the above except the cloud store against the built CLI in a temp project.
458
+
459
+ ## Watch Mode
460
+
461
+ Monitor your project in the background:
462
+
463
+ ```bash
464
+ codeloop watch # Start watching
465
+ codeloop watch --with-serve # Watch + board server (live UI)
466
+ ```
467
+
468
+ Watch detects file changes, git commits, test results, and build errors. Events are logged to `.codeloop/watch.log` and pushed to the board UI via SSE when the server is running.
469
+
470
+ ## Skill Registry
471
+
472
+ Install community skills or share your own:
473
+
474
+ ```bash
475
+ codeloop search "deploy" # Find skills
476
+ codeloop install review-checklist # Install from registry
477
+ codeloop install github:user/repo # Install from GitHub
478
+ codeloop install ./local-skill # Install from local path
479
+ codeloop list # Show installed skills
480
+ codeloop remove review-checklist # Uninstall
481
+ ```
482
+
483
+ Every installed skill gets security-validated (no `exec()`, no credential access, no pipe-to-shell) and locked with integrity hashes in `.codeloop/skills.lock`.
484
+
485
+ ## Works With Everything
486
+
487
+ codeloop auto-detects your stack and tools:
488
+
489
+ | Stack | Detected by | Starter config |
490
+ |-------|-------------|----------------|
491
+ | TypeScript | `tsconfig.json` | Typecheck, console.log scan, `any` warnings |
492
+ | Python | `pyproject.toml`, `setup.py` | mypy, ruff, print() detection, pdb scan |
493
+ | Go | `go.mod` | go vet, go build, fmt.Print detection |
494
+ | Generic | Fallback | Minimal — you configure |
495
+
496
+ | Tool | Commands installed to | Compatibility |
497
+ |------|---------------------|---------------|
498
+ | Claude Code | `.claude/commands/` | Full (primary target) |
499
+ | Cursor | `.cursor/commands/` | Knowledge + config (tool hints are Claude-specific) |
500
+ | Codex | `.agents/skills/` | Knowledge + config (tool hints are Claude-specific) |
501
+
502
+ **Note**: The `allowed-tools` frontmatter in skill files uses Claude Code tool names (Bash, Read, Edit, etc.). Cursor and Codex ignore this field — the skill instructions still work, but tool restrictions aren't enforced. The knowledge files (gotchas, patterns, rules) and config are fully portable across all tools.
503
+
504
+ ## CLI Reference
505
+
506
+ ```bash
507
+ # Project setup
508
+ codeloop init # Interactive setup
509
+ codeloop init --tools claude,cursor # Skip tool prompt
510
+ codeloop init --starter python # Force specific stack
511
+ codeloop status # Knowledge stats, version check
512
+ codeloop update # Update skills (never touches knowledge)
513
+
514
+ # Lanes
515
+ codeloop lane list | show <id> | lint # Inspect and check lanes
516
+ codeloop card new <lane> <title> # Start a card (also: show, list, advance, approve, reject)
517
+ codeloop inbox # Gates waiting on you, what shipped, numbers
518
+ codeloop run --due # Start due cron lanes, advance unparked cards
519
+ codeloop run --agent [name] # Same, with a headless agent doing each stage first (--dry-run to preview)
520
+ codeloop brief <card> # The stage brief an agent is given
521
+ codeloop schedule install | status | remove # Crontab entry for `codeloop run --agent`
522
+ codeloop adopt # Index existing skills and commands
523
+ codeloop lane propose | eval | promote | rollback
524
+ codeloop check file <path> --has <s> # Done-check helper for lane stages
525
+ codeloop check research <card> # Verdict line and source lines in research.md (--min-sources, --online)
526
+ codeloop check mock <card> # Mock built from the shared template, every spec screen drawn
527
+ codeloop mock new <card> --topic <t> # Mock file from the shared template
528
+ codeloop mocks index # Mock gallery page
529
+ codeloop pack build # Protobox skills-only manifest
530
+ codeloop spec new | check # Spec folder for a card
531
+ codeloop task list | done | check # Layer-tagged tasks
532
+ codeloop import speckit | bmad # Bring existing specs in as cards
533
+ codeloop verify <nnn> [--mutate] # Run use cases, write evidence
534
+ codeloop stats # Autonomy numbers from card events
535
+ codeloop wiki capture | inject | list | lint
536
+ codeloop wiki competitor add | list # One wiki page per competitor
537
+ codeloop scan competitors # Propose a plan card for what each competitor's changelog added
538
+ codeloop card propose <lane> <title> # A card that waits for the owner before it enters its lane
539
+ codeloop learn # Apply gotcha frequency thresholds
540
+ codeloop render # Agents, rules and skills for Claude, Cursor, Codex
541
+ codeloop mcp # MCP server on stdio
542
+ codeloop gate check <id> --require <gate>
543
+ codeloop init --hooks | --ci github # commit-msg hook, CI workflows
544
+ codeloop start | next | approve | reject # Short forms of the card commands
545
+ codeloop cloud connect | status | push | pull | disconnect # Optional: Protobox copy of board, wiki, config and lanes
546
+
547
+ # Live monitoring
548
+ codeloop watch # Background file + git monitor
549
+ codeloop serve # Board UI server (http://127.0.0.1:4040, token in the printed URL)
550
+
551
+ # Skill registry
552
+ codeloop search <query> # Search for skills
553
+ codeloop install <name> # Install a skill
554
+ codeloop list # Show installed skills
555
+ codeloop remove <name> # Uninstall a skill
556
+ codeloop publish # Publish your skill to the registry
557
+ codeloop login # Authenticate with GitHub
558
+ ```
559
+
560
+ ## The Knowledge Files
561
+
562
+ **`rules.md`** — Non-negotiable. Always loaded as CRITICAL. Start with universal rules, add yours.
563
+
564
+ **`gotchas.md`** — Discovered through work. Each entry has `[freq:N]`. Severity auto-scales with frequency. Organized by sections matching your scopes.
565
+
566
+ **`patterns.md`** — What works well. HIGH-confidence patterns become expectations — deviations trigger warnings during review.
567
+
568
+ **`principles.md`** — How you want the AI to operate. Plan first? Verify before done? Write it here once, it applies everywhere.
569
+
570
+ All plain markdown. No lock-in, no proprietary format. If you stop using codeloop tomorrow, the knowledge stays as useful documentation.
571
+
572
+ ## Working on codeloop itself
573
+
574
+ This repo runs on its own lanes (`.codeloop/lanes/`), which name only the bundled skills.
575
+
576
+ ```bash
577
+ npm ci && npm --prefix ui ci
578
+ npm run build:all
579
+ node dist/index.js adopt --from templates/commands # index the bundled skills
580
+ node dist/index.js lane lint
581
+ npm test && bash scripts/e2e-founder-loop.sh
582
+ node dist/index.js inbox # the repo's own cards
583
+ ```
584
+
585
+ `scripts/e2e-cloud.sh` and the cloud part of `scripts/demo-founder-week.sh` need a Protobox workspace; set `PROTOBOX_CACHE` to a JSON file holding its workspace id and API key. Both skip the cloud steps when it is absent.
586
+
587
+ ## License
588
+
589
+ MIT
@@ -0,0 +1,2 @@
1
+ import { Command } from 'commander';
2
+ export declare const adoptCommand: Command;
@@ -0,0 +1,26 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { loadLanes, SKILLS_INDEX } from '../lib/lane.js';
4
+ import { defaultSkillDirs, doneGaps, duplicateSkills, scanSkills, writeSkillsIndex } from '../lib/skills.js';
5
+ import { guard } from './guard.js';
6
+ export const adoptCommand = new Command('adopt')
7
+ .description('Index the skills and commands that already exist so lanes can name them')
8
+ .option('--from <dir...>', 'Directories to scan (default: .claude/skills, .claude/commands, .cursor/commands, .agents/skills in the project, and ~/.claude/skills, ~/.claude/commands)')
9
+ .option('--gaps', 'List lane stages with no mechanical done check')
10
+ .action(guard((opts) => {
11
+ const projectDir = process.cwd();
12
+ const entries = scanSkills(projectDir, opts.from ?? defaultSkillDirs(projectDir));
13
+ writeSkillsIndex(projectDir, entries);
14
+ console.log(` indexed ${entries.length} skills and commands into ${SKILLS_INDEX}`);
15
+ for (const dup of duplicateSkills(entries)) {
16
+ console.log(chalk.yellow(` duplicate: ${dup.name}`));
17
+ dup.sources.forEach(s => console.log(chalk.dim(` ${s}`)));
18
+ }
19
+ if (opts.gaps) {
20
+ const gaps = doneGaps(loadLanes(projectDir));
21
+ if (gaps.length === 0)
22
+ console.log(' no gaps: every lane stage has a check command');
23
+ gaps.forEach(g => console.log(chalk.yellow(` gap: ${g.lane}/${g.stage}: ${g.reason}`)));
24
+ }
25
+ }));
26
+ //# sourceMappingURL=adopt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adopt.js","sourceRoot":"","sources":["../../src/commands/adopt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC7G,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,yEAAyE,CAAC;KACtF,MAAM,CAAC,iBAAiB,EAAE,4JAA4J,CAAC;KACvL,MAAM,CAAC,QAAQ,EAAE,gDAAgD,CAAC;KAClE,MAAM,CAAC,KAAK,CAAC,CAAC,IAAyC,EAAE,EAAE;IAC1D,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IACjC,MAAM,OAAO,GAAG,UAAU,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,IAAI,gBAAgB,CAAC,UAAU,CAAC,CAAC,CAAC;IAClF,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACtC,OAAO,CAAC,GAAG,CAAC,aAAa,OAAO,CAAC,MAAM,6BAA6B,YAAY,EAAE,CAAC,CAAC;IAEpF,KAAK,MAAM,GAAG,IAAI,eAAe,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,gBAAgB,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACtD,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,IAAI,GAAG,QAAQ,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;QAC7C,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,iDAAiD,CAAC,CAAC;QACtF,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3F,CAAC;AACH,CAAC,CAAC,CAAC,CAAC"}