@lambdacurry/arbor 0.3.8 → 0.4.1

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 +76 -10
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -1608,6 +1608,9 @@ var contributions = sqliteTable("contributions", {
1608
1608
  mentions: text("mentions", { mode: "json" }).$type(),
1609
1609
  attachmentIds: text("attachment_ids", { mode: "json" }).$type(),
1610
1610
  editedAt: ts("edited_at"),
1611
+ standoutAt: ts("standout_at"),
1612
+ standoutBy: text("standout_by").references(() => profiles.id),
1613
+ deletedAt: ts("deleted_at"),
1611
1614
  createdAt: ts("created_at").notNull()
1612
1615
  }, (t) => ({ threadIdx: index("contributions_thread_idx").on(t.threadId) }));
1613
1616
  var reviews = sqliteTable("reviews", {
@@ -1618,6 +1621,8 @@ var reviews = sqliteTable("reviews", {
1618
1621
  facetKey: text("facet_key").$type(),
1619
1622
  polarity: text("polarity").$type(),
1620
1623
  note: text("note").notNull(),
1624
+ mentions: text("mentions", { mode: "json" }).$type(),
1625
+ editedAt: ts("edited_at"),
1621
1626
  aiIssued: integer("ai_issued", { mode: "boolean" }).notNull().default(false),
1622
1627
  createdAt: ts("created_at").notNull()
1623
1628
  }, (t) => ({
@@ -1831,6 +1836,9 @@ class InMemoryVectorStore {
1831
1836
  get size() {
1832
1837
  return this.records.size;
1833
1838
  }
1839
+ has(id) {
1840
+ return this.records.has(id);
1841
+ }
1834
1842
  }
1835
1843
  // ../core/src/retrieval/fts.ts
1836
1844
  var recallFts = sqliteTable("recall_fts", {
@@ -1847,7 +1855,8 @@ var INDEX_ON = new Set([
1847
1855
  "contribution.edited",
1848
1856
  "comment.added",
1849
1857
  "comment.edited",
1850
- "artifact.created"
1858
+ "artifact.created",
1859
+ "review.added"
1851
1860
  ]);
1852
1861
  // ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/external.js
1853
1862
  var exports_external = {};
@@ -16189,12 +16198,13 @@ var ACTIONS = [
16189
16198
  {
16190
16199
  name: "stamp",
16191
16200
  title: "Stamp (review) a contribution",
16192
- description: "Vouch for or push back on someone else's contribution — neutral (omit facet+polarity) or signed (a facet + ▲/▽). Use this to register quality judgment with a one-line why; you cannot stamp your own, and re-stamping updates yours in place.",
16201
+ description: "Vouch for or push back on someone else's contribution — neutral (omit facet+polarity) or signed (a facet + ▲/▽). Use this to register quality judgment with a 'why'; you cannot stamp your own, and re-stamping updates yours in place. A STAMP is also how you answer a review-ask (AD-130): if `inbox`/a thread's open ask tells you to stamp a contribution, do it here. The note is a MARKDOWN body (AD-143) — be as substantive as the review needs; you can @-mention people and reference other work with [[con_…]].",
16193
16202
  inputSchema: {
16194
16203
  contributionId: exports_external.string().describe("the contribution id, e.g. con_…"),
16195
16204
  facetKey: exports_external.enum(STAMP_FACETS).optional().describe("quality|impact|fit|originality (omit for a neutral stamp)"),
16196
16205
  polarity: exports_external.enum(["positive", "negative"]).optional().describe("required with a facet"),
16197
- note: exports_external.string().min(1).optional().describe("the one-line 'why' (required for a signed stamp)")
16206
+ note: exports_external.string().min(1).optional().describe("the 'why' — markdown, required for a signed stamp (AD-143)"),
16207
+ mentions: exports_external.array(exports_external.object({ kind: exports_external.enum(["person", "contribution", "artifact"]), id: exports_external.string(), label: exports_external.string() })).optional().describe("inline @-mentions in the note; person mentions notify")
16198
16208
  },
16199
16209
  surfaces: ["mcp", "cli"],
16200
16210
  run: forward("review.add")
@@ -16291,8 +16301,8 @@ var ACTIONS = [
16291
16301
  },
16292
16302
  {
16293
16303
  name: "promote_contribution",
16294
- title: "Promote a contribution to a standout artifact",
16295
- description: "Promote a contribution into a durable, recallable artifact — it becomes a `promoted` artifact owned by that contribution's author and a \uD83C\uDF96️ standout in the thread. Reach for this when a contribution is worth retaining and citing as one of the thread's outputs. MANY contributions in a thread can be promoted (there's no single 'answer'); idempotent — re-promoting the same contribution returns the same artifact.",
16304
+ title: "Promote a contribution to a \uD83C\uDF96️ standout",
16305
+ description: "Mark a contribution a \uD83C\uDF96️ standoutrecognition that boosts it in recall and flags it as one of the thread's outputs (AD-140: promotion is a MARK on the contribution, not a separate artifact). Reach for this when a contribution is worth recognizing. MANY contributions in a thread can be standouts (there's no single 'answer'); idempotent — re-promoting is a quiet no-op.",
16296
16306
  inputSchema: {
16297
16307
  contributionId: exports_external.string().describe("the contribution to promote, con_… (its thread + author are derived)")
16298
16308
  },
@@ -16301,14 +16311,34 @@ var ACTIONS = [
16301
16311
  },
16302
16312
  {
16303
16313
  name: "demote_contribution",
16304
- title: "Demote a promoted contribution",
16305
- description: "The deliberate UNDO of promote_contribution: removes the contribution's standout mark and archives its artifact (a restorable lifecycle move, not a delete). Reach for this when a promotion was premature or superseded. Idempotent — demoting an unpromoted contribution is a quiet no-op.",
16314
+ title: "Demote a standout contribution",
16315
+ description: "The deliberate UNDO of promote_contribution: clear the \uD83C\uDF96️ standout mark (AD-140 no artifact is touched; promotion never minted one). Reach for this when a promotion was premature. Idempotent — demoting a non-standout contribution is a quiet no-op.",
16306
16316
  inputSchema: {
16307
- contributionId: exports_external.string().describe("the promoted contribution to demote, con_…")
16317
+ contributionId: exports_external.string().describe("the standout contribution to demote, con_…")
16308
16318
  },
16309
16319
  surfaces: ["mcp", "cli"],
16310
16320
  run: forward("contribution.demote")
16311
16321
  },
16322
+ {
16323
+ name: "delete_contribution",
16324
+ title: "Remove a contribution",
16325
+ description: "Soft-delete your own contribution — it's removed from the thread and from recall but stays audited and RESTORABLE (AD-141). A referenced contribution (something cites/replies to/stamps it) leaves a quiet tombstone so nothing is orphaned; a leaf one vanishes. Author-only — unless you're the org owner, who may remove any contribution for moderation. Use this to retire something posted in error or no longer worth standing behind.",
16326
+ inputSchema: {
16327
+ contributionId: exports_external.string().describe("the contribution to remove, con_…")
16328
+ },
16329
+ surfaces: ["mcp", "cli"],
16330
+ run: forward("contribution.delete")
16331
+ },
16332
+ {
16333
+ name: "restore_contribution",
16334
+ title: "Restore a removed contribution",
16335
+ description: "Undo a removal — clear the tombstone and bring the contribution back into the thread and recall (AD-141). Author-only, or the org owner. The deliberate inverse of delete_contribution.",
16336
+ inputSchema: {
16337
+ contributionId: exports_external.string().describe("the removed contribution to restore, con_…")
16338
+ },
16339
+ surfaces: ["mcp", "cli"],
16340
+ run: forward("contribution.restore")
16341
+ },
16312
16342
  {
16313
16343
  name: "request",
16314
16344
  title: "Ask for a review",
@@ -16328,7 +16358,7 @@ var ACTIONS = [
16328
16358
  {
16329
16359
  name: "respond",
16330
16360
  title: "Respond to a request",
16331
- description: "Fulfill a request addressed to you by posting the contribution that answers it (AD-048 respond-not-claim). Reach for this after `inbox` surfaces an obligation; it returns the request's recomputed status (open | completed | expired).",
16361
+ description: "Fulfill a request addressed to you by posting the contribution that answers it (AD-048 respond-not-claim). Reach for this after `inbox` surfaces an obligation — each open ask carries an `answerWith` line telling you the exact call. NOTE: a review-ask is answered by `stamp` (AD-130), not `respond`. If you ALREADY posted an answer as a plain contribution, use `mark_as_response` to bind it. Returns the request's recomputed status (open | completed | expired).",
16332
16362
  inputSchema: {
16333
16363
  requestId: exports_external.string().describe("the request id, req_…"),
16334
16364
  type: exports_external.enum(CONTRIBUTION_TYPES).describe("the contribution type"),
@@ -16338,6 +16368,27 @@ var ACTIONS = [
16338
16368
  surfaces: ["mcp", "cli"],
16339
16369
  run: forward("request.respond")
16340
16370
  },
16371
+ {
16372
+ name: "mark_as_response",
16373
+ title: "Mark a contribution as a request's response",
16374
+ description: "Bind an ALREADY-POSTED contribution as the answer to a request (AD-142) — when an answer was posted as a plain contribution instead of through `respond`. Allowed if you're the contribution's AUTHOR ('this is my answer') or the REQUESTER ('this answered me'). The contribution must be in the request's thread; the request must be open. Re-evaluates completion.",
16375
+ inputSchema: {
16376
+ requestId: exports_external.string().describe("the open request, req_…"),
16377
+ contributionId: exports_external.string().describe("the existing contribution that answers it, con_…")
16378
+ },
16379
+ surfaces: ["mcp", "cli"],
16380
+ run: forward("request.bind")
16381
+ },
16382
+ {
16383
+ name: "cancel_request",
16384
+ title: "Cancel a request",
16385
+ description: "Cancel an OPEN request you raised (or any open request, if you're the org owner) — it moves to a terminal `cancelled` state and the inbox items it fanned out are SILENTLY withdrawn (they leave recipients' inboxes, no notification). Use this when an ask is no longer needed. Only open requests can be cancelled (a completed/expired one can't).",
16386
+ inputSchema: {
16387
+ requestId: exports_external.string().describe("the open request to cancel, req_…")
16388
+ },
16389
+ surfaces: ["mcp", "cli"],
16390
+ run: forward("request.cancel")
16391
+ },
16341
16392
  {
16342
16393
  name: "inbox",
16343
16394
  title: "List your inbox",
@@ -17004,7 +17055,22 @@ function renderVersion(ctx) {
17004
17055
  emitDual({ name: PKG.name, version: CLI_VERSION }, `arbor ${CLI_VERSION}
17005
17056
  `, "version", ctx);
17006
17057
  }
17007
- var HELP = `arbor — the Arbor CLI (AD-009 human write path)
17058
+ var HELP = `arbor — the Arbor CLI: people and agents deliberate on typed work, and Arbor remembers
17059
+ what's settled. Your token (env ARBOR_TOKEN, or \`arbor auth\`) resolves who you act AS — the CLI
17060
+ never asserts it. Run \`arbor whoami\` to confirm, \`arbor tree\` to map the workspace.
17061
+
17062
+ Etiquette — WHEN to act (the judgment; per-command mechanics are listed below):
17063
+ · Recall first — \`arbor recall "<question>"\` before you contribute; cite prior work, don't repeat it.
17064
+ · One typed point per contribution (proposal / critique / question / evidence / risk / correction /
17065
+ assertion / decision). Markdown bodies — pass long/multiline bodies with \`--body-file -\` (stdin),
17066
+ don't shell-quote them.
17067
+ · References live in your prose — a URL or \`[label](#con_…)\` in the body becomes a typed reference;
17068
+ there is no separate links field.
17069
+ · Answer asks THROUGH them — \`arbor respond\` (or \`arbor stamp\` a review ask) so the ask completes
17070
+ and the requester is notified; a plain reply that happens to answer leaves the ask hanging.
17071
+ · Review honestly (\`arbor stamp\` = vouch / push back with a why), promote sparingly (curation, not
17072
+ applause), and \`arbor edit\` rather than repost.
17073
+ Full norms: GET /agent.md on your Arbor server, or the saffron arbor-collaboration shared skill.
17008
17074
 
17009
17075
  Usage: arbor <command> [--flags]
17010
17076
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.3.8",
3
+ "version": "0.4.1",
4
4
  "description": "The Arbor CLI \u2014 a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
5
5
  "type": "module",
6
6
  "bin": {