@corenel/harness 0.2.0 → 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 (163) hide show
  1. package/dist/acp/agentMap.d.ts +34 -0
  2. package/dist/acp/agentMap.d.ts.map +1 -0
  3. package/dist/acp/agentMap.js +110 -0
  4. package/dist/acp/agentMap.js.map +1 -0
  5. package/dist/acp/index.d.ts +4 -0
  6. package/dist/acp/index.d.ts.map +1 -0
  7. package/dist/acp/index.js +6 -0
  8. package/dist/acp/index.js.map +1 -0
  9. package/dist/acp/policyMap.d.ts +55 -0
  10. package/dist/acp/policyMap.d.ts.map +1 -0
  11. package/dist/acp/policyMap.js +121 -0
  12. package/dist/acp/policyMap.js.map +1 -0
  13. package/dist/acp/types.d.ts +41 -0
  14. package/dist/acp/types.d.ts.map +1 -0
  15. package/dist/acp/types.js +14 -0
  16. package/dist/acp/types.js.map +1 -0
  17. package/dist/api/backend.d.ts +39 -0
  18. package/dist/api/backend.d.ts.map +1 -0
  19. package/dist/api/backend.js +126 -0
  20. package/dist/api/backend.js.map +1 -0
  21. package/dist/api/client.d.ts +95 -0
  22. package/dist/api/client.d.ts.map +1 -0
  23. package/dist/api/client.js +212 -0
  24. package/dist/api/client.js.map +1 -0
  25. package/dist/api/fileMirrorSource.d.ts +24 -0
  26. package/dist/api/fileMirrorSource.d.ts.map +1 -0
  27. package/dist/api/fileMirrorSource.js +59 -0
  28. package/dist/api/fileMirrorSource.js.map +1 -0
  29. package/dist/api/mirror.d.ts +102 -0
  30. package/dist/api/mirror.d.ts.map +1 -0
  31. package/dist/api/mirror.js +204 -0
  32. package/dist/api/mirror.js.map +1 -0
  33. package/dist/api/mirrorScheduler.d.ts +56 -0
  34. package/dist/api/mirrorScheduler.d.ts.map +1 -0
  35. package/dist/api/mirrorScheduler.js +167 -0
  36. package/dist/api/mirrorScheduler.js.map +1 -0
  37. package/dist/compression.d.ts +15 -1
  38. package/dist/compression.d.ts.map +1 -1
  39. package/dist/compression.js +32 -1
  40. package/dist/compression.js.map +1 -1
  41. package/dist/core/loop.d.ts +12 -0
  42. package/dist/core/loop.d.ts.map +1 -1
  43. package/dist/core/loop.js +138 -14
  44. package/dist/core/loop.js.map +1 -1
  45. package/dist/core/spawn.d.ts +54 -0
  46. package/dist/core/spawn.d.ts.map +1 -0
  47. package/dist/core/spawn.js +58 -0
  48. package/dist/core/spawn.js.map +1 -0
  49. package/dist/dag/executeNode.js +2 -2
  50. package/dist/fileSchema.js +1 -1
  51. package/dist/guardrail/guardrail.js +1 -1
  52. package/dist/guardrail/index.js +7 -7
  53. package/dist/guardrail/permission-service.js +1 -1
  54. package/dist/guardrail/serialize.js +1 -1
  55. package/dist/guardrail/store.js +2 -2
  56. package/dist/install/lockfile.d.ts +79 -0
  57. package/dist/install/lockfile.d.ts.map +1 -0
  58. package/dist/install/lockfile.js +155 -0
  59. package/dist/install/lockfile.js.map +1 -0
  60. package/dist/install/store.d.ts +13 -0
  61. package/dist/install/store.d.ts.map +1 -0
  62. package/dist/install/store.js +38 -0
  63. package/dist/install/store.js.map +1 -0
  64. package/dist/log.d.ts.map +1 -1
  65. package/dist/log.js +6 -1
  66. package/dist/log.js.map +1 -1
  67. package/dist/prompts/config.js +2 -2
  68. package/dist/prompts/host.d.ts +4 -0
  69. package/dist/prompts/host.d.ts.map +1 -1
  70. package/dist/prompts/host.js.map +1 -1
  71. package/dist/prompts/index.d.ts.map +1 -1
  72. package/dist/prompts/index.js +13 -6
  73. package/dist/prompts/index.js.map +1 -1
  74. package/dist/prompts/library/defaults.generated.js +2 -2
  75. package/dist/prompts/library/defaults.generated.js.map +1 -1
  76. package/dist/prompts/library/index.js +1 -1
  77. package/dist/providers/contextWindow.d.ts +19 -0
  78. package/dist/providers/contextWindow.d.ts.map +1 -0
  79. package/dist/providers/contextWindow.js +68 -0
  80. package/dist/providers/contextWindow.js.map +1 -0
  81. package/dist/providers/gateway.d.ts +3 -0
  82. package/dist/providers/gateway.d.ts.map +1 -1
  83. package/dist/providers/gateway.js +4 -1
  84. package/dist/providers/gateway.js.map +1 -1
  85. package/dist/sessions/apiLeaseStore.d.ts +10 -0
  86. package/dist/sessions/apiLeaseStore.d.ts.map +1 -0
  87. package/dist/sessions/apiLeaseStore.js +41 -0
  88. package/dist/sessions/apiLeaseStore.js.map +1 -0
  89. package/dist/sessions/blobGc.d.ts +62 -0
  90. package/dist/sessions/blobGc.d.ts.map +1 -0
  91. package/dist/sessions/blobGc.js +154 -0
  92. package/dist/sessions/blobGc.js.map +1 -0
  93. package/dist/sessions/fileRecallStore.js +1 -1
  94. package/dist/sessions/fileSessionStore.js +1 -1
  95. package/dist/sessions/head.d.ts +90 -0
  96. package/dist/sessions/head.d.ts.map +1 -0
  97. package/dist/sessions/head.js +82 -0
  98. package/dist/sessions/head.js.map +1 -0
  99. package/dist/sessions/inflight.d.ts +58 -0
  100. package/dist/sessions/inflight.d.ts.map +1 -0
  101. package/dist/sessions/inflight.js +0 -0
  102. package/dist/sessions/inflight.js.map +1 -0
  103. package/dist/sessions/lease.d.ts +59 -0
  104. package/dist/sessions/lease.d.ts.map +1 -0
  105. package/dist/sessions/lease.js +115 -0
  106. package/dist/sessions/lease.js.map +1 -0
  107. package/dist/sessions/leaseStore.d.ts +46 -0
  108. package/dist/sessions/leaseStore.d.ts.map +1 -0
  109. package/dist/sessions/leaseStore.js +58 -0
  110. package/dist/sessions/leaseStore.js.map +1 -0
  111. package/dist/sessions/timeline.d.ts +134 -0
  112. package/dist/sessions/timeline.d.ts.map +1 -0
  113. package/dist/sessions/timeline.js +127 -0
  114. package/dist/sessions/timeline.js.map +1 -0
  115. package/dist/sidecar/host.d.ts +241 -5
  116. package/dist/sidecar/host.d.ts.map +1 -1
  117. package/dist/sidecar/host.js +630 -5
  118. package/dist/sidecar/host.js.map +1 -1
  119. package/dist/sidecar/server.d.ts +124 -2
  120. package/dist/sidecar/server.d.ts.map +1 -1
  121. package/dist/sidecar/server.js +620 -9
  122. package/dist/sidecar/server.js.map +1 -1
  123. package/dist/sidecar/wsChannel.d.ts +4 -0
  124. package/dist/sidecar/wsChannel.d.ts.map +1 -0
  125. package/dist/sidecar/wsChannel.js +62 -0
  126. package/dist/sidecar/wsChannel.js.map +1 -0
  127. package/dist/skills.js +2 -2
  128. package/dist/snapshot/effects.d.ts +69 -0
  129. package/dist/snapshot/effects.d.ts.map +1 -0
  130. package/dist/snapshot/effects.js +67 -0
  131. package/dist/snapshot/effects.js.map +1 -0
  132. package/dist/snapshot/manifest.d.ts +73 -0
  133. package/dist/snapshot/manifest.d.ts.map +1 -0
  134. package/dist/snapshot/manifest.js +141 -0
  135. package/dist/snapshot/manifest.js.map +1 -0
  136. package/dist/snapshot/tree.d.ts +62 -0
  137. package/dist/snapshot/tree.d.ts.map +1 -0
  138. package/dist/snapshot/tree.js +147 -0
  139. package/dist/snapshot/tree.js.map +1 -0
  140. package/dist/tools/builtins.d.ts.map +1 -1
  141. package/dist/tools/builtins.js +67 -8
  142. package/dist/tools/builtins.js.map +1 -1
  143. package/dist/tools/callAgent.d.ts +16 -0
  144. package/dist/tools/callAgent.d.ts.map +1 -0
  145. package/dist/tools/callAgent.js +53 -0
  146. package/dist/tools/callAgent.js.map +1 -0
  147. package/dist/tools/files.d.ts +10 -0
  148. package/dist/tools/files.d.ts.map +1 -1
  149. package/dist/tools/files.js +159 -8
  150. package/dist/tools/files.js.map +1 -1
  151. package/dist/tools/http.js +1 -1
  152. package/dist/tools/namespaces.d.ts +1 -1
  153. package/dist/tools/namespaces.d.ts.map +1 -1
  154. package/dist/tools/namespaces.js +40 -2
  155. package/dist/tools/namespaces.js.map +1 -1
  156. package/dist/tools/procs.d.ts +18 -0
  157. package/dist/tools/procs.d.ts.map +1 -0
  158. package/dist/tools/procs.js +281 -0
  159. package/dist/tools/procs.js.map +1 -0
  160. package/dist/tools/todo.d.ts.map +1 -1
  161. package/dist/tools/todo.js +12 -0
  162. package/dist/tools/todo.js.map +1 -1
  163. package/package.json +18 -7
