negotium 0.1.34 → 0.1.35

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.
package/dist/main.js CHANGED
@@ -3919,7 +3919,7 @@ var init_claude_provider = __esm(async () => {
3919
3919
  });
3920
3920
 
3921
3921
  // ../../packages/core/src/version.ts
3922
- var NEGOTIUM_VERSION = "0.1.34";
3922
+ var NEGOTIUM_VERSION = "0.1.35";
3923
3923
 
3924
3924
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
3925
3925
  import { spawn as spawn3 } from "child_process";
@@ -4275,6 +4275,29 @@ function summarizeTargets(values) {
4275
4275
  return targets[0] ?? "";
4276
4276
  return `${targets[0]} +${targets.length - 1}`;
4277
4277
  }
4278
+ function summarizeSsh(words) {
4279
+ let destination = "";
4280
+ let index = 0;
4281
+ while (index < words.length) {
4282
+ const word = words[index] ?? "";
4283
+ if (word === "--") {
4284
+ destination = words[index + 1] ?? "";
4285
+ index += 2;
4286
+ break;
4287
+ }
4288
+ if (!word.startsWith("-")) {
4289
+ destination = word;
4290
+ index += 1;
4291
+ break;
4292
+ }
4293
+ index += SSH_OPTIONS_WITH_VALUE.has(word) ? 2 : 1;
4294
+ }
4295
+ if (!destination)
4296
+ return "ssh";
4297
+ const remoteCommand = words.slice(index).join(" ");
4298
+ const remoteSummary = remoteCommand ? summarizeShellCommand(remoteCommand) : "";
4299
+ return ["ssh", destination, remoteSummary].filter(Boolean).join(" \xB7 ");
4300
+ }
4278
4301
  function summarizeShellPart(value) {
4279
4302
  const words = shellWords(value).filter((word) => !/^\d*>/.test(word));
4280
4303
  while (words[0] === "sudo")
@@ -4294,6 +4317,8 @@ function summarizeShellPart(value) {
4294
4317
  if (executable === "command" && words[0] === "-v") {
4295
4318
  return words[1] ? `find ${commandName(words[1])}` : "find command";
4296
4319
  }
4320
+ if (executable === "ssh")
4321
+ return summarizeSsh(words);
4297
4322
  if (executable === "git") {
4298
4323
  while (words[0]?.startsWith("-")) {
4299
4324
  const option = words.shift();
@@ -4592,8 +4617,31 @@ function formatToolUse(name, input) {
4592
4617
  }
4593
4618
  return displayName;
4594
4619
  }
4595
- var TOOL_SUMMARY_MAX_CHARS = 90, TOOL_SUMMARY_HEAD_CHARS = 52, TOOL_SUMMARY_TAIL_CHARS = 28, TOOL_DIFF_MAX_CHARS = 4000, TOOL_DIFF_SOURCE_MAX_BYTES = 2000000, SHELL_SUMMARY_MAX_PARTS = 3, SUMMARY_KEYS;
4620
+ var TOOL_SUMMARY_MAX_CHARS = 90, TOOL_SUMMARY_HEAD_CHARS = 52, TOOL_SUMMARY_TAIL_CHARS = 28, TOOL_DIFF_MAX_CHARS = 4000, TOOL_DIFF_SOURCE_MAX_BYTES = 2000000, SHELL_SUMMARY_MAX_PARTS = 3, SSH_OPTIONS_WITH_VALUE, SUMMARY_KEYS;
4596
4621
  var init_tool_format = __esm(() => {
4622
+ SSH_OPTIONS_WITH_VALUE = new Set([
4623
+ "-B",
4624
+ "-b",
4625
+ "-c",
4626
+ "-D",
4627
+ "-E",
4628
+ "-e",
4629
+ "-F",
4630
+ "-I",
4631
+ "-i",
4632
+ "-J",
4633
+ "-L",
4634
+ "-l",
4635
+ "-m",
4636
+ "-O",
4637
+ "-o",
4638
+ "-p",
4639
+ "-Q",
4640
+ "-R",
4641
+ "-S",
4642
+ "-W",
4643
+ "-w"
4644
+ ]);
4597
4645
  SUMMARY_KEYS = [
4598
4646
  "command",
4599
4647
  "cmd",
@@ -22917,41 +22965,13 @@ var init_path_suggest = __esm(() => {
22917
22965
  TRAILING_PUNCT = /[.,;:!?)\]}>"'`]+$/;
22918
22966
  });
22919
22967
 
22920
- // ../../adapters/terminal/src/terminal-width.ts
22921
- function stripAnsi(value) {
22922
- return value.replace(new RegExp("\\u001b\\[[0-?]*[ -/]*[@-~]", "g"), "");
22923
- }
22924
- function runeWidth(char) {
22925
- const code = char.codePointAt(0) ?? 0;
22926
- if (code === 8205 || code >= 65024 && code <= 65039)
22927
- return 0;
22928
- if (code >= 4352 && (code <= 4447 || code === 9001 || code === 9002 || code >= 11904 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65135 || code >= 65280 && code <= 65376 || code >= 127744 && code <= 129791 || code >= 131072)) {
22929
- return 2;
22930
- }
22931
- return 1;
22932
- }
22933
- function displayWidth(value) {
22934
- return [...stripAnsi(value)].reduce((width, char) => width + runeWidth(char), 0);
22935
- }
22936
-
22937
22968
  // ../../adapters/terminal/src/subagent-graph.ts
22938
- import { spawn as spawn7 } from "child_process";
22939
- import { createRequire as createRequire2 } from "module";
22969
+ import { layoutTerminalGraph } from "orchgraph";
22940
22970
  function adjustSubagentGraphSpacing(current3, delta) {
22941
22971
  return Math.min(MAX_SUBAGENT_GRAPH_SPACING, Math.max(MIN_SUBAGENT_GRAPH_SPACING, current3 + delta));
22942
22972
  }
22943
- function terminalGraphLayout(spacing) {
22944
- const normalized = adjustSubagentGraphSpacing(spacing, 0);
22945
- return {
22946
- padding: Math.max(1, Math.round(normalized / 4)),
22947
- nodeSpacing: normalized,
22948
- layerSpacing: Math.max(2, Math.round(normalized * 0.75)),
22949
- edgeNodeSpacing: Math.max(1, Math.round(normalized / 2)),
22950
- edgeEdgeSpacing: Math.max(1, Math.round(normalized / 2))
22951
- };
22952
- }
22953
- function textWidth(value) {
22954
- return displayWidth(value);
22973
+ function isSubagentGraphEdgeKind(value) {
22974
+ return value === "owns" || value === "owns-parent-only" || value === "tell" || value === "tell-bidirectional";
22955
22975
  }
22956
22976
  function scopedTopics(topics, activeTopicId) {
22957
22977
  const root = topics.find((topic) => topic.id === activeTopicId);
@@ -22978,6 +22998,18 @@ function scopedTopics(topics, activeTopicId) {
22978
22998
  append(root);
22979
22999
  return scoped;
22980
23000
  }
23001
+ function edgePresentation(kind) {
23002
+ switch (kind) {
23003
+ case "owns":
23004
+ return { direction: "both", style: "solid" };
23005
+ case "owns-parent-only":
23006
+ return { direction: "forward", style: "solid", label: "status only \u2193" };
23007
+ case "tell":
23008
+ return { direction: "forward", style: "dashed", label: "tell" };
23009
+ case "tell-bidirectional":
23010
+ return { direction: "both", style: "dashed", label: "tell \u2194" };
23011
+ }
23012
+ }
22981
23013
  function buildSubagentGraph(topics, activeTopicId, runningTopicIds = new Set) {
22982
23014
  const scoped = scopedTopics(topics, activeTopicId);
22983
23015
  const scopedIds = new Set(scoped.map((topic) => topic.id));
@@ -23000,29 +23032,29 @@ function buildSubagentGraph(topics, activeTopicId, runningTopicIds = new Set) {
23000
23032
  scopedIds.add(target.id);
23001
23033
  }
23002
23034
  }
23003
- const edges = [];
23035
+ const domainEdges = [];
23004
23036
  const edgeKeys = new Set;
23005
23037
  const addEdge = (kind, source, target) => {
23006
23038
  if (!scopedIds.has(source) || !scopedIds.has(target) || source === target)
23007
23039
  return;
23008
23040
  if (kind === "tell") {
23009
- const reverseIndex = edges.findIndex((edge) => (edge.kind === "tell" || edge.kind === "tell-bidirectional") && edge.source === target && edge.target === source);
23041
+ const reverseIndex = domainEdges.findIndex((edge) => (edge.kind === "tell" || edge.kind === "tell-bidirectional") && edge.source === target && edge.target === source);
23010
23042
  if (reverseIndex >= 0) {
23011
- const reverse = edges[reverseIndex];
23012
- if (reverse.kind === "tell") {
23043
+ const reverse = domainEdges[reverseIndex];
23044
+ if (reverse?.kind === "tell") {
23013
23045
  edgeKeys.delete(reverse.id);
23014
- const id = `tell-bidirectional:${reverse.source}:${reverse.target}`;
23015
- edges[reverseIndex] = { ...reverse, id, kind: "tell-bidirectional" };
23016
- edgeKeys.add(id);
23046
+ const id2 = `tell-bidirectional:${reverse.source}:${reverse.target}`;
23047
+ domainEdges[reverseIndex] = { ...reverse, id: id2, kind: "tell-bidirectional" };
23048
+ edgeKeys.add(id2);
23017
23049
  }
23018
23050
  return;
23019
23051
  }
23020
23052
  }
23021
- const key = `${kind}:${source}:${target}`;
23022
- if (edgeKeys.has(key))
23053
+ const id = `${kind}:${source}:${target}`;
23054
+ if (edgeKeys.has(id))
23023
23055
  return;
23024
- edgeKeys.add(key);
23025
- edges.push({ id: key, source, target, kind });
23056
+ edgeKeys.add(id);
23057
+ domainEdges.push({ id, source, target, kind });
23026
23058
  };
23027
23059
  for (const topic of scoped) {
23028
23060
  if (topic.id !== activeTopicId && topic.parentTopicId) {
@@ -23032,292 +23064,40 @@ function buildSubagentGraph(topics, activeTopicId, runningTopicIds = new Set) {
23032
23064
  addEdge("tell", topic.id, targetId);
23033
23065
  }
23034
23066
  }
23035
- return {
23036
- rootTitle: scoped[0]?.title ?? activeTopicId,
23037
- nodes: scoped.map((topic) => ({
23038
- id: topic.id,
23039
- title: topic.title.trim() || topic.id,
23040
- detail: `${topic.agent ?? "agent"} \xB7 ${topic.effectiveModel ?? topic.defaultModel ?? "default"} \xB7 ${topic.effectiveEffort ?? topic.defaultEffort ?? "default"}`,
23041
- running: runningTopicIds.has(topic.id)
23042
- })),
23043
- edges
23044
- };
23045
- }
23046
- function layoutInput(graph, spacing) {
23047
- const layout = terminalGraphLayout(spacing);
23067
+ const nodes = scoped.map((topic) => ({
23068
+ id: topic.id,
23069
+ label: topic.title.trim() || topic.id,
23070
+ detail: `${topic.agent ?? "agent"} \xB7 ${topic.effectiveModel ?? topic.defaultModel ?? "default"} \xB7 ${topic.effectiveEffort ?? topic.defaultEffort ?? "default"}`,
23071
+ state: runningTopicIds.has(topic.id) ? "running" : "idle"
23072
+ }));
23073
+ const root = nodes[0];
23048
23074
  return {
23049
23075
  id: "subagents",
23050
- layoutOptions: {
23051
- "elk.algorithm": "layered",
23052
- "elk.direction": "DOWN",
23053
- "elk.edgeRouting": "ORTHOGONAL",
23054
- "elk.padding": `[top=${layout.padding},left=${layout.padding},bottom=${layout.padding},right=${layout.padding}]`,
23055
- "elk.spacing.nodeNode": String(layout.nodeSpacing),
23056
- "elk.layered.spacing.nodeNodeBetweenLayers": String(layout.layerSpacing),
23057
- "elk.layered.spacing.edgeNodeBetweenLayers": String(layout.edgeNodeSpacing),
23058
- "elk.layered.spacing.edgeEdgeBetweenLayers": String(layout.edgeEdgeSpacing),
23059
- "elk.layered.nodePlacement.favorStraightEdges": "true",
23060
- "elk.layered.crossingMinimization.strategy": "LAYER_SWEEP"
23061
- },
23062
- children: graph.nodes.map((node) => {
23063
- const contentWidth = Math.max(textWidth(node.title) + 4, textWidth(node.detail) + 2, 12);
23064
- return { id: node.id, width: contentWidth + 2, height: 4 };
23065
- }),
23066
- edges: graph.edges.map((edge) => ({
23067
- id: edge.id,
23068
- sources: [edge.source],
23069
- targets: [edge.target]
23070
- }))
23076
+ title: root?.label ?? activeTopicId,
23077
+ direction: "DOWN",
23078
+ nodes,
23079
+ edges: domainEdges.map((edge) => ({ ...edge, ...edgePresentation(edge.kind) })),
23080
+ rootDetail: root?.detail,
23081
+ rootRunning: root?.state === "running"
23071
23082
  };
23072
23083
  }
23073
- function appendElkOutput(current3, chunk, maxBytes = MAX_ELK_OUTPUT_BYTES) {
23074
- if (Buffer.byteLength(current3) + Buffer.byteLength(chunk) > maxBytes) {
23075
- throw new Error(`ELK output exceeded ${maxBytes} bytes`);
23076
- }
23077
- return current3 + chunk;
23078
- }
23079
- async function runElk(input, signal) {
23080
- const require2 = createRequire2(import.meta.url);
23081
- const elkPath = require2.resolve("elkjs/lib/elk.bundled.js");
23082
- const nodeBinary = process.env.NEGOTIUM_NODE_BINARY?.trim() || "node";
23083
- return await new Promise((resolve19, reject) => {
23084
- const child = spawn7(nodeBinary, ["--eval", ELK_HOST_SOURCE, elkPath], {
23085
- stdio: ["pipe", "pipe", "pipe"],
23086
- signal,
23087
- timeout: 15000,
23088
- killSignal: "SIGKILL"
23089
- });
23090
- let stdout = "";
23091
- let stderr = "";
23092
- child.stdout.setEncoding("utf8");
23093
- child.stderr.setEncoding("utf8");
23094
- child.stdout.on("data", (chunk) => {
23095
- try {
23096
- stdout = appendElkOutput(stdout, chunk);
23097
- } catch (error) {
23098
- child.kill("SIGKILL");
23099
- reject(error);
23100
- }
23101
- });
23102
- child.stderr.on("data", (chunk) => {
23103
- try {
23104
- stderr = appendElkOutput(stderr, chunk);
23105
- } catch (error) {
23106
- child.kill("SIGKILL");
23107
- reject(error);
23108
- }
23109
- });
23110
- child.once("error", (error) => {
23111
- reject(error.code === "ENOENT" ? new Error("Node.js 20+ is required for the agent graph (Ctrl-G)") : error);
23112
- });
23113
- child.once("exit", (code, signal2) => {
23114
- if (code !== 0) {
23115
- reject(new Error(stderr.trim() || `ELK exited with ${signal2 ? `signal ${signal2}` : `code ${String(code)}`}`));
23116
- return;
23117
- }
23118
- try {
23119
- resolve19(JSON.parse(stdout));
23120
- } catch {
23121
- reject(new Error("ELK returned an invalid layout"));
23122
- }
23123
- });
23124
- child.stdin.end(JSON.stringify(input));
23125
- });
23126
- }
23127
- function rounded(value) {
23128
- return Math.max(0, Math.round(value ?? 0));
23129
- }
23130
- function edgeCharacter(existing, next, tell) {
23131
- const glyph = tell ? next === "horizontal" ? "\u2508" : "\u250A" : next === "horizontal" ? "\u2500" : "\u2502";
23132
- if (existing === " " || existing === glyph)
23133
- return glyph;
23134
- if ("\u2500\u2508".includes(existing) && next === "horizontal")
23135
- return existing;
23136
- if ("\u2502\u250A".includes(existing) && next === "vertical")
23137
- return existing;
23138
- return "\u253C";
23139
- }
23140
- function edgeMidpoint(points) {
23141
- const lengths = points.slice(1).map((point, index) => {
23142
- const previous = points[index];
23143
- return Math.abs(point.x - previous.x) + Math.abs(point.y - previous.y);
23084
+ async function layoutSubagentGraph(graph, spacing = DEFAULT_SUBAGENT_GRAPH_SPACING, signal) {
23085
+ const canvas = await layoutTerminalGraph(graph, {
23086
+ direction: "DOWN",
23087
+ spacing,
23088
+ signal,
23089
+ timeoutMs: 15000
23144
23090
  });
23145
- let remaining = lengths.reduce((sum, length) => sum + length, 0) / 2;
23146
- for (let index = 0;index < lengths.length; index += 1) {
23147
- const length = lengths[index];
23148
- const start = points[index];
23149
- const end = points[index + 1];
23150
- if (remaining <= length) {
23151
- const ratio = length === 0 ? 0 : remaining / length;
23152
- return {
23153
- x: Math.round(start.x + (end.x - start.x) * ratio),
23154
- y: Math.round(start.y + (end.y - start.y) * ratio)
23155
- };
23156
- }
23157
- remaining -= length;
23158
- }
23159
- return points.at(-1) ?? { x: 0, y: 0 };
23160
- }
23161
- function renderCanvas(graph, layout) {
23162
- const width = Math.max(1, rounded(layout.width) + 2);
23163
- const height = Math.max(1, rounded(layout.height) + 2);
23164
- const cells = Array.from({ length: height }, () => Array.from({ length: width }, () => " "));
23165
- const put = (x, y, value) => {
23166
- if (y < 0 || y >= height || x < 0 || x >= width)
23167
- return;
23168
- cells[y][x] = value;
23169
- };
23170
- const putText = (x, y, value, maxWidth) => {
23171
- let column = 0;
23172
- for (const character of [...value]) {
23173
- const width2 = displayWidth(character);
23174
- if (column + width2 > maxWidth)
23175
- break;
23176
- put(x + column, y, character);
23177
- if (width2 === 2)
23178
- put(x + column + 1, y, "");
23179
- column += width2;
23180
- }
23181
- };
23182
- const edgeById = new Map(graph.edges.map((edge) => [edge.id, edge]));
23183
- const edgeLabels = [];
23184
- const edges = [];
23185
- for (const laidOutEdge of layout.edges ?? []) {
23186
- const edge = edgeById.get(laidOutEdge.id);
23187
- if (!edge)
23188
- continue;
23189
- const edgeCells = new Map;
23190
- const recordEdgeCell = (x, y) => {
23191
- edgeCells.set(`${x}:${y}`, { x, y });
23192
- };
23193
- for (const section of laidOutEdge.sections ?? []) {
23194
- const points = [section.startPoint, ...section.bendPoints ?? [], section.endPoint].map((point) => ({ x: rounded(point.x) + 1, y: rounded(point.y) + 1 }));
23195
- for (let index = 1;index < points.length; index += 1) {
23196
- const from = points[index - 1];
23197
- const to = points[index];
23198
- const horizontal = from.y === to.y;
23199
- const distance = horizontal ? Math.abs(to.x - from.x) : Math.abs(to.y - from.y);
23200
- const xStep = horizontal ? Math.sign(to.x - from.x) : 0;
23201
- const yStep = horizontal ? 0 : Math.sign(to.y - from.y);
23202
- for (let offset = 0;offset <= distance; offset += 1) {
23203
- const x = from.x + xStep * offset;
23204
- const y = from.y + yStep * offset;
23205
- const existing = cells[y]?.[x] ?? " ";
23206
- put(x, y, edgeCharacter(existing, horizontal ? "horizontal" : "vertical", edge.kind === "tell" || edge.kind === "tell-bidirectional"));
23207
- recordEdgeCell(x, y);
23208
- }
23209
- }
23210
- const end = points.at(-1);
23211
- const before = points.at(-2);
23212
- if (end && before) {
23213
- const arrowX = end.x - Math.sign(end.x - before.x);
23214
- const arrowY = end.y - Math.sign(end.y - before.y);
23215
- const arrow = end.y > before.y ? "\u25BC" : end.y < before.y ? "\u25B2" : end.x > before.x ? "\u25B6" : "\u25C0";
23216
- put(arrowX, arrowY, arrow);
23217
- recordEdgeCell(arrowX, arrowY);
23218
- }
23219
- if (edge.kind === "owns" || edge.kind === "tell-bidirectional") {
23220
- const start = points[0];
23221
- const after = points[1];
23222
- if (start && after) {
23223
- const arrowX = start.x + Math.sign(after.x - start.x);
23224
- const arrowY = start.y + Math.sign(after.y - start.y);
23225
- const arrow = after.y > start.y ? "\u25B2" : after.y < start.y ? "\u25BC" : after.x > start.x ? "\u25C0" : "\u25B6";
23226
- put(arrowX, arrowY, arrow);
23227
- recordEdgeCell(arrowX, arrowY);
23228
- }
23229
- }
23230
- if ((edge.kind === "owns-parent-only" || edge.kind === "tell" || edge.kind === "tell-bidirectional") && points.length > 1) {
23231
- const middle = edgeMidpoint(points);
23232
- const label = edge.kind === "owns-parent-only" ? " status only \u2193 " : edge.kind === "tell-bidirectional" ? " tell \u2194 " : " tell ";
23233
- edgeLabels.push({
23234
- x: middle.x - Math.floor(label.length / 2),
23235
- y: middle.y,
23236
- text: label
23237
- });
23238
- }
23239
- }
23240
- edges.push({
23241
- sourceTopicId: edge.source,
23242
- targetTopicId: edge.target,
23243
- kind: edge.kind,
23244
- cells: [...edgeCells.values()]
23245
- });
23246
- }
23247
- for (const label of edgeLabels)
23248
- putText(label.x, label.y, label.text, textWidth(label.text));
23249
- const nodeById = new Map(graph.nodes.map((node) => [node.id, node]));
23250
- const nodes = [];
23251
- for (const laidOutNode of layout.children ?? []) {
23252
- const node = nodeById.get(laidOutNode.id);
23253
- if (!node)
23254
- continue;
23255
- const x = rounded(laidOutNode.x) + 1;
23256
- const y = rounded(laidOutNode.y) + 1;
23257
- const nodeWidth = Math.max(4, rounded(laidOutNode.width));
23258
- const nodeHeight = Math.max(4, rounded(laidOutNode.height));
23259
- for (let row = 0;row < nodeHeight; row += 1) {
23260
- for (let column = 0;column < nodeWidth; column += 1)
23261
- put(x + column, y + row, " ");
23262
- }
23263
- put(x, y, "\u256D");
23264
- put(x + nodeWidth - 1, y, "\u256E");
23265
- put(x, y + nodeHeight - 1, "\u2570");
23266
- put(x + nodeWidth - 1, y + nodeHeight - 1, "\u256F");
23267
- for (let column = 1;column < nodeWidth - 1; column += 1) {
23268
- put(x + column, y, "\u2500");
23269
- put(x + column, y + nodeHeight - 1, "\u2500");
23270
- }
23271
- for (let row = 1;row < nodeHeight - 1; row += 1) {
23272
- put(x, y + row, "\u2502");
23273
- put(x + nodeWidth - 1, y + row, "\u2502");
23274
- }
23275
- putText(x + 2, y + 1, `${node.running ? "\u25CF" : "\u25CB"} ${node.title}`, nodeWidth - 3);
23276
- putText(x + 2, y + 2, node.detail, nodeWidth - 3);
23277
- nodes.push({
23278
- topicId: node.id,
23279
- title: node.title,
23280
- markerX: x + 2,
23281
- markerY: y + 1
23282
- });
23283
- }
23284
23091
  return {
23285
- title: graph.rootTitle,
23286
- rootDetail: graph.nodes[0]?.detail,
23287
- rootRunning: graph.nodes[0]?.running,
23288
- nodes,
23289
- edges,
23290
- lines: cells.map((row) => row.join("").trimEnd()),
23291
- width,
23292
- height
23092
+ ...canvas,
23093
+ title: graph.title,
23094
+ rootDetail: graph.rootDetail,
23095
+ rootRunning: graph.rootRunning,
23096
+ edges: canvas.edges.map(({ kind, ...edge }) => isSubagentGraphEdgeKind(kind) ? { ...edge, kind } : edge)
23293
23097
  };
23294
23098
  }
23295
- async function layoutSubagentGraph(graph, spacing = DEFAULT_SUBAGENT_GRAPH_SPACING, signal) {
23296
- if (graph.nodes.length === 0) {
23297
- return { title: graph.rootTitle, lines: [], width: 0, height: 0 };
23298
- }
23299
- return renderCanvas(graph, await runElk(layoutInput(graph, spacing), signal));
23300
- }
23301
- var DEFAULT_SUBAGENT_GRAPH_SPACING = 4, MIN_SUBAGENT_GRAPH_SPACING = 2, MAX_SUBAGENT_GRAPH_SPACING = 10, ELK_HOST_SOURCE = `
23302
- const modulePath = process.argv[1];
23303
- const imported = require(modulePath);
23304
- const ELK = imported.default || imported;
23305
- let input = "";
23306
- process.stdin.setEncoding("utf8");
23307
- process.stdin.on("data", (chunk) => input += chunk);
23308
- process.stdin.on("end", async () => {
23309
- try {
23310
- const result = await new ELK().layout(JSON.parse(input));
23311
- process.stdout.write(JSON.stringify(result));
23312
- } catch (error) {
23313
- process.stderr.write(error && error.stack ? error.stack : String(error));
23314
- process.exitCode = 1;
23315
- }
23316
- });
23317
- `, MAX_ELK_OUTPUT_BYTES;
23318
- var init_subagent_graph = __esm(() => {
23319
- MAX_ELK_OUTPUT_BYTES = 1024 * 1024;
23320
- });
23099
+ var DEFAULT_SUBAGENT_GRAPH_SPACING = 4, MIN_SUBAGENT_GRAPH_SPACING = 2, MAX_SUBAGENT_GRAPH_SPACING = 10;
23100
+ var init_subagent_graph = () => {};
23321
23101
 
23322
23102
  // ../../adapters/terminal/src/state.ts
23323
23103
  function createInitialState(userId) {
@@ -23813,6 +23593,23 @@ var init_state2 = __esm(async () => {
23813
23593
  init_subagent_graph();
23814
23594
  });
23815
23595
 
23596
+ // ../../adapters/terminal/src/terminal-width.ts
23597
+ function stripAnsi(value) {
23598
+ return value.replace(new RegExp("\\u001b\\[[0-?]*[ -/]*[@-~]", "g"), "");
23599
+ }
23600
+ function runeWidth(char) {
23601
+ const code = char.codePointAt(0) ?? 0;
23602
+ if (code === 8205 || code >= 65024 && code <= 65039)
23603
+ return 0;
23604
+ if (code >= 4352 && (code <= 4447 || code === 9001 || code === 9002 || code >= 11904 && code <= 42191 || code >= 44032 && code <= 55203 || code >= 63744 && code <= 64255 || code >= 65040 && code <= 65135 || code >= 65280 && code <= 65376 || code >= 127744 && code <= 129791 || code >= 131072)) {
23605
+ return 2;
23606
+ }
23607
+ return 1;
23608
+ }
23609
+ function displayWidth(value) {
23610
+ return [...stripAnsi(value)].reduce((width, char) => width + runeWidth(char), 0);
23611
+ }
23612
+
23816
23613
  // ../../adapters/terminal/src/render.ts
23817
23614
  function workingFrame(frame) {
23818
23615
  const index = Math.abs(Math.trunc(frame)) % WORKING_FRAMES.length;
@@ -24503,14 +24300,14 @@ function subagentGraphLines(state, width, height, animationFrame) {
24503
24300
  const position = maxX > 0 || maxY > 0 ? ` \xB7 view ${x + 1},${y + 1}/${maxX + 1},${maxY + 1}` : "";
24504
24301
  const graphNodes = canvas?.nodes ?? [];
24505
24302
  const graphEdges = canvas?.edges ?? [];
24506
- const runningNodes = graphNodes.filter((node) => state.activity[node.topicId]?.running);
24507
- const nodeTitleById = new Map(graphNodes.map((node) => [node.topicId, node.title]));
24303
+ const runningNodes = graphNodes.filter((node) => state.activity[node.id]?.running);
24304
+ const nodeTitleById = new Map(graphNodes.map((node) => [node.id, node.label]));
24508
24305
  const hasActiveTell = (sourceTopicId, targetTopicId) => {
24509
24306
  const targetTitle = nodeTitleById.get(targetTopicId);
24510
24307
  const activity = state.activity[sourceTopicId];
24511
24308
  return Boolean(activity?.running && activity.tools.some((tool) => tool.sessionAction === "tell" && (tool.sessionTarget === targetTopicId || tool.sessionTarget === targetTitle)));
24512
24309
  };
24513
- const activeEdges = graphEdges.filter((edge) => hasActiveTell(edge.sourceTopicId, edge.targetTopicId) || (edge.kind === "owns" || edge.kind === "tell-bidirectional") && hasActiveTell(edge.targetTopicId, edge.sourceTopicId));
24310
+ const activeEdges = graphEdges.filter((edge) => hasActiveTell(edge.source, edge.target) || (edge.kind === "owns" || edge.kind === "tell-bidirectional") && hasActiveTell(edge.target, edge.source));
24514
24311
  const highlightedCellsByRow = new Map;
24515
24312
  for (const edge of activeEdges) {
24516
24313
  for (const cell of edge.cells) {
@@ -24519,7 +24316,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
24519
24316
  highlightedCellsByRow.set(cell.y, columns);
24520
24317
  }
24521
24318
  }
24522
- const rootTopicId = graphNodes[0]?.topicId;
24319
+ const rootTopicId = graphNodes[0]?.id;
24523
24320
  const rootRunning = rootTopicId ? Boolean(state.activity[rootTopicId]?.running) : Boolean(canvas?.rootRunning);
24524
24321
  const header = [
24525
24322
  line(" Agent graph", {
@@ -24527,7 +24324,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
24527
24324
  bold: true
24528
24325
  }),
24529
24326
  line(canvas ? ` ${rootRunning ? workingFrame(animationFrame) : "\u25CB"} ${canvas.title}${canvas.rootDetail ? ` \xB7 ${canvas.rootDetail}` : ""}` : " Current topic", { fg: rootRunning ? theme.green : theme.text, bold: true }),
24530
- line(runningNodes.length > 0 ? ` Working: ${runningNodes.map((node) => node.title).join(", ")}` : " Working: none", { fg: runningNodes.length > 0 ? theme.green : theme.muted }),
24327
+ line(runningNodes.length > 0 ? ` Working: ${runningNodes.map((node) => node.label).join(", ")}` : " Working: none", { fg: runningNodes.length > 0 ? theme.green : theme.muted }),
24531
24328
  line(` [/] spacing ${state.subagentGraphSpacing} \xB7 drag: all directions \xB7 wheel: up/down \xB7 arrows/hjkl move \xB7 Ctrl-G/Esc close${position}`, {
24532
24329
  fg: theme.muted
24533
24330
  }),
@@ -24537,7 +24334,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
24537
24334
  line("")
24538
24335
  ];
24539
24336
  if (state.subagentGraphLoading) {
24540
- return [...header, line(" Laying out graph with ELK\u2026", { fg: theme.cyan })].slice(0, height);
24337
+ return [...header, line(" Laying out graph with Orchgraph\u2026", { fg: theme.cyan })].slice(0, height);
24541
24338
  }
24542
24339
  if (!canvas || canvas.lines.length === 0) {
24543
24340
  return [...header, line(" No graph data", { fg: theme.muted })].slice(0, height);
@@ -24550,7 +24347,7 @@ function subagentGraphLines(state, width, height, animationFrame) {
24550
24347
  for (const node of graphNodes) {
24551
24348
  if (node.markerY !== canvasY)
24552
24349
  continue;
24553
- const marker = state.activity[node.topicId]?.running ? workingFrame(animationFrame) : "\u25CB";
24350
+ const marker = state.activity[node.id]?.running ? workingFrame(animationFrame) : "\u25CB";
24554
24351
  canvasLine = replaceAtDisplayColumn(canvasLine, node.markerX, marker);
24555
24352
  }
24556
24353
  const text2 = sliceWidthRange(canvasLine, x, viewportWidth);
@@ -36161,4 +35958,4 @@ switch (command) {
36161
35958
  }
36162
35959
  }
36163
35960
 
36164
- //# debugId=DC511282561B4D1A64756E2164756E21
35961
+ //# debugId=6D26E247972E960464756E2164756E21