@lambdacurry/arbor 0.14.4 → 0.14.5

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 +99 -5
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -38,6 +38,7 @@ var ERROR_REASONS = new Set([
38
38
  "authorization.denied",
39
39
  "resource.not_found",
40
40
  "conflict.state",
41
+ "conflict.computer_recipe",
41
42
  "limit.exceeded",
42
43
  "provider.timeout",
43
44
  "provider.failure",
@@ -1581,12 +1582,55 @@ var githubWebhookDeliveries = sqliteTable("github_webhook_deliveries", {
1581
1582
  var threadComputers = sqliteTable("thread_computers", {
1582
1583
  id: text("id").primaryKey(),
1583
1584
  threadId: text("thread_id").notNull().references(() => threads.id),
1585
+ generation: integer("generation").notNull().default(1),
1584
1586
  provider: text("provider").$type().notNull(),
1587
+ backend: text("backend").$type().notNull().default("worker-shell"),
1588
+ containerProfile: text("container_profile"),
1589
+ repositories: text("repositories", { mode: "json" }).$type().notNull().default([]),
1590
+ setupScriptConfigured: integer("setup_script_configured", { mode: "boolean" }).notNull().default(false),
1591
+ configKey: text("config_key").notNull().default("legacy"),
1592
+ configRevision: text("config_revision").notNull().default("legacy"),
1593
+ predecessorComputerId: text("predecessor_computer_id"),
1594
+ successorComputerId: text("successor_computer_id"),
1595
+ restoredFromSnapshotId: text("restored_from_snapshot_id"),
1585
1596
  currentSnapshotId: text("current_snapshot_id"),
1586
1597
  createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
1587
1598
  createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
1588
1599
  createdAt: ts("created_at").notNull()
1589
- }, (t) => ({ threadIdx: uniqueIndex("thread_computers_thread_idx").on(t.threadId) }));
1600
+ }, (t) => ({
1601
+ threadIdx: index("thread_computers_thread_idx").on(t.threadId, t.generation),
1602
+ generationIdx: uniqueIndex("thread_computers_generation_idx").on(t.threadId, t.generation)
1603
+ }));
1604
+ var threadComputerHeads = sqliteTable("thread_computer_heads", {
1605
+ threadId: text("thread_id").primaryKey().references(() => threads.id),
1606
+ activeComputerId: text("active_computer_id").notNull().unique().references(() => threadComputers.id),
1607
+ updatedByProfileId: text("updated_by_profile_id").notNull().references(() => profiles.id),
1608
+ updatedExecutionContextId: text("updated_execution_context_id").notNull().references(() => executionContexts.id),
1609
+ updatedAt: ts("updated_at").notNull()
1610
+ });
1611
+ var computerReprovisions = sqliteTable("computer_reprovisions", {
1612
+ id: text("id").primaryKey(),
1613
+ threadId: text("thread_id").notNull().references(() => threads.id),
1614
+ actorProfileId: text("actor_profile_id").notNull().references(() => profiles.id),
1615
+ executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
1616
+ idempotencyKey: text("idempotency_key").notNull(),
1617
+ targetConfigKey: text("target_config_key").notNull(),
1618
+ reason: text("reason").notNull(),
1619
+ status: text("status").$type().notNull().default("pending"),
1620
+ oldComputerId: text("old_computer_id").notNull().references(() => threadComputers.id),
1621
+ newComputerId: text("new_computer_id").references(() => threadComputers.id),
1622
+ sourceSessionId: text("source_session_id"),
1623
+ targetSessionId: text("target_session_id"),
1624
+ checkpointOutcome: text("checkpoint_outcome").$type().notNull().default("not_needed"),
1625
+ restorationOutcome: text("restoration_outcome").$type().notNull().default("not_needed"),
1626
+ restoredSnapshotId: text("restored_snapshot_id"),
1627
+ failureCode: text("failure_code"),
1628
+ createdAt: ts("created_at").notNull(),
1629
+ completedAt: ts("completed_at")
1630
+ }, (t) => ({
1631
+ idempotencyIdx: uniqueIndex("computer_reprovisions_idempotency_idx").on(t.threadId, t.actorProfileId, t.idempotencyKey),
1632
+ threadIdx: index("computer_reprovisions_thread_idx").on(t.threadId, t.createdAt)
1633
+ }));
1590
1634
  var computerSessions = sqliteTable("computer_sessions", {
1591
1635
  id: text("id").primaryKey(),
1592
1636
  computerId: text("computer_id").notNull().references(() => threadComputers.id),
@@ -16576,6 +16620,15 @@ var computerConfig = exports_external.looseObject({
16576
16620
  setupScript: nullableString,
16577
16621
  repositories: exports_external.array(exports_external.string())
16578
16622
  });
16623
+ var redactedComputerRecipe = exports_external.looseObject({
16624
+ provider: exports_external.string(),
16625
+ backend: exports_external.enum(["worker-shell", "container"]),
16626
+ containerProfile: nullableString,
16627
+ repositories: exports_external.array(exports_external.string()),
16628
+ setupScriptConfigured: exports_external.boolean(),
16629
+ configRevision: exports_external.string(),
16630
+ layers: exports_external.array(exports_external.looseObject({ scope: exports_external.string() }))
16631
+ });
16579
16632
  var computerConfigLayer = exports_external.looseObject({
16580
16633
  id,
16581
16634
  scope: exports_external.string(),
@@ -16903,11 +16956,20 @@ var MCP_OUTPUT_SCHEMAS = {
16903
16956
  }),
16904
16957
  get_computer: exports_external.looseObject({
16905
16958
  threadId: id,
16906
- config: computerConfig,
16907
- topicBase: snapshot.nullable(),
16959
+ config: redactedComputerRecipe,
16960
+ compatibility: exports_external.looseObject({
16961
+ state: exports_external.enum(["ready", "stale_config", "backend_mismatch", "replacement_required"]),
16962
+ reason: exports_external.string(),
16963
+ effectiveRecipe: redactedComputerRecipe,
16964
+ materializedRecipe: redactedComputerRecipe.nullable()
16965
+ }),
16966
+ topicBase: jsonObject.nullable(),
16908
16967
  computer: jsonObject.nullable(),
16968
+ activeGenerationId: id.nullable(),
16969
+ generations: exports_external.array(jsonObject),
16909
16970
  sessions: exports_external.array(jsonObject),
16910
- lineage: exports_external.array(snapshot)
16971
+ lineage: exports_external.array(jsonObject),
16972
+ reprovisions: exports_external.array(jsonObject)
16911
16973
  }),
16912
16974
  publish_topic_computer: exports_external.looseObject({
16913
16975
  published: exports_external.boolean(),
@@ -17181,6 +17243,19 @@ var MCP_OUTPUT_SCHEMAS = {
17181
17243
  materialized: checkpoint.nullable(),
17182
17244
  runtime: jsonObject
17183
17245
  }),
17246
+ computer_reprovision: exports_external.looseObject({
17247
+ reprovisionId: id,
17248
+ threadId: id,
17249
+ status: exports_external.string(),
17250
+ oldComputerId: id,
17251
+ newComputerId: id.nullable(),
17252
+ computerSessionId: id.nullable(),
17253
+ checkpointOutcome: exports_external.string(),
17254
+ restorationOutcome: exports_external.string(),
17255
+ restoredSnapshotId: id.nullable(),
17256
+ failureCode: exports_external.string().nullable(),
17257
+ reason: exports_external.string()
17258
+ }),
17184
17259
  computer_exec: exports_external.looseObject({
17185
17260
  stdout: exports_external.string().optional(),
17186
17261
  stderr: exports_external.string().optional(),
@@ -17421,6 +17496,7 @@ var MCP_TOOL_ANNOTATIONS = {
17421
17496
  app_archive: additive,
17422
17497
  charter: destructive,
17423
17498
  computer_open: additive,
17499
+ computer_reprovision: destructiveIdempotent,
17424
17500
  computer_exec: destructiveOpenWorld,
17425
17501
  computer_status: readOnly,
17426
17502
  computer_verify: openWorld,
@@ -17779,6 +17855,19 @@ var ACTION_DEFINITIONS = [
17779
17855
  toolset: "loop",
17780
17856
  run: forward("computer_runtime.open")
17781
17857
  },
17858
+ {
17859
+ name: "computer_reprovision",
17860
+ title: "Replace a Thread computer",
17861
+ description: "Explicitly replace an incompatible active Computer generation from the Thread's effective recipe. The old generation remains authoritative unless the successor restores supported state and passes health. Same-provider worker-shell→container migration is supported; container→worker-shell and cross-provider migration fail explicitly. Reuse one idempotencyKey only for the same replacement request.",
17862
+ inputSchema: {
17863
+ threadId: exports_external.string().describe("the Thread whose active Computer generation is replaced, thr_…"),
17864
+ idempotencyKey: exports_external.string().min(1).max(200).describe("stable key for this ONE replacement request; reuse it unchanged for retries"),
17865
+ reason: exports_external.string().min(1).max(500).describe("concise auditable reason for replacing the active generation")
17866
+ },
17867
+ surfaces: ["computer-mcp", "computer-cli"],
17868
+ toolset: "loop",
17869
+ run: forward("computer_runtime.reprovision")
17870
+ },
17782
17871
  {
17783
17872
  name: "computer_exec",
17784
17873
  title: "Run a command",
@@ -17988,7 +18077,7 @@ var ACTION_DEFINITIONS = [
17988
18077
  {
17989
18078
  name: "get_computer",
17990
18079
  title: "Read a Thread computer",
17991
- description: "Read a Thread's effective recipe, stable computer identity, current Topic/Thread snapshot refs, recent attachment receipts, and bounded lineage. This is durable Arbor protocol state, not live process/presence status; use Currybox for ephemeral runtime observations.",
18080
+ description: "Read a Thread's redacted effective recipe, active materialized generation, compatibility state, historical generation lineage, current Topic/Thread snapshot refs, recent attachment receipts, and replacement outcomes. Recipe metadata includes provider/backend/profile/repositories/config revision and whether setup is configured, never setup content or credentials. This is durable Arbor protocol state, not live process/presence status.",
17992
18081
  inputSchema: {
17993
18082
  threadId: exports_external.string().describe("the Thread, thr_…"),
17994
18083
  lineageLimit: exports_external.number().int().min(1).max(100).optional().describe("recent receipts/lineage rows (default 20)")
@@ -19506,6 +19595,11 @@ function parseErrorDetails(value) {
19506
19595
  };
19507
19596
  }
19508
19597
  }
19598
+ if (typeof raw.compatibilityState === "string") {
19599
+ details.compatibilityState = raw.compatibilityState;
19600
+ }
19601
+ if (typeof raw.suggestedAction === "string")
19602
+ details.suggestedAction = raw.suggestedAction;
19509
19603
  return details;
19510
19604
  }
19511
19605
  function detailsForError(err) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.14.4",
3
+ "version": "0.14.5",
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",