@lambdacurry/arbor 0.21.23 → 0.21.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 +27 -2
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -2011,6 +2011,11 @@ var threadComputers = sqliteTable("thread_computers", {
2011
2011
  successorComputerId: text("successor_computer_id"),
2012
2012
  restoredFromSnapshotId: text("restored_from_snapshot_id"),
2013
2013
  currentSnapshotId: text("current_snapshot_id"),
2014
+ workspaceMutationStarted: integer("workspace_mutation_started").notNull().default(0),
2015
+ workspaceMutationAcknowledged: integer("workspace_mutation_acknowledged").notNull().default(0),
2016
+ workspaceDurableMutationVersion: integer("workspace_durable_mutation_version"),
2017
+ workspaceRecoveryLeaseId: text("workspace_recovery_lease_id"),
2018
+ workspaceRecoveryLeaseExpiresAt: ts("workspace_recovery_lease_expires_at"),
2014
2019
  createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
2015
2020
  createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
2016
2021
  createdAt: ts("created_at").notNull()
@@ -2057,10 +2062,13 @@ var computerSessions = sqliteTable("computer_sessions", {
2057
2062
  executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
2058
2063
  configKey: text("config_key").notNull(),
2059
2064
  startingSnapshotId: text("starting_snapshot_id"),
2065
+ openIdempotencyKey: text("open_idempotency_key"),
2066
+ openIdempotencyFingerprint: text("open_idempotency_fingerprint"),
2060
2067
  attachedAt: ts("attached_at").notNull()
2061
2068
  }, (t) => ({
2062
2069
  computerIdx: index("computer_sessions_computer_idx").on(t.computerId, t.attachedAt),
2063
- threadIdx: index("computer_sessions_thread_idx").on(t.threadId, t.attachedAt)
2070
+ threadIdx: index("computer_sessions_thread_idx").on(t.threadId, t.attachedAt),
2071
+ openIdempotencyIdx: uniqueIndex("computer_sessions_open_idempotency_idx").on(t.profileId, t.threadId, t.openIdempotencyKey)
2064
2072
  }));
2065
2073
  var computerRuns = sqliteTable("computer_runs", {
2066
2074
  id: text("id").primaryKey(),
@@ -2841,6 +2849,11 @@ var RUN_PROVIDER_LIFECYCLE_PHASE_SET = new Set(RUN_PROVIDER_LIFECYCLE_PHASES);
2841
2849
 
2842
2850
  // ../core/src/ops/computer.ts
2843
2851
  var MAX_COMPUTER_REPOSITORIES = 10;
2852
+ var COMPUTER_WORKSPACE_RECOVERY_CHECKPOINT_DEADLINE_MS = 10 * 60 * 1000;
2853
+ var COMPUTER_WORKSPACE_RECOVERY_ATTACH_DEADLINE_MS = 31 * 60 * 1000;
2854
+ var COMPUTER_WORKSPACE_RECOVERY_HEALTH_DEADLINE_MS = 2 * 60 * 1000;
2855
+ var COMPUTER_WORKSPACE_RECOVERY_HEADROOM_MS = 2 * 60 * 1000;
2856
+ var COMPUTER_WORKSPACE_RECOVERY_LEASE_MS = COMPUTER_WORKSPACE_RECOVERY_CHECKPOINT_DEADLINE_MS + COMPUTER_WORKSPACE_RECOVERY_ATTACH_DEADLINE_MS + COMPUTER_WORKSPACE_RECOVERY_HEALTH_DEADLINE_MS + COMPUTER_WORKSPACE_RECOVERY_HEADROOM_MS;
2844
2857
 
2845
2858
  // ../core/src/ops/request.ts
2846
2859
  var REQUEST_TTL_MS = 14 * 24 * 60 * 60 * 1000;
@@ -18333,6 +18346,11 @@ var MCP_OUTPUT_SCHEMAS = {
18333
18346
  defaultCwd: exports_external.string(),
18334
18347
  capabilities: computerOpenCapabilities,
18335
18348
  agentBrief: computerOpenAgentBrief,
18349
+ startupReceipt: exports_external.object({
18350
+ computerSessionId: id,
18351
+ replayed: exports_external.boolean(),
18352
+ mutationRetrySafety: exports_external.literal("safe")
18353
+ }),
18336
18354
  reconciliation: exports_external.union([
18337
18355
  exports_external.object({
18338
18356
  action: exports_external.literal("automatic_reprovision"),
@@ -18712,6 +18730,11 @@ var OUTPUT_SHAPERS = {
18712
18730
  "restorationOutcome",
18713
18731
  "addedRepositories"
18714
18732
  ]);
18733
+ const startupReceipt = selected(result.startupReceipt, [
18734
+ "computerSessionId",
18735
+ "replayed",
18736
+ "mutationRetrySafety"
18737
+ ]);
18715
18738
  return defined([
18716
18739
  ["computerSessionId", result.computerSessionId],
18717
18740
  [
@@ -18743,6 +18766,7 @@ var OUTPUT_SHAPERS = {
18743
18766
  ["activeRuns", activeRuns]
18744
18767
  ]) : undefined
18745
18768
  ],
18769
+ ["startupReceipt", startupReceipt],
18746
18770
  ["reconciliation", reconciliation]
18747
18771
  ]);
18748
18772
  },
@@ -19681,6 +19705,7 @@ var ACTION_DEFINITIONS = [
19681
19705
  description: "Open a Thread project environment and return its session/workspace, verified root repository instruction pointers, Agent Brief, capabilities, Runs, and reconciliation receipt. Forward profile-revision or additive authorized repository drift auto-reconciles through a successor; removal, setup, backend/provider/profile changes, or ambiguous drift refuse with computer_reprovision guidance.",
19682
19706
  inputSchema: {
19683
19707
  threadId: exports_external.string().describe("the Arbor Thread whose stable computer to open, thr_…"),
19708
+ idempotencyKey: exports_external.string().min(1).max(200).describe("stable key for this ONE logical open; retry the same call unchanged—even after a lost response—to reuse the same ComputerSession; never mint a new key for an unresolved attempt"),
19684
19709
  vcpus: exports_external.number().int().min(1).max(4).optional().describe("optional container vCPU request"),
19685
19710
  label: exports_external.string().optional().describe("short runtime label for operator diagnostics")
19686
19711
  },
@@ -22635,7 +22660,7 @@ async function renderMe(ctx, action) {
22635
22660
  ` : "") + spaceLines;
22636
22661
  emitDual(me, human, action, ctx);
22637
22662
  }
22638
- var CLI_NOTE = `On this CLI, before your first write: commands are NOUN-VERB (\`thread get\`, \`space get\`, not \`get thread\`). The underscore tool-names you see in MCP, recall, and docs (\`set_space_charter\`, \`transition_thread\`) work as CLI commands VERBATIM too — \`set_space_charter …\` and \`set space charter …\` are the same command, either form. Computer work is one parallel family: start project work with \`arbor computer open --thread-id thr_…\`, keep its cms_… receipt, then pass it as \`--computer-session-id\` to later tools. Checkpoint intermediate complete units; \`computer stop\` performs the final checkpoint before teardown. Internal Currybox grants are exchanged per call and never printed. A public screenshot is lighter: \`arbor computer verify --thread-id thr_… --target-url https://…\` runs directly, with no open/checkpoint/stop ceremony, and returns a gated download URL plus ready-to-place Markdown; put that Markdown where the image belongs in the contribution body and pass the matching attachment id. A single-argument command also takes a bare positional — \`recall "your question"\`, \`thread get thr_…\` — so you don't have to name the obvious flag. Flag names are kebab-derived from the inputs (\`--thread-id\`, \`--request-id\`, \`--contribution-id\` — not \`--thread\`/\`--request\`), so check \`arbor help\` or \`arbor <command> --help\` (now focused on that command's flags) instead of guessing. Pass long/markdown bodies via \`--body-file -\` (stdin), never shell-quoted; a one-line \`--summary\` (1-2 short sentences, hard limit 500 chars) on a long contribution becomes its recall snippet. List inputs always accept a REPEATED flag, one item each (\`--guidance "…" --guidance "…"\`) — the form that works everywhere. A single value additionally comma-splits for TOKEN lists (\`--capabilities a,b,c\`), but stays one literal item for PROSE lists (\`--guidance\`, \`--ways-to-help\`, \`--contribution-lanes\`) so a comma inside a sentence can't shred it; \`arbor <command> --help\` names which form each list flag takes. \`tree\` is the lifecycle map (default depth \`topics\`): choose a Topic, then \`recall --topic top_… "your question"\` before targeted \`thread get\`/\`artifact get\`; use \`topic get\` or deeper tree only when you intentionally need Topic-wide context or enumeration. If \`inbox\` is empty, that's "nothing needs you" — but if you're unsure your auth resolved, \`whoami\` confirms it.`;
22663
+ var CLI_NOTE = `On this CLI, before your first write: commands are NOUN-VERB (\`thread get\`, \`space get\`, not \`get thread\`). The underscore tool-names you see in MCP, recall, and docs (\`set_space_charter\`, \`transition_thread\`) work as CLI commands VERBATIM too — \`set_space_charter …\` and \`set space charter …\` are the same command, either form. Computer work is one parallel family: start project work with \`arbor computer open --thread-id thr_… --idempotency-key scope-open-1\`, reuse that key only for the same logical open, keep its cms_… receipt, then pass it as \`--computer-session-id\` to later tools. Checkpoint intermediate complete units; \`computer stop\` performs the final checkpoint before teardown. Internal Currybox grants are exchanged per call and never printed. A public screenshot is lighter: \`arbor computer verify --thread-id thr_… --target-url https://…\` runs directly, with no open/checkpoint/stop ceremony, and returns a gated download URL plus ready-to-place Markdown; put that Markdown where the image belongs in the contribution body and pass the matching attachment id. A single-argument command also takes a bare positional — \`recall "your question"\`, \`thread get thr_…\` — so you don't have to name the obvious flag. Flag names are kebab-derived from the inputs (\`--thread-id\`, \`--request-id\`, \`--contribution-id\` — not \`--thread\`/\`--request\`), so check \`arbor help\` or \`arbor <command> --help\` (now focused on that command's flags) instead of guessing. Pass long/markdown bodies via \`--body-file -\` (stdin), never shell-quoted; a one-line \`--summary\` (1-2 short sentences, hard limit 500 chars) on a long contribution becomes its recall snippet. List inputs always accept a REPEATED flag, one item each (\`--guidance "…" --guidance "…"\`) — the form that works everywhere. A single value additionally comma-splits for TOKEN lists (\`--capabilities a,b,c\`), but stays one literal item for PROSE lists (\`--guidance\`, \`--ways-to-help\`, \`--contribution-lanes\`) so a comma inside a sentence can't shred it; \`arbor <command> --help\` names which form each list flag takes. \`tree\` is the lifecycle map (default depth \`topics\`): choose a Topic, then \`recall --topic top_… "your question"\` before targeted \`thread get\`/\`artifact get\`; use \`topic get\` or deeper tree only when you intentionally need Topic-wide context or enumeration. If \`inbox\` is empty, that's "nothing needs you" — but if you're unsure your auth resolved, \`whoami\` confirms it.`;
22639
22664
  function renderOrient(ctx) {
22640
22665
  emitDual({ orientation: ORIENTATION, cliNote: CLI_NOTE }, `${ORIENTATION}
22641
22666
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.21.23",
3
+ "version": "0.21.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",