@corenel/harness 0.3.2 → 0.4.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 (72) hide show
  1. package/dist/acp/index.js +2 -2
  2. package/dist/api/backend.js +1 -1
  3. package/dist/api/fileMirrorSource.js +2 -2
  4. package/dist/api/mirror.js +1 -1
  5. package/dist/compression.d.ts +15 -1
  6. package/dist/compression.d.ts.map +1 -1
  7. package/dist/compression.js +32 -1
  8. package/dist/compression.js.map +1 -1
  9. package/dist/core/loop.d.ts +10 -0
  10. package/dist/core/loop.d.ts.map +1 -1
  11. package/dist/core/loop.js +137 -14
  12. package/dist/core/loop.js.map +1 -1
  13. package/dist/core/spawn.d.ts +54 -0
  14. package/dist/core/spawn.d.ts.map +1 -0
  15. package/dist/core/spawn.js +58 -0
  16. package/dist/core/spawn.js.map +1 -0
  17. package/dist/dag/executeNode.js +2 -2
  18. package/dist/fileSchema.js +1 -1
  19. package/dist/guardrail/guardrail.js +1 -1
  20. package/dist/guardrail/index.js +7 -7
  21. package/dist/guardrail/permission-service.js +1 -1
  22. package/dist/guardrail/serialize.js +1 -1
  23. package/dist/guardrail/store.js +2 -2
  24. package/dist/prompts/config.js +2 -2
  25. package/dist/prompts/index.d.ts.map +1 -1
  26. package/dist/prompts/index.js +9 -6
  27. package/dist/prompts/index.js.map +1 -1
  28. package/dist/prompts/library/defaults.generated.js +1 -1
  29. package/dist/prompts/library/defaults.generated.js.map +1 -1
  30. package/dist/prompts/library/index.js +1 -1
  31. package/dist/providers/contextWindow.d.ts +19 -0
  32. package/dist/providers/contextWindow.d.ts.map +1 -0
  33. package/dist/providers/contextWindow.js +68 -0
  34. package/dist/providers/contextWindow.js.map +1 -0
  35. package/dist/providers/gateway.js +1 -1
  36. package/dist/sessions/apiLeaseStore.js +1 -1
  37. package/dist/sessions/blobGc.d.ts +62 -0
  38. package/dist/sessions/blobGc.d.ts.map +1 -0
  39. package/dist/sessions/blobGc.js +154 -0
  40. package/dist/sessions/blobGc.js.map +1 -0
  41. package/dist/sessions/fileRecallStore.js +1 -1
  42. package/dist/sessions/fileSessionStore.js +1 -1
  43. package/dist/sidecar/host.d.ts +18 -2
  44. package/dist/sidecar/host.d.ts.map +1 -1
  45. package/dist/sidecar/host.js +38 -3
  46. package/dist/sidecar/host.js.map +1 -1
  47. package/dist/sidecar/server.d.ts.map +1 -1
  48. package/dist/sidecar/server.js +12 -0
  49. package/dist/sidecar/server.js.map +1 -1
  50. package/dist/sidecar/wsChannel.d.ts +4 -0
  51. package/dist/sidecar/wsChannel.d.ts.map +1 -0
  52. package/dist/sidecar/wsChannel.js +62 -0
  53. package/dist/sidecar/wsChannel.js.map +1 -0
  54. package/dist/skills.js +2 -2
  55. package/dist/tools/builtins.js +6 -6
  56. package/dist/tools/callAgent.d.ts +16 -0
  57. package/dist/tools/callAgent.d.ts.map +1 -0
  58. package/dist/tools/callAgent.js +53 -0
  59. package/dist/tools/callAgent.js.map +1 -0
  60. package/dist/tools/files.d.ts +10 -0
  61. package/dist/tools/files.d.ts.map +1 -1
  62. package/dist/tools/files.js +159 -8
  63. package/dist/tools/files.js.map +1 -1
  64. package/dist/tools/http.js +1 -1
  65. package/dist/tools/namespaces.d.ts.map +1 -1
  66. package/dist/tools/namespaces.js +16 -2
  67. package/dist/tools/namespaces.js.map +1 -1
  68. package/dist/tools/procs.d.ts +18 -0
  69. package/dist/tools/procs.d.ts.map +1 -0
  70. package/dist/tools/procs.js +281 -0
  71. package/dist/tools/procs.js.map +1 -0
  72. package/package.json +14 -7
