@lambdacurry/arbor 0.22.22 → 0.22.24

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 (2) hide show
  1. package/dist/arbor.js +94 -20
  2. 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.22",
5
+ version: "0.22.24",
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",
@@ -6712,6 +6712,69 @@ var computerRunStarts = sqliteTable("computer_run_starts", {
6712
6712
  snapshotIdx: index("computer_run_starts_snapshot_idx").on(t.snapshotId),
6713
6713
  runIdx: uniqueIndex("computer_run_starts_run_idx").on(t.runId)
6714
6714
  }));
6715
+ var computerOutputCaptures = sqliteTable("computer_output_captures", {
6716
+ id: text("id").primaryKey(),
6717
+ runId: text("run_id").notNull().references(() => computerRuns.id),
6718
+ processId: text("process_id").notNull(),
6719
+ computerId: text("computer_id").notNull().references(() => threadComputers.id),
6720
+ threadId: text("thread_id").notNull().references(() => threads.id),
6721
+ computerSessionId: text("computer_session_id").notNull().references(() => computerSessions.id),
6722
+ runProfileId: text("run_profile_id").notNull().references(() => profiles.id),
6723
+ runExecutionContextId: text("run_execution_context_id").notNull().references(() => executionContexts.id),
6724
+ sessionProfileId: text("session_profile_id").notNull().references(() => profiles.id),
6725
+ sessionExecutionContextId: text("session_execution_context_id").notNull().references(() => executionContexts.id),
6726
+ execution: text("execution").$type().notNull(),
6727
+ processState: text("process_state").$type().notNull(),
6728
+ processActivityKind: text("process_activity_kind").$type(),
6729
+ processExecution: text("process_execution").$type(),
6730
+ providerGeneration: integer2("provider_generation"),
6731
+ workspaceGeneration: text("workspace_generation"),
6732
+ expectedCurrentSnapshotId: text("expected_current_snapshot_id").references(() => computerSnapshots.id),
6733
+ terminalOutcome: text("terminal_outcome").$type(),
6734
+ exitCode: integer2("exit_code"),
6735
+ timedOut: integer2("timed_out", { mode: "boolean" }),
6736
+ durationMs: integer2("duration_ms"),
6737
+ status: text("status").$type().notNull().default("pending"),
6738
+ stdoutBytes: integer2("stdout_bytes").notNull().default(0),
6739
+ stderrBytes: integer2("stderr_bytes").notNull().default(0),
6740
+ requestedStdoutBytes: integer2("requested_stdout_bytes"),
6741
+ requestedStderrBytes: integer2("requested_stderr_bytes"),
6742
+ pageIntentDigest: text("page_intent_digest"),
6743
+ intentStdoutBytes: integer2("intent_stdout_bytes"),
6744
+ intentStderrBytes: integer2("intent_stderr_bytes"),
6745
+ intentTerminalOutcome: text("intent_terminal_outcome").$type(),
6746
+ intentExitCode: integer2("intent_exit_code"),
6747
+ intentTimedOut: integer2("intent_timed_out", { mode: "boolean" }),
6748
+ intentDurationMs: integer2("intent_duration_ms"),
6749
+ lastPublishedIntentDigest: text("last_published_intent_digest"),
6750
+ cleanupToken: text("cleanup_token"),
6751
+ cleanupClaimedAt: ts("cleanup_claimed_at"),
6752
+ completedAt: ts("completed_at"),
6753
+ expiresAt: ts("expires_at"),
6754
+ updatedAt: ts("updated_at").notNull(),
6755
+ createdAt: ts("created_at").notNull()
6756
+ }, (t) => ({
6757
+ runProcessIdx: uniqueIndex("computer_output_captures_run_process_idx").on(t.runId, t.processId),
6758
+ computerIdx: index("computer_output_captures_computer_idx").on(t.computerId, t.status),
6759
+ pendingIdx: index("computer_output_captures_pending_idx").on(t.status, t.updatedAt),
6760
+ expiresIdx: index("computer_output_captures_expires_idx").on(t.status, t.expiresAt)
6761
+ }));
6762
+ var computerOutputChunks = sqliteTable("computer_output_chunks", {
6763
+ id: text("id").primaryKey(),
6764
+ captureId: text("capture_id").notNull().references(() => computerOutputCaptures.id),
6765
+ stream: text("stream").$type().notNull(),
6766
+ startOffset: integer2("start_offset").notNull(),
6767
+ size: integer2("size").notNull(),
6768
+ blobKey: text("blob_key").notNull(),
6769
+ sha256: text("sha256").notNull(),
6770
+ pageIntentDigest: text("page_intent_digest").notNull(),
6771
+ verifiedAt: ts("verified_at"),
6772
+ deletedAt: ts("deleted_at"),
6773
+ createdAt: ts("created_at").notNull()
6774
+ }, (t) => ({
6775
+ rangeIdx: uniqueIndex("computer_output_chunks_range_idx").on(t.captureId, t.stream, t.startOffset),
6776
+ blobKeyIdx: uniqueIndex("computer_output_chunks_blob_key_idx").on(t.blobKey)
6777
+ }));
6715
6778
  var previews = sqliteTable("previews", {
6716
6779
  id: text("id").primaryKey(),
6717
6780
  threadId: text("thread_id").notNull().references(() => threads.id),
@@ -7548,6 +7611,8 @@ var assigneeColumns = {
7548
7611
  color: profiles.color,
7549
7612
  emoji: profiles.emoji
7550
7613
  };
7614
+ // ../core/src/ops/computer-output.ts
7615
+ var COMPUTER_OUTPUT_DEFAULT_STALE_MS = 24 * 60 * 60 * 1000;
7551
7616
  // ../core/src/ops/computer-recovery.ts
7552
7617
  var COMPUTER_RECOVERY_GRANT_MAX_TTL_MS = 24 * 60 * 60 * 1000;
7553
7618
  // ../core/src/ops/preview.ts
@@ -7844,7 +7909,7 @@ var computerRunFinishAssessment = looseObject({
7844
7909
  state: _enum(["safe", "blocked", "unknown"]),
7845
7910
  requiresDiscard: boolean2(),
7846
7911
  repositories: array(looseObject({
7847
- repository: string2(),
7912
+ repository: string2().nullable(),
7848
7913
  path: string2(),
7849
7914
  startHead: string2().nullable(),
7850
7915
  currentHead: string2().nullable(),
@@ -7885,7 +7950,7 @@ var computerAgentBrief = looseObject({
7885
7950
  });
7886
7951
  var computerRunGitStart = looseObject({
7887
7952
  repositories: array(looseObject({
7888
- repository: string2(),
7953
+ repository: string2().nullable(),
7889
7954
  path: string2(),
7890
7955
  git: computerRunGitState.nullable()
7891
7956
  }))
@@ -9071,7 +9136,7 @@ var MCP_OUTPUT_SCHEMAS = {
9071
9136
  durablyFinishable: boolean2(),
9072
9137
  finishAssessment: computerRunFinishAssessment,
9073
9138
  repositories: array(looseObject({
9074
- repository: string2(),
9139
+ repository: string2().nullable(),
9075
9140
  path: string2(),
9076
9141
  start: computerRunGitState.nullable(),
9077
9142
  current: computerRunGitState.nullable(),
@@ -9163,6 +9228,7 @@ var MCP_OUTPUT_SCHEMAS = {
9163
9228
  computer_process_read: looseObject({
9164
9229
  processId: string2(),
9165
9230
  status: string2(),
9231
+ outputRetention: object({ state: literal("preserved"), expiresAt: timestamp }).optional(),
9166
9232
  timedOut: boolean2().optional(),
9167
9233
  endedAt: timestamp.nullable().optional(),
9168
9234
  durationMs: number2().int().min(0).nullable().optional(),
@@ -9563,6 +9629,7 @@ var OUTPUT_SHAPERS = {
9563
9629
  computer_process_read: (result) => defined([
9564
9630
  ["processId", result.processId],
9565
9631
  ["status", result.status],
9632
+ ["outputRetention", omitNull(result.outputRetention)],
9566
9633
  ["timedOut", omitNull(result.timedOut)],
9567
9634
  ["stdout", result.stdout],
9568
9635
  ["stderr", result.stderr],
@@ -9949,13 +10016,13 @@ Arbor's MCP is the collaboration and durable-knowledge surface. Configure, autho
9949
10016
 
9950
10017
  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.`;
9951
10018
  var ARBOR_SKILL_MARKDOWN = renderArborSkill(ORIENTATION);
9952
- 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 or output is truncated, take \`processId\`/\`nextCursor\` and continue with \`computer_process_read\`. Do not chain \`pnpm test && pnpm build\` in one exec; split steps or pass \`background:true\`. The CLI polls only while the process is silent unless \`--no-wait\`; it returns the first bounded output page instead of concatenating continuation pages into one agent context.
10019
+ 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\`. The CLI polls only while the process is silent unless \`--no-wait\`; it returns the first bounded output page instead of concatenating continuation pages into one agent context.
9953
10020
 
9954
10021
  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.
9955
10022
 
9956
10023
  ${ARBOR_FEEDBACK_GUIDANCE}
9957
10024
 
9958
- 1. ORIENT, CONFIGURE, AND AUTHORIZE. Start with provider-free get_computer(threadId) to inspect the effective inherited recipe, repository authorization, compatibility, recoverySafety, and durable lineage without contacting execution. Use set_organization_computer, set_space_computer, set_topic_computer, or set_thread_computer only when the corresponding complete sparse layer must be replaced; use github_repositories then github_connect_repository to authorize repositories at the narrowest scope that should inherit them. If github_repositories looks stale, github_refresh_installation reconciles the cached inventory from GitHub. computer_run_start(threadId, mode) is the front door: it attaches durable identity itself and starts an isolated write Run from the Thread's base snapshot without booting the parent. Each returned repository entry includes verified root instruction pointers when that repo has an AGENTS.md: read surfaced repository instructions before substantial edits or verification, then check for a nearer nested AGENTS.md once the target path is known. Repo-local instructions/scripts/config beat guessed formatter, test, lint, or build commands.
10025
+ 1. ORIENT, CONFIGURE, AND AUTHORIZE. Start with provider-free get_computer(threadId) to inspect the effective inherited recipe, repository authorization, compatibility, recoverySafety, and durable lineage without contacting execution. Use set_organization_computer, set_space_computer, set_topic_computer, or set_thread_computer only when the corresponding complete sparse layer must be replaced; use github_connect_repository with a known installed id, exact owner/name, or canonical GitHub URL, or use github_repositories when browsing, to authorize repositories at the narrowest scope that should inherit them. If github_repositories looks stale, github_refresh_installation reconciles the cached inventory from GitHub. computer_run_start(threadId, mode) is the front door: it attaches durable identity itself and starts an isolated write Run from the Thread's base snapshot without booting the parent. Each returned repository entry includes verified root instruction pointers when that repo has an AGENTS.md: read surfaced repository instructions before substantial edits or verification, then check for a nearer nested AGENTS.md once the target path is known. Repo-local instructions/scripts/config beat guessed formatter, test, lint, or build commands.
9959
10026
  2. READ THE CAPABILITIES CARD, NOT THE BACKEND. runId is the one address: every runtime tool takes it, and the computerSessionId a Run carries is legacy input. computer_status(runId) describes the live PARENT Thread Computer behind a shared Run; it does not establish isolated Run activity, so use computer_run_receipt(runId) and computer_process_read for Run-owned work. Command-line utilities, including Git and package managers, run through computer_exec; check unfamiliar binaries with command -v.
9960
10027
  3. ONE RUN PER TASK. A write Run defaults to an isolated execution environment with its own filesystem, processes, ports, and /tmp while preserving /workspace paths; a read Run shares the parent. Pass runId to Run-aware tools. If a response is lost, recover the durable operation/process identity from computer_run_receipt and read it before retrying. computer_process_read and computer_process_terminate settle a provider-absent current-generation process from exact evidence; computer_run_suspend performs that bounded settlement internally and never replays unknown work. A still-active process returns a retryable busy state; an unknown current-generation mutation fail-closes. An isolated local commit or Preview is not Git publication; push coherent work and prove it with computer_repo_work_status before computer_run_finish destroys the final placement. discard=true with outcome failed or cancelled is the explicit choice to abandon unknown or proven non-durable work without replaying it.
9961
10028
  4. CHECKPOINT COMPLETE UNITS THROUGH THE RUN. computer_run_suspend(runId) checkpoints an intermediate complete unit — an isolated Run publishes its exact workspace and releases its Sandbox, a shared Run advances the parent lineage — and computer_run_finish(runId) makes the final one; finishing the last active shared Run also stops the parent. An isolated Run Preview is durable review output, not adoption or a checkpoint. The internal provider-handle publication operations are not agent tools.
@@ -10109,9 +10176,9 @@ var ACTION_DEFINITIONS = [
10109
10176
  {
10110
10177
  name: "github_connect_repository",
10111
10178
  title: "Connect a GitHub repository",
10112
- description: "Connect or disconnect a listed GitHub repository at organization, Space, Topic, or Thread scope so matching descendant Computers may materialize it. The caller must manage that scope, GitHub installation coverage remains a separate gate, and get_computer shows the effective grant.",
10179
+ description: "Connect or disconnect an installed GitHub repository at organization, Space, Topic, or Thread scope; pass its installed id, exact owner/name, or canonical GitHub URL, so browsing the inventory is optional. The caller must manage that scope, GitHub installation coverage remains a separate gate, and get_computer shows the effective grant.",
10113
10180
  inputSchema: {
10114
- repositoryId: string2().describe("installed repository id from github_repositories, ghr_…"),
10181
+ repositoryId: string2().describe("installed repository id from github_repositories (ghr_…), exact owner/name, or canonical https://github.com/owner/name URL"),
10115
10182
  scope: _enum(["organization", "space", "topic", "thread"]).describe("the Arbor scope that may use this repository's context; topic is the durable choice for a project every Thread under it develops"),
10116
10183
  scopeId: string2().describe("id matching the selected scope"),
10117
10184
  connected: boolean2().describe("true to connect; false to disconnect recoverably")
@@ -10597,7 +10664,7 @@ var ACTION_DEFINITIONS = [
10597
10664
  inputSchema: {
10598
10665
  backend: _enum(["worker-shell", "container"]).nullable().optional().describe("default execution tier, or null to use worker-shell"),
10599
10666
  containerProfile: string2().nullable().optional().describe("logical container profile; bun-typescript-v1 guarantees Bash, Git, GitHub CLI (gh), Bun 1.4.2, bunx, Node 26.5.1, pnpm 10.33.0, Python 3.13.15 (python/python3), jq, and ripgrep (rg), or null to clear"),
10600
- setupScript: string2().nullable().optional().describe("optional strict Bash setup run after connected repositories materialize, or null to clear"),
10667
+ setupScript: string2().nullable().optional().describe("optional strict Bash setup for a fresh base after repositories materialize; install scoped tools in /workspace/.local/bin so exec finds them and snapshots retain them; null clears"),
10601
10668
  repositories: array(string2()).max(MAX_COMPUTER_REPOSITORIES).nullable().optional().describe("connected GitHub repositories to materialize into a fresh reusable base and allow for later Git calls; [] clears and null inherits")
10602
10669
  },
10603
10670
  surfaces: ["computer-mcp", "cli"],
@@ -10612,7 +10679,7 @@ var ACTION_DEFINITIONS = [
10612
10679
  spaceId: string2().describe("the Space, spc_…"),
10613
10680
  backend: _enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
10614
10681
  containerProfile: string2().nullable().optional().describe("logical container profile; bun-typescript-v1 guarantees Bash, Git, GitHub CLI (gh), Bun 1.4.2, bunx, Node 26.5.1, pnpm 10.33.0, Python 3.13.15 (python/python3), jq, and ripgrep (rg), or null to clear inherited profile"),
10615
- setupScript: string2().nullable().optional().describe("optional strict Bash setup run after connected repositories materialize, or null to clear"),
10682
+ setupScript: string2().nullable().optional().describe("optional strict Bash setup for a fresh base after repositories materialize; install scoped tools in /workspace/.local/bin so exec finds them and snapshots retain them; null clears"),
10616
10683
  repositories: array(string2()).max(MAX_COMPUTER_REPOSITORIES).nullable().optional().describe("connected GitHub repositories to materialize into a fresh reusable base and allow for later Git calls; [] clears and null inherits")
10617
10684
  },
10618
10685
  surfaces: ["computer-mcp", "cli"],
@@ -10627,7 +10694,7 @@ var ACTION_DEFINITIONS = [
10627
10694
  topicId: string2().describe("the Topic, top_…"),
10628
10695
  backend: _enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
10629
10696
  containerProfile: string2().nullable().optional().describe("logical container profile; bun-typescript-v1 guarantees Bash, Git, GitHub CLI (gh), Bun 1.4.2, bunx, Node 26.5.1, pnpm 10.33.0, Python 3.13.15 (python/python3), jq, and ripgrep (rg), or null to clear inherited profile"),
10630
- setupScript: string2().nullable().optional().describe("optional strict Bash setup run after connected repositories materialize"),
10697
+ setupScript: string2().nullable().optional().describe("optional strict Bash setup for a fresh base after repositories materialize; install scoped tools in /workspace/.local/bin so exec finds them and snapshots retain them"),
10631
10698
  repositories: array(string2()).max(MAX_COMPUTER_REPOSITORIES).nullable().optional().describe("connected GitHub repositories to materialize into a fresh reusable base and allow for later Git calls; [] clears and null inherits"),
10632
10699
  ...LIVE_PREVIEW_CONFIG_INPUT
10633
10700
  },
@@ -10643,7 +10710,7 @@ var ACTION_DEFINITIONS = [
10643
10710
  threadId: string2().describe("the Thread, thr_…"),
10644
10711
  backend: _enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
10645
10712
  containerProfile: string2().nullable().optional().describe("logical container profile; bun-typescript-v1 guarantees Bash, Git, GitHub CLI (gh), Bun 1.4.2, bunx, Node 26.5.1, pnpm 10.33.0, Python 3.13.15 (python/python3), jq, and ripgrep (rg), or null to clear inherited profile"),
10646
- setupScript: string2().nullable().optional().describe("optional strict Bash setup run after connected repositories materialize"),
10713
+ setupScript: string2().nullable().optional().describe("optional strict Bash setup for a fresh base after repositories materialize; install scoped tools in /workspace/.local/bin so exec finds them and snapshots retain them"),
10647
10714
  repositories: array(string2()).max(MAX_COMPUTER_REPOSITORIES).nullable().optional().describe("connected GitHub repositories to materialize into a fresh reusable base and allow for later Git calls; [] clears and null inherits"),
10648
10715
  ...LIVE_PREVIEW_CONFIG_INPUT
10649
10716
  },
@@ -10712,9 +10779,9 @@ var ACTION_DEFINITIONS = [
10712
10779
  {
10713
10780
  name: "computer_run_suspend",
10714
10781
  title: "Suspend a run",
10715
- description: "Checkpoint an active WRITE Run for an external wait (the same runId resumes next): an isolated Run publishes its exact workspace and releases its Sandbox, a shared Run checkpoints the parent lineage. Performs bounded process read/terminate/settlement internally: suspends when settled, returns retryable busy if a process is active, or fail-closes on unknown mutation and never replays unknown work.",
10782
+ description: "Checkpoint an active WRITE Run for an external wait: isolated Runs publish their exact workspace and release the Sandbox; shared Runs checkpoint the parent, and the same runId resumes next. Preserves unread terminal output internally for 30 days; no caller drain is required, larger captures use bounded same-Run retries, and active/unknown work or failed preservation blocks release without replay.",
10716
10783
  inputSchema: {
10717
- runId: string2().describe("the active isolated WRITE Run to suspend, run_…")
10784
+ runId: string2().describe("the active WRITE Run to suspend, run_…")
10718
10785
  },
10719
10786
  surfaces: ["computer-mcp", "computer-cli"],
10720
10787
  toolset: "loop",
@@ -10723,7 +10790,7 @@ var ACTION_DEFINITIONS = [
10723
10790
  {
10724
10791
  name: "computer_repo_work_status",
10725
10792
  title: "Inspect repository finish state",
10726
- description: "Inspect an active isolated WRITE Run's Git publication, PR, CI, and review before retry, wait, or finish. Returns repository state (e.g. ci-pending) plus runDisposition.action computer_run_suspend when published work waits on CI/review/human authorization the same runId resumes; dirty, unpublished, unknown-publication, failing, or changes-requested work keeps the local nextAction.",
10793
+ description: "Inspect workspace Git worktrees, including manual clones, for publication, PR, CI, and review in an active isolated WRITE Run. Returns repository state and runDisposition.action computer_run_suspend when published work waits on CI/review/human authorization, resuming the same runId; dirty, missing, unpublished, or unverified work keeps a local nextAction.",
10727
10794
  inputSchema: {
10728
10795
  runId: string2().describe("the active isolated WRITE Run to inspect, run_…")
10729
10796
  },
@@ -10734,7 +10801,7 @@ var ACTION_DEFINITIONS = [
10734
10801
  {
10735
10802
  name: "computer_run_finish",
10736
10803
  title: "Finish a run",
10737
- description: "Finish a Run with an explicit terminal outcome; ordinary finish refuses unsettled operations and proven non-durable isolated WRITE work, and the last shared Run's finish also stops the parent. To abandon an unknown or non-durable disposable Run without replaying it, pass discard=true with outcome failed or cancelled; the receipt keeps the evidence and repeating the outcome is a safe no-op.",
10804
+ description: "Finish a Run with unread terminal output preserved for 30 days without caller drain; active/unknown work, failed preservation, incomplete Git discovery, or unsafe worktrees block release. The last shared Run stops the parent; to abandon an unknown or non-durable disposable Run, pass discard=true with outcome failed or cancelled and retry safely from its receipt.",
10738
10805
  inputSchema: {
10739
10806
  runId: string2().describe("the runId returned by computer_run_start, run_…"),
10740
10807
  outcome: _enum(["finished", "failed", "cancelled"]).optional().describe("terminal outcome; defaults to finished"),
@@ -10773,7 +10840,7 @@ var ACTION_DEFINITIONS = [
10773
10840
  {
10774
10841
  name: "computer_exec",
10775
10842
  title: "Run a command",
10776
- description: "Run one bounded shell operation in a Run (pass runId) with ambient GitHub authorization; timeout kills the process. If the command is running or a truncated output page is returned, use processId with computer_process_read and nextCursor when present; after a missed isolated response use computer_run_receipt.operations[].operationId with computer_process_read instead of repeating the mutation.",
10843
+ description: "Run a shell command in runId with ambient GitHub authorization and /workspace/.local/bin on PATH; timeout kills the process. Observe running work with computer_process_read, use nextCursor for a truncated output page when needed, and finish without draining; after a missed response use computer_run_receipt.operations[].operationId with computer_process_read instead of repeating the mutation.",
10777
10844
  inputSchema: {
10778
10845
  computerSessionId: string2().optional().describe("legacy alternative to runId: a computerSessionId on that Computer, cms_…; required unless runId is supplied"),
10779
10846
  command: string2().min(1).describe("the shell command to run"),
@@ -10792,12 +10859,12 @@ var ACTION_DEFINITIONS = [
10792
10859
  {
10793
10860
  name: "computer_process_read",
10794
10861
  title: "Read a background process",
10795
- description: "Read one provider-owned process from computer_exec, including a recovered Run operation, using nextCursor for incremental output. Successful Run reads durably retain the latest provider observation; a later timeout stays unknown and unsafe while returning it with age, and Arbor settles the durable operation only from terminal or exact provider-absence proof.",
10862
+ description: "Read original process output using nextCursor; preserved output stays readable for 30 days after preservation, including repeated cursors after finish/suspend, without provider wake. Live reads retain the latest observation; a later timeout remains unknown/unsafe with its age, and Arbor settles the durable operation only from terminal or exact provider-absence proof.",
10796
10863
  inputSchema: {
10797
10864
  computerSessionId: string2().optional().describe("legacy alternative to runId: a computerSessionId on that Computer, cms_…; required unless runId is supplied"),
10798
10865
  runId: string2().optional().describe("the Run that owns this process, if it was started inside a Run"),
10799
10866
  processId: string2().min(1).describe("the processId returned by background exec, or matching computer_run_receipt.operations[].operationId for recovered foreground Run work, proc_…"),
10800
- cursor: string2().optional().describe("continue after nextCursor from the prior process read; omit for a small latest tail"),
10867
+ cursor: string2().optional().describe("continue after nextCursor from the prior result; omit to read from the beginning"),
10801
10868
  maxBytes: number2().int().min(1024).max(65536).optional().describe("maximum combined output bytes to return; default 4,096, opt up only when needed")
10802
10869
  },
10803
10870
  surfaces: ["computer-mcp", "computer-cli"],
@@ -11658,7 +11725,7 @@ var ACTION_DEFINITIONS = [
11658
11725
  {
11659
11726
  name: "service_register",
11660
11727
  title: "Register a Computer lifecycle service",
11661
- description: "Register a persistent service identity for Currybox Computer lifecycle maintenance and mint its API key (shown ONCE). Human owner/admin CLI setup only. The credential is restricted to computer.get + computer.lifecycle_runs + computer.append_run_lifecycle + computer.checkpoint + computer.suspend_run + computer.resume_run + computer.reconcile_runs and to the Spaces listed here; store it as the Currybox control plane's Arbor credential.",
11728
+ description: "Register a persistent service identity for Currybox Computer lifecycle maintenance and mint its API key (shown ONCE). Human owner/admin CLI setup only. The credential is restricted to computer.get + computer.lifecycle_runs + computer.append_run_lifecycle + computer.checkpoint + computer.preserve_run_output + computer.suspend_run + computer.resume_run + computer.reconcile_runs and to the Spaces listed here; store it as the Currybox control plane's Arbor credential.",
11662
11729
  inputSchema: {
11663
11730
  displayName: string2().min(1).describe("the service display name, e.g. Currybox lifecycle service"),
11664
11731
  spaceIds: array(string2().min(1)).min(1).describe("Spaces whose Thread computers the service may maintain")
@@ -12918,6 +12985,7 @@ function codeForStatus(status) {
12918
12985
  case 403:
12919
12986
  return "FORBIDDEN";
12920
12987
  case 404:
12988
+ case 410:
12921
12989
  return "NOT_FOUND";
12922
12990
  case 409:
12923
12991
  return "CONFLICT";
@@ -12978,6 +13046,12 @@ function parseErrorDetails(value) {
12978
13046
  details.operationId = raw.operationId;
12979
13047
  if (typeof raw.processId === "string")
12980
13048
  details.processId = raw.processId;
13049
+ if (raw.outputRetention && typeof raw.outputRetention === "object") {
13050
+ const retention = raw.outputRetention;
13051
+ if (retention.state === "expired" && typeof retention.expiresAt === "string") {
13052
+ details.outputRetention = { state: "expired", expiresAt: retention.expiresAt };
13053
+ }
13054
+ }
12981
13055
  if (raw.commandExecution === "not-routed" || raw.commandExecution === "unknown") {
12982
13056
  details.commandExecution = raw.commandExecution;
12983
13057
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.22.22",
3
+ "version": "0.22.24",
4
4
  "description": "The Arbor CLI — a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
5
5
  "keywords": [
6
6
  "agents",