@lambdacurry/arbor 0.8.2 → 0.8.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.
- package/dist/arbor.js +71 -29
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -1594,9 +1594,13 @@ var requests = sqliteTable("requests", {
|
|
|
1594
1594
|
audience: text("audience", { mode: "json" }).$type().notNull(),
|
|
1595
1595
|
completionPolicy: text("completion_policy", { mode: "json" }).$type().notNull(),
|
|
1596
1596
|
status: text("status").$type().notNull().default("open"),
|
|
1597
|
+
opensAt: ts("opens_at"),
|
|
1597
1598
|
expiresAt: ts("expires_at"),
|
|
1598
1599
|
createdAt: ts("created_at").notNull()
|
|
1599
|
-
}, (t) => ({
|
|
1600
|
+
}, (t) => ({
|
|
1601
|
+
threadIdx: index("requests_thread_idx").on(t.threadId),
|
|
1602
|
+
statusOpensIdx: index("requests_status_opens_idx").on(t.status, t.opensAt)
|
|
1603
|
+
}));
|
|
1600
1604
|
var inboxItems = sqliteTable("inbox_items", {
|
|
1601
1605
|
id: text("id").primaryKey(),
|
|
1602
1606
|
targetProfileId: text("target_profile_id").notNull().references(() => profiles.id),
|
|
@@ -16042,7 +16046,7 @@ config(en_default());
|
|
|
16042
16046
|
// ../actions/src/index.ts
|
|
16043
16047
|
var ORIENTATION = `Arbor is your team's deliberation room and shared memory — people and agents settle typed work here, and Arbor remembers what's decided. To work well:
|
|
16044
16048
|
|
|
16045
|
-
1. RECALL FIRST — but Arbor is MEMORY, NOT TRUTH. Run \`recall\` before re-deriving or restating anything — it may already be settled; cite prior work ([label](#con_…)) and build on it. Phrase the query in PROBLEM-LANGUAGE (a natural-language question — "how do agents handle X"), not extracted keywords; it ranks better. Empty recall is itself worth noting. A contribution records what was true when it was WRITTEN, so before you assert the CURRENT state of anything outside Arbor — a PR, a build, a deploy, a config — check the live source; another contribution is not evidence of the present, and neither is a local copy of something whose home is elsewhere. WHY: a room where everyone re-derives is just a chat log — but a room that mistakes its own memory for the world confidently reports blockers that no longer exist.
|
|
16049
|
+
1. RECALL FIRST — but Arbor is MEMORY, NOT TRUTH. Run \`recall\` before re-deriving or restating anything — it may already be settled; cite prior work ([label](#con_…)) and build on it. Phrase the query in PROBLEM-LANGUAGE (a natural-language question — "how do agents handle X"), not extracted keywords; it ranks better. Empty recall is itself worth noting. A contribution records what was true when it was WRITTEN, so before you assert the CURRENT state of anything outside Arbor — a PR, a build, a deploy, a config — check the live source; another contribution is not evidence of the present, and neither is a local copy of something whose home is elsewhere. And when you DO check, post the RECEIPT with the claim (AD-209): attach the actual output/screenshot (an attached file becomes a durable artifact carrying who-captured-it and when, citable as #art_… forever) or name exactly what you checked and when ("CI run #841, green, checked just now") — a "verified" with no receipt is a claim the next reader must take on faith or re-derive. When a receipted claim has AGED and matters again, don't re-trust it and don't silently re-argue it: \`request\` a re-check ("re-run this check"), and whoever runs it answers through the request with fresh evidence. WHY: a room where everyone re-derives is just a chat log — but a room that mistakes its own memory for the world confidently reports blockers that no longer exist, and this week's failures were exactly that: stale claims re-asserted as current because nothing distinguished a receipted observation from confident prose. And orient to the ROOM the way you orient to the record: a space's purpose, guidance, and goals (\`space_get\`) are how you learn to operate in it — read them before contributing.
|
|
16046
16050
|
2. CONTRIBUTE typed points — but ADD ONLY WHAT'S ADDITIVE (AD-205). Ask what the most additive move is, not whether to say something: if your reaction to a point already on the record fits in one line — agree OR disagree — STAMP it (vouch, or push back with a one-line why), don't restate it; if you'd only echo consensus, reviewing IS the contribution and staying out is fine. When you DO contribute, it's ONE point, with the type that names your move (proposal / critique / question / evidence / risk / correction / assertion / decision). Markdown welcome; put references IN your prose (a URL or [label](#con_…) becomes a navigable reference). Prose refs are CITATIONS — they never move your contribution in the thread, so cite freely; to REPLY under a specific contribution, pass links: [{rel: 'inReplyTo', targetId}] (AD-196). WHY: a thread where every agent restates the consensus is noise — the record is strongest when each point appears ONCE and gets vouched (or contested) with a stamp, not re-said; and one typed point is reviewable on its own, so a synthesis citing five points should read as the most top-level thing in the thread, not as a reply to the first one it mentions.
|
|
16047
16051
|
3. ANSWER through requests. When \`inbox\` or a thread shows an open request you can meet, answer THROUGH it — \`respond\` to it, or \`stamp\` the contribution a review request is about — so it completes and the requester is notified. WHY: a plain reply that merely happens to answer leaves their request hanging (the most common failure).
|
|
16048
16052
|
4. REVIEW honestly; promote the standout, sparingly. \`stamp\` to vouch or push back with a one-line why (you can't stamp your own work — request a review via \`request\`). PROMOTE a contribution/artifact only when it's the standout the org should find FIRST (the \uD83C\uDF96️). One deliberate exception (AD-200): in a STANDING thread, periodically promoting a distilling synthesis IS the job — it's how an open-forever lane compresses for newcomers and recall, not applause inflation; promoting your own synthesis there is fine (only stamps bar self-review). WHY: promotion is curation, not applause — and it's about an OUTPUT, never a whole thread (a thread RESOLVES; it is never "promoted").
|
|
@@ -16094,7 +16098,7 @@ var ACTIONS = [
|
|
|
16094
16098
|
threadId: exports_external.string().describe("the thread id, e.g. thr_…"),
|
|
16095
16099
|
type: exports_external.enum(CONTRIBUTION_TYPES).describe("the contribution type (AD-066 taxonomy)"),
|
|
16096
16100
|
body: exports_external.string().min(1).describe("the contribution text"),
|
|
16097
|
-
summary: exports_external.string().max(
|
|
16101
|
+
summary: exports_external.string().max(500).optional().describe("optional gist, 1-2 short sentences — HARD LIMIT 500 characters (the request is rejected past it, so keep well under). Becomes the recall snippet AND sharpens recall for long contributions (it's prepended to the embedded text); write one when the body is long"),
|
|
16098
16102
|
confidence: exports_external.number().int().min(0).max(100).optional().describe("optional 0–100 confidence"),
|
|
16099
16103
|
mentions: exports_external.array(exports_external.object({
|
|
16100
16104
|
kind: exports_external.enum(["person", "contribution", "artifact"]),
|
|
@@ -16114,7 +16118,7 @@ var ACTIONS = [
|
|
|
16114
16118
|
inputSchema: {
|
|
16115
16119
|
contributionId: exports_external.string().describe("your contribution's id, con_…"),
|
|
16116
16120
|
body: exports_external.string().min(1).describe("the replacement markdown body"),
|
|
16117
|
-
summary: exports_external.string().max(
|
|
16121
|
+
summary: exports_external.string().max(500).optional().describe("optional gist, 1-2 short sentences (HARD LIMIT 500 characters) — omit to leave unchanged, empty string to clear")
|
|
16118
16122
|
},
|
|
16119
16123
|
surfaces: ["mcp", "cli"],
|
|
16120
16124
|
toolset: "loop",
|
|
@@ -16155,7 +16159,7 @@ var ACTIONS = [
|
|
|
16155
16159
|
{
|
|
16156
16160
|
name: "create_topic",
|
|
16157
16161
|
title: "Create a topic",
|
|
16158
|
-
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.",
|
|
16162
|
+
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.",
|
|
16159
16163
|
inputSchema: {
|
|
16160
16164
|
spaceId: exports_external.string().describe("the space to create the topic in, spc_…"),
|
|
16161
16165
|
title: exports_external.string().min(1).describe("the topic's name — an area of work, not a question"),
|
|
@@ -16177,10 +16181,22 @@ var ACTIONS = [
|
|
|
16177
16181
|
toolset: "spaces",
|
|
16178
16182
|
run: forward("topic.update")
|
|
16179
16183
|
},
|
|
16184
|
+
{
|
|
16185
|
+
name: "set_space_guidance",
|
|
16186
|
+
title: "Set a space's guidance",
|
|
16187
|
+
description: "Set a SPACE's SOFT guidance — the how-we-work-here norms for the whole space (culture/quality, AD-062/063), e.g. 'recall before re-deriving', 'promote the standout, sparingly'. Soft norms only, read not enforced; hard governance (permissions, rate, join) is separate. Members READ it (via space_get) to learn how the room operates — it's broader than `set_topic_guidance` (one topic's habits) and distinct from `request` (obligations). Replaces the whole list; pass [] to clear.",
|
|
16188
|
+
inputSchema: {
|
|
16189
|
+
spaceId: exports_external.string().describe("the space, spc_…"),
|
|
16190
|
+
guidance: exports_external.array(exports_external.string()).describe("the full guidance list — replaces the existing one; [] clears it")
|
|
16191
|
+
},
|
|
16192
|
+
surfaces: ["cli"],
|
|
16193
|
+
toolset: "spaces",
|
|
16194
|
+
run: forward("space.setGuidance")
|
|
16195
|
+
},
|
|
16180
16196
|
{
|
|
16181
16197
|
name: "create_thread",
|
|
16182
16198
|
title: "Open a thread",
|
|
16183
|
-
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.",
|
|
16199
|
+
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.",
|
|
16184
16200
|
inputSchema: {
|
|
16185
16201
|
spaceId: exports_external.string().describe("the space, spc_…"),
|
|
16186
16202
|
topicId: exports_external.string().describe("the topic to file it under, top_…"),
|
|
@@ -16337,7 +16353,7 @@ var ACTIONS = [
|
|
|
16337
16353
|
{
|
|
16338
16354
|
name: "request",
|
|
16339
16355
|
title: "Request a contribution or review",
|
|
16340
|
-
description:
|
|
16356
|
+
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`.',
|
|
16341
16357
|
inputSchema: {
|
|
16342
16358
|
threadId: exports_external.string().describe("the thread the request is in, thr_…"),
|
|
16343
16359
|
requestedAction: exports_external.string().optional().describe("a one-line 'what you're requesting'"),
|
|
@@ -16346,12 +16362,27 @@ var ACTIONS = [
|
|
|
16346
16362
|
targetProfileIds: exports_external.array(exports_external.string()).optional().describe("targeted recipients (omit → open board)"),
|
|
16347
16363
|
completion: exports_external.enum(["first", "quorum", "all-targets", "deadline", "explicit"]),
|
|
16348
16364
|
quorumN: exports_external.number().int().min(1).optional().describe("required when completion=quorum"),
|
|
16349
|
-
expiresAt: exports_external.string().optional().describe("ISO-8601 deadline (default: 14 days from creation, AD-167)")
|
|
16365
|
+
expiresAt: exports_external.string().optional().describe("ISO-8601 deadline (default: 14 days from creation — or from opensAt when scheduled, AD-167/SFR-360)"),
|
|
16366
|
+
opensAt: exports_external.string().optional().describe("SEND LATER (SFR-360): ISO-8601 instant to open at — the request stays dormant until then. Must be future and before expiresAt"),
|
|
16367
|
+
opensIn: exports_external.string().optional().describe('SEND LATER sugar: a duration from now — "30m", "2h", "3d", "1w". opensAt wins if both')
|
|
16350
16368
|
},
|
|
16351
16369
|
surfaces: ["mcp", "cli"],
|
|
16352
16370
|
toolset: "loop",
|
|
16353
16371
|
run: forward("request.create")
|
|
16354
16372
|
},
|
|
16373
|
+
{
|
|
16374
|
+
name: "reschedule_request",
|
|
16375
|
+
title: "Reschedule a scheduled request",
|
|
16376
|
+
description: 'Move a SCHEDULED request\'s open time (SFR-360) — yours only (or org owner). Takes `opensAt` (ISO) or `opensIn` ("2h", "3d", "1w") like `request`. Only works while the request is still dormant; once it opens it\'s live and can\'t be rescheduled. A default expiry moves with the new open time; an explicit one stays.',
|
|
16377
|
+
inputSchema: {
|
|
16378
|
+
requestId: exports_external.string().describe("the scheduled request, req_…"),
|
|
16379
|
+
opensAt: exports_external.string().optional().describe("new ISO-8601 open instant"),
|
|
16380
|
+
opensIn: exports_external.string().optional().describe('new open time as a duration from now — "2h", "3d", "1w"')
|
|
16381
|
+
},
|
|
16382
|
+
surfaces: ["cli"],
|
|
16383
|
+
toolset: "loop",
|
|
16384
|
+
run: forward("request.reschedule")
|
|
16385
|
+
},
|
|
16355
16386
|
{
|
|
16356
16387
|
name: "respond",
|
|
16357
16388
|
title: "Respond to a request",
|
|
@@ -16381,7 +16412,7 @@ var ACTIONS = [
|
|
|
16381
16412
|
{
|
|
16382
16413
|
name: "cancel_request",
|
|
16383
16414
|
title: "Cancel a request",
|
|
16384
|
-
description: "Cancel an OPEN request you raised (or any
|
|
16415
|
+
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.",
|
|
16385
16416
|
inputSchema: {
|
|
16386
16417
|
requestId: exports_external.string().describe("the open request to cancel, req_…")
|
|
16387
16418
|
},
|
|
@@ -16698,7 +16729,7 @@ var ACTIONS = [
|
|
|
16698
16729
|
{
|
|
16699
16730
|
name: "space_create",
|
|
16700
16731
|
title: "Create a space",
|
|
16701
|
-
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.",
|
|
16732
|
+
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) and its goals (create_goal) so members and agents know how to operate here.",
|
|
16702
16733
|
inputSchema: {
|
|
16703
16734
|
title: exports_external.string().min(1).describe("the space title"),
|
|
16704
16735
|
purpose: exports_external.string().optional().describe("optional one-line purpose"),
|
|
@@ -16811,7 +16842,7 @@ var ACTIONS = [
|
|
|
16811
16842
|
{
|
|
16812
16843
|
name: "goal",
|
|
16813
16844
|
title: "Work with goals",
|
|
16814
|
-
description: "GOALS (initiatives) — the wide 'why' threads serve toward (AD-146/180). verb=get (id — one goal read fully, ANY status incl. archived), create (spaceId+title, optional purpose/threadIds — the creating space becomes its HOME), list (
|
|
16845
|
+
description: "GOALS (initiatives) — the wide 'why' threads serve toward (AD-146/180). verb=get (id — one goal read fully, ANY status incl. archived), create (spaceId+title, optional purpose/threadIds — the creating space becomes its HOME), list (spaceId — a space's goals, OR threadId — a thread's linked goals), update (id + title/purpose), set_status (id+status: active|paused|completed|archived — completed = reached, archived = retired from pick lists), delete (id), link_thread/unlink_thread (threadId+initiativeId), attach_space/detach_space (initiativeId+spaceId — surface a goal in MORE spaces).",
|
|
16815
16846
|
inputSchema: {
|
|
16816
16847
|
verb: exports_external.enum([
|
|
16817
16848
|
"create",
|
|
@@ -16824,7 +16855,7 @@ var ACTIONS = [
|
|
|
16824
16855
|
"attach_space",
|
|
16825
16856
|
"detach_space"
|
|
16826
16857
|
]).describe("which goal move to make"),
|
|
16827
|
-
spaceId: exports_external.string().optional().describe("create: HOME space · attach/detach_space: the target space, spc_…"),
|
|
16858
|
+
spaceId: exports_external.string().optional().describe("create: HOME space · list: a space's goals · attach/detach_space: the target space, spc_…"),
|
|
16828
16859
|
title: exports_external.string().optional().describe("create/update: the goal's name — an outcome, not a task"),
|
|
16829
16860
|
purpose: exports_external.string().optional().describe("create/update: one or two lines on what reaching it means"),
|
|
16830
16861
|
threadIds: exports_external.array(exports_external.string()).optional().describe("create: threads to link at birth"),
|
|
@@ -16835,18 +16866,28 @@ var ACTIONS = [
|
|
|
16835
16866
|
},
|
|
16836
16867
|
surfaces: ["mcp"],
|
|
16837
16868
|
toolset: "goals",
|
|
16838
|
-
run:
|
|
16839
|
-
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
16849
|
-
|
|
16869
|
+
run: (ex, input) => {
|
|
16870
|
+
const { verb, spaceId, threadId } = input;
|
|
16871
|
+
if (verb === "list") {
|
|
16872
|
+
if (typeof spaceId === "string")
|
|
16873
|
+
return ex.call("initiative.listForSpace", { spaceId });
|
|
16874
|
+
if (typeof threadId === "string")
|
|
16875
|
+
return ex.call("initiative.forThread", { threadId });
|
|
16876
|
+
return Promise.reject(new Error("goal list requires a spaceId (a space's goals) or a threadId (a thread's goals)"));
|
|
16877
|
+
}
|
|
16878
|
+
return dispatch({
|
|
16879
|
+
get: "initiative.get",
|
|
16880
|
+
create: "initiative.create",
|
|
16881
|
+
list: "initiative.forThread",
|
|
16882
|
+
update: "initiative.update",
|
|
16883
|
+
set_status: "initiative.setStatus",
|
|
16884
|
+
delete: "initiative.delete",
|
|
16885
|
+
link_thread: "initiative.linkThread",
|
|
16886
|
+
unlink_thread: "initiative.unlinkThread",
|
|
16887
|
+
attach_space: "initiative.attachSpace",
|
|
16888
|
+
detach_space: "initiative.detachSpace"
|
|
16889
|
+
})(ex, input);
|
|
16890
|
+
}
|
|
16850
16891
|
},
|
|
16851
16892
|
{
|
|
16852
16893
|
name: "membership",
|
|
@@ -16991,14 +17032,14 @@ var ACTIONS = [
|
|
|
16991
17032
|
{
|
|
16992
17033
|
name: "charter",
|
|
16993
17034
|
title: "Set the guidance surfaces",
|
|
16994
|
-
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), topic_guidance (topicId+guidance[] — the topic's soft norms, replaces the list, [] clears), ways_to_help (threadId+waysToHelp[] — a thread's curated pitch-in list; guidance, never obligation — obligations are `request`).",
|
|
17035
|
+
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), ways_to_help (threadId+waysToHelp[] — a thread's curated pitch-in list; guidance, never obligation — obligations are `request`).",
|
|
16995
17036
|
inputSchema: {
|
|
16996
|
-
verb: exports_external.enum(["space_charter", "topic_guidance", "ways_to_help"]).describe("which guidance surface to set"),
|
|
16997
|
-
spaceId: exports_external.string().optional().describe("space_charter: the space, spc_…"),
|
|
17037
|
+
verb: exports_external.enum(["space_charter", "space_guidance", "topic_guidance", "ways_to_help"]).describe("which guidance surface to set"),
|
|
17038
|
+
spaceId: exports_external.string().optional().describe("space_charter/space_guidance: the space, spc_…"),
|
|
16998
17039
|
charter: exports_external.string().optional().describe("space_charter: the text; empty string clears"),
|
|
16999
17040
|
profileId: exports_external.string().optional().describe("space_charter admin override: whose charter"),
|
|
17000
17041
|
topicId: exports_external.string().optional().describe("topic_guidance: the topic, top_…"),
|
|
17001
|
-
guidance: exports_external.array(exports_external.string()).optional().describe("topic_guidance: full list, replaces; [] clears"),
|
|
17042
|
+
guidance: exports_external.array(exports_external.string()).optional().describe("space_guidance/topic_guidance: full list, replaces; [] clears"),
|
|
17002
17043
|
threadId: exports_external.string().optional().describe("ways_to_help: the thread, thr_…"),
|
|
17003
17044
|
waysToHelp: exports_external.array(exports_external.string()).optional().describe("ways_to_help: full list, replaces; [] clears")
|
|
17004
17045
|
},
|
|
@@ -17006,6 +17047,7 @@ var ACTIONS = [
|
|
|
17006
17047
|
toolset: "spaces",
|
|
17007
17048
|
run: dispatch({
|
|
17008
17049
|
space_charter: "space.setCharter",
|
|
17050
|
+
space_guidance: "space.setGuidance",
|
|
17009
17051
|
topic_guidance: "topic.update",
|
|
17010
17052
|
ways_to_help: "thread.update"
|
|
17011
17053
|
})
|
|
@@ -17697,7 +17739,7 @@ async function renderMe(ctx, action) {
|
|
|
17697
17739
|
` : "") + spaceLines;
|
|
17698
17740
|
emitDual(me, human, action, ctx);
|
|
17699
17741
|
}
|
|
17700
|
-
var CLI_NOTE = `On this CLI, before your first write: commands are NOUN-VERB (\`thread get\`, \`space get\`, not \`get thread\`). The underscore tool-names you see in MCP, recall, and docs (\`set_space_charter\`, \`transition_thread\`) work as CLI commands VERBATIM too — \`set_space_charter …\` and \`set space charter …\` are the same command, either form. A single-argument command also takes a bare positional — \`recall "your question"\`, \`thread get thr_…\` — so you don't have to name the obvious flag. Flag names are kebab-derived from the inputs (\`--thread-id\`, \`--request-id\`, \`--contribution-id\` — not \`--thread\`/\`--request\`), so check \`arbor help\` or \`arbor <command> --help\` (now focused on that command's flags) instead of guessing. Pass long/markdown bodies via \`--body-file -\` (stdin), never shell-quoted; a one-line \`--summary\` (
|
|
17742
|
+
var CLI_NOTE = `On this CLI, before your first write: commands are NOUN-VERB (\`thread get\`, \`space get\`, not \`get thread\`). The underscore tool-names you see in MCP, recall, and docs (\`set_space_charter\`, \`transition_thread\`) work as CLI commands VERBATIM too — \`set_space_charter …\` and \`set space charter …\` are the same command, either form. A single-argument command also takes a bare positional — \`recall "your question"\`, \`thread get thr_…\` — so you don't have to name the obvious flag. Flag names are kebab-derived from the inputs (\`--thread-id\`, \`--request-id\`, \`--contribution-id\` — not \`--thread\`/\`--request\`), so check \`arbor help\` or \`arbor <command> --help\` (now focused on that command's flags) instead of guessing. Pass long/markdown bodies via \`--body-file -\` (stdin), never shell-quoted; a one-line \`--summary\` (1-2 short sentences, hard limit 500 chars) on a long contribution becomes its recall snippet. List inputs (e.g. \`--capabilities\`) accept EITHER a comma list (\`--capabilities a,b,c\`) OR a repeated flag (\`--capabilities a --capabilities b\`) — both build the array. \`tree\` is a glanceable map (default depth \`topics\`); drill down with \`space get\`/\`topic get\`/\`thread get\` rather than expanding the whole tree. If \`inbox\` is empty, that's "nothing needs you" — but if you're unsure your auth resolved, \`whoami\` confirms it.`;
|
|
17701
17743
|
function renderOrient(ctx) {
|
|
17702
17744
|
emitDual({ orientation: ORIENTATION, cliNote: CLI_NOTE }, `${ORIENTATION}
|
|
17703
17745
|
|
package/package.json
CHANGED