@voybio/ace-swarm 2.4.9 → 2.4.10

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 (185) hide show
  1. package/CHANGELOG.md +52 -14
  2. package/README.md +14 -10
  3. package/assets/.agents/ACE/ACE_coders/AGENTS.md +23 -30
  4. package/assets/.agents/ACE/ACE_coders/INSTRUCTIONS.md +21 -30
  5. package/assets/.agents/skills/landing-review-watcher/SKILL.md +1 -1
  6. package/assets/.agents/skills/learn-from-work/SKILL.md +41 -0
  7. package/assets/agent-state/ACE_WORKFLOW.md +25 -2
  8. package/assets/agent-state/MODULES/schemas/ACE_RUNTIME_PROFILE.schema.json +143 -2
  9. package/assets/agent-state/MODULES/schemas/RUNTIME_EXECUTOR_SESSION_REGISTRY.schema.json +2 -2
  10. package/assets/agent-state/MODULES/schemas/SWARM_HANDOFF.schema.json +10 -0
  11. package/assets/eval-battery/battery.json +1 -1
  12. package/assets/instructions/ACE_Coder.instructions.md +9 -13
  13. package/assets/scripts/ace-hook-dispatch.mjs +16 -411
  14. package/assets/tasks/SWARM_HANDOFF.example_ui_to_coders.json +1 -2
  15. package/assets/vendor/README.md +9 -0
  16. package/assets/vendor/vericify-reader.mjs +272 -0
  17. package/assets/vendor/vericify-reader.provenance.json +10 -0
  18. package/dist/ace-autonomy.d.ts +58 -0
  19. package/dist/ace-autonomy.js +211 -6
  20. package/dist/ace-internal-tools.d.ts +1 -0
  21. package/dist/ace-internal-tools.js +3 -3
  22. package/dist/ace-server-instructions.d.ts +3 -3
  23. package/dist/ace-server-instructions.js +46 -192
  24. package/dist/cli.js +44 -6
  25. package/dist/experience-reflector.d.ts +7 -0
  26. package/dist/experience-reflector.js +39 -0
  27. package/dist/goal-engine.d.ts +64 -7
  28. package/dist/goal-engine.js +197 -41
  29. package/dist/handoff-registry.d.ts +10 -0
  30. package/dist/handoff-registry.js +59 -0
  31. package/dist/helpers/artifacts.d.ts +6 -2
  32. package/dist/helpers/artifacts.js +8 -6
  33. package/dist/helpers/bootstrap.js +13 -20
  34. package/dist/helpers/path-utils.js +2 -0
  35. package/dist/helpers/store-resolution.js +18 -3
  36. package/dist/helpers/workspace-root.d.ts +2 -0
  37. package/dist/helpers/workspace-root.js +9 -0
  38. package/dist/helpers.d.ts +1 -0
  39. package/dist/helpers.js +1 -0
  40. package/dist/hermes/bridge-protocol.d.ts +1 -1
  41. package/dist/hermes/session-manager.d.ts +17 -0
  42. package/dist/hermes/session-manager.js +67 -14
  43. package/dist/host-goal-engine.d.ts +138 -0
  44. package/dist/host-goal-engine.js +793 -0
  45. package/dist/host-goal-status.d.ts +113 -0
  46. package/dist/host-goal-status.js +175 -0
  47. package/dist/host-learning.d.ts +68 -0
  48. package/dist/host-learning.js +115 -0
  49. package/dist/host-observation.d.ts +12 -0
  50. package/dist/host-observation.js +91 -0
  51. package/dist/host-plan-revision.d.ts +14 -0
  52. package/dist/host-plan-revision.js +101 -0
  53. package/dist/host-verification-job.d.ts +12 -0
  54. package/dist/host-verification-job.js +183 -0
  55. package/dist/host-work-context.d.ts +12 -0
  56. package/dist/host-work-context.js +8 -0
  57. package/dist/job-scheduler.d.ts +48 -14
  58. package/dist/job-scheduler.js +169 -23
  59. package/dist/job-worker.d.ts +3 -1
  60. package/dist/job-worker.js +10 -3
  61. package/dist/kanban.d.ts +4 -1
  62. package/dist/kanban.js +44 -16
  63. package/dist/learned-artifacts.d.ts +64 -0
  64. package/dist/learned-artifacts.js +321 -0
  65. package/dist/learning-controls.d.ts +142 -0
  66. package/dist/learning-controls.js +135 -0
  67. package/dist/learning-input-context.d.ts +9 -0
  68. package/dist/learning-input-context.js +62 -0
  69. package/dist/learning-lifecycle.d.ts +10 -0
  70. package/dist/learning-lifecycle.js +11 -0
  71. package/dist/learning-overlays.d.ts +3 -0
  72. package/dist/learning-overlays.js +17 -0
  73. package/dist/learning-policy.d.ts +40 -0
  74. package/dist/learning-policy.js +38 -0
  75. package/dist/learning-records.d.ts +35 -0
  76. package/dist/learning-records.js +17 -0
  77. package/dist/learning-scorecard.d.ts +82 -0
  78. package/dist/learning-scorecard.js +86 -0
  79. package/dist/learning-serving.d.ts +29 -0
  80. package/dist/learning-serving.js +134 -0
  81. package/dist/linked-work.d.ts +9 -0
  82. package/dist/linked-work.js +28 -0
  83. package/dist/local-model-runtime.js +1 -1
  84. package/dist/mcp-command-progress.d.ts +16 -0
  85. package/dist/mcp-command-progress.js +70 -0
  86. package/dist/model-bridge.d.ts +14 -13
  87. package/dist/model-bridge.js +73 -41
  88. package/dist/orchestrator-supervisor.d.ts +108 -6
  89. package/dist/orchestrator-supervisor.js +4 -32
  90. package/dist/plan-proposal.js +3 -3
  91. package/dist/playbook-curator.d.ts +1 -0
  92. package/dist/playbook-curator.js +11 -9
  93. package/dist/process-identity.d.ts +8 -0
  94. package/dist/process-identity.js +38 -0
  95. package/dist/progress-command.d.ts +34 -0
  96. package/dist/progress-command.js +153 -0
  97. package/dist/prompts.js +15 -15
  98. package/dist/resources.js +2 -2
  99. package/dist/runtime-command.d.ts +8 -1
  100. package/dist/runtime-command.js +48 -7
  101. package/dist/runtime-executor.js +33 -11
  102. package/dist/runtime-profile-syntax.d.ts +6 -0
  103. package/dist/runtime-profile-syntax.js +121 -0
  104. package/dist/runtime-profile.d.ts +37 -5
  105. package/dist/runtime-profile.js +36 -129
  106. package/dist/runtime-tool-specs.js +1 -1
  107. package/dist/safe-edit.d.ts +7 -3
  108. package/dist/safe-edit.js +40 -47
  109. package/dist/schemas.js +4 -2
  110. package/dist/server.d.ts +2 -16
  111. package/dist/server.js +14 -20
  112. package/dist/shared.d.ts +2 -0
  113. package/dist/shared.js +2 -0
  114. package/dist/skill-auditor.d.ts +19 -0
  115. package/dist/skill-auditor.js +32 -2
  116. package/dist/skill-catalog.d.ts +4 -1
  117. package/dist/skill-catalog.js +6 -5
  118. package/dist/store/ace-packed-store.d.ts +5 -1
  119. package/dist/store/ace-packed-store.js +33 -1
  120. package/dist/store/bootstrap-store.js +19 -12
  121. package/dist/store/cache-workspace.d.ts +8 -0
  122. package/dist/store/cache-workspace.js +94 -27
  123. package/dist/store/importer.js +11 -20
  124. package/dist/store/knowledge-bake.d.ts +3 -1
  125. package/dist/store/knowledge-bake.js +10 -1
  126. package/dist/store/legacy-vericify-posts.d.ts +8 -0
  127. package/dist/store/legacy-vericify-posts.js +76 -0
  128. package/dist/store/materializers/hook-context-materializer.d.ts +2 -1
  129. package/dist/store/materializers/hook-context-materializer.js +6 -2
  130. package/dist/store/materializers/host-file-materializer.js +2 -2
  131. package/dist/store/materializers/projection-manager.d.ts +4 -1
  132. package/dist/store/materializers/projection-manager.js +10 -3
  133. package/dist/store/materializers/todo-syncer.d.ts +39 -20
  134. package/dist/store/materializers/todo-syncer.js +208 -110
  135. package/dist/store/materializers/vericify-projector.js +15 -26
  136. package/dist/store/repositories/goal-repository.d.ts +51 -2
  137. package/dist/store/repositories/goal-repository.js +114 -48
  138. package/dist/store/repositories/playbook-repository.d.ts +41 -3
  139. package/dist/store/repositories/playbook-repository.js +61 -5
  140. package/dist/store/repositories/todo-repository.d.ts +8 -2
  141. package/dist/store/repositories/todo-repository.js +1 -1
  142. package/dist/store/repositories/vericify-repository.d.ts +4 -0
  143. package/dist/store/repositories/vericify-repository.js +46 -0
  144. package/dist/store/skills-install.d.ts +1 -0
  145. package/dist/store/skills-install.js +20 -16
  146. package/dist/store/source-preservation.d.ts +24 -0
  147. package/dist/store/source-preservation.js +79 -0
  148. package/dist/store/store-artifacts.js +8 -1
  149. package/dist/store/test-write-boundary.d.ts +16 -0
  150. package/dist/store/test-write-boundary.js +175 -0
  151. package/dist/store/types.d.ts +5 -1
  152. package/dist/store/write-coordinator.js +16 -0
  153. package/dist/task-plan-context.d.ts +11 -0
  154. package/dist/task-plan-context.js +59 -0
  155. package/dist/todo-state.d.ts +19 -9
  156. package/dist/todo-state.js +204 -321
  157. package/dist/tools-agent.d.ts +1 -1
  158. package/dist/tools-agent.js +38 -62
  159. package/dist/tools-files.d.ts +0 -3
  160. package/dist/tools-files.js +21 -11
  161. package/dist/tools-framework.js +16 -25
  162. package/dist/tools-goal.d.ts +2 -4
  163. package/dist/tools-goal.js +119 -16
  164. package/dist/tools-handoff.js +28 -4
  165. package/dist/tools-lifecycle.js +1 -1
  166. package/dist/tools-memory.d.ts +0 -3
  167. package/dist/tools-memory.js +51 -6
  168. package/dist/tools-scheduler.js +19 -17
  169. package/dist/tools-todo.js +160 -148
  170. package/dist/vericify-bridge.d.ts +8 -0
  171. package/dist/vericify-bridge.js +18 -0
  172. package/dist/vericify-context.d.ts +4 -0
  173. package/dist/vericify-context.js +26 -5
  174. package/dist/vericify-native.d.ts +101 -0
  175. package/dist/vericify-native.js +221 -0
  176. package/dist/verification-worker.d.ts +2 -0
  177. package/dist/verification-worker.js +31 -0
  178. package/docs/mcp-tool-reference.md +44 -9
  179. package/package.json +19 -6
  180. package/scripts/dev/run-tests-isolated.mjs +165 -0
  181. package/scripts/dev/run_hermes_crispr_live.mjs +1 -0
  182. package/scripts/dev/test-isolation-guard.mjs +20 -0
  183. package/scripts/dev/test-preload.mjs +153 -0
  184. package/scripts/dev/test-source-inventory.mjs +31 -0
  185. package/docs/development.md +0 -46
