orka-cli 1.0.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 (288) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/CONTRIBUTING.md +59 -0
  3. package/README.md +208 -0
  4. package/dist/agents/base-agent.d.ts +48 -0
  5. package/dist/agents/base-agent.d.ts.map +1 -0
  6. package/dist/agents/base-agent.js +59 -0
  7. package/dist/agents/base-agent.js.map +1 -0
  8. package/dist/agents/builder.d.ts +53 -0
  9. package/dist/agents/builder.d.ts.map +1 -0
  10. package/dist/agents/builder.js +147 -0
  11. package/dist/agents/builder.js.map +1 -0
  12. package/dist/agents/coordinator.d.ts +45 -0
  13. package/dist/agents/coordinator.d.ts.map +1 -0
  14. package/dist/agents/coordinator.js +201 -0
  15. package/dist/agents/coordinator.js.map +1 -0
  16. package/dist/agents/index.d.ts +8 -0
  17. package/dist/agents/index.d.ts.map +1 -0
  18. package/dist/agents/index.js +7 -0
  19. package/dist/agents/index.js.map +1 -0
  20. package/dist/agents/reviewer.d.ts +39 -0
  21. package/dist/agents/reviewer.d.ts.map +1 -0
  22. package/dist/agents/reviewer.js +119 -0
  23. package/dist/agents/reviewer.js.map +1 -0
  24. package/dist/agents/scout.d.ts +35 -0
  25. package/dist/agents/scout.d.ts.map +1 -0
  26. package/dist/agents/scout.js +76 -0
  27. package/dist/agents/scout.js.map +1 -0
  28. package/dist/agents/tester.d.ts +25 -0
  29. package/dist/agents/tester.d.ts.map +1 -0
  30. package/dist/agents/tester.js +76 -0
  31. package/dist/agents/tester.js.map +1 -0
  32. package/dist/cli/board.d.ts +28 -0
  33. package/dist/cli/board.d.ts.map +1 -0
  34. package/dist/cli/board.js +178 -0
  35. package/dist/cli/board.js.map +1 -0
  36. package/dist/cli/cost.d.ts +31 -0
  37. package/dist/cli/cost.d.ts.map +1 -0
  38. package/dist/cli/cost.js +85 -0
  39. package/dist/cli/cost.js.map +1 -0
  40. package/dist/cli/credentials.d.ts +23 -0
  41. package/dist/cli/credentials.d.ts.map +1 -0
  42. package/dist/cli/credentials.js +77 -0
  43. package/dist/cli/credentials.js.map +1 -0
  44. package/dist/cli/dry-run.d.ts +3 -0
  45. package/dist/cli/dry-run.d.ts.map +1 -0
  46. package/dist/cli/dry-run.js +21 -0
  47. package/dist/cli/dry-run.js.map +1 -0
  48. package/dist/cli/extras.d.ts +21 -0
  49. package/dist/cli/extras.d.ts.map +1 -0
  50. package/dist/cli/extras.js +39 -0
  51. package/dist/cli/extras.js.map +1 -0
  52. package/dist/cli/fix.d.ts +11 -0
  53. package/dist/cli/fix.d.ts.map +1 -0
  54. package/dist/cli/fix.js +72 -0
  55. package/dist/cli/fix.js.map +1 -0
  56. package/dist/cli/git-session.d.ts +21 -0
  57. package/dist/cli/git-session.d.ts.map +1 -0
  58. package/dist/cli/git-session.js +62 -0
  59. package/dist/cli/git-session.js.map +1 -0
  60. package/dist/cli/index.d.ts +4 -0
  61. package/dist/cli/index.d.ts.map +1 -0
  62. package/dist/cli/index.js +546 -0
  63. package/dist/cli/index.js.map +1 -0
  64. package/dist/cli/init.d.ts +16 -0
  65. package/dist/cli/init.d.ts.map +1 -0
  66. package/dist/cli/init.js +75 -0
  67. package/dist/cli/init.js.map +1 -0
  68. package/dist/cli/login.d.ts +9 -0
  69. package/dist/cli/login.d.ts.map +1 -0
  70. package/dist/cli/login.js +114 -0
  71. package/dist/cli/login.js.map +1 -0
  72. package/dist/cli/logs.d.ts +16 -0
  73. package/dist/cli/logs.d.ts.map +1 -0
  74. package/dist/cli/logs.js +37 -0
  75. package/dist/cli/logs.js.map +1 -0
  76. package/dist/cli/memory-learner.d.ts +7 -0
  77. package/dist/cli/memory-learner.d.ts.map +1 -0
  78. package/dist/cli/memory-learner.js +36 -0
  79. package/dist/cli/memory-learner.js.map +1 -0
  80. package/dist/cli/memory.d.ts +13 -0
  81. package/dist/cli/memory.d.ts.map +1 -0
  82. package/dist/cli/memory.js +52 -0
  83. package/dist/cli/memory.js.map +1 -0
  84. package/dist/cli/plugin.d.ts +5 -0
  85. package/dist/cli/plugin.d.ts.map +1 -0
  86. package/dist/cli/plugin.js +42 -0
  87. package/dist/cli/plugin.js.map +1 -0
  88. package/dist/cli/resume.d.ts +18 -0
  89. package/dist/cli/resume.d.ts.map +1 -0
  90. package/dist/cli/resume.js +84 -0
  91. package/dist/cli/resume.js.map +1 -0
  92. package/dist/cli/rollback.d.ts +11 -0
  93. package/dist/cli/rollback.d.ts.map +1 -0
  94. package/dist/cli/rollback.js +12 -0
  95. package/dist/cli/rollback.js.map +1 -0
  96. package/dist/cli/rules.d.ts +7 -0
  97. package/dist/cli/rules.d.ts.map +1 -0
  98. package/dist/cli/rules.js +20 -0
  99. package/dist/cli/rules.js.map +1 -0
  100. package/dist/cli/run.d.ts +35 -0
  101. package/dist/cli/run.d.ts.map +1 -0
  102. package/dist/cli/run.js +294 -0
  103. package/dist/cli/run.js.map +1 -0
  104. package/dist/cli/session.d.ts +5 -0
  105. package/dist/cli/session.d.ts.map +1 -0
  106. package/dist/cli/session.js +46 -0
  107. package/dist/cli/session.js.map +1 -0
  108. package/dist/cli/ui/Board.d.ts +22 -0
  109. package/dist/cli/ui/Board.d.ts.map +1 -0
  110. package/dist/cli/ui/Board.js +40 -0
  111. package/dist/cli/ui/Board.js.map +1 -0
  112. package/dist/cli/ui/StatusBar.d.ts +10 -0
  113. package/dist/cli/ui/StatusBar.d.ts.map +1 -0
  114. package/dist/cli/ui/StatusBar.js +6 -0
  115. package/dist/cli/ui/StatusBar.js.map +1 -0
  116. package/dist/config.d.ts +4 -0
  117. package/dist/config.d.ts.map +1 -0
  118. package/dist/config.js +79 -0
  119. package/dist/config.js.map +1 -0
  120. package/dist/core/bus.d.ts +19 -0
  121. package/dist/core/bus.d.ts.map +1 -0
  122. package/dist/core/bus.js +25 -0
  123. package/dist/core/bus.js.map +1 -0
  124. package/dist/core/context.d.ts +10 -0
  125. package/dist/core/context.d.ts.map +1 -0
  126. package/dist/core/context.js +42 -0
  127. package/dist/core/context.js.map +1 -0
  128. package/dist/core/dispatcher.d.ts +25 -0
  129. package/dist/core/dispatcher.d.ts.map +1 -0
  130. package/dist/core/dispatcher.js +76 -0
  131. package/dist/core/dispatcher.js.map +1 -0
  132. package/dist/core/errors.d.ts +8 -0
  133. package/dist/core/errors.d.ts.map +1 -0
  134. package/dist/core/errors.js +13 -0
  135. package/dist/core/errors.js.map +1 -0
  136. package/dist/core/file-ownership.d.ts +25 -0
  137. package/dist/core/file-ownership.d.ts.map +1 -0
  138. package/dist/core/file-ownership.js +81 -0
  139. package/dist/core/file-ownership.js.map +1 -0
  140. package/dist/core/index.d.ts +9 -0
  141. package/dist/core/index.d.ts.map +1 -0
  142. package/dist/core/index.js +6 -0
  143. package/dist/core/index.js.map +1 -0
  144. package/dist/core/mcp-client-pool.d.ts +9 -0
  145. package/dist/core/mcp-client-pool.d.ts.map +1 -0
  146. package/dist/core/mcp-client-pool.js +26 -0
  147. package/dist/core/mcp-client-pool.js.map +1 -0
  148. package/dist/core/mcp-client.d.ts +27 -0
  149. package/dist/core/mcp-client.d.ts.map +1 -0
  150. package/dist/core/mcp-client.js +63 -0
  151. package/dist/core/mcp-client.js.map +1 -0
  152. package/dist/core/plugin-loader.d.ts +41 -0
  153. package/dist/core/plugin-loader.d.ts.map +1 -0
  154. package/dist/core/plugin-loader.js +62 -0
  155. package/dist/core/plugin-loader.js.map +1 -0
  156. package/dist/core/plugin-sdk.d.ts +5 -0
  157. package/dist/core/plugin-sdk.d.ts.map +1 -0
  158. package/dist/core/plugin-sdk.js +2 -0
  159. package/dist/core/plugin-sdk.js.map +1 -0
  160. package/dist/core/state.d.ts +77 -0
  161. package/dist/core/state.d.ts.map +1 -0
  162. package/dist/core/state.js +357 -0
  163. package/dist/core/state.js.map +1 -0
  164. package/dist/core/task.d.ts +13 -0
  165. package/dist/core/task.d.ts.map +1 -0
  166. package/dist/core/task.js +87 -0
  167. package/dist/core/task.js.map +1 -0
  168. package/dist/git/__tests__/helpers.d.ts +3 -0
  169. package/dist/git/__tests__/helpers.d.ts.map +1 -0
  170. package/dist/git/__tests__/helpers.js +18 -0
  171. package/dist/git/__tests__/helpers.js.map +1 -0
  172. package/dist/git/branch.d.ts +7 -0
  173. package/dist/git/branch.d.ts.map +1 -0
  174. package/dist/git/branch.js +62 -0
  175. package/dist/git/branch.js.map +1 -0
  176. package/dist/git/commit.d.ts +3 -0
  177. package/dist/git/commit.d.ts.map +1 -0
  178. package/dist/git/commit.js +21 -0
  179. package/dist/git/commit.js.map +1 -0
  180. package/dist/git/conflict.d.ts +19 -0
  181. package/dist/git/conflict.d.ts.map +1 -0
  182. package/dist/git/conflict.js +86 -0
  183. package/dist/git/conflict.js.map +1 -0
  184. package/dist/git/index.d.ts +7 -0
  185. package/dist/git/index.d.ts.map +1 -0
  186. package/dist/git/index.js +7 -0
  187. package/dist/git/index.js.map +1 -0
  188. package/dist/git/merge.d.ts +16 -0
  189. package/dist/git/merge.d.ts.map +1 -0
  190. package/dist/git/merge.js +101 -0
  191. package/dist/git/merge.js.map +1 -0
  192. package/dist/git/safety.d.ts +16 -0
  193. package/dist/git/safety.d.ts.map +1 -0
  194. package/dist/git/safety.js +64 -0
  195. package/dist/git/safety.js.map +1 -0
  196. package/dist/git/utils.d.ts +8 -0
  197. package/dist/git/utils.d.ts.map +1 -0
  198. package/dist/git/utils.js +39 -0
  199. package/dist/git/utils.js.map +1 -0
  200. package/dist/mcp-server/index.d.ts +2 -0
  201. package/dist/mcp-server/index.d.ts.map +1 -0
  202. package/dist/mcp-server/index.js +39 -0
  203. package/dist/mcp-server/index.js.map +1 -0
  204. package/dist/mcp-server/tools.d.ts +70 -0
  205. package/dist/mcp-server/tools.d.ts.map +1 -0
  206. package/dist/mcp-server/tools.js +112 -0
  207. package/dist/mcp-server/tools.js.map +1 -0
  208. package/dist/models/item.d.ts +6 -0
  209. package/dist/models/item.d.ts.map +1 -0
  210. package/dist/models/item.js +2 -0
  211. package/dist/models/item.js.map +1 -0
  212. package/dist/orchestration/glue.d.ts +31 -0
  213. package/dist/orchestration/glue.d.ts.map +1 -0
  214. package/dist/orchestration/glue.js +204 -0
  215. package/dist/orchestration/glue.js.map +1 -0
  216. package/dist/orchestration/index.d.ts +3 -0
  217. package/dist/orchestration/index.d.ts.map +1 -0
  218. package/dist/orchestration/index.js +3 -0
  219. package/dist/orchestration/index.js.map +1 -0
  220. package/dist/orchestration/runtime.d.ts +35 -0
  221. package/dist/orchestration/runtime.d.ts.map +1 -0
  222. package/dist/orchestration/runtime.js +165 -0
  223. package/dist/orchestration/runtime.js.map +1 -0
  224. package/dist/providers/base-provider.d.ts +28 -0
  225. package/dist/providers/base-provider.d.ts.map +1 -0
  226. package/dist/providers/base-provider.js +2 -0
  227. package/dist/providers/base-provider.js.map +1 -0
  228. package/dist/providers/claude.d.ts +10 -0
  229. package/dist/providers/claude.d.ts.map +1 -0
  230. package/dist/providers/claude.js +93 -0
  231. package/dist/providers/claude.js.map +1 -0
  232. package/dist/providers/gemini.d.ts +16 -0
  233. package/dist/providers/gemini.d.ts.map +1 -0
  234. package/dist/providers/gemini.js +101 -0
  235. package/dist/providers/gemini.js.map +1 -0
  236. package/dist/providers/index.d.ts +21 -0
  237. package/dist/providers/index.d.ts.map +1 -0
  238. package/dist/providers/index.js +68 -0
  239. package/dist/providers/index.js.map +1 -0
  240. package/dist/providers/mcp-provider.d.ts +11 -0
  241. package/dist/providers/mcp-provider.d.ts.map +1 -0
  242. package/dist/providers/mcp-provider.js +42 -0
  243. package/dist/providers/mcp-provider.js.map +1 -0
  244. package/dist/providers/mock.d.ts +10 -0
  245. package/dist/providers/mock.d.ts.map +1 -0
  246. package/dist/providers/mock.js +66 -0
  247. package/dist/providers/mock.js.map +1 -0
  248. package/dist/providers/model-registry.d.ts +9 -0
  249. package/dist/providers/model-registry.d.ts.map +1 -0
  250. package/dist/providers/model-registry.js +153 -0
  251. package/dist/providers/model-registry.js.map +1 -0
  252. package/dist/providers/ollama.d.ts +11 -0
  253. package/dist/providers/ollama.d.ts.map +1 -0
  254. package/dist/providers/ollama.js +141 -0
  255. package/dist/providers/ollama.js.map +1 -0
  256. package/dist/providers/openai.d.ts +17 -0
  257. package/dist/providers/openai.d.ts.map +1 -0
  258. package/dist/providers/openai.js +109 -0
  259. package/dist/providers/openai.js.map +1 -0
  260. package/dist/providers/zai.d.ts +6 -0
  261. package/dist/providers/zai.d.ts.map +1 -0
  262. package/dist/providers/zai.js +17 -0
  263. package/dist/providers/zai.js.map +1 -0
  264. package/dist/server/api.d.ts +5 -0
  265. package/dist/server/api.d.ts.map +1 -0
  266. package/dist/server/api.js +153 -0
  267. package/dist/server/api.js.map +1 -0
  268. package/dist/server/index.d.ts +14 -0
  269. package/dist/server/index.d.ts.map +1 -0
  270. package/dist/server/index.js +98 -0
  271. package/dist/server/index.js.map +1 -0
  272. package/dist/server/middleware.d.ts +6 -0
  273. package/dist/server/middleware.d.ts.map +1 -0
  274. package/dist/server/middleware.js +35 -0
  275. package/dist/server/middleware.js.map +1 -0
  276. package/dist/server/tunnel.d.ts +7 -0
  277. package/dist/server/tunnel.d.ts.map +1 -0
  278. package/dist/server/tunnel.js +44 -0
  279. package/dist/server/tunnel.js.map +1 -0
  280. package/dist/server/websocket.d.ts +11 -0
  281. package/dist/server/websocket.d.ts.map +1 -0
  282. package/dist/server/websocket.js +48 -0
  283. package/dist/server/websocket.js.map +1 -0
  284. package/dist/types.d.ts +90 -0
  285. package/dist/types.d.ts.map +1 -0
  286. package/dist/types.js +2 -0
  287. package/dist/types.js.map +1 -0
  288. package/package.json +62 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
