@lambdacurry/arbor 0.23.2 → 0.23.4

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 +104 -10
  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.23.2",
5
+ version: "0.23.4",
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",
@@ -4943,7 +4943,7 @@ var LIFECYCLE_TYPE_DESCRIPTIONS = {
4943
4943
  };
4944
4944
  function transitionThreadActionDescription() {
4945
4945
  const types = LIFECYCLE_TYPES.map((type) => `\`${type}\` ${LIFECYCLE_TYPE_DESCRIPTIONS[type]}`).join("; ");
4946
- return `Move a Thread by key, case-insensitive name, or type (\`--to resolved\` still works as a bare type); illegal jumps rejected; optional \`--rank\`. ${types}; live menu is \`thread_get.transitionsFrom\`.`;
4946
+ return `Move a Thread by key, case-insensitive name, or type (\`--to resolved\` still works as a bare type); every type is reachable; optional \`--rank\`. ${types}; live menu is \`thread_get.transitionsFrom\`.`;
4947
4947
  }
4948
4948
  var CONTRIBUTION_TYPES = [
4949
4949
  "comment",
@@ -6737,6 +6737,7 @@ var computerRuns = sqliteTable("computer_runs", {
6737
6737
  runtimeUpdatedAt: ts("runtime_updated_at"),
6738
6738
  gitStart: text("git_start", { mode: "json" }).$type(),
6739
6739
  f1Authority: text("f1_authority", { mode: "json" }).$type(),
6740
+ workspaceState: text("workspace_state", { mode: "json" }).$type(),
6740
6741
  finishRequest: text("finish_request", { mode: "json" }).$type(),
6741
6742
  status: text("status").$type().notNull().default("active"),
6742
6743
  label: text("label"),
@@ -6804,6 +6805,68 @@ var packageCacheProjectUsage = sqliteTable("package_cache_project_usage", {
6804
6805
  objectBudget: check("package_cache_project_usage_object_budget", sql`${t.objectCount} + ${t.reservedObjects} <= ${t.maxObjects}`),
6805
6806
  dailyWriteBudget: check("package_cache_project_usage_daily_write_budget", sql`${t.writeBytesToday} + ${t.reservedBytes} <= ${t.maxWriteBytesPerDay}`)
6806
6807
  }));
6808
+ var taskCacheObjects = sqliteTable("task_cache_objects", {
6809
+ key: text("key").primaryKey(),
6810
+ orgId: text("org_id").notNull().references(() => orgs.id),
6811
+ project: text("project").notNull(),
6812
+ runner: text("runner").notNull(),
6813
+ hash: text("hash").notNull(),
6814
+ byteLength: integer2("byte_length").notNull(),
6815
+ status: text("status").$type().notNull(),
6816
+ reservationId: text("reservation_id").notNull(),
6817
+ producerRunId: text("producer_run_id").notNull().references(() => computerRuns.id),
6818
+ producerTrust: text("producer_trust").$type().notNull(),
6819
+ artifactTag: text("artifact_tag").notNull(),
6820
+ sourceSha: text("source_sha"),
6821
+ dirtyHash: text("dirty_hash"),
6822
+ durationMs: integer2("duration_ms"),
6823
+ providerChargedAt: ts("provider_charged_at"),
6824
+ etag: text("etag"),
6825
+ createdAt: ts("created_at").notNull(),
6826
+ readyAt: ts("ready_at"),
6827
+ expiresAt: ts("expires_at").notNull()
6828
+ }, (t) => ({
6829
+ reservationUq: uniqueIndex("task_cache_objects_reservation_uniq").on(t.reservationId),
6830
+ projectRunnerStatusExpiryIdx: index("task_cache_objects_project_runner_status_expiry_idx").on(t.orgId, t.project, t.runner, t.status, t.expiresAt)
6831
+ }));
6832
+ var taskCacheProjectUsage = sqliteTable("task_cache_project_usage", {
6833
+ id: text("id").primaryKey(),
6834
+ orgId: text("org_id").notNull().references(() => orgs.id),
6835
+ project: text("project").notNull(),
6836
+ maxStoredBytes: integer2("max_stored_bytes").notNull(),
6837
+ maxObjects: integer2("max_objects").notNull(),
6838
+ maxWriteBytesPerDay: integer2("max_write_bytes_per_day").notNull(),
6839
+ maxClassAOpsPerDay: integer2("max_class_a_ops_per_day").notNull(),
6840
+ maxClassBOpsPerDay: integer2("max_class_b_ops_per_day").notNull(),
6841
+ dailyPeriod: text("daily_period").notNull(),
6842
+ writeBytesToday: integer2("write_bytes_today").notNull().default(0),
6843
+ classAOpsToday: integer2("class_a_ops_today").notNull().default(0),
6844
+ classBOpsToday: integer2("class_b_ops_today").notNull().default(0),
6845
+ storedBytes: integer2("stored_bytes").notNull().default(0),
6846
+ objectCount: integer2("object_count").notNull().default(0),
6847
+ reservedBytes: integer2("reserved_bytes").notNull().default(0),
6848
+ reservedObjects: integer2("reserved_objects").notNull().default(0),
6849
+ writeBytes: integer2("write_bytes").notNull().default(0),
6850
+ readBytes: integer2("read_bytes").notNull().default(0),
6851
+ hits: integer2("hits").notNull().default(0),
6852
+ misses: integer2("misses").notNull().default(0),
6853
+ rejections: integer2("rejections").notNull().default(0),
6854
+ classAOps: integer2("class_a_ops").notNull().default(0),
6855
+ classBOps: integer2("class_b_ops").notNull().default(0),
6856
+ publicationsNew: integer2("publications_new").notNull().default(0),
6857
+ publicationsDuplicate: integer2("publications_duplicate").notNull().default(0),
6858
+ publicationsReconciled: integer2("publications_reconciled").notNull().default(0),
6859
+ publicationsRejected: integer2("publications_rejected").notNull().default(0),
6860
+ updatedAt: ts("updated_at").notNull()
6861
+ }, (t) => ({
6862
+ projectUq: uniqueIndex("task_cache_project_usage_project_uniq").on(t.orgId, t.project),
6863
+ nonnegative: check("task_cache_project_usage_nonnegative", sql`${t.storedBytes} >= 0 AND ${t.objectCount} >= 0 AND ${t.reservedBytes} >= 0 AND ${t.reservedObjects} >= 0 AND ${t.writeBytesToday} >= 0 AND ${t.classAOpsToday} >= 0 AND ${t.classBOpsToday} >= 0`),
6864
+ byteBudget: check("task_cache_project_usage_byte_budget", sql`${t.storedBytes} + ${t.reservedBytes} <= ${t.maxStoredBytes}`),
6865
+ objectBudget: check("task_cache_project_usage_object_budget", sql`${t.objectCount} + ${t.reservedObjects} <= ${t.maxObjects}`),
6866
+ dailyWriteBudget: check("task_cache_project_usage_daily_write_budget", sql`${t.writeBytesToday} <= ${t.maxWriteBytesPerDay}`),
6867
+ dailyClassABudget: check("task_cache_project_usage_daily_class_a_budget", sql`${t.classAOpsToday} <= ${t.maxClassAOpsPerDay}`),
6868
+ dailyClassBBudget: check("task_cache_project_usage_daily_class_b_budget", sql`${t.classBOpsToday} <= ${t.maxClassBOpsPerDay}`)
6869
+ }));
6807
6870
  var computerSnapshots = sqliteTable("computer_snapshots", {
6808
6871
  id: text("id").primaryKey(),
6809
6872
  ownerScope: text("owner_scope").$type().notNull(),
@@ -7727,6 +7790,7 @@ var artifactTldrawPreviewCandidates = sqliteTable("artifact_tldraw_preview_candi
7727
7790
  r2KeyIdx: uniqueIndex("artifact_tldraw_preview_candidates_r2_key_uniq").on(t.r2Key)
7728
7791
  }));
7729
7792
  // ../core/src/lifecycle/thread.ts
7793
+ var TYPE_SET = new Set(LIFECYCLE_TYPES);
7730
7794
  var STATUS_OPENNESS = {
7731
7795
  backlog: { working: false, currentWork: false, closed: false },
7732
7796
  active: { working: true, currentWork: true, closed: false },
@@ -7916,6 +7980,7 @@ var COMPUTER_RUN_F1_FINAL_FAILURE_CODES = new Set([
7916
7980
  ]);
7917
7981
  var TERMINAL = new Set(["finished", "failed", "cancelled"]);
7918
7982
  var RUN_LIFECYCLE_TYPES = new Set(["run.started", "run.finished", "run.failed", "run.cancelled"]);
7983
+ var COMPUTER_RUN_RECOVERY_WINDOW_MS = 60 * 60 * 1000;
7919
7984
  var COMPUTER_RUN_ACTIVITY_LABEL_MAX = 120;
7920
7985
  var RUN_PROVIDER_LIFECYCLE_PHASES = [
7921
7986
  "allocate",
@@ -7966,9 +8031,18 @@ var assigneeColumns = {
7966
8031
  color: profiles.color,
7967
8032
  emoji: profiles.emoji
7968
8033
  };
8034
+ var lastActivityExpr = sql`coalesce(
8035
+ (select max(${contributions.createdAt}) from ${contributions}
8036
+ where ${contributions.threadId} = ${threads.id}),
8037
+ ${threads.createdAt}
8038
+ )`;
7969
8039
  // ../core/src/ops/package-cache.ts
7970
8040
  var PACKAGE_CACHE_PENDING_TTL_MS = 15 * 60 * 1000;
7971
8041
  var PACKAGE_CACHE_FINAL_TTL_MS = 30 * 24 * 60 * 60 * 1000;
8042
+ // ../core/src/ops/task-cache.ts
8043
+ var TASK_CACHE_PENDING_TTL_MS = 15 * 60 * 1000;
8044
+ var TASK_CACHE_FINAL_TTL_MS = 7 * 24 * 60 * 60 * 1000;
8045
+ var TASK_CACHE_RECOVERABLE_TTL_MS = 30 * 24 * 60 * 60 * 1000;
7972
8046
  // ../core/src/ops/computer-output.ts
7973
8047
  var COMPUTER_OUTPUT_DEFAULT_STALE_MS = 24 * 60 * 60 * 1000;
7974
8048
  // ../core/src/ops/computer-recovery.ts
@@ -9095,12 +9169,19 @@ var MCP_OUTPUT_SCHEMAS = {
9095
9169
  topicTitle: string2(),
9096
9170
  createdAt: string2(),
9097
9171
  lastActivityAt: string2(),
9172
+ lifecycleLabel: string2().optional(),
9173
+ workflow: looseObject({
9174
+ id: string2(),
9175
+ allowedTypes: array(string2()),
9176
+ labelByType: record(string2(), string2())
9177
+ }).optional(),
9098
9178
  assignees: array(threadAssignee),
9099
9179
  url: string2().optional()
9100
9180
  })),
9101
9181
  nextCursor: nullableString,
9102
9182
  total: number2().int().min(0),
9103
- status: string2().optional()
9183
+ status: string2().optional(),
9184
+ order: string2().optional()
9104
9185
  }),
