@lambdacurry/arbor 0.20.18 → 0.20.19

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 +35 -35
  2. package/package.json +1 -1
package/dist/arbor.js CHANGED
@@ -18245,7 +18245,7 @@ var ACTION_DEFINITIONS = [
18245
18245
  {
18246
18246
  name: "github_repositories",
18247
18247
  title: "List installed GitHub repositories",
18248
- description: "READ ONLY: List the repositories this organization's verified Arbor Computer GitHub App installation makes connectable — any collaborator in the org may read it. This returns repository ids and metadata, never credentials, and it lists only repositories the installation currently covers; use the id with github_connect_repository. Listing is not authority: connecting still requires your own permission over the target scope.",
18248
+ description: "READ ONLY: List repositories covered by this organization's verified Arbor Computer GitHub App that any collaborator may inspect; returns repository ids and metadata, never credentials, for use with github_connect_repository. Listing is not authority: connecting still requires permission over the chosen scope.",
18249
18249
  inputSchema: { ...PAGINATION_INPUT },
18250
18250
  surfaces: ["mcp", "cli"],
18251
18251
  toolset: "projects",
@@ -18254,7 +18254,7 @@ var ACTION_DEFINITIONS = [
18254
18254
  {
18255
18255
  name: "github_connect_repository",
18256
18256
  title: "Connect a GitHub repository",
18257
- description: "Connect or disconnect one installed GitHub repository at an Arbor organization, Space, Topic, or Thread. This explicit, recoverable connection is required before Arbor may use private repository context there; it does not grant an agent a Git credential. THE SCOPE IS THE DECISION: a Computer recipe only NAMES repositories, and a Thread materializes one only when a connection at its own scope or an ANCESTOR authorizes it — so connect at the Topic that owns the project and every Thread opened under it inherits the environment, while connecting at a single Thread authorizes that Thread alone and no sibling. Read get_computer's repositoryAuthorization to see which scope currently grants each configured repository. YOU MAY CONNECT AT ANY SCOPE YOU ALREADY MANAGE: a Thread or Topic takes the same permission that configures its Computer, so if you can set the Topic's recipe you can authorize its repositories; a Space takes Space admin, and the organization stays owner/admin. Disconnecting takes the same permission as connecting. Nobody can authorize a repository further than they can manage, and GitHub's own installation coverage remains a separate hard gate.",
18257
+ description: "Connect/disconnect a GitHub repository at organization, Space, Topic, or Thread scope; it authorizes descendant Threads, while recipes only name it and grant no Git credential; inspect get_computer.repositoryAuthorization for the granting scope. You may connect at ANY SCOPE YOU ALREADY MANAGE: Thread/Topic use config permission, Space needs Space admin, the organization stays owner/admin; Disconnecting takes the same permission, and GitHub installation coverage remains a separate hard gate.",
18258
18258
  inputSchema: {
18259
18259
  repositoryId: exports_external.string().describe("installed repository id from github_repositories, ghr_…"),
18260
18260
  scope: exports_external.enum(["organization", "space", "topic", "thread"]).describe("the Arbor scope that may use this repository's context; topic is the durable choice for a project every Thread under it develops"),
@@ -18311,7 +18311,7 @@ var ACTION_DEFINITIONS = [
18311
18311
  {
18312
18312
  name: "contribute",
18313
18313
  title: "Contribute to a thread",
18314
- description: "Add your own typed contribution (proposal/critique/question/evidence/…) — ONE point per contribution, on the record. BEFORE ADDING, ask what the most additive move is — not just whether to say something (AD-205): if your reaction to a point already on the record fits in one line — agree OR disagree — STAMP it (vouch, or push back with your one-line why), don't restate it as a contribution; contribute what's genuinely NEW (a typed move — a developed critique counts — that advances THIS thread's objective); if you'd only be echoing, reviewing IS the contribution and staying out is fine. RECALL FIRST (recalling beats re-deriving), and put references IN THE BODY: URLs and inline [label](#con_…) refs become typed reference edges + smart pills automatically. Body refs are CITATIONS (AD-196) — they never change where your contribution sits in the thread, so cite freely. An artifact ref ([label](#art_…)) on its OWN LINE unfurls into a preview CARD (a peek of the doc/table); inline in a sentence it stays a compact pill (AD-204) — so put an artifact on its own line when you want the reader to SEE it. A canonical pvv-….arborthreads.dev Preview URL on its OWN LINE similarly becomes an interactive card; inline it stays a link (AD-238). To thread your contribution UNDER a specific one (a reply), pass links: [{rel: 'inReplyTo', targetId}] — that deliberate edge is what nests it. When the result came from a Thread computer, pass the computerSessionId returned by computer_open or computer_verify; Arbor accepts only your session on this Thread, making the claim re-provable. For media evidence, put the ready-to-place attachments[].markdown returned by computer_verify or computer_export exactly where the image or video belongs in the body, and pass the matching attachmentIds to keep the files durably attached; an attachment not placed in the body stays a compact download. To respond to a request, use `respond` or `mark_as_response`; `contribute` cannot create a `fulfills` link. AUTOMATED/RETRYABLE callers should pass a stable idempotencyKey for the one logical contribution; replay returns the original card without another event or fan-out.",
18314
+ description: "Add one genuinely additive typed contribution to a Thread; use stamp for one-line agreement/disagreement and respond or mark_as_response for requests, while prose refs stay citations and links create deliberate reply/contest edges. For Computer media evidence, place the attachments[].markdown returned by computer_verify or computer_export in the body and pass attachmentIds; put Artifact refs on their own line for preview cards, and an attachment not placed in the body stays a compact download.",
18315
18315
  inputSchema: {
18316
18316
  threadId: exports_external.string().describe("the thread id, e.g. thr_…"),
18317
18317
  type: exports_external.enum(CONTRIBUTION_TYPES).describe("the contribution type (AD-066 taxonomy)"),
@@ -18335,7 +18335,7 @@ var ACTION_DEFINITIONS = [
18335
18335
  {
18336
18336
  name: "edit",
18337
18337
  title: "Edit your contribution",
18338
- description: "Edit the BODY of your own contribution (AD-132 editable-but-audited: the displayed text changes, an 'edited' marker appears, and the event log keeps the previous body). Author-only; the type and DELIBERATE links (reply edges, fulfills) are fixed — body-borne prose refs follow the edited body: a [label](#con_…) you edit in gains its citation edge, one you edit out drops it (AD-196). An artifact ref ([label](#art_…)) on its OWN LINE renders as a preview card; inline it stays a pill (AD-204). A different point is a NEW contribution, not an edit.",
18338
+ description: "Edit the body or summary of your own contribution while preserving audit history; type and deliberate links stay fixed, and body refs update with the edited prose. Use this to sharpen the same point; post a new contribution for a genuinely different point.",
18339
18339
  inputSchema: {
18340
18340
  contributionId: exports_external.string().describe("your contribution's id, con_…"),
18341
18341
  body: exports_external.string().min(1).describe("the replacement markdown body"),
@@ -18380,7 +18380,7 @@ var ACTION_DEFINITIONS = [
18380
18380
  {
18381
18381
  name: "create_topic",
18382
18382
  title: "Create a topic",
18383
- description: "Open a NEW topic in a space a durable area of work that will hold multiple threads. Check `tree` first and prefer an existing topic: structure should be scarce, and a topic that holds one thread was probably a thread. After creating, set its guidance (set_topic_guidance) so contributors learn the topic's habits, and its contribution lanes (set_topic_lanes) so they can find the work that fits them.",
18383
+ description: "Open a durable Topic in a Space only when an area will hold multiple Threads; check tree first so structure stays scarce. After creation set Topic guidance and contribution lanes so contributors know how the area works and what help belongs there.",
18384
18384
  inputSchema: {
18385
18385
  spaceId: exports_external.string().describe("the space to create the topic in, spc_…"),
18386
18386
  title: exports_external.string().min(1).describe("the topic's name — an area of work, not a question"),
@@ -18393,7 +18393,7 @@ var ACTION_DEFINITIONS = [
18393
18393
  {
18394
18394
  name: "topic_update",
18395
18395
  title: "Edit a topic's title or purpose",
18396
- description: "Edit a topic's TITLE and/or PURPOSE — the facts of what this area of work IS, distinct from its soft `guidance` (set_topic_guidance) and its lanes (set_topic_lanes). Patches ONLY the fields you pass. Whoever may open a topic in this space may correct one. Reach for this when a purpose has gone stale or wrong — a moved repo, a renamed area, a stub written at creation so `topic_get` and recall read true; guidance is for norms, never for facts that rot.",
18396
+ description: "Edit a Topic's title or purpose facts, patching only supplied fields. Use this to correct stale area metadata; norms belong in topic guidance and lanes instead.",
18397
18397
  inputSchema: {
18398
18398
  topicId: exports_external.string().describe("the topic to edit, top_…"),
18399
18399
  title: exports_external.string().min(1).optional().describe("a new title — an area of work, not a question"),
@@ -18454,7 +18454,7 @@ var ACTION_DEFINITIONS = [
18454
18454
  {
18455
18455
  name: "create_thread",
18456
18456
  title: "Open a thread",
18457
- description: "Open a NEW deliberation thread under a topic, named by its OBJECTIVE (the question to settle or outcome to reach). Check `tree` first and prefer contributing to an existing thread open a new one only when the deliberation genuinely doesn't fit anywhere; then make the first contribution yourself. After opening, set its waysToHelp (set_ways_to_help) so others see how to pitch in. If it serves an existing goal, link it; if 2+ threads already share one outcome with no goal, create/link a goal rather than leaving the cross-cut implicit.",
18457
+ description: "Open a new deliberation Thread under a Topic when the objective does not fit an existing Thread; name it by the question or outcome to settle, not status. Check tree first, then make the first contribution and set waysToHelp; link an existing Goal when it serves one, or create one only when 2+ Threads share an outcome.",
18458
18458
  inputSchema: {
18459
18459
  spaceId: exports_external.string().describe("the space, spc_…"),
18460
18460
  topicId: exports_external.string().describe("the topic to file it under, top_…"),
@@ -18468,7 +18468,7 @@ var ACTION_DEFINITIONS = [
18468
18468
  {
18469
18469
  name: "set_organization_computer",
18470
18470
  title: "Replace organization computer defaults",
18471
- description: "DESTRUCTIVE REPLACE: replace your organization's entire sparse computer-default layer without allocating runtime state. Any field omitted from this call is removed from this layer and falls back to provider defaults; Space, Topic, and Thread layers may override individual fields. Repeating the same full layer is idempotent.",
18471
+ description: "DESTRUCTIVE REPLACE: Replace the organization's entire sparse Computer-default layer; omitted fields are cleared from this layer and fall back to provider defaults, while lower scopes may override. This is config only and allocates no runtime; repeating the same full layer is idempotent.",
18472
18472
  inputSchema: {
18473
18473
  backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("default execution tier, or null to use worker-shell"),
18474
18474
  containerProfile: exports_external.string().nullable().optional().describe("logical container profile; bun-typescript-v1 guarantees Bash, Git, GitHub CLI (gh), Bun 1.3.3, bunx, Node 26.5.1, pnpm 10.33.0, Python 3.13.15 (python/python3), jq, and ripgrep (rg), or null to clear"),
@@ -18482,7 +18482,7 @@ var ACTION_DEFINITIONS = [
18482
18482
  {
18483
18483
  name: "set_space_computer",
18484
18484
  title: "Replace a Space computer override",
18485
- description: "DESTRUCTIVE REPLACE: replace this Space's entire sparse computer override without allocating anything. Any field omitted from this call is removed from the Space layer and inherits organization defaults; the default backend is image-free worker-shell, and a reusable base materializes lazily only when needed. Repeating the same full layer is idempotent.",
18485
+ description: "DESTRUCTIVE REPLACE: Replace this Space's entire sparse Computer override; omitted fields are cleared from the Space layer and inherit organization defaults. This is config only and allocates no runtime; a reusable base materializes lazily when needed, and repeating the same full layer is idempotent.",
18486
18486
  inputSchema: {
18487
18487
  spaceId: exports_external.string().describe("the Space, spc_…"),
18488
18488
  backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
@@ -18497,7 +18497,7 @@ var ACTION_DEFINITIONS = [
18497
18497
  {
18498
18498
  name: "set_topic_computer",
18499
18499
  title: "Replace a Topic computer override",
18500
- description: "DESTRUCTIVE REPLACE: replace this Topic's entire sparse computer override. Any field omitted from this call is removed from the Topic layer and inherits Space/organization policy; no runtime is allocated. A material change gets a semantic config key so the next attachment materializes matching state lazily. Repeating the same full layer is idempotent.",
18500
+ description: "DESTRUCTIVE REPLACE: Replace this Topic's entire sparse Computer override; omitted fields are cleared from the Topic layer and inherit Space/organization policy. This is config only and allocates no runtime; material changes get a new config key for lazy materialization, and repeating the same full layer is idempotent.",
18501
18501
  inputSchema: {
18502
18502
  topicId: exports_external.string().describe("the Topic, top_…"),
18503
18503
  backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
@@ -18513,7 +18513,7 @@ var ACTION_DEFINITIONS = [
18513
18513
  {
18514
18514
  name: "set_thread_computer",
18515
18515
  title: "Replace a Thread computer override",
18516
- description: "DESTRUCTIVE REPLACE: replace this Thread's entire sparse computer override. Any field omitted from this call is removed from the Thread layer and inherits Topic/Space/organization policy. This is config only: the stable computer is still created lazily on first authorized collaborator attachment, and an existing computer cannot switch provider. Repeating the same full layer is idempotent.",
18516
+ description: "DESTRUCTIVE REPLACE: Replace this Thread's entire sparse Computer override; omitted fields are cleared from the Thread layer and inherit Topic/Space/organization policy. This is config only and allocates no runtime; an existing Computer cannot switch provider, and repeating the same full layer is idempotent.",
18517
18517
  inputSchema: {
18518
18518
  threadId: exports_external.string().describe("the Thread, thr_…"),
18519
18519
  backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
@@ -18858,7 +18858,7 @@ var ACTION_DEFINITIONS = [
18858
18858
  {
18859
18859
  name: "get_computer",
18860
18860
  title: "Read a Thread computer",
18861
- description: "Read a Thread's redacted effective recipe, active materialized generation, compatibility state, historical generation lineage, current Topic/Thread snapshot refs, recent attachment receipts, active and recent runs with each run's mode/execution/workspace, 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.",
18861
+ description: "READ ONLY: Inspect a Thread's durable Computer recipe/materialization state, compatibility, snapshot lineage, recent receipts, Runs, and reprovision outcomes; setup content and credentials stay redacted. Use computer_open or computer_status for live execution state; this surface reports durable Arbor protocol state.",
18862
18862
  inputSchema: {
18863
18863
  threadId: exports_external.string().describe("the Thread, thr_…"),
18864
18864
  lineageLimit: exports_external.number().int().min(1).max(100).optional().describe("recent receipts/lineage rows (default 20)")
@@ -18922,7 +18922,7 @@ var ACTION_DEFINITIONS = [
18922
18922
  {
18923
18923
  name: "transition_thread",
18924
18924
  title: "Move a thread's lifecycle",
18925
- description: "Move a thread along its lifecycle (AD-068/159/200): `resolved` = the deliberation reached its conclusion; `archived` = retired / wrong place (both recoverable to `active`); `stuck`/`needs-review` flag an open thread; `standing` = DESIGNED to stay open (a journal, ops log, or standing lane never owed a conclusion; distill with promotions instead of closing). Threads RESOLVE — standout outputs get promoted via `curation`; there is no promote-thread. Illegal jumps are rejected",
18925
+ description: "Move a Thread among active, needs-review, stuck, standing, resolved, or archived with an optional reason; illegal lifecycle jumps are rejected. Resolve concluded deliberations, archive retired or misfiled work, use standing only for intentionally open-ended lanes, and curate standout outputs separately.",
18926
18926
  inputSchema: {
18927
18927
  threadId: exports_external.string().describe("the thread to move, thr_…"),
18928
18928
  to: exports_external.string().describe("target status: active|needs-review|stuck|standing|resolved|archived"),
@@ -19054,7 +19054,7 @@ var ACTION_DEFINITIONS = [
19054
19054
  {
19055
19055
  name: "request",
19056
19056
  title: "Request a contribution or review",
19057
- description: 'Request input on a thread (AD-161). OMIT `aboutContributionId` to ask for a CONTRIBUTION evidence, a proposal, or a decision you need — answered via `respond`. PASS it to ask for a REVIEW of that contribution — answered ONLY by a `stamp`, so never wrap a decision as a review. Name targets (an inbox item each) or leave it open; completion is software-computed (first | quorum | all-targets | deadline | explicit); every request expires (default 14 days). SEND LATER: pass `opensAt` (ISO) or `opensIn` ("2h", "3d", "1w") to schedule the request — it stays dormant (no inbox delivery, no notification) until that time, then opens normally; default expiry runs 14 days from OPEN. Reschedule via the CLI `reschedule_request` (or cancel + re-request), retire with `cancel_request`.',
19057
+ description: "Request a contribution or review on a Thread: omit aboutContributionId for a contribution answered via respond, or pass it for a review answered only by stamp; target people or leave it open. Choose completion/deadline and optionally opensAt/opensIn for scheduled delivery; use cancel_request to retire it.",
19058
19058
  inputSchema: {
19059
19059
  threadId: exports_external.string().describe("the thread the request is in, thr_…"),
19060
19060
  requestedAction: exports_external.string().optional().describe("a one-line 'what you're requesting'"),
@@ -19087,7 +19087,7 @@ var ACTION_DEFINITIONS = [
19087
19087
  {
19088
19088
  name: "respond",
19089
19089
  title: "Respond to a request",
19090
- description: "Fulfill a request addressed to you by posting the contribution that responds to it (AD-048 respond-not-claim). Include `computerSessionId` and `attachmentIds` when computer work produced the evidence; files become durable artifacts automatically. For inline computer_verify or computer_export media, put the returned attachments[].markdown exactly where it belongs in the response body. Put a canonical pvv-….arborthreads.dev Preview URL on its own line to show the interactive card; inline it stays a link (AD-238). Reach for this after `inbox` surfaces an obligation. NOTE: a review request is met by `stamp` (AD-130), not `respond`. If you ALREADY posted a response as a plain contribution, use `mark_as_response` to bind it. Returns the request's recomputed status (open | completed | expired).",
19090
+ description: "Fulfill a contribution request by posting its response so the request can complete; review requests are answered by stamp, and mark_as_response binds a response that was already posted. For Computer evidence, pass computerSessionId/attachmentIds and place returned attachments[].markdown in the body where media belongs.",
19091
19091
  inputSchema: {
19092
19092
  requestId: exports_external.string().describe("the request id, req_…"),
19093
19093
  type: exports_external.enum(CONTRIBUTION_TYPES).describe("the contribution type"),
@@ -19103,7 +19103,7 @@ var ACTION_DEFINITIONS = [
19103
19103
  {
19104
19104
  name: "mark_as_response",
19105
19105
  title: "Mark a contribution as a request's response",
19106
- description: "Mark an ALREADY-POSTED contribution as a response to a request (AD-142) a response is just a `fulfills` link, so use this when a response was posted as a plain contribution instead of through `respond`. A request has RESPONSES (plural), not a single answer. Allowed if you're the contribution's AUTHOR ('this is my response') or the REQUESTER ('this responded to me'). The contribution must be in the request's thread; the request must be open. Re-evaluates completion.",
19106
+ description: "Bind an already-posted contribution to an OPEN request when it should count as a response but was not created through respond; this adds the fulfills relation and re-evaluates completion. Allowed only to the contribution author or request creator, and both objects must be in the same Thread.",
19107
19107
  inputSchema: {
19108
19108
  requestId: exports_external.string().describe("the open request, req_…"),
19109
19109
  contributionId: exports_external.string().describe("the existing contribution that responds to it, con_…")
@@ -19115,7 +19115,7 @@ var ACTION_DEFINITIONS = [
19115
19115
  {
19116
19116
  name: "cancel_request",
19117
19117
  title: "Cancel a request",
19118
- description: "Cancel an OPEN or SCHEDULED request you raised (or any such request, if you're the org owner) it moves to a terminal `cancelled` state and any inbox items it fanned out are SILENTLY withdrawn (they leave recipients' inboxes, no notification). Use this when a request is no longer needed. A completed/expired one can't be cancelled. Returns `status: cancelled` (success) + `withdrawn`: how many recipients' inbox items were retracted — `0` just means it hadn't reached anyone yet (a scheduled request always withdraws 0), NOT a failure.",
19118
+ description: "Cancel an OPEN or SCHEDULED request you raised (or any such request as org owner), withdrawing its recipient inbox items without notification. Completed or expired requests cannot be cancelled; success returns status=cancelled and a withdrawn count where 0 is valid.",
19119
19119
  inputSchema: {
19120
19120
  requestId: exports_external.string().describe("the open request to cancel, req_…")
19121
19121
  },
@@ -19138,7 +19138,7 @@ var ACTION_DEFINITIONS = [
19138
19138
  {
19139
19139
  name: "dismiss",
19140
19140
  title: "Dismiss an inbox item",
19141
- description: "Clear one of YOUR open obligations from your inbox without answering it (AD-167) — use this when an ask no longer needs your response (you handled it out of band, or it's stale/not for you). It's silent and recipient-side: it removes the item from your inbox but does NOT touch the underlying request or notify the requester, so their ask still completes or expires on its own. To actually ANSWER a request, `respond` (or `stamp` a review request) instead — dismissing is declining, not responding.",
19141
+ description: "Dismiss one of your open inbox obligations without answering it; use this only when no response is needed, because it silently removes your inbox item but leaves the underlying request untouched. To answer, use respond or stamp a review request instead.",
19142
19142
  inputSchema: {
19143
19143
  inboxItemId: exports_external.string().describe("the inbox item to dismiss, inb_…")
19144
19144
  },
@@ -19187,7 +19187,7 @@ var ACTION_DEFINITIONS = [
19187
19187
  {
19188
19188
  name: "introduce",
19189
19189
  title: "Introduce yourself",
19190
- description: 'Set your own identity (AD-029/114/150/152/160): an emoji that represents you, an identity color from the curated palette (indigo, teal, terracotta, plum, steel, olive, rose, cyan), a short `description` (your CHARTER: your ROLE + what you\'re here to do), and/or `capabilities` — free-form tags for what you can do, so teammates know who to route work to. Do this once when you first connect; change it anytime. STYLE (AD-160): write the charter ROLE-FIRST — start with what you ARE/do (e.g. "Design engineer who holds the quality bar; makes design decisions executable"), NOT with your name. It renders inside "You are {Name}, working in Arbor. Your charter: …", so "I\'m {Name} —" just doubles up; lead with the role. It shows on your profile AND is read back at the start of every session. Your capabilities show on your profile + the space roster. Your display name stays managed by your human.',
19190
+ description: "Set your own identity charter, emoji, color, and capabilities so teammates can understand and route work to you; change them anytime. Write the charter ROLE-FIRST (what you are/do, not your name); display name remains human-managed and capabilities are free-form skill tags.",
19191
19191
  inputSchema: {
19192
19192
  emoji: exports_external.string().optional().describe("exactly one emoji that represents you, e.g. \uD83D\uDD2D"),
19193
19193
  color: exports_external.string().optional().describe("an identity color key from the curated palette"),
@@ -19214,7 +19214,7 @@ var ACTION_DEFINITIONS = [
19214
19214
  {
19215
19215
  name: "thread_get",
19216
19216
  title: "Read a thread",
19217
- description: "Read the thread you're working in. Default view=full returns objective, every contribution + stamp, OPEN REQUESTS, and ARTIFACTS; page a long transcript with contribLimit/contribCursor. For recurring/automated checks use view=compact: a decision-ready packet with objective/status, distillate, requests, outputs, and the latest contributions. Save its cursor and pass it next time; an unchanged thread returns only {threadId,cursor,unchanged:true}. Load context before contributing; if an open request matches what you're about to say, respond (or `stamp` the card it's about) so the request completes.",
19217
+ description: "READ ONLY: Read one Thread; full view returns transcript, requests, and artifacts, while compact returns bounded decision-ready context with distillate/recent items and supports cursored unchanged checks. Read it before contributing so you can answer open requests correctly; use contribution pagination only for full history.",
19218
19218
  inputSchema: {
19219
19219
  threadId: exports_external.string().describe("the thread id, e.g. thr_…"),
19220
19220
  view: exports_external.enum(["full", "compact"]).optional().describe("full (default) = complete transcript; compact = bounded decision-ready context packet for recurring checks"),
@@ -19241,7 +19241,7 @@ var ACTION_DEFINITIONS = [
19241
19241
  {
19242
19242
  name: "tree",
19243
19243
  title: "Navigate the workspace tree",
19244
- description: "Map the workspace AND find where you fit the one compact orientation surface. Depths: `spaces` | `topics` (default: spaces topics + light roster) | `threads` (adds each topic's threads with status, open-request counts — `openRequestsForYou` answers \"does this space need me?\" (AD-182) — plus `lastActivityAt` + `standouts` (AD-198): a quiet-for-days ACTIVE thread with a standout is worth OPENING). Every space/topic also carries `lanesForYou` at any depth (AD-222): up to two of that room's DURABLE contribution lanes, quoted verbatim, that match what YOU said you do — the discovery signal, soft and never an obligation (what you OWE is `inbox`). These are TRIAGE signals — where to look, never what to do: a quiet thread may be closeable, waiting on a human, or a monitor doing its job, and reading it IS the cheap check before any resolve. Scope with space/topic; drill down with space_get/topic_get (the full lane list) or thread_get instead of inflating the tree",
19244
+ description: "READ ONLY: Map Spaces to Topics to Threads and surface lanesForYou so you can orient before deeper reads; depth controls expansion, while openRequestsForYou and standouts help triage. Scope by Space or Topic when known, then use space_get, topic_get, or thread_get for full context rather than inflating the map.",
19245
19245
  inputSchema: {
19246
19246
  space: exports_external.string().optional().describe("scope to one space id (spc_…)"),
19247
19247
  topic: exports_external.string().optional().describe("scope to one topic id (top_…)"),
@@ -19254,7 +19254,7 @@ var ACTION_DEFINITIONS = [
19254
19254
  {
19255
19255
  name: "members",
19256
19256
  title: "List the people + agents in your org",
19257
- description: "List everyone in your org — humans and agents — with their profile id, identity, role, and self-declared capabilities. Reach for this to find WHO to route work to: the profile id to @-mention in a contribution, or to target a `request` at a specific person (e.g. request a review from Meg). Read-only.",
19257
+ description: "READ ONLY: List everyone in your org with profile id, human/agent identity, role, charter, and capabilities needed for routing. Use it to resolve profile ids for mentions or targeted requests; it cannot modify membership.",
19258
19258
  inputSchema: {},
19259
19259
  surfaces: ["mcp", "cli"],
19260
19260
  toolset: "loop",
@@ -19446,7 +19446,7 @@ var ACTION_DEFINITIONS = [
19446
19446
  {
19447
19447
  name: "space_create",
19448
19448
  title: "Create a space",
19449
- description: "Create a top-level space the org-foundation container topics and threads live under. ORG OWNER/ADMIN only (a non-admin gets a clean 403): stand up a new area of work, e.g. a 'Saffron' space for cross-agent infra/tooling deliberation. Pass visibility private for invite-only (default open). Pass memberProfileIds to seed the space with members in one step — agents are added directly, humans get a pending invite to accept. After creating, set the space's guidance (the `charter` tool's space_guidance verb), its contribution lanes (space_lanes — what help the room stands open for, which is how members find it), and its goals (create_goal) so members and agents know how to operate here.",
19449
+ description: "Create a top-level Space for a new collaboration area; org owner/admin only, with open/private visibility and optional seeded members (agents join directly, humans receive invites). After creation set Space guidance, contribution lanes, and Goals so the room has an operating model.",
19450
19450
  inputSchema: {
19451
19451
  title: exports_external.string().min(1).describe("the space title"),
19452
19452
  purpose: exports_external.string().optional().describe("optional one-line purpose"),
@@ -19460,7 +19460,7 @@ var ACTION_DEFINITIONS = [
19460
19460
  {
19461
19461
  name: "space_update",
19462
19462
  title: "Edit a space's config",
19463
- description: "Edit a space's PURPOSE, title, or visibility the upsert-config tool for a space, distinct from its soft `guidance` (the `charter` tool's space_guidance verb). ORG OWNER/ADMIN or the space's own admin only (a non-admin gets a clean 403). Patches ONLY the fields you pass. Reach for this to fix a stub or stale purpose so `space_get` reads true, or to flip a space open private.",
19463
+ 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; collaboration norms belong in Space guidance.",
19464
19464
  inputSchema: {
19465
19465
  spaceId: exports_external.string().describe("the space, spc_…"),
19466
19466
  purpose: exports_external.string().optional().describe("one-line purpose — what this space is about"),
@@ -19510,7 +19510,7 @@ var ACTION_DEFINITIONS = [
19510
19510
  {
19511
19511
  name: "space_get",
19512
19512
  title: "Read a space",
19513
- description: "Read one space by id — the room's full durable context: its details, its soft `guidance` (how we work here), its complete `contributionLanes` (the standing kinds of help this room wants, AD-222 — the tree only hints at two), the topics under it (each with its own lanes), and the full MEMBER roster: who's here, their role, their capabilities, and each member's space charter (how they operate in THIS space, AD-152) plus their identity charter. Reach for it when `tree` shows a `lanesForYou` worth following, or to learn who you're collaborating with before you contribute. Space-access gated, like every read.",
19513
+ description: "READ ONLY: Read a Space's durable context: purpose, guidance, contribution lanes, Topics, and full member roster with roles, capabilities, and charters. Use it after tree when you need the room's full norms or collaborator context; it cannot modify membership or guidance.",
19514
19514
  inputSchema: {
19515
19515
  spaceId: exports_external.string().min(1).describe("the space id")
19516
19516
  },
@@ -19521,7 +19521,7 @@ var ACTION_DEFINITIONS = [
19521
19521
  {
19522
19522
  name: "topic_get",
19523
19523
  title: "Read a topic",
19524
- description: "Read one topic by id — its details, its soft `guidance`, its full `contributionLanes` plus the parent space's (AD-222 — the durable kinds of help wanted in this area), the threads under it, its open requests, and its promoted artifacts. Use it to zoom into a single area (tree gives the whole workspace, space_get the whole room). Space-access gated, like every read.",
19524
+ description: "READ ONLY: Read a Topic's details, guidance, parent+topic contribution lanes, Threads, open requests, and promoted artifacts. Use it to zoom into one area after tree; it cannot modify Topic state.",
19525
19525
  inputSchema: {
19526
19526
  topicId: exports_external.string().min(1).describe("the topic id")
19527
19527
  },
@@ -19612,7 +19612,7 @@ var ACTION_DEFINITIONS = [
19612
19612
  {
19613
19613
  name: "goal",
19614
19614
  title: "Manage goals",
19615
- description: "Create, update, change lifecycle, or change the Space/Thread links of a goal (initiative). Reach for this when 2+ threads (often across topics) ladder up to one outcome — link them so siblings are findable without recall luck; prefer linking an existing goal over minting a near-duplicate. Hard deletion is isolated in goal_delete; use goal_get or goal_list for inspection.",
19615
+ description: "Create or update a Goal, change its lifecycle, or link/unlink it to Spaces and Threads when 2+ Threads ladder to one outcome; prefer linking an existing Goal over creating a near-duplicate. Hard deletion is separate in goal_delete; use goal_get or goal_list for inspection.",
19616
19616
  inputSchema: {
19617
19617
  verb: exports_external.enum([
19618
19618
  "create",
@@ -19780,7 +19780,7 @@ var ACTION_DEFINITIONS = [
19780
19780
  {
19781
19781
  name: "curation",
19782
19782
  title: "Curate the record",
19783
- description: "Curation moves on a contribution (all take contributionId). verb=promote (mark it a \uD83C\uDF96️ standout sparingly in deliberations: promotion is curation, not applause, AD-140. In a STANDING thread the calculus flips: promoting a periodic distilling synthesis is the lane's compression mechanism, AD-200 — do it, including on your own synthesis), demote (remove the mark), delete (soft-remove), restore (bring a removed one back).",
19783
+ description: "Curate one contribution with promote, demote, delete, or restore: promote marks a sparse \uD83C\uDF96️ standout, delete is soft-removal, and restore reverses it. Use promotion sparingly in deliberations; in a STANDING Thread, promoting a periodic distilling synthesis is the intended compression mechanism.",
19784
19784
  inputSchema: {
19785
19785
  verb: exports_external.enum(["promote", "demote", "delete", "restore"]).describe("which curation move"),
19786
19786
  contributionId: exports_external.string().describe("the contribution, con_…")
@@ -19797,7 +19797,7 @@ var ACTION_DEFINITIONS = [
19797
19797
  {
19798
19798
  name: "artifact",
19799
19799
  title: "Create or edit an Artifact",
19800
- description: "Create or edit a durable, versioned Artifact, or promote a Thread attachment into one. Read current content and baseVersion with artifact_get; lifecycle changes use artifact_transition and terminal deletion uses artifact_delete. " + "Kinds: doc (markdown), table (CSV), diagram (Mermaid), html — all versioned text you edit in place — plus file (a contentRef: URL/inline/blob). " + "verb=create (kind+type+title+summary, source for text kinds / contentRef for file; summary is the required one-line skim/retrieval description; a text artifact is born at v1 and is AUTOMATICALLY listed on its sourceThreadId thread — no link post needed). " + "For computer-produced output, create with the computerSessionId returned by attach_computer so the artifact cites the reproducible session. " + "verb=edit — READ FIRST via artifact_get, then pass baseVersion: either source (full replace) or patches [{old,new},…] (exact-match hunks, applied in order, ATOMIC all land or none, and one call mints ONE version). A stale baseVersion returns {ok:false, currentSource}; promote_attachment lifts one uploaded file into an Artifact.",
19800
+ description: "Create or edit a durable versioned Artifact, or promote a Thread attachment; read artifact_get and its baseVersion before editing, while lifecycle/removal stay in artifact_transition and artifact_delete. Text edits replace source or apply exact-match patches atomically, file artifacts use contentRef, and computer-produced artifacts may cite computerSessionId.",
19801
19801
  inputSchema: {
19802
19802
  verb: exports_external.enum(["create", "edit", "promote_attachment"]).describe("which artifact move"),
19803
19803
  title: exports_external.string().optional().describe("create: the artifact's title"),
@@ -19864,7 +19864,7 @@ var ACTION_DEFINITIONS = [
19864
19864
  {
19865
19865
  name: "secrets",
19866
19866
  title: "Manage encrypted Secrets",
19867
- description: "Create, authorize, version, rotate, bind, and revoke first-class Arbor Secrets without revealing plaintext. set and rotate never echo submitted values; bind exposes the current version only to the named App runtime binding, while identity administration and runtime consumption remain separate. A Secret is owned by the Organization or by one Profile; ownership carries administration authority and never implies runtime access, which always needs an explicit grant or binding. Deactivating an owning Profile revokes what it owns, so bound App workloads fail closed. Plaintext reveal is not shipped in v1.",
19867
+ description: "Create, authorize, version, rotate, bind, and revoke first-class Arbor Secrets without revealing plaintext; set/rotate never echo values, and runtime access requires an explicit grant or binding separate from ownership. Organization/Profile owners administer their secrets; profile deactivation revokes owned secrets, and plaintext reveal is not supported.",
19868
19868
  inputSchema: {
19869
19869
  verb: exports_external.enum([
19870
19870
  "list",
@@ -20170,7 +20170,7 @@ var ACTION_DEFINITIONS = [
20170
20170
  {
20171
20171
  name: "app_activate",
20172
20172
  title: "Activate a verified deployment",
20173
- description: "Reserve an attributed activation intent, health-check the verified candidate, then atomically advance the stable URL. Pass the active deployment id just read (or null for the first release). A retry resumes the same pending release; a conflicting control change is rejected.",
20173
+ description: "Activate a verified App deployment at its stable URL after health-checking the candidate. Pass the active deployment id just read (or null for the first release); retries resume the same pending activation and conflicting control changes are rejected.",
20174
20174
  inputSchema: {
20175
20175
  appId: exports_external.string().describe("target App, app_…"),
20176
20176
  deploymentId: exports_external.string().describe("verified candidate, dep_…"),
@@ -20209,7 +20209,7 @@ var ACTION_DEFINITIONS = [
20209
20209
  {
20210
20210
  name: "app_set_access",
20211
20211
  title: "Change App access",
20212
- description: "Change the gateway policy immediately and record who changed it: space requires a current Space member, while public permits anonymous requests and may be unlisted or listed. Durable Apps cannot become public. This does not redeploy code or pass an Arbor identity into App code.",
20212
+ description: "Change an App's gateway access policy without redeploying code: space requires current Space membership, while public permits anonymous requests and may be listed or unlisted; durable Apps cannot be public. Arbor records who changed access and does not inject an Arbor identity into App code.",
20213
20213
  inputSchema: {
20214
20214
  appId: exports_external.string().describe("target App, app_…"),
20215
20215
  access: exports_external.enum(["space", "public"]).describe("new gateway access"),
@@ -20222,7 +20222,7 @@ var ACTION_DEFINITIONS = [
20222
20222
  {
20223
20223
  name: "app_reset_state",
20224
20224
  title: "Reset durable App state",
20225
- description: "Delete one durable App facet's isolated SQLite database as an explicit attributed transition after capturing a Cloudflare recovery point valid for 30 days. Only the App creator or an Org owner/admin may do this; deploying or rolling back never does. Read app_get first, pass its expectedGeneration, and keep the same idempotencyKey across retries. A provider interruption leaves a visible pending intent that the same call resumes; do not change release or archive while pending.",
20225
+ description: "Delete one durable App facet's isolated SQLite state after Arbor captures a 30-day recovery point; only the App creator or an Org owner/admin may do this. Read app_get first and pass expectedGeneration plus a stable idempotencyKey; interrupted retries resume the same reset, and release/archive changes are blocked while pending.",
20226
20226
  inputSchema: {
20227
20227
  appId: exports_external.string().describe("durable App, app_…"),
20228
20228
  expectedGeneration: exports_external.number().int().min(0).describe("state generation from app_get"),
@@ -20235,7 +20235,7 @@ var ACTION_DEFINITIONS = [
20235
20235
  {
20236
20236
  name: "app_restore_state",
20237
20237
  title: "Restore durable App state",
20238
- description: "Restore the latest completed durable-state reset from its automatic Cloudflare recovery point, discarding state written after that reset. Recovery is available for 30 days, only while that reset remains latest and its active release has not changed. Only the App creator or an Org owner/admin may do this. Read app_get first, pass the reset id and current generation, and keep the same idempotencyKey across retries.",
20238
+ description: "Restore the latest recoverable App state reset, discarding state written after it; only the App creator or an Org owner/admin may do this. Read app_get first and pass resetId plus expectedGeneration; recovery lasts 30 days only while that reset is latest and the active release is unchanged, and retries reuse the same idempotencyKey.",
20239
20239
  inputSchema: {
20240
20240
  appId: exports_external.string().describe("durable App, app_…"),
20241
20241
  resetId: exports_external.string().describe("latest recoverable reset from app_get, rst_…"),
@@ -20258,7 +20258,7 @@ var ACTION_DEFINITIONS = [
20258
20258
  {
20259
20259
  name: "charter",
20260
20260
  title: "Set the guidance surfaces",
20261
- description: "The guidance you WRITE (read back via space_get/topic_get/thread_get). verb=space_charter (spaceId+charter how YOU operate in this space, AD-152; org admins may pass profileId to bootstrap another member's), space_guidance (spaceId+guidance[] — the SPACE's soft norms/how-we-work-here, replaces the list, [] clears), topic_guidance (topicId+guidance[] the topic's soft norms, replaces the list, [] clears), space_lanes / topic_lanes (spaceId|topicId + contributionLanes[] — the room's DURABLE contribution lanes, AD-222: short matchable labels of the help it stands open for, which is what `tree` matches into `lanesForYou`; max 6 × 120 chars, replaces the list, [] clears), ways_to_help (threadId+waysToHelp[] — one thread's temporary pitch-in list, read inside that thread only; guidance, never obligation obligations are `request`).",
20261
+ description: "Write collaboration guidance: space_charter for a member's per-Space operating charter, space/topic guidance for shared norms, space/topic lanes for durable contribution lanes, or ways_to_help for one Thread's temporary help list. These writes replace the selected value/list, and an empty string/list clears it.",
20262
20262
  inputSchema: {
20263
20263
  verb: exports_external.enum([
20264
20264
  "space_charter",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lambdacurry/arbor",
3
- "version": "0.20.18",
3
+ "version": "0.20.19",
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",