1
+ # Changelog
2
+
3
+ ## [1.0.0] — 2026-03-12
4
+
5
+ ### Added
6
+ - Live Ink TUI board selama `orka run` (auto-detect TTY, `--no-ink` untuk CI)
7
+ - Mock/demo mode (`--mock`) — test tanpa API key atau Ollama
8
+ - `orka login --provider claude|openai` — credential storage di `~/.orka/credentials.json`
9
+ - `orka logout --provider <name>`, `orka whoami`
10
+ - Claude Code credential import (best-effort)
11
+ - OpenAI/GPT-4o provider
12
+ - Error messages Bahasa Indonesia untuk semua provider errors
13
+ - `ORKA_DEBUG=1` — tampilkan stack trace lengkap
14
+ - AbortSignal support di renderBoard — board unmount bersih saat session selesai
15
+
16
+ ### Foundation (v0.x → v1.0)
17
+ - Multi-agent orchestration: Coordinator + Scout + N Builders + Reviewer
18
+ - Zero file conflict via atomic SQLite file locks
19
+ - Claude dan Ollama provider
20
+ - Auto-branch, auto-merge, rebase, conflict resolution
21
+ - `orka resume` — lanjut dari crash atau pause
22
+ - `orka rollback`, `orka cost`, `orka rules`, `orka memory`, `orka plugin`
23
+
24
+ ### Platform
25
+ macOS dan Linux. Windows tidak didukung penuh di v1.0.
@@ -0,0 +1,59 @@
1
+ # Contributing to Orka
2
+
3
+ ## Prerequisites
4
+
5
+ - Node.js v20+, npm v10+, Git
6
+ - Platform: macOS atau Linux
7
+ (Windows: `chmod 600` pada credentials.json tidak efektif — known limitation v1.0)
8
+
9
+ ## Setup
10
+
11
+ ```bash
12
+ git clone <repo>
13
+ cd orka
14
+ npm install
15
+ npm test # 270+ tests
16
+ npm run build # compile ke dist/
17
+ ```
18
+
19
+ ## Quick Demo (tanpa API key)
20
+
21
+ ```bash
22
+ npm run build
23
+ node dist/cli/index.js run "buat CRUD API" --mock
24
+ node dist/cli/index.js whoami
25
+ ```
26
+
27
+ ## Real Provider Test
28
+
29
+ ```bash
30
+ node dist/cli/index.js login --provider claude # import dari Claude Code atau masukkan API key
31
+ node dist/cli/index.js login --provider openai # masukkan sk-...
32
+ node dist/cli/index.js run "buat hello world"
33
+ ```
34
+
35
+ ## Credential Storage
36
+
37
+ Disimpan di `~/.orka/credentials.json` (chmod 600, plaintext JSON).
38
+ Known limitation v1.0: tidak pakai OS keychain. Auto-refresh direncanakan v1.1.
39
+
40
+ ## Debugging
41
+
42
+ ```bash
43
+ ORKA_DEBUG=1 node dist/cli/index.js run "test" --mock
44
+ ```
45
+
46
+ ## Commit Convention
47
+
48
+ Format: `type(scope): message`
49
+
50
+ - `feat(cli): ...` — fitur baru
51
+ - `fix(providers): ...` — bug fix
52
+ - `chore: ...` — maintenance
53
+ - `docs: ...` — dokumentasi
54
+ - `test: ...` — perubahan test
55
+
56
+ ## Branch Strategy
57
+
58
+ - `main` — stabil, langsung ke npm
59
+ - `feature/<nama>` — PR ke main
package/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # Orka
2
+
3
+ Multi-agent coding orchestration CLI. Orka mengorkestrasi AI agents untuk bekerja seperti tim engineering — Coordinator dekomposisi goal, Scout analisis codebase, Builder implementasi paralel, Reviewer jaga kualitas — semua terkoordinasi otomatis tanpa konflik file.
4
+
5
+ ```
6
+ $ orka run "build user authentication with OAuth2 and JWT"
7
+
8
+ ┌─────────────────────────────────────────────────────────┐
9
+ │ Orka — session #a3f2 │
10
+ │ Goal: Build user authentication with OAuth2 and JWT │
11
+ │ Elapsed: 2m 34s │ Tokens: 12.4k │ Cost: $0.03 │
12
+ ├──────────┬──────────────────────────┬────────┬──────────┤
13
+ │ Status │ Task │ Agent │ Files │
14
+ ├──────────┼──────────────────────────┼────────┼──────────┤
15
+ │ ✓ DONE │ Scan codebase │ scout │ — │
16
+ │ ✓ DONE │ Auth types & schemas │ bld-1 │ 3 files │
17
+ │ ◎ REVIEW│ Auth service │ bld-1 │ 2 files │
18
+ │ ⚡ BUILD │ API routes & middleware │ bld-2 │ 4 files │
19
+ │ ⏳ QUEUE │ Login & signup UI │ — │ 5 files │
20
+ └──────────┴──────────────────────────┴────────┴──────────┘
21
+ [P]ause [L]ogs [C]ost detail [Q]uit
22
+ ```
23
+
24
+ ## Fitur
25
+
26
+ - **Multi-agent paralel** — Coordinator + Scout + N Builders + Reviewer bekerja serentak
27
+ - **Zero file conflict** — file ownership via atomic SQLite lock, tidak ada dua agent edit file yang sama
28
+ - **Review gate** — setiap perubahan di-review Reviewer sebelum di-commit, max 3x retry sebelum eskalasi ke user
29
+ - **Agent-agnostic** — Claude, Ollama (gratis/lokal), OpenAI, Gemini — bisa dicampur per role
30
+ - **Git integration** — auto-branch per task, auto-merge setelah approved, rebase in-flight branches
31
+ - **Survive crash** — state di SQLite, `orka resume` lanjut dari titik terakhir
32
+ - **Cost tracking** — token dan biaya per agent, real-time di TUI
33
+
34
+ ## Instalasi
35
+
36
+ ```bash
37
+ npm install -g orka-cli
38
+ ```
39
+
40
+ Atau run tanpa install:
41
+ ```bash
42
+ npx orka-cli init
43
+ ```
44
+
45
+ **Prasyarat:** Node.js v20+, minimal satu LLM provider (API key atau Ollama)
46
+
47
+ ## Quickstart
48
+
49
+ ```bash
50
+ # Bootstrap config awal
51
+ orka init --profile ollama
52
+
53
+ # Mode core (default): goal -> scout -> coordinator -> builder/reviewer
54
+ orka run "buat CRUD endpoint untuk /api/products"
55
+
56
+ # Mode manual: pakai target file eksplisit untuk single-task run
57
+ orka run "buat CRUD endpoint untuk /api/products" --files src/api/products.ts
58
+
59
+ # Rollback ke base commit session terakhir
60
+ orka rollback
61
+
62
+ # Lihat status implementasi yang sudah tersedia
63
+ orka status
64
+ ```
65
+
66
+ ## Konfigurasi
67
+
68
+ `orka init` akan generate `orka.config.yaml` di root project. Edit manual jika perlu:
69
+
70
+ ```yaml
71
+ providers:
72
+ claude:
73
+ apiKey: ${ANTHROPIC_API_KEY} # dari environment variable
74
+ ollama:
75
+ baseUrl: http://localhost:11434
76
+
77
+ swarm:
78
+ builders: 2 # jumlah Builder agent paralel
79
+
80
+ roles:
81
+ coordinator: { provider: claude, model: claude-sonnet-4-20250514 }
82
+ scout: { provider: claude, model: claude-haiku-4-5-20251001 }
83
+ builder: { provider: ollama, model: deepseek-coder-v2 }
84
+ reviewer: { provider: claude, model: claude-sonnet-4-20250514 }
85
+
86
+ git:
87
+ auto_branch: true
88
+ auto_merge: true
89
+ commit_prefix: "[orka]"
90
+ push: false # tidak pernah push tanpa izin user
91
+ conflict_resolution: prompt # prompt | auto | manual
92
+ ```
93
+
94
+ ### Setup Hemat (semua Ollama, gratis)
95
+
96
+ ```yaml
97
+ roles:
98
+ coordinator: { provider: ollama, model: llama3 }
99
+ scout: { provider: ollama, model: llama3 }
100
+ builder: { provider: ollama, model: deepseek-coder-v2 }
101
+ reviewer: { provider: ollama, model: llama3 }
102
+ ```
103
+
104
+ ### Setup Quality (cloud untuk Coordinator & Reviewer)
105
+
106
+ ```yaml
107
+ roles:
108
+ coordinator: { provider: claude, model: claude-sonnet-4-20250514 }
109
+ scout: { provider: claude, model: claude-haiku-4-5-20251001 }
110
+ builder: { provider: ollama, model: deepseek-coder-v2 }
111
+ reviewer: { provider: claude, model: claude-sonnet-4-20250514 }
112
+ ```
113
+
114
+ ## Rules System
115
+
116
+ Buat `orka.rules.md` di root project untuk mengatur perilaku semua agent:
117
+
118
+ ```markdown
119
+ ## Code Style
120
+ - Gunakan Bahasa Indonesia untuk error messages
121
+ - Naming: camelCase untuk functions, PascalCase untuk types
122
+
123
+ ## Architecture
124
+ - Semua API routes di src/app/api/
125
+ - Pakai Zod untuk validation, bukan manual type checking
126
+ ```
127
+
128
+ Global rules (berlaku semua project): `~/.orka/rules.md`
129
+
130
+ ## Commands
131
+
132
+ ```bash
133
+ orka init # generate config dari preset
134
+ orka init --wizard # setup wizard interaktif
135
+ orka init --profile ollama # local-first preset (tanpa Claude)
136
+ orka run "goal" # auto-planning orchestration flow
137
+ orka run "goal" --files src/app.ts # manual single-task run
138
+ orka run "goal" --no-git # nonaktifkan session branch + auto-commit
139
+ orka status # tampilkan status board session terakhir
140
+ orka status --ink # status board interaktif via Ink
141
+ orka status --watch # status board live refresh (text)
142
+ orka board # tampilkan session board terakhir
143
+ orka board --watch # board mode live refresh
144
+ orka board --ink # board interaktif berbasis Ink
145
+ orka board --ink --watch # board Ink + live refresh
146
+ orka logs # activity log session terakhir
147
+ orka logs --session session-123 # filter ke session tertentu
148
+ orka logs --type task:completed # filter berdasarkan message type
149
+ orka pause # pause semua agent
150
+ orka resume # lanjut dari pause / crash
151
+ orka rollback # rollback session branch terakhir ke base commit
152
+ orka fix # resolve git conflict otomatis (LLM)
153
+ orka fix --strategy ours # pakai versi branch saat ini
154
+ orka fix --strategy theirs # pakai versi incoming branch
155
+ orka cost # token & cost summary
156
+ orka rules edit # edit orka.rules.md
157
+ orka memory show # tampilkan memory
158
+ orka memory add "catatan" # tambah entry
159
+ orka memory clear # hapus semua memory
160
+ orka plugin add my-plugin # pasang plugin ke registry lokal
161
+ orka plugin list # lihat plugin aktif
162
+ ```
163
+
164
+ ## Git Flow
165
+
166
+ Orka tidak pernah mengubah branch aktif kamu secara langsung:
167
+
168
+ ```
169
+ main (branch kamu)
170
+
171
+ └── orka/session-<timestamp> ← session branch
172
+ ├── orka/task-auth-schemas ← per-task branch (builder-1)
173
+ ├── orka/task-auth-service ← per-task branch (builder-2)
174
+ └── orka/task-api-routes ← per-task branch (builder-2)
175
+ ```
176
+
177
+ Setelah semua task approved, Orka tanya: `Merge ke main? [Y/n]`
178
+
179
+ **Safety rules:**
180
+ - Tidak pernah force push
181
+ - Tidak pernah push ke remote tanpa konfirmasi
182
+ - Merge conflict → pause + notifikasi, tidak auto-resolve diam-diam
183
+
184
+ ## Dokumentasi
185
+
186
+ - [Design Spec](docs/superpowers/specs/2026-03-11-orka-design.md) — arsitektur lengkap
187
+ - [BRD](docs/superpowers/specs/2026-03-11-brd.md) — business requirements
188
+ - [PRD](docs/superpowers/specs/2026-03-11-prd.md) — product requirements & user stories
189
+ - [ERD](docs/superpowers/specs/2026-03-11-erd.md) — database schema
190
+ - [Contributing](CONTRIBUTING.md) — setup development, commit rules, branching strategy repo
191
+
192
+ ## Roadmap
193
+
194
+ | Versi | Fitur |
195
+ |-------|-------|
196
+ | **v1.0** | Core orchestration, 4 roles, Claude + Ollama, TUI, git integration, rules, resume |
197
+ | **v1.1** | OpenAI + Gemini, smart context management, memory auto-learning, `--dry-run` |
198
+ | **v1.2** | Plugin system (custom roles, providers, hooks) |
199
+ | **v2.0** | Desktop app (Electron/Tauri) |
200
+ | **v3.0** | Web dashboard + managed cloud service |
201
+
202
+ ## Contributing
203
+
204
+ Lihat [CONTRIBUTING.md](CONTRIBUTING.md).
205
+
206
+ ## License
207
+
208
+ MIT
@@ -0,0 +1,48 @@
1
+ import type { BusMessage, MessageBus } from '../core/bus.js';
2
+ import type { StateStore } from '../core/state.js';
3
+ import { ContextManager } from '../core/context.js';
4
+ import type { ChatMessage, ChatOptions, LLMProvider, TokenUsage } from '../providers/base-provider.js';
5
+ import type { AgentRole, TaskRecord } from '../types.js';
6
+ export interface AgentResult {
7
+ success: boolean;
8
+ output: string;
9
+ }
10
+ type Subscription = {
11
+ type: string;
12
+ handler: (message: BusMessage) => void;
13
+ };
14
+ export declare abstract class BaseAgent {
15
+ readonly id: string;
16
+ protected readonly bus: MessageBus;
17
+ protected readonly provider: LLMProvider;
18
+ protected readonly store?: (Pick<StateStore, "registerAgent"> & {
19
+ recordCost?: (agentId: string, usage: TokenUsage, meta?: {
20
+ provider?: string;
21
+ model?: string;
22
+ sessionId?: string | null;
23
+ }) => void;
24
+ }) | undefined;
25
+ protected readonly sessionId?: string | undefined;
26
+ protected readonly contextManager?: ContextManager | undefined;
27
+ abstract readonly role: AgentRole;
28
+ private unsubscribers;
29
+ private usage;
30
+ constructor(id: string, bus: MessageBus, provider: LLMProvider, store?: (Pick<StateStore, "registerAgent"> & {
31
+ recordCost?: (agentId: string, usage: TokenUsage, meta?: {
32
+ provider?: string;
33
+ model?: string;
34
+ sessionId?: string | null;
35
+ }) => void;
36
+ }) | undefined, sessionId?: string | undefined, contextManager?: ContextManager | undefined);
37
+ initialize(): Promise<void>;
38
+ listen(): void;
39
+ stop(): void;
40
+ abstract execute(task: TaskRecord): Promise<AgentResult>;
41
+ abstract report(result: AgentResult): void;
42
+ protected abstract subscriptions(): Subscription[];
43
+ protected abstract systemPrompt(): string;
44
+ protected chat(messages: ChatMessage[], options?: ChatOptions): Promise<import("../providers/base-provider.js").ChatResponse>;
45
+ get totalUsage(): TokenUsage;
46
+ }
47
+ export {};
48
+ //# sourceMappingURL=base-agent.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-agent.d.ts","sourceRoot":"","sources":["../../src/agents/base-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACnD,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AACtG,OAAO,KAAK,EAAE,SAAS,EAA6B,UAAU,EAAE,MAAM,aAAa,CAAA;AAEnF,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,OAAO,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,KAAK,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,IAAI,CAAA;CAAE,CAAA;AAE5E,8BAAsB,SAAS;aAOX,EAAE,EAAE,MAAM;IAC1B,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU;IAClC,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW;IACxC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG;QAC7D,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,EACjB,IAAI,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,KACpE,IAAI,CAAA;KACV;IACD,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM;IACrC,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,cAAc;IAjBpD,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IAEjC,OAAO,CAAC,aAAa,CAAwB;IAC7C,OAAO,CAAC,KAAK,CAAkD;gBAG7C,EAAE,EAAE,MAAM,EACP,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,WAAW,EACrB,KAAK,CAAC,GAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG;QAC7D,UAAU,CAAC,EAAE,CACX,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,UAAU,EACjB,IAAI,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,KACpE,IAAI,CAAA;KACV,aAAA,EACkB,SAAS,CAAC,EAAE,MAAM,YAAA,EAClB,cAAc,CAAC,EAAE,cAAc,YAAA;IAG9C,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAejC,MAAM,IAAI,IAAI;IAOd,IAAI,IAAI,IAAI;IAQZ,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAExD,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAE1C,SAAS,CAAC,QAAQ,CAAC,aAAa,IAAI,YAAY,EAAE;IAElD,SAAS,CAAC,QAAQ,CAAC,YAAY,IAAI,MAAM;cAEzB,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW;IAanE,IAAI,UAAU,IAAI,UAAU,CAE3B;CACF"}
@@ -0,0 +1,59 @@
1
+ export class BaseAgent {
2
+ id;
3
+ bus;
4
+ provider;
5
+ store;
6
+ sessionId;
7
+ contextManager;
8
+ unsubscribers = [];
9
+ usage = { inputTokens: 0, outputTokens: 0 };
10
+ constructor(id, bus, provider, store, sessionId, contextManager) {
11
+ this.id = id;
12
+ this.bus = bus;
13
+ this.provider = provider;
14
+ this.store = store;
15
+ this.sessionId = sessionId;
16
+ this.contextManager = contextManager;
17
+ }
18
+ async initialize() {
19
+ if (!this.store) {
20
+ return;
21
+ }
22
+ this.store.registerAgent({
23
+ id: this.id,
24
+ role: this.role,
25
+ provider: this.provider.name,
26
+ model: this.provider.name,
27
+ status: 'idle',
28
+ currentTask: null,
29
+ });
30
+ }
31
+ listen() {
32
+ for (const subscription of this.subscriptions()) {
33
+ const unsubscribe = this.bus.subscribe(subscription.type, subscription.handler);
34
+ this.unsubscribers.push(unsubscribe);
35
+ }
36
+ }
37
+ stop() {
38
+ for (const unsubscribe of this.unsubscribers) {
39
+ unsubscribe();
40
+ }
41
+ this.unsubscribers = [];
42
+ }
43
+ async chat(messages, options) {
44
+ const prepared = this.contextManager ? await this.contextManager.prepare(messages) : messages;
45
+ const response = await this.provider.chat(prepared, options);
46
+ this.usage.inputTokens += response.usage.inputTokens;
47
+ this.usage.outputTokens += response.usage.outputTokens;
48
+ this.store?.recordCost?.(this.id, response.usage, {
49
+ provider: this.provider.name,
50
+ model: this.provider.name,
51
+ sessionId: this.sessionId ?? null,
52
+ });
53
+ return response;
54
+ }
55
+ get totalUsage() {
56
+ return { ...this.usage };
57
+ }
58
+ }
59
+ //# sourceMappingURL=base-agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-agent.js","sourceRoot":"","sources":["../../src/agents/base-agent.ts"],"names":[],"mappings":"AAaA,MAAM,OAAgB,SAAS;IAOX;IACG;IACA;IACA;IAOA;IACA;IAfb,aAAa,GAAsB,EAAE,CAAA;IACrC,KAAK,GAAe,EAAE,WAAW,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC,EAAE,CAAA;IAE/D,YACkB,EAAU,EACP,GAAe,EACf,QAAqB,EACrB,KAMlB,EACkB,SAAkB,EAClB,cAA+B;QAXlC,OAAE,GAAF,EAAE,CAAQ;QACP,QAAG,GAAH,GAAG,CAAY;QACf,aAAQ,GAAR,QAAQ,CAAa;QACrB,UAAK,GAAL,KAAK,CAMvB;QACkB,cAAS,GAAT,SAAS,CAAS;QAClB,mBAAc,GAAd,cAAc,CAAiB;IACjD,CAAC;IAEJ,KAAK,CAAC,UAAU;QACd,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,OAAM;QACR,CAAC;QAED,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;YACvB,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAoB;YAC5C,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YACzB,MAAM,EAAE,MAA4B;YACpC,WAAW,EAAE,IAAI;SAClB,CAAC,CAAA;IACJ,CAAC;IAED,MAAM;QACJ,KAAK,MAAM,YAAY,IAAI,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;YAChD,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,YAAY,CAAC,IAAa,EAAE,YAAY,CAAC,OAAO,CAAC,CAAA;YACxF,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;QACtC,CAAC;IACH,CAAC;IAED,IAAI;QACF,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YAC7C,WAAW,EAAE,CAAA;QACf,CAAC;QAED,IAAI,CAAC,aAAa,GAAG,EAAE,CAAA;IACzB,CAAC;IAUS,KAAK,CAAC,IAAI,CAAC,QAAuB,EAAE,OAAqB;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAA;QAC7F,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC5D,IAAI,CAAC,KAAK,CAAC,WAAW,IAAI,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAA;QACpD,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAA;QACtD,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAK,EAAE;YAChD,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YAC5B,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;YACzB,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI;SAClC,CAAC,CAAA;QACF,OAAO,QAAQ,CAAA;IACjB,CAAC;IAED,IAAI,UAAU;QACZ,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAA;IAC1B,CAAC;CACF"}
@@ -0,0 +1,53 @@
1
+ import type { BusMessage, MessageBus } from '../core/bus.js';
2
+ import type { StateStore } from '../core/state.js';
3
+ import type { LLMProvider } from '../providers/base-provider.js';
4
+ import type { AgentRole, TaskRecord } from '../types.js';
5
+ import { BaseAgent, type AgentResult } from './base-agent.js';
6
+ export interface BuilderFileOps {
7
+ isOwnedBy(filePath: string, agentId: string): boolean;
8
+ writeFile(path: string, content: string): Promise<void>;
9
+ readFile(path: string): Promise<string>;
10
+ }
11
+ interface FileChange {
12
+ path: string;
13
+ content: string;
14
+ }
15
+ export declare class BuilderAgent extends BaseAgent {
16
+ private readonly fileOps;
17
+ readonly role: AgentRole;
18
+ private codebaseBrief;
19
+ private reviewFeedback;
20
+ private currentTask;
21
+ private pendingReviews;
22
+ constructor(id: string, bus: MessageBus, provider: LLMProvider, fileOps: BuilderFileOps, store?: Pick<StateStore, 'registerAgent'> & {
23
+ recordCost?: (agentId: string, usage: {
24
+ inputTokens: number;
25
+ outputTokens: number;
26
+ }, meta?: {
27
+ provider?: string;
28
+ model?: string;
29
+ sessionId?: string | null;
30
+ }) => void;
31
+ }, sessionId?: string);
32
+ protected subscriptions(): {
33
+ type: string;
34
+ handler: (message: BusMessage) => void;
35
+ }[];
36
+ protected systemPrompt(): string;
37
+ execute(task: TaskRecord): Promise<AgentResult>;
38
+ private buildPrompt;
39
+ private extractJson;
40
+ applyChanges(agentId: string, changes: FileChange[]): Promise<{
41
+ applied: string[];
42
+ rejected: string[];
43
+ }>;
44
+ report(result: AgentResult): void;
45
+ setCodebaseBrief(brief: string): void;
46
+ setReviewFeedback(feedback: string): void;
47
+ get currentTaskId(): string | null;
48
+ addPendingReview(taskId: string): void;
49
+ removePendingReview(taskId: string): void;
50
+ get pendingReviewCount(): number;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/agents/builder.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAA;AAC5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAA;AAChE,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAE7D,MAAM,WAAW,cAAc;IAC7B,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAA;IACrD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;CACxC;AAED,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,qBAAa,YAAa,SAAQ,SAAS;IAWvC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAV1B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAY;IACpC,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,cAAc,CAAsB;IAC5C,OAAO,CAAC,WAAW,CAAsB;IACzC,OAAO,CAAC,cAAc,CAAoB;gBAGxC,EAAE,EAAE,MAAM,EACV,GAAG,EAAE,UAAU,EACf,QAAQ,EAAE,WAAW,EACJ,OAAO,EAAE,cAAc,EACxC,KAAK,CAAC,EAAE,IAAI,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG;QAC1C,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;YAAE,WAAW,EAAE,MAAM,CAAC;YAAC,YAAY,EAAE,MAAM,CAAA;SAAE,EAAE,IAAI,CAAC,EAAE;YAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;SAAE,KAAK,IAAI,CAAA;KACtK,EACD,SAAS,CAAC,EAAE,MAAM;IAKpB,SAAS,CAAC,aAAa;;2BAIE,UAAU;;IAsBnC,SAAS,CAAC,YAAY,IAAI,MAAM;IAc1B,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAwBrD,OAAO,CAAC,WAAW;IAWnB,OAAO,CAAC,WAAW;IAoBb,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAgB9G,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAajC,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAIrC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIzC,IAAI,aAAa,IAAI,MAAM,GAAG,IAAI,CAEjC;IAED,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAItC,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAIzC,IAAI,kBAAkB,IAAI,MAAM,CAE/B;CACF"}
@@ -0,0 +1,147 @@
1
+ import { BaseAgent } from './base-agent.js';
2
+ export class BuilderAgent extends BaseAgent {
3
+ fileOps;
4
+ role = 'builder';
5
+ codebaseBrief = null;
6
+ reviewFeedback = null;
7
+ currentTask = null;
8
+ pendingReviews = new Set();
9
+ constructor(id, bus, provider, fileOps, store, sessionId) {
10
+ super(id, bus, provider, store, sessionId);
11
+ this.fileOps = fileOps;
12
+ }
13
+ subscriptions() {
14
+ return [
15
+ {
16
+ type: 'task:assigned',
17
+ handler: (message) => {
18
+ if (message.payload.target === this.id) {
19
+ this.bus.publish({
20
+ type: 'agent:status',
21
+ agentId: this.id,
22
+ payload: { status: 'building', taskId: message.taskId },
23
+ timestamp: Date.now(),
24
+ });
25
+ }
26
+ },
27
+ },
28
+ {
29
+ type: 'task:rejected',
30
+ handler: (message) => {
31
+ if (message.payload.builder === this.id) {
32
+ this.reviewFeedback = message.payload.feedback;
33
+ }
34
+ },
35
+ },
36
+ ];
37
+ }
38
+ systemPrompt() {
39
+ let prompt = `You are a Builder agent — a senior software engineer.
40
+ Your job is to implement code changes for a given task.
41
+ Output your changes as JSON: { "files": [{ "path": "...", "content": "..." }] }
42
+ Only modify files that you have been assigned ownership of.
43
+ Ensure code is correct, follows project conventions, and handles edge cases.`;
44
+ if (this.codebaseBrief) {
45
+ prompt += `\n\nCodebase Brief:\n${this.codebaseBrief}`;
46
+ }
47
+ return prompt;
48
+ }
49
+ async execute(task) {
50
+ this.currentTask = task.id;
51
+ const response = await this.chat([
52
+ { role: 'system', content: this.systemPrompt() },
53
+ { role: 'user', content: this.buildPrompt(task) },
54
+ ]);
55
+ try {
56
+ const parsed = this.extractJson(response.content);
57
+ if (parsed?.files?.length) {
58
+ const result = await this.applyChanges(this.id, parsed.files);
59
+ return {
60
+ success: result.rejected.length === 0,
61
+ output: response.content,
62
+ };
63
+ }
64
+ }
65
+ catch {
66
+ return { success: true, output: response.content };
67
+ }
68
+ return { success: true, output: response.content };
69
+ }
70
+ buildPrompt(task) {
71
+ let prompt = `Task: ${task.goal}\n\nOwned files:\n${task.filesOwned.join('\n')}`;
72
+ if (this.reviewFeedback) {
73
+ prompt += `\n\nPrevious review feedback (attempt ${task.reviewAttempts}):\n${this.reviewFeedback}`;
74
+ this.reviewFeedback = null;
75
+ }
76
+ return prompt;
77
+ }
78
+ extractJson(content) {
79
+ // Strategy 1: content is pure JSON
80
+ try {
81
+ return JSON.parse(content.trim());
82
+ }
83
+ catch { /* continue */ }
84
+ // Strategy 2: JSON inside a ```json ... ``` fence (anywhere in the response)
85
+ const fenceMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/i);
86
+ if (fenceMatch) {
87
+ try {
88
+ return JSON.parse(fenceMatch[1].trim());
89
+ }
90
+ catch { /* continue */ }
91
+ }
92
+ // Strategy 3: find first { to last } (handles text before/after JSON)
93
+ const start = content.indexOf('{');
94
+ const end = content.lastIndexOf('}');
95
+ if (start !== -1 && end > start) {
96
+ try {
97
+ return JSON.parse(content.slice(start, end + 1));
98
+ }
99
+ catch { /* continue */ }
100
+ }
101
+ return null;
102
+ }
103
+ async applyChanges(agentId, changes) {
104
+ const applied = [];
105
+ const rejected = [];
106
+ for (const change of changes) {
107
+ if (this.fileOps.isOwnedBy(change.path, agentId)) {
108
+ await this.fileOps.writeFile(change.path, change.content);
109
+ applied.push(change.path);
110
+ }
111
+ else {
112
+ rejected.push(change.path);
113
+ }
114
+ }
115
+ return { applied, rejected };
116
+ }
117
+ report(result) {
118
+ const taskId = this.currentTask;
119
+ this.currentTask = null;
120
+ this.bus.publish({
121
+ type: 'task:completed',
122
+ agentId: this.id,
123
+ taskId: taskId ?? undefined,
124
+ payload: { output: result.output },
125
+ timestamp: Date.now(),
126
+ });
127
+ }
128
+ setCodebaseBrief(brief) {
129
+ this.codebaseBrief = brief;
130
+ }
131
+ setReviewFeedback(feedback) {
132
+ this.reviewFeedback = feedback;
133
+ }
134
+ get currentTaskId() {
135
+ return this.currentTask;
136
+ }
137
+ addPendingReview(taskId) {
138
+ this.pendingReviews.add(taskId);
139
+ }
140
+ removePendingReview(taskId) {
141
+ this.pendingReviews.delete(taskId);
142
+ }
143
+ get pendingReviewCount() {
144
+ return this.pendingReviews.size;
145
+ }
146
+ }
147
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/agents/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { BusMessage, MessageBus } from '../core/bus.js';
2
+ import type { StateStore } from '../core/state.js';
3
+ import type { LLMProvider } from '../providers/base-provider.js';
4
+ import type { AgentRole, TaskRecord } from '../types.js';
5
+ import { BaseAgent, type AgentResult } from './base-agent.js';
6
+ interface DecomposedTask {
7
+ id: string;
8
+ goal: string;
9
+ dependencies: string[];
10
+ files: string[];
11
+ }
12
+ interface FileConflict {
13
+ file: string;
14
+ tasks: string[];
15
+ }
16
+ type CostStore = Pick<StateStore, 'registerAgent'> & {
17
+ recordCost?: (agentId: string, usage: {
18
+ inputTokens: number;
19
+ outputTokens: number;
20
+ }, meta?: {
21
+ provider?: string;
22
+ model?: string;
23
+ sessionId?: string | null;
24
+ }) => void;
25
+ };
26
+ export declare class CoordinatorAgent extends BaseAgent {
27
+ readonly role: AgentRole;
28
+ private codebaseBrief;
29
+ constructor(id: string, bus: MessageBus, provider: LLMProvider, store?: CostStore, sessionId?: string);
30
+ protected subscriptions(): {
31
+ type: string;
32
+ handler: (message: BusMessage) => void;
33
+ }[];
34
+ protected systemPrompt(): string;
35
+ execute(task: TaskRecord): Promise<AgentResult>;
36
+ decompose(goal: string): Promise<DecomposedTask[]>;
37
+ detectFileConflicts(tasks: DecomposedTask[]): FileConflict[];
38
+ resolveConflicts(tasks: DecomposedTask[]): DecomposedTask[];
39
+ toTaskRecords(tasks: DecomposedTask[], sessionId: string): TaskRecord[];
40
+ startSession(sessionId: string, goal: string): void;
41
+ report(result: AgentResult): void;
42
+ setCodebaseBrief(brief: string): void;
43
+ }
44
+ export {};
45
+ //# sourceMappingURL=coordinator.d.ts.map