@lambdacurry/arbor 0.23.26 → 0.23.28

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 +216 -13
  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.26",
5
+ version: "0.23.28",
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",
@@ -2232,6 +2232,112 @@ function handleIntersectionResults(result, left, right) {
2232
2232
  result.value = merged.data;
2233
2233
  return result;
2234
2234
  }
2235
+ var $ZodTuple = /* @__PURE__ */ $constructor("$ZodTuple", (inst, def) => {
2236
+ $ZodType.init(inst, def);
2237
+ const items = def.items;
2238
+ inst._zod.parse = (payload, ctx) => {
2239
+ const input = payload.value;
2240
+ if (!Array.isArray(input)) {
2241
+ payload.issues.push({
2242
+ input,
2243
+ inst,
2244
+ expected: "tuple",
2245
+ code: "invalid_type"
2246
+ });
2247
+ return payload;
2248
+ }
2249
+ payload.value = [];
2250
+ const proms = [];
2251
+ const optinStart = getTupleOptStart(items, "optin");
2252
+ const optoutStart = getTupleOptStart(items, "optout");
2253
+ if (!def.rest) {
2254
+ if (input.length < optinStart) {
2255
+ payload.issues.push({
2256
+ code: "too_small",
2257
+ minimum: optinStart,
2258
+ inclusive: true,
2259
+ input,
2260
+ inst,
2261
+ origin: "array"
2262
+ });
2263
+ return payload;
2264
+ }
2265
+ if (input.length > items.length) {
2266
+ payload.issues.push({
2267
+ code: "too_big",
2268
+ maximum: items.length,
2269
+ inclusive: true,
2270
+ input,
2271
+ inst,
2272
+ origin: "array"
2273
+ });
2274
+ }
2275
+ }
2276
+ const itemResults = new Array(items.length);
2277
+ for (let i = 0;i < items.length; i++) {
2278
+ const r = items[i]._zod.run({ value: input[i], issues: [] }, ctx);
2279
+ if (r instanceof Promise) {
2280
+ proms.push(r.then((rr) => {
2281
+ itemResults[i] = rr;
2282
+ }));
2283
+ } else {
2284
+ itemResults[i] = r;
2285
+ }
2286
+ }
2287
+ if (def.rest) {
2288
+ let i = items.length - 1;
2289
+ const rest = input.slice(items.length);
2290
+ for (const el of rest) {
2291
+ i++;
2292
+ const result = def.rest._zod.run({ value: el, issues: [] }, ctx);
2293
+ if (result instanceof Promise) {
2294
+ proms.push(result.then((r) => handleTupleResult(r, payload, i)));
2295
+ } else {
2296
+ handleTupleResult(result, payload, i);
2297
+ }
2298
+ }
2299
+ }
2300
+ if (proms.length) {
2301
+ return Promise.all(proms).then(() => handleTupleResults(itemResults, payload, items, input, optoutStart));
2302
+ }
2303
+ return handleTupleResults(itemResults, payload, items, input, optoutStart);
2304
+ };
2305
+ });
2306
+ function getTupleOptStart(items, key) {
2307
+ for (let i = items.length - 1;i >= 0; i--) {
2308
+ if (items[i]._zod[key] !== "optional")
2309
+ return i + 1;
2310
+ }
2311
+ return 0;
2312
+ }
2313
+ function handleTupleResult(result, final, index) {
2314
+ if (result.issues.length) {
2315
+ final.issues.push(...prefixIssues(index, result.issues));
2316
+ }
2317
+ final.value[index] = result.value;
2318
+ }
2319
+ function handleTupleResults(itemResults, final, items, input, optoutStart) {
2320
+ for (let i = 0;i < items.length; i++) {
2321
+ const r = itemResults[i];
2322
+ const isPresent = i < input.length;
2323
+ if (r.issues.length) {
2324
+ if (!isPresent && i >= optoutStart) {
2325
+ final.value.length = i;
2326
+ break;
2327
+ }
2328
+ final.issues.push(...prefixIssues(i, r.issues));
2329
+ }
2330
+ final.value[i] = r.value;
2331
+ }
2332
+ for (let i = final.value.length - 1;i >= input.length; i--) {
2333
+ if (items[i]._zod.optout === "optional" && final.value[i] === undefined) {
2334
+ final.value.length = i;
2335
+ } else {
2336
+ break;
2337
+ }
2338
+ }
2339
+ return final;
2340
+ }
2235
2341
  var $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def) => {
2236
2342
  $ZodType.init(inst, def);
2237
2343
  inst._zod.parse = (payload, ctx) => {
@@ -3875,6 +3981,48 @@ var intersectionProcessor = (schema, ctx, json, params) => {
3875
3981
  ];
3876
3982
  json.allOf = allOf;
3877
3983
  };
3984
+ var tupleProcessor = (schema, ctx, _json, params) => {
3985
+ const json = _json;
3986
+ const def = schema._zod.def;
3987
+ json.type = "array";
3988
+ const prefixPath = ctx.target === "draft-2020-12" ? "prefixItems" : "items";
3989
+ const restPath = ctx.target === "draft-2020-12" ? "items" : ctx.target === "openapi-3.0" ? "items" : "additionalItems";
3990
+ const prefixItems = def.items.map((x, i) => process2(x, ctx, {
3991
+ ...params,
3992
+ path: [...params.path, prefixPath, i]
3993
+ }));
3994
+ const rest = def.rest ? process2(def.rest, ctx, {
3995
+ ...params,
3996
+ path: [...params.path, restPath, ...ctx.target === "openapi-3.0" ? [def.items.length] : []]
3997
+ }) : null;
3998
+ if (ctx.target === "draft-2020-12") {
3999
+ json.prefixItems = prefixItems;
4000
+ if (rest) {
4001
+ json.items = rest;
4002
+ }
4003
+ } else if (ctx.target === "openapi-3.0") {
4004
+ json.items = {
4005
+ anyOf: prefixItems
4006
+ };
4007
+ if (rest) {
4008
+ json.items.anyOf.push(rest);
4009
+ }
4010
+ json.minItems = prefixItems.length;
4011
+ if (!rest) {
4012
+ json.maxItems = prefixItems.length;
4013
+ }
4014
+ } else {
4015
+ json.items = prefixItems;
4016
+ if (rest) {
4017
+ json.additionalItems = rest;
4018
+ }
4019
+ }
4020
+ const { minimum, maximum } = schema._zod.bag;
4021
+ if (typeof minimum === "number")
4022
+ json.minItems = minimum;
4023
+ if (typeof maximum === "number")
4024
+ json.maxItems = maximum;
4025
+ };
3878
4026
  var recordProcessor = (schema, ctx, _json, params) => {
3879
4027
  const json = _json;
3880
4028
  const def = schema._zod.def;
@@ -4629,6 +4777,26 @@ function intersection(left, right) {
4629
4777
  right
4630
4778
  });
4631
4779
  }
