@lambdacurry/arbor 0.21.8 → 0.21.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/arbor.js +187 -25
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -17864,6 +17864,7 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
17864
17864
|
}),
|
|
17865
17865
|
admin_feedback_capability: jsonObject,
|
|
17866
17866
|
admin_feedback_evidence: jsonObject,
|
|
17867
|
+
admin_feedback: jsonObject,
|
|
17867
17868
|
admin_feedback_topic: jsonObject,
|
|
17868
17869
|
admin_feedback_thread: jsonObject,
|
|
17869
17870
|
admin_feedback_publish: jsonObject,
|
|
@@ -18364,7 +18365,9 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
18364
18365
|
exitCode: exports_external.number().optional(),
|
|
18365
18366
|
processId: exports_external.string().optional(),
|
|
18366
18367
|
status: exports_external.string().optional(),
|
|
18367
|
-
cwd: exports_external.string().optional()
|
|
18368
|
+
cwd: exports_external.string().optional(),
|
|
18369
|
+
execution: exports_external.enum(["completed", "running"]).optional(),
|
|
18370
|
+
nextAction: exports_external.literal("computer_process_read").optional()
|
|
18368
18371
|
}),
|
|
18369
18372
|
computer_process_read: exports_external.looseObject({
|
|
18370
18373
|
status: exports_external.string(),
|
|
@@ -18681,6 +18684,8 @@ var OUTPUT_SHAPERS = {
|
|
|
18681
18684
|
["exitCode", result.exitCode],
|
|
18682
18685
|
["processId", result.processId],
|
|
18683
18686
|
["status", result.status],
|
|
18687
|
+
["execution", result.execution],
|
|
18688
|
+
["nextAction", result.nextAction],
|
|
18684
18689
|
["cwd", input.cwd === undefined ? result.cwd : undefined]
|
|
18685
18690
|
]),
|
|
18686
18691
|
computer_process_read: (result) => defined([
|
|
@@ -18770,6 +18775,7 @@ var MCP_TOOL_ANNOTATIONS = {
|
|
|
18770
18775
|
feedback_status: readOnly,
|
|
18771
18776
|
admin_feedback_capability: destructiveIdempotent,
|
|
18772
18777
|
admin_feedback_evidence: destructive,
|
|
18778
|
+
admin_feedback: destructive,
|
|
18773
18779
|
admin_feedback_topic: destructive,
|
|
18774
18780
|
admin_feedback_thread: destructive,
|
|
18775
18781
|
admin_feedback_publish: additive,
|
|
@@ -18904,7 +18910,9 @@ Arbor's MCP is the collaboration and durable-knowledge surface. Configure, autho
|
|
|
18904
18910
|
8. DURABLE OUTPUT IS AN ARTIFACT, NOT A LONG CONTRIBUTION (AD-201). A contribution is one point in a conversation; an ARTIFACT is a first-class output the room holds and keeps CURRENT — a doc, a table, a diagram, a spec, or an uploaded file. When your point is really a deliverable the team will read or UPDATE later — a table of options, a reference doc, a plan, a rubric — make it an artifact (\`artifact\` verb=create with kind doc/table/diagram/html + \`source\`, or promote a file) instead of pasting it into prose. Text-kind artifacts are LIVING: \`artifact_get\` it, then \`artifact\` verb=edit naming the \`baseVersion\` you read — patches apply exact-match and atomically, one version per call, every version attributed. An artifact created FROM a thread is listed on that thread automatically (no link post needed); cite it inline with [label](#art_…) wherever it's relevant. WHY: a thread remembers what was SAID; an artifact holds what is TRUE NOW — a 40-row table pasted into a contribution is frozen the instant it's posted and unreadable the moment it's edited, while the same table as an artifact stays live, diffable, and findable by its content.
|
|
18905
18911
|
|
|
18906
18912
|
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.`;
|
|
18907
|
-
var COMPUTER_ORIENTATION = `
|
|
18913
|
+
var COMPUTER_ORIENTATION = `Long Computer work returns a handle — do not hold one tool call for a full test or build. \`computer_exec\` runs a command; if the result is still running, take \`processId\` and poll \`computer_process_read\`. Do not chain \`pnpm test && pnpm build\` in one exec; split steps or pass \`background:true\`. The CLI waits on the same handle unless \`--no-wait\`.
|
|
18914
|
+
|
|
18915
|
+
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.
|
|
18908
18916
|
|
|
18909
18917
|
${ARBOR_FEEDBACK_GUIDANCE}
|
|
18910
18918
|
|
|
@@ -18938,6 +18946,49 @@ function dispatch(map2, reshape) {
|
|
|
18938
18946
|
return ex.call(op, reshape && verb ? reshape(verb, rest) : rest);
|
|
18939
18947
|
};
|
|
18940
18948
|
}
|
|
18949
|
+
var ADMIN_FEEDBACK_VERBS = [
|
|
18950
|
+
"publish",
|
|
18951
|
+
"merge",
|
|
18952
|
+
"transition",
|
|
18953
|
+
"edit",
|
|
18954
|
+
"curate",
|
|
18955
|
+
"topic",
|
|
18956
|
+
"create",
|
|
18957
|
+
"update",
|
|
18958
|
+
"move",
|
|
18959
|
+
"archive",
|
|
18960
|
+
"restore"
|
|
18961
|
+
];
|
|
18962
|
+
var ADMIN_FEEDBACK_THREAD_VERBS = new Set([
|
|
18963
|
+
"create",
|
|
18964
|
+
"update",
|
|
18965
|
+
"move",
|
|
18966
|
+
"transition",
|
|
18967
|
+
"archive",
|
|
18968
|
+
"restore",
|
|
18969
|
+
"merge"
|
|
18970
|
+
]);
|
|
18971
|
+
var ADMIN_FEEDBACK_VERB_HELP = ADMIN_FEEDBACK_VERBS.join(" | ");
|
|
18972
|
+
function runAdminFeedback(ex, input) {
|
|
18973
|
+
const { verb, ...rest } = input;
|
|
18974
|
+
if (verb === "curate") {
|
|
18975
|
+
if (rest.curate === "delete")
|
|
18976
|
+
return ex.call("feedback_admin.remove", rest);
|
|
18977
|
+
if (rest.curate === "restore")
|
|
18978
|
+
return ex.call("feedback_admin.restore", rest);
|
|
18979
|
+
return Promise.reject(new Error('curate requires curate "delete" or "restore"'));
|
|
18980
|
+
}
|
|
18981
|
+
if (verb && ADMIN_FEEDBACK_THREAD_VERBS.has(verb)) {
|
|
18982
|
+
return ex.call("feedback_admin.thread", { ...rest, action: verb });
|
|
18983
|
+
}
|
|
18984
|
+
if (verb === "publish")
|
|
18985
|
+
return ex.call("feedback_admin.publish", rest);
|
|
18986
|
+
if (verb === "edit")
|
|
18987
|
+
return ex.call("feedback_admin.edit", rest);
|
|
18988
|
+
if (verb === "topic")
|
|
18989
|
+
return ex.call("feedback_admin.topic", rest);
|
|
18990
|
+
return Promise.reject(new Error(`unknown verb "${verb ?? ""}" — expected one of: ${ADMIN_FEEDBACK_VERB_HELP}`));
|
|
18991
|
+
}
|
|
18941
18992
|
var NOTIFICATION_TRIAGE_DESCRIPTION = "READ ONLY: List your awareness feed newest first with unseen count and derived triage class: `settled-context` = settled Thread context; `owed-by-me` = an open request pointing to `inbox`; `judgment-available` = live engagement inviting judgment; `closed-loop` = your request completed; `room-motion` = ambient activity. Notifications are FYI, not a second obligation surface: `inbox` alone contains work owed by you; this cannot mark notifications read or modify inbox obligations.";
|
|
18942
18993
|
var PAGINATION_INPUT = {
|
|
18943
18994
|
limit: exports_external.number().int().min(1).optional().describe("max items to return — enables pagination"),
|
|
@@ -19129,6 +19180,36 @@ var ACTION_DEFINITIONS = [
|
|
|
19129
19180
|
status: "feedback_admin.status"
|
|
19130
19181
|
})
|
|
19131
19182
|
},
|
|
19183
|
+
{
|
|
19184
|
+
name: "admin_feedback",
|
|
19185
|
+
title: "Moderate shared Arbor Feedback",
|
|
19186
|
+
description: "After a ship, recall matching Feedback, merge duplicates, publish the outcome, and transition the canonical Thread to resolved. Moderators only: this cannot file reports or expose receipt metadata.",
|
|
19187
|
+
inputSchema: {
|
|
19188
|
+
verb: exports_external.enum(ADMIN_FEEDBACK_VERBS).describe("close loop: publish, merge, transition; also edit, curate, topic, and thread lifecycle"),
|
|
19189
|
+
threadId: exports_external.string().optional().describe("publish / update / move / transition / archive / restore: Thread id"),
|
|
19190
|
+
type: exports_external.enum(CONTRIBUTION_TYPES).optional().describe("publish/edit: shared contribution type, including maintainer decision"),
|
|
19191
|
+
body: exports_external.string().min(1).optional().describe("publish: follow-on body · edit: replacement body"),
|
|
19192
|
+
summary: exports_external.string().max(500).nullable().optional().describe("publish/edit: gist; edit null/empty clears"),
|
|
19193
|
+
confidence: exports_external.number().int().min(0).max(100).optional().describe("publish: 0–100 confidence"),
|
|
19194
|
+
idempotencyKey: exports_external.string().min(1).max(200).optional().describe("publish: stable retry key"),
|
|
19195
|
+
feedbackId: exports_external.string().optional().describe("publish: optional receipt id; additionally requires review_private"),
|
|
19196
|
+
contributionId: exports_external.string().optional().describe("edit/curate: shared contribution id"),
|
|
19197
|
+
curate: exports_external.enum(["delete", "restore"]).optional().describe("curate: delete or restore a shared contribution"),
|
|
19198
|
+
action: exports_external.enum(["create", "update", "archive", "restore"]).optional().describe("topic: create, update, archive, or restore"),
|
|
19199
|
+
topicId: exports_external.string().optional().describe("topic / create / move / update: Feedback Topic id"),
|
|
19200
|
+
title: exports_external.string().min(1).optional().describe("topic/create/update: title"),
|
|
19201
|
+
purpose: exports_external.string().optional().describe("topic: purpose"),
|
|
19202
|
+
sourceThreadId: exports_external.string().optional().describe("merge: duplicate source Thread id"),
|
|
19203
|
+
targetThreadId: exports_external.string().optional().describe("merge: canonical destination Thread id"),
|
|
19204
|
+
objective: exports_external.string().min(1).optional().describe("create/update: Thread objective"),
|
|
19205
|
+
status: exports_external.enum(["active", "needs-review", "stuck", "standing", "resolved", "archived"]).optional().describe("transition/update: target Thread status"),
|
|
19206
|
+
reason: exports_external.string().optional().describe("merge: concise auditable rationale")
|
|
19207
|
+
},
|
|
19208
|
+
surfaces: ["mcp"],
|
|
19209
|
+
toolset: "admin",
|
|
19210
|
+
requiresCapability: "moderate",
|
|
19211
|
+
run: runAdminFeedback
|
|
19212
|
+
},
|
|
19132
19213
|
{
|
|
19133
19214
|
name: "admin_feedback_topic",
|
|
19134
19215
|
title: "Maintain shared Feedback Topics",
|
|
@@ -19139,7 +19220,7 @@ var ACTION_DEFINITIONS = [
|
|
|
19139
19220
|
title: exports_external.string().min(1).optional().describe("create/update: Topic title"),
|
|
19140
19221
|
purpose: exports_external.string().optional().describe("create/update: Topic purpose")
|
|
19141
19222
|
},
|
|
19142
|
-
surfaces: ["
|
|
19223
|
+
surfaces: ["cli"],
|
|
19143
19224
|
toolset: "admin",
|
|
19144
19225
|
run: forward("feedback_admin.topic")
|
|
19145
19226
|
},
|
|
@@ -19158,7 +19239,7 @@ var ACTION_DEFINITIONS = [
|
|
|
19158
19239
|
status: exports_external.enum(["active", "needs-review", "stuck", "standing", "resolved", "archived"]).optional().describe("transition/update: target Thread status"),
|
|
19159
19240
|
reason: exports_external.string().optional().describe("merge: concise auditable rationale")
|
|
19160
19241
|
},
|
|
19161
|
-
surfaces: ["
|
|
19242
|
+
surfaces: ["cli"],
|
|
19162
19243
|
toolset: "admin",
|
|
19163
19244
|
run: forward("feedback_admin.thread")
|
|
19164
19245
|
},
|
|
@@ -19175,7 +19256,7 @@ var ACTION_DEFINITIONS = [
|
|
|
19175
19256
|
idempotencyKey: exports_external.string().min(1).max(200).optional(),
|
|
19176
19257
|
feedbackId: exports_external.string().optional().describe("optional receipt id; additionally requires review_private")
|
|
19177
19258
|
},
|
|
19178
|
-
surfaces: ["
|
|
19259
|
+
surfaces: ["cli"],
|
|
19179
19260
|
toolset: "admin",
|
|
19180
19261
|
run: forward("feedback_admin.publish")
|
|
19181
19262
|
},
|
|
@@ -19189,7 +19270,7 @@ var ACTION_DEFINITIONS = [
|
|
|
19189
19270
|
summary: exports_external.string().max(500).nullable().optional().describe("replacement gist; null/empty clears"),
|
|
19190
19271
|
type: exports_external.enum(CONTRIBUTION_TYPES).optional().describe("replacement shared contribution type")
|
|
19191
19272
|
},
|
|
19192
|
-
surfaces: ["
|
|
19273
|
+
surfaces: ["cli"],
|
|
19193
19274
|
toolset: "admin",
|
|
19194
19275
|
run: forward("feedback_admin.edit")
|
|
19195
19276
|
},
|
|
@@ -19201,7 +19282,7 @@ var ACTION_DEFINITIONS = [
|
|
|
19201
19282
|
verb: exports_external.enum(["delete", "restore"]),
|
|
19202
19283
|
contributionId: exports_external.string().describe("shared Feedback contribution id")
|
|
19203
19284
|
},
|
|
19204
|
-
surfaces: ["
|
|
19285
|
+
surfaces: ["cli"],
|
|
19205
19286
|
toolset: "admin",
|
|
19206
19287
|
run: dispatch({ delete: "feedback_admin.remove", restore: "feedback_admin.restore" })
|
|
19207
19288
|
},
|
|
@@ -19537,14 +19618,14 @@ var ACTION_DEFINITIONS = [
|
|
|
19537
19618
|
{
|
|
19538
19619
|
name: "computer_exec",
|
|
19539
19620
|
title: "Run a command",
|
|
19540
|
-
description: "Run one bounded shell operation in a parent Computer or Run with ambient GitHub authorization for connected humans.
|
|
19621
|
+
description: "Run one bounded shell operation in a parent Computer or Run with ambient GitHub authorization for connected humans. A long command returns processId if still running — poll computer_process_read (background:true skips the wait; timeout kills the process); after a missed isolated response use computer_run_receipt.operations[].operationId with computer_process_read instead of repeating the mutation.",
|
|
19541
19622
|
inputSchema: {
|
|
19542
19623
|
computerSessionId: exports_external.string().optional().describe("the computerSessionId returned by computer_open, cms_…; required unless runId is supplied"),
|
|
19543
19624
|
command: exports_external.string().min(1).describe("the shell command to run"),
|
|
19544
19625
|
runId: exports_external.string().optional().describe("route this command according to this Run execution placement, run_… (from computer_run_start)"),
|
|
19545
19626
|
cwd: exports_external.string().optional().describe("working directory under /workspace, or under the run; omit to use defaultCwd"),
|
|
19546
|
-
timeout: exports_external.number().int().min(1000).max(1800000).optional().describe("
|
|
19547
|
-
background: exports_external.boolean().optional().describe("start
|
|
19627
|
+
timeout: exports_external.number().int().min(1000).max(1800000).optional().describe("process kill deadline in milliseconds, from 1,000 through 1,800,000 — not the RPC hold"),
|
|
19628
|
+
background: exports_external.boolean().optional().describe("start the process and return immediately without the short RPC wait"),
|
|
19548
19629
|
activityLabel: exports_external.string().min(1).max(COMPUTER_RUN_ACTIVITY_LABEL_MAX).optional().describe("short human-readable label for run-scoped background work; Arbor records this label instead of the raw command or output"),
|
|
19549
19630
|
activityKind: exports_external.literal("verification").optional().describe("mark a labeled run-scoped background command as a verification check; its provider-observed terminal result is recorded as verification.finished"),
|
|
19550
19631
|
strict: exports_external.boolean().optional().describe("fail on the first unhandled command or pipeline failure; defaults to true, set false only for intentional best-effort execution")
|
|
@@ -21249,6 +21330,9 @@ var ACTION_DEFINITIONS = [
|
|
|
21249
21330
|
}
|
|
21250
21331
|
];
|
|
21251
21332
|
var ACTIONS = ACTION_DEFINITIONS.map((action) => {
|
|
21333
|
+
if (action.requiresCapability && !action.surfaces.includes("mcp")) {
|
|
21334
|
+
throw new Error(`${action.name}: requiresCapability is an MCP catalog gate`);
|
|
21335
|
+
}
|
|
21252
21336
|
if (!action.surfaces.some((surface) => surface === "mcp" || surface === "computer-mcp")) {
|
|
21253
21337
|
return action;
|
|
21254
21338
|
}
|
|
@@ -21555,7 +21639,8 @@ var GLOBAL_BOOLEAN_FLAGS = new Set([
|
|
|
21555
21639
|
"json",
|
|
21556
21640
|
"quiet",
|
|
21557
21641
|
"no-quiet",
|
|
21558
|
-
"help"
|
|
21642
|
+
"help",
|
|
21643
|
+
"no-wait"
|
|
21559
21644
|
]);
|
|
21560
21645
|
var RESERVED_FLAGS = new Set([
|
|
21561
21646
|
...GLOBAL_BOOLEAN_FLAGS,
|
|
@@ -21647,6 +21732,66 @@ function emitDual(data, human, action, ctx) {
|
|
|
21647
21732
|
process.stdout.write(human);
|
|
21648
21733
|
}
|
|
21649
21734
|
|
|
21735
|
+
// src/computer-exec-wait.ts
|
|
21736
|
+
var DEFAULT_PROCESS_DEADLINE_MS = 1800000;
|
|
21737
|
+
var POLL_MS = 400;
|
|
21738
|
+
var processRead = ACTIONS.find((action) => action.name === "computer_process_read");
|
|
21739
|
+
function record3(value) {
|
|
21740
|
+
return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
21741
|
+
}
|
|
21742
|
+
function isRunning(value) {
|
|
21743
|
+
const status = typeof value.status === "string" ? value.status.toLowerCase() : "";
|
|
21744
|
+
if (value.done === false)
|
|
21745
|
+
return true;
|
|
21746
|
+
if (status === "running" || status === "started" || status === "starting")
|
|
21747
|
+
return true;
|
|
21748
|
+
if (value.done === true)
|
|
21749
|
+
return false;
|
|
21750
|
+
if (status === "completed" || status === "exited" || status === "failed" || status === "cancelled" || status === "terminated" || status === "killed" || status === "unknown") {
|
|
21751
|
+
return false;
|
|
21752
|
+
}
|
|
21753
|
+
if (typeof value.exitCode === "number")
|
|
21754
|
+
return false;
|
|
21755
|
+
return typeof value.processId === "string";
|
|
21756
|
+
}
|
|
21757
|
+
function sleep(ms) {
|
|
21758
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
21759
|
+
}
|
|
21760
|
+
function isComputerExecHandle(value) {
|
|
21761
|
+
const rec = record3(value);
|
|
21762
|
+
return Boolean(rec && typeof rec.processId === "string" && isRunning(rec));
|
|
21763
|
+
}
|
|
21764
|
+
async function waitForComputerExec(executor, input, value, ctx) {
|
|
21765
|
+
if (!processRead || !isComputerExecHandle(value))
|
|
21766
|
+
return value;
|
|
21767
|
+
let latest = value;
|
|
21768
|
+
let cursor = typeof latest.nextCursor === "string" && latest.nextCursor ? latest.nextCursor : undefined;
|
|
21769
|
+
const deadline = Date.now() + (typeof input.timeout === "number" && Number.isFinite(input.timeout) ? input.timeout : DEFAULT_PROCESS_DEADLINE_MS);
|
|
21770
|
+
advise(`Process ${String(latest.processId)} is still running; polling computer_process_read.
|
|
21771
|
+
`, ctx);
|
|
21772
|
+
while (isRunning(latest) && Date.now() < deadline) {
|
|
21773
|
+
await sleep(POLL_MS);
|
|
21774
|
+
const read = record3(await processRead.run(executor, {
|
|
21775
|
+
processId: latest.processId,
|
|
21776
|
+
...cursor ? { cursor } : {},
|
|
21777
|
+
...typeof input.runId === "string" ? { runId: input.runId } : {},
|
|
21778
|
+
...typeof input.computerSessionId === "string" ? { computerSessionId: input.computerSessionId } : {}
|
|
21779
|
+
}));
|
|
21780
|
+
if (!read) {
|
|
21781
|
+
throw new Error("computer_process_read returned an empty result");
|
|
21782
|
+
}
|
|
21783
|
+
latest = read;
|
|
21784
|
+
if (typeof read.nextCursor === "string" && read.nextCursor)
|
|
21785
|
+
cursor = read.nextCursor;
|
|
21786
|
+
const stdout = typeof latest.stdout === "string" ? latest.stdout : "";
|
|
21787
|
+
if (stdout)
|
|
21788
|
+
advise(stdout, ctx);
|
|
21789
|
+
if (latest.recovery)
|
|
21790
|
+
break;
|
|
21791
|
+
}
|
|
21792
|
+
return latest;
|
|
21793
|
+
}
|
|
21794
|
+
|
|
21650
21795
|
// src/schema.ts
|
|
21651
21796
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
21652
21797
|
function kebab(field) {
|
|
@@ -21989,11 +22134,14 @@ Bare arguments fill ${explicitPositionals.map((spec) => `--${spec.flag}`).join("
|
|
|
21989
22134
|
|
|
21990
22135
|
Alias: \`arbor ${alias2}\` (the tool-name form) resolves to this same command.` : "";
|
|
21991
22136
|
const heading = `${commandWords(action)}${alias2 ? ` (alias: ${alias2})` : ""}`;
|
|
22137
|
+
const waitLines = action.name === "computer_exec" ? [
|
|
22138
|
+
" --no-wait [<boolean>] [optional] — return a running processId immediately instead of polling computer_process_read"
|
|
22139
|
+
] : [];
|
|
21992
22140
|
return `${heading} — ${action.description}
|
|
21993
22141
|
|
|
21994
|
-
${usage}
|
|
22142
|
+
${usage}${waitLines.length > 0 ? " [--no-wait]" : ""}
|
|
21995
22143
|
|
|
21996
|
-
${lines.join(`
|
|
22144
|
+
${[...lines, ...waitLines].join(`
|
|
21997
22145
|
`)}${primaryNote}${explicitNote}${aliasNote}
|
|
21998
22146
|
`;
|
|
21999
22147
|
}
|
|
@@ -22002,13 +22150,24 @@ function commandCatalog() {
|
|
|
22002
22150
|
command: commandWords(action),
|
|
22003
22151
|
name: action.name,
|
|
22004
22152
|
description: action.description,
|
|
22005
|
-
flags:
|
|
22006
|
-
|
|
22007
|
-
|
|
22008
|
-
|
|
22009
|
-
|
|
22010
|
-
|
|
22011
|
-
|
|
22153
|
+
flags: [
|
|
22154
|
+
...flagsForSchema(action.inputSchema).map((f) => ({
|
|
22155
|
+
flag: f.flag,
|
|
22156
|
+
kind: f.kind,
|
|
22157
|
+
required: f.required,
|
|
22158
|
+
acceptsFile: f.kind === "string",
|
|
22159
|
+
description: f.description
|
|
22160
|
+
})),
|
|
22161
|
+
...action.name === "computer_exec" ? [
|
|
22162
|
+
{
|
|
22163
|
+
flag: "no-wait",
|
|
22164
|
+
kind: "boolean",
|
|
22165
|
+
required: false,
|
|
22166
|
+
acceptsFile: false,
|
|
22167
|
+
description: "return a running processId immediately instead of polling computer_process_read"
|
|
22168
|
+
}
|
|
22169
|
+
] : []
|
|
22170
|
+
]
|
|
22012
22171
|
}));
|
|
22013
22172
|
}
|
|
22014
22173
|
function applyPositionals(action, extras, flags) {
|
|
@@ -22087,13 +22246,16 @@ async function runObjectVerb(positionals, flags, ctx) {
|
|
|
22087
22246
|
advise(`Agent registered. Save its apiKey now — it is shown only once:
|
|
22088
22247
|
`, ctx);
|
|
22089
22248
|
}
|
|
22090
|
-
|
|
22249
|
+
let value = await action.run(httpExecutor, input);
|
|
22250
|
+
if (action.name === "computer_exec" && !truthyFlag(flags["no-wait"])) {
|
|
22251
|
+
value = await waitForComputerExec(httpExecutor, input, value, ctx);
|
|
22252
|
+
}
|
|
22091
22253
|
emitData(shapeActionOutput(action.name, value, input), action.name, ctx);
|
|
22092
22254
|
}
|
|
22093
22255
|
|
|
22094
22256
|
// src/connect.ts
|
|
22095
22257
|
var DEFAULT_POLL_INTERVAL_MS = 2000;
|
|
22096
|
-
var
|
|
22258
|
+
var sleep2 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
22097
22259
|
function bareConnectUrl(apiUrl, returnedUrl) {
|
|
22098
22260
|
const fallback = `${apiUrl.replace(/\/$/, "")}/connect`;
|
|
22099
22261
|
if (!returnedUrl)
|
|
@@ -22137,7 +22299,7 @@ async function connect(opts) {
|
|
|
22137
22299
|
if (Date.now() > deadline) {
|
|
22138
22300
|
throw new Error("pairing timed out — ask for a new pairing key and run `arbor connect` again");
|
|
22139
22301
|
}
|
|
22140
|
-
await
|
|
22302
|
+
await sleep2(pollIntervalMs);
|
|
22141
22303
|
const tokRes = await fetch(`${apiUrl}/api/agent/connect/token`, {
|
|
22142
22304
|
method: "POST",
|
|
22143
22305
|
headers,
|
|
@@ -22163,7 +22325,7 @@ async function connect(opts) {
|
|
|
22163
22325
|
// src/login.ts
|
|
22164
22326
|
var CLIENT_ID = "arbor-cli";
|
|
22165
22327
|
var GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
|
|
22166
|
-
var
|
|
22328
|
+
var sleep3 = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
22167
22329
|
async function login(opts) {
|
|
22168
22330
|
const apiUrl = opts.url ?? loadConfig().apiUrl;
|
|
22169
22331
|
const codeRes = await fetch(`${apiUrl}/api/auth/device/code`, {
|
|
@@ -22188,7 +22350,7 @@ async function login(opts) {
|
|
|
22188
22350
|
for (;; ) {
|
|
22189
22351
|
if (Date.now() > deadline)
|
|
22190
22352
|
throw new Error("login timed out — run `arbor login` again");
|
|
22191
|
-
await
|
|
22353
|
+
await sleep3(interval);
|
|
22192
22354
|
const tokRes = await fetch(`${apiUrl}/api/auth/device/token`, {
|
|
22193
22355
|
method: "POST",
|
|
22194
22356
|
headers: { "content-type": "application/json" },
|
package/package.json
CHANGED