@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
@@ -0,0 +1,111 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { existsSync, readFileSync, writeFileSync, unlinkSync } from 'fs';
4
+ import { join } from 'path';
5
+ import { createWatchEngine, loadWatchConfig } from '../watch/index.js';
6
+ const PID_FILE = '.codeloop/.watch.pid';
7
+ export const watchCommand = new Command('watch')
8
+ .description('Watch project for changes, track progress on the board')
9
+ .option('--with-serve', 'Also start the board server')
10
+ .option('--stop', 'Stop background watcher')
11
+ .option('--bg', 'Run in background')
12
+ .action(async (options) => {
13
+ const projectDir = process.cwd();
14
+ // --stop: kill background watcher
15
+ if (options.stop) {
16
+ const pidPath = join(projectDir, PID_FILE);
17
+ if (!existsSync(pidPath)) {
18
+ console.log(chalk.dim(' Not running'));
19
+ return;
20
+ }
21
+ const pid = parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);
22
+ try {
23
+ process.kill(pid);
24
+ console.log(chalk.green(` Stopped watcher (PID ${pid})`));
25
+ }
26
+ catch {
27
+ console.log(chalk.yellow(` Process ${pid} not found (already stopped?)`));
28
+ }
29
+ unlinkSync(pidPath);
30
+ return;
31
+ }
32
+ // Check project is initialized
33
+ const configPath = join(projectDir, '.codeloop', 'config.yaml');
34
+ if (!existsSync(configPath)) {
35
+ console.log(chalk.red(' No config.yaml found. Run `codeloop init` first.'));
36
+ process.exit(1);
37
+ }
38
+ const config = loadWatchConfig(projectDir);
39
+ if (!config.enabled) {
40
+ console.log(chalk.yellow(' Watch mode is disabled in config.yaml (watch.enabled: false)'));
41
+ return;
42
+ }
43
+ // --bg: fork as background process
44
+ if (options.bg) {
45
+ const { fork } = await import('child_process');
46
+ const args = ['watch'];
47
+ if (options.withServe)
48
+ args.push('--with-serve');
49
+ const child = fork(process.argv[1], args, {
50
+ detached: true,
51
+ stdio: 'ignore',
52
+ });
53
+ child.unref();
54
+ if (child.pid) {
55
+ const pidPath = join(projectDir, PID_FILE);
56
+ writeFileSync(pidPath, String(child.pid), 'utf-8');
57
+ console.log(chalk.green(` Watcher started in background (PID ${child.pid})`));
58
+ }
59
+ return;
60
+ }
61
+ // Foreground mode
62
+ let broadcastFn;
63
+ // --with-serve: also start board server
64
+ if (options.withServe) {
65
+ const { createApp } = await import('../lib/server.js');
66
+ const { serve } = await import('@hono/node-server');
67
+ const { app, broadcast } = createApp(projectDir);
68
+ broadcastFn = broadcast;
69
+ const port = 4040;
70
+ serve({ fetch: app.fetch, port }, () => {
71
+ console.log(chalk.bold(` Board: ${chalk.cyan(`http://localhost:${port}`)}`));
72
+ });
73
+ }
74
+ const engine = createWatchEngine(projectDir, broadcastFn);
75
+ console.log();
76
+ console.log(chalk.bold(' Codeloop Watch'));
77
+ const signals = Object.entries(config.signals)
78
+ .filter(([, v]) => v)
79
+ .map(([k]) => k);
80
+ console.log(chalk.dim(` Signals: ${signals.join(', ')}`));
81
+ console.log(chalk.dim(` Idle timeout: ${config.idle_timeout}s`));
82
+ console.log(chalk.dim(' Press Ctrl+C to stop'));
83
+ console.log();
84
+ engine.start();
85
+ // Graceful shutdown
86
+ const shutdown = () => {
87
+ console.log(chalk.dim('\n Stopping watcher...'));
88
+ engine.stop();
89
+ process.exit(0);
90
+ };
91
+ process.on('SIGINT', shutdown);
92
+ process.on('SIGTERM', shutdown);
93
+ });
94
+ export function getWatchStatus(projectDir) {
95
+ const pidPath = join(projectDir, PID_FILE);
96
+ if (!existsSync(pidPath))
97
+ return { running: false };
98
+ const pid = parseInt(readFileSync(pidPath, 'utf-8').trim(), 10);
99
+ try {
100
+ process.kill(pid, 0);
101
+ return { running: true, pid };
102
+ }
103
+ catch {
104
+ try {
105
+ unlinkSync(pidPath);
106
+ }
107
+ catch { /* ignore */ }
108
+ return { running: false };
109
+ }
110
+ }
111
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const wikiCommand: Command;
3
+ export declare const learnCommand: Command;
@@ -0,0 +1,85 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { addCompetitor, listCompetitors } from '../lib/competitors.js';
4
+ import { capture, inject, learn, lintWiki, listPages } from '../lib/wiki.js';
5
+ import { guard } from './guard.js';
6
+ const row = (p) => ` ${p.severity === 'critical' ? chalk.red('critical') : 'warning '} freq ${String(p.freq).padEnd(3)} ${p.title} ${chalk.dim(p.path)}`;
7
+ export const wikiCommand = new Command('wiki').description('Gotchas, decisions and concepts that agents read before a stage and write after it');
8
+ wikiCommand
9
+ .command('capture')
10
+ .description('Write a page; capturing an existing title raises its frequency')
11
+ .requiredOption('--title <title>', 'Page title')
12
+ .option('--scope <glob...>', 'File globs the page applies to', [])
13
+ .option('--body <text>', 'Page body', '')
14
+ .option('--kind <kind>', 'gotcha | decision | concept', 'gotcha')
15
+ .option('--card <id>', 'Card this came from')
16
+ .action(guard((opts) => {
17
+ console.log(row(capture(process.cwd(), opts)));
18
+ }));
19
+ wikiCommand
20
+ .command('inject')
21
+ .description('Print the pages whose scope matches the given files')
22
+ .requiredOption('--files <path...>', 'Changed or soon-to-change files')
23
+ .option('--json', 'JSON output')
24
+ .action(guard((opts) => {
25
+ const pages = inject(process.cwd(), opts.files);
26
+ if (opts.json) {
27
+ console.log(JSON.stringify(pages, null, 2));
28
+ return;
29
+ }
30
+ for (const p of pages)
31
+ console.log(`## ${p.title} (${p.kind}, freq ${p.freq}, ${p.severity})\n\n${p.body}\n`);
32
+ if (pages.length === 0)
33
+ console.log(' no wiki pages apply to these files');
34
+ }));
35
+ wikiCommand
36
+ .command('list')
37
+ .description('List pages')
38
+ .action(guard(() => {
39
+ const pages = listPages(process.cwd());
40
+ if (pages.length === 0)
41
+ console.log(' no wiki pages');
42
+ pages.forEach(p => console.log(row(p)));
43
+ }));
44
+ wikiCommand
45
+ .command('lint')
46
+ .description('Report broken links (exit 1), stale pages and duplicate titles')
47
+ .action(guard(() => {
48
+ const { broken, stale, duplicates } = lintWiki(process.cwd());
49
+ broken.forEach(b => console.error(chalk.red(` broken: ${b}`)));
50
+ stale.forEach(s => console.log(chalk.yellow(` stale: ${s}`)));
51
+ duplicates.forEach(d => console.log(chalk.yellow(` duplicate: ${d}`)));
52
+ if (broken.length)
53
+ process.exit(1);
54
+ console.log(` wiki ok${stale.length + duplicates.length ? ` (${stale.length} stale, ${duplicates.length} duplicate)` : ''}`);
55
+ }));
56
+ const competitorCommand = wikiCommand.command('competitor').description('One wiki page per competitor: links at the top, findings from each research stage below');
57
+ competitorCommand
58
+ .command('add <name>')
59
+ .description('Create .codeloop/wiki/competitors/<name>.md, or update the links of an existing page')
60
+ .option('--docs <url>', 'Where their product docs are')
61
+ .option('--changelog <url>', 'Where they announce what shipped; `codeloop scan competitors` reads it')
62
+ .option('--title <title>', 'Display name (default: the name)')
63
+ .action(guard((name, opts) => {
64
+ const page = addCompetitor(process.cwd(), { name, ...opts });
65
+ console.log(` ${page.path} ${chalk.dim(`docs ${page.docs ?? '-'} changelog ${page.changelog ?? '-'}`)}`);
66
+ }));
67
+ competitorCommand
68
+ .command('list')
69
+ .description('List competitor pages')
70
+ .action(guard(() => {
71
+ const pages = listCompetitors(process.cwd());
72
+ if (pages.length === 0)
73
+ console.log(' no competitor pages; `codeloop wiki competitor add <name> --docs <url> --changelog <url>`');
74
+ pages.forEach(c => console.log(` ${c.title.padEnd(16)} ${chalk.dim(c.path)} changelog ${c.changelog ?? '-'}`));
75
+ }));
76
+ export const learnCommand = new Command('learn')
77
+ .description('Apply frequency thresholds: critical at critical_frequency, promoted to rules.md at promote_frequency')
78
+ .action(guard(() => {
79
+ const { critical, promoted } = learn(process.cwd());
80
+ critical.forEach(t => console.log(` now critical: ${t}`));
81
+ promoted.forEach(t => console.log(` promoted to .codeloop/rules.md: ${t}`));
82
+ if (critical.length + promoted.length === 0)
83
+ console.log(' nothing crossed a threshold');
84
+ }));
85
+ //# sourceMappingURL=wiki.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wiki.js","sourceRoot":"","sources":["../../src/commands/wiki.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { initCommand } from './commands/init.js';
4
+ import { updateCommand } from './commands/update.js';
5
+ import { statusCommand } from './commands/status.js';
6
+ import { serveCommand } from './commands/serve.js';
7
+ import { watchCommand } from './commands/watch.js';
8
+ import { installCommand } from './commands/install.js';
9
+ import { searchCommand } from './commands/search.js';
10
+ import { listCommand } from './commands/list.js';
11
+ import { removeCommand } from './commands/remove.js';
12
+ import { publishCommand } from './commands/publish.js';
13
+ import { loginCommand } from './commands/login.js';
14
+ import { laneCommand } from './commands/lane.js';
15
+ import { approveCommand, cardCommand, nextCommand, rejectCommand, startCommand } from './commands/card.js';
16
+ import { inboxCommand } from './commands/inbox.js';
17
+ import { runCommand } from './commands/run.js';
18
+ import { briefCommand } from './commands/brief.js';
19
+ import { scheduleCommand } from './commands/schedule.js';
20
+ import { adoptCommand } from './commands/adopt.js';
21
+ import { checkCommand } from './commands/check.js';
22
+ import { packCommand } from './commands/pack.js';
23
+ import { specCommand, taskCommand } from './commands/spec.js';
24
+ import { importCommand } from './commands/import.js';
25
+ import { statsCommand, verifyCommand } from './commands/verify.js';
26
+ import { learnCommand, wikiCommand } from './commands/wiki.js';
27
+ import { configCommand, gateCommand, mcpCommand, renderCommand } from './commands/render.js';
28
+ import { cloudCommand, syncBeforeCommand } from './commands/cloud.js';
29
+ import { mockCommand, mocksCommand } from './commands/mock.js';
30
+ import { scanCommand } from './commands/scan.js';
31
+ const program = new Command();
32
+ program
33
+ .name('codeloop')
34
+ .description('Self-improving development workflow for AI coding agents')
35
+ .version('0.3.0');
36
+ // With the cloud connected, every command first pushes pending writes and takes what changed there.
37
+ program.hook('preAction', (_program, action) => {
38
+ let top = action;
39
+ while (top.parent && top.parent !== program)
40
+ top = top.parent;
41
+ syncBeforeCommand(top.name());
42
+ });
43
+ // Project management
44
+ program.addCommand(initCommand);
45
+ program.addCommand(updateCommand);
46
+ program.addCommand(statusCommand);
47
+ program.addCommand(serveCommand);
48
+ program.addCommand(watchCommand);
49
+ // Lane engine
50
+ program.addCommand(laneCommand);
51
+ program.addCommand(cardCommand);
52
+ program.addCommand(startCommand);
53
+ program.addCommand(nextCommand);
54
+ program.addCommand(approveCommand);
55
+ program.addCommand(rejectCommand);
56
+ program.addCommand(inboxCommand);
57
+ program.addCommand(runCommand);
58
+ program.addCommand(briefCommand);
59
+ program.addCommand(scheduleCommand);
60
+ program.addCommand(adoptCommand);
61
+ program.addCommand(checkCommand);
62
+ program.addCommand(packCommand);
63
+ program.addCommand(specCommand);
64
+ program.addCommand(mockCommand);
65
+ program.addCommand(mocksCommand);
66
+ program.addCommand(scanCommand);
67
+ program.addCommand(taskCommand);
68
+ program.addCommand(importCommand);
69
+ program.addCommand(verifyCommand);
70
+ program.addCommand(statsCommand);
71
+ program.addCommand(wikiCommand);
72
+ program.addCommand(learnCommand);
73
+ program.addCommand(renderCommand);
74
+ program.addCommand(mcpCommand);
75
+ program.addCommand(gateCommand);
76
+ program.addCommand(configCommand);
77
+ program.addCommand(cloudCommand);
78
+ // Skill registry
79
+ program.addCommand(installCommand);
80
+ program.addCommand(searchCommand);
81
+ program.addCommand(listCommand);
82
+ program.addCommand(removeCommand);
83
+ program.addCommand(publishCommand);
84
+ program.addCommand(loginCommand);
85
+ program.parse();
86
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { type Card } from './cards.js';
2
+ export declare const BRIEFS_DIR = ".codeloop/state/briefs";
3
+ export declare const AGENT_RUNS_DIR = ".codeloop/state/agent-runs";
4
+ export interface AgentConfig {
5
+ name: string;
6
+ cmd: string;
7
+ timeoutMinutes: number;
8
+ maxRunsPerDay: number;
9
+ }
10
+ export interface AgentsConfig {
11
+ agents: Record<string, AgentConfig>;
12
+ default?: string;
13
+ /** `run.agent: true`: a plain `codeloop run` starts agents too. */
14
+ runByDefault: boolean;
15
+ }
16
+ export declare function loadAgents(projectDir: string): AgentsConfig;
17
+ export declare function resolveAgent(projectDir: string, name?: string): AgentConfig;
18
+ export declare function briefPath(card: Card): string;
19
+ /** Everything a headless agent is given to do the card's current stage. */
20
+ export declare function buildBrief(projectDir: string, card: Card): string;
21
+ export interface AgentRun {
22
+ exit: number | null;
23
+ timedOut: boolean;
24
+ durationMs: number;
25
+ }
26
+ /** Runs the agent command in the project with `{brief}` filled in. Output goes to `logFile`. */
27
+ export declare function runAgent(projectDir: string, agent: AgentConfig, briefFile: string, logFile: string): Promise<AgentRun>;
@@ -0,0 +1,178 @@
1
+ import { spawn } from 'child_process';
2
+ import { closeSync, existsSync, mkdirSync, openSync, readdirSync, readFileSync, readSync, statSync, writeFileSync } from 'fs';
3
+ import { dirname, isAbsolute, join } from 'path';
4
+ import { RefusalError, safeName } from './cards.js';
5
+ import { listCompetitors } from './competitors.js';
6
+ import { loadConfig } from './config.js';
7
+ import { stageBrief } from './flow.js';
8
+ import { loadLane, loadSkillsIndex, shellQuote, SKILLS_INDEX } from './lane.js';
9
+ import { checkEnv } from './shell.js';
10
+ import { parseFrontmatter } from './skills.js';
11
+ import { readTasks } from './spec.js';
12
+ import { inject } from './wiki.js';
13
+ export const BRIEFS_DIR = '.codeloop/state/briefs';
14
+ export const AGENT_RUNS_DIR = '.codeloop/state/agent-runs';
15
+ const DEFAULT_TIMEOUT_MINUTES = 20;
16
+ const DEFAULT_MAX_RUNS_PER_DAY = 20;
17
+ const LOG_TAIL_BYTES = 64_000;
18
+ export function loadAgents(projectDir) {
19
+ const raw = loadConfig(projectDir);
20
+ const agents = {};
21
+ for (const [name, value] of Object.entries((raw.agents ?? {}))) {
22
+ if (name === 'default')
23
+ continue;
24
+ if (typeof value?.cmd !== 'string' || !value.cmd.trim())
25
+ throw new RefusalError(`agents.${name} in .codeloop/config.yaml has no cmd`);
26
+ agents[name] = {
27
+ name,
28
+ cmd: value.cmd,
29
+ timeoutMinutes: Number(value.timeout_minutes ?? DEFAULT_TIMEOUT_MINUTES),
30
+ maxRunsPerDay: Number(value.max_runs_per_day ?? DEFAULT_MAX_RUNS_PER_DAY),
31
+ };
32
+ }
33
+ return { agents, default: raw.agents?.default, runByDefault: raw.run?.agent === true };
34
+ }
35
+ export function resolveAgent(projectDir, name) {
36
+ const config = loadAgents(projectDir);
37
+ const names = Object.keys(config.agents);
38
+ if (names.length === 0)
39
+ throw new RefusalError('no agent is configured; add `agents:` to .codeloop/config.yaml (the starter config has presets for claude and codex)');
40
+ const wanted = name ?? config.default ?? (names.length === 1 ? names[0] : undefined);
41
+ if (!wanted)
42
+ throw new RefusalError(`several agents are configured (${names.join(', ')}); name one or set agents.default`);
43
+ const agent = config.agents[wanted];
44
+ if (!agent)
45
+ throw new RefusalError(`agent "${wanted}" is not in .codeloop/config.yaml (configured: ${names.join(', ')})`);
46
+ return agent;
47
+ }
48
+ export function briefPath(card) {
49
+ return `${BRIEFS_DIR}/${card.id}-${safeName(card.stage, 'stage id')}.md`;
50
+ }
51
+ function skillBody(projectDir, name) {
52
+ const source = loadSkillsIndex(projectDir)?.find(s => s.name === name)?.source;
53
+ if (!source)
54
+ return null;
55
+ const file = isAbsolute(source) ? source : join(projectDir, source);
56
+ return existsSync(file) ? parseFrontmatter(readFileSync(file, 'utf-8')).body.trim() : null;
57
+ }
58
+ // The stage output, what is already in the card's spec folder, and the paths its open tasks name.
59
+ function filesInScope(projectDir, card, output) {
60
+ const files = output ? [output] : [];
61
+ if (card.spec && existsSync(join(projectDir, card.spec))) {
62
+ files.push(...readdirSync(join(projectDir, card.spec)).map(f => `${card.spec}/${f}`));
63
+ if (existsSync(join(projectDir, card.spec, 'tasks.md'))) {
64
+ for (const task of readTasks(projectDir, card.spec).tasks.filter(t => !t.done)) {
65
+ files.push(...(task.text.match(/(?:[\w.-]+\/)+[\w.-]+/g) ?? []));
66
+ }
67
+ }
68
+ }
69
+ return [...new Set(files)];
70
+ }
71
+ /** Everything a headless agent is given to do the card's current stage. */
72
+ export function buildBrief(projectDir, card) {
73
+ const stage = stageBrief(projectDir, card);
74
+ if (!stage)
75
+ throw new RefusalError(`card ${card.id} has no stage to brief (it is ${card.stage})`);
76
+ const lane = loadLane(projectDir, card.lane);
77
+ const events = card.events.filter(e => e.stage === card.stage);
78
+ const lines = [
79
+ `# Stage brief: ${card.id} ${card.stage}`,
80
+ '',
81
+ `Card: ${card.id}`,
82
+ `Title: ${card.title}`,
83
+ `Lane: ${lane.id} (version ${lane.version})`,
84
+ `Stage: ${card.stage}`,
85
+ ...(stage.skill ? [`Skill: ${stage.skill}`] : []),
86
+ ...(stage.output ? [`Output: ${stage.output}`] : []),
87
+ '',
88
+ '## The check that must pass',
89
+ '',
90
+ `The stage is finished when this command, run from the project root, exits 0${stage.output ? `. It judges ${stage.output}, which this stage writes` : ''}:`,
91
+ '',
92
+ ` ${stage.done}`,
93
+ '',
94
+ ];
95
+ const failed = events.filter(e => e.action === 'fail' || e.action === 'stuck').at(-1);
96
+ if (stage.notes.length || stage.rejections.length || failed?.note) {
97
+ lines.push('## Feedback on this stage', '');
98
+ for (const note of stage.notes)
99
+ lines.push(`- Stage note: ${note}`);
100
+ stage.rejections.forEach((note, i) => lines.push(`- ${i === stage.rejections.length - 1 ? 'Latest rejection' : 'Earlier rejection'}: ${note}`));
101
+ if (failed?.note)
102
+ lines.push('', `The check last failed${failed.action === 'stuck' ? ' and the card was marked stuck' : ''} with:`, '', ...failed.note.split('\n').map(l => ` ${l}`));
103
+ lines.push('');
104
+ }
105
+ if (stage.skill) {
106
+ const body = skillBody(projectDir, stage.skill);
107
+ lines.push(`## Skill: ${stage.skill}`, '', body ?? `The skill's text is not in ${SKILLS_INDEX}; use the /${stage.skill} skill if your tool has it.`, '');
108
+ }
109
+ const pages = inject(projectDir, filesInScope(projectDir, card, stage.output));
110
+ if (pages.length) {
111
+ lines.push('## Wiki pages that apply', '');
112
+ for (const p of pages)
113
+ lines.push(`### ${p.title} (${p.kind}, freq ${p.freq}, ${p.severity})`, '', p.body, '');
114
+ }
115
+ const competitors = card.stage === 'research' ? listCompetitors(projectDir) : [];
116
+ if (competitors.length) {
117
+ lines.push('## Competitors', '', `Read each one's docs and changelog for this feature. Give each a row in ${stage.output ?? 'the research file'} that starts with its name: the row is copied to its page when the stage passes.`, '');
118
+ for (const c of competitors)
119
+ lines.push(`### ${c.title} (${c.path})`, '', ...(c.docs ? [`Docs: ${c.docs}`] : []), ...(c.changelog ? [`Changelog: ${c.changelog}`] : []), '', c.body, '');
120
+ }
121
+ lines.push('## Rules', '', `- Do only the ${card.stage} stage of ${card.id}.`, stage.output ? `- Write the output to ${stage.output}.` : '- Leave the project in the state the check asks for.', '- Do not run `codeloop approve`, `codeloop next` or `codeloop card advance`. The run that started you checks the work and moves the card.', '- Do not edit .codeloop/cards.json or anything in .codeloop/lanes/.', '- Stop when the output is written.', '');
122
+ return lines.join('\n');
123
+ }
124
+ // Keeps the end of the log, where an agent says what it did or why it stopped.
125
+ function keepTail(file) {
126
+ const size = statSync(file).size;
127
+ if (size <= LOG_TAIL_BYTES)
128
+ return;
129
+ const fd = openSync(file, 'r');
130
+ const buffer = Buffer.alloc(LOG_TAIL_BYTES);
131
+ readSync(fd, buffer, 0, LOG_TAIL_BYTES, size - LOG_TAIL_BYTES);
132
+ closeSync(fd);
133
+ writeFileSync(file, `[first ${size - LOG_TAIL_BYTES} bytes dropped]\n${buffer.toString('utf-8')}`);
134
+ }
135
+ /** Runs the agent command in the project with `{brief}` filled in. Output goes to `logFile`. */
136
+ export function runAgent(projectDir, agent, briefFile, logFile) {
137
+ mkdirSync(dirname(logFile), { recursive: true });
138
+ const out = openSync(logFile, 'w');
139
+ const started = Date.now();
140
+ return new Promise(done => {
141
+ let timedOut = false;
142
+ let finished = false;
143
+ const finish = (exit) => {
144
+ if (finished)
145
+ return;
146
+ finished = true;
147
+ clearTimeout(timer);
148
+ closeSync(out);
149
+ keepTail(logFile);
150
+ done({ exit, timedOut, durationMs: Date.now() - started });
151
+ };
152
+ // The command's output goes straight to the file: a pipe held open by a child the agent left
153
+ // behind would keep this process waiting after the agent itself has gone.
154
+ const child = spawn(agent.cmd.replaceAll('{brief}', shellQuote(briefFile)), {
155
+ cwd: projectDir,
156
+ shell: true,
157
+ detached: true,
158
+ stdio: ['ignore', out, out],
159
+ env: { ...checkEnv(), CODELOOP_ROLE: 'agent', CODELOOP_AGENT_RUN: agent.name },
160
+ });
161
+ const timer = setTimeout(() => {
162
+ timedOut = true;
163
+ // `detached` made the shell a process group leader, so this reaches the agent and its children.
164
+ try {
165
+ process.kill(-child.pid, 'SIGKILL');
166
+ }
167
+ catch {
168
+ child.kill('SIGKILL');
169
+ }
170
+ }, agent.timeoutMinutes * 60_000);
171
+ child.on('error', e => {
172
+ writeFileSync(logFile, `could not start: ${e.message}\n`, { flag: 'a' });
173
+ finish(null);
174
+ });
175
+ child.on('exit', code => finish(code));
176
+ });
177
+ }
178
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../../src/lib/agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ export interface TaskStep {
2
+ text: string;
3
+ done: boolean;
4
+ }
5
+ export interface Task {
6
+ id: string;
7
+ title: string;
8
+ description?: string;
9
+ status: 'backlog' | 'planned' | 'in_progress' | 'review' | 'done';
10
+ labels: string[];
11
+ steps: TaskStep[];
12
+ commits: string[];
13
+ acceptanceCriteria?: string[];
14
+ createdAt: string;
15
+ updatedAt: string;
16
+ }
17
+ export interface Board {
18
+ version: 1;
19
+ columns: string[];
20
+ tasks: Task[];
21
+ }
22
+ export declare function createBoard(): Board;
23
+ export declare function nextId(board: Board): string;
24
+ export interface AddTaskInput {
25
+ title: string;
26
+ description?: string;
27
+ status?: Task['status'];
28
+ labels?: string[];
29
+ steps?: TaskStep[];
30
+ acceptanceCriteria?: string[];
31
+ }
32
+ export declare function addTask(board: Board, input: AddTaskInput): Board;
33
+ export declare function updateTask(board: Board, id: string, patch: Partial<Omit<Task, 'id' | 'createdAt'>>): Board;
34
+ export declare function moveTask(board: Board, id: string, newStatus: Task['status']): Board;
35
+ export declare function deleteTask(board: Board, id: string): Board;
36
+ export declare function getTask(board: Board, id: string): Task | undefined;
37
+ export declare function loadBoard(dir: string): Board;
38
+ export declare function saveBoard(dir: string, board: Board): void;