@@ -15,26 +15,177 @@ function ensureWritable(path) {
15
15
  throw new Error(`${PROMPD_INSTALL_DIR}/ install dirs are read-only (managed by package install). Refusing to modify "${path}". Install or remove packages instead of editing them directly.`);
16
16
  }
17
17
  }
18
- function flatten(nodes, out = []) {
19
- for (const n of nodes) {
20
- out.push(`${n.kind === 'directory' ? '[dir] ' : ''}${n.path}${n.kind === 'file' && n.size != null ? ` (${n.size}b)` : ''}`);
21
- if (n.children?.length)
22
- flatten(n.children, out);
18
+ function describe(n) {
19
+ return `${n.kind === 'directory' ? '[dir] ' : ''}${n.path}${n.kind === 'file' && n.size != null ? ` (${n.size}b)` : ''}`;
20
+ }
21
+ /** Every node in the ALREADY-MATERIALIZED tree, in BFS (level) order: every
22
+ * depth-0 node before ANY depth-1 node, every depth-1 before any depth-2, and
23
+ * so on. Used only to decide WHICH nodes survive the cap (see
24
+ * `selectByBreadthFirstCap` below) — never to render, because that reordering
25
+ * has its own cost (see the doc comment there). Also doubles as the total
26
+ * node count.
27
+ *
28
+ * IMPORTANT — what `maxDepth` does and does not save: `roots` here is the
29
+ * full result of `FileService.list()`, which has ALREADY recursed the whole
30
+ * subtree by the time this function ever sees it — `FileService.list(dir?:
31
+ * string)` (`packages/protocol/files.ts`) has no depth parameter, and none of
32
+ * its implementations (`packages/tools-node/fileService.ts`,
33
+ * `src/services/files/DirectoryHandleFileService.ts`,
34
+ * `src/services/files/SidecarFileService.ts`) stop early. So `maxDepth`
35
+ * bounds what is COLLECTED FROM that in-memory listing into `out` (and
36
+ * therefore what is returned to the model) — it does NOT reduce the
37
+ * `fs.readdir`/`fs.stat`/IPC cost of producing `roots` in the first place.
38
+ * That deeper fix belongs in the `FileService.list` port and its
39
+ * implementations, not here. Omit `maxDepth` for the unlimited,
40
+ * today's-behavior case. */
41
+ function bfsNodes(roots, maxDepth = Infinity) {
42
+ const out = [];
43
+ let level = roots;
44
+ let depth = 1;
45
+ while (level.length) {
46
+ const next = [];
47
+ for (const n of level) {
48
+ out.push(n);
49
+ if (n.kind === 'directory' && n.children?.length && depth < maxDepth)
50
+ next.push(...n.children);
51
+ }
52
+ level = next;
53
+ depth++;
54
+ }
55
+ return out;
56
+ }
57
+ /** Cap on entries a single `list_files` call returns. A stranger typing `ls` in
58
+ * a large repo (no `dir`) got the WHOLE tree back — 4,369 entries in one real
59
+ * run, an 87K-token prompt on the very next model call. A few hundred entries
60
+ * is plenty to orient in a repo (see any file's immediate siblings, spot the
61
+ * top-level layout) without paying for the whole thing; 300 is that number —
62
+ * generous enough that an ordinary project's top few levels fit whole, small
63
+ * enough that a monorepo's `node_modules`-scale sprawl can't leak through
64
+ * uncapped. Every host (browser, node CLI, sidecar) shares this file, so the
65
+ * cap applies uniformly rather than per-host. */
66
+ export const LIST_FILES_MAX_ENTRIES = 300;
67
+ /** WHICH nodes survive: the first `LIST_FILES_MAX_ENTRIES` in BFS order —
68
+ * see `bfsNodes`'s comment for why breadth-first is what makes a global count
69
+ * cap keep the top of the tree instead of one arbitrary deep branch. Returns
70
+ * the surviving set plus the true total (for the marker). */
71
+ function selectByBreadthFirstCap(roots, maxDepth) {
72
+ const bfs = bfsNodes(roots, maxDepth);
73
+ return { keep: new Set(bfs.slice(0, LIST_FILES_MAX_ENTRIES)), total: bfs.length };
74
+ }
75
+ /** Render the surviving nodes in ORIGINAL TREE ORDER (depth-first pre-order —
76
+ * the natural, readable shape: a directory immediately followed by its own
77
+ * contents), not the BFS order used to select them.
78
+ *
79
+ * BFS decides WHICH 300 entries survive; it must not also decide how they are
80
+ * DISPLAYED. In a small repo that was never truncated, every node survives
81
+ * (`keep` has everything), and rendering in BFS order would still separate
82
+ * every directory from its own contents — level by level instead of subtree
83
+ * by subtree — which is a strictly worse read for the overwhelmingly common
84
+ * case (no truncation at all) to fix a problem that only exists when
85
+ * truncation happens. So: select breadth-first, render depth-first, over the
86
+ * SAME `keep` set — a directory's children only appear here if the directory
87
+ * itself survived (BFS always keeps a parent before any of its children, so
88
+ * that's automatic, not a race), and only the children that themselves
89
+ * survived. */
90
+ function describeInTreeOrder(roots, keep, maxDepth = Infinity, depth = 1, out = []) {
91
+ for (const n of roots) {
92
+ if (!keep.has(n))
93
+ continue;
94
+ out.push(describe(n));
95
+ if (n.kind === 'directory' && n.children?.length && depth < maxDepth) {
96
+ describeInTreeOrder(n.children, keep, maxDepth, depth + 1, out);
97
+ }
23
98
  }
24
99
  return out;
25
100
  }
101
+ /** The unmistakable trailing marker — never let the model believe a
102
+ * truncated listing is the whole tree.
103
+ *
104
+ * `total` (and therefore `omitted`) is always the count of entries within the
105
+ * scope this call actually collected FROM — i.e. `bfsNodes`'s output length,
106
+ * which a depth limit already shrank before this is ever called (see
107
+ * `bfsNodes`'s doc comment — the underlying `FileService.list` still walked
108
+ * the full subtree; `maxDepth` only bounds what was collected from that
109
+ * result). So when `depth` is given, `total` here is the count within that
110
+ * depth, not the size of the whole tree, and the two truncation reasons — a
111
+ * depth limit excluding lower levels, vs. the entry cap additionally cutting
112
+ * within the collected scope — are DIFFERENT signals the model needs to tell
113
+ * apart to decide what to do next.
114
+ *
115
+ * Written as plain consecutive sentences, not a parenthetical nested inside
116
+ * the count — a model parses "340 total (not the whole tree (because...))"
117
+ * less reliably than separate sentences saying the same things in order. And
118
+ * when `depth` is in force, the right remedy is a LARGER `depth` (to see
119
+ * deeper), never "limit how many levels" (it's already limited) — telling the
120
+ * model to narrow further when it already narrowed is the wrong direction. */
121
+ function truncationMarker(total, maxDepth) {
122
+ const omitted = total - LIST_FILES_MAX_ENTRIES;
123
+ const omittedEntries = `${omitted} more entr${omitted === 1 ? 'y' : 'ies'} omitted`;
124
+ if (maxDepth != null && Number.isFinite(maxDepth)) {
125
+ return `… truncated: ${omittedEntries}. ${total} entries were collected within depth ${maxDepth}; ` +
126
+ 'deeper levels were not counted, so this is not the size of the whole tree. ' +
127
+ 'Pass `dir` to narrow by subdirectory, or a larger `depth` to go deeper.';
128
+ }
129
+ return `… truncated: ${omittedEntries} (${total} total). ` +
130
+ 'Pass `dir` to list a specific subdirectory (narrower breadth), or `depth` to limit how many levels deep the listing goes (narrower depth), instead of the whole tree.';
131
+ }
132
+ /** Normalizes model-supplied `depth` into a safe, meaningful bound, or
133
+ * `undefined` for "unlimited" (today's behavior — full recursive listing,
134
+ * still subject to the entry cap). Never throws: `depth` is model output and
135
+ * may be anything.
136
+ *
137
+ * Rules:
138
+ * - missing / null / not coercible to a finite number -> `undefined`
139
+ * (unlimited) — the safest fallback, since it reproduces the behavior
140
+ * every existing caller already relies on.
141
+ * - a numeric string ("2") is accepted the same as a number.
142
+ * - non-finite (`NaN`, `Infinity`) -> `undefined` (unlimited).
143
+ * - fractional values are floored (2.7 -> 2): depth is a count of whole
144
+ * levels, there is no such thing as "2.7 levels deep".
145
+ * - anything below 1 (0, negative) is clamped up to 1 — the shallowest
146
+ * depth that still means something ("immediate children only"), rather
147
+ * than being rejected or treated as unlimited.
148
+ * - very large values (1e9) are accepted as-is; they behave as
149
+ * "effectively unlimited" and are still bounded by `LIST_FILES_MAX_ENTRIES`
150
+ * like the unlimited case, so there's no separate ceiling to enforce. */
151
+ function normalizeDepth(args) {
152
+ const v = args['depth'];
153
+ if (v == null)
154
+ return undefined;
155
+ const n = typeof v === 'number' ? v : typeof v === 'string' ? Number(v) : NaN;
156
+ if (!Number.isFinite(n))
157
+ return undefined;
158
+ const floored = Math.floor(n);
159
+ return floored < 1 ? 1 : floored;
160
+ }
26
161
  export const listFilesTool = {
27
162
  name: 'list_files',
28
163
  description: 'List files and directories in the workspace (the open folder or the virtual workspace). ' +
29
- 'Optionally pass `dir` to list a subdirectory. Returns paths relative to the workspace root.',
164
+ 'Start shallow and drill in: pass `depth` to limit how many levels deep the listing goes ' +
165
+ '(vertical narrowing — `depth: 1` returns just the immediate children of the target, a quick ' +
166
+ 'orientation call) and/or `dir` to list a specific subdirectory instead of the whole tree ' +
167
+ '(horizontal narrowing). Omit `depth` for a full recursive listing. Returns paths relative to ' +
168
+ 'the workspace root.',
30
169
  parameters: {
31
170
  type: 'object',
32
- properties: { dir: { type: 'string', description: 'Subdirectory to list (optional; omit for the root).' } },
171
+ properties: {
172
+ dir: { type: 'string', description: 'Subdirectory to list (optional; omit for the root).' },
173
+ depth: {
174
+ type: 'number',
175
+ description: 'How many levels deep to list (optional; omit for the full recursive tree). ' +
176
+ '1 = immediate children of `dir` (or the root) only, 2 = two levels, and so on. ' +
177
+ 'Values below 1 (0, negative) are treated as 1, not rejected.',
178
+ },
179
+ },
33
180
  },
34
181
  async run(args, ctx) {
35
182
  const files = requireFiles(ctx);
36
183
  const nodes = await files.list(str(args, 'dir') || undefined);
37
- const lines = flatten(nodes);
184
+ const maxDepth = normalizeDepth(args);
185
+ const { keep, total } = selectByBreadthFirstCap(nodes, maxDepth);
186
+ const lines = describeInTreeOrder(nodes, keep, maxDepth);
187
+ if (total > LIST_FILES_MAX_ENTRIES)
188
+ lines.push(truncationMarker(total, maxDepth));
38
189
  return lines.length ? lines.join('\n') : '(empty)';
39
190
  },
40
191
  };
@@ -1 +1 @@
1
- {"version":3,"file":"files.js","sourceRoot":"","sources":["../../tools/files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"files.js","sourceRoot":"","sources":["../../tools/files.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { outboundUrlError, safeFetch } from './urlGuard';
1
+ import { outboundUrlError, safeFetch } from './urlGuard.js';
2
2
  function str(args, key) {
3
3
  const v = args[key];
4
4
  return typeof v === 'string' ? v : v == null ? '' : String(v);
@@ -1,4 +1,4 @@
1
- export type ToolNamespace = 'fs' | 'prompd' | 'web' | 'memory' | 'agent' | 'shell' | 'system' | 'mcp' | 'skill' | 'other';
1
+ export type ToolNamespace = 'fs' | 'sidecar' | 'prompd' | 'web' | 'memory' | 'agent' | 'shell' | 'system' | 'mcp' | 'skill' | 'other';
2
2
  /** Display order + labels for the namespaces (capabilities panel grouping). */
3
3
  export declare const NAMESPACE_LABELS: {
4
4
  ns: ToolNamespace;
@@ -1 +1 @@
1
- {"version":3,"file":"namespaces.d.ts","sourceRoot":"","sources":["../../tools/namespaces.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,aAAa,GACrB,IAAI,GACJ,QAAQ,GACR,KAAK,GACL,QAAQ,GACR,OAAO,GACP,OAAO,GACP,QAAQ,GACR,KAAK,GACL,OAAO,GACP,OAAO,CAAC;AAEZ,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE;IAAE,EAAE,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAWlE,CAAC;AAcF,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,aAAa,CAUpE;AAED;;;4CAG4C;AAC5C,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAQxD;AAED;6EAC6E;AAC7E,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAE9D;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAI1F;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAEvD"}
1
+ {"version":3,"file":"namespaces.d.ts","sourceRoot":"","sources":["../../tools/namespaces.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,aAAa,GACrB,IAAI,GASJ,SAAS,GACT,QAAQ,GACR,KAAK,GACL,QAAQ,GACR,OAAO,GACP,OAAO,GACP,QAAQ,GACR,KAAK,GACL,OAAO,GACP,OAAO,CAAC;AAEZ,+EAA+E;AAC/E,eAAO,MAAM,gBAAgB,EAAE;IAAE,EAAE,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAYlE,CAAC;AAiCF,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,2FAA2F;AAC3F,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,aAAa,CAUpE;AAED;;;4CAG4C;AAC5C,wBAAgB,WAAW,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAsBxD;AAED;6EAC6E;AAC7E,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,EAAE,CAE9D;AAED,iEAAiE;AACjE,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAI1F;AAED,iFAAiF;AACjF,wBAAgB,aAAa,CAAC,EAAE,EAAE,aAAa,GAAG,MAAM,CAEvD"}
@@ -10,10 +10,11 @@
10
10
  *
11
11
  * Policy globs may target a whole namespace (fs:*) or one tool (fs:write_file),
12
12
  * and legacy bare-name globs (write_file) still match for back-compat. */
13
- import { matchesAnyGlob } from '../guardrail/glob';
13
+ import { matchesAnyGlob } from '../guardrail/glob.js';
14
14
  /** Display order + labels for the namespaces (capabilities panel grouping). */
15
15
  export const NAMESPACE_LABELS = [
16
16
  { ns: 'fs', label: 'Files' },
17
+ { ns: 'sidecar', label: 'This machine' },
17
18
  { ns: 'prompd', label: 'Prompd' },
18
19
  { ns: 'web', label: 'Web' },
19
20
  { ns: 'memory', label: 'Memory' },
@@ -33,7 +34,26 @@ const BUILTIN_NAMESPACES = {
33
34
  web_search: 'web',
34
35
  save_memory: 'memory', recall_memory: 'memory', recall_result: 'memory',
35
36
  kv_get: 'memory', kv_set: 'memory', search_sessions: 'memory',
36
- ask_user: 'agent', spawn_agent: 'agent', spawn_agents: 'agent', todo_write: 'agent',
37
+ ask_user: 'agent', spawn_agent: 'agent', spawn_agents: 'agent', call_agent: 'agent', todo_write: 'agent',
38
+ // Named here as a backstop; the sidecar's own decls also carry `namespace`,
39
+ // and an explicit field always wins (resolveNamespace). Both say the same
40
+ // thing so a sidecar that predates this still lands in the right namespace.
41
+ sidecar_fs_read_file: 'sidecar', sidecar_fs_write_file: 'sidecar',
42
+ sidecar_fs_read_bytes: 'sidecar', sidecar_fs_list_dir: 'sidecar',
43
+ sidecar_fs_delete: 'sidecar', sidecar_shell_exec: 'sidecar',
44
+ // Host-side orchestration tools. They are not in allTools() - they reach the
45
+ // agent as remote decls (workerFactory) - but they are still governed by the
46
+ // policy, so they need a canonical address like everything else.
47
+ create_strategy: 'agent', edit_strategy: 'agent', view_strategy: 'agent', run_strategy: 'agent',
48
+ list_strategies: 'agent', list_saved_strategies: 'agent',
49
+ // Long-lived process control (proc_start/proc_stop/proc_list, see tools/procs.ts).
50
+ // `shell` is its own subject, deliberately distinct from the one-shot exec's
51
+ // `sidecar:shell_exec`: a process that stays running is a different risk from
52
+ // one that returns, and one address lets an operator ban (or allow) both
53
+ // start and stop together. proc_list is a read - it namespaces as `sidecar`
54
+ // (like the other machine-state reads) so it is NOT swept up by a `shell:*`
55
+ // deny; listing what is running carries none of spawn/kill's risk.
56
+ proc_start: 'shell', proc_stop: 'shell', proc_list: 'sidecar',
37
57
  };
38
58
  /** Resolve a tool's namespace: explicit field > built-in table > wire prefix > 'other'. */
39
59
  export function resolveNamespace(tool) {
@@ -62,6 +82,24 @@ export function toolAddress(tool) {
62
82
  if (m)
63
83
  leaf = leaf.slice(m[0].length);
64
84
  }
85
+ // `sidecar_fs_write_file` -> `sidecar:write_file`. The wire name carries the
86
+ // prefix because the MODEL sees a flat list and needs to tell the two apart;
87
+ // the address carries it in the namespace instead, so it is not said twice.
88
+ // `sidecar_fs_` before `sidecar_` — the longer prefix has to win.
89
+ if (ns === 'sidecar') {
90
+ for (const p of ['sidecar_fs_', 'sidecar_']) {
91
+ if (leaf.startsWith(p)) {
92
+ leaf = leaf.slice(p.length);
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ // proc_start and proc_stop are two ends of the SAME governed capability
98
+ // (starting a long-lived process, and ending one) — they share the one
99
+ // address `shell:spawn` on purpose, so a policy rule can only ever gate both
100
+ // together, never start-without-stop or the reverse.
101
+ if (ns === 'shell' && (leaf === 'proc_start' || leaf === 'proc_stop'))
102
+ leaf = 'spawn';
65
103
  return `${ns}:${leaf}`;
66
104
  }
67
105
  /** Candidate strings a policy glob may target for this tool: its address and its
@@ -1 +1 @@
1
- {"version":3,"file":"namespaces.js","sourceRoot":"","sources":["../../tools/namespaces.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"namespaces.js","sourceRoot":"","sources":["../../tools/namespaces.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { AgentTool, SidecarProcs } from '@corenel/protocol';
2
+ export interface ProcToolsOptions {
3
+ /** Identifies the run/session starting processes through these tools. Stamped
4
+ * onto every ProcInfo.label this factory produces (agentLabel()) so a dock
5
+ * listing can show provenance even after a reload. Optional — omitting it
6
+ * still marks the process as agent-started, just without a session name. */
7
+ session?: string;
8
+ /** Cap on concurrent agent-started RUNNING processes (see AGENT_TAG /
9
+ * isAgentStarted) — independent of, and smaller than, the daemon's own
10
+ * MAX_RUNNING. Default DEFAULT_AGENT_BUDGET. */
11
+ agentBudget?: number;
12
+ }
13
+ /** Build the proc_start / proc_stop / proc_list tools over a live SidecarProcs.
14
+ * `procs` is expected to be a real, already-constructed process table (node
15
+ * child_process-backed in production, a fake in tests) — this file never
16
+ * constructs one itself. */
17
+ export declare function procTools(procs: SidecarProcs, opts?: ProcToolsOptions): AgentTool[];
18
+ //# sourceMappingURL=procs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"procs.d.ts","sourceRoot":"","sources":["../../tools/procs.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,SAAS,EAAoC,YAAY,EAAE,MAAM,mBAAmB,CAAC;AA0JnG,MAAM,WAAW,gBAAgB;IAC/B;;;gFAG4E;IAC5E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;oDAEgD;IAChD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;4BAG4B;AAC5B,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,EAAE,IAAI,GAAE,gBAAqB,GAAG,SAAS,EAAE,CA2JvF"}
@@ -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