@lambdacurry/arbor 0.22.35 → 0.22.37
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 +137 -8
- package/package.json +1 -1
package/dist/arbor.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// package.json
|
|
3
3
|
var package_default = {
|
|
4
4
|
name: "@lambdacurry/arbor",
|
|
5
|
-
version: "0.22.
|
|
5
|
+
version: "0.22.37",
|
|
6
6
|
description: "The Arbor CLI — a shared workspace for people and agents. The human + headless-agent write path over Arbor's guarded operation surface.",
|
|
7
7
|
keywords: [
|
|
8
8
|
"agents",
|
|
@@ -4933,6 +4933,41 @@ var CONTRIBUTION_TYPES = [
|
|
|
4933
4933
|
"decision"
|
|
4934
4934
|
];
|
|
4935
4935
|
var STAMP_FACETS = ["quality", "impact", "fit", "originality"];
|
|
4936
|
+
var ARTIFACT_TYPES = [
|
|
4937
|
+
"markdown",
|
|
4938
|
+
"concept",
|
|
4939
|
+
"decision",
|
|
4940
|
+
"research-brief",
|
|
4941
|
+
"summary",
|
|
4942
|
+
"plan",
|
|
4943
|
+
"json",
|
|
4944
|
+
"yaml",
|
|
4945
|
+
"schema",
|
|
4946
|
+
"table",
|
|
4947
|
+
"rubric",
|
|
4948
|
+
"profile-snapshot",
|
|
4949
|
+
"image",
|
|
4950
|
+
"diagram",
|
|
4951
|
+
"mockup",
|
|
4952
|
+
"canvas",
|
|
4953
|
+
"html-bundle",
|
|
4954
|
+
"dashboard",
|
|
4955
|
+
"prototype",
|
|
4956
|
+
"audio",
|
|
4957
|
+
"video",
|
|
4958
|
+
"transcript",
|
|
4959
|
+
"diff",
|
|
4960
|
+
"pr-reference",
|
|
4961
|
+
"script",
|
|
4962
|
+
"api-spec",
|
|
4963
|
+
"test-plan",
|
|
4964
|
+
"prompt",
|
|
4965
|
+
"tool-spec",
|
|
4966
|
+
"workflow",
|
|
4967
|
+
"routing-rule",
|
|
4968
|
+
"eval-rubric",
|
|
4969
|
+
"external-reference"
|
|
4970
|
+
];
|
|
4936
4971
|
// ../core/src/feedback/constants.ts
|
|
4937
4972
|
var ARBOR_FEEDBACK_TYPES = [
|
|
4938
4973
|
"comment",
|
|
@@ -6284,14 +6319,17 @@ var profiles = sqliteTable("profiles", {
|
|
|
6284
6319
|
permissions: text("permissions", { mode: "json" }).$type().notNull().default([]),
|
|
6285
6320
|
reputation: text("reputation", { mode: "json" }).$type().notNull().default({}),
|
|
6286
6321
|
status: text("status").$type().notNull().default("active"),
|
|
6287
|
-
betterAuthUserId: text("better_auth_user_id")
|
|
6322
|
+
betterAuthUserId: text("better_auth_user_id"),
|
|
6288
6323
|
managedByProfileId: text("managed_by_profile_id"),
|
|
6289
6324
|
color: text("color").$type(),
|
|
6290
6325
|
emoji: text("emoji"),
|
|
6291
6326
|
description: text("description"),
|
|
6292
6327
|
notificationPrefs: text("notification_prefs", { mode: "json" }).$type(),
|
|
6293
6328
|
createdAt: ts("created_at").notNull()
|
|
6294
|
-
}, (t) => ({
|
|
6329
|
+
}, (t) => ({
|
|
6330
|
+
orgIdx: index("profiles_org_idx").on(t.orgId),
|
|
6331
|
+
baUserOrgUq: uniqueIndex("profiles_better_auth_user_org_unique").on(t.betterAuthUserId, t.orgId)
|
|
6332
|
+
}));
|
|
6295
6333
|
var clients = sqliteTable("clients", {
|
|
6296
6334
|
id: text("id").primaryKey(),
|
|
6297
6335
|
kind: text("kind").$type().notNull(),
|
|
@@ -6360,6 +6398,17 @@ var invitations = sqliteTable("invitations", {
|
|
|
6360
6398
|
emailIdx: index("invitations_email_idx").on(t.email, t.status),
|
|
6361
6399
|
tokenIdx: uniqueIndex("invitations_token_idx").on(t.token)
|
|
6362
6400
|
}));
|
|
6401
|
+
var humanSessionBindings = sqliteTable("human_session_bindings", {
|
|
6402
|
+
sessionId: text("session_id").primaryKey(),
|
|
6403
|
+
activeProfileId: text("active_profile_id").notNull(),
|
|
6404
|
+
updatedAt: ts("updated_at").notNull()
|
|
6405
|
+
}, (t) => ({ profileIdx: index("human_session_bindings_profile_idx").on(t.activeProfileId) }));
|
|
6406
|
+
var oauthClientBindings = sqliteTable("oauth_client_bindings", {
|
|
6407
|
+
userId: text("user_id").notNull(),
|
|
6408
|
+
clientId: text("client_id").notNull(),
|
|
6409
|
+
profileId: text("profile_id").notNull(),
|
|
6410
|
+
createdAt: ts("created_at").notNull()
|
|
6411
|
+
}, (t) => ({ pk: primaryKey({ columns: [t.userId, t.clientId] }) }));
|
|
6363
6412
|
var agentPairings = sqliteTable("agent_pairings", {
|
|
6364
6413
|
id: text("id").primaryKey(),
|
|
6365
6414
|
orgId: text("org_id").notNull().references(() => orgs.id),
|
|
@@ -8637,9 +8686,30 @@ var MCP_OUTPUT_SCHEMAS = {
|
|
|
8637
8686
|
profile: profile2,
|
|
8638
8687
|
client: looseObject({ id, kind: string2() }),
|
|
8639
8688
|
platform: looseObject({ level: string2() }).optional(),
|
|
8689
|
+
memberships: array(jsonObject).optional(),
|
|
8690
|
+
pendingInvites: array(jsonObject).optional(),
|
|
8640
8691
|
spaceCharters: array(jsonObject).optional(),
|
|
8641
8692
|
completeness: jsonObject.optional()
|
|
8642
8693
|
}),
|
|
8694
|
+
org_switch: looseObject({
|
|
8695
|
+
profile: jsonObject,
|
|
8696
|
+
memberships: array(jsonObject)
|
|
8697
|
+
}),
|
|
8698
|
+
invitation_accept: looseObject({
|
|
8699
|
+
profileId: id,
|
|
8700
|
+
orgId: id,
|
|
8701
|
+
orgName: string2().nullable(),
|
|
8702
|
+
orgRole: string2()
|
|
8703
|
+
}),
|
|
8704
|
+
org_create: looseObject({
|
|
8705
|
+
orgId: id,
|
|
8706
|
+
profileId: id,
|
|
8707
|
+
name: string2()
|
|
8708
|
+
}),
|
|
8709
|
+
org_leave: looseObject({
|
|
8710
|
+
leftProfileId: id,
|
|
8711
|
+
locked: boolean2()
|
|
8712
|
+
}),
|
|
8643
8713
|
introduce: profileMutation,
|
|
8644
8714
|
thread_get: looseObject({
|
|
8645
8715
|
threadId: id.optional(),
|
|
@@ -9807,6 +9877,10 @@ var MCP_TOOL_ANNOTATIONS = {
|
|
|
9807
9877
|
inbox: readOnly,
|
|
9808
9878
|
dismiss: destructive,
|
|
9809
9879
|
whoami: readOnly,
|
|
9880
|
+
org_switch: idempotent,
|
|
9881
|
+
invitation_accept: additive,
|
|
9882
|
+
org_create: additive,
|
|
9883
|
+
org_leave: destructive,
|
|
9810
9884
|
introduce: additive,
|
|
9811
9885
|
thread_get: readOnly,
|
|
9812
9886
|
tree: readOnly,
|
|
@@ -10123,6 +10197,7 @@ var TLDRAW_EXEC_OPERATIONS_SCHEMA = array(TLDRAW_EXEC_OPERATION_SCHEMA).min(1).m
|
|
|
10123
10197
|
});
|
|
10124
10198
|
}).describe("preferred declarative edits, applied in order; mutually exclusive with code");
|
|
10125
10199
|
// ../actions/src/index.ts
|
|
10200
|
+
var ARTIFACT_TYPE_DESCRIPTION = `semantic type (one of: ${ARTIFACT_TYPES.join(", ")})`;
|
|
10126
10201
|
var ARBOR_FEEDBACK_INPUT_TYPES = [...ARBOR_FEEDBACK_TYPES, "friction"];
|
|
10127
10202
|
var CONTRIBUTION_ADD_LINK_RELS = [
|
|
10128
10203
|
"cites",
|
|
@@ -11279,7 +11354,7 @@ var ACTION_DEFINITIONS = [
|
|
|
11279
11354
|
title: "Create an artifact",
|
|
11280
11355
|
description: "Promote durable output — a decision, summary, plan, or research brief — into a first-class artifact you own. Give it a concise summary of what the Artifact is or accomplishes; this is the skim and retrieval description, not a repeat of its title. 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 a Thread Computer, pass its producing computerSessionId when available 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.",
|
|
11281
11356
|
inputSchema: {
|
|
11282
|
-
type:
|
|
11357
|
+
type: _enum(ARTIFACT_TYPES).describe(ARTIFACT_TYPE_DESCRIPTION),
|
|
11283
11358
|
kind: _enum(["doc", "table", "diagram", "html", "file"]).optional().describe("structural kind (default file). doc/table/diagram/html are editable, versioned text"),
|
|
11284
11359
|
title: string2().min(1),
|
|
11285
11360
|
source: string2().optional().describe("text kinds: the initial content (v1)"),
|
|
@@ -11544,7 +11619,7 @@ var ACTION_DEFINITIONS = [
|
|
|
11544
11619
|
{
|
|
11545
11620
|
name: "whoami",
|
|
11546
11621
|
title: "Who am I",
|
|
11547
|
-
description: "Return your
|
|
11622
|
+
description: "Return your Arbor identity as resolved from your credential: which profile and org you're acting as, and which other orgs you can switch to on a human session.",
|
|
11548
11623
|
inputSchema: {},
|
|
11549
11624
|
surfaces: ["mcp", "cli"],
|
|
11550
11625
|
toolset: "loop",
|
|
@@ -11872,6 +11947,50 @@ var ACTION_DEFINITIONS = [
|
|
|
11872
11947
|
toolset: "admin",
|
|
11873
11948
|
run: forward("service.register")
|
|
11874
11949
|
},
|
|
11950
|
+
{
|
|
11951
|
+
name: "org_switch",
|
|
11952
|
+
title: "Switch workspace",
|
|
11953
|
+
description: "Act as your Profile in another org you already belong to (orgId from whoami's memberships). Session-only, not a PAT.",
|
|
11954
|
+
inputSchema: {
|
|
11955
|
+
orgId: string2().min(1).describe("the org to switch this session into")
|
|
11956
|
+
},
|
|
11957
|
+
surfaces: ["mcp", "cli"],
|
|
11958
|
+
toolset: "loop",
|
|
11959
|
+
run: forward("org.switch")
|
|
11960
|
+
},
|
|
11961
|
+
{
|
|
11962
|
+
name: "invitation_accept",
|
|
11963
|
+
title: "Accept an org invitation",
|
|
11964
|
+
description: "Join another org from a pending invitation while already signed in (invitationId from whoami's pendingInvites). Session-only, not a PAT.",
|
|
11965
|
+
inputSchema: {
|
|
11966
|
+
invitationId: string2().min(1).describe("the pending invitation id")
|
|
11967
|
+
},
|
|
11968
|
+
surfaces: ["mcp", "cli"],
|
|
11969
|
+
toolset: "loop",
|
|
11970
|
+
run: forward("invitation.accept")
|
|
11971
|
+
},
|
|
11972
|
+
{
|
|
11973
|
+
name: "org_create",
|
|
11974
|
+
title: "Create a workspace",
|
|
11975
|
+
description: "Create a new org you own (a personal workspace) and switch this session into it. Session-only, not a PAT.",
|
|
11976
|
+
inputSchema: {
|
|
11977
|
+
name: string2().min(1).optional().describe("workspace name; defaults to '{you}'s workspace'")
|
|
11978
|
+
},
|
|
11979
|
+
surfaces: ["mcp", "cli"],
|
|
11980
|
+
toolset: "loop",
|
|
11981
|
+
run: forward("org.create")
|
|
11982
|
+
},
|
|
11983
|
+
{
|
|
11984
|
+
name: "org_leave",
|
|
11985
|
+
title: "Leave a workspace",
|
|
11986
|
+
description: "Leave an org you belong to, disabling that Profile — keep at least one workspace, and appoint another owner before leaving a multi-person org. Session-only, not a PAT.",
|
|
11987
|
+
inputSchema: {
|
|
11988
|
+
orgId: string2().min(1).optional().describe("org to leave; defaults to the current org")
|
|
11989
|
+
},
|
|
11990
|
+
surfaces: ["cli"],
|
|
11991
|
+
toolset: "loop",
|
|
11992
|
+
run: forward("org.leave")
|
|
11993
|
+
},
|
|
11875
11994
|
{
|
|
11876
11995
|
name: "human_invite",
|
|
11877
11996
|
title: "Invite a human",
|
|
@@ -12188,7 +12307,7 @@ var ACTION_DEFINITIONS = [
|
|
|
12188
12307
|
verb: _enum(["create", "edit", "set_live_preview", "set_snapshot", "promote_attachment"]).describe("which artifact move"),
|
|
12189
12308
|
title: string2().optional().describe("create: the artifact's title"),
|
|
12190
12309
|
kind: _enum(["doc", "table", "diagram", "html", "file"]).optional().describe("create: structural kind (default file). doc/table/diagram/html are editable text"),
|
|
12191
|
-
type:
|
|
12310
|
+
type: _enum(ARTIFACT_TYPES).optional().describe(`create: ${ARTIFACT_TYPE_DESCRIPTION}`),
|
|
12192
12311
|
source: string2().optional().describe("create (text kinds): the initial content · edit verb=replace: the full new content"),
|
|
12193
12312
|
contentRef: string2().optional().describe("create (kind=file): where the content lives, e.g. inline://… or a URL"),
|
|
12194
12313
|
editPolicy: _enum(["owner", "members", "anyone"]).optional().describe("create: who may edit (default members)"),
|
|
@@ -14481,10 +14600,20 @@ async function renderMe(ctx, action) {
|
|
|
14481
14600
|
const setCharters = me.spaceCharters ?? [];
|
|
14482
14601
|
const charterLines = setCharters.length > 0 ? ` space charters:
|
|
14483
14602
|
` + setCharters.map((s) => ` • ${s.spaceTitle} — ${clamp(s.charter)}
|
|
14603
|
+
`).join("") : "";
|
|
14604
|
+
const currentOrg = me.memberships?.find((m) => m.current);
|
|
14605
|
+
const otherOrgs = (me.memberships ?? []).filter((m) => !m.current);
|
|
14606
|
+
const orgLine = currentOrg ? ` org ${currentOrg.orgName} (${me.profile.orgId}) · resolved via ${me.client.kind}
|
|
14607
|
+
` : ` org ${me.profile.orgId} · resolved via ${me.client.kind}
|
|
14608
|
+
`;
|
|
14609
|
+
const switchLines = otherOrgs.length > 0 ? ` other workspaces:
|
|
14610
|
+
` + otherOrgs.map((m) => ` • ${m.orgName} — \`org_switch --org-id ${m.orgId}\`
|
|
14611
|
+
`).join("") : "";
|
|
14612
|
+
const inviteLines = (me.pendingInvites ?? []).length > 0 ? ` pending invites:
|
|
14613
|
+
` + (me.pendingInvites ?? []).map((i) => ` • ${i.orgName} — \`invitation_accept --invitation-id ${i.invitationId}\`
|
|
14484
14614
|
`).join("") : "";
|
|
14485
14615
|
const human = `${me.profile.displayName} · ${me.profile.kind} · org-role ${me.profile.orgRole}
|
|
14486
|
-
` + `
|
|
14487
|
-
` + setLines + charterLines + (gaps.length > 0 ? ` to be more legible to your team, set: ${gaps.join("; ")} (\`introduce\`)
|
|
14616
|
+
` + orgLine + switchLines + inviteLines + setLines + charterLines + (gaps.length > 0 ? ` to be more legible to your team, set: ${gaps.join("; ")} (\`introduce\`)
|
|
14488
14617
|
` : "") + spaceLines;
|
|
14489
14618
|
emitDual(me, human, action, ctx);
|
|
14490
14619
|
}
|
package/package.json
CHANGED