4780
+ var ZodTuple = /* @__PURE__ */ $constructor("ZodTuple", (inst, def) => {
4781
+ $ZodTuple.init(inst, def);
4782
+ ZodType.init(inst, def);
4783
+ inst._zod.processJSONSchema = (ctx, json, params) => tupleProcessor(inst, ctx, json, params);
4784
+ inst.rest = (rest) => inst.clone({
4785
+ ...inst._zod.def,
4786
+ rest
4787
+ });
4788
+ });
4789
+ function tuple(items, _paramsOrRest, _params) {
4790
+ const hasRest = _paramsOrRest instanceof $ZodType;
4791
+ const params = hasRest ? _params : _paramsOrRest;
4792
+ const rest = hasRest ? _paramsOrRest : null;
4793
+ return new ZodTuple({
4794
+ type: "tuple",
4795
+ items,
4796
+ rest,
4797
+ ...normalizeParams(params)
4798
+ });
4799
+ }
4632
4800
  var ZodRecord = /* @__PURE__ */ $constructor("ZodRecord", (inst, def) => {
4633
4801
  $ZodRecord.init(inst, def);
4634
4802
  ZodType.init(inst, def);
@@ -6457,12 +6625,13 @@ var workflows = sqliteTable("workflows", {
6457
6625
  name: text("name").notNull(),
6458
6626
  summary: text("summary").notNull(),
6459
6627
  labels: text("labels", { mode: "json" }).$type().notNull(),
6628
+ derivedFromBuiltin: text("derived_from_builtin").$type(),
6460
6629
  createdAt: ts("created_at").notNull(),
6461
6630
  updatedAt: ts("updated_at").notNull()
6462
6631
  }, (t) => ({ orgIdx: index("workflows_org_idx").on(t.orgId) }));
6463
6632
  var spaceWorkflows = sqliteTable("space_workflows", {
6464
6633
  spaceId: text("space_id").notNull().references(() => spaces.id),
6465
- workflowId: text("workflow_id").notNull().references(() => workflows.id),
6634
+ workflowId: text("workflow_id").notNull(),
6466
6635
  isDefault: integer2("is_default", { mode: "boolean" }).notNull().default(false)
6467
6636
  }, (t) => ({
6468
6637
  pk: primaryKey({ columns: [t.spaceId, t.workflowId] }),
@@ -6476,7 +6645,7 @@ var topics = sqliteTable("topics", {
6476
6645
  purpose: text("purpose"),
6477
6646
  guidance: text("guidance", { mode: "json" }).$type().notNull().default([]),
6478
6647
  contributionLanes: text("contribution_lanes", { mode: "json" }).$type().notNull().default([]),
6479
- workflowId: text("workflow_id").references(() => workflows.id),
6648
+ workflowId: text("workflow_id"),
6480
6649
  archivedAt: ts("archived_at"),
6481
6650
  createdAt: ts("created_at").notNull()
6482
6651
  }, (t) => ({
@@ -7751,7 +7920,26 @@ var notificationCursors = sqliteTable("notification_cursors", {
7751
7920
  var recallIndex = sqliteTable("recall_index", {
7752
7921
  objectId: text("object_id").primaryKey(),
7753
7922
  indexedAt: ts("indexed_at").notNull(),
7754
- chunks: integer2("chunks")
7923
+ chunks: integer2("chunks"),
7924
+ pendingToken: text("pending_token"),
7925
+ vectorRevision: text("vector_revision")
7926
+ }, (t) => ({ pendingIdx: index("recall_index_pending_idx").on(t.pendingToken) }));
7927
+ var recallLifecycleRefreshes = sqliteTable("recall_lifecycle_refreshes", {
7928
+ threadId: text("thread_id").primaryKey().references(() => threads.id, { onDelete: "cascade" }),
7929
+ targetType: text("target_type").$type().notNull(),
7930
+ generation: text("generation").notNull(),
7931
+ cursorType: text("cursor_type").$type(),
7932
+ cursorId: text("cursor_id"),
7933
+ leaseToken: text("lease_token"),
7934
+ leaseUntil: ts("lease_until"),
7935
+ updatedAt: ts("updated_at").notNull()
7936
+ }, (t) => ({
7937
+ pendingIdx: index("recall_lifecycle_refreshes_pending_idx").on(t.updatedAt)
7938
+ }));
7939
+ var recallVectorLeases = sqliteTable("recall_vector_leases", {
7940
+ threadId: text("thread_id").primaryKey().references(() => threads.id, { onDelete: "cascade" }),
7941
+ token: text("token").notNull(),
7942
+ leaseUntil: ts("lease_until").notNull()
7755
7943
  });
7756
7944
  var watches = sqliteTable("watches", {
7757
7945
  id: text("id").primaryKey(),
@@ -7833,6 +8021,7 @@ var BUILTIN_WORKFLOW_IDS = [
7833
8021
  "experiment",
7834
8022
  "funnel"
7835
8023
  ];
8024
+ var BUILTIN_WORKFLOW_ID_SET = new Set(BUILTIN_WORKFLOW_IDS);
7836
8025
  var col = (key, name, type, order, extra) => ({ key, name, type, order, ...extra });
7837
8026
  var STANDARD = {
7838
8027
  id: "standard",
@@ -8179,6 +8368,9 @@ var recallFts = sqliteTable("recall_fts", {
8179
8368
  thread: text("thread")
8180
8369
  });
8181
8370
 
8371
+ // ../core/src/retrieval/vector-lease.ts
8372
+ var LEASE_MS = 5 * 60000;
8373
+
8182
8374
  // ../core/src/retrieval/index-consumer.ts
8183
8375
  var INDEX_ON = new Set([
8184
8376
  "contribution.added",
@@ -8193,6 +8385,9 @@ var INDEX_ON = new Set([
8193
8385
  "contribution.restored"
8194
8386
  ]);
8195
8387
  var PURGE_ON = new Set(["contribution.deleted"]);
8388
+ // ../core/src/retrieval/lifecycle-refresh.ts
8389
+ var LEASE_MS2 = 2 * 60000;
8390
+ var MISSING_VECTOR_GRACE_MS = 5 * 60000;
8196
8391
  // ../actions/src/external-read-defaults.ts
8197
8392
  var EXTERNAL_DEFAULT_PAGE_SIZE = 50;
8198
8393
  var TREE_EXTERNAL_DEFAULT_PAGE_SIZE = 4;
@@ -8734,6 +8929,8 @@ var workflowSummary = looseObject({
8734
8929
  name: string2(),
8735
8930
  summary: string2(),
8736
8931
  origin: string2().optional(),
8932
+ selectedBy: string2().optional(),
8933
+ derivedFromBuiltin: nullableString.optional(),
8737
8934
  isDefault: boolean2().optional(),
8738
8935
  labels: array(jsonObject).optional(),
8739
8936
  createdAt: string2().optional(),
@@ -11082,13 +11279,19 @@ var ACTION_DEFINITIONS = [
11082
11279
  {
11083
11280
  name: "recall",
11084
11281
  title: "Recall existing knowledge",
11085
- description: "Search Arbor semantically for existing contributions, artifacts, and decisions. Use `tree` for lifecycle/attention routing; once you know the area, pass space/topic/thread to keep recall inside that working set before targeted reads.",
11282
+ description: "Search Arbor semantically for existing contributions, artifacts, and decisions. Use `tree` for lifecycle/attention routing; pass space/topic/thread to narrow the working set, status: current for work awaiting conclusion, or lifecycle types for another slice; omit status for broad prior art.",
11086
11283
  inputSchema: {
11087
11284
  query: string2().min(1).describe("what you want to recall, in natural language"),
11088
11285
  space: string2().optional().describe("optional space id to scope the search"),
11089
11286
  topic: string2().optional().describe("optional topic id to scope the search"),
11090
11287
  thread: string2().optional().describe("optional thread id to scope the search"),
11091
11288
  topK: number2().int().min(1).optional().describe("how many results to return (default 10)"),
11289
+ status: union([
11290
+ literal("current"),
11291
+ _enum(LIFECYCLE_TYPES),
11292
+ tuple([literal("current")]),
11293
+ array(_enum(LIFECYCLE_TYPES)).min(1).max(8)
11294
+ ]).optional().describe("current = active + needs-review + stuck; or one or more protocol lifecycle types. Omit for broad prior art. Explicit status excludes Topic hits; archived includes archived Thread content without includeHistorical."),
11092
11295
  includeHistorical: boolean2().optional().describe("include superseded/archived knowledge (default false)")
11093
11296
  },
11094
11297
  surfaces: ["mcp", "cli"],
@@ -11389,7 +11592,7 @@ var ACTION_DEFINITIONS = [
11389
11592
  spaceId: string2().describe("the space to create the topic in, spc_…"),
11390
11593
  title: string2().min(1).describe("the topic's name — an area of work, not a question"),
11391
11594
  purpose: string2().optional().describe("what this Topic accomplishes and what belongs here, leading with its primary role — Direction, Delivery, Operations, Intake, Coordination, or Learning; name an external or split source of truth or a handoff boundary only when it materially matters"),
11392
- workflow: string2().optional().describe("catalog id from `space_get.workflows` (pick by summary); must already be attached to this Space")
11595
+ workflow: string2().optional().describe("a workflow id from `space_get.workflows` (pick by summary) — a built-in such as `queue` or a catalog `wfl_…`; must already be attached to this Space")
11393
11596
  },
11394
11597
  surfaces: ["mcp", "cli"],
11395
11598
  toolset: "structure",
@@ -11403,7 +11606,7 @@ var ACTION_DEFINITIONS = [
11403
11606
  topicId: string2().describe("the topic to edit, top_…"),
11404
11607
  title: string2().min(1).optional().describe("a new title — an area of work, not a question"),
11405
11608
  purpose: string2().optional().describe("a new purpose — what this Topic accomplishes and what belongs here, leading with its primary role (Direction, Delivery, Operations, Intake, Coordination, or Learning); name an external or split source of truth or a handoff boundary only when it materially matters"),
11406
- workflow: string2().nullable().optional().describe("catalog id from `space_get.workflows` (pick by summary); must be attached to the Space; blank or null inherits the Space default")
11609
+ workflow: string2().nullable().optional().describe("a workflow id from `space_get.workflows` (pick by summary) — a built-in such as `queue` or a catalog `wfl_…`; must be attached to the Space; blank or null inherits the Space default")
11407
11610
  },
11408
11611
  surfaces: ["mcp", "cli"],
11409
11612
  toolset: "spaces",
@@ -12631,15 +12834,15 @@ var ACTION_DEFINITIONS = [
12631
12834
  {
12632
12835
  name: "space_update",
12633
12836
  title: "Edit a space's config",
12634
- description: "Edit a Space's purpose, title, or visibility; org owner/admin or that Space's admin only, and only supplied fields are patched. Use this for factual room metadata, including open/private, or org-admin `--attach-workflow` / `--detach-workflow` / `--default-workflow`; collaboration norms belong in Space guidance.",
12837
+ description: "Edit a Space's purpose, title, visibility, or offered workflows (`--attach-workflow` / `--detach-workflow` / `--default-workflow` take a built-in id like `queue` or a catalog `wfl_…`); org owner/admin or that Space's admin only, patching only supplied fields. Norms belong in Space guidance.",
12635
12838
  inputSchema: {
12636
12839
  spaceId: string2().describe("the space, spc_…"),
12637
12840
  purpose: string2().optional().describe("why this boundary exists and what it is around — commonly a Product/System, Program/Function, Portfolio/Network, or Practice/Community — plus its dominant work modes (Build, Operate, Coordinate, Discuss, Share) when that helps; plain prose, not metadata syntax"),
12638
12841
  title: string2().optional().describe("a new title for the space"),
12639
12842
  visibility: _enum(["open", "private"]).optional().describe("open or private (invite-only)"),
12640
- attachWorkflow: string2().optional().describe("org-admin: attach this catalog workflow id to the Space allowlist"),
12641
- detachWorkflow: string2().optional().describe("org-admin: detach this catalog workflow; rejected if a Topic still selects it"),
12642
- defaultWorkflow: string2().optional().describe("org-admin: name which attached workflow new Topics inherit")
12843
+ attachWorkflow: string2().optional().describe("add a workflow to this Space's list: a built-in id (`standard`, `queue`, `content`, `experiment`, `funnel`) or a catalog `wfl_…` from `workflow_list`"),
12844
+ detachWorkflow: string2().optional().describe("remove a workflow (built-in id or `wfl_…`) from this Space's list; rejected while a Topic still selects it"),
12845
+ defaultWorkflow: string2().optional().describe("name which attached workflow (built-in id or `wfl_…`) new Topics inherit; with none, Standard")
12643
12846
  },
12644
12847
  surfaces: ["mcp", "cli"],
12645
12848
  toolset: "spaces",
@@ -12648,7 +12851,7 @@ var ACTION_DEFINITIONS = [
12648
12851
  {
12649
12852
  name: "workflow_create",
12650
12853
  title: "Create a catalog workflow",
12651
- description: "Copy a built-in into the org catalog (`--from-builtin`) or author name, summary, and labels. Org-admin; copy-then-edit — the built-in constant is never mutated in place.",
12854
+ description: "Customize a built-in by copying it into the org catalog (`--from-builtin`), or author name, summary, and labels. Org-admin; to use a built-in unchanged, attach it by id with `space_update`.",
12652
12855
  inputSchema: {
12653
12856
  fromBuiltin: _enum(BUILTIN_WORKFLOW_IDS).optional().describe("copy this built-in template into the catalog"),
12654
12857
  name: string2().min(1).optional().describe("catalog name; defaults from the built-in"),
@@ -12676,7 +12879,7 @@ var ACTION_DEFINITIONS = [
12676
12879
  {
12677
12880
  name: "workflow_list",
12678
12881
  title: "List org workflows",
12679
- description: "List built-in templates and this org's catalog copies, each with its required summary. Org-admin; members read the Space allowlist on `space_get`.",
12882
+ description: "List the built-in workflows (attach by id) and this org's catalog (`wfl_…`), each with its summary and `origin`. Pick one to attach with `space_update`; a Space's own list is on `space_get`.",
12680
12883
  inputSchema: {},
12681
12884
  surfaces: ["mcp", "cli"],
12682
12885
  toolset: "structure",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.23.26",
3
+ "version": "0.23.28",
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",