@lambdacurry/arbor 0.11.0 → 0.11.5
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 +388 -9
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -1465,6 +1465,121 @@ var threads = sqliteTable("threads", {
|
|
|
1465
1465
|
topicIdx: index("threads_topic_idx").on(t.topicId),
|
|
1466
1466
|
spaceIdx: index("threads_space_idx").on(t.spaceId)
|
|
1467
1467
|
}));
|
|
1468
|
+
var computerConfigs = sqliteTable("computer_configs", {
|
|
1469
|
+
id: text("id").primaryKey(),
|
|
1470
|
+
scope: text("scope").$type().notNull(),
|
|
1471
|
+
scopeId: text("scope_id").notNull(),
|
|
1472
|
+
orgId: text("org_id").notNull().references(() => orgs.id),
|
|
1473
|
+
spaceId: text("space_id").references(() => spaces.id),
|
|
1474
|
+
topicId: text("topic_id").references(() => topics.id),
|
|
1475
|
+
threadId: text("thread_id").references(() => threads.id),
|
|
1476
|
+
config: text("config", { mode: "json" }).$type().notNull().default({}),
|
|
1477
|
+
version: integer("version").notNull().default(1),
|
|
1478
|
+
createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
|
|
1479
|
+
updatedByProfileId: text("updated_by_profile_id").notNull().references(() => profiles.id),
|
|
1480
|
+
createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1481
|
+
updatedExecutionContextId: text("updated_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1482
|
+
createdAt: ts("created_at").notNull(),
|
|
1483
|
+
updatedAt: ts("updated_at").notNull()
|
|
1484
|
+
}, (t) => ({
|
|
1485
|
+
scopeIdx: uniqueIndex("computer_configs_scope_idx").on(t.scope, t.scopeId),
|
|
1486
|
+
orgIdx: index("computer_configs_org_idx").on(t.orgId),
|
|
1487
|
+
spaceIdx: index("computer_configs_space_idx").on(t.spaceId),
|
|
1488
|
+
topicIdx: index("computer_configs_topic_idx").on(t.topicId),
|
|
1489
|
+
threadIdx: index("computer_configs_thread_idx").on(t.threadId)
|
|
1490
|
+
}));
|
|
1491
|
+
var threadComputers = sqliteTable("thread_computers", {
|
|
1492
|
+
id: text("id").primaryKey(),
|
|
1493
|
+
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1494
|
+
provider: text("provider").$type().notNull(),
|
|
1495
|
+
currentSnapshotId: text("current_snapshot_id"),
|
|
1496
|
+
createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
|
|
1497
|
+
createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1498
|
+
createdAt: ts("created_at").notNull()
|
|
1499
|
+
}, (t) => ({ threadIdx: uniqueIndex("thread_computers_thread_idx").on(t.threadId) }));
|
|
1500
|
+
var computerSessions = sqliteTable("computer_sessions", {
|
|
1501
|
+
id: text("id").primaryKey(),
|
|
1502
|
+
computerId: text("computer_id").notNull().references(() => threadComputers.id),
|
|
1503
|
+
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1504
|
+
profileId: text("profile_id").notNull().references(() => profiles.id),
|
|
1505
|
+
executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
|
|
1506
|
+
configKey: text("config_key").notNull(),
|
|
1507
|
+
startingSnapshotId: text("starting_snapshot_id"),
|
|
1508
|
+
attachedAt: ts("attached_at").notNull()
|
|
1509
|
+
}, (t) => ({
|
|
1510
|
+
computerIdx: index("computer_sessions_computer_idx").on(t.computerId, t.attachedAt),
|
|
1511
|
+
threadIdx: index("computer_sessions_thread_idx").on(t.threadId, t.attachedAt)
|
|
1512
|
+
}));
|
|
1513
|
+
var computerSnapshots = sqliteTable("computer_snapshots", {
|
|
1514
|
+
id: text("id").primaryKey(),
|
|
1515
|
+
ownerScope: text("owner_scope").$type().notNull(),
|
|
1516
|
+
topicId: text("topic_id").notNull().references(() => topics.id),
|
|
1517
|
+
computerId: text("computer_id").references(() => threadComputers.id),
|
|
1518
|
+
parentSnapshotId: text("parent_snapshot_id"),
|
|
1519
|
+
lineageKey: text("lineage_key"),
|
|
1520
|
+
configKey: text("config_key"),
|
|
1521
|
+
provider: text("provider").$type().notNull(),
|
|
1522
|
+
providerRef: text("provider_ref").notNull(),
|
|
1523
|
+
producingSessionId: text("producing_session_id").references(() => computerSessions.id),
|
|
1524
|
+
authorProfileId: text("author_profile_id").notNull().references(() => profiles.id),
|
|
1525
|
+
executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
|
|
1526
|
+
contentDigest: text("content_digest"),
|
|
1527
|
+
createdAt: ts("created_at").notNull()
|
|
1528
|
+
}, (t) => ({
|
|
1529
|
+
providerRefIdx: uniqueIndex("computer_snapshots_provider_ref_idx").on(t.provider, t.providerRef),
|
|
1530
|
+
topicBaseIdx: uniqueIndex("computer_snapshots_topic_base_idx").on(t.topicId, t.configKey),
|
|
1531
|
+
lineageIdx: uniqueIndex("computer_snapshots_lineage_idx").on(t.lineageKey),
|
|
1532
|
+
computerIdx: index("computer_snapshots_computer_idx").on(t.computerId, t.createdAt),
|
|
1533
|
+
parentIdx: index("computer_snapshots_parent_idx").on(t.parentSnapshotId)
|
|
1534
|
+
}));
|
|
1535
|
+
var previews = sqliteTable("previews", {
|
|
1536
|
+
id: text("id").primaryKey(),
|
|
1537
|
+
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1538
|
+
spaceId: text("space_id").notNull().references(() => spaces.id),
|
|
1539
|
+
title: text("title").notNull(),
|
|
1540
|
+
routing: text("routing").$type().notNull().default("static"),
|
|
1541
|
+
currentVersionId: text("current_version_id"),
|
|
1542
|
+
createdByProfileId: text("created_by_profile_id").notNull().references(() => profiles.id),
|
|
1543
|
+
createdExecutionContextId: text("created_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1544
|
+
createdAt: ts("created_at").notNull()
|
|
1545
|
+
}, (t) => ({
|
|
1546
|
+
threadIdx: index("previews_thread_idx").on(t.threadId, t.createdAt),
|
|
1547
|
+
spaceIdx: index("previews_space_idx").on(t.spaceId)
|
|
1548
|
+
}));
|
|
1549
|
+
var previewVersions = sqliteTable("preview_versions", {
|
|
1550
|
+
id: text("id").primaryKey(),
|
|
1551
|
+
previewId: text("preview_id").notNull().references(() => previews.id),
|
|
1552
|
+
version: integer("version").notNull(),
|
|
1553
|
+
hostLabel: text("host_label").notNull(),
|
|
1554
|
+
status: text("status").$type().notNull().default("pending"),
|
|
1555
|
+
objectPrefix: text("object_prefix").notNull(),
|
|
1556
|
+
manifest: text("manifest", { mode: "json" }).$type().notNull(),
|
|
1557
|
+
manifestDigest: text("manifest_digest").notNull(),
|
|
1558
|
+
fileCount: integer("file_count").notNull(),
|
|
1559
|
+
byteCount: integer("byte_count").notNull(),
|
|
1560
|
+
computerSessionId: text("computer_session_id").notNull().references(() => computerSessions.id),
|
|
1561
|
+
snapshotId: text("snapshot_id").notNull().references(() => computerSnapshots.id),
|
|
1562
|
+
publishedByProfileId: text("published_by_profile_id").notNull().references(() => profiles.id),
|
|
1563
|
+
publishedExecutionContextId: text("published_execution_context_id").notNull().references(() => executionContexts.id),
|
|
1564
|
+
failureCode: text("failure_code"),
|
|
1565
|
+
createdAt: ts("created_at").notNull(),
|
|
1566
|
+
readyAt: ts("ready_at")
|
|
1567
|
+
}, (t) => ({
|
|
1568
|
+
previewVersionIdx: uniqueIndex("preview_versions_preview_version_idx").on(t.previewId, t.version),
|
|
1569
|
+
hostIdx: uniqueIndex("preview_versions_host_idx").on(t.hostLabel),
|
|
1570
|
+
sessionIdx: index("preview_versions_session_idx").on(t.computerSessionId, t.createdAt),
|
|
1571
|
+
snapshotIdx: index("preview_versions_snapshot_idx").on(t.snapshotId)
|
|
1572
|
+
}));
|
|
1573
|
+
var previewVersionFinalizations = sqliteTable("preview_version_finalizations", {
|
|
1574
|
+
versionId: text("version_id").primaryKey().references(() => previewVersions.id),
|
|
1575
|
+
finalizedAt: ts("finalized_at").notNull()
|
|
1576
|
+
});
|
|
1577
|
+
var previewViewerGrantUses = sqliteTable("preview_viewer_grant_uses", {
|
|
1578
|
+
jti: text("jti").primaryKey(),
|
|
1579
|
+
versionId: text("version_id").notNull().references(() => previewVersions.id),
|
|
1580
|
+
profileId: text("profile_id").notNull().references(() => profiles.id),
|
|
1581
|
+
consumedAt: ts("consumed_at").notNull()
|
|
1582
|
+
});
|
|
1468
1583
|
var threadInitiatives = sqliteTable("thread_initiatives", {
|
|
1469
1584
|
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1470
1585
|
initiativeId: text("initiative_id").notNull().references(() => initiatives.id)
|
|
@@ -1477,6 +1592,7 @@ var contributions = sqliteTable("contributions", {
|
|
|
1477
1592
|
threadId: text("thread_id").notNull().references(() => threads.id),
|
|
1478
1593
|
authorProfileId: text("author_profile_id").notNull().references(() => profiles.id),
|
|
1479
1594
|
executionContextId: text("execution_context_id").notNull().references(() => executionContexts.id),
|
|
1595
|
+
computerSessionId: text("computer_session_id").references(() => computerSessions.id),
|
|
1480
1596
|
type: text("type").$type().notNull(),
|
|
1481
1597
|
body: text("body").notNull(),
|
|
1482
1598
|
summary: text("summary"),
|
|
@@ -1551,6 +1667,7 @@ var artifacts = sqliteTable("artifacts", {
|
|
|
1551
1667
|
summary: text("summary"),
|
|
1552
1668
|
ownerProfileId: text("owner_profile_id").notNull().references(() => profiles.id),
|
|
1553
1669
|
sourceThreadId: text("source_thread_id").notNull().references(() => threads.id),
|
|
1670
|
+
computerSessionId: text("computer_session_id").references(() => computerSessions.id),
|
|
1554
1671
|
sourceContributionIds: text("source_contribution_ids", { mode: "json" }).$type(),
|
|
1555
1672
|
topicIds: text("topic_ids", { mode: "json" }).$type().notNull().default([]),
|
|
1556
1673
|
initiativeIds: text("initiative_ids", { mode: "json" }).$type().notNull().default([]),
|
|
@@ -1673,6 +1790,8 @@ var EMOJI_RE = new RegExp("^\\p{RGI_Emoji}$", "v");
|
|
|
1673
1790
|
var BASE_MS = Date.parse("2026-07-20T15:00:00.000Z");
|
|
1674
1791
|
// ../core/src/ops/agent-pairing.ts
|
|
1675
1792
|
var PAIRING_TTL_MS = 15 * 60 * 1000;
|
|
1793
|
+
// ../core/src/ops/preview.ts
|
|
1794
|
+
var PREVIEW_MAX_BYTES = 2 * 1024 * 1024;
|
|
1676
1795
|
// ../core/src/queries/lane-match.ts
|
|
1677
1796
|
var STOP_WORDS = new Set("a an and are as at be by for from has have here how i in is it me of on or our the their they this to was what when where which who will with you your".split(" "));
|
|
1678
1797
|
// ../core/src/queries/activity.ts
|
|
@@ -16113,7 +16232,7 @@ var ACTIONS = [
|
|
|
16113
16232
|
{
|
|
16114
16233
|
name: "contribute",
|
|
16115
16234
|
title: "Contribute to a thread",
|
|
16116
|
-
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. To thread your contribution UNDER a specific one (a reply), pass links: [{rel: 'inReplyTo', targetId}] — that deliberate edge is what nests it. 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.",
|
|
16235
|
+
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. 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. Pass attachmentIds returned by computer_verify to place its visual evidence inline. 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.",
|
|
16117
16236
|
inputSchema: {
|
|
16118
16237
|
threadId: exports_external.string().describe("the thread id, e.g. thr_…"),
|
|
16119
16238
|
type: exports_external.enum(CONTRIBUTION_TYPES).describe("the contribution type (AD-066 taxonomy)"),
|
|
@@ -16121,6 +16240,8 @@ var ACTIONS = [
|
|
|
16121
16240
|
idempotencyKey: exports_external.string().min(1).max(200).optional().describe("stable key for this ONE logical contribution (≤200 chars), e.g. cron-run/work-item + output slot; safe retries return the original contribution. Reusing it with different content is a conflict."),
|
|
16122
16241
|
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"),
|
|
16123
16242
|
confidence: exports_external.number().int().min(0).max(100).optional().describe("optional 0–100 confidence"),
|
|
16243
|
+
computerSessionId: exports_external.string().optional().describe("the attached computer session that produced this result, cms_…"),
|
|
16244
|
+
attachmentIds: exports_external.array(exports_external.string()).max(10).optional().describe("Thread-scoped file evidence to show inline, including attachmentIds returned by computer_verify"),
|
|
16124
16245
|
mentions: exports_external.array(exports_external.object({
|
|
16125
16246
|
kind: exports_external.enum(["person", "contribution", "artifact"]),
|
|
16126
16247
|
id: exports_external.string(),
|
|
@@ -16265,6 +16386,240 @@ var ACTIONS = [
|
|
|
16265
16386
|
toolset: "loop",
|
|
16266
16387
|
run: forward("thread.create")
|
|
16267
16388
|
},
|
|
16389
|
+
{
|
|
16390
|
+
name: "set_organization_computer",
|
|
16391
|
+
title: "Set organization computer defaults",
|
|
16392
|
+
description: "Replace your organization's sparse computer-default layer without allocating runtime state. Omitted/null values fall back to provider defaults; Space, Topic, and Thread layers may override individual fields.",
|
|
16393
|
+
inputSchema: {
|
|
16394
|
+
backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("default execution tier, or null to use worker-shell"),
|
|
16395
|
+
containerProfile: exports_external.string().nullable().optional().describe("optional logical Currybox container profile, or null to clear"),
|
|
16396
|
+
setupScript: exports_external.string().nullable().optional().describe("optional setup run when materializing a reusable base, or null to clear"),
|
|
16397
|
+
repositories: exports_external.array(exports_external.string()).nullable().optional().describe("default repositories, repeated --repositories; [] clears and null inherits provider default")
|
|
16398
|
+
},
|
|
16399
|
+
surfaces: ["mcp", "cli"],
|
|
16400
|
+
toolset: "structure",
|
|
16401
|
+
run: forward("computer_config.set_organization")
|
|
16402
|
+
},
|
|
16403
|
+
{
|
|
16404
|
+
name: "set_space_computer",
|
|
16405
|
+
title: "Set a Space computer",
|
|
16406
|
+
description: "Replace a Space's sparse computer override without allocating anything. Omitted/null fields inherit organization defaults; the default backend is image-free worker-shell, and a reusable base materializes lazily only when needed.",
|
|
16407
|
+
inputSchema: {
|
|
16408
|
+
spaceId: exports_external.string().describe("the Space, spc_…"),
|
|
16409
|
+
backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
|
|
16410
|
+
containerProfile: exports_external.string().nullable().optional().describe("optional logical Currybox container profile, or null to clear inherited profile"),
|
|
16411
|
+
setupScript: exports_external.string().nullable().optional().describe("optional setup run when materializing a reusable base, or null to clear"),
|
|
16412
|
+
repositories: exports_external.array(exports_external.string()).nullable().optional().describe("repository allowlist/default clones; [] clears and null inherits")
|
|
16413
|
+
},
|
|
16414
|
+
surfaces: ["mcp", "cli"],
|
|
16415
|
+
toolset: "structure",
|
|
16416
|
+
run: forward("computer_config.set_space")
|
|
16417
|
+
},
|
|
16418
|
+
{
|
|
16419
|
+
name: "set_topic_computer",
|
|
16420
|
+
title: "Override a Topic computer",
|
|
16421
|
+
description: "Replace a Topic's sparse computer override; omitted/null fields inherit Space/organization policy, and no runtime is allocated. A material change gets a semantic config key so the next attachment materializes matching state lazily.",
|
|
16422
|
+
inputSchema: {
|
|
16423
|
+
topicId: exports_external.string().describe("the Topic, top_…"),
|
|
16424
|
+
backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
|
|
16425
|
+
containerProfile: exports_external.string().nullable().optional().describe("optional logical Currybox container profile, or null to clear inherited profile"),
|
|
16426
|
+
setupScript: exports_external.string().nullable().optional().describe("optional setup run, or null to clear"),
|
|
16427
|
+
repositories: exports_external.array(exports_external.string()).nullable().optional().describe("repository allowlist/default clones; [] clears and null inherits")
|
|
16428
|
+
},
|
|
16429
|
+
surfaces: ["mcp", "cli"],
|
|
16430
|
+
toolset: "structure",
|
|
16431
|
+
run: forward("computer_config.set_topic")
|
|
16432
|
+
},
|
|
16433
|
+
{
|
|
16434
|
+
name: "set_thread_computer",
|
|
16435
|
+
title: "Override a Thread computer",
|
|
16436
|
+
description: "Replace one Thread's sparse computer override. This is config only: the stable computer is still created lazily on first authorized collaborator attachment, and an existing computer cannot switch provider.",
|
|
16437
|
+
inputSchema: {
|
|
16438
|
+
threadId: exports_external.string().describe("the Thread, thr_…"),
|
|
16439
|
+
backend: exports_external.enum(["worker-shell", "container"]).nullable().optional().describe("override execution tier, or null to inherit"),
|
|
16440
|
+
containerProfile: exports_external.string().nullable().optional().describe("optional logical Currybox container profile, or null to clear inherited profile"),
|
|
16441
|
+
setupScript: exports_external.string().nullable().optional().describe("optional setup run, or null to clear"),
|
|
16442
|
+
repositories: exports_external.array(exports_external.string()).nullable().optional().describe("repository allowlist/default clones; [] clears and null inherits")
|
|
16443
|
+
},
|
|
16444
|
+
surfaces: ["mcp", "cli"],
|
|
16445
|
+
toolset: "structure",
|
|
16446
|
+
run: forward("computer_config.set_thread")
|
|
16447
|
+
},
|
|
16448
|
+
{
|
|
16449
|
+
name: "attach_computer",
|
|
16450
|
+
title: "Attach a Thread computer",
|
|
16451
|
+
description: "Lazily attach the one stable computer identity to a Thread and mint an immutable, server-attributed session receipt. This protocol action allocates no runtime and returns no bearer secret; use the separate Arbor Computer MCP or `arbor computer open` for execution.",
|
|
16452
|
+
inputSchema: {
|
|
16453
|
+
threadId: exports_external.string().describe("the Thread whose computer you are attaching, thr_…")
|
|
16454
|
+
},
|
|
16455
|
+
surfaces: ["mcp", "cli"],
|
|
16456
|
+
toolset: "loop",
|
|
16457
|
+
run: forward("computer.attach")
|
|
16458
|
+
},
|
|
16459
|
+
{
|
|
16460
|
+
name: "computer_open",
|
|
16461
|
+
title: "Open a Thread computer",
|
|
16462
|
+
description: "Open or resume this Thread's project environment for filesystem or command work. Returns computerSessionId; pass it unchanged to later Computer tools and to Contributions or responses produced from the work.",
|
|
16463
|
+
inputSchema: {
|
|
16464
|
+
threadId: exports_external.string().describe("the Arbor Thread whose stable computer to open, thr_…"),
|
|
16465
|
+
vcpus: exports_external.number().int().min(1).max(4).optional().describe("optional container vCPU request"),
|
|
16466
|
+
label: exports_external.string().optional().describe("short runtime label for operator diagnostics")
|
|
16467
|
+
},
|
|
16468
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16469
|
+
toolset: "loop",
|
|
16470
|
+
run: forward("computer_runtime.open")
|
|
16471
|
+
},
|
|
16472
|
+
{
|
|
16473
|
+
name: "computer_exec",
|
|
16474
|
+
title: "Run a command",
|
|
16475
|
+
description: "Run a bounded command in an opened Thread computer, normally from /workspace. Use background only for the container backend; worker-shell deliberately serializes mutations and rejects long-lived processes.",
|
|
16476
|
+
inputSchema: {
|
|
16477
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
16478
|
+
command: exports_external.string().min(1).describe("the shell command to run"),
|
|
16479
|
+
cwd: exports_external.string().optional().describe("working directory under /workspace"),
|
|
16480
|
+
timeout: exports_external.number().int().min(1000).max(1800000).optional().describe("timeout in milliseconds, from 1,000 through 1,800,000"),
|
|
16481
|
+
background: exports_external.boolean().optional().describe("start a container process and return its pid")
|
|
16482
|
+
},
|
|
16483
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16484
|
+
toolset: "loop",
|
|
16485
|
+
run: forward("computer_runtime.exec")
|
|
16486
|
+
},
|
|
16487
|
+
{
|
|
16488
|
+
name: "computer_status",
|
|
16489
|
+
title: "Inspect a computer",
|
|
16490
|
+
description: "Read live Currybox process and runtime status for an opened computer. This is ephemeral provider state; use get_computer on the Arbor surface for durable config and snapshot lineage.",
|
|
16491
|
+
inputSchema: {
|
|
16492
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…")
|
|
16493
|
+
},
|
|
16494
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16495
|
+
toolset: "loop",
|
|
16496
|
+
run: forward("computer_runtime.status")
|
|
16497
|
+
},
|
|
16498
|
+
{
|
|
16499
|
+
name: "computer_verify",
|
|
16500
|
+
title: "Capture public visual evidence",
|
|
16501
|
+
description: "Capture the 1280×720 rendering of one public HTTPS URL without starting the Thread's project runtime. Returns computerSessionId, attachmentIds, capture metadata, and a gated downloadUrl; Computer MCP also emits the PNG as an inspectable image block. Pass the receipt and attachment ids to contribute or respond. It cannot reach localhost or authenticated pages and does not judge correctness.",
|
|
16502
|
+
inputSchema: {
|
|
16503
|
+
threadId: exports_external.string().describe("the Arbor Thread that will own the evidence, thr_…"),
|
|
16504
|
+
targetUrl: exports_external.url().refine((value) => value.startsWith("https://"), "targetUrl must use HTTPS").describe("one public HTTPS URL to capture")
|
|
16505
|
+
},
|
|
16506
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16507
|
+
toolset: "loop",
|
|
16508
|
+
run: forward("computer_runtime.verify")
|
|
16509
|
+
},
|
|
16510
|
+
{
|
|
16511
|
+
name: "computer_read",
|
|
16512
|
+
title: "Read a project file",
|
|
16513
|
+
description: "Read one file from the opened computer when command output is the wrong shape. Paths must stay under /workspace.",
|
|
16514
|
+
inputSchema: {
|
|
16515
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
16516
|
+
path: exports_external.string().describe("absolute path under /workspace")
|
|
16517
|
+
},
|
|
16518
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16519
|
+
toolset: "loop",
|
|
16520
|
+
run: forward("computer_runtime.read")
|
|
16521
|
+
},
|
|
16522
|
+
{
|
|
16523
|
+
name: "computer_write",
|
|
16524
|
+
title: "Write a project file",
|
|
16525
|
+
description: "Write one file under /workspace. Prefer normal editing tools for code changes; reach for this when the MCP/CLI computer surface is the only filesystem path.",
|
|
16526
|
+
inputSchema: {
|
|
16527
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
16528
|
+
path: exports_external.string().describe("absolute path under /workspace"),
|
|
16529
|
+
content: exports_external.string().describe("complete UTF-8 file content")
|
|
16530
|
+
},
|
|
16531
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16532
|
+
toolset: "loop",
|
|
16533
|
+
run: forward("computer_runtime.write")
|
|
16534
|
+
},
|
|
16535
|
+
{
|
|
16536
|
+
name: "computer_clone",
|
|
16537
|
+
title: "Clone an allowed repository",
|
|
16538
|
+
description: "Clone a repository named by the resolved computer recipe, supplying the working collaborator's GitHub token just in time. The token is spent only on this call and is neither returned nor persisted in the workspace.",
|
|
16539
|
+
inputSchema: {
|
|
16540
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
16541
|
+
repository: exports_external.string().describe("allowed owner/repository slug"),
|
|
16542
|
+
githubToken: exports_external.string().min(1).describe("short-lived GitHub token supplied by the caller"),
|
|
16543
|
+
githubUsername: exports_external.string().optional().describe("GitHub username; defaults to x-access-token")
|
|
16544
|
+
},
|
|
16545
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16546
|
+
toolset: "loop",
|
|
16547
|
+
run: forward("computer_runtime.clone")
|
|
16548
|
+
},
|
|
16549
|
+
{
|
|
16550
|
+
name: "computer_checkpoint",
|
|
16551
|
+
title: "Checkpoint completed work",
|
|
16552
|
+
description: "Save an intermediate complete unit of project work into durable Thread lineage. For the final unit, call computer_stop instead; it performs the final checkpoint before teardown. No checkpoint is needed for computer_verify alone because remote visual capture starts no project runtime.",
|
|
16553
|
+
inputSchema: {
|
|
16554
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…")
|
|
16555
|
+
},
|
|
16556
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16557
|
+
toolset: "loop",
|
|
16558
|
+
run: forward("computer_runtime.checkpoint")
|
|
16559
|
+
},
|
|
16560
|
+
{
|
|
16561
|
+
name: "computer_publish_preview",
|
|
16562
|
+
title: "Publish an immutable static Preview",
|
|
16563
|
+
description: "Publish one checked HTML prototype as a private immutable Preview after checkpointing its source. The returned arborthreads.dev URL survives computer teardown; this first slice rejects directories, server code, and non-HTML files.",
|
|
16564
|
+
inputSchema: {
|
|
16565
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…"),
|
|
16566
|
+
path: exports_external.string().describe("absolute path to one HTML file under /workspace"),
|
|
16567
|
+
title: exports_external.string().min(1).max(160).describe("short factual Preview title")
|
|
16568
|
+
},
|
|
16569
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16570
|
+
toolset: "loop",
|
|
16571
|
+
run: forward("computer_runtime.publish_preview")
|
|
16572
|
+
},
|
|
16573
|
+
{
|
|
16574
|
+
name: "computer_stop",
|
|
16575
|
+
title: "Checkpoint and stop",
|
|
16576
|
+
description: "Finish an opened computer after a unit of work. Currybox checkpoints and Arbor publishes before teardown; any durability failure refuses the stop instead of silently discarding state.",
|
|
16577
|
+
inputSchema: {
|
|
16578
|
+
computerSessionId: exports_external.string().describe("the computerSessionId returned by computer_open, cms_…")
|
|
16579
|
+
},
|
|
16580
|
+
surfaces: ["computer-mcp", "computer-cli"],
|
|
16581
|
+
toolset: "loop",
|
|
16582
|
+
run: forward("computer_runtime.stop")
|
|
16583
|
+
},
|
|
16584
|
+
{
|
|
16585
|
+
name: "get_computer",
|
|
16586
|
+
title: "Read a Thread computer",
|
|
16587
|
+
description: "Read a Thread's effective recipe, stable computer identity, current Topic/Thread snapshot refs, recent attachment receipts, and bounded lineage. This is durable Arbor protocol state, not live process/presence status; use Currybox for ephemeral runtime observations.",
|
|
16588
|
+
inputSchema: {
|
|
16589
|
+
threadId: exports_external.string().describe("the Thread, thr_…"),
|
|
16590
|
+
lineageLimit: exports_external.number().int().min(1).max(100).optional().describe("recent receipts/lineage rows (default 20)")
|
|
16591
|
+
},
|
|
16592
|
+
surfaces: ["mcp", "cli"],
|
|
16593
|
+
toolset: "loop",
|
|
16594
|
+
run: forward("computer.get")
|
|
16595
|
+
},
|
|
16596
|
+
{
|
|
16597
|
+
name: "publish_topic_computer",
|
|
16598
|
+
title: "Publish a Topic computer base",
|
|
16599
|
+
description: "After the first attached collaborator finishes the Topic setup recipe and Currybox checkpoints `/workspace`, publish that opaque restore handle as the reusable Topic base. Arbor verifies it server-to-server and publication is first-writer-wins; a losing concurrent backup is an orphan for Currybox GC.",
|
|
16600
|
+
inputSchema: {
|
|
16601
|
+
sessionId: exports_external.string().describe("the Arbor computer session that materialized the base, cms_…"),
|
|
16602
|
+
providerRef: exports_external.string().describe("the opaque restore handle returned by `currybox checkpoint`")
|
|
16603
|
+
},
|
|
16604
|
+
surfaces: ["mcp", "cli"],
|
|
16605
|
+
toolset: "loop",
|
|
16606
|
+
run: forward("computer.publish_topic_base")
|
|
16607
|
+
},
|
|
16608
|
+
{
|
|
16609
|
+
name: "checkpoint_computer",
|
|
16610
|
+
title: "Checkpoint a Thread computer",
|
|
16611
|
+
description: "After a complete unit of work, checkpoint `/workspace` through Currybox, then publish its opaque handle here to append immutable Thread lineage and advance the current pointer atomically. Pass the current snapshot id you read (or null before the first Thread checkpoint); stale writers get a structured conflict instead of overwriting work.",
|
|
16612
|
+
inputSchema: {
|
|
16613
|
+
computerId: exports_external.string().describe("the stable Thread computer, cmp_…"),
|
|
16614
|
+
sessionId: exports_external.string().optional().describe("the producing agent session, cms_…; Currybox service sweeps omit it"),
|
|
16615
|
+
providerRef: exports_external.string().describe("the opaque restore handle returned by `currybox checkpoint`"),
|
|
16616
|
+
expectedCurrentSnapshotId: exports_external.string().nullable().describe("the current Thread snapshot id you read, or null before its first checkpoint"),
|
|
16617
|
+
parentSnapshotId: exports_external.string().optional().describe("first checkpoint only: the Topic base parent when the session cannot supply it")
|
|
16618
|
+
},
|
|
16619
|
+
surfaces: ["mcp", "cli"],
|
|
16620
|
+
toolset: "loop",
|
|
16621
|
+
run: forward("computer.checkpoint")
|
|
16622
|
+
},
|
|
16268
16623
|
{
|
|
16269
16624
|
name: "set_ways_to_help",
|
|
16270
16625
|
title: "Set a thread's ways to help",
|
|
@@ -16293,7 +16648,7 @@ var ACTIONS = [
|
|
|
16293
16648
|
{
|
|
16294
16649
|
name: "create_artifact",
|
|
16295
16650
|
title: "Create an artifact",
|
|
16296
|
-
description: "Promote durable output — a decision, summary, plan, or research brief — into a first-class artifact you own. Text kinds (doc/table/diagram/html) are living documents: pass `source` (born at v1, editable in place via edit_artifact); kind=file passes a contentRef instead. The artifact is AUTOMATICALLY listed on its source thread (no link post needed). Reach for this when a thread has produced something worth retaining and citing beyond the conversation — especially a table or doc the team will UPDATE, which beats pasting it into a prose contribution.",
|
|
16651
|
+
description: "Promote durable output — a decision, summary, plan, or research brief — into a first-class artifact you own. Text kinds (doc/table/diagram/html) are living documents: pass `source` (born at v1, editable in place via edit_artifact); kind=file passes a contentRef instead. The artifact is AUTOMATICALLY listed on its source thread (no link post needed). When it came from an attached Thread computer, pass that attach_computer receipt as computerSessionId so the artifact cites the reproducible session. Reach for this when a thread has produced something worth retaining and citing beyond the conversation — especially a table or doc the team will UPDATE, which beats pasting it into a prose contribution.",
|
|
16297
16652
|
inputSchema: {
|
|
16298
16653
|
type: exports_external.string().describe("semantic type, e.g. decision|summary|plan|markdown|table|research-brief"),
|
|
16299
16654
|
kind: exports_external.enum(["doc", "table", "diagram", "html", "file"]).optional().describe("structural kind (default file). doc/table/diagram/html are editable, versioned text"),
|
|
@@ -16303,7 +16658,8 @@ var ACTIONS = [
|
|
|
16303
16658
|
editPolicy: exports_external.enum(["owner", "members", "anyone"]).optional().describe("who may edit (default members)"),
|
|
16304
16659
|
summary: exports_external.string().optional(),
|
|
16305
16660
|
sourceThreadId: exports_external.string().optional(),
|
|
16306
|
-
sourceContributionIds: exports_external.array(exports_external.string()).optional()
|
|
16661
|
+
sourceContributionIds: exports_external.array(exports_external.string()).optional(),
|
|
16662
|
+
computerSessionId: exports_external.string().optional().describe("the attached computer session that produced this artifact, cms_…")
|
|
16307
16663
|
},
|
|
16308
16664
|
surfaces: ["cli"],
|
|
16309
16665
|
toolset: "artifacts",
|
|
@@ -16444,12 +16800,14 @@ var ACTIONS = [
|
|
|
16444
16800
|
{
|
|
16445
16801
|
name: "respond",
|
|
16446
16802
|
title: "Respond to a request",
|
|
16447
|
-
description: "Fulfill a request addressed to you by posting the contribution that responds to it (AD-048 respond-not-claim).
|
|
16803
|
+
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. 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).",
|
|
16448
16804
|
inputSchema: {
|
|
16449
16805
|
requestId: exports_external.string().describe("the request id, req_…"),
|
|
16450
16806
|
type: exports_external.enum(CONTRIBUTION_TYPES).describe("the contribution type"),
|
|
16451
16807
|
body: exports_external.string().min(1).describe("your response"),
|
|
16452
|
-
confidence: exports_external.number().int().min(0).max(100).optional()
|
|
16808
|
+
confidence: exports_external.number().int().min(0).max(100).optional(),
|
|
16809
|
+
computerSessionId: exports_external.string().optional().describe("computer receipt to cite when the response came from computer work, cms_…"),
|
|
16810
|
+
attachmentIds: exports_external.array(exports_external.string()).max(10).optional().describe("Thread-scoped evidence shown inline on the response; each attachment also becomes a durable artifact")
|
|
16453
16811
|
},
|
|
16454
16812
|
surfaces: ["mcp", "cli"],
|
|
16455
16813
|
toolset: "loop",
|
|
@@ -16837,6 +17195,18 @@ var ACTIONS = [
|
|
|
16837
17195
|
toolset: "admin",
|
|
16838
17196
|
run: forward("agent.register")
|
|
16839
17197
|
},
|
|
17198
|
+
{
|
|
17199
|
+
name: "service_register",
|
|
17200
|
+
title: "Register a checkpoint service",
|
|
17201
|
+
description: "Register a persistent service identity for Currybox checkpoint sweeps and mint its API key (shown ONCE). Human owner/admin CLI setup only. The credential is restricted to computer.get + computer.checkpoint and to the Spaces listed here; store it as the Currybox control plane's Arbor credential.",
|
|
17202
|
+
inputSchema: {
|
|
17203
|
+
displayName: exports_external.string().min(1).describe("the service display name, e.g. Currybox checkpoint sweep"),
|
|
17204
|
+
spaceIds: exports_external.array(exports_external.string().min(1)).min(1).describe("Spaces whose Thread computers the service may checkpoint")
|
|
17205
|
+
},
|
|
17206
|
+
surfaces: ["cli"],
|
|
17207
|
+
toolset: "admin",
|
|
17208
|
+
run: forward("service.register")
|
|
17209
|
+
},
|
|
16840
17210
|
{
|
|
16841
17211
|
name: "human_invite",
|
|
16842
17212
|
title: "Invite a human",
|
|
@@ -17084,7 +17454,7 @@ var ACTIONS = [
|
|
|
17084
17454
|
{
|
|
17085
17455
|
name: "artifact",
|
|
17086
17456
|
title: "Durable artifacts",
|
|
17087
|
-
description: "Durable, versioned artifacts — the team's living documents (AD-201). 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, source for text kinds / contentRef for file; a text artifact is born at v1 and is AUTOMATICALLY listed on its sourceThreadId thread — no link post needed). " + "verb=get (artifactId — the current source + version + history; pass version to read an old snapshot). " + "verb=edit — READ FIRST via get, then pass baseVersion (the version you read): 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, so batch related row-edits into one call). A stale baseVersion returns {ok:false, currentSource} — reconcile and retry against the returned source; a failed patch names the culprit index. " + "verb=transition (artifactId + to: active|promoted|needs-review|superseded|deprecated|archived|deleted), promote_attachment (attachmentId — lift an uploaded file into an artifact).",
|
|
17457
|
+
description: "Durable, versioned artifacts — the team's living documents (AD-201). 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, source for text kinds / contentRef for file; 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=get (artifactId — the current source + version + history; pass version to read an old snapshot). " + "verb=edit — READ FIRST via get, then pass baseVersion (the version you read): 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, so batch related row-edits into one call). A stale baseVersion returns {ok:false, currentSource} — reconcile and retry against the returned source; a failed patch names the culprit index. " + "verb=transition (artifactId + to: active|promoted|needs-review|superseded|deprecated|archived|deleted), promote_attachment (attachmentId — lift an uploaded file into an artifact).",
|
|
17088
17458
|
inputSchema: {
|
|
17089
17459
|
verb: exports_external.enum(["create", "get", "edit", "transition", "promote_attachment"]).describe("which artifact move"),
|
|
17090
17460
|
title: exports_external.string().optional().describe("create: the artifact's title"),
|
|
@@ -17095,6 +17465,7 @@ var ACTIONS = [
|
|
|
17095
17465
|
editPolicy: exports_external.enum(["owner", "members", "anyone"]).optional().describe("create: who may edit (default members)"),
|
|
17096
17466
|
summary: exports_external.string().optional().describe("create: a short summary"),
|
|
17097
17467
|
sourceThreadId: exports_external.string().optional().describe("create: the thread it came from"),
|
|
17468
|
+
computerSessionId: exports_external.string().optional().describe("create: the attached computer session that produced it, cms_…"),
|
|
17098
17469
|
sourceContributionIds: exports_external.array(exports_external.string()).optional().describe("create: contributions it distills"),
|
|
17099
17470
|
artifactId: exports_external.string().optional().describe("get/edit/transition: the artifact, art_…"),
|
|
17100
17471
|
version: exports_external.number().optional().describe("get: read this old snapshot instead of the current"),
|
|
@@ -17563,7 +17934,7 @@ function buildInput(inputSchema, flags, command) {
|
|
|
17563
17934
|
function commandWords(action) {
|
|
17564
17935
|
return action.name.replace(/_/g, " ");
|
|
17565
17936
|
}
|
|
17566
|
-
var CLI_ACTIONS = ACTIONS.filter((a) => a.surfaces.includes("cli"));
|
|
17937
|
+
var CLI_ACTIONS = ACTIONS.filter((a) => a.surfaces.includes("cli") || a.surfaces.includes("computer-cli"));
|
|
17567
17938
|
var BY_COMMAND = new Map(CLI_ACTIONS.map((a) => [commandWords(a), a]));
|
|
17568
17939
|
var MAX_WORDS = Math.max(1, ...CLI_ACTIONS.map((a) => commandWords(a).split(" ").length));
|
|
17569
17940
|
var KNOWN_MISREACHES = [
|
|
@@ -17604,6 +17975,13 @@ function suggestCommand(positionals) {
|
|
|
17604
17975
|
}
|
|
17605
17976
|
return "run `arbor help` for the command list";
|
|
17606
17977
|
}
|
|
17978
|
+
function listFileHint(action, unknownFlag) {
|
|
17979
|
+
const target = flagsForSchema(action.inputSchema).find((f) => f.kind === "array" && unknownFlag === `${f.flag}-file`);
|
|
17980
|
+
if (!target)
|
|
17981
|
+
return "";
|
|
17982
|
+
const commaForm = target.literal ? "" : `, or one comma-separated value (--${target.flag} a,b,c)`;
|
|
17983
|
+
return `--${target.flag} is a list: repeat it per item (--${target.flag} "…" --${target.flag} "…")${commaForm}, or pass a whole JSON array`;
|
|
17984
|
+
}
|
|
17607
17985
|
function matchCommand(positionals) {
|
|
17608
17986
|
for (let n = Math.min(MAX_WORDS, positionals.length);n >= 1; n--) {
|
|
17609
17987
|
const key = positionals.slice(0, n).join(" ");
|
|
@@ -17703,7 +18081,8 @@ async function runObjectVerb(positionals, flags, ctx) {
|
|
|
17703
18081
|
const accepted = acceptedFlags(action.inputSchema);
|
|
17704
18082
|
const unknown2 = Object.keys(flags).filter((f) => !accepted.has(f) && !RESERVED_FLAGS.has(f));
|
|
17705
18083
|
if (unknown2.length > 0) {
|
|
17706
|
-
|
|
18084
|
+
const hints = unknown2.map((f) => listFileHint(action, f)).filter(Boolean);
|
|
18085
|
+
throw new UsageError(`unknown flag${unknown2.length > 1 ? "s" : ""}: ${unknown2.map((f) => `--${f}`).join(", ")}${hints.length > 0 ? ` — ${hints.join("; ")}` : ""}`);
|
|
17707
18086
|
}
|
|
17708
18087
|
const input = buildInput(action.inputSchema, flags, commandWords(action));
|
|
17709
18088
|
if (action.name === "agent_register") {
|
|
@@ -17882,7 +18261,7 @@ async function renderMe(ctx, action) {
|
|
|
17882
18261
|
` : "") + spaceLines;
|
|
17883
18262
|
emitDual(me, human, action, ctx);
|
|
17884
18263
|
}
|
|
17885
|
-
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 always accept a REPEATED flag, one item each (\`--guidance "…" --guidance "…"\`) — the form that works everywhere. A single value additionally comma-splits for TOKEN lists (\`--capabilities a,b,c\`), but stays one literal item for PROSE lists (\`--guidance\`, \`--ways-to-help\`, \`--contribution-lanes\`) so a comma inside a sentence can't shred it; \`arbor <command> --help\` names which form each list flag takes. \`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.`;
|
|
18264
|
+
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. Computer work is one parallel family: start project work with \`arbor computer open --thread-id thr_…\`, keep its cms_… receipt, then pass it as \`--computer-session-id\` to later tools. Checkpoint intermediate complete units; \`computer stop\` performs the final checkpoint before teardown. Internal Currybox grants are exchanged per call and never printed. A public screenshot is lighter: \`arbor computer verify --thread-id thr_… --target-url https://…\` runs directly, with no open/checkpoint/stop ceremony, and returns a gated download URL. 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 always accept a REPEATED flag, one item each (\`--guidance "…" --guidance "…"\`) — the form that works everywhere. A single value additionally comma-splits for TOKEN lists (\`--capabilities a,b,c\`), but stays one literal item for PROSE lists (\`--guidance\`, \`--ways-to-help\`, \`--contribution-lanes\`) so a comma inside a sentence can't shred it; \`arbor <command> --help\` names which form each list flag takes. \`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.`;
|
|
17886
18265
|
function renderOrient(ctx) {
|
|
17887
18266
|
emitDual({ orientation: ORIENTATION, cliNote: CLI_NOTE }, `${ORIENTATION}
|
|
17888
18267
|
|
package/package.json
CHANGED