@@ -0,0 +1,281 @@
1
+ const DEFAULT_SETTLE_MS = 10000;
2
+ const MIN_SETTLE_MS = 100;
3
+ const MAX_SETTLE_MS = 120000;
4
+ /** How many processes THIS factory will let the agent have running at once,
5
+ * counted within the daemon's own MAX_RUNNING=8. Deliberately smaller than the
6
+ * daemon's cap: the operator may want to run their own dev server, build watch,
7
+ * and log tail alongside whatever the agent starts, and an agent that can eat
8
+ * every slot locks them out of their own dock. This protects the OPERATOR, not
9
+ * the agent — it is not a courtesy limit the agent could reasonably ask to
10
+ * raise. */
11
+ const DEFAULT_AGENT_BUDGET = 3;
12
+ /** Every process this file starts is labelled with this marker (plus the
13
+ * session, when known) so a listing can tell "the agent started this" from "a
14
+ * human started this" from ProcInfo.label alone — durable across reloads and
15
+ * reconnects, because the label lives on the daemon-owned ProcInfo, not in this
16
+ * factory's own memory. */
17
+ const AGENT_TAG = 'agent';
18
+ function agentLabel(session, userLabel) {
19
+ const tag = session ? `${AGENT_TAG}:${session}` : AGENT_TAG;
20
+ return userLabel ? `${userLabel} [${tag}]` : `[${tag}]`;
21
+ }
22
+ /** True if a ProcInfo's label carries this file's agent marker — used to count
23
+ * agent-started processes from the daemon's OWN table (procs.list()), not from
24
+ * a Set this factory keeps in memory, so the budget holds even across a reload
25
+ * that drops this factory and rebuilds it. */
26
+ function isAgentStarted(info) {
27
+ return /\[agent(:[^\]]*)?\]/.test(info.label ?? '');
28
+ }
29
+ function str(args, key) {
30
+ const v = args[key];
31
+ return typeof v === 'string' && v.length ? v : undefined;
32
+ }
33
+ function clamp(n, min, max) {
34
+ if (!Number.isFinite(n))
35
+ return min;
36
+ return Math.min(Math.max(n, min), max);
37
+ }
38
+ /** Beyond this many characters, `renderTail`'s output is truncated -- same
39
+ * budget and reasoning as shellTool's MAX_OUTPUT (packages/cli/src/shellTool.ts):
40
+ * the retention ring this reads from is bounded at up to 200_000 chars
41
+ * (packages/sidecar/src/procs.ts / packages/cli/src/sidecarProcs.ts), which is
42
+ * still large enough for one `proc_start` result to blow the model's context
43
+ * window on its own. `corenel run`'s tool context wires no `recall`, so
44
+ * offload cannot rescue this the way it can a `tool-result` that goes through
45
+ * compression -- the cap has to be applied here. */
46
+ const RENDER_TAIL_MAX = 30000;
47
+ /** Render the buffered tail for a process. `truncated` must show up as WORDS —
48
+ * a tail that looks complete when it is not is the failure that matters, so
49
+ * this is never left to a caller to notice on its own. Keeps the LAST
50
+ * RENDER_TAIL_MAX characters (not the first): for a process still starting up,
51
+ * the most recent output is the one that says whether it's ready. */
52
+ function renderTail(procs, procId) {
53
+ const { chunks, truncated } = procs.backlog(procId, 0);
54
+ const body = chunks.map((c) => (c.stream === 'err' ? `[stderr] ${c.text}` : c.text)).join('');
55
+ const capped = body.length > RENDER_TAIL_MAX;
56
+ const shown = capped ? body.slice(body.length - RENDER_TAIL_MAX) : body;
57
+ const notes = [];
58
+ if (truncated)
59
+ notes.push('[some earlier output was dropped from the buffer and is not shown here]');
60
+ if (capped) {
61
+ notes.push(`[showing only the last ${RENDER_TAIL_MAX} of ${body.length} characters -- earlier output in ` +
62
+ 'this result was cut to avoid blowing the context window]');
63
+ }
64
+ const note = notes.length ? `\n${notes.join('\n')}` : '';
65
+ return (shown ? `Output so far:\n${shown}` : 'No output yet.') + note;
66
+ }
67
+ function describeInfo(info) {
68
+ return `${info.procId} (pid ${info.pid ?? 'unknown'}): ${info.command}${info.label ? ` [${info.label}]` : ''}`;
69
+ }
70
+ /** Race the three ways `proc_start` can resolve. Whichever happens first wins;
71
+ * the other two paths are torn down (unsubscribed / timer cleared) so only one
72
+ * result is ever produced. */
73
+ function watchStart(procs, procId, waitFor, settleMs, onChunk) {
74
+ return new Promise((resolve) => {
75
+ let settled = false;
76
+ let lastSeenSeq = 0;
77
+ let buffer = '';
78
+ const finish = (outcome) => {
79
+ if (settled)
80
+ return;
81
+ settled = true;
82
+ clearTimeout(timer);
83
+ unsub();
84
+ resolve(outcome);
85
+ };
86
+ const handleChunk = (c) => {
87
+ if (c.seq <= lastSeenSeq)
88
+ return; // already seen (backlog catch-up vs. live)
89
+ lastSeenSeq = c.seq;
90
+ // Check settled BEFORE streaming: once this call has resolved, nothing
91
+ // reads ctx.stream for it anymore, so a chunk delivered afterwards
92
+ // (synchronous backlog catch-up can call finish() partway through, per
93
+ // the caller's own comment above) must not be pushed at all, not pushed
94
+ // and then ignored for wait_for matching.
95
+ if (settled)
96
+ return;
97
+ onChunk(c);
98
+ if (!waitFor)
99
+ return;
100
+ buffer += c.text;
101
+ if (buffer.includes(waitFor)) {
102
+ const info = procs.get(procId);
103
+ if (info)
104
+ finish({ kind: 'matched', info });
105
+ }
106
+ };
107
+ // `timer` and `unsub` must both be assigned BEFORE anything that can call
108
+ // `finish` synchronously (the backlog catch-up below can: a command that
109
+ // fails instantly, or prints its wait_for text, before this promise's
110
+ // caller ever gets control back) — finish() reads both.
111
+ const timer = setTimeout(() => {
112
+ const info = procs.get(procId);
113
+ if (info)
114
+ finish({ kind: 'settled', info });
115
+ }, settleMs);
116
+ const unsub = procs.subscribe((ev) => {
117
+ if (ev.procId !== procId)
118
+ return;
119
+ if (ev.kind === 'out')
120
+ handleChunk(ev.chunk);
121
+ else
122
+ finish({ kind: 'exited', info: ev.info });
123
+ });
124
+ // Catch up on anything already buffered/settled BEFORE we subscribed — the
125
+ // daemon's spawn() has an await in it (root confinement), so output (or
126
+ // even exit, for a command that fails instantly) can land before this
127
+ // function's caller ever gets control back.
128
+ for (const c of procs.backlog(procId, 0).chunks)
129
+ handleChunk(c);
130
+ if (!settled) {
131
+ const cur = procs.get(procId);
132
+ if (cur && !cur.running)
133
+ finish({ kind: 'exited', info: cur });
134
+ }
135
+ });
136
+ }
137
+ /** Build the proc_start / proc_stop / proc_list tools over a live SidecarProcs.
138
+ * `procs` is expected to be a real, already-constructed process table (node
139
+ * child_process-backed in production, a fake in tests) — this file never
140
+ * constructs one itself. */
141
+ export function procTools(procs, opts = {}) {
142
+ const budget = opts.agentBudget ?? DEFAULT_AGENT_BUDGET;
143
+ const agentRunningCount = () => procs.list().filter((p) => p.running && isAgentStarted(p)).length;
144
+ const procStart = {
145
+ name: 'proc_start',
146
+ means: 'start a long-running command (a dev server, a watcher, a build) and watch its output',
147
+ description: 'Start a long-lived command (e.g. "npm run start") and watch it come up. Unlike a one-shot ' +
148
+ 'shell exec, this does not wait for the command to finish — it resolves once EITHER wait_for ' +
149
+ 'matches a substring of the output, OR settle_ms elapses with the process still running, OR the ' +
150
+ 'process exits early. The result text always says explicitly which of those happened and whether ' +
151
+ 'the process is still running. The process keeps running (and its output keeps being pushed live) ' +
152
+ 'after this call resolves; use proc_list to see it again and proc_stop to end it.',
153
+ parameters: {
154
+ type: 'object',
155
+ properties: {
156
+ command: { type: 'string', description: 'the shell command line to run' },
157
+ cwd: { type: 'string', description: 'working directory relative to the chosen root (default ".")' },
158
+ root: { type: 'string', description: 'which pre-approved root to resolve cwd against' },
159
+ label: { type: 'string', description: 'a short human-readable label for this process' },
160
+ wait_for: {
161
+ type: 'string',
162
+ description: 'a plain SUBSTRING (never a regex) to watch for in the combined output, e.g. "Local: http://". ' +
163
+ 'When it appears, the call resolves immediately instead of waiting out settle_ms.',
164
+ },
165
+ settle_ms: {
166
+ type: 'number',
167
+ description: `how long to wait, in ms, before resolving anyway if wait_for never matches and the process hasn't exited (default ${DEFAULT_SETTLE_MS}, max ${MAX_SETTLE_MS})`,
168
+ },
169
+ },
170
+ required: ['command'],
171
+ },
172
+ namespace: 'shell',
173
+ mutates: true,
174
+ permission: 'ask',
175
+ async run(args, ctx) {
176
+ const command = str(args, 'command')?.trim();
177
+ if (!command)
178
+ return 'Error: no command given';
179
+ const waitFor = str(args, 'wait_for');
180
+ const settleMs = clamp(Number(args.settle_ms) || DEFAULT_SETTLE_MS, MIN_SETTLE_MS, MAX_SETTLE_MS);
181
+ const running = agentRunningCount();
182
+ if (running >= budget) {
183
+ return (`Error: refusing to start another process — this agent already has ${running} of its ` +
184
+ `${budget} allowed concurrent processes running. Stop one with proc_stop first, or ask the ` +
185
+ 'operator to start it themselves.');
186
+ }
187
+ const cwd = str(args, 'cwd');
188
+ const root = str(args, 'root');
189
+ let info;
190
+ try {
191
+ info = await procs.spawn({
192
+ command,
193
+ ...(cwd ? { cwd } : {}),
194
+ ...(root ? { root } : {}),
195
+ label: agentLabel(opts.session, str(args, 'label')),
196
+ });
197
+ }
198
+ catch (e) {
199
+ return `Error: could not start the process: ${e instanceof Error ? e.message : String(e)}`;
200
+ }
201
+ const outcome = await watchStart(procs, info.procId, waitFor, settleMs, (c) => ctx.stream?.(c.text));
202
+ const tail = renderTail(procs, info.procId);
203
+ if (outcome.kind === 'matched') {
204
+ return (`Started ${describeInfo(outcome.info)}\n` +
205
+ `STILL RUNNING — matched wait_for ${JSON.stringify(waitFor)} in its output.\n\n${tail}`);
206
+ }
207
+ if (outcome.kind === 'settled') {
208
+ const waitNote = waitFor ? ` (wait_for ${JSON.stringify(waitFor)} has NOT appeared yet)` : '';
209
+ return (`Started ${describeInfo(outcome.info)}\n` +
210
+ `STILL RUNNING after ${settleMs}ms with no exit${waitNote}.\n\n${tail}`);
211
+ }
212
+ // outcome.kind === 'exited'
213
+ const { info: endInfo } = outcome;
214
+ const status = `exit code ${endInfo.exitCode ?? 'unknown'}${endInfo.signal ? ` (signal ${endInfo.signal})` : ''}`;
215
+ return (`Started ${describeInfo(endInfo)}\n` +
216
+ `ALREADY EXITED before it finished starting — it is NOT running. ${status}.\n\n${tail}`);
217
+ },
218
+ };
219
+ const procStop = {
220
+ name: 'proc_stop',
221
+ means: 'stop a process this agent (or the operator) started',
222
+ description: 'Stop a running process by its proc_id (from proc_start or proc_list). Idempotent — stopping an ' +
223
+ 'already-stopped or unknown process is reported, not treated as an error.',
224
+ parameters: {
225
+ type: 'object',
226
+ properties: { proc_id: { type: 'string', description: 'the procId to stop' } },
227
+ required: ['proc_id'],
228
+ },
229
+ namespace: 'shell',
230
+ mutates: true,
231
+ permission: 'ask',
232
+ async run(args) {
233
+ const procId = str(args, 'proc_id');
234
+ if (!procId)
235
+ return 'Error: no proc_id given';
236
+ const before = procs.get(procId);
237
+ if (!before)
238
+ return `${procId}: no such process (it may already have been evicted after exiting).`;
239
+ if (!before.running) {
240
+ const status = `exit code ${before.exitCode ?? 'unknown'}${before.signal ? ` (signal ${before.signal})` : ''}`;
241
+ return `${describeInfo(before)} was already stopped (${status}).`;
242
+ }
243
+ try {
244
+ procs.kill(procId);
245
+ }
246
+ catch (e) {
247
+ return `Error: could not stop ${procId}: ${e instanceof Error ? e.message : String(e)}`;
248
+ }
249
+ return `Stopping ${describeInfo(before)} (SIGTERM sent; it will be force-killed if it doesn't exit).`;
250
+ },
251
+ };
252
+ const procList = {
253
+ name: 'proc_list',
254
+ means: 'see every process running or recently run on this machine',
255
+ description: 'List the processes visible through this connection, running or recently exited — including ones ' +
256
+ 'started before this conversation, or in an earlier turn whose proc_id has since fallen out of ' +
257
+ 'context. A process started elsewhere (by the operator, or another client) AFTER this connection ' +
258
+ 'was established may not appear here until it reconnects — if an expected process (e.g. a dev ' +
259
+ 'server you did not start) is missing, that does not mean it is not running; ask before starting ' +
260
+ 'a second one on the same port. Each entry says whether it was started by an agent or by the ' +
261
+ 'operator directly.',
262
+ parameters: { type: 'object', properties: {} },
263
+ namespace: 'sidecar',
264
+ async run() {
265
+ const all = procs.list();
266
+ if (!all.length)
267
+ return 'No processes.';
268
+ return all
269
+ .map((p) => {
270
+ const who = isAgentStarted(p) ? 'agent-started' : 'operator-started';
271
+ const state = p.running
272
+ ? 'running'
273
+ : `exited (code ${p.exitCode ?? 'unknown'}${p.signal ? `, signal ${p.signal}` : ''})`;
274
+ return `${describeInfo(p)} — ${who}, ${state}`;
275
+ })
276
+ .join('\n');
277
+ },
278
+ };
279
+ return [procStart, procStop, procList];
280
+ }
281
+ //# sourceMappingURL=procs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procs.js","sourceRoot":"","sources":["../../tools/procs.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@corenel/harness",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
- "description": "Corenel — host-agnostic agent harness (kernel). Consumed as source; the app resolves it via the `corenel` path alias, node consumers via this workspace package + the exports map below. The app never hits these exports (the alias intercepts first), so the .ts-only wildcard is safe — node only ever imports the clean .ts kernel subpaths (e.g. corenel/sidecar/server), never the coupled .tsx UI.",
5
+ "description": "Corenel — host-agnostic agent harness (kernel). The app resolves it via the `corenel` path alias (bypasses these exports entirely); vitest aliases it to source too. Everything else — node consumers like @corenel/cli, @corenel/term, @corenel/sidecar — resolves it through this workspace package via the exports map below, which points at dist/ unconditionally (not just at publish) so in-repo and published resolution are identical: a bundle that treats @corenel/harness as external (see packages/term/build.mjs) must see the SAME module instance node sees when it later resolves this package at runtime, and plain node cannot execute the raw .ts sources at all. Run `pnpm build` here (or let a dependent's prebuild do it) before relying on this package outside the app/vitest. NOTE: @xyflow/react and dagre are NOT dependencies here at all — this package has no .tsx files and imports neither. `react` IS a real (small) runtime dependency: `todos.ts` uses `useSyncExternalStore`. It is declared below as an OPTIONAL peer, not a hard dependency, so node-only consumers (cli/term/sidecar) aren't forced to install react; node consumers hoist it today only because something else in the tree happens to pull it in. Do not add @xyflow/react or dagre as dependencies/peers without testing a packed install end to end — an earlier attempt at that (before this package had any .tsx files) failed npm's peer resolution with ERESOLVE.",
6
6
  "exports": {
7
7
  "./acp": {
8
8
  "types": "./dist/acp/index.d.ts",
@@ -28,12 +28,18 @@
28
28
  "dependencies": {
29
29
  "openai": "^4.77.0",
30
30
  "yaml": "^2.8.3",
31
- "@corenel/protocol": "0.3.2"
31
+ "@corenel/protocol": "0.4.0"
32
32
  },
33
33
  "peerDependencies": {
34
- "@xyflow/react": "^12.11.0",
35
- "dagre": "^0.8.5",
36
- "react": "^18.3.1"
34
+ "react": "^18.0.0 || ^19.0.0"
35
+ },
36
+ "peerDependenciesMeta": {
37
+ "react": {
38
+ "optional": true
39
+ }
40
+ },
41
+ "devDependencies": {
42
+ "@types/ws": "^8.5.13"
37
43
  },
38
44
  "publishConfig": {
39
45
  "access": "public"
@@ -42,6 +48,7 @@
42
48
  "dist"
43
49
  ],
44
50
  "scripts": {
45
- "build": "tsc -p tsconfig.build.json"
51
+ "prebuild": "pnpm --filter @corenel/protocol build",
52
+ "build": "node build.mjs"
46
53
  }
47
54
  }