@@ -0,0 +1,153 @@
1
+ // Test-only Node boundary. It is not an OS sandbox for arbitrary native code.
2
+ import fs from 'node:fs';
3
+ import fsp from 'node:fs/promises';
4
+ import cp from 'node:child_process';
5
+ import { syncBuiltinESMExports } from 'node:module';
6
+ import { isAbsolute, join, relative, sep } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+ import { promisify } from 'node:util';
9
+ import { randomUUID } from 'node:crypto';
10
+
11
+ const raw = Object.fromEntries(Object.entries(fs).filter(([, value]) => typeof value === 'function').map(([key, value]) => [key, value.bind(fs)]));
12
+ const rawExecFileSync = cp.execFileSync.bind(cp);
13
+ const rawRealpathNative = fs.realpathSync.native.bind(fs);
14
+ const sessionFile = process.env.ACE_TEST_SESSION_FILE;
15
+ if (!sessionFile) throw new Error('ACE test isolation required: missing session file');
16
+ const session = JSON.parse(raw.readFileSync(sessionFile, 'utf8'));
17
+ const lease = () => JSON.parse(raw.readFileSync(session.lease_file, 'utf8'));
18
+ if (lease().status !== 'active' || lease().run_id !== session.run_id) throw new Error('ACE test isolation required: inactive session');
19
+ if ((process.env.NODE_TEST_CONTEXT || process.env.ACE_TEST_PROBE === '1') && !process.env.ACE_TEST_WORKER_ROOT) {
20
+ const allocation = raw.mkdtempSync(join(session.fixtures_root, 'worker-'));
21
+ const workspace = join(allocation, 'workspace'); const temporary = join(allocation, 'tmp');
22
+ raw.mkdirSync(workspace); raw.mkdirSync(temporary);
23
+ process.env.ACE_TEST_WORKER_ROOT = workspace;
24
+ process.env.ACE_WORKSPACE_ROOT = workspace;
25
+ process.env.ACE_TEST_ALLOWED_ROOTS = JSON.stringify([allocation]);
26
+ process.env.TMPDIR = temporary; process.env.TMP = temporary; process.env.TEMP = temporary;
27
+ }
28
+ process.env.ACE_TEST_ISOLATION = '1';
29
+ process.env.ACE_TEST_RUN_ID = session.run_id;
30
+ process.env.ACE_TEST_LEASE_FILE = session.lease_file;
31
+ process.env.ACE_TEST_SENTINEL_PATH = session.sentinel;
32
+
33
+ function processFields(args) {
34
+ if (!Array.isArray(args) || args[0] !== '-p' || !/^\d+$/.test(args[1] ?? '')) return undefined;
35
+ const rest = args.slice(2).join(' ');
36
+ return rest === '-o lstart=' ? 'start' : rest === '-o stat=' ? 'stat' : rest === '-o lstart= -o stat=' ? 'both' : undefined;
37
+ }
38
+ function inspectProcess(args, opts = {}) {
39
+ const fields = processFields(args);
40
+ if (!session.process_info_broker || !fields) return rawExecFileSync('ps', args, opts);
41
+ const id = randomUUID(); const name = `${id}.json`; const request = join(session.process_info_requests, name); const response = join(session.process_info_responses, name);
42
+ raw.writeFileSync(`${request}.tmp`, JSON.stringify({ run_id: session.run_id, pid: Number(args[1]), fields })); raw.renameSync(`${request}.tmp`, request);
43
+ const end = Date.now() + (Number.isFinite(opts.timeout) && opts.timeout > 0 ? opts.timeout : 10000);
44
+ const wait = new Int32Array(new SharedArrayBuffer(4));
45
+ while (Date.now() < end) {
46
+ if (raw.existsSync(response)) {
47
+ const result = JSON.parse(raw.readFileSync(response, 'utf8')); raw.unlinkSync(response);
48
+ if (result.run_id !== session.run_id || result.pid !== Number(args[1])) throw new Error('Invalid owned process-info response');
49
+ if (!result.ok) throw Object.assign(new Error(result.stderr || 'OS process information unavailable'), { code: result.code, status: result.status, stdout: result.stdout, stderr: result.stderr });
50
+ return opts.encoding && opts.encoding !== 'buffer' ? result.stdout : Buffer.from(result.stdout);
51
+ }
52
+ Atomics.wait(wait, 0, 0, 5);
53
+ }
54
+ throw Object.assign(new Error('Owned process-info request timed out'), { code: 'ETIMEDOUT' });
55
+ }
56
+
57
+ // Every Node descendant inherits this import, including detached verification.
58
+ const registration = join(session.registry_root, `${process.pid}.json`);
59
+ let identity;
60
+ try { identity = inspectProcess(['-p', String(process.pid), '-o', 'lstart='], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim().replace(/\s+/g, ' '); } catch { identity = null; }
61
+ raw.writeFileSync(registration, JSON.stringify({ pid: process.pid, parent: process.ppid, identity, registered_at: Date.now() }));
62
+ process.once('exit', () => { try { raw.unlinkSync(registration); } catch {} });
63
+
64
+ if (process.env.ACE_TEST_WORKER_ROOT) {
65
+ const { captureTestWriteBoundary, currentTestWriteAnchors } = await import(new URL('../../dist/store/test-write-boundary.js', import.meta.url));
66
+ const check = path => {
67
+ if (typeof path === 'number') {
68
+ if (path === 1 || path === 2) return () => {};
69
+ const pinned = descriptors.get(path); if (!pinned) throw new Error('ace_test_write_boundary: untracked file descriptor'); pinned(); return pinned;
70
+ }
71
+ const pin = captureTestWriteBoundary(path instanceof URL ? fileURLToPath(path) : Buffer.isBuffer(path) ? path.toString() : path); pin(); return pin;
72
+ };
73
+ const descriptors = new Map();
74
+ const paths = { appendFile: [0], writeFile: [0], mkdir: [0], mkdtemp: [0], rm: [0], rmdir: [0], unlink: [0], rename: [0, 1], copyFile: [1], cp: [1], link: [0, 1], symlink: [1], chmod: [0], chown: [0], lchown: [0], lchmod: [0], truncate: [0], utimes: [0], lutimes: [0], createWriteStream: [0] };
75
+ for (const [name, indices] of Object.entries(paths)) {
76
+ for (const method of [name, `${name}Sync`]) if (typeof fs[method] === 'function') {
77
+ const original = fs[method].bind(fs);
78
+ fs[method] = (...args) => { indices.forEach(index => check(args[index])); return original(...args); };
79
+ }
80
+ if (typeof fsp[name] === 'function') {
81
+ const original = fsp[name].bind(fsp);
82
+ fsp[name] = async (...args) => { indices.forEach(index => check(args[index])); return original(...args); };
83
+ }
84
+ }
85
+ const writable = flags => typeof flags === 'number' ? Boolean(flags & (fs.constants.O_WRONLY | fs.constants.O_RDWR | fs.constants.O_CREAT | fs.constants.O_TRUNC | fs.constants.O_APPEND)) : /[wa+]/.test(flags ?? 'r');
86
+ const openSync = fs.openSync.bind(fs);
87
+ fs.openSync = (path, flags, ...rest) => { const pin = writable(flags) ? check(path) : undefined; const fd = openSync(path, flags, ...rest); if (pin) descriptors.set(fd, pin); return fd; };
88
+ const open = fs.open.bind(fs);
89
+ fs.open = (path, flags, ...rest) => {
90
+ const pin = writable(flags) ? check(path) : undefined; const callback = rest.pop();
91
+ return open(path, flags, ...rest, (error, fd) => { if (!error && pin) descriptors.set(fd, pin); callback(error, fd); });
92
+ };
93
+ const promiseOpen = fsp.open.bind(fsp);
94
+ fsp.open = async (path, flags, ...rest) => {
95
+ const pin = writable(flags) ? check(path) : undefined; const handle = await promiseOpen(path, flags, ...rest);
96
+ if (pin) {
97
+ descriptors.set(handle.fd, pin);
98
+ for (const key of ['write', 'writev', 'writeFile', 'appendFile', 'truncate', 'chmod', 'chown', 'utimes', 'createWriteStream']) if (typeof handle[key] === 'function') {
99
+ const operation = handle[key].bind(handle); handle[key] = (...args) => { pin(); return operation(...args); };
100
+ }
101
+ }
102
+ return handle;
103
+ };
104
+ for (const method of ['write', 'writeSync', 'writev', 'writevSync', 'ftruncate', 'ftruncateSync', 'fchmod', 'fchmodSync', 'fchown', 'fchownSync', 'futimes', 'futimesSync']) if (typeof fs[method] === 'function') {
105
+ const operation = fs[method].bind(fs); fs[method] = (fd, ...args) => { check(fd); return operation(fd, ...args); };
106
+ }
107
+ const inside = (path, base) => { const tail = relative(base, path); return tail !== '..' && !tail.startsWith(`..${sep}`) && !isAbsolute(tail); };
108
+ const inherited = Object.fromEntries(['ACE_TEST_ISOLATION', 'ACE_TEST_SESSION_FILE', 'ACE_TEST_RUN_ID', 'ACE_TEST_LEASE_FILE', 'ACE_TEST_ALLOWED_ROOTS', 'ACE_TEST_WORKER_ROOT', 'ACE_TEST_SENTINEL_PATH', 'NODE_OPTIONS'].map(key => [key, process.env[key]]));
109
+ function options(given = {}) {
110
+ // An explicit environment may intentionally omit credentials. Preserve that
111
+ // boundary and reattach only the isolation identity below.
112
+ const env = { ...(given.env ?? process.env) };
113
+ let requested;
114
+ try { requested = JSON.parse(env.ACE_TEST_ALLOWED_ROOTS); } catch {}
115
+ const parentRoots = JSON.parse(inherited.ACE_TEST_ALLOWED_ROOTS);
116
+ const narrow = Array.isArray(requested) && requested.length && requested.every(path => typeof path === 'string' && isAbsolute(path) && parentRoots.some(base => inside(rawRealpathNative(path), rawRealpathNative(base))));
117
+ const anchors = [...currentTestWriteAnchors()];
118
+ const workspace = env.ACE_WORKSPACE_ROOT;
119
+ if (workspace && raw.existsSync(workspace)) { const path = rawRealpathNative(workspace); const st = raw.statSync(path, { bigint: true }); anchors.push({ path, dev: String(st.dev), ino: String(st.ino) }); }
120
+ Object.assign(env, inherited);
121
+ if (narrow) env.ACE_TEST_ALLOWED_ROOTS = JSON.stringify(requested);
122
+ env.ACE_TEST_WRITE_ANCHORS = JSON.stringify(anchors);
123
+ return { ...given, env };
124
+ }
125
+ function registerOwned(child) {
126
+ if (!child?.pid) return child;
127
+ const file = join(session.registry_root, `${child.pid}.json`); let childIdentity;
128
+ try { childIdentity = inspectProcess(['-p', String(child.pid), '-o', 'lstart='], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }).trim().replace(/\s+/g, ' '); } catch { childIdentity = null; }
129
+ raw.writeFileSync(file, JSON.stringify({ pid: child.pid, parent: process.pid, identity: childIdentity, registered_at: Date.now() }));
130
+ child.once('exit', () => { try { raw.unlinkSync(file); } catch {} }); return child;
131
+ }
132
+ for (const name of ['spawn', 'spawnSync', 'execFile', 'execFileSync', 'fork']) {
133
+ const original = cp[name].bind(cp);
134
+ cp[name] = (command, args, opts, callback) => {
135
+ if (!Array.isArray(args)) { callback = opts; opts = args; args = []; }
136
+ if (typeof opts === 'function') { callback = opts; opts = {}; }
137
+ if (name === 'execFileSync' && (command === 'ps' || command === '/bin/ps') && session.process_info_broker && processFields(args)) return inspectProcess(args, opts);
138
+ const child = callback ? original(command, args, options(opts), callback) : original(command, args, options(opts));
139
+ return name.endsWith('Sync') ? child : registerOwned(child);
140
+ };
141
+ }
142
+ for (const name of ['exec', 'execSync']) {
143
+ const original = cp[name].bind(cp);
144
+ cp[name] = (command, opts, callback) => { if (typeof opts === 'function') { callback = opts; opts = {}; } const child = callback ? original(command, options(opts), callback) : original(command, options(opts)); return name.endsWith('Sync') ? child : registerOwned(child); };
145
+ }
146
+ for (const name of ['exec', 'execFile']) cp[name][promisify.custom] = (...args) => {
147
+ let child;
148
+ const result = new Promise((resolvePromise, reject) => { child = cp[name](...args, (error, stdout, stderr) => error ? reject(Object.assign(error, { stdout, stderr })) : resolvePromise({ stdout, stderr })); });
149
+ result.child = child; return result;
150
+ };
151
+ syncBuiltinESMExports();
152
+ globalThis[Symbol.for('ace.test.preload')] = true;
153
+ }
@@ -0,0 +1,31 @@
1
+ import { existsSync, lstatSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { execFileSync } from 'node:child_process';
3
+ import { dirname, isAbsolute, join, resolve } from 'node:path';
4
+
5
+ const safe = name => typeof name === 'string' && name && !isAbsolute(name) && !name.split(/[\\/]/).includes('..') && !/^(?:agent-state|\.agents|\.git|node_modules)(?:[\\/]|$)/.test(name);
6
+
7
+ /** An installed package has no Git checkout. Inventory only its declared files. */
8
+ export function testSourceFiles(source) {
9
+ const manifest = join(source, '.ace-test-source-files.json');
10
+ if (existsSync(manifest)) return JSON.parse(readFileSync(manifest, 'utf8')).filter(safe);
11
+ if (existsSync(join(source, '.git'))) return execFileSync('git', ['ls-files', '-z', '--cached', '--others', '--exclude-standard'], { cwd: source, encoding: 'utf8' }).split('\0').filter(safe);
12
+ const pkg = JSON.parse(readFileSync(join(source, 'package.json'), 'utf8'));
13
+ const roots = ['package.json', 'package-lock.json', 'README.md', 'CHANGELOG.md', 'LICENSE', ...(pkg.files ?? [])].map(name => typeof name === 'string' ? name.split(/[*?[]/, 1)[0].replace(/[\\/]$/, '') : '').filter(safe);
14
+ const files = new Set();
15
+ function visit(name) {
16
+ if (!safe(name) || !existsSync(join(source, name))) return;
17
+ const stat = lstatSync(join(source, name));
18
+ if (stat.isSymbolicLink()) return;
19
+ if (stat.isDirectory()) for (const child of readdirSync(join(source, name))) visit(join(name, child));
20
+ else if (stat.isFile()) files.add(name);
21
+ }
22
+ roots.forEach(visit); return [...files].sort();
23
+ }
24
+
25
+ export function findTestDependencies(source) {
26
+ let cursor = resolve(source);
27
+ for (;;) {
28
+ const candidate = join(cursor, 'node_modules'); if (existsSync(candidate)) return candidate;
29
+ const parent = dirname(cursor); if (parent === cursor) throw new Error('Installed ACE dependencies are unavailable; use the package installation containing node_modules'); cursor = parent;
30
+ }
31
+ }
@@ -1,46 +0,0 @@
1
- # Development
2
-
3
- > Companion to the [README](../README.md).
4
-
5
- ```bash
6
- cd ace-mcp-server
7
- npm install
8
- npm run build
9
- npm test
10
- npm run start
11
- ```
12
-
13
- Run the Hermes live driver from a source checkout. The script is included in the npm package as of 2.4.6, but it imports the checkout/package `dist/` tree and is a diagnostic, not a supported production command. It exits nonzero if setup, protocol, or artifact checks fail.
14
-
15
- ```bash
16
- npm run build
17
- # with a local llama.cpp or Ollama runtime running:
18
- ACE_WORKSPACE_ROOT=$PWD \
19
- ACE_HERMES_ROOT=/path/to/hermes-agent \
20
- HERMES_PYTHON=/path/to/hermes-python \
21
- ACE_LIVE_PROVIDERS=llama.cpp \
22
- ACE_LIVE_LLAMA_CPP_BASE_URL=http://127.0.0.1:8080/v1 \
23
- ACE_LIVE_LLAMA_CPP_MODEL=gemma-3-4b-it \
24
- ACE_LIVE_HERMES_MAX_TURNS=3 \
25
- node scripts/dev/run_hermes_crispr_live.mjs
26
- ```
27
-
28
- `ACE_LIVE_OUTPUT_ONLY=1` deliberately bypasses tool writing and is only for inspecting raw model output; it cannot satisfy the driver’s evidence-gated job check.
29
-
30
- ## Key source files
31
-
32
- | File | Role |
33
- |---|---|
34
- | `src/index.ts` | Package entry point |
35
- | `src/cli.ts` | CLI command dispatch |
36
- | `src/server.ts` | MCP server setup and stdio transport |
37
- | `src/tools.ts` | Tool registration hub (delegates to domain modules) |
38
- | `src/hermes/session-manager.ts` | `HermesSubprocessExecutor` — Hermes subprocess lifecycle |
39
- | `src/hermes/bridge-protocol.ts` | Frame decoder for the Hermes bridge protocol |
40
- | `src/model-bridge.ts` | Model bridge interface and process orchestration |
41
- | `src/goal-engine.ts` | Goal engine — self-paced, evidence-gated objective loop |
42
- | `src/job-worker.ts` | In-process job worker for the scheduler execution loop |
43
- | `src/public-surface.ts` | Public surface audit and schema-bound entry map |
44
- | `src/store/ace-packed-store.ts` | ACEPACK binary store read/write |
45
- | `src/local-model-policy.ts` | Operator allow/block policy for local models |
46
- | `scripts/hermes_bridge_worker.py` | Packaged Python worker for the Hermes bridge |