@lambdacurry/arbor 0.22.29 → 0.22.31
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/arbor.js +97 -13
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// package.json
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@lambdacurry/arbor",
|
|
5
|
-
version: "0.22.
|
|
5
|
+
version: "0.22.31",
|
|
6
6
|
description: "The Arbor CLI — a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
|
|
7
7
|
keywords: [
|
|
8
8
|
"agents",
|
|
@@ -9946,6 +9946,8 @@ ${orientation}
|
|
|
9946
9946
|
|
|
9947
9947
|
// ../actions/src/tldraw-agent.ts
|
|
9948
9948
|
var TLDRAW_EXEC_MAX_OPERATIONS = 100;
|
|
9949
|
+
var TLDRAW_DIAGRAM_MAX_NODES = 64;
|
|
9950
|
+
var TLDRAW_DIAGRAM_MAX_EDGES = 96;
|
|
9949
9951
|
var shapeId = string2().regex(/^shape:[A-Za-z0-9_-]{1,128}$/).describe("stable tldraw shape id, shape:…");
|
|
9950
9952
|
var shapeType = _enum(["geo", "text", "note", "frame", "arrow", "line", "draw", "group"]).describe("built-in tldraw shape type; use code mode for custom or asset-backed shapes");
|
|
9951
9953
|
var finite = number2().finite();
|
|
@@ -9977,6 +9979,21 @@ var update = object({
|
|
|
9977
9979
|
meta: jsonRecord.optional()
|
|
9978
9980
|
}).strict();
|
|
9979
9981
|
var shapeIds = array(shapeId).min(1).max(TLDRAW_EXEC_MAX_OPERATIONS);
|
|
9982
|
+
var diagramKey = string2().min(1).max(80).describe("caller-meaningful node key; returned as the alias for its generated tldraw shape id");
|
|
9983
|
+
var diagramLabel = string2().min(1).max(160);
|
|
9984
|
+
var diagram = object({
|
|
9985
|
+
op: literal("diagram"),
|
|
9986
|
+
direction: _enum(["LR", "RL", "TB", "BT"]).describe("graph reading direction: left/right or top/bottom"),
|
|
9987
|
+
nodes: array(object({
|
|
9988
|
+
key: diagramKey,
|
|
9989
|
+
label: diagramLabel
|
|
9990
|
+
}).strict()).min(1).max(TLDRAW_DIAGRAM_MAX_NODES),
|
|
9991
|
+
edges: array(object({
|
|
9992
|
+
from: diagramKey,
|
|
9993
|
+
to: diagramKey,
|
|
9994
|
+
label: diagramLabel.optional()
|
|
9995
|
+
}).strict()).max(TLDRAW_DIAGRAM_MAX_EDGES)
|
|
9996
|
+
}).strict();
|
|
9980
9997
|
var TLDRAW_EXEC_OPERATION_SCHEMA = discriminatedUnion("op", [
|
|
9981
9998
|
create,
|
|
9982
9999
|
update,
|
|
@@ -9995,10 +10012,14 @@ var TLDRAW_EXEC_OPERATION_SCHEMA = discriminatedUnion("op", [
|
|
|
9995
10012
|
op: literal("group"),
|
|
9996
10013
|
ids: shapeIds.min(2),
|
|
9997
10014
|
groupId: shapeId.optional()
|
|
9998
|
-
}).strict()
|
|
10015
|
+
}).strict(),
|
|
10016
|
+
diagram
|
|
9999
10017
|
]);
|
|
10000
10018
|
var TLDRAW_EXEC_OPERATIONS_SCHEMA = array(TLDRAW_EXEC_OPERATION_SCHEMA).min(1).max(TLDRAW_EXEC_MAX_OPERATIONS).superRefine((operations, ctx) => {
|
|
10001
10019
|
const createdIds = new Set;
|
|
10020
|
+
const diagramKeys = new Set;
|
|
10021
|
+
let totalDiagramNodes = 0;
|
|
10022
|
+
let totalDiagramEdges = 0;
|
|
10002
10023
|
operations.forEach((operation, index) => {
|
|
10003
10024
|
if (operation.op === "create") {
|
|
10004
10025
|
if (createdIds.has(operation.id)) {
|
|
@@ -10023,6 +10044,61 @@ var TLDRAW_EXEC_OPERATIONS_SCHEMA = array(TLDRAW_EXEC_OPERATION_SCHEMA).min(1).m
|
|
|
10023
10044
|
seen.add(id);
|
|
10024
10045
|
});
|
|
10025
10046
|
}
|
|
10047
|
+
if (operation.op === "diagram") {
|
|
10048
|
+
const previousNodeTotal = totalDiagramNodes;
|
|
10049
|
+
const previousEdgeTotal = totalDiagramEdges;
|
|
10050
|
+
totalDiagramNodes += operation.nodes.length;
|
|
10051
|
+
totalDiagramEdges += operation.edges.length;
|
|
10052
|
+
if (previousNodeTotal <= TLDRAW_DIAGRAM_MAX_NODES && totalDiagramNodes > TLDRAW_DIAGRAM_MAX_NODES) {
|
|
10053
|
+
ctx.addIssue({
|
|
10054
|
+
code: "custom",
|
|
10055
|
+
message: `diagram nodes exceed execution limit: ${TLDRAW_DIAGRAM_MAX_NODES}`,
|
|
10056
|
+
path: [index, "nodes"]
|
|
10057
|
+
});
|
|
10058
|
+
}
|
|
10059
|
+
if (previousEdgeTotal <= TLDRAW_DIAGRAM_MAX_EDGES && totalDiagramEdges > TLDRAW_DIAGRAM_MAX_EDGES) {
|
|
10060
|
+
ctx.addIssue({
|
|
10061
|
+
code: "custom",
|
|
10062
|
+
message: `diagram edges exceed execution limit: ${TLDRAW_DIAGRAM_MAX_EDGES}`,
|
|
10063
|
+
path: [index, "edges"]
|
|
10064
|
+
});
|
|
10065
|
+
}
|
|
10066
|
+
const keys = new Set;
|
|
10067
|
+
operation.nodes.forEach((node, nodeIndex) => {
|
|
10068
|
+
if (keys.has(node.key)) {
|
|
10069
|
+
ctx.addIssue({
|
|
10070
|
+
code: "custom",
|
|
10071
|
+
message: `duplicate diagram node key: ${node.key}`,
|
|
10072
|
+
path: [index, "nodes", nodeIndex, "key"]
|
|
10073
|
+
});
|
|
10074
|
+
}
|
|
10075
|
+
if (diagramKeys.has(node.key)) {
|
|
10076
|
+
ctx.addIssue({
|
|
10077
|
+
code: "custom",
|
|
10078
|
+
message: `diagram node key is already used in this execution: ${node.key}`,
|
|
10079
|
+
path: [index, "nodes", nodeIndex, "key"]
|
|
10080
|
+
});
|
|
10081
|
+
}
|
|
10082
|
+
keys.add(node.key);
|
|
10083
|
+
diagramKeys.add(node.key);
|
|
10084
|
+
});
|
|
10085
|
+
operation.edges.forEach((edge, edgeIndex) => {
|
|
10086
|
+
if (!keys.has(edge.from)) {
|
|
10087
|
+
ctx.addIssue({
|
|
10088
|
+
code: "custom",
|
|
10089
|
+
message: `diagram edge source does not name a node: ${edge.from}`,
|
|
10090
|
+
path: [index, "edges", edgeIndex, "from"]
|
|
10091
|
+
});
|
|
10092
|
+
}
|
|
10093
|
+
if (!keys.has(edge.to)) {
|
|
10094
|
+
ctx.addIssue({
|
|
10095
|
+
code: "custom",
|
|
10096
|
+
message: `diagram edge target does not name a node: ${edge.to}`,
|
|
10097
|
+
path: [index, "edges", edgeIndex, "to"]
|
|
10098
|
+
});
|
|
10099
|
+
}
|
|
10100
|
+
});
|
|
10101
|
+
}
|
|
10026
10102
|
});
|
|
10027
10103
|
}).describe("preferred declarative edits, applied in order; mutually exclusive with code");
|
|
10028
10104
|
// ../actions/src/index.ts
|
|
@@ -10054,7 +10130,7 @@ Arbor's MCP is the collaboration and durable-knowledge surface. Configure, autho
|
|
|
10054
10130
|
|
|
10055
10131
|
Run \`arbor help\` (or read the MCP tool list) for the exact command/flags — those stay generated from the live action surface, so they're always current.`;
|
|
10056
10132
|
var ARBOR_SKILL_MARKDOWN = renderArborSkill(ORIENTATION);
|
|
10057
|
-
var COMPUTER_ORIENTATION = `Long Computer work returns a processId handle — do not hold one tool call for a full test or build. \`computer_exec\` runs a command; if the result is still running, observe it with \`computer_process_read\`; read a truncated continuation only when you need more output. Finish and suspend preserve unread terminal output internally, with original process IDs/cursors recoverable for 30 days. Do not chain \`pnpm test && pnpm build\` in one exec; split steps or pass \`background:true\`.
|
|
10133
|
+
var COMPUTER_ORIENTATION = `Long Computer work returns a processId handle — do not hold one tool call for a full test or build. \`computer_exec\` runs a command; if the result is still running, observe it with \`computer_process_read\`; read a truncated continuation only when you need more output. Finish and suspend preserve unread terminal output internally, with original process IDs/cursors recoverable for 30 days. Do not chain \`pnpm test && pnpm build\` in one exec; split steps or pass \`background:true\`. An explicit waitForTerminalMs uses one server wait and canonical output page; otherwise the CLI polls only while the process is silent unless \`--no-wait\`. It never concatenates continuation pages into one agent context.
|
|
10058
10134
|
|
|
10059
10135
|
Arbor Computer is the complete software execution platform attached to Arbor's durable collaboration graph. It configures project environments, executes and verifies work, packages and releases Apps, and preserves reviewable evidence; it does not schedule agents or replace Arbor collaboration.
|
|
10060
10136
|
|
|
@@ -10878,16 +10954,17 @@ var ACTION_DEFINITIONS = [
|
|
|
10878
10954
|
{
|
|
10879
10955
|
name: "computer_exec",
|
|
10880
10956
|
title: "Run a command",
|
|
10881
|
-
description: "Run a shell command in runId with ambient GitHub authorization
|
|
10957
|
+
description: "Run a shell command in runId with ambient GitHub authorization; timeout kills the process. Use waitForTerminalMs for immediate or bounded native observation, then continue with computer_process_read and nextCursor for a truncated output page; background is mutually exclusive, and after response loss read computer_run_receipt.operations[].operationId instead of repeating the mutation.",
|
|
10882
10958
|
inputSchema: {
|
|
10883
10959
|
computerSessionId: string2().optional().describe("legacy alternative to runId: a computerSessionId on that Computer, cms_…; required unless runId is supplied"),
|
|
10884
10960
|
command: string2().min(1).describe("the shell command to run"),
|
|
10885
10961
|
runId: string2().optional().describe("route this command according to this Run execution placement, run_… (from computer_run_start)"),
|
|
10886
10962
|
cwd: string2().optional().describe("working directory under /workspace, or under the run; omit to use defaultCwd"),
|
|
10887
10963
|
timeout: number2().int().min(1000).max(1800000).optional().describe("process kill deadline in milliseconds, from 1,000 through 1,800,000 — not the RPC hold"),
|
|
10888
|
-
background: boolean2().optional().describe("start the process and return immediately without the short RPC wait"),
|
|
10889
|
-
|
|
10890
|
-
|
|
10964
|
+
background: boolean2().optional().describe("start the process and return immediately without the short RPC wait; mutually exclusive with waitForTerminalMs"),
|
|
10965
|
+
waitForTerminalMs: number2().int().min(0).max(45000).optional().describe("explicit terminal-observation window from 0 through 45,000 milliseconds; 0 returns immediately, a positive value returns one canonical output page when the native wait ends or expires, and descendants may keep the result running; mutually exclusive with background"),
|
|
10966
|
+
activityLabel: string2().min(1).max(COMPUTER_RUN_ACTIVITY_LABEL_MAX).optional().describe("short human-readable label for retained run-scoped work selected by background or waitForTerminalMs; Arbor records this label instead of the raw command or output"),
|
|
10967
|
+
activityKind: literal("verification").optional().describe("mark labeled retained run-scoped work as a verification check; its provider-observed terminal result is recorded as verification.finished"),
|
|
10891
10968
|
strict: boolean2().optional().describe("fail on the first unhandled command or pipeline failure; defaults to true, set false only for intentional best-effort execution")
|
|
10892
10969
|
},
|
|
10893
10970
|
surfaces: ["computer-mcp", "computer-cli"],
|
|
@@ -10897,13 +10974,14 @@ var ACTION_DEFINITIONS = [
|
|
|
10897
10974
|
{
|
|
10898
10975
|
name: "computer_process_read",
|
|
10899
10976
|
title: "Read a background process",
|
|
10900
|
-
description: "Read
|
|
10977
|
+
description: "Read process output with nextCursor; preserved bytes remain available for 30 days after preservation, including repeated cursors after finish/suspend, without provider wake. waitForTerminalMs adds one bounded native observation and page; expiry or descendants may still run, transport failure stays unknown/unsafe, and Arbor settles the durable operation only from terminal or exact absence proof.",
|
|
10901
10978
|
inputSchema: {
|
|
10902
10979
|
computerSessionId: string2().optional().describe("legacy alternative to runId: a computerSessionId on that Computer, cms_…; required unless runId is supplied"),
|
|
10903
10980
|
runId: string2().optional().describe("the Run that owns this process, if it was started inside a Run"),
|
|
10904
10981
|
processId: string2().min(1).describe("the processId returned by background exec, or matching computer_run_receipt.operations[].operationId for recovered foreground Run work, proc_…"),
|
|
10905
10982
|
cursor: string2().optional().describe("continue after nextCursor from the prior result; omit to read from the beginning"),
|
|
10906
|
-
maxBytes: number2().int().min(1024).max(65536).optional().describe("maximum combined output bytes to return; default 4,096, opt up only when needed")
|
|
10983
|
+
maxBytes: number2().int().min(1024).max(65536).optional().describe("maximum combined output bytes to return; default 4,096, opt up only when needed"),
|
|
10984
|
+
waitForTerminalMs: number2().int().min(0).max(45000).optional().describe("use one native terminal-observation window up to this many milliseconds, then return one canonical output page; 0 is immediate, surviving descendants may remain running, and omission preserves the current read behavior")
|
|
10907
10985
|
},
|
|
10908
10986
|
surfaces: ["computer-mcp", "computer-cli"],
|
|
10909
10987
|
toolset: "loop",
|
|
@@ -12267,7 +12345,7 @@ var ACTION_DEFINITIONS = [
|
|
|
12267
12345
|
{
|
|
12268
12346
|
name: "tldraw_exec",
|
|
12269
12347
|
title: "Run a one-shot tldraw program",
|
|
12270
|
-
description: `Modify the current live tldraw board with preferred declarative operations or bounded JavaScript, then return a durable execution receipt; use IDs from a fresh observe, reacquire this current schema after compaction, and never replay an unknown result. First use: read the tldraw guide at ${AGENT_GUIDE_URLS.tldraw}.`,
|
|
12348
|
+
description: `Modify the current live tldraw board with preferred declarative operations or bounded JavaScript, including a graph-scoped diagram operation that lays out keyed nodes and native bound edges without caller-supplied coordinates, then return a durable execution receipt; use IDs from a fresh observe, reacquire this current schema after compaction, and never replay an unknown result. First use: read the tldraw guide at ${AGENT_GUIDE_URLS.tldraw}.`,
|
|
12271
12349
|
inputSchema: {
|
|
12272
12350
|
artifactId: string2().describe("the tldraw Artifact, art_…"),
|
|
12273
12351
|
code: string2().min(1).max(1e5).optional().describe("advanced script source; mutually exclusive with operations"),
|
|
@@ -14073,7 +14151,7 @@ Alias: \`arbor ${aliases[0]}\` (the tool-name form) resolves to this same comman
|
|
|
14073
14151
|
Aliases: ${aliases.map((alias) => `\`arbor ${alias}\``).join(", ")} (tool-name forms) resolve to this same command.` : "";
|
|
14074
14152
|
const heading = `${commandWords(action)}${aliases.length === 1 ? ` (alias: ${aliases[0]})` : aliases.length > 1 ? ` (aliases: ${aliases.join(", ")})` : ""}`;
|
|
14075
14153
|
const waitLines = action.name === "computer_exec" ? [
|
|
14076
|
-
" --no-wait [<boolean>] [optional] — return a running processId immediately instead of polling computer_process_read"
|
|
14154
|
+
" --no-wait [<boolean>] [optional] — return a running processId immediately instead of polling computer_process_read; mutually exclusive with --wait-for-terminal-ms"
|
|
14077
14155
|
] : [];
|
|
14078
14156
|
return `${heading} — ${action.description}
|
|
14079
14157
|
|
|
@@ -14102,7 +14180,7 @@ function commandCatalog() {
|
|
|
14102
14180
|
kind: "boolean",
|
|
14103
14181
|
required: false,
|
|
14104
14182
|
acceptsFile: false,
|
|
14105
|
-
description: "return a running processId immediately instead of polling computer_process_read"
|
|
14183
|
+
description: "return a running processId immediately instead of polling computer_process_read; mutually exclusive with --wait-for-terminal-ms"
|
|
14106
14184
|
}
|
|
14107
14185
|
] : []
|
|
14108
14186
|
]
|
|
@@ -14164,6 +14242,12 @@ async function runObjectVerb(positionals, flags, ctx) {
|
|
|
14164
14242
|
delete inputFlags.json;
|
|
14165
14243
|
}
|
|
14166
14244
|
const input = buildInput(action.inputSchema, inputFlags, commandWords(action));
|
|
14245
|
+
if (action.name === "computer_exec" && flags["no-wait"] !== undefined && input.waitForTerminalMs !== undefined) {
|
|
14246
|
+
throw new UsageError("--no-wait and --wait-for-terminal-ms are mutually exclusive", {
|
|
14247
|
+
reason: "validation.invalid_value",
|
|
14248
|
+
field: "waitForTerminalMs"
|
|
14249
|
+
});
|
|
14250
|
+
}
|
|
14167
14251
|
if (action.name === "app_request" && input.json !== undefined) {
|
|
14168
14252
|
if (input.body !== undefined) {
|
|
14169
14253
|
throw new UsageError("--json and --body are mutually exclusive", {
|
|
@@ -14185,7 +14269,7 @@ async function runObjectVerb(positionals, flags, ctx) {
|
|
|
14185
14269
|
`, ctx);
|
|
14186
14270
|
}
|
|
14187
14271
|
let value = await action.run(httpExecutor, input);
|
|
14188
|
-
if (action.name === "computer_exec" && !truthyFlag(flags["no-wait"])) {
|
|
14272
|
+
if (action.name === "computer_exec" && !truthyFlag(flags["no-wait"]) && input.waitForTerminalMs === undefined) {
|
|
14189
14273
|
value = await waitForComputerExec(httpExecutor, input, value, ctx);
|
|
14190
14274
|
}
|
|
14191
14275
|
emitData(shapeActionOutput(action.name, value, input), action.name, ctx);
|
package/package.json
CHANGED