aura-code 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 (288) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +137 -0
  3. package/dist/agent/context.d.ts +13 -0
  4. package/dist/agent/context.js +183 -0
  5. package/dist/agent/context.js.map +1 -0
  6. package/dist/agent/loop.d.ts +60 -0
  7. package/dist/agent/loop.js +228 -0
  8. package/dist/agent/loop.js.map +1 -0
  9. package/dist/agent/session-store.d.ts +30 -0
  10. package/dist/agent/session-store.js +178 -0
  11. package/dist/agent/session-store.js.map +1 -0
  12. package/dist/agent/spawner.d.ts +57 -0
  13. package/dist/agent/spawner.js +112 -0
  14. package/dist/agent/spawner.js.map +1 -0
  15. package/dist/agent/system-prompt.d.ts +3 -0
  16. package/dist/agent/system-prompt.js +100 -0
  17. package/dist/agent/system-prompt.js.map +1 -0
  18. package/dist/architect/engine.d.ts +47 -0
  19. package/dist/architect/engine.js +217 -0
  20. package/dist/architect/engine.js.map +1 -0
  21. package/dist/architect/types.d.ts +61 -0
  22. package/dist/architect/types.js +6 -0
  23. package/dist/architect/types.js.map +1 -0
  24. package/dist/cli/diamond.d.ts +1 -0
  25. package/dist/cli/diamond.js +23 -0
  26. package/dist/cli/diamond.js.map +1 -0
  27. package/dist/cli/display.d.ts +44 -0
  28. package/dist/cli/display.js +234 -0
  29. package/dist/cli/display.js.map +1 -0
  30. package/dist/cli/index.d.ts +2 -0
  31. package/dist/cli/index.js +1734 -0
  32. package/dist/cli/index.js.map +1 -0
  33. package/dist/config/defaults.d.ts +46 -0
  34. package/dist/config/defaults.js +106 -0
  35. package/dist/config/defaults.js.map +1 -0
  36. package/dist/config/project-config.d.ts +90 -0
  37. package/dist/config/project-config.js +141 -0
  38. package/dist/config/project-config.js.map +1 -0
  39. package/dist/harness/proposer.d.ts +26 -0
  40. package/dist/harness/proposer.js +204 -0
  41. package/dist/harness/proposer.js.map +1 -0
  42. package/dist/harness/weakness-miner.d.ts +28 -0
  43. package/dist/harness/weakness-miner.js +359 -0
  44. package/dist/harness/weakness-miner.js.map +1 -0
  45. package/dist/integrations/harnesses.d.ts +23 -0
  46. package/dist/integrations/harnesses.js +161 -0
  47. package/dist/integrations/harnesses.js.map +1 -0
  48. package/dist/orchestration/competence.d.ts +53 -0
  49. package/dist/orchestration/competence.js +181 -0
  50. package/dist/orchestration/competence.js.map +1 -0
  51. package/dist/orchestration/executor.d.ts +42 -0
  52. package/dist/orchestration/executor.js +206 -0
  53. package/dist/orchestration/executor.js.map +1 -0
  54. package/dist/orchestration/index.d.ts +20 -0
  55. package/dist/orchestration/index.js +39 -0
  56. package/dist/orchestration/index.js.map +1 -0
  57. package/dist/orchestration/orchestrator-prompts.d.ts +11 -0
  58. package/dist/orchestration/orchestrator-prompts.js +153 -0
  59. package/dist/orchestration/orchestrator-prompts.js.map +1 -0
  60. package/dist/orchestration/orchestrator.d.ts +27 -0
  61. package/dist/orchestration/orchestrator.js +169 -0
  62. package/dist/orchestration/orchestrator.js.map +1 -0
  63. package/dist/orchestration/plan-store.d.ts +53 -0
  64. package/dist/orchestration/plan-store.js +176 -0
  65. package/dist/orchestration/plan-store.js.map +1 -0
  66. package/dist/orchestration/router-prompts.d.ts +6 -0
  67. package/dist/orchestration/router-prompts.js +55 -0
  68. package/dist/orchestration/router-prompts.js.map +1 -0
  69. package/dist/orchestration/router.d.ts +23 -0
  70. package/dist/orchestration/router.js +70 -0
  71. package/dist/orchestration/router.js.map +1 -0
  72. package/dist/orchestration/ruby-detect.d.ts +6 -0
  73. package/dist/orchestration/ruby-detect.js +130 -0
  74. package/dist/orchestration/ruby-detect.js.map +1 -0
  75. package/dist/orchestration/ruby-types.d.ts +44 -0
  76. package/dist/orchestration/ruby-types.js +6 -0
  77. package/dist/orchestration/ruby-types.js.map +1 -0
  78. package/dist/orchestration/specialist-prompts.d.ts +19 -0
  79. package/dist/orchestration/specialist-prompts.js +143 -0
  80. package/dist/orchestration/specialist-prompts.js.map +1 -0
  81. package/dist/orchestration/specialists.d.ts +66 -0
  82. package/dist/orchestration/specialists.js +175 -0
  83. package/dist/orchestration/specialists.js.map +1 -0
  84. package/dist/orchestration/types.d.ts +82 -0
  85. package/dist/orchestration/types.js +6 -0
  86. package/dist/orchestration/types.js.map +1 -0
  87. package/dist/perception/extractor.d.ts +7 -0
  88. package/dist/perception/extractor.js +521 -0
  89. package/dist/perception/extractor.js.map +1 -0
  90. package/dist/perception/graph-store.d.ts +25 -0
  91. package/dist/perception/graph-store.js +117 -0
  92. package/dist/perception/graph-store.js.map +1 -0
  93. package/dist/perception/index.d.ts +4 -0
  94. package/dist/perception/index.js +18 -0
  95. package/dist/perception/index.js.map +1 -0
  96. package/dist/perception/queries.d.ts +29 -0
  97. package/dist/perception/queries.js +354 -0
  98. package/dist/perception/queries.js.map +1 -0
  99. package/dist/perception/types.d.ts +103 -0
  100. package/dist/perception/types.js +6 -0
  101. package/dist/perception/types.js.map +1 -0
  102. package/dist/providers/anthropic.d.ts +11 -0
  103. package/dist/providers/anthropic.js +172 -0
  104. package/dist/providers/anthropic.js.map +1 -0
  105. package/dist/providers/factory.d.ts +58 -0
  106. package/dist/providers/factory.js +354 -0
  107. package/dist/providers/factory.js.map +1 -0
  108. package/dist/providers/fallback.d.ts +24 -0
  109. package/dist/providers/fallback.js +72 -0
  110. package/dist/providers/fallback.js.map +1 -0
  111. package/dist/providers/google.d.ts +11 -0
  112. package/dist/providers/google.js +129 -0
  113. package/dist/providers/google.js.map +1 -0
  114. package/dist/providers/openai-compatible.d.ts +24 -0
  115. package/dist/providers/openai-compatible.js +216 -0
  116. package/dist/providers/openai-compatible.js.map +1 -0
  117. package/dist/providers/resilient-factory.d.ts +24 -0
  118. package/dist/providers/resilient-factory.js +57 -0
  119. package/dist/providers/resilient-factory.js.map +1 -0
  120. package/dist/providers/resilient.d.ts +63 -0
  121. package/dist/providers/resilient.js +145 -0
  122. package/dist/providers/resilient.js.map +1 -0
  123. package/dist/providers/types.d.ts +84 -0
  124. package/dist/providers/types.js +6 -0
  125. package/dist/providers/types.js.map +1 -0
  126. package/dist/ruby/alternator.d.ts +40 -0
  127. package/dist/ruby/alternator.js +233 -0
  128. package/dist/ruby/alternator.js.map +1 -0
  129. package/dist/ruby/competence.d.ts +34 -0
  130. package/dist/ruby/competence.js +264 -0
  131. package/dist/ruby/competence.js.map +1 -0
  132. package/dist/ruby/episode-capture.d.ts +56 -0
  133. package/dist/ruby/episode-capture.js +193 -0
  134. package/dist/ruby/episode-capture.js.map +1 -0
  135. package/dist/ruby/fine-tune.d.ts +16 -0
  136. package/dist/ruby/fine-tune.js +253 -0
  137. package/dist/ruby/fine-tune.js.map +1 -0
  138. package/dist/ruby/index.d.ts +10 -0
  139. package/dist/ruby/index.js +26 -0
  140. package/dist/ruby/index.js.map +1 -0
  141. package/dist/ruby/ruby-model.d.ts +36 -0
  142. package/dist/ruby/ruby-model.js +81 -0
  143. package/dist/ruby/ruby-model.js.map +1 -0
  144. package/dist/ruby/training-data.d.ts +11 -0
  145. package/dist/ruby/training-data.js +107 -0
  146. package/dist/ruby/training-data.js.map +1 -0
  147. package/dist/ruby/types.d.ts +136 -0
  148. package/dist/ruby/types.js +20 -0
  149. package/dist/ruby/types.js.map +1 -0
  150. package/dist/safety/permissions.d.ts +32 -0
  151. package/dist/safety/permissions.js +304 -0
  152. package/dist/safety/permissions.js.map +1 -0
  153. package/dist/server/index.d.ts +9 -0
  154. package/dist/server/index.js +342 -0
  155. package/dist/server/index.js.map +1 -0
  156. package/dist/server/session.d.ts +22 -0
  157. package/dist/server/session.js +16 -0
  158. package/dist/server/session.js.map +1 -0
  159. package/dist/setup/first-run.d.ts +41 -0
  160. package/dist/setup/first-run.js +386 -0
  161. package/dist/setup/first-run.js.map +1 -0
  162. package/dist/setup/global-config.d.ts +19 -0
  163. package/dist/setup/global-config.js +97 -0
  164. package/dist/setup/global-config.js.map +1 -0
  165. package/dist/tools/audio-transcribe.d.ts +8 -0
  166. package/dist/tools/audio-transcribe.js +156 -0
  167. package/dist/tools/audio-transcribe.js.map +1 -0
  168. package/dist/tools/browser.d.ts +15 -0
  169. package/dist/tools/browser.js +241 -0
  170. package/dist/tools/browser.js.map +1 -0
  171. package/dist/tools/calendar.d.ts +12 -0
  172. package/dist/tools/calendar.js +196 -0
  173. package/dist/tools/calendar.js.map +1 -0
  174. package/dist/tools/clipboard.d.ts +7 -0
  175. package/dist/tools/clipboard.js +90 -0
  176. package/dist/tools/clipboard.js.map +1 -0
  177. package/dist/tools/cron.d.ts +10 -0
  178. package/dist/tools/cron.js +167 -0
  179. package/dist/tools/cron.js.map +1 -0
  180. package/dist/tools/edit-file.d.ts +6 -0
  181. package/dist/tools/edit-file.js +98 -0
  182. package/dist/tools/edit-file.js.map +1 -0
  183. package/dist/tools/email.d.ts +11 -0
  184. package/dist/tools/email.js +153 -0
  185. package/dist/tools/email.js.map +1 -0
  186. package/dist/tools/git.d.ts +1 -0
  187. package/dist/tools/git.js +7 -0
  188. package/dist/tools/git.js.map +1 -0
  189. package/dist/tools/http-request.d.ts +12 -0
  190. package/dist/tools/http-request.js +91 -0
  191. package/dist/tools/http-request.js.map +1 -0
  192. package/dist/tools/image-read.d.ts +7 -0
  193. package/dist/tools/image-read.js +125 -0
  194. package/dist/tools/image-read.js.map +1 -0
  195. package/dist/tools/index.d.ts +3 -0
  196. package/dist/tools/index.js +201 -0
  197. package/dist/tools/index.js.map +1 -0
  198. package/dist/tools/list-dir.d.ts +1 -0
  199. package/dist/tools/list-dir.js +6 -0
  200. package/dist/tools/list-dir.js.map +1 -0
  201. package/dist/tools/mcp.d.ts +11 -0
  202. package/dist/tools/mcp.js +356 -0
  203. package/dist/tools/mcp.js.map +1 -0
  204. package/dist/tools/memory.d.ts +9 -0
  205. package/dist/tools/memory.js +124 -0
  206. package/dist/tools/memory.js.map +1 -0
  207. package/dist/tools/notify.d.ts +9 -0
  208. package/dist/tools/notify.js +40 -0
  209. package/dist/tools/notify.js.map +1 -0
  210. package/dist/tools/read-file.d.ts +6 -0
  211. package/dist/tools/read-file.js +76 -0
  212. package/dist/tools/read-file.js.map +1 -0
  213. package/dist/tools/run-shell.d.ts +1 -0
  214. package/dist/tools/run-shell.js +6 -0
  215. package/dist/tools/run-shell.js.map +1 -0
  216. package/dist/tools/run-tests.d.ts +1 -0
  217. package/dist/tools/run-tests.js +6 -0
  218. package/dist/tools/run-tests.js.map +1 -0
  219. package/dist/tools/search-code.d.ts +1 -0
  220. package/dist/tools/search-code.js +6 -0
  221. package/dist/tools/search-code.js.map +1 -0
  222. package/dist/tools/telegram-bot.d.ts +2 -0
  223. package/dist/tools/telegram-bot.js +693 -0
  224. package/dist/tools/telegram-bot.js.map +1 -0
  225. package/dist/tools/telegram-safety.d.ts +52 -0
  226. package/dist/tools/telegram-safety.js +189 -0
  227. package/dist/tools/telegram-safety.js.map +1 -0
  228. package/dist/tools/telegram.d.ts +16 -0
  229. package/dist/tools/telegram.js +227 -0
  230. package/dist/tools/telegram.js.map +1 -0
  231. package/dist/tools/tools.d.ts +48 -0
  232. package/dist/tools/tools.js +328 -0
  233. package/dist/tools/tools.js.map +1 -0
  234. package/dist/tools/web-fetch.d.ts +11 -0
  235. package/dist/tools/web-fetch.js +119 -0
  236. package/dist/tools/web-fetch.js.map +1 -0
  237. package/dist/tools/web-search.d.ts +8 -0
  238. package/dist/tools/web-search.js +81 -0
  239. package/dist/tools/web-search.js.map +1 -0
  240. package/dist/tools/whatsapp.d.ts +10 -0
  241. package/dist/tools/whatsapp.js +222 -0
  242. package/dist/tools/whatsapp.js.map +1 -0
  243. package/dist/tools/write-file.d.ts +1 -0
  244. package/dist/tools/write-file.js +6 -0
  245. package/dist/tools/write-file.js.map +1 -0
  246. package/dist/tools/youtube-transcript.d.ts +9 -0
  247. package/dist/tools/youtube-transcript.js +200 -0
  248. package/dist/tools/youtube-transcript.js.map +1 -0
  249. package/dist/util/circuit-breaker.d.ts +44 -0
  250. package/dist/util/circuit-breaker.js +78 -0
  251. package/dist/util/circuit-breaker.js.map +1 -0
  252. package/dist/util/env.d.ts +18 -0
  253. package/dist/util/env.js +39 -0
  254. package/dist/util/env.js.map +1 -0
  255. package/dist/util/errors.d.ts +42 -0
  256. package/dist/util/errors.js +121 -0
  257. package/dist/util/errors.js.map +1 -0
  258. package/dist/util/rate-limiter.d.ts +71 -0
  259. package/dist/util/rate-limiter.js +141 -0
  260. package/dist/util/rate-limiter.js.map +1 -0
  261. package/dist/util/retry.d.ts +30 -0
  262. package/dist/util/retry.js +57 -0
  263. package/dist/util/retry.js.map +1 -0
  264. package/dist/util/sanitize.d.ts +16 -0
  265. package/dist/util/sanitize.js +255 -0
  266. package/dist/util/sanitize.js.map +1 -0
  267. package/dist/verify/checks.d.ts +21 -0
  268. package/dist/verify/checks.js +311 -0
  269. package/dist/verify/checks.js.map +1 -0
  270. package/dist/verify/index.d.ts +33 -0
  271. package/dist/verify/index.js +127 -0
  272. package/dist/verify/index.js.map +1 -0
  273. package/dist/verify/types.d.ts +20 -0
  274. package/dist/verify/types.js +3 -0
  275. package/dist/verify/types.js.map +1 -0
  276. package/dist/versioncheck.d.ts +22 -0
  277. package/dist/versioncheck.js +203 -0
  278. package/dist/versioncheck.js.map +1 -0
  279. package/dist/viz/index.d.ts +2 -0
  280. package/dist/viz/index.js +733 -0
  281. package/dist/viz/index.js.map +1 -0
  282. package/dist/workflows/engine.d.ts +46 -0
  283. package/dist/workflows/engine.js +320 -0
  284. package/dist/workflows/engine.js.map +1 -0
  285. package/dist/workflows/types.d.ts +92 -0
  286. package/dist/workflows/types.js +6 -0
  287. package/dist/workflows/types.js.map +1 -0
  288. package/package.json +86 -0
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getHarnessStatus = getHarnessStatus;
37
+ exports.getHermesStatus = getHermesStatus;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const child_process_1 = require("child_process");
41
+ const HERMES_HOME = process.env.HERMES_HOME ?? '/home/dusanmilosavljevic/.hermes';
42
+ const HERMES_WORKSPACE = process.env.HERMES_WORKSPACE ?? '/home/dusanmilosavljevic/hermes-workspace';
43
+ const harnesses = [
44
+ {
45
+ id: 'opencode',
46
+ name: 'OpenCode',
47
+ command: 'opencode',
48
+ role: 'External terminal coding agent for project-level coding tasks.',
49
+ notes: ['Use as an alternate coding backend.', 'Ruby should pass a project cwd and a bounded prompt.'],
50
+ },
51
+ {
52
+ id: 'openclaude',
53
+ name: 'OpenClaude',
54
+ command: 'openclaude',
55
+ role: 'Claude-style CLI harness for coding and conversational work.',
56
+ notes: ['Useful as a Claude-compatible fallback.', 'Keep secrets in env/config, not in prompts.'],
57
+ },
58
+ {
59
+ id: 'antigravity',
60
+ name: 'Antigravity CLI',
61
+ command: 'agy',
62
+ role: 'Agentic workspace harness with project boundaries, permissions and background workflows.',
63
+ notes: ['Best treated as a workspace runner.', 'Ruby can inspect availability first, then expose launch actions.'],
64
+ },
65
+ {
66
+ id: 'pi',
67
+ name: 'Pi CLI',
68
+ command: 'pi',
69
+ role: 'General AI CLI/client available on this machine.',
70
+ notes: ['Useful for conversational or lightweight delegated tasks.', 'Adapter should stay optional until command contract is confirmed.'],
71
+ },
72
+ {
73
+ id: 'ollama',
74
+ name: 'Ollama',
75
+ command: 'ollama',
76
+ role: 'Local model runtime for offline/local inference.',
77
+ notes: ['Provider already supports ollama/* models.', 'Status may be available even when daemon is stopped.'],
78
+ },
79
+ ];
80
+ function getHarnessStatus() {
81
+ return harnesses.map((h) => {
82
+ const found = which(h.command);
83
+ if (!found)
84
+ return { ...h, status: 'missing', notes: [...h.notes, 'Command not found in PATH.'] };
85
+ const version = getVersion(h.command);
86
+ return {
87
+ ...h,
88
+ status: version ? 'available' : 'partial',
89
+ path: found,
90
+ version: version ?? 'installed, version unavailable',
91
+ };
92
+ });
93
+ }
94
+ function getHermesStatus() {
95
+ const homeExists = fs.existsSync(HERMES_HOME);
96
+ const workspaceExists = fs.existsSync(HERMES_WORKSPACE);
97
+ const scriptsDir = path.join(HERMES_HOME, 'scripts');
98
+ const skillsDir = path.join(HERMES_HOME, 'skills');
99
+ const scripts = listFiles(scriptsDir, ['.py', '.sh', '.js', '.ts']).slice(0, 24);
100
+ const skills = listSkillNames(skillsDir);
101
+ return {
102
+ home: HERMES_HOME,
103
+ workspace: HERMES_WORKSPACE,
104
+ homeExists,
105
+ workspaceExists,
106
+ scripts,
107
+ skills: skills.slice(0, 36),
108
+ skillCount: skills.length,
109
+ processStateExists: fs.existsSync(path.join(HERMES_HOME, 'processes.json')),
110
+ gatewayStateExists: fs.existsSync(path.join(HERMES_HOME, 'gateway_state.json')),
111
+ };
112
+ }
113
+ function which(command) {
114
+ try {
115
+ return (0, child_process_1.execFileSync)('which', [command], { encoding: 'utf8', timeout: 3000 }).trim() || undefined;
116
+ }
117
+ catch {
118
+ return undefined;
119
+ }
120
+ }
121
+ function getVersion(command) {
122
+ for (const args of [['--version'], ['version'], ['-v']]) {
123
+ try {
124
+ const out = (0, child_process_1.execFileSync)(command, args, { encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'pipe'] });
125
+ const version = out.trim().split('\n')[0]?.trim();
126
+ if (version)
127
+ return version;
128
+ }
129
+ catch {
130
+ // Try the next conventional version flag.
131
+ }
132
+ }
133
+ return undefined;
134
+ }
135
+ function listFiles(dir, extensions) {
136
+ if (!fs.existsSync(dir))
137
+ return [];
138
+ try {
139
+ return fs.readdirSync(dir, { withFileTypes: true })
140
+ .filter((entry) => entry.isFile() && extensions.some((ext) => entry.name.endsWith(ext)))
141
+ .map((entry) => entry.name)
142
+ .sort();
143
+ }
144
+ catch {
145
+ return [];
146
+ }
147
+ }
148
+ function listSkillNames(dir) {
149
+ if (!fs.existsSync(dir))
150
+ return [];
151
+ try {
152
+ return fs.readdirSync(dir, { withFileTypes: true })
153
+ .filter((entry) => entry.isDirectory() && !entry.name.startsWith('.'))
154
+ .map((entry) => entry.name)
155
+ .sort();
156
+ }
157
+ catch {
158
+ return [];
159
+ }
160
+ }
161
+ //# sourceMappingURL=harnesses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"harnesses.js","sourceRoot":"","sources":["../../src/integrations/harnesses.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { PlanStep } from './types.js';
2
+ export type SpecialistRole = PlanStep['specialist'];
3
+ /**
4
+ * Task domains used to score which specialist performs best.
5
+ * Maps loosely to PlanStep.specialist roles but allows finer routing.
6
+ */
7
+ export type CompetenceDomain = 'research' | 'implementation' | 'review' | 'planning' | 'ruby_gems' | 'ruby_tests' | 'refactor';
8
+ /** A single specialist's score in one domain, learned over time. */
9
+ export interface CompetenceScore {
10
+ specialist: SpecialistRole;
11
+ domain: CompetenceDomain;
12
+ /** Performance estimate in [0, 1]. */
13
+ score: number;
14
+ /** Number of step outcomes that contributed to this score. */
15
+ sampleCount: number;
16
+ /** Unix timestamp (ms) of the last update. */
17
+ lastUpdated: number;
18
+ }
19
+ /** Per-project competence profile persisted on disk. */
20
+ export interface ProjectCompetence {
21
+ projectRoot: string;
22
+ scores: CompetenceScore[];
23
+ version: 1;
24
+ }
25
+ /** Outcome signal fed back after a plan step finishes. */
26
+ export interface StepOutcome {
27
+ specialist: SpecialistRole;
28
+ domain: CompetenceDomain;
29
+ /** Whether the step reached `done` (not `failed` or `skipped`). */
30
+ success: boolean;
31
+ /** Optional normalised quality in [0, 1] from reviewer or heuristics. */
32
+ quality?: number;
33
+ }
34
+ /** Maps each specialist role to its primary competence domain. */
35
+ export declare const PRIMARY_DOMAIN: Record<SpecialistRole, CompetenceDomain>;
36
+ /** Builds the initial competence matrix from role priors. */
37
+ export declare function defaultCompetenceMatrix(): CompetenceScore[];
38
+ /**
39
+ * Returns the best specialist for a domain using stored scores, falling back to
40
+ * priors when no project profile exists.
41
+ */
42
+ export declare function recommendSpecialist(domain: CompetenceDomain, scores: CompetenceScore[]): SpecialistRole;
43
+ /**
44
+ * Exponential moving average update for one (specialist, domain) pair.
45
+ * `alpha` controls learning rate (higher = more weight on latest outcome).
46
+ */
47
+ export declare function applyOutcome(scores: CompetenceScore[], outcome: StepOutcome, alpha?: number): CompetenceScore[];
48
+ export declare const competenceStore: {
49
+ filePath(projectRoot: string): string;
50
+ load(projectRoot: string): Promise<ProjectCompetence>;
51
+ save(profile: ProjectCompetence): Promise<void>;
52
+ recordOutcome(projectRoot: string, outcome: StepOutcome): Promise<ProjectCompetence>;
53
+ };
@@ -0,0 +1,181 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.competenceStore = exports.PRIMARY_DOMAIN = void 0;
37
+ exports.defaultCompetenceMatrix = defaultCompetenceMatrix;
38
+ exports.recommendSpecialist = recommendSpecialist;
39
+ exports.applyOutcome = applyOutcome;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ // ─────────────────────────────────────────────────────────────────────────────
43
+ // Defaults — prior beliefs before any project-specific learning
44
+ // ─────────────────────────────────────────────────────────────────────────────
45
+ const DEFAULT_PRIORS = {
46
+ researcher: { research: 0.9, implementation: 0.4, ruby_gems: 0.6, refactor: 0.5 },
47
+ coder: { implementation: 0.9, ruby_gems: 0.85, ruby_tests: 0.7, refactor: 0.8, research: 0.35 },
48
+ reviewer: { review: 0.95, implementation: 0.5, refactor: 0.6 },
49
+ planner: { planning: 0.95, research: 0.7, refactor: 0.55 },
50
+ };
51
+ /** Maps each specialist role to its primary competence domain. */
52
+ exports.PRIMARY_DOMAIN = {
53
+ researcher: 'research',
54
+ coder: 'implementation',
55
+ reviewer: 'review',
56
+ planner: 'planning',
57
+ };
58
+ function key(specialist, domain) {
59
+ return `${specialist}:${domain}`;
60
+ }
61
+ function clamp01(n) {
62
+ return Math.max(0, Math.min(1, n));
63
+ }
64
+ /** Builds the initial competence matrix from role priors. */
65
+ function defaultCompetenceMatrix() {
66
+ const scores = [];
67
+ const now = Date.now();
68
+ for (const specialist of Object.keys(DEFAULT_PRIORS)) {
69
+ for (const [domain, score] of Object.entries(DEFAULT_PRIORS[specialist])) {
70
+ scores.push({
71
+ specialist,
72
+ domain: domain,
73
+ score: score,
74
+ sampleCount: 0,
75
+ lastUpdated: now,
76
+ });
77
+ }
78
+ }
79
+ return scores;
80
+ }
81
+ /**
82
+ * Returns the best specialist for a domain using stored scores, falling back to
83
+ * priors when no project profile exists.
84
+ */
85
+ function recommendSpecialist(domain, scores) {
86
+ const candidates = scores.filter(s => s.domain === domain);
87
+ if (candidates.length === 0) {
88
+ const fallback = Object.entries(exports.PRIMARY_DOMAIN)
89
+ .find(([, d]) => d === domain);
90
+ if (fallback)
91
+ return fallback[0];
92
+ return 'coder';
93
+ }
94
+ const best = candidates.reduce((a, b) => (a.score >= b.score ? a : b));
95
+ return best.specialist;
96
+ }
97
+ /**
98
+ * Exponential moving average update for one (specialist, domain) pair.
99
+ * `alpha` controls learning rate (higher = more weight on latest outcome).
100
+ */
101
+ function applyOutcome(scores, outcome, alpha = 0.15) {
102
+ const signal = outcome.success
103
+ ? clamp01(outcome.quality ?? 1)
104
+ : clamp01((outcome.quality ?? 0) * 0.25);
105
+ const now = Date.now();
106
+ const k = key(outcome.specialist, outcome.domain);
107
+ const idx = scores.findIndex(s => key(s.specialist, s.domain) === k);
108
+ if (idx < 0) {
109
+ const prior = DEFAULT_PRIORS[outcome.specialist]?.[outcome.domain] ?? 0.5;
110
+ return [
111
+ ...scores,
112
+ {
113
+ specialist: outcome.specialist,
114
+ domain: outcome.domain,
115
+ score: clamp01((1 - alpha) * prior + alpha * signal),
116
+ sampleCount: 1,
117
+ lastUpdated: now,
118
+ },
119
+ ];
120
+ }
121
+ const cur = scores[idx];
122
+ const next = {
123
+ ...cur,
124
+ score: clamp01((1 - alpha) * cur.score + alpha * signal),
125
+ sampleCount: cur.sampleCount + 1,
126
+ lastUpdated: now,
127
+ };
128
+ return [...scores.slice(0, idx), next, ...scores.slice(idx + 1)];
129
+ }
130
+ // ─────────────────────────────────────────────────────────────────────────────
131
+ // Persistence — {projectRoot}/.aura/competence.json
132
+ // ─────────────────────────────────────────────────────────────────────────────
133
+ exports.competenceStore = {
134
+ filePath(projectRoot) {
135
+ return path.join(projectRoot, '.aura', 'competence.json');
136
+ },
137
+ async load(projectRoot) {
138
+ const filePath = this.filePath(projectRoot);
139
+ if (!fs.existsSync(filePath)) {
140
+ return {
141
+ projectRoot,
142
+ scores: defaultCompetenceMatrix(),
143
+ version: 1,
144
+ };
145
+ }
146
+ const raw = await fs.promises.readFile(filePath, 'utf8');
147
+ try {
148
+ const parsed = JSON.parse(raw);
149
+ if (parsed?.version === 1 && Array.isArray(parsed.scores)) {
150
+ return parsed;
151
+ }
152
+ }
153
+ catch {
154
+ /* fall through */
155
+ }
156
+ return {
157
+ projectRoot,
158
+ scores: defaultCompetenceMatrix(),
159
+ version: 1,
160
+ };
161
+ },
162
+ async save(profile) {
163
+ const filePath = this.filePath(profile.projectRoot);
164
+ const dir = path.dirname(filePath);
165
+ if (!fs.existsSync(dir))
166
+ fs.mkdirSync(dir, { recursive: true });
167
+ const tmp = filePath + '.tmp';
168
+ await fs.promises.writeFile(tmp, JSON.stringify(profile, null, 2), 'utf8');
169
+ await fs.promises.rename(tmp, filePath);
170
+ },
171
+ async recordOutcome(projectRoot, outcome) {
172
+ const profile = await this.load(projectRoot);
173
+ const updated = {
174
+ ...profile,
175
+ scores: applyOutcome(profile.scores, outcome),
176
+ };
177
+ await this.save(updated);
178
+ return updated;
179
+ },
180
+ };
181
+ //# sourceMappingURL=competence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"competence.js","sourceRoot":"","sources":["../../src/orchestration/competence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { LLMProvider } from '../providers/types.js';
2
+ import type { ProjectContext } from '../agent/context.js';
3
+ import type { ProjectPerception } from '../perception/types.js';
4
+ import type { ExecutionPlan } from './types.js';
5
+ import type { Display } from '../cli/display.js';
6
+ /** Options passed to the plan executor. */
7
+ export interface ExecutorOptions {
8
+ /** The plan to execute (mutated in place as steps progress). */
9
+ plan: ExecutionPlan;
10
+ /** Provider used by every specialist step. */
11
+ provider: LLMProvider;
12
+ /** Loaded project context passed to specialists. */
13
+ context: ProjectContext;
14
+ /** Display sink for progress events. */
15
+ display: Display;
16
+ /** Optional perception snapshot forwarded to each specialist. */
17
+ perception?: ProjectPerception;
18
+ /** Optional abort signal; sets plan status to `'aborted'` when fired. */
19
+ signal?: AbortSignal;
20
+ /** Maximum steps running concurrently. Defaults to 3. */
21
+ maxParallel?: number;
22
+ }
23
+ /**
24
+ * Runs all steps in `opts.plan` respecting their dependency graph.
25
+ *
26
+ * Steps whose `dependsOn` arrays are all resolved run immediately, up to
27
+ * `maxParallel` at once using `Promise.allSettled`. When a step fails,
28
+ * every step that transitively depends on it is marked `'skipped'` so
29
+ * independent branches continue unaffected. The final plan is persisted to
30
+ * disk and returned.
31
+ *
32
+ * Never throws — if every step fails, the plan is returned with
33
+ * status `'failed'`.
34
+ */
35
+ export declare function executePlan(opts: ExecutorOptions): Promise<ExecutionPlan>;
36
+ /**
37
+ * Asks the provider to write a coherent summary of all completed step results.
38
+ *
39
+ * Falls back to a plain concatenation of step results if the provider call
40
+ * fails or returns empty text. Never throws.
41
+ */
42
+ export declare function synthesise(plan: ExecutionPlan, provider: LLMProvider, context: ProjectContext): Promise<string>;
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.executePlan = executePlan;
4
+ exports.synthesise = synthesise;
5
+ const specialists_js_1 = require("./specialists.js");
6
+ const plan_store_js_1 = require("./plan-store.js");
7
+ const competence_js_1 = require("./competence.js");
8
+ /**
9
+ * Runs all steps in `opts.plan` respecting their dependency graph.
10
+ *
11
+ * Steps whose `dependsOn` arrays are all resolved run immediately, up to
12
+ * `maxParallel` at once using `Promise.allSettled`. When a step fails,
13
+ * every step that transitively depends on it is marked `'skipped'` so
14
+ * independent branches continue unaffected. The final plan is persisted to
15
+ * disk and returned.
16
+ *
17
+ * Never throws — if every step fails, the plan is returned with
18
+ * status `'failed'`.
19
+ */
20
+ async function executePlan(opts) {
21
+ const { plan, provider, context, display, perception, signal } = opts;
22
+ const maxParallel = opts.maxParallel ?? 3;
23
+ plan.status = 'running';
24
+ display.header(`Plan: ${plan.goal}`, `${plan.steps.length} step${plan.steps.length !== 1 ? 's' : ''}`);
25
+ display.showPlan(plan);
26
+ const memory = [];
27
+ while (true) {
28
+ if (signal?.aborted) {
29
+ plan.status = 'aborted';
30
+ plan.completed = Date.now();
31
+ await persist(plan);
32
+ return plan;
33
+ }
34
+ const ready = findReadySteps(plan.steps);
35
+ if (ready.length === 0) {
36
+ // Catch any waiting steps blocked by a failed/skipped dep that hasn't
37
+ // been propagated yet, then decide whether to stop.
38
+ propagateAllSkips(plan.steps);
39
+ if (plan.steps.every(s => isTerminal(s.status)))
40
+ break;
41
+ // Nothing runnable and plan is not fully terminal — shouldn't happen
42
+ // with a valid acyclic plan, but guard to avoid an infinite loop.
43
+ break;
44
+ }
45
+ const batch = ready.slice(0, maxParallel);
46
+ for (const step of batch) {
47
+ step.status = 'running';
48
+ display.stepStarted(step);
49
+ }
50
+ const settled = await Promise.allSettled(batch.map(step => (0, specialists_js_1.runSpecialist)({ provider, context, perception, step, memory: [...memory], display, signal })));
51
+ for (let i = 0; i < settled.length; i++) {
52
+ const step = batch[i];
53
+ const result = settled[i];
54
+ if (result.status === 'fulfilled' && result.value.success) {
55
+ step.status = 'done';
56
+ step.result = result.value.result;
57
+ step.tokensUsed = result.value.tokensUsed;
58
+ step.durationMs = result.value.durationMs;
59
+ const entry = {
60
+ key: step.id,
61
+ value: result.value.result,
62
+ stepId: step.id,
63
+ timestamp: Date.now(),
64
+ };
65
+ memory.push(entry);
66
+ try {
67
+ await plan_store_js_1.planStore.saveMemory(context.root, entry);
68
+ }
69
+ catch { /* best-effort */ }
70
+ competence_js_1.competenceStore.recordOutcome(context.root, {
71
+ specialist: step.specialist,
72
+ domain: competence_js_1.PRIMARY_DOMAIN[step.specialist],
73
+ success: true,
74
+ quality: 1,
75
+ }).catch(() => { });
76
+ display.stepCompleted(step, step.result);
77
+ }
78
+ else {
79
+ const errMsg = result.status === 'rejected'
80
+ ? String(result.reason)
81
+ : result.value.result;
82
+ step.status = 'failed';
83
+ step.result = errMsg;
84
+ step.durationMs = result.status === 'fulfilled' ? result.value.durationMs : 0;
85
+ competence_js_1.competenceStore.recordOutcome(context.root, {
86
+ specialist: step.specialist,
87
+ domain: competence_js_1.PRIMARY_DOMAIN[step.specialist],
88
+ success: false,
89
+ }).catch(() => { });
90
+ propagateSkips(plan.steps, step.id);
91
+ }
92
+ }
93
+ if (plan.steps.every(s => isTerminal(s.status)))
94
+ break;
95
+ }
96
+ // ── Finalise plan ────────────────────────────────────────────────────────────
97
+ plan.outcome = await synthesise(plan, provider, context);
98
+ plan.status = plan.steps.some(s => s.status === 'failed') ? 'failed' : 'done';
99
+ plan.completed = Date.now();
100
+ plan.totalTokens = plan.steps.reduce((n, s) => n + (s.tokensUsed ?? 0), 0);
101
+ const doneCount = plan.steps.filter(s => s.status === 'done').length;
102
+ display.summary(plan.outcome, plan.steps.length, doneCount);
103
+ await persist(plan);
104
+ return plan;
105
+ }
106
+ // ─────────────────────────────────────────────────────────────────────────────
107
+ // synthesise
108
+ // ─────────────────────────────────────────────────────────────────────────────
109
+ /**
110
+ * Asks the provider to write a coherent summary of all completed step results.
111
+ *
112
+ * Falls back to a plain concatenation of step results if the provider call
113
+ * fails or returns empty text. Never throws.
114
+ */
115
+ async function synthesise(plan, provider, context) {
116
+ const done = plan.steps.filter(s => s.status === 'done' && s.result);
117
+ if (done.length === 0) {
118
+ return plan.steps.some(s => s.status === 'failed')
119
+ ? 'All steps failed — no changes were made.'
120
+ : 'No steps completed.';
121
+ }
122
+ const stepBlocks = done
123
+ .map((s, i) => `Step ${i + 1} [${s.specialist}] — ${s.task}\n${s.result}`)
124
+ .join('\n\n');
125
+ const system = `You are summarising the results of a multi-agent coding task ` +
126
+ `for project "${context.name}". ` +
127
+ `Be concise — 3 to 5 sentences. State what was accomplished and what changed.`;
128
+ const history = [{
129
+ role: 'user',
130
+ content: `Goal: ${plan.goal}\n\n` +
131
+ `Here are the results of each specialist step. ` +
132
+ `Synthesise them into a coherent summary of what was accomplished and what changed.\n\n` +
133
+ stepBlocks,
134
+ }];
135
+ try {
136
+ const response = await provider.complete(system, history, []);
137
+ const text = response.text.trim();
138
+ return text.length > 0 ? text : fallbackSynthesis(done);
139
+ }
140
+ catch {
141
+ return fallbackSynthesis(done);
142
+ }
143
+ }
144
+ // ─────────────────────────────────────────────────────────────────────────────
145
+ // Internal helpers
146
+ // ─────────────────────────────────────────────────────────────────────────────
147
+ /** Returns steps that are `'waiting'` and have all dependencies in `'done'` state. */
148
+ function findReadySteps(steps) {
149
+ const doneIds = new Set(steps.filter(s => s.status === 'done').map(s => s.id));
150
+ return steps.filter(s => s.status === 'waiting' && s.dependsOn.every(dep => doneIds.has(dep)));
151
+ }
152
+ /**
153
+ * Marks all `'waiting'` steps that directly depend on `failedId` as
154
+ * `'skipped'`, then recursively propagates through their dependents (BFS).
155
+ */
156
+ function propagateSkips(steps, failedId) {
157
+ let frontier = [failedId];
158
+ while (frontier.length > 0) {
159
+ const next = [];
160
+ for (const id of frontier) {
161
+ for (const step of steps) {
162
+ if (step.status === 'waiting' && step.dependsOn.includes(id)) {
163
+ step.status = 'skipped';
164
+ next.push(step.id);
165
+ }
166
+ }
167
+ }
168
+ frontier = next;
169
+ }
170
+ }
171
+ /**
172
+ * Sweeps all steps and ensures any `'waiting'` step whose dependency set
173
+ * includes a failed or skipped step is itself marked `'skipped'`.
174
+ * Runs to fixpoint to handle multi-level chains.
175
+ */
176
+ function propagateAllSkips(steps) {
177
+ const blocked = new Set(steps
178
+ .filter(s => s.status === 'failed' || s.status === 'skipped')
179
+ .map(s => s.id));
180
+ let changed = true;
181
+ while (changed) {
182
+ changed = false;
183
+ for (const step of steps) {
184
+ if (step.status === 'waiting' && step.dependsOn.some(d => blocked.has(d))) {
185
+ step.status = 'skipped';
186
+ blocked.add(step.id);
187
+ changed = true;
188
+ }
189
+ }
190
+ }
191
+ }
192
+ function isTerminal(status) {
193
+ return status === 'done' || status === 'failed' || status === 'skipped';
194
+ }
195
+ function fallbackSynthesis(steps) {
196
+ return steps
197
+ .map(s => `[${s.specialist}] ${(s.result ?? '').slice(0, 300)}`)
198
+ .join('\n\n');
199
+ }
200
+ async function persist(plan) {
201
+ try {
202
+ await plan_store_js_1.planStore.save(plan);
203
+ }
204
+ catch { /* best-effort */ }
205
+ }
206
+ //# sourceMappingURL=executor.js.map