@lambdacurry/arbor 0.24.16 → 0.24.17

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 +59 -15
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -7657,13 +7657,16 @@ var threads = sqliteTable("threads", {
7657
7657
  openQuestions: text("open_questions", { mode: "json" }).$type().notNull().default([]),
7658
7658
  expectedOutput: text("expected_output").notNull().default(""),
7659
7659
  number: integer2("number"),
7660
- createdAt: ts("created_at").notNull()
7660
+ createdAt: ts("created_at").notNull(),
7661
+ lastActivityAt: ts("last_activity_at")
7661
7662
  }, (t) => ({
7662
7663
  spaceNumberUq: uniqueIndex("threads_space_number_uq").on(t.spaceId, t.number),
7663
7664
  topicIdx: index("threads_topic_idx").on(t.topicId),
7664
7665
  spaceIdx: index("threads_space_idx").on(t.spaceId),
7665
7666
  lifecycleTypeIdx: index("threads_lifecycle_type_idx").on(t.lifecycleType),
7666
- topicLifecycleRankIdx: index("threads_topic_lifecycle_rank_idx").on(t.topicId, t.lifecycleType, t.rank)
7667
+ topicLifecycleRankIdx: index("threads_topic_lifecycle_rank_idx").on(t.topicId, t.lifecycleType, t.rank),
7668
+ topicLabelRankIdx: index("threads_topic_label_rank_idx").on(t.topicId, t.lifecycleLabel, t.rank, t.lastActivityAt),
7669
+ topicActivityIdx: index("threads_topic_activity_idx").on(t.topicId, t.lastActivityAt, t.id)
7667
7670
  }));
