@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,38 @@
1
+ export type SignalType = 'file_change' | 'git_commit' | 'test_result' | 'build_status' | 'idle';
2
+ export interface WatchSignal {
3
+ type: SignalType;
4
+ timestamp: string;
5
+ data: Record<string, unknown>;
6
+ }
7
+ export interface SignalConfig {
8
+ file_change: boolean;
9
+ git_commit: boolean;
10
+ test_result: boolean;
11
+ build_status: boolean;
12
+ idle: boolean;
13
+ }
14
+ /**
15
+ * Watch for file changes using fs.watch on the project directory.
16
+ * Fires a callback for each relevant file change.
17
+ */
18
+ export declare function watchFiles(projectDir: string, ignore: string[], callback: (signal: WatchSignal) => void): {
19
+ close: () => void;
20
+ };
21
+ /**
22
+ * Poll .git/refs/heads for new commits.
23
+ * Returns the latest commit SHA, or null if not a git repo.
24
+ */
25
+ export declare function getLatestCommitSha(projectDir: string): string | null;
26
+ /**
27
+ * Poll for new git commits at a given interval.
28
+ */
29
+ export declare function pollGitCommits(projectDir: string, intervalMs: number, callback: (signal: WatchSignal) => void): {
30
+ close: () => void;
31
+ };
32
+ /**
33
+ * Idle timer — fires after no file changes for the specified duration.
34
+ */
35
+ export declare function createIdleTimer(timeoutMs: number, callback: (signal: WatchSignal) => void): {
36
+ reset: () => void;
37
+ close: () => void;
38
+ };
@@ -0,0 +1,119 @@
1
+ import { watch } from 'fs';
2
+ import { join, relative } from 'path';
3
+ import { execSync } from 'child_process';
4
+ const DEFAULT_IGNORE = ['node_modules', 'dist', '.git', '*.log', '.codeloop/.serve.pid', '.codeloop/.watch.pid'];
5
+ /**
6
+ * Watch for file changes using fs.watch on the project directory.
7
+ * Fires a callback for each relevant file change.
8
+ */
9
+ export function watchFiles(projectDir, ignore, callback) {
10
+ const ignoreSet = new Set([...DEFAULT_IGNORE, ...ignore]);
11
+ const watchers = [];
12
+ function shouldIgnore(filePath) {
13
+ const rel = relative(projectDir, filePath);
14
+ for (const pattern of ignoreSet) {
15
+ if (rel.startsWith(pattern) || rel.includes(`/${pattern}/`) || rel.includes(`/${pattern}`)) {
16
+ return true;
17
+ }
18
+ // Simple glob: *.log → endsWith .log
19
+ if (pattern.startsWith('*.') && rel.endsWith(pattern.slice(1))) {
20
+ return true;
21
+ }
22
+ }
23
+ return false;
24
+ }
25
+ try {
26
+ const watcher = watch(projectDir, { recursive: true }, (_event, filename) => {
27
+ if (!filename)
28
+ return;
29
+ const fullPath = join(projectDir, filename);
30
+ if (shouldIgnore(fullPath))
31
+ return;
32
+ callback({
33
+ type: 'file_change',
34
+ timestamp: new Date().toISOString(),
35
+ data: { file: filename },
36
+ });
37
+ });
38
+ watchers.push(watcher);
39
+ }
40
+ catch {
41
+ // fs.watch with recursive may not be supported on all platforms
42
+ }
43
+ return {
44
+ close: () => {
45
+ for (const w of watchers)
46
+ w.close();
47
+ },
48
+ };
49
+ }
50
+ /**
51
+ * Poll .git/refs/heads for new commits.
52
+ * Returns the latest commit SHA, or null if not a git repo.
53
+ */
54
+ export function getLatestCommitSha(projectDir) {
55
+ try {
56
+ return execSync('git rev-parse --short HEAD', {
57
+ cwd: projectDir,
58
+ encoding: 'utf-8',
59
+ stdio: ['pipe', 'pipe', 'pipe'],
60
+ }).trim();
61
+ }
62
+ catch {
63
+ return null;
64
+ }
65
+ }
66
+ /**
67
+ * Poll for new git commits at a given interval.
68
+ */
69
+ export function pollGitCommits(projectDir, intervalMs, callback) {
70
+ let lastSha = getLatestCommitSha(projectDir);
71
+ const timer = setInterval(() => {
72
+ const currentSha = getLatestCommitSha(projectDir);
73
+ if (currentSha && currentSha !== lastSha) {
74
+ // Get commit message
75
+ let message = '';
76
+ try {
77
+ message = execSync(`git log -1 --format=%s ${currentSha}`, {
78
+ cwd: projectDir,
79
+ encoding: 'utf-8',
80
+ stdio: ['pipe', 'pipe', 'pipe'],
81
+ }).trim();
82
+ }
83
+ catch { /* ignore */ }
84
+ callback({
85
+ type: 'git_commit',
86
+ timestamp: new Date().toISOString(),
87
+ data: { sha: currentSha, previousSha: lastSha, message },
88
+ });
89
+ lastSha = currentSha;
90
+ }
91
+ }, intervalMs);
92
+ return {
93
+ close: () => clearInterval(timer),
94
+ };
95
+ }
96
+ /**
97
+ * Idle timer — fires after no file changes for the specified duration.
98
+ */
99
+ export function createIdleTimer(timeoutMs, callback) {
100
+ let timer = null;
101
+ function start() {
102
+ if (timer)
103
+ clearTimeout(timer);
104
+ timer = setTimeout(() => {
105
+ callback({
106
+ type: 'idle',
107
+ timestamp: new Date().toISOString(),
108
+ data: { idleSeconds: timeoutMs / 1000 },
109
+ });
110
+ }, timeoutMs);
111
+ }
112
+ start();
113
+ return {
114
+ reset: () => start(),
115
+ close: () => { if (timer)
116
+ clearTimeout(timer); },
117
+ };
118
+ }
119
+ //# sourceMappingURL=signals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signals.js","sourceRoot":"","sources":["../../src/watch/signals.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { WatchSignal } from './signals.js';
2
+ export interface TriggerResult {
3
+ action: string;
4
+ details: string;
5
+ }
6
+ /**
7
+ * Process a signal and determine what actions to take.
8
+ * Returns a list of actions taken (for logging/reporting).
9
+ */
10
+ export declare function processSignal(projectDir: string, signal: WatchSignal): TriggerResult[];
@@ -0,0 +1,67 @@
1
+ import { loadBoard, saveBoard, updateTask } from '../lib/board.js';
2
+ /**
3
+ * Process a signal and determine what actions to take.
4
+ * Returns a list of actions taken (for logging/reporting).
5
+ */
6
+ export function processSignal(projectDir, signal) {
7
+ const results = [];
8
+ switch (signal.type) {
9
+ case 'file_change':
10
+ // File changes are primarily used to reset the idle timer.
11
+ // No board action needed for individual file saves.
12
+ results.push({
13
+ action: 'file_tracked',
14
+ details: `${signal.data.file}`,
15
+ });
16
+ break;
17
+ case 'git_commit': {
18
+ // Append commit SHA to the active board task
19
+ try {
20
+ let board = loadBoard(projectDir);
21
+ const activeTask = board.tasks.find(t => t.status === 'in_progress' || t.status === 'planned');
22
+ if (activeTask) {
23
+ const commits = [...activeTask.commits, signal.data.sha];
24
+ board = updateTask(board, activeTask.id, { commits });
25
+ saveBoard(projectDir, board);
26
+ results.push({
27
+ action: 'commit_tracked',
28
+ details: `${signal.data.sha} → task ${activeTask.id} (${signal.data.message})`,
29
+ });
30
+ }
31
+ else {
32
+ results.push({
33
+ action: 'commit_untracked',
34
+ details: `${signal.data.sha} — no active task on board`,
35
+ });
36
+ }
37
+ }
38
+ catch {
39
+ results.push({
40
+ action: 'commit_error',
41
+ details: `Failed to update board with commit ${signal.data.sha}`,
42
+ });
43
+ }
44
+ break;
45
+ }
46
+ case 'idle':
47
+ results.push({
48
+ action: 'idle_timeout',
49
+ details: `No activity for ${signal.data.idleSeconds}s`,
50
+ });
51
+ break;
52
+ case 'test_result':
53
+ results.push({
54
+ action: 'test_tracked',
55
+ details: `Tests: ${signal.data.passed}/${signal.data.total} passed`,
56
+ });
57
+ break;
58
+ case 'build_status':
59
+ results.push({
60
+ action: 'build_tracked',
61
+ details: `Build: ${signal.data.status}`,
62
+ });
63
+ break;
64
+ }
65
+ return results;
66
+ }
67
+ //# sourceMappingURL=triggers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"triggers.js","sourceRoot":"","sources":["../../src/watch/triggers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAuB,MAAM,iBAAiB,CAAC;AAQxF;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,UAAkB,EAAE,MAAmB;IACnE,MAAM,OAAO,GAAoB,EAAE,CAAC;IAEpC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,aAAa;YAChB,2DAA2D;YAC3D,oDAAoD;YACpD,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;aAC/B,CAAC,CAAC;YACH,MAAM;QAER,KAAK,YAAY,CAAC,CAAC,CAAC;YAClB,6CAA6C;YAC7C,IAAI,CAAC;gBACH,IAAI,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;gBAClC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CACjC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,aAAa,IAAI,CAAC,CAAC,MAAM,KAAK,SAAS,CAC1D,CAAC;gBAEF,IAAI,UAAU,EAAE,CAAC;oBACf,MAAM,OAAO,GAAG,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAa,CAAC,CAAC;oBACnE,KAAK,GAAG,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;oBACtD,SAAS,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;oBAE7B,OAAO,CAAC,IAAI,CAAC;wBACX,MAAM,EAAE,gBAAgB;wBACxB,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,WAAW,UAAU,CAAC,EAAE,KAAK,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG;qBAC/E,CAAC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACN,OAAO,CAAC,IAAI,CAAC;wBACX,MAAM,EAAE,kBAAkB;wBAC1B,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,4BAA4B;qBACxD,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,CAAC,IAAI,CAAC;oBACX,MAAM,EAAE,cAAc;oBACtB,OAAO,EAAE,sCAAsC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE;iBACjE,CAAC,CAAC;YACL,CAAC;YACD,MAAM;QACR,CAAC;QAED,KAAK,MAAM;YACT,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,mBAAmB,MAAM,CAAC,IAAI,CAAC,WAAW,GAAG;aACvD,CAAC,CAAC;YACH,MAAM;QAER,KAAK,aAAa;YAChB,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,cAAc;gBACtB,OAAO,EAAE,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,SAAS;aACpE,CAAC,CAAC;YACH,MAAM;QAER,KAAK,cAAc;YACjB,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,eAAe;gBACvB,OAAO,EAAE,UAAU,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE;aACxC,CAAC,CAAC;YACH,MAAM;IACV,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@protoboxai/codeloop",
3
+ "version": "0.3.0",
4
+ "description": "Self-improving development workflow for AI coding agents",
5
+ "homepage": "https://codeloop.protobox.ai",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/sixfactors/codeloop.git"
9
+ },
10
+ "bugs": {
11
+ "url": "https://github.com/sixfactors/codeloop/issues"
12
+ },
13
+ "type": "module",
14
+ "bin": {
15
+ "codeloop": "dist/index.js"
16
+ },
17
+ "scripts": {
18
+ "build": "tsc",
19
+ "build:ui": "cd ui && npm run build",
20
+ "build:all": "tsc && cd ui && npm run build",
21
+ "dev": "tsc --watch",
22
+ "test": "vitest run",
23
+ "test:watch": "vitest",
24
+ "test:coverage": "vitest run --coverage",
25
+ "prepublishOnly": "npm run build:all"
26
+ },
27
+ "keywords": [
28
+ "claude-code",
29
+ "cursor",
30
+ "codex",
31
+ "workflow",
32
+ "developer-tools",
33
+ "cli",
34
+ "ai-coding"
35
+ ],
36
+ "author": "Dean Grover",
37
+ "license": "MIT",
38
+ "dependencies": {
39
+ "@hono/node-server": "^1.19.9",
40
+ "@modelcontextprotocol/sdk": "^1.31.0",
41
+ "chalk": "^5.3.0",
42
+ "commander": "^12.1.0",
43
+ "fs-extra": "^11.2.0",
44
+ "hono": "^4.12.0",
45
+ "yaml": "^2.5.0",
46
+ "zod": "^4.6.5"
47
+ },
48
+ "devDependencies": {
49
+ "@types/fs-extra": "^11.0.4",
50
+ "@types/node": "^20.14.0",
51
+ "@vitest/coverage-v8": "^4.0.18",
52
+ "typescript": "^5.5.0",
53
+ "vitest": "^4.0.18"
54
+ },
55
+ "engines": {
56
+ "node": ">=18.0.0"
57
+ },
58
+ "files": [
59
+ "dist",
60
+ "templates",
61
+ "starters",
62
+ "registry"
63
+ ]
64
+ }
@@ -0,0 +1,106 @@
1
+ {
2
+ "version": 1,
3
+ "updatedAt": "2026-02-21T00:00:00Z",
4
+ "skills": [
5
+ {
6
+ "name": "design",
7
+ "version": "0.2.0",
8
+ "description": "Architecture before code — generate lightweight spec from codebase analysis",
9
+ "author": "sixfactors",
10
+ "tags": ["pipeline", "architecture", "planning"],
11
+ "stack": "generic",
12
+ "tier": "trusted",
13
+ "source": "builtin"
14
+ },
15
+ {
16
+ "name": "plan",
17
+ "version": "0.2.0",
18
+ "description": "Plan a task — write spec to tasks/todo.md, enter plan mode",
19
+ "author": "sixfactors",
20
+ "tags": ["pipeline", "planning", "tdd"],
21
+ "stack": "generic",
22
+ "tier": "trusted",
23
+ "source": "builtin"
24
+ },
25
+ {
26
+ "name": "manage",
27
+ "version": "0.2.0",
28
+ "description": "Track task progress — read/update tasks/todo.md",
29
+ "author": "sixfactors",
30
+ "tags": ["pipeline", "tasks", "tracking"],
31
+ "stack": "generic",
32
+ "tier": "trusted",
33
+ "source": "builtin"
34
+ },
35
+ {
36
+ "name": "test",
37
+ "version": "0.2.0",
38
+ "description": "Run tests, parse results, track coverage history",
39
+ "author": "sixfactors",
40
+ "tags": ["pipeline", "testing", "coverage"],
41
+ "stack": "generic",
42
+ "tier": "trusted",
43
+ "source": "builtin"
44
+ },
45
+ {
46
+ "name": "commit",
47
+ "version": "0.2.0",
48
+ "description": "Review + reflect + commit in one flow",
49
+ "author": "sixfactors",
50
+ "tags": ["pipeline", "git", "review"],
51
+ "stack": "generic",
52
+ "tier": "trusted",
53
+ "source": "builtin"
54
+ },
55
+ {
56
+ "name": "qa",
57
+ "version": "0.2.0",
58
+ "description": "Quality gate — run all checks before promoting a task",
59
+ "author": "sixfactors",
60
+ "tags": ["pipeline", "quality", "gate"],
61
+ "stack": "generic",
62
+ "tier": "trusted",
63
+ "source": "builtin"
64
+ },
65
+ {
66
+ "name": "deploy",
67
+ "version": "0.2.0",
68
+ "description": "Deploy to staging or production with verification gates",
69
+ "author": "sixfactors",
70
+ "tags": ["pipeline", "deploy", "staging", "production"],
71
+ "stack": "generic",
72
+ "tier": "trusted",
73
+ "source": "builtin"
74
+ },
75
+ {
76
+ "name": "debug",
77
+ "version": "0.2.0",
78
+ "description": "Investigate production issues — search logs, check health",
79
+ "author": "sixfactors",
80
+ "tags": ["pipeline", "debugging", "logs", "production"],
81
+ "stack": "generic",
82
+ "tier": "trusted",
83
+ "source": "builtin"
84
+ },
85
+ {
86
+ "name": "reflect",
87
+ "version": "0.1.0",
88
+ "description": "Session-end reflection — capture what you learned",
89
+ "author": "sixfactors",
90
+ "tags": ["pipeline", "reflection", "learning"],
91
+ "stack": "generic",
92
+ "tier": "trusted",
93
+ "source": "builtin"
94
+ },
95
+ {
96
+ "name": "ship",
97
+ "version": "0.2.0",
98
+ "description": "Close the loop — QA, deploy staging, deploy prod, verify, close task",
99
+ "author": "sixfactors",
100
+ "tags": ["pipeline", "deploy", "orchestration"],
101
+ "stack": "generic",
102
+ "tier": "trusted",
103
+ "source": "builtin"
104
+ }
105
+ ]
106
+ }
@@ -0,0 +1,95 @@
1
+ # Codeloop Configuration
2
+ # Generic starter — minimal assumptions, works with any project.
3
+ # Customize scopes, quality_checks, and diff_scan for your stack.
4
+
5
+ project:
6
+ name: "my-project"
7
+
8
+ # Scopes map file paths to knowledge sections.
9
+ # /commit uses scopes to load only relevant gotchas and patterns.
10
+ scopes:
11
+ all:
12
+ paths: ["**/*"]
13
+ gotcha_sections: []
14
+ pattern_sections: []
15
+
16
+ # Quality checks run during /commit Phase 1.
17
+ # Add build/lint/typecheck commands for your stack.
18
+ quality_checks: {}
19
+ # all:
20
+ # - name: "Lint"
21
+ # command: "npm run lint 2>&1 | tail -20"
22
+
23
+ # Diff scan rules check the actual diff for violations.
24
+ # Each match is reported at the specified severity.
25
+ diff_scan: []
26
+ # - pattern: "console\\.log"
27
+ # files: "*.ts,*.js"
28
+ # exclude: "*.test.*"
29
+ # severity: CRITICAL
30
+ # message: "console.log in production code"
31
+ # - pattern: "TODO"
32
+ # files: "*"
33
+ # severity: WARNING
34
+ # message: "TODO comment found"
35
+
36
+ # Testing — used by /test and /qa
37
+ # test:
38
+ # command: "npm test" # or pytest, go test ./..., cargo test
39
+ # coverage_threshold: 80 # optional, for /qa gate
40
+ # integrity_checks: true # scan for fake-pass patterns
41
+
42
+ # Deployment — used by /deploy and /ship
43
+ # deploy:
44
+ # staging:
45
+ # command: "" # your staging deploy command
46
+ # verify: "" # post-deploy smoke test
47
+ # production:
48
+ # command: "" # your production deploy command
49
+ # verify: "" # post-deploy smoke test
50
+ # requires: staging # must pass staging first
51
+
52
+ # Debugging — used by /debug
53
+ # debug:
54
+ # logs: "" # command to tail production logs
55
+ # health: "" # health check URL or command
56
+
57
+ # Conventional commit types allowed.
58
+ commit:
59
+ types: [feat, fix, refactor, docs, test, chore, perf]
60
+ format: "type(scope): message"
61
+
62
+ # Watch mode — used by `codeloop watch`
63
+ # watch:
64
+ # enabled: true
65
+ # idle_timeout: 300 # seconds before idle signal
66
+ # signals:
67
+ # file_change: true
68
+ # git_commit: true
69
+ # test_result: true
70
+ # build_status: true
71
+ # idle: true
72
+ # ignore:
73
+ # - node_modules
74
+ # - dist
75
+ # - .git
76
+ # - "*.log"
77
+
78
+ # Unattended runs — used by `codeloop run --agent` and `codeloop schedule install`.
79
+ # The command gets the stage brief; {brief} becomes the shell-quoted path to it.
80
+ # agents:
81
+ # default: claude
82
+ # claude:
83
+ # cmd: "claude -p --permission-mode acceptEdits < {brief}"
84
+ # timeout_minutes: 20 # the agent is killed after this
85
+ # max_runs_per_day: 20 # agent starts across the project in any 24 hours
86
+ # codex:
87
+ # cmd: "codex exec - < {brief}"
88
+ # run:
89
+ # agent: true # plain `codeloop run` starts agents too
90
+
91
+ # Codeloop behavior settings.
92
+ codeloop:
93
+ critical_frequency: 3 # Gotchas at this freq or higher → CRITICAL in review
94
+ promote_frequency: 10 # Suggest promoting to rules.md at this freq
95
+ max_knowledge_lines: 200 # Warn when knowledge files exceed this
@@ -0,0 +1,99 @@
1
+ # Codeloop Configuration
2
+ # Go starter
3
+
4
+ project:
5
+ name: "my-project"
6
+
7
+ scopes:
8
+ backend:
9
+ paths: ["cmd/**", "internal/**", "pkg/**"]
10
+ gotcha_sections: ["Backend", "Database", "API"]
11
+ pattern_sections: ["Backend", "API"]
12
+ tests:
13
+ paths: ["**/*_test.go"]
14
+ gotcha_sections: ["Testing"]
15
+ pattern_sections: ["Testing"]
16
+ config:
17
+ paths: [".github/**", "Dockerfile*", "docker-compose*", "Makefile"]
18
+ gotcha_sections: ["CI", "Config"]
19
+ pattern_sections: ["CI"]
20
+
21
+ quality_checks:
22
+ backend:
23
+ - name: "Vet"
24
+ command: "go vet ./... 2>&1 | tail -20"
25
+ - name: "Build"
26
+ command: "go build ./... 2>&1 | tail -20"
27
+
28
+ diff_scan:
29
+ - pattern: "fmt\\.Print"
30
+ files: "*.go"
31
+ exclude: "*_test.go"
32
+ severity: WARNING
33
+ message: "fmt.Print in production code — use structured logging"
34
+ - pattern: "panic\\("
35
+ files: "*.go"
36
+ exclude: "*_test.go"
37
+ severity: WARNING
38
+ message: "panic() in production code — return errors instead"
39
+
40
+ # Testing — used by /test and /qa
41
+ test:
42
+ command: "go test ./..."
43
+ coverage_threshold: 70
44
+ integrity_checks: false
45
+
46
+ # Deployment — used by /deploy and /ship
47
+ # Uncomment and fill in your deploy commands:
48
+ # deploy:
49
+ # staging:
50
+ # command: "make deploy-staging"
51
+ # verify: "curl -sf https://staging.example.com/health"
52
+ # production:
53
+ # command: "make deploy-prod"
54
+ # verify: "curl -sf https://example.com/health"
55
+ # requires: staging
56
+
57
+ # Debugging — used by /debug
58
+ # Uncomment and fill in your log/health commands:
59
+ # debug:
60
+ # logs: "kubectl logs deployment/myapp --tail=50"
61
+ # health: "curl -sf https://example.com/health"
62
+
63
+ commit:
64
+ types: [feat, fix, refactor, docs, test, chore, perf]
65
+ format: "type(scope): message"
66
+
67
+ # Watch mode — used by `codeloop watch`
68
+ watch:
69
+ enabled: true
70
+ idle_timeout: 300
71
+ signals:
72
+ file_change: true
73
+ git_commit: true
74
+ test_result: true
75
+ build_status: true
76
+ idle: true
77
+ ignore:
78
+ - vendor
79
+ - bin
80
+ - .git
81
+ - "*.log"
82
+
83
+ # Unattended runs — used by `codeloop run --agent` and `codeloop schedule install`.
84
+ # The command gets the stage brief; {brief} becomes the shell-quoted path to it.
85
+ # agents:
86
+ # default: claude
87
+ # claude:
88
+ # cmd: "claude -p --permission-mode acceptEdits < {brief}"
89
+ # timeout_minutes: 20 # the agent is killed after this
90
+ # max_runs_per_day: 20 # agent starts across the project in any 24 hours
91
+ # codex:
92
+ # cmd: "codex exec - < {brief}"
93
+ # run:
94
+ # agent: true # plain `codeloop run` starts agents too
95
+
96
+ codeloop:
97
+ critical_frequency: 3
98
+ promote_frequency: 10
99
+ max_knowledge_lines: 200