9105
9186
  tree: looseObject({
9106
9187
  spaces: array(treeSpace),
@@ -11252,12 +11333,12 @@ var ACTION_DEFINITIONS = [
11252
11333
  },
11253
11334
  {
11254
11335
  name: "thread_list",
11255
- title: "List threads by responsibility",
11256
- description: "List the Threads you are responsible for (default), those assigned to another profile (or jointly to several), or the unassigned ones inside one Space or Topic current work only (active, needs-review, stuck) unless status widens it. Read it to decide what to move forward; `inbox` remains the list of specific actions you owe.",
11336
+ title: "List assigned threads or a Space's threads",
11337
+ 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.",
11257
11338
  inputSchema: {
11258
- assignee: union([string2(), array(string2()).min(1).max(5)]).optional().describe("`me` (default) or a profile id, prof_…; a list (repeat the flag) means assigned to ALL of them the pair view"),
11339
+ 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)"),
11259
11340
  unassigned: boolean2().optional().describe("threads with no assignee — requires spaceId or topicId"),
11260
- spaceId: string2().optional().describe("narrow to one space, spc_…"),
11341
+ spaceId: string2().optional().describe("one space, spc_… — required for assignee=any; unassigned needs spaceId or topicId"),
11261
11342
  topicId: string2().optional().describe("narrow to one topic, top_…"),
11262
11343
  status: _enum([
11263
11344
  "current",
@@ -11271,6 +11352,7 @@ var ACTION_DEFINITIONS = [
11271
11352
  "canceled",
11272
11353
  "archived"
11273
11354
  ]).optional().describe("default current = active + needs-review + stuck; all includes backlog/standing/resolved/canceled/archived"),
11355
+ order: _enum(["assigned", "activity"]).optional().describe("default assigned = newest assignment first; activity = last_activity_at DESC (aggregate board order)"),
11274
11356
  limit: number2().int().min(1).max(100).optional().describe("page size (default 20, max 100)"),
11275
11357
  cursor: string2().optional().describe("keyset cursor from a prior page's nextCursor")
11276
11358
  },
@@ -14625,9 +14707,21 @@ function positionalSpecs(action) {
14625
14707
  return fields.map((field) => specs.find((spec) => spec.field === field));
14626
14708
  }
14627
14709
  var KNOWN_MISREACHES = [
14628
- { tried: "thread list", use: "tree --depth threads", why: "threads are listed by the tree" },
14629
- { tried: "threads", use: "tree --depth threads", why: "threads are listed by the tree" },
14630
- { tried: "list threads", use: "tree --depth threads", why: "threads are listed by the tree" },
14710
+ {
14711
+ tried: "thread list",
14712
+ use: "thread_list",
14713
+ why: "the bounded page (My Threads by default; a Space is --space-id --assignee any)"
14714
+ },
14715
+ {
14716
+ tried: "threads",
14717
+ use: "tree --depth threads",
14718
+ why: "the tree is the map; thread_list is the bounded page"
14719
+ },
14720
+ {
14721
+ tried: "list threads",
14722
+ use: "tree --depth threads",
14723
+ why: "the tree is the map; thread_list is the bounded page"
14724
+ },
14631
14725
  { tried: "spaces", use: "tree", why: "the tree lists spaces" },
14632
14726
  { tried: "space list", use: "tree", why: "the tree lists spaces" },
14633
14727
  { tried: "topics", use: "tree --depth topics", why: "topics are a tree depth" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.23.2",
3
+ "version": "0.23.4",
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",