7668
7671
  var computerConfigs = sqliteTable("computer_configs", {
7669
7672
  id: text("id").primaryKey(),
@@ -8040,6 +8043,29 @@ var computerSnapshots = sqliteTable("computer_snapshots", {
8040
8043
  runIdx: index("computer_snapshots_run_idx").on(t.runId, t.createdAt),
8041
8044
  parentIdx: index("computer_snapshots_parent_idx").on(t.parentSnapshotId)
8042
8045
  }));
8046
+ var computerCheckpointOperations = sqliteTable("computer_checkpoint_operations", {
8047
+ operationId: text("operation_id").primaryKey(),
8048
+ computerId: text("computer_id").notNull().references(() => threadComputers.id),
8049
+ payload: text("payload").notNull(),
8050
+ payloadDigest: text("payload_digest").notNull(),
8051
+ workspaceGeneration: text("workspace_generation").notNull(),
8052
+ captureMutationVersion: integer2("capture_mutation_version").notNull(),
8053
+ expectedHeadSnapshotId: text("expected_head_snapshot_id"),
8054
+ state: text("state").$type().notNull(),
8055
+ failureCode: text("failure_code"),
8056
+ nativeSnapshotId: text("native_snapshot_id"),
8057
+ capturedAt: ts("captured_at"),
8058
+ expiresAt: ts("expires_at"),
8059
+ portableProviderRef: text("portable_provider_ref"),
8060
+ publishedSnapshotId: text("published_snapshot_id"),
8061
+ restoreSessionId: text("restore_session_id"),
8062
+ restoreState: text("restore_state").$type(),
8063
+ restoredAt: ts("restored_at"),
8064
+ createdAt: ts("created_at").notNull(),
8065
+ updatedAt: ts("updated_at").notNull()
8066
+ }, (t) => ({
8067
+ computerIdx: index("computer_checkpoint_operations_computer_idx").on(t.computerId, t.createdAt)
8068
+ }));
8043
8069
  var computerSnapshotEvidence = sqliteTable("computer_snapshot_evidence", {
8044
8070
  snapshotId: text("snapshot_id").primaryKey().references(() => computerSnapshots.id),
8045
8071
  purpose: text("purpose").$type().notNull(),
@@ -9199,11 +9225,7 @@ var assigneeColumns = {
9199
9225
  color: profiles.color,
9200
9226
  emoji: profiles.emoji
9201
9227
  };
9202
- var lastActivityExpr = sql`coalesce(
9203
- (select max(${contributions.createdAt}) from ${contributions}
9204
- where ${contributions.threadId} = ${threads.id}),
9205
- ${threads.createdAt}
9206
- )`;
9228
+ var lastActivity = sql`${threads.lastActivityAt}`;
9207
9229
 
9208
9230
  // ../core/src/ops/space.ts
9209
9231
  var GUIDANCE_LIMITS = {
@@ -9320,6 +9342,8 @@ var BASE_MS = Date.parse("2026-07-20T15:00:00.000Z");
9320
9342
  var PAIRING_TTL_MS = 15 * 60 * 1000;
9321
9343
  // ../core/src/ops/space-visit.ts
9322
9344
  var VISIT_THROTTLE_MS = 5 * 60 * 1000;
9345
+ // ../core/src/ops/computer-checkpoint-operations.ts
9346
+ var CHECKPOINT_OPERATION_TTL_SECONDS = 7 * 24 * 60 * 60;
9323
9347
  // ../core/src/ops/package-cache.ts
9324
9348
  var PACKAGE_CACHE_PENDING_TTL_MS = 15 * 60 * 1000;
9325
9349
  var PACKAGE_CACHE_FINAL_TTL_MS = 30 * 24 * 60 * 60 * 1000;
@@ -10603,9 +10627,26 @@ function buildOutputSchemas() {
10603
10627
  workflow: workflowSummary.optional(),
10604
10628
  threads: array(thread).optional(),
10605
10629
  promotedArtifacts: array(artifact).optional(),
10606
- total: number2().int().min(0),
10630
+ total: number2().int().min(0).optional(),
10607
10631
  nextCursor: string2().optional(),
10608
- computerConfig: resolvedComputerConfig.nullable().optional()
10632
+ computerConfig: resolvedComputerConfig.nullable().optional(),
10633
+ counts: looseObject({
10634
+ total: number2().int().min(0),
10635
+ byStatus: record(string2(), number2().int().min(0)),
10636
+ byLabel: record(string2(), number2().int().min(0))
10637
+ }).optional(),
10638
+ canEditGuidance: boolean2().optional()
10639
+ }).superRefine((value, ctx) => {
10640
+ if (value.threads !== undefined && value.total === undefined) {
10641
+ ctx.addIssue({
10642
+ code: "custom",
10643
+ path: ["total"],
10644
+ message: "a Thread roster requires total"
10645
+ });
10646
+ }
10647
+ if (value.threads === undefined && value.counts === undefined) {
10648
+ ctx.addIssue({ code: "custom", path: ["counts"], message: "a header requires counts" });
10649
+ }
10609
10650
  }),
10610
10651
  goal: looseObject({
10611
10652
  id: id.optional(),
@@ -13061,7 +13102,7 @@ var ACTION_DEFINITIONS = [
13061
13102
  {
13062
13103
  name: "thread_list",
13063
13104
  title: "List assigned threads or a Space's threads",
13064
- description: "List Threads you are responsible for (default), another profile's or jointly several, unassigned in one Space/Topic, or every Thread in a Space (`assignee=any` + spaceId) — default current work; status widens; order=activity is last-activity DESC (the aggregate board). `inbox` remains what you owe.",
13105
+ description: "List Threads you are responsible for (default), another profile's or jointly several, unassigned in one Space/Topic, or every Thread in a Space or Topic (`assignee=any` + spaceId or one topicId) — default current work; status widens; order=activity is last-activity DESC (the aggregate board). `inbox` remains what you owe.",
13065
13106
  inputSchema: {
13066
13107
  assignee: union([string2(), array(string2()).min(1).max(5)]).optional().describe("`me` (default), a profile id (prof_…), a list (assigned to ALL of them), or `any` (every Thread in the required spaceId)"),
13067
13108
  unassigned: boolean2().optional().describe("threads with no assignee — requires spaceId or topicId"),
@@ -13094,8 +13135,9 @@ var ACTION_DEFINITIONS = [
13094
13135
  "archived"
13095
13136
  ])).min(1).max(8)
13096
13137
  ]).optional().describe("default current = active + needs-review + stuck; all includes backlog/standing/resolved/canceled/archived; or a list of statuses to keep (current/all only alone)"),
13097
- order: _enum(["assigned", "activity"]).optional().describe("default assigned = newest assignment first; activity = last_activity_at DESC (aggregate board order)"),
13098
- limit: number2().int().min(1).max(100).optional().describe("page size (default 20, max 100)"),
13138
+ order: _enum(["assigned", "activity", "column"]).optional().describe("default assigned = newest assignment first; activity = last_activity_at DESC (default page 50); column = one Topic Board column, ranked then by recency (needs assignee=any, one topicId, lifecycleLabel)"),
13139
+ lifecycleLabel: string2().min(1).optional().describe("order=column only: the Board column's lifecycle label key"),
13140
+ limit: number2().int().min(1).max(100).optional().describe("page size (default 20; 50 for order=activity; max 100)"),
13099
13141
  cursor: string2().optional().describe("keyset cursor from a prior page's nextCursor")
13100
13142
  },
13101
13143
  surfaces: ["mcp", "cli"],
@@ -14517,11 +14559,13 @@ var ACTION_DEFINITIONS = [
14517
14559
  {
14518
14560
  name: "topic_get",
14519
14561
  title: "Read a topic",
14520
- description: "Read a Topic's durable context, guidance, the room's standing ways to help (`contributionLanes`), selected workflow summary, open requests, promoted artifacts, and a paged Thread roster (default 50; `total` is the full roster size). Continue with `cursor`, or use `all=true` / `--all` only for intentional complete enumeration; for a concrete question in a large Topic, prefer Topic-scoped `recall`.",
14562
+ description: "Read a Topic's durable context, guidance, the room's standing ways to help (`contributionLanes`), selected workflow summary, open requests, promoted artifacts, and a paged Thread roster (default 50; `total` is the full roster size). Continue with `cursor`, or use `all=true` / `--all` only for intentional complete enumeration; for a concrete question in a large Topic, prefer Topic-scoped `recall`. `threads=none` is the header alone.",
14521
14563
  inputSchema: {
14522
14564
  topicId: string2().min(1).describe("the topic id"),
14565
+ threads: _enum(["page", "none"]).optional().describe("page (default) includes the Thread roster page; none = header only — counts by status/label, participants, open-request count (no limit/cursor/all); page its Threads with thread_list assignee=any + topicId"),
14523
14566
  ...PAGINATION_INPUT
14524
14567
  },
14568
+ externalReadDefaults: { unpagedWhen: { field: "threads", value: "none" } },
14525
14569
  surfaces: ["mcp", "cli"],
14526
14570
  toolset: "loop",
14527
14571
  run: forward("topic.get")
@@ -15526,7 +15570,7 @@ var ACTIONS = ACTION_DEFINITIONS.map((action) => {
15526
15570
  });
15527
15571
 
15528
15572
  // ../actions/src/retention-entry.ts
15529
- var ARBOR_VERSION = "0.24.16";
15573
+ var ARBOR_VERSION = "0.24.17";
15530
15574
  var historyPolicySchema = _enum(["full", "checkpoint"]).optional().describe("text Artifacts: future history retention policy; full retains every source snapshot, checkpoint keeps metadata for every revision and source only when explicitly retained");
15531
15575
  var retainSourceSchema = boolean2().optional().describe("edit: in checkpoint mode, retain this newly minted content revision's source");
15532
15576
  var checkpointSchema = boolean2().optional().describe("edit: retain the exact current version source without incrementing content version");
@@ -16410,7 +16454,7 @@ function dispositionFilename(value) {
16410
16454
  // package.json
16411
16455
  var package_default = {
16412
16456
  name: "@lambdacurry/arbor",
16413
- version: "0.24.16",
16457
+ version: "0.24.17",
16414
16458
  description: "The Arbor CLI — a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
16415
16459
  keywords: [
16416
16460
  "agents",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.24.16",
3
+ "version": "0.24.17",
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",