bazilion 0.7.0 → 0.9.0
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/README.md +47 -5
- package/dist/cli.js +1257 -638
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +5334 -1594
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0001_init.sql +318 -88
- package/dist/web/client/assets/{FieldRow-CNKma5LE.js → FieldRow-DmwAFfbF.js} +1 -1
- package/dist/web/client/assets/ProductionTeamPolicyEditor-1a5jQqUB.js +7 -0
- package/dist/web/client/assets/ProductionTeamPolicyEditor-DLioOiRN.css +1 -0
- package/dist/web/client/assets/ProfileCommunicationEditor-D1OZ8WE5.js +1 -0
- package/dist/web/client/assets/RecoveryState-QfMSuwy3.js +1 -0
- package/dist/web/client/assets/TeamTabs-BViZ4sti.js +1 -0
- package/dist/web/client/assets/TemplatesTabs-DVcY9pMD.js +1 -0
- package/dist/web/client/assets/_id-8P7brhGy.js +1 -0
- package/dist/web/client/assets/_id-C3o3MHq8.js +1 -0
- package/dist/web/client/assets/_id-DGRrSF1e.js +1 -0
- package/dist/web/client/assets/_id-DGyKURCp.js +1 -0
- package/dist/web/client/assets/_id-KnJe-aW9.js +1 -0
- package/dist/web/client/assets/activity-DJuhhQCb.js +1 -0
- package/dist/web/client/assets/activity-WWvJSo4t.js +1 -0
- package/dist/web/client/assets/agents-C32T1voV.js +1 -0
- package/dist/web/client/assets/agents-nH4m4gZ1.js +1 -0
- package/dist/web/client/assets/approvals-DGi0PSx8.js +1 -0
- package/dist/web/client/assets/approvals-l8jIZjqz.js +1 -0
- package/dist/web/client/assets/{config-BSAVT-17.js → config-C7wvi1nR.js} +2 -2
- package/dist/web/client/assets/context-BEGWE3RC.js +1 -0
- package/dist/web/client/assets/inbox--4aBaAgG.js +1 -0
- package/dist/web/client/assets/index-BCXoh1c8.js +12 -0
- package/dist/web/client/assets/{login-D8lNr2SX.js → login-Bk2wwIHQ.js} +1 -1
- package/dist/web/client/assets/{mcp-BLnngDsj.js → mcp-vM7xgh9e.js} +1 -1
- package/dist/web/client/assets/members-cPKfnrSL.js +1 -0
- package/dist/web/client/assets/memory-BOcsaemD.js +1 -0
- package/dist/web/client/assets/policy-BGLCJYvS.js +1 -0
- package/dist/web/client/assets/policy-K4hIbbIN.js +1 -0
- package/dist/web/client/assets/{preload-helper-CvnapA2_.js → preload-helper-eOOCz1Fu.js} +1 -1
- package/dist/web/client/assets/routes-DnrP3dwv.js +1 -0
- package/dist/web/client/assets/services-C2_O3ifw.js +1 -0
- package/dist/web/client/assets/skills-B__fLZjx.js +1 -0
- package/dist/web/client/assets/styles-Dn24-ZvP.css +2 -0
- package/dist/web/client/assets/team-policy-BdX340m4.js +1 -0
- package/dist/web/client/assets/teams-CSNyLz3l.js +1 -0
- package/dist/web/client/assets/teams-DZMB4_iw.js +1 -0
- package/dist/web/client/assets/teams-rpaYKNIb.js +1 -0
- package/dist/web/client/assets/telegram-B1O4Ko0V.js +1 -0
- package/dist/web/client/assets/{tokens-D2_O9ARe.js → tokens-D7FH9VgA.js} +1 -1
- package/dist/web/client/assets/triggers-3PLy2_Fo.js +1 -0
- package/dist/web/client/assets/welcome-B-QQobzq.js +1 -0
- package/dist/web/client/assets/{ChatPane-DzEgOEqS.js → wire-constants-BY9Q9Z7d.js} +4 -4
- package/dist/web/server/assets/{ChatPane-BvpswYvF.js → ChatPane-Dh3qxzdb.js} +23 -12
- package/dist/web/server/assets/ProductionTeamPolicyEditor-Bke5doyl.js +1009 -0
- package/dist/web/server/assets/ProfileCommunicationEditor-C2RU-2QB.js +107 -0
- package/dist/web/server/assets/RecoveryState-B2SG-mrY.js +37 -0
- package/dist/web/server/assets/{Sidebar-DmEiewRN.js → Sidebar-CGmtCnYU.js} +372 -48
- package/dist/web/server/assets/TeamTabs-BPxDBfqy.js +50 -0
- package/dist/web/server/assets/{TemplatesTabs---7h5GYa.js → TemplatesTabs-zf4YhStd.js} +6 -6
- package/dist/web/server/assets/{_id-CXg-Blec.js → _id-5lLzLwcv.js} +52 -40
- package/dist/web/server/assets/_id-A8Xiv6Lc.js +11 -0
- package/dist/web/server/assets/{_id-BqnDy_Ca.js → _id-B04VaQlh.js} +6 -5
- package/dist/web/server/assets/{_id-D0ytyXGY.js → _id-B6g9wmPR.js} +167 -31
- package/dist/web/server/assets/_id-ButXHnRH.js +14 -0
- package/dist/web/server/assets/_id-C4AOhstq.js +44 -0
- package/dist/web/server/assets/{_id-DDixKEud.js → _id-CCHA0gdR.js} +72 -12
- package/dist/web/server/assets/{_id-D_Ew11ED.js → _id-CUWgTqMS.js} +8 -8
- package/dist/web/server/assets/_id-DJkzwHjM.js +42 -0
- package/dist/web/server/assets/{_id-CnQflrRv.js → _id-DdC9wpNN.js} +5 -5
- package/dist/web/server/assets/{_id-81NrHA5d.js → _id-DkFgCIb-.js} +9 -1
- package/dist/web/server/assets/{_id-D8duqgd5.js → _id-_nFwi9gD.js} +5 -4
- package/dist/web/server/assets/{_id-Sjw0zhA6.js → _id-fpFQ9_Ya.js} +4 -4
- package/dist/web/server/assets/_tanstack-start-manifest_v-Div-TukY.js +241 -0
- package/dist/web/server/assets/activity-C2ZKg1Q9.js +170 -0
- package/dist/web/server/assets/activity-CGCf8BQf.js +11 -0
- package/dist/web/server/assets/activity-DedraoFj.js +14 -0
- package/dist/web/server/assets/activity-GPx8NCeB.js +12 -0
- package/dist/web/server/assets/{profiles-CZ5NkmVw.js → agents-B8kinIPW.js} +4 -4
- package/dist/web/server/assets/{agents-k5QURC4I.js → agents-BR2qXlXF.js} +4 -4
- package/dist/web/server/assets/{agents-ChcAJUI5.js → agents-Bp1nsVs2.js} +1 -1
- package/dist/web/server/assets/{profiles-LxcC_L6n.js → agents-CUQmWhTp.js} +36 -10
- package/dist/web/server/assets/{agents-C7SBPN0M.js → agents-DU9Hqs58.js} +51 -12
- package/dist/web/server/assets/{profiles-C6a3RKgu.js → agents-LHowEI6S.js} +4 -4
- package/dist/web/server/assets/approvals-CbFXFvG8.js +11 -0
- package/dist/web/server/assets/approvals-DHgARzd8.js +242 -0
- package/dist/web/server/assets/approvals-Dw2LJoSA.js +14 -0
- package/dist/web/server/assets/approvals-VPc0YpLN.js +12 -0
- package/dist/web/server/assets/{auth-DzRAMwVt.js → auth-l-Vf8wlu.js} +5 -1
- package/dist/web/server/assets/{config-CdVjqjin.js → config-BvKctDOX.js} +4 -4
- package/dist/web/server/assets/{config-Bq3o924J.js → config-QvHaxGlP.js} +1 -1
- package/dist/web/server/assets/context-5lrf2ame.js +12 -0
- package/dist/web/server/assets/context-CEr4-xiA.js +49 -0
- package/dist/web/server/assets/context-D3Egm-vY.js +12 -0
- package/dist/web/server/assets/members-40DxRdVj.js +48 -0
- package/dist/web/server/assets/members-DlGBKZNl.js +12 -0
- package/dist/web/server/assets/members-ksELRsyk.js +12 -0
- package/dist/web/server/assets/{memory-Ns2-Z31p.js → memory-B5moRnnp.js} +5 -5
- package/dist/web/server/assets/{memory-BaYnfm7K.js → memory-CO0jKGzJ.js} +8 -8
- package/dist/web/server/assets/memory-CiTl4cN9.js +289 -0
- package/dist/web/server/assets/policy-BYVXqsan.js +11 -0
- package/dist/web/server/assets/policy-DNcGZLOB.js +21 -0
- package/dist/web/server/assets/policy-Dr55y-Mh.js +496 -0
- package/dist/web/server/assets/policy-Dxs78_GO.js +40 -0
- package/dist/web/server/assets/{router-BpBZgRwn.js → router-_izWQUeG.js} +156 -101
- package/dist/web/server/assets/{routes-Ce2VWrU9.js → routes-BSSKp3Rv.js} +4 -4
- package/dist/web/server/assets/{routes-C61gBiXa.js → routes-BrTOoeth.js} +5 -5
- package/dist/web/server/assets/{routes-V9URcp1v.js → routes-DOj6ljcm.js} +1 -1
- package/dist/web/server/assets/{services-B91w2f-X.js → services-CHe4ihJk.js} +11 -11
- package/dist/web/server/assets/{services-Ccc5s2bS.js → services-Pv_V88VA.js} +3 -3
- package/dist/web/server/assets/{skills-dLyBZb3B.js → skills-D89ND2kR.js} +67 -7
- package/dist/web/server/assets/{skills-CpsyR_WA.js → skills-l2cyQ3zS.js} +1 -1
- package/dist/web/server/assets/{start-CYDpZ6cb.js → start-DlHq0RaQ.js} +1 -1
- package/dist/web/server/assets/team-policy-Csvc5EDd.js +180 -0
- package/dist/web/server/assets/teams-35Oprf6e.js +14 -0
- package/dist/web/server/assets/teams-3im0oQnS.js +11 -0
- package/dist/web/server/assets/teams-B5IF65p2.js +12 -0
- package/dist/web/server/assets/teams-B9O-WDH5.js +108 -0
- package/dist/web/server/assets/teams-DFkN7ic7.js +36 -0
- package/dist/web/server/assets/teams-DH1CvWmT.js +12 -0
- package/dist/web/server/assets/teams-zcm9XaQU.js +174 -0
- package/dist/web/server/assets/{telegram-DfAddLdv.js → telegram-C9sQFwWj.js} +7 -7
- package/dist/web/server/assets/{telegram-T3l9KtiE.js → telegram-mTnJCOmn.js} +1 -1
- package/dist/web/server/assets/{welcome-CP4CZ9B6.js → welcome-CDGE2Sdk.js} +2 -2
- package/dist/web/server/assets/{wire-constants-Deb4NxBb.js → wire-constants-C8nBJcU3.js} +3 -3
- package/dist/web/server/server.js +64 -42
- package/dist/worker.js +180 -128
- package/dist/worker.js.map +1 -1
- package/package.json +7 -7
- package/dist/migrations/0002_profile_groups.sql +0 -38
- package/dist/migrations/0003_agent_telegram.sql +0 -40
- package/dist/migrations/0004_agent_mirror_mode.sql +0 -17
- package/dist/migrations/0005_group_topic_name_format.sql +0 -15
- package/dist/migrations/0006_telegram_acl.sql +0 -18
- package/dist/migrations/0007_mcp_servers.sql +0 -30
- package/dist/migrations/0008_seed_user_md.sql +0 -39
- package/dist/web/client/assets/MembersEditor-C6UpqDdV.js +0 -1
- package/dist/web/client/assets/SpawnTeamModal-BEkNCKXm.js +0 -1
- package/dist/web/client/assets/TemplatesTabs-Da7mg9FI.js +0 -1
- package/dist/web/client/assets/_id-BdKmo0gb.js +0 -1
- package/dist/web/client/assets/_id-LT6Ejjr0.js +0 -1
- package/dist/web/client/assets/_id-MR2XjWh0.js +0 -1
- package/dist/web/client/assets/_id-_6jIt0_-.js +0 -1
- package/dist/web/client/assets/agents-0arKbVYG.js +0 -1
- package/dist/web/client/assets/groups-BqTkhHes.js +0 -1
- package/dist/web/client/assets/inbox-ozoCXzr5.js +0 -1
- package/dist/web/client/assets/index-iayCEuU2.js +0 -12
- package/dist/web/client/assets/memory-D1GQjEvN.js +0 -1
- package/dist/web/client/assets/profile-groups-C2yJPTaE.js +0 -1
- package/dist/web/client/assets/profiles-BV7AAZjj.js +0 -1
- package/dist/web/client/assets/routes-DSHQLA7K.js +0 -1
- package/dist/web/client/assets/services-BbCJe1Du.js +0 -1
- package/dist/web/client/assets/skills-C6czKR5I.js +0 -1
- package/dist/web/client/assets/styles-C06axZZk.css +0 -2
- package/dist/web/client/assets/telegram-gE4j8gte.js +0 -1
- package/dist/web/client/assets/triggers-WljnfEfJ.js +0 -1
- package/dist/web/client/assets/welcome-Dn-zvmBE.js +0 -1
- package/dist/web/client/assets/wire-constants-BkT5-597.js +0 -1
- package/dist/web/server/assets/MembersEditor-BWQztvrX.js +0 -131
- package/dist/web/server/assets/SpawnTeamModal-dSN421k_.js +0 -107
- package/dist/web/server/assets/_id-BKev9H1p.js +0 -12
- package/dist/web/server/assets/_id-BNwlbWHP.js +0 -24
- package/dist/web/server/assets/_id-CRqqi8IE.js +0 -161
- package/dist/web/server/assets/_tanstack-start-manifest_v-DBlFH2gg.js +0 -178
- package/dist/web/server/assets/groups-CbSwND2r.js +0 -12
- package/dist/web/server/assets/groups-CeRRlZaZ.js +0 -150
- package/dist/web/server/assets/groups-pk4CYSuf.js +0 -21
- package/dist/web/server/assets/memory-CQaqWnyM.js +0 -284
- package/dist/web/server/assets/profile-groups-CiU06yN1.js +0 -28
- package/dist/web/server/assets/profile-groups-D21MYoLM.js +0 -208
- package/dist/web/server/assets/profile-groups-aoJleXHP.js +0 -12
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { defineCommand as
|
|
4
|
+
import { defineCommand as defineCommand25, runCommand, showUsage } from "citty";
|
|
5
5
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "bazilion",
|
|
9
|
-
version: "0.
|
|
10
|
-
description: "Multi-agent runtime CLI \u2014 spawn LLM agents, manage profiles/
|
|
9
|
+
version: "0.9.0",
|
|
10
|
+
description: "Multi-agent runtime CLI \u2014 spawn LLM agents, manage profiles/teams/skills, and run the local daemon.",
|
|
11
11
|
license: "MIT",
|
|
12
12
|
repository: {
|
|
13
13
|
type: "git",
|
|
@@ -49,9 +49,9 @@ var package_default = {
|
|
|
49
49
|
access: "public"
|
|
50
50
|
},
|
|
51
51
|
dependencies: {
|
|
52
|
-
"@earendil-works/pi-agent-core": "^0.
|
|
53
|
-
"@earendil-works/pi-ai": "^0.
|
|
54
|
-
"@earendil-works/pi-coding-agent": "^0.
|
|
52
|
+
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
53
|
+
"@earendil-works/pi-ai": "^0.80.6",
|
|
54
|
+
"@earendil-works/pi-coding-agent": "^0.80.6",
|
|
55
55
|
"@hono/node-server": "^2.0.6",
|
|
56
56
|
"@mozilla/readability": "^0.6.0",
|
|
57
57
|
"@tanstack/react-router": "1.170.16",
|
|
@@ -277,13 +277,13 @@ function asPaths(v) {
|
|
|
277
277
|
return v ? Array.isArray(v) ? v : [v] : [];
|
|
278
278
|
}
|
|
279
279
|
var spawnCmd = defineCommand({
|
|
280
|
-
meta: { name: "spawn", description: "Spawn an agent from a profile into a
|
|
280
|
+
meta: { name: "spawn", description: "Spawn an agent from a profile into a team" },
|
|
281
281
|
args: {
|
|
282
282
|
profile: { type: "string", required: true, description: "Profile id" },
|
|
283
283
|
name: { type: "string", description: "Agent name (defaults to profile name)" },
|
|
284
|
-
|
|
284
|
+
team: {
|
|
285
285
|
type: "string",
|
|
286
|
-
description: "
|
|
286
|
+
description: "Team to join (defaults to 'default')"
|
|
287
287
|
},
|
|
288
288
|
model: { type: "string", description: "Override profile default model" },
|
|
289
289
|
reasoning: {
|
|
@@ -293,14 +293,21 @@ var spawnCmd = defineCommand({
|
|
|
293
293
|
},
|
|
294
294
|
async run({ args }) {
|
|
295
295
|
const client = createClient2();
|
|
296
|
+
const teamId = args.team ?? "default";
|
|
297
|
+
const policy = await client.get(
|
|
298
|
+
`/api/teams/${encodeURIComponent(teamId)}/policy`
|
|
299
|
+
);
|
|
296
300
|
const body = {
|
|
297
301
|
profileId: args.profile,
|
|
298
302
|
name: args.name,
|
|
299
303
|
model: args.model,
|
|
300
304
|
reasoningLevel: args.reasoning,
|
|
301
|
-
|
|
305
|
+
teamId,
|
|
306
|
+
teamExpectedRevision: policy.teamPolicy.revision,
|
|
307
|
+
placement: "open"
|
|
302
308
|
};
|
|
303
|
-
const
|
|
309
|
+
const response = await client.post("/api/agents", body);
|
|
310
|
+
const agent = response.agent;
|
|
304
311
|
console.log(`spawned agent ${agent.id} (${agent.name})`);
|
|
305
312
|
console.log(`dir: ${agent.dir}`);
|
|
306
313
|
}
|
|
@@ -364,12 +371,12 @@ var listCmd = defineCommand({
|
|
|
364
371
|
async run({ args }) {
|
|
365
372
|
const client = createClient2();
|
|
366
373
|
const q = args.all ? "?includeArchived=true" : "";
|
|
367
|
-
const
|
|
368
|
-
if (
|
|
374
|
+
const list3 = await client.get(`/api/agents${q}`);
|
|
375
|
+
if (list3.length === 0) {
|
|
369
376
|
console.log("(no agents)");
|
|
370
377
|
return;
|
|
371
378
|
}
|
|
372
|
-
const rows =
|
|
379
|
+
const rows = list3.map(
|
|
373
380
|
(a) => args.long ? [a.id, a.status, a.name, a.profileId] : (
|
|
374
381
|
// Short UUID prefix — all CLI commands accept 4+ char prefixes now.
|
|
375
382
|
[a.id.slice(0, 8), a.status, a.name]
|
|
@@ -392,7 +399,7 @@ var showCmd = defineCommand({
|
|
|
392
399
|
console.log(`profile: ${r.profile.id}`);
|
|
393
400
|
console.log(`model: ${r.model}`);
|
|
394
401
|
console.log(`dir: ${r.agent.dir}`);
|
|
395
|
-
console.log(`
|
|
402
|
+
console.log(`team: ${r.team.id} ${r.team.path}`);
|
|
396
403
|
console.log("skills:");
|
|
397
404
|
if (r.skills.length === 0) {
|
|
398
405
|
console.log(" (none)");
|
|
@@ -430,7 +437,13 @@ var deleteCmd = defineCommand({
|
|
|
430
437
|
},
|
|
431
438
|
async run({ args }) {
|
|
432
439
|
const client = createClient2();
|
|
433
|
-
await client.
|
|
440
|
+
const agent = await client.get(`/api/agents/${encodeURIComponent(args.id)}`);
|
|
441
|
+
const policy = await client.get(
|
|
442
|
+
`/api/teams/${encodeURIComponent(agent.team.id)}/policy`
|
|
443
|
+
);
|
|
444
|
+
await client.del(
|
|
445
|
+
`/api/agents/${encodeURIComponent(args.id)}?expectedTeamRevision=${policy.teamPolicy.revision}`
|
|
446
|
+
);
|
|
434
447
|
console.log(`deleted agent ${args.id}`);
|
|
435
448
|
}
|
|
436
449
|
});
|
|
@@ -632,8 +645,8 @@ var chatContextCmd = defineCommand({
|
|
|
632
645
|
if (ctx.systemPrompt.skillsListChars > 0) {
|
|
633
646
|
console.log(` skills line: ${ctx.systemPrompt.skillsListChars.toLocaleString()} chars`);
|
|
634
647
|
}
|
|
635
|
-
if (ctx.systemPrompt.
|
|
636
|
-
console.log(`
|
|
648
|
+
if (ctx.systemPrompt.teamListChars > 0) {
|
|
649
|
+
console.log(` team block: ${ctx.systemPrompt.teamListChars.toLocaleString()} chars`);
|
|
637
650
|
}
|
|
638
651
|
if (ctx.systemPrompt.userMdChars > 0) {
|
|
639
652
|
console.log(` user_md block: ${ctx.systemPrompt.userMdChars.toLocaleString()} chars`);
|
|
@@ -662,10 +675,10 @@ var chatContextCmd = defineCommand({
|
|
|
662
675
|
}
|
|
663
676
|
console.log("");
|
|
664
677
|
}
|
|
665
|
-
console.log("##
|
|
666
|
-
console.log(` - ${ctx.
|
|
667
|
-
if (ctx.
|
|
668
|
-
console.log(` user_md: ${ctx.
|
|
678
|
+
console.log("## team");
|
|
679
|
+
console.log(` - ${ctx.team.id} (${ctx.team.name}): ${ctx.team.path}`);
|
|
680
|
+
if (ctx.team.userMdChars > 0) {
|
|
681
|
+
console.log(` user_md: ${ctx.team.userMdChars.toLocaleString()} chars`);
|
|
669
682
|
}
|
|
670
683
|
console.log("");
|
|
671
684
|
console.log("## history");
|
|
@@ -736,15 +749,38 @@ var skillAddCmd = defineCommand({
|
|
|
736
749
|
meta: { name: "add", description: "Attach a skill to an agent" },
|
|
737
750
|
args: {
|
|
738
751
|
agent: { type: "positional", required: true },
|
|
739
|
-
skill: { type: "positional", required: true }
|
|
752
|
+
skill: { type: "positional", required: true },
|
|
753
|
+
"allow-warnings": {
|
|
754
|
+
type: "boolean",
|
|
755
|
+
description: "Attach even when the static skill scan reports findings"
|
|
756
|
+
}
|
|
740
757
|
},
|
|
741
758
|
async run({ args }) {
|
|
742
759
|
const client = createClient2();
|
|
743
|
-
const body = { skill: args.skill };
|
|
744
|
-
|
|
760
|
+
const body = { skill: args.skill, allowFindings: args["allow-warnings"] };
|
|
761
|
+
try {
|
|
762
|
+
await client.post(`/api/agents/${args.agent}/skills`, body);
|
|
763
|
+
} catch (err) {
|
|
764
|
+
if (err instanceof ApiClientError && err.body.code === "skill_scan_blocked") {
|
|
765
|
+
console.error(`error: ${err.body.error}`);
|
|
766
|
+
printSkillFindings(err.body.findings ?? []);
|
|
767
|
+
console.error(" hint: inspect the skill, then rerun with --allow-warnings to confirm");
|
|
768
|
+
process.exitCode = 1;
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
throw err;
|
|
772
|
+
}
|
|
745
773
|
console.log(`attached skill ${args.skill} to ${args.agent}`);
|
|
746
774
|
}
|
|
747
775
|
});
|
|
776
|
+
function printSkillFindings(findings) {
|
|
777
|
+
if (findings.length === 0) return;
|
|
778
|
+
console.error("scan findings:");
|
|
779
|
+
for (const f of findings) {
|
|
780
|
+
const line = f.line ? ` line ${f.line}` : "";
|
|
781
|
+
console.error(` ${f.severity}: ${f.code}${line} - ${f.message}`);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
748
784
|
var skillRmCmd = defineCommand({
|
|
749
785
|
meta: { name: "rm", description: "Detach a skill from an agent" },
|
|
750
786
|
args: {
|
|
@@ -765,16 +801,28 @@ var skillCmd = defineCommand({
|
|
|
765
801
|
}
|
|
766
802
|
});
|
|
767
803
|
var moveCmd = defineCommand({
|
|
768
|
-
meta: { name: "move", description: "Move an agent to a different
|
|
804
|
+
meta: { name: "move", description: "Move an agent to a different team" },
|
|
769
805
|
args: {
|
|
770
806
|
agent: { type: "positional", required: true },
|
|
771
|
-
|
|
807
|
+
team: { type: "positional", required: true }
|
|
772
808
|
},
|
|
773
809
|
async run({ args }) {
|
|
774
810
|
const client = createClient2();
|
|
775
|
-
const
|
|
776
|
-
|
|
777
|
-
|
|
811
|
+
const [agent, destination] = await Promise.all([
|
|
812
|
+
client.get(`/api/agents/${encodeURIComponent(args.agent)}`),
|
|
813
|
+
client.get(`/api/teams/${encodeURIComponent(args.team)}/policy`)
|
|
814
|
+
]);
|
|
815
|
+
const source = await client.get(
|
|
816
|
+
`/api/teams/${encodeURIComponent(agent.team.id)}/policy`
|
|
817
|
+
);
|
|
818
|
+
const body = {
|
|
819
|
+
teamId: args.team,
|
|
820
|
+
sourceExpectedRevision: source.teamPolicy.revision,
|
|
821
|
+
destinationExpectedRevision: destination.teamPolicy.revision,
|
|
822
|
+
placement: "open"
|
|
823
|
+
};
|
|
824
|
+
await client.patch(`/api/agents/${args.agent}/team`, body);
|
|
825
|
+
console.log(`moved ${args.agent} to team ${args.team}`);
|
|
778
826
|
}
|
|
779
827
|
});
|
|
780
828
|
var sessionHeadCmd = defineCommand({
|
|
@@ -829,15 +877,102 @@ var agentCommand = defineCommand({
|
|
|
829
877
|
}
|
|
830
878
|
});
|
|
831
879
|
|
|
880
|
+
// src/commands/approval.ts
|
|
881
|
+
import { defineCommand as defineCommand2 } from "citty";
|
|
882
|
+
var list = defineCommand2({
|
|
883
|
+
meta: { name: "list", description: "List communication approval queue/history" },
|
|
884
|
+
args: {
|
|
885
|
+
status: { type: "string", default: "pending" },
|
|
886
|
+
team: { type: "string" },
|
|
887
|
+
json: { type: "boolean" }
|
|
888
|
+
},
|
|
889
|
+
async run({ args }) {
|
|
890
|
+
const query = new URLSearchParams({ status: args.status, limit: "100" });
|
|
891
|
+
if (args.team) query.set("teamId", args.team);
|
|
892
|
+
const body = await createClient2().get(
|
|
893
|
+
`/api/approvals?${query}`
|
|
894
|
+
);
|
|
895
|
+
if (args.json) return console.log(JSON.stringify(body, null, 2));
|
|
896
|
+
if (!body.approvals.length) return console.log("(no approvals)");
|
|
897
|
+
for (const line of columnize([
|
|
898
|
+
["id", "status", "path", "origin", "expires"],
|
|
899
|
+
...body.approvals.map((item) => [
|
|
900
|
+
item.id,
|
|
901
|
+
item.status,
|
|
902
|
+
`${endpoint(item.source)} -> ${endpoint(item.target)}`,
|
|
903
|
+
item.origin,
|
|
904
|
+
new Date(item.expiresAt).toISOString()
|
|
905
|
+
])
|
|
906
|
+
]))
|
|
907
|
+
console.log(line);
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
var show = defineCommand2({
|
|
911
|
+
meta: { name: "show", description: "Show one approval including payload and audit events" },
|
|
912
|
+
args: { id: { type: "positional", required: true }, json: { type: "boolean" } },
|
|
913
|
+
async run({ args }) {
|
|
914
|
+
const item = await createClient2().get(
|
|
915
|
+
`/api/approvals/${encodeURIComponent(args.id)}`
|
|
916
|
+
);
|
|
917
|
+
if (args.json) return console.log(JSON.stringify(item, null, 2));
|
|
918
|
+
console.log(`# ${item.id}`);
|
|
919
|
+
console.log(`status: ${item.status}`);
|
|
920
|
+
console.log(`attempt: ${item.attemptKind}:${item.attemptId}`);
|
|
921
|
+
console.log(`path: ${endpoint(item.source)} -> ${endpoint(item.target)}`);
|
|
922
|
+
console.log(`origin: ${item.origin}`);
|
|
923
|
+
console.log(`expires: ${new Date(item.expiresAt).toISOString()}`);
|
|
924
|
+
console.log(
|
|
925
|
+
`revisions: ${item.policyRefs.map((ref) => `${ref.teamId}@${ref.revision}`).join(", ")}`
|
|
926
|
+
);
|
|
927
|
+
console.log(`events: ${item.events.map((event) => event.event).join(" -> ")}`);
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
function decision(name) {
|
|
931
|
+
return defineCommand2({
|
|
932
|
+
meta: {
|
|
933
|
+
name,
|
|
934
|
+
description: name === "approve" ? "Approve and deliver one captured attempt" : `${name === "deny" ? "Deny" : "Cancel"} one pending attempt`
|
|
935
|
+
},
|
|
936
|
+
args: {
|
|
937
|
+
id: { type: "positional", required: true },
|
|
938
|
+
reason: { type: "string" },
|
|
939
|
+
yes: { type: "boolean", description: "Required explicit non-interactive confirmation" },
|
|
940
|
+
json: { type: "boolean" }
|
|
941
|
+
},
|
|
942
|
+
async run({ args }) {
|
|
943
|
+
if (!args.yes) throw new Error(`refusing ${name}: review with approval show, then pass --yes`);
|
|
944
|
+
const item = await createClient2().post(
|
|
945
|
+
`/api/approvals/${encodeURIComponent(args.id)}/${name}`,
|
|
946
|
+
args.reason ? { reason: args.reason } : {}
|
|
947
|
+
);
|
|
948
|
+
if (args.json) console.log(JSON.stringify(item, null, 2));
|
|
949
|
+
else console.log(`${item.id}: ${item.status}`);
|
|
950
|
+
}
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
function endpoint(value) {
|
|
954
|
+
return value.kind === "agent" ? `agent:${value.id}` : value.kind === "user" ? `user:${value.teamId}` : `outside:${value.teamId}`;
|
|
955
|
+
}
|
|
956
|
+
var approvalCommand = defineCommand2({
|
|
957
|
+
meta: { name: "approval", description: "Manage communication approval queue and history" },
|
|
958
|
+
subCommands: {
|
|
959
|
+
list,
|
|
960
|
+
show,
|
|
961
|
+
approve: decision("approve"),
|
|
962
|
+
deny: decision("deny"),
|
|
963
|
+
cancel: decision("cancel")
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
|
|
832
967
|
// src/commands/auth.ts
|
|
833
968
|
import { loginOpenAICodex } from "@earendil-works/pi-ai/oauth";
|
|
834
|
-
import { defineCommand as
|
|
969
|
+
import { defineCommand as defineCommand3 } from "citty";
|
|
835
970
|
function formatExpiry(ms) {
|
|
836
971
|
if (!ms) return "(unknown)";
|
|
837
972
|
const d = new Date(ms);
|
|
838
973
|
return d.toISOString().replace(/\.\d+Z$/, "Z");
|
|
839
974
|
}
|
|
840
|
-
var openaiLoginCmd =
|
|
975
|
+
var openaiLoginCmd = defineCommand3({
|
|
841
976
|
meta: {
|
|
842
977
|
name: "login",
|
|
843
978
|
description: "Connect your ChatGPT account via OAuth (browser sign-in)"
|
|
@@ -879,7 +1014,7 @@ var openaiLoginCmd = defineCommand2({
|
|
|
879
1014
|
console.log(" bazilion provider models-set openai-codex gpt-5.3-codex-spark");
|
|
880
1015
|
}
|
|
881
1016
|
});
|
|
882
|
-
var openaiLogoutCmd =
|
|
1017
|
+
var openaiLogoutCmd = defineCommand3({
|
|
883
1018
|
meta: {
|
|
884
1019
|
name: "logout",
|
|
885
1020
|
description: "Forget the stored ChatGPT OAuth credentials"
|
|
@@ -890,7 +1025,7 @@ var openaiLogoutCmd = defineCommand2({
|
|
|
890
1025
|
console.log("disconnected ChatGPT OAuth credentials");
|
|
891
1026
|
}
|
|
892
1027
|
});
|
|
893
|
-
var openaiStatusCmd =
|
|
1028
|
+
var openaiStatusCmd = defineCommand3({
|
|
894
1029
|
meta: {
|
|
895
1030
|
name: "status",
|
|
896
1031
|
description: "Show ChatGPT OAuth connection status"
|
|
@@ -907,7 +1042,7 @@ var openaiStatusCmd = defineCommand2({
|
|
|
907
1042
|
console.log(`access token expires: ${formatExpiry(status.expiresAt)}`);
|
|
908
1043
|
}
|
|
909
1044
|
});
|
|
910
|
-
var openaiCmd =
|
|
1045
|
+
var openaiCmd = defineCommand3({
|
|
911
1046
|
meta: {
|
|
912
1047
|
name: "openai",
|
|
913
1048
|
description: "Manage ChatGPT (OAuth) authentication"
|
|
@@ -918,7 +1053,7 @@ var openaiCmd = defineCommand2({
|
|
|
918
1053
|
status: openaiStatusCmd
|
|
919
1054
|
}
|
|
920
1055
|
});
|
|
921
|
-
var authCommand =
|
|
1056
|
+
var authCommand = defineCommand3({
|
|
922
1057
|
meta: {
|
|
923
1058
|
name: "auth",
|
|
924
1059
|
description: "OAuth-based provider authentication (ChatGPT account, etc.)"
|
|
@@ -934,8 +1069,8 @@ import { createWriteStream, existsSync as existsSync2, mkdirSync, readdirSync, r
|
|
|
934
1069
|
import { resolve } from "path";
|
|
935
1070
|
import { Readable } from "stream";
|
|
936
1071
|
import { pipeline } from "stream/promises";
|
|
937
|
-
import { defineCommand as
|
|
938
|
-
var createCmd =
|
|
1072
|
+
import { defineCommand as defineCommand4 } from "citty";
|
|
1073
|
+
var createCmd = defineCommand4({
|
|
939
1074
|
meta: { name: "create", description: "Download a tar.gz backup of ~/.bazilion from the server" },
|
|
940
1075
|
args: {
|
|
941
1076
|
output: {
|
|
@@ -976,7 +1111,7 @@ async function probeServerRunning(port) {
|
|
|
976
1111
|
return false;
|
|
977
1112
|
}
|
|
978
1113
|
}
|
|
979
|
-
var restoreCmd =
|
|
1114
|
+
var restoreCmd = defineCommand4({
|
|
980
1115
|
meta: {
|
|
981
1116
|
name: "restore",
|
|
982
1117
|
description: "Extract a backup tar.gz into ~/.bazilion (offline; server must be stopped)"
|
|
@@ -1029,7 +1164,7 @@ var restoreCmd = defineCommand3({
|
|
|
1029
1164
|
console.log("start the server with: bazilion serve (migrations apply automatically)");
|
|
1030
1165
|
}
|
|
1031
1166
|
});
|
|
1032
|
-
var backupCommand =
|
|
1167
|
+
var backupCommand = defineCommand4({
|
|
1033
1168
|
meta: { name: "backup", description: "Create or restore a ~/.bazilion tar.gz backup" },
|
|
1034
1169
|
subCommands: {
|
|
1035
1170
|
create: createCmd,
|
|
@@ -1043,7 +1178,7 @@ var backupCommand = defineCommand3({
|
|
|
1043
1178
|
});
|
|
1044
1179
|
|
|
1045
1180
|
// src/commands/completion.ts
|
|
1046
|
-
import { defineCommand as
|
|
1181
|
+
import { defineCommand as defineCommand5 } from "citty";
|
|
1047
1182
|
async function walk(cmd, path, out) {
|
|
1048
1183
|
const subsRaw = cmd.subCommands ?? {};
|
|
1049
1184
|
const subNames = Object.keys(subsRaw);
|
|
@@ -1148,7 +1283,7 @@ function fishScript(flat) {
|
|
|
1148
1283
|
`;
|
|
1149
1284
|
}
|
|
1150
1285
|
function completionCommand(main2) {
|
|
1151
|
-
return
|
|
1286
|
+
return defineCommand5({
|
|
1152
1287
|
meta: {
|
|
1153
1288
|
name: "completion",
|
|
1154
1289
|
description: "Print a shell completion script (bash, zsh, or fish)"
|
|
@@ -1173,13 +1308,13 @@ function completionCommand(main2) {
|
|
|
1173
1308
|
}
|
|
1174
1309
|
|
|
1175
1310
|
// src/commands/config.ts
|
|
1176
|
-
import { defineCommand as
|
|
1311
|
+
import { defineCommand as defineCommand6 } from "citty";
|
|
1177
1312
|
function displayValue(f) {
|
|
1178
1313
|
if (!f.set) return "(unset)";
|
|
1179
1314
|
if (f.kind === "secret") return f.preview ?? "(set)";
|
|
1180
1315
|
return f.value ?? "(set)";
|
|
1181
1316
|
}
|
|
1182
|
-
var listCmd2 =
|
|
1317
|
+
var listCmd2 = defineCommand6({
|
|
1183
1318
|
meta: {
|
|
1184
1319
|
name: "list",
|
|
1185
1320
|
description: "List every configurable field (credentials + URLs) across all services"
|
|
@@ -1202,7 +1337,7 @@ var listCmd2 = defineCommand5({
|
|
|
1202
1337
|
for (const line of columnize(rows)) console.log(line);
|
|
1203
1338
|
}
|
|
1204
1339
|
});
|
|
1205
|
-
var setCmd =
|
|
1340
|
+
var setCmd = defineCommand6({
|
|
1206
1341
|
meta: {
|
|
1207
1342
|
name: "set",
|
|
1208
1343
|
description: "Set a configurable field (auto-routes to secrets or plaintext store)"
|
|
@@ -1229,7 +1364,7 @@ var setCmd = defineCommand5({
|
|
|
1229
1364
|
console.log(`${state.envVar} (${state.kind}): ${displayValue(state)}`);
|
|
1230
1365
|
}
|
|
1231
1366
|
});
|
|
1232
|
-
var rmCmd =
|
|
1367
|
+
var rmCmd = defineCommand6({
|
|
1233
1368
|
meta: { name: "rm", description: "Remove a configurable field value" },
|
|
1234
1369
|
args: {
|
|
1235
1370
|
envVar: { type: "positional", required: true, description: "Env var name to clear" }
|
|
@@ -1240,7 +1375,7 @@ var rmCmd = defineCommand5({
|
|
|
1240
1375
|
console.log(`removed ${args.envVar}`);
|
|
1241
1376
|
}
|
|
1242
1377
|
});
|
|
1243
|
-
var configCommand =
|
|
1378
|
+
var configCommand = defineCommand6({
|
|
1244
1379
|
meta: {
|
|
1245
1380
|
name: "config",
|
|
1246
1381
|
description: "Manage service configuration \u2014 credentials (encrypted) and URLs/IDs (plaintext), unified under one CLI"
|
|
@@ -1257,7 +1392,7 @@ import { spawn as spawn2 } from "child_process";
|
|
|
1257
1392
|
import { existsSync as existsSync3 } from "fs";
|
|
1258
1393
|
import { connect } from "net";
|
|
1259
1394
|
import { join as join2 } from "path";
|
|
1260
|
-
import { defineCommand as
|
|
1395
|
+
import { defineCommand as defineCommand7 } from "citty";
|
|
1261
1396
|
var bundledDaemonEntry = join2(import.meta.dirname, "daemon.js");
|
|
1262
1397
|
var sourceDaemonEntry = join2(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
|
|
1263
1398
|
var daemonEntry = existsSync3(bundledDaemonEntry) ? bundledDaemonEntry : sourceDaemonEntry;
|
|
@@ -1351,7 +1486,7 @@ function spawnProcess(label, entry2, env) {
|
|
|
1351
1486
|
stdio: "inherit"
|
|
1352
1487
|
});
|
|
1353
1488
|
}
|
|
1354
|
-
var dashboardCommand =
|
|
1489
|
+
var dashboardCommand = defineCommand7({
|
|
1355
1490
|
meta: {
|
|
1356
1491
|
name: "dashboard",
|
|
1357
1492
|
description: "Start the bazilion daemon and bundled web UI"
|
|
@@ -1470,8 +1605,8 @@ var dashboardCommand = defineCommand6({
|
|
|
1470
1605
|
});
|
|
1471
1606
|
|
|
1472
1607
|
// src/commands/doctor.ts
|
|
1473
|
-
import { defineCommand as
|
|
1474
|
-
var doctorCommand =
|
|
1608
|
+
import { defineCommand as defineCommand8 } from "citty";
|
|
1609
|
+
var doctorCommand = defineCommand8({
|
|
1475
1610
|
meta: { name: "doctor", description: "Diagnose your bazilion install" },
|
|
1476
1611
|
async run() {
|
|
1477
1612
|
const client = createClient2();
|
|
@@ -1498,7 +1633,7 @@ var doctorCommand = defineCommand7({
|
|
|
1498
1633
|
console.log(
|
|
1499
1634
|
` ${r.database.activeAgents} active agent(s) (${r.database.totalAgents} total)`
|
|
1500
1635
|
);
|
|
1501
|
-
console.log(` ${r.database.
|
|
1636
|
+
console.log(` ${r.database.teams} team(s)`);
|
|
1502
1637
|
} else {
|
|
1503
1638
|
check("open database", false, r.database.error);
|
|
1504
1639
|
}
|
|
@@ -1582,178 +1717,6 @@ var doctorCommand = defineCommand7({
|
|
|
1582
1717
|
}
|
|
1583
1718
|
});
|
|
1584
1719
|
|
|
1585
|
-
// src/commands/group.ts
|
|
1586
|
-
import { readFileSync as readFileSync3 } from "fs";
|
|
1587
|
-
import { stdin as stdin2 } from "process";
|
|
1588
|
-
import { defineCommand as defineCommand8 } from "citty";
|
|
1589
|
-
var addCmd = defineCommand8({
|
|
1590
|
-
meta: {
|
|
1591
|
-
name: "add",
|
|
1592
|
-
description: "Register a group at ~/.bazilion/groups/<slug>/ (use --link to point at an existing tree)"
|
|
1593
|
-
},
|
|
1594
|
-
args: {
|
|
1595
|
-
id: { type: "positional", required: true, description: "Group slug" },
|
|
1596
|
-
name: { type: "string", description: "Display name (defaults to slug)" },
|
|
1597
|
-
link: {
|
|
1598
|
-
type: "string",
|
|
1599
|
-
description: "Absolute path of an existing directory; the group slot becomes a symlink to it"
|
|
1600
|
-
}
|
|
1601
|
-
},
|
|
1602
|
-
async run({ args }) {
|
|
1603
|
-
const client = createClient2();
|
|
1604
|
-
const body = {
|
|
1605
|
-
id: args.id,
|
|
1606
|
-
...args.name ? { name: args.name } : {},
|
|
1607
|
-
...args.link ? { link: args.link } : {}
|
|
1608
|
-
};
|
|
1609
|
-
const g = await client.post("/api/groups", body);
|
|
1610
|
-
console.log(`registered group ${g.id} at ${g.path}`);
|
|
1611
|
-
}
|
|
1612
|
-
});
|
|
1613
|
-
var listCmd3 = defineCommand8({
|
|
1614
|
-
meta: { name: "list", description: "List groups" },
|
|
1615
|
-
async run() {
|
|
1616
|
-
const client = createClient2();
|
|
1617
|
-
const list = await client.get("/api/groups");
|
|
1618
|
-
if (list.length === 0) {
|
|
1619
|
-
console.log("(no groups)");
|
|
1620
|
-
return;
|
|
1621
|
-
}
|
|
1622
|
-
const rows = list.map((g) => [g.id, g.path]);
|
|
1623
|
-
for (const line of columnize(rows)) console.log(line);
|
|
1624
|
-
}
|
|
1625
|
-
});
|
|
1626
|
-
var rmCmd2 = defineCommand8({
|
|
1627
|
-
meta: { name: "rm", description: "Remove a group registration" },
|
|
1628
|
-
args: {
|
|
1629
|
-
id: { type: "positional", required: true }
|
|
1630
|
-
},
|
|
1631
|
-
async run({ args }) {
|
|
1632
|
-
const client = createClient2();
|
|
1633
|
-
await client.del(`/api/groups/${args.id}`);
|
|
1634
|
-
console.log(`removed group ${args.id}`);
|
|
1635
|
-
}
|
|
1636
|
-
});
|
|
1637
|
-
async function readStdin() {
|
|
1638
|
-
const chunks = [];
|
|
1639
|
-
for await (const chunk of stdin2) chunks.push(chunk);
|
|
1640
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
1641
|
-
}
|
|
1642
|
-
var userMdShowCmd = defineCommand8({
|
|
1643
|
-
meta: { name: "show", description: "Print the group's USER.md" },
|
|
1644
|
-
args: { id: { type: "positional", required: true } },
|
|
1645
|
-
async run({ args }) {
|
|
1646
|
-
const client = createClient2();
|
|
1647
|
-
const g = await client.get(`/api/groups/${args.id}`);
|
|
1648
|
-
process.stdout.write(g.userMd);
|
|
1649
|
-
if (g.userMd && !g.userMd.endsWith("\n")) process.stdout.write("\n");
|
|
1650
|
-
}
|
|
1651
|
-
});
|
|
1652
|
-
var userMdSetCmd = defineCommand8({
|
|
1653
|
-
meta: {
|
|
1654
|
-
name: "set",
|
|
1655
|
-
description: "Replace the group's USER.md (from --file, --from-stdin, or inline text)"
|
|
1656
|
-
},
|
|
1657
|
-
args: {
|
|
1658
|
-
id: { type: "positional", required: true },
|
|
1659
|
-
file: { type: "string", description: "Read content from a file path" },
|
|
1660
|
-
"from-stdin": { type: "boolean", description: "Read content from stdin" },
|
|
1661
|
-
text: { type: "string", description: "Inline content" }
|
|
1662
|
-
},
|
|
1663
|
-
async run({ args }) {
|
|
1664
|
-
let content;
|
|
1665
|
-
if (args["from-stdin"]) content = await readStdin();
|
|
1666
|
-
else if (args.file) content = readFileSync3(args.file, "utf8");
|
|
1667
|
-
else if (args.text !== void 0) content = args.text;
|
|
1668
|
-
else {
|
|
1669
|
-
console.error("group user-md set: provide --file, --from-stdin, or --text");
|
|
1670
|
-
process.exit(2);
|
|
1671
|
-
}
|
|
1672
|
-
const client = createClient2();
|
|
1673
|
-
const body = { userMd: content };
|
|
1674
|
-
await client.put(`/api/groups/${args.id}/user-md`, body);
|
|
1675
|
-
console.log(`updated USER.md for group ${args.id} (${content.length} bytes)`);
|
|
1676
|
-
}
|
|
1677
|
-
});
|
|
1678
|
-
var userMdClearCmd = defineCommand8({
|
|
1679
|
-
meta: { name: "clear", description: "Clear the group's USER.md to empty" },
|
|
1680
|
-
args: { id: { type: "positional", required: true } },
|
|
1681
|
-
async run({ args }) {
|
|
1682
|
-
const client = createClient2();
|
|
1683
|
-
const body = { userMd: "" };
|
|
1684
|
-
await client.put(`/api/groups/${args.id}/user-md`, body);
|
|
1685
|
-
console.log(`cleared USER.md for group ${args.id}`);
|
|
1686
|
-
}
|
|
1687
|
-
});
|
|
1688
|
-
var userMdCmd = defineCommand8({
|
|
1689
|
-
meta: { name: "user-md", description: "View or edit a group's USER.md" },
|
|
1690
|
-
subCommands: {
|
|
1691
|
-
show: userMdShowCmd,
|
|
1692
|
-
set: userMdSetCmd,
|
|
1693
|
-
clear: userMdClearCmd
|
|
1694
|
-
}
|
|
1695
|
-
});
|
|
1696
|
-
var topicFormatShowCmd = defineCommand8({
|
|
1697
|
-
meta: { name: "show", description: "Print the group's Telegram topic-name template" },
|
|
1698
|
-
args: { id: { type: "positional", required: true } },
|
|
1699
|
-
async run({ args }) {
|
|
1700
|
-
const client = createClient2();
|
|
1701
|
-
const g = await client.get(`/api/groups/${args.id}`);
|
|
1702
|
-
console.log(g.telegramTopicNameFormat ?? "(default naming)");
|
|
1703
|
-
}
|
|
1704
|
-
});
|
|
1705
|
-
var topicFormatSetCmd = defineCommand8({
|
|
1706
|
-
meta: {
|
|
1707
|
-
name: "set",
|
|
1708
|
-
description: "Set the topic-name template. Tokens: {agent.name} {group.name} {group.slug} (must include {agent.name})"
|
|
1709
|
-
},
|
|
1710
|
-
args: {
|
|
1711
|
-
id: { type: "positional", required: true },
|
|
1712
|
-
format: {
|
|
1713
|
-
type: "positional",
|
|
1714
|
-
required: true,
|
|
1715
|
-
description: 'e.g. "{group.name} / {agent.name}"'
|
|
1716
|
-
}
|
|
1717
|
-
},
|
|
1718
|
-
async run({ args }) {
|
|
1719
|
-
const client = createClient2();
|
|
1720
|
-
const body = { format: args.format };
|
|
1721
|
-
const g = await client.put(`/api/groups/${args.id}/topic-format`, body);
|
|
1722
|
-
console.log(`set topic-name template for group ${args.id}: ${g.telegramTopicNameFormat}`);
|
|
1723
|
-
}
|
|
1724
|
-
});
|
|
1725
|
-
var topicFormatClearCmd = defineCommand8({
|
|
1726
|
-
meta: { name: "clear", description: "Clear the template (revert to built-in naming)" },
|
|
1727
|
-
args: { id: { type: "positional", required: true } },
|
|
1728
|
-
async run({ args }) {
|
|
1729
|
-
const client = createClient2();
|
|
1730
|
-
const body = { format: null };
|
|
1731
|
-
await client.put(`/api/groups/${args.id}/topic-format`, body);
|
|
1732
|
-
console.log(`cleared topic-name template for group ${args.id}`);
|
|
1733
|
-
}
|
|
1734
|
-
});
|
|
1735
|
-
var topicFormatCmd = defineCommand8({
|
|
1736
|
-
meta: {
|
|
1737
|
-
name: "topic-format",
|
|
1738
|
-
description: "View or edit a group's Telegram forum-topic name template"
|
|
1739
|
-
},
|
|
1740
|
-
subCommands: {
|
|
1741
|
-
show: topicFormatShowCmd,
|
|
1742
|
-
set: topicFormatSetCmd,
|
|
1743
|
-
clear: topicFormatClearCmd
|
|
1744
|
-
}
|
|
1745
|
-
});
|
|
1746
|
-
var groupCommand = defineCommand8({
|
|
1747
|
-
meta: { name: "group", description: "Manage groups (collaboration contexts)" },
|
|
1748
|
-
subCommands: {
|
|
1749
|
-
add: addCmd,
|
|
1750
|
-
list: listCmd3,
|
|
1751
|
-
rm: rmCmd2,
|
|
1752
|
-
"user-md": userMdCmd,
|
|
1753
|
-
"topic-format": topicFormatCmd
|
|
1754
|
-
}
|
|
1755
|
-
});
|
|
1756
|
-
|
|
1757
1720
|
// src/commands/inbox.ts
|
|
1758
1721
|
import { defineCommand as defineCommand9 } from "citty";
|
|
1759
1722
|
function decodeText(payload) {
|
|
@@ -1767,11 +1730,11 @@ function decodeText(payload) {
|
|
|
1767
1730
|
function messageRow(m) {
|
|
1768
1731
|
const when = new Date(m.createdAt).toISOString();
|
|
1769
1732
|
const state = m.readAt ? "read" : "NEW";
|
|
1770
|
-
const
|
|
1771
|
-
const preview =
|
|
1733
|
+
const text2 = decodeText(m.payload);
|
|
1734
|
+
const preview = text2.length > 60 ? `${text2.slice(0, 60)}\u2026` : text2;
|
|
1772
1735
|
return [m.id, state, when, `from:${m.fromAgentId.slice(0, 8)}`, `"${preview}"`];
|
|
1773
1736
|
}
|
|
1774
|
-
var
|
|
1737
|
+
var listCmd3 = defineCommand9({
|
|
1775
1738
|
meta: { name: "list", description: "List messages in an agent inbox" },
|
|
1776
1739
|
args: {
|
|
1777
1740
|
agent: { type: "positional", required: true, description: "Recipient agent id" },
|
|
@@ -1824,14 +1787,14 @@ var readCmd = defineCommand9({
|
|
|
1824
1787
|
var inboxCommand = defineCommand9({
|
|
1825
1788
|
meta: { name: "inbox", description: "Inspect agent inboxes" },
|
|
1826
1789
|
subCommands: {
|
|
1827
|
-
list:
|
|
1790
|
+
list: listCmd3,
|
|
1828
1791
|
show: showCmd2,
|
|
1829
1792
|
read: readCmd
|
|
1830
1793
|
}
|
|
1831
1794
|
});
|
|
1832
1795
|
|
|
1833
1796
|
// src/commands/login.ts
|
|
1834
|
-
import { existsSync as existsSync4, readFileSync as
|
|
1797
|
+
import { existsSync as existsSync4, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
1835
1798
|
import { defineCommand as defineCommand10 } from "citty";
|
|
1836
1799
|
function normalizeServer(raw) {
|
|
1837
1800
|
let url;
|
|
@@ -1870,7 +1833,7 @@ var loginCommand = defineCommand10({
|
|
|
1870
1833
|
`${paths.authFile} not found. Start the daemon with "bazilion serve" first \u2014 login stores the remote there.`
|
|
1871
1834
|
);
|
|
1872
1835
|
}
|
|
1873
|
-
const auth = JSON.parse(
|
|
1836
|
+
const auth = JSON.parse(readFileSync3(paths.authFile, "utf8"));
|
|
1874
1837
|
if (args.clear) {
|
|
1875
1838
|
if (!auth.remote) {
|
|
1876
1839
|
console.log("no remote stored \u2014 nothing to clear");
|
|
@@ -1912,7 +1875,7 @@ function serverRow(s) {
|
|
|
1912
1875
|
where
|
|
1913
1876
|
];
|
|
1914
1877
|
}
|
|
1915
|
-
var
|
|
1878
|
+
var addCmd = defineCommand11({
|
|
1916
1879
|
meta: { name: "add", description: "Register an MCP server" },
|
|
1917
1880
|
args: {
|
|
1918
1881
|
name: { type: "positional", required: true, description: "Unique name ([a-zA-Z0-9_])" },
|
|
@@ -1939,7 +1902,7 @@ var addCmd2 = defineCommand11({
|
|
|
1939
1902
|
console.log(`${server.id} ${server.name} ${server.transport}`);
|
|
1940
1903
|
}
|
|
1941
1904
|
});
|
|
1942
|
-
var
|
|
1905
|
+
var listCmd4 = defineCommand11({
|
|
1943
1906
|
meta: { name: "list", description: "List MCP servers" },
|
|
1944
1907
|
async run() {
|
|
1945
1908
|
const client = createClient2();
|
|
@@ -1960,7 +1923,7 @@ var showCmd3 = defineCommand11({
|
|
|
1960
1923
|
console.log(JSON.stringify(server, null, 2));
|
|
1961
1924
|
}
|
|
1962
1925
|
});
|
|
1963
|
-
var
|
|
1926
|
+
var rmCmd2 = defineCommand11({
|
|
1964
1927
|
meta: { name: "rm", description: "Delete an MCP server" },
|
|
1965
1928
|
args: { id: { type: "positional", required: true } },
|
|
1966
1929
|
async run({ args }) {
|
|
@@ -2008,10 +1971,10 @@ var testCmd = defineCommand11({
|
|
|
2008
1971
|
var mcpCommand = defineCommand11({
|
|
2009
1972
|
meta: { name: "mcp", description: "Manage MCP servers" },
|
|
2010
1973
|
subCommands: {
|
|
2011
|
-
add:
|
|
2012
|
-
list:
|
|
1974
|
+
add: addCmd,
|
|
1975
|
+
list: listCmd4,
|
|
2013
1976
|
show: showCmd3,
|
|
2014
|
-
rm:
|
|
1977
|
+
rm: rmCmd2,
|
|
2015
1978
|
enable: enableCmd,
|
|
2016
1979
|
disable: disableCmd,
|
|
2017
1980
|
test: testCmd
|
|
@@ -2024,39 +1987,39 @@ function encodeKey(key) {
|
|
|
2024
1987
|
return key.split("/").map(encodeURIComponent).join("/");
|
|
2025
1988
|
}
|
|
2026
1989
|
var writeCmd = defineCommand12({
|
|
2027
|
-
meta: { name: "write", description: "Write an entry into a
|
|
1990
|
+
meta: { name: "write", description: "Write an entry into a team's shared memory" },
|
|
2028
1991
|
args: {
|
|
2029
|
-
|
|
1992
|
+
team: { type: "positional", required: true, description: "Team slug" },
|
|
2030
1993
|
key: { type: "positional", required: true, description: "Memory key (path under memory/)" },
|
|
2031
1994
|
content: { type: "positional", required: true, description: "Content to write" }
|
|
2032
1995
|
},
|
|
2033
1996
|
async run({ args }) {
|
|
2034
1997
|
const client = createClient2();
|
|
2035
1998
|
const entry2 = await client.put(
|
|
2036
|
-
`/api/
|
|
1999
|
+
`/api/teams/${args.team}/memory/${encodeKey(args.key)}`,
|
|
2037
2000
|
{ content: args.content }
|
|
2038
2001
|
);
|
|
2039
2002
|
console.log(`wrote ${entry2.key} (${entry2.content.length} bytes)`);
|
|
2040
2003
|
}
|
|
2041
2004
|
});
|
|
2042
2005
|
var readCmd2 = defineCommand12({
|
|
2043
|
-
meta: { name: "read", description: "Read an entry from a
|
|
2006
|
+
meta: { name: "read", description: "Read an entry from a team's shared memory" },
|
|
2044
2007
|
args: {
|
|
2045
|
-
|
|
2008
|
+
team: { type: "positional", required: true, description: "Team slug" },
|
|
2046
2009
|
key: { type: "positional", required: true }
|
|
2047
2010
|
},
|
|
2048
2011
|
async run({ args }) {
|
|
2049
2012
|
const client = createClient2();
|
|
2050
2013
|
const entry2 = await client.get(
|
|
2051
|
-
`/api/
|
|
2014
|
+
`/api/teams/${args.team}/memory/${encodeKey(args.key)}`
|
|
2052
2015
|
);
|
|
2053
2016
|
console.log(entry2.content);
|
|
2054
2017
|
}
|
|
2055
2018
|
});
|
|
2056
2019
|
var searchCmd = defineCommand12({
|
|
2057
|
-
meta: { name: "search", description: "Search a
|
|
2020
|
+
meta: { name: "search", description: "Search a team's shared memory" },
|
|
2058
2021
|
args: {
|
|
2059
|
-
|
|
2022
|
+
team: { type: "positional", required: true, description: "Team slug" },
|
|
2060
2023
|
query: { type: "positional", required: true },
|
|
2061
2024
|
limit: { type: "string", description: "Max results (default 10)" }
|
|
2062
2025
|
},
|
|
@@ -2064,7 +2027,7 @@ var searchCmd = defineCommand12({
|
|
|
2064
2027
|
const client = createClient2();
|
|
2065
2028
|
const limit = args.limit ? Number.parseInt(args.limit, 10) : 10;
|
|
2066
2029
|
const params = new URLSearchParams({ q: args.query, limit: String(limit) });
|
|
2067
|
-
const hits = await client.get(`/api/
|
|
2030
|
+
const hits = await client.get(`/api/teams/${args.team}/memory/search?${params}`);
|
|
2068
2031
|
if (hits.length === 0) {
|
|
2069
2032
|
console.log("(no matches)");
|
|
2070
2033
|
return;
|
|
@@ -2074,14 +2037,14 @@ var searchCmd = defineCommand12({
|
|
|
2074
2037
|
}
|
|
2075
2038
|
}
|
|
2076
2039
|
});
|
|
2077
|
-
var
|
|
2078
|
-
meta: { name: "list", description: "List all entries in a
|
|
2040
|
+
var listCmd5 = defineCommand12({
|
|
2041
|
+
meta: { name: "list", description: "List all entries in a team's shared memory" },
|
|
2079
2042
|
args: {
|
|
2080
|
-
|
|
2043
|
+
team: { type: "positional", required: true, description: "Team slug" }
|
|
2081
2044
|
},
|
|
2082
2045
|
async run({ args }) {
|
|
2083
2046
|
const client = createClient2();
|
|
2084
|
-
const all = await client.get(`/api/
|
|
2047
|
+
const all = await client.get(`/api/teams/${args.team}/memory`);
|
|
2085
2048
|
if (all.length === 0) {
|
|
2086
2049
|
console.log("(no memory entries)");
|
|
2087
2050
|
return;
|
|
@@ -2091,36 +2054,36 @@ var listCmd6 = defineCommand12({
|
|
|
2091
2054
|
}
|
|
2092
2055
|
}
|
|
2093
2056
|
});
|
|
2094
|
-
var
|
|
2095
|
-
meta: { name: "rm", description: "Remove an entry from a
|
|
2057
|
+
var rmCmd3 = defineCommand12({
|
|
2058
|
+
meta: { name: "rm", description: "Remove an entry from a team's shared memory" },
|
|
2096
2059
|
args: {
|
|
2097
|
-
|
|
2060
|
+
team: { type: "positional", required: true, description: "Team slug" },
|
|
2098
2061
|
key: { type: "positional", required: true }
|
|
2099
2062
|
},
|
|
2100
2063
|
async run({ args }) {
|
|
2101
2064
|
const client = createClient2();
|
|
2102
|
-
await client.del(`/api/
|
|
2065
|
+
await client.del(`/api/teams/${args.team}/memory/${encodeKey(args.key)}`);
|
|
2103
2066
|
console.log(`removed ${args.key}`);
|
|
2104
2067
|
}
|
|
2105
2068
|
});
|
|
2106
2069
|
var memoryCommand = defineCommand12({
|
|
2107
2070
|
meta: {
|
|
2108
2071
|
name: "memory",
|
|
2109
|
-
description: "Manage a
|
|
2072
|
+
description: "Manage a team's shared memory (BM25-indexed markdown notes)"
|
|
2110
2073
|
},
|
|
2111
2074
|
subCommands: {
|
|
2112
2075
|
write: writeCmd,
|
|
2113
2076
|
read: readCmd2,
|
|
2114
2077
|
search: searchCmd,
|
|
2115
|
-
list:
|
|
2116
|
-
rm:
|
|
2078
|
+
list: listCmd5,
|
|
2079
|
+
rm: rmCmd3
|
|
2117
2080
|
}
|
|
2118
2081
|
});
|
|
2119
2082
|
|
|
2120
2083
|
// src/commands/profile.ts
|
|
2121
2084
|
import { spawn as spawn3 } from "child_process";
|
|
2122
2085
|
import { randomBytes } from "crypto";
|
|
2123
|
-
import { readFileSync as
|
|
2086
|
+
import { readFileSync as readFileSync4, rmSync as rmSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
2124
2087
|
import { tmpdir } from "os";
|
|
2125
2088
|
import { join as join3 } from "path";
|
|
2126
2089
|
|
|
@@ -2196,7 +2159,7 @@ var createCmd2 = defineCommand13({
|
|
|
2196
2159
|
},
|
|
2197
2160
|
async run({ args }) {
|
|
2198
2161
|
const skillsMode = parseSkillsMode(args["skills-mode"]);
|
|
2199
|
-
const readTemplate = (path) => path ?
|
|
2162
|
+
const readTemplate = (path) => path ? readFileSync4(path, "utf8") : void 0;
|
|
2200
2163
|
const body = {
|
|
2201
2164
|
id: args.id,
|
|
2202
2165
|
name: args.name,
|
|
@@ -2215,16 +2178,16 @@ var createCmd2 = defineCommand13({
|
|
|
2215
2178
|
console.log(`created profile ${profile.id} at ${profile.dir}`);
|
|
2216
2179
|
}
|
|
2217
2180
|
});
|
|
2218
|
-
var
|
|
2181
|
+
var listCmd6 = defineCommand13({
|
|
2219
2182
|
meta: { name: "list", description: "List profiles" },
|
|
2220
2183
|
async run() {
|
|
2221
2184
|
const client = createClient2();
|
|
2222
|
-
const
|
|
2223
|
-
if (
|
|
2185
|
+
const list3 = await client.get("/api/profiles");
|
|
2186
|
+
if (list3.length === 0) {
|
|
2224
2187
|
console.log("(no profiles)");
|
|
2225
2188
|
return;
|
|
2226
2189
|
}
|
|
2227
|
-
const rows =
|
|
2190
|
+
const rows = list3.map((p) => [p.id, p.defaultModel, p.name]);
|
|
2228
2191
|
for (const line of columnize(rows)) console.log(line);
|
|
2229
2192
|
}
|
|
2230
2193
|
});
|
|
@@ -2283,7 +2246,7 @@ var editCmd2 = defineCommand13({
|
|
|
2283
2246
|
child.on("close", (c) => resolve3(c ?? 0));
|
|
2284
2247
|
});
|
|
2285
2248
|
if (code !== 0) throw new Error(`editor exited with code ${code}`);
|
|
2286
|
-
const updated =
|
|
2249
|
+
const updated = readFileSync4(tmpPath, "utf8");
|
|
2287
2250
|
if (updated === content) {
|
|
2288
2251
|
console.log("(no changes)");
|
|
2289
2252
|
return;
|
|
@@ -2348,7 +2311,7 @@ var profileCommand = defineCommand13({
|
|
|
2348
2311
|
meta: { name: "profile", description: "Manage profiles" },
|
|
2349
2312
|
subCommands: {
|
|
2350
2313
|
create: createCmd2,
|
|
2351
|
-
list:
|
|
2314
|
+
list: listCmd6,
|
|
2352
2315
|
show: showCmd4,
|
|
2353
2316
|
edit: editCmd2,
|
|
2354
2317
|
update: updateCmd,
|
|
@@ -2356,295 +2319,71 @@ var profileCommand = defineCommand13({
|
|
|
2356
2319
|
}
|
|
2357
2320
|
});
|
|
2358
2321
|
|
|
2359
|
-
// src/commands/
|
|
2360
|
-
import { spawn as spawn4 } from "child_process";
|
|
2361
|
-
import { randomBytes as randomBytes2 } from "crypto";
|
|
2362
|
-
import { readFileSync as readFileSync6, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
2363
|
-
import { tmpdir as tmpdir2 } from "os";
|
|
2364
|
-
import { join as join4 } from "path";
|
|
2322
|
+
// src/commands/provider.ts
|
|
2365
2323
|
import { defineCommand as defineCommand14 } from "citty";
|
|
2366
|
-
var
|
|
2367
|
-
meta: {
|
|
2324
|
+
var listCmd7 = defineCommand14({
|
|
2325
|
+
meta: {
|
|
2326
|
+
name: "list",
|
|
2327
|
+
description: "List all providers with enabled/disabled state and curated model counts"
|
|
2328
|
+
},
|
|
2368
2329
|
args: {
|
|
2369
|
-
|
|
2370
|
-
name: { type: "string", description: "Display name (defaults to slug)" },
|
|
2371
|
-
"user-md-file": {
|
|
2372
|
-
type: "string",
|
|
2373
|
-
description: "Path to a starter USER.md; seeded into a freshly-created target group"
|
|
2374
|
-
}
|
|
2330
|
+
enabled: { type: "boolean", description: "Show only enabled providers" }
|
|
2375
2331
|
},
|
|
2376
2332
|
async run({ args }) {
|
|
2377
|
-
const body = { id: args.id };
|
|
2378
|
-
if (args.name) body.name = args.name;
|
|
2379
|
-
if (args["user-md-file"]) body.userMd = readFileSync6(args["user-md-file"], "utf8");
|
|
2380
|
-
const client = createClient2();
|
|
2381
|
-
const created = await client.post("/api/profile-groups", body);
|
|
2382
|
-
console.log(`created profile group ${created.id}`);
|
|
2383
|
-
}
|
|
2384
|
-
});
|
|
2385
|
-
var listCmd8 = defineCommand14({
|
|
2386
|
-
meta: { name: "list", description: "List profile groups" },
|
|
2387
|
-
async run() {
|
|
2388
2333
|
const client = createClient2();
|
|
2389
|
-
const
|
|
2390
|
-
|
|
2391
|
-
|
|
2334
|
+
const { providers } = await client.get("/api/config/providers");
|
|
2335
|
+
const filtered = args.enabled ? providers.filter((p) => p.enabled) : providers;
|
|
2336
|
+
if (filtered.length === 0) {
|
|
2337
|
+
console.log("(no providers to show)");
|
|
2392
2338
|
return;
|
|
2393
2339
|
}
|
|
2394
|
-
const rows =
|
|
2340
|
+
const rows = filtered.map((p) => [
|
|
2341
|
+
p.id,
|
|
2342
|
+
p.enabled ? "enabled" : "disabled",
|
|
2343
|
+
`${p.curated.length} curated`,
|
|
2344
|
+
`${p.catalog.length} catalog`,
|
|
2345
|
+
p.enabled ? "" : `(set ${p.envHint})`
|
|
2346
|
+
]);
|
|
2395
2347
|
for (const line of columnize(rows)) console.log(line);
|
|
2396
2348
|
}
|
|
2397
2349
|
});
|
|
2398
|
-
var
|
|
2399
|
-
meta: {
|
|
2350
|
+
var modelsCmd = defineCommand14({
|
|
2351
|
+
meta: {
|
|
2352
|
+
name: "models",
|
|
2353
|
+
description: "Show curated + catalog + live models for one provider"
|
|
2354
|
+
},
|
|
2400
2355
|
args: {
|
|
2401
|
-
|
|
2402
|
-
json: { type: "boolean", description: "Emit full JSON (members + basics)" }
|
|
2356
|
+
name: { type: "positional", required: true, description: "Provider name" }
|
|
2403
2357
|
},
|
|
2404
2358
|
async run({ args }) {
|
|
2405
2359
|
const client = createClient2();
|
|
2406
|
-
const
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2360
|
+
const { providers } = await client.get("/api/config/providers");
|
|
2361
|
+
const p = providers.find((x) => x.id === args.name);
|
|
2362
|
+
if (!p) {
|
|
2363
|
+
console.error(`unknown provider: ${args.name}`);
|
|
2364
|
+
process.exit(1);
|
|
2410
2365
|
}
|
|
2411
|
-
console.log(`# ${
|
|
2412
|
-
console.log(`
|
|
2413
|
-
console.log(
|
|
2414
|
-
|
|
2415
|
-
);
|
|
2416
|
-
console.log("");
|
|
2417
|
-
if (
|
|
2418
|
-
|
|
2419
|
-
|
|
2366
|
+
console.log(`# ${p.id} (${p.enabled ? "enabled" : "disabled"})`);
|
|
2367
|
+
if (!p.enabled) console.log(` (set ${p.envHint} to enable)`);
|
|
2368
|
+
console.log("\n## curated");
|
|
2369
|
+
if (p.curated.length === 0) console.log(" (none \u2014 use `provider models-set` to pin some)");
|
|
2370
|
+
else for (const m of p.curated) console.log(` ${m}`);
|
|
2371
|
+
console.log("\n## catalog (from pi-ai)");
|
|
2372
|
+
if (p.catalog.length === 0) console.log(" (empty)");
|
|
2373
|
+
else for (const m of p.catalog) console.log(` ${m}`);
|
|
2374
|
+
if (p.live) {
|
|
2375
|
+
console.log("\n## live (from upstream /v1/models)");
|
|
2376
|
+
if (p.live.error) console.log(` (error: ${p.live.error})`);
|
|
2377
|
+
else if (p.live.models.length === 0) console.log(" (empty)");
|
|
2378
|
+
else for (const m of p.live.models) console.log(` ${m}`);
|
|
2420
2379
|
}
|
|
2421
|
-
console.log("members:");
|
|
2422
|
-
const rows = [
|
|
2423
|
-
["#", "profile", "agent-name", "model-override", "reasoning"],
|
|
2424
|
-
...detail.members.map((m) => [
|
|
2425
|
-
String(m.position),
|
|
2426
|
-
m.profileId,
|
|
2427
|
-
m.agentName,
|
|
2428
|
-
m.modelOverride ?? "-",
|
|
2429
|
-
m.reasoningLevel ?? "-"
|
|
2430
|
-
])
|
|
2431
|
-
];
|
|
2432
|
-
for (const line of columnize(rows)) console.log(` ${line}`);
|
|
2433
2380
|
}
|
|
2434
2381
|
});
|
|
2435
|
-
var
|
|
2436
|
-
meta: {
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
"user-md-file": {
|
|
2441
|
-
type: "string",
|
|
2442
|
-
description: "Path to new USER.md content (pass empty string to clear)"
|
|
2443
|
-
}
|
|
2444
|
-
},
|
|
2445
|
-
async run({ args }) {
|
|
2446
|
-
const body = {};
|
|
2447
|
-
if (args.name !== void 0) body.name = args.name;
|
|
2448
|
-
if (args["user-md-file"] !== void 0) {
|
|
2449
|
-
body.userMd = args["user-md-file"] === "" ? null : readFileSync6(args["user-md-file"], "utf8");
|
|
2450
|
-
}
|
|
2451
|
-
if (Object.keys(body).length === 0) {
|
|
2452
|
-
throw new Error("nothing to update \u2014 pass at least one of --name/--user-md-file");
|
|
2453
|
-
}
|
|
2454
|
-
const client = createClient2();
|
|
2455
|
-
const updated = await client.patch(`/api/profile-groups/${args.id}`, body);
|
|
2456
|
-
console.log(`updated profile group ${updated.id}`);
|
|
2457
|
-
}
|
|
2458
|
-
});
|
|
2459
|
-
var editCmd3 = defineCommand14({
|
|
2460
|
-
meta: { name: "edit", description: "Edit the member array in $EDITOR (JSON)" },
|
|
2461
|
-
args: {
|
|
2462
|
-
id: { type: "positional", required: true }
|
|
2463
|
-
},
|
|
2464
|
-
async run({ args }) {
|
|
2465
|
-
const client = createClient2();
|
|
2466
|
-
const detail = await client.get(`/api/profile-groups/${args.id}`);
|
|
2467
|
-
const editable = detail.members.map((m) => ({
|
|
2468
|
-
profileId: m.profileId,
|
|
2469
|
-
agentName: m.agentName,
|
|
2470
|
-
modelOverride: m.modelOverride,
|
|
2471
|
-
reasoningLevel: m.reasoningLevel
|
|
2472
|
-
}));
|
|
2473
|
-
const before = `${JSON.stringify(editable, null, 2)}
|
|
2474
|
-
`;
|
|
2475
|
-
const tmpPath = join4(
|
|
2476
|
-
tmpdir2(),
|
|
2477
|
-
`bazilion-profile-group-${args.id}-${randomBytes2(4).toString("hex")}.json`
|
|
2478
|
-
);
|
|
2479
|
-
writeFileSync4(tmpPath, before);
|
|
2480
|
-
try {
|
|
2481
|
-
const editor = process.env.EDITOR ?? process.env.VISUAL ?? "vi";
|
|
2482
|
-
const code = await new Promise((resolve3, reject) => {
|
|
2483
|
-
const child = spawn4(editor, [tmpPath], { stdio: "inherit" });
|
|
2484
|
-
child.on("error", reject);
|
|
2485
|
-
child.on("close", (c) => resolve3(c ?? 0));
|
|
2486
|
-
});
|
|
2487
|
-
if (code !== 0) throw new Error(`editor exited with code ${code}`);
|
|
2488
|
-
const after = readFileSync6(tmpPath, "utf8");
|
|
2489
|
-
if (after === before) {
|
|
2490
|
-
console.log("(no changes)");
|
|
2491
|
-
return;
|
|
2492
|
-
}
|
|
2493
|
-
let parsed;
|
|
2494
|
-
try {
|
|
2495
|
-
parsed = JSON.parse(after);
|
|
2496
|
-
} catch (err) {
|
|
2497
|
-
throw new Error(`invalid JSON: ${err.message}`);
|
|
2498
|
-
}
|
|
2499
|
-
if (!Array.isArray(parsed)) {
|
|
2500
|
-
throw new Error("expected a JSON array of members");
|
|
2501
|
-
}
|
|
2502
|
-
const body = {
|
|
2503
|
-
members: parsed.map((s, i) => {
|
|
2504
|
-
const row = s;
|
|
2505
|
-
if (!row || typeof row.profileId !== "string" || typeof row.agentName !== "string") {
|
|
2506
|
-
throw new Error(`member ${i}: profileId and agentName are required strings`);
|
|
2507
|
-
}
|
|
2508
|
-
return {
|
|
2509
|
-
profileId: row.profileId,
|
|
2510
|
-
agentName: row.agentName,
|
|
2511
|
-
modelOverride: row.modelOverride ?? null,
|
|
2512
|
-
reasoningLevel: row.reasoningLevel === null || row.reasoningLevel === void 0 ? null : row.reasoningLevel
|
|
2513
|
-
};
|
|
2514
|
-
})
|
|
2515
|
-
};
|
|
2516
|
-
await client.put(`/api/profile-groups/${args.id}/members`, body);
|
|
2517
|
-
console.log(`saved ${body.members.length} member(s)`);
|
|
2518
|
-
} finally {
|
|
2519
|
-
try {
|
|
2520
|
-
rmSync3(tmpPath, { force: true });
|
|
2521
|
-
} catch {
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
});
|
|
2526
|
-
var deleteCmd3 = defineCommand14({
|
|
2527
|
-
meta: { name: "delete", description: "Delete a profile group (does not affect spawned agents)" },
|
|
2528
|
-
args: {
|
|
2529
|
-
id: { type: "positional", required: true }
|
|
2530
|
-
},
|
|
2531
|
-
async run({ args }) {
|
|
2532
|
-
const client = createClient2();
|
|
2533
|
-
await client.del(`/api/profile-groups/${args.id}`);
|
|
2534
|
-
console.log(`deleted profile group ${args.id}`);
|
|
2535
|
-
}
|
|
2536
|
-
});
|
|
2537
|
-
var spawnCmd2 = defineCommand14({
|
|
2538
|
-
meta: { name: "spawn", description: "Spawn the whole team into a group (transactional)" },
|
|
2539
|
-
args: {
|
|
2540
|
-
id: { type: "positional", required: true },
|
|
2541
|
-
group: {
|
|
2542
|
-
type: "string",
|
|
2543
|
-
description: "Target group slug (overrides the template default)"
|
|
2544
|
-
},
|
|
2545
|
-
"user-md-file": {
|
|
2546
|
-
type: "string",
|
|
2547
|
-
description: "Path to USER.md content to seed (only takes effect on a fresh target group)"
|
|
2548
|
-
}
|
|
2549
|
-
},
|
|
2550
|
-
async run({ args }) {
|
|
2551
|
-
const body = {};
|
|
2552
|
-
if (args.group) body.groupSlug = args.group;
|
|
2553
|
-
if (args["user-md-file"]) body.userMd = readFileSync6(args["user-md-file"], "utf8");
|
|
2554
|
-
const client = createClient2();
|
|
2555
|
-
const result = await client.post(
|
|
2556
|
-
`/api/profile-groups/${args.id}/spawn`,
|
|
2557
|
-
body
|
|
2558
|
-
);
|
|
2559
|
-
console.log(`spawned ${result.agents.length} agent(s) into group ${result.groupSlug}`);
|
|
2560
|
-
const rows = result.agents.map((a) => [a.id, a.name]);
|
|
2561
|
-
for (const line of columnize(rows)) console.log(` ${line}`);
|
|
2562
|
-
if (result.orphanAgentIds && result.orphanAgentIds.length > 0) {
|
|
2563
|
-
console.error("");
|
|
2564
|
-
console.error(`warning: ${result.orphanAgentIds.length} orphan agent dir(s) left on disk:`);
|
|
2565
|
-
for (const id of result.orphanAgentIds) console.error(` ${id}`);
|
|
2566
|
-
process.exitCode = 1;
|
|
2567
|
-
}
|
|
2568
|
-
}
|
|
2569
|
-
});
|
|
2570
|
-
var profileGroupCommand = defineCommand14({
|
|
2571
|
-
meta: { name: "profile-group", description: "Manage profile groups" },
|
|
2572
|
-
subCommands: {
|
|
2573
|
-
create: createCmd3,
|
|
2574
|
-
list: listCmd8,
|
|
2575
|
-
show: showCmd5,
|
|
2576
|
-
update: updateCmd2,
|
|
2577
|
-
edit: editCmd3,
|
|
2578
|
-
delete: deleteCmd3,
|
|
2579
|
-
spawn: spawnCmd2
|
|
2580
|
-
}
|
|
2581
|
-
});
|
|
2582
|
-
|
|
2583
|
-
// src/commands/provider.ts
|
|
2584
|
-
import { defineCommand as defineCommand15 } from "citty";
|
|
2585
|
-
var listCmd9 = defineCommand15({
|
|
2586
|
-
meta: {
|
|
2587
|
-
name: "list",
|
|
2588
|
-
description: "List all providers with enabled/disabled state and curated model counts"
|
|
2589
|
-
},
|
|
2590
|
-
args: {
|
|
2591
|
-
enabled: { type: "boolean", description: "Show only enabled providers" }
|
|
2592
|
-
},
|
|
2593
|
-
async run({ args }) {
|
|
2594
|
-
const client = createClient2();
|
|
2595
|
-
const { providers } = await client.get("/api/config/providers");
|
|
2596
|
-
const filtered = args.enabled ? providers.filter((p) => p.enabled) : providers;
|
|
2597
|
-
if (filtered.length === 0) {
|
|
2598
|
-
console.log("(no providers to show)");
|
|
2599
|
-
return;
|
|
2600
|
-
}
|
|
2601
|
-
const rows = filtered.map((p) => [
|
|
2602
|
-
p.id,
|
|
2603
|
-
p.enabled ? "enabled" : "disabled",
|
|
2604
|
-
`${p.curated.length} curated`,
|
|
2605
|
-
`${p.catalog.length} catalog`,
|
|
2606
|
-
p.enabled ? "" : `(set ${p.envHint})`
|
|
2607
|
-
]);
|
|
2608
|
-
for (const line of columnize(rows)) console.log(line);
|
|
2609
|
-
}
|
|
2610
|
-
});
|
|
2611
|
-
var modelsCmd = defineCommand15({
|
|
2612
|
-
meta: {
|
|
2613
|
-
name: "models",
|
|
2614
|
-
description: "Show curated + catalog + live models for one provider"
|
|
2615
|
-
},
|
|
2616
|
-
args: {
|
|
2617
|
-
name: { type: "positional", required: true, description: "Provider name" }
|
|
2618
|
-
},
|
|
2619
|
-
async run({ args }) {
|
|
2620
|
-
const client = createClient2();
|
|
2621
|
-
const { providers } = await client.get("/api/config/providers");
|
|
2622
|
-
const p = providers.find((x) => x.id === args.name);
|
|
2623
|
-
if (!p) {
|
|
2624
|
-
console.error(`unknown provider: ${args.name}`);
|
|
2625
|
-
process.exit(1);
|
|
2626
|
-
}
|
|
2627
|
-
console.log(`# ${p.id} (${p.enabled ? "enabled" : "disabled"})`);
|
|
2628
|
-
if (!p.enabled) console.log(` (set ${p.envHint} to enable)`);
|
|
2629
|
-
console.log("\n## curated");
|
|
2630
|
-
if (p.curated.length === 0) console.log(" (none \u2014 use `provider models-set` to pin some)");
|
|
2631
|
-
else for (const m of p.curated) console.log(` ${m}`);
|
|
2632
|
-
console.log("\n## catalog (from pi-ai)");
|
|
2633
|
-
if (p.catalog.length === 0) console.log(" (empty)");
|
|
2634
|
-
else for (const m of p.catalog) console.log(` ${m}`);
|
|
2635
|
-
if (p.live) {
|
|
2636
|
-
console.log("\n## live (from upstream /v1/models)");
|
|
2637
|
-
if (p.live.error) console.log(` (error: ${p.live.error})`);
|
|
2638
|
-
else if (p.live.models.length === 0) console.log(" (empty)");
|
|
2639
|
-
else for (const m of p.live.models) console.log(` ${m}`);
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
});
|
|
2643
|
-
var modelsSetCmd = defineCommand15({
|
|
2644
|
-
meta: {
|
|
2645
|
-
name: "models-set",
|
|
2646
|
-
description: "Replace the curated model list for a provider (comma-separated)"
|
|
2647
|
-
},
|
|
2382
|
+
var modelsSetCmd = defineCommand14({
|
|
2383
|
+
meta: {
|
|
2384
|
+
name: "models-set",
|
|
2385
|
+
description: "Replace the curated model list for a provider (comma-separated)"
|
|
2386
|
+
},
|
|
2648
2387
|
args: {
|
|
2649
2388
|
name: { type: "positional", required: true, description: "Provider name" },
|
|
2650
2389
|
models: {
|
|
@@ -2665,7 +2404,7 @@ var modelsSetCmd = defineCommand15({
|
|
|
2665
2404
|
for (const m of saved.models) console.log(` ${m}`);
|
|
2666
2405
|
}
|
|
2667
2406
|
});
|
|
2668
|
-
var enableCmd2 =
|
|
2407
|
+
var enableCmd2 = defineCommand14({
|
|
2669
2408
|
meta: { name: "enable", description: "Toggle a provider on so agents can use it" },
|
|
2670
2409
|
args: {
|
|
2671
2410
|
name: { type: "positional", required: true, description: "Provider id (e.g. anthropic)" }
|
|
@@ -2679,7 +2418,7 @@ var enableCmd2 = defineCommand15({
|
|
|
2679
2418
|
console.log(`${res.name}: enabled`);
|
|
2680
2419
|
}
|
|
2681
2420
|
});
|
|
2682
|
-
var disableCmd2 =
|
|
2421
|
+
var disableCmd2 = defineCommand14({
|
|
2683
2422
|
meta: {
|
|
2684
2423
|
name: "disable",
|
|
2685
2424
|
description: "Toggle a provider off \u2014 agents will refuse its model strings"
|
|
@@ -2696,7 +2435,7 @@ var disableCmd2 = defineCommand15({
|
|
|
2696
2435
|
console.log(`${res.name}: disabled`);
|
|
2697
2436
|
}
|
|
2698
2437
|
});
|
|
2699
|
-
var testCmd2 =
|
|
2438
|
+
var testCmd2 = defineCommand14({
|
|
2700
2439
|
meta: { name: "test", description: "Send a single chat to a model and print the reply" },
|
|
2701
2440
|
args: {
|
|
2702
2441
|
model: {
|
|
@@ -2717,10 +2456,10 @@ var testCmd2 = defineCommand15({
|
|
|
2717
2456
|
}
|
|
2718
2457
|
}
|
|
2719
2458
|
});
|
|
2720
|
-
var providerCommand =
|
|
2459
|
+
var providerCommand = defineCommand14({
|
|
2721
2460
|
meta: { name: "provider", description: "Manage and test LLM providers" },
|
|
2722
2461
|
subCommands: {
|
|
2723
|
-
list:
|
|
2462
|
+
list: listCmd7,
|
|
2724
2463
|
enable: enableCmd2,
|
|
2725
2464
|
disable: disableCmd2,
|
|
2726
2465
|
models: modelsCmd,
|
|
@@ -2730,8 +2469,8 @@ var providerCommand = defineCommand15({
|
|
|
2730
2469
|
});
|
|
2731
2470
|
|
|
2732
2471
|
// src/commands/send.ts
|
|
2733
|
-
import { defineCommand as
|
|
2734
|
-
var sendCommand =
|
|
2472
|
+
import { defineCommand as defineCommand15 } from "citty";
|
|
2473
|
+
var sendCommand = defineCommand15({
|
|
2735
2474
|
meta: {
|
|
2736
2475
|
name: "send",
|
|
2737
2476
|
description: "Send a message from one agent to another"
|
|
@@ -2747,20 +2486,29 @@ var sendCommand = defineCommand16({
|
|
|
2747
2486
|
from: args.from,
|
|
2748
2487
|
payload: { text: args.message }
|
|
2749
2488
|
};
|
|
2750
|
-
const
|
|
2751
|
-
|
|
2489
|
+
const result = await client.post(
|
|
2490
|
+
`/api/agents/${args.to}/messages`,
|
|
2491
|
+
body
|
|
2492
|
+
);
|
|
2493
|
+
if ("approvalId" in result) {
|
|
2494
|
+
console.log(
|
|
2495
|
+
`pending approval ${result.approvalId} (expires ${new Date(result.expiresAt).toISOString()})`
|
|
2496
|
+
);
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
2499
|
+
console.log(`sent message ${result.id}`);
|
|
2752
2500
|
}
|
|
2753
2501
|
});
|
|
2754
2502
|
|
|
2755
2503
|
// src/commands/serve.ts
|
|
2756
|
-
import { spawn as
|
|
2504
|
+
import { spawn as spawn4 } from "child_process";
|
|
2757
2505
|
import { existsSync as existsSync5 } from "fs";
|
|
2758
|
-
import { join as
|
|
2759
|
-
import { defineCommand as
|
|
2760
|
-
var bundledDaemonEntry2 =
|
|
2761
|
-
var sourceDaemonEntry2 =
|
|
2506
|
+
import { join as join4 } from "path";
|
|
2507
|
+
import { defineCommand as defineCommand16 } from "citty";
|
|
2508
|
+
var bundledDaemonEntry2 = join4(import.meta.dirname, "daemon.js");
|
|
2509
|
+
var sourceDaemonEntry2 = join4(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
|
|
2762
2510
|
var daemonEntry2 = existsSync5(bundledDaemonEntry2) ? bundledDaemonEntry2 : sourceDaemonEntry2;
|
|
2763
|
-
var serveCommand =
|
|
2511
|
+
var serveCommand = defineCommand16({
|
|
2764
2512
|
meta: {
|
|
2765
2513
|
name: "serve",
|
|
2766
2514
|
description: "Start the bazilion daemon (HTTP API)"
|
|
@@ -2793,7 +2541,7 @@ var serveCommand = defineCommand17({
|
|
|
2793
2541
|
console.log(`starting bazilion daemon at http://${host}:${port}`);
|
|
2794
2542
|
console.log("(web UI runs separately: cd apps/web && pnpm dev)");
|
|
2795
2543
|
const nodeArgs2 = daemonEntry2.endsWith(".ts") ? ["--import", "tsx/esm", daemonEntry2] : [daemonEntry2];
|
|
2796
|
-
const proc =
|
|
2544
|
+
const proc = spawn4("node", nodeArgs2, {
|
|
2797
2545
|
env,
|
|
2798
2546
|
stdio: "inherit"
|
|
2799
2547
|
});
|
|
@@ -2827,10 +2575,16 @@ var serveCommand = defineCommand17({
|
|
|
2827
2575
|
});
|
|
2828
2576
|
|
|
2829
2577
|
// src/commands/skill.ts
|
|
2830
|
-
import { existsSync as existsSync6, readFileSync as
|
|
2578
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5, statSync } from "fs";
|
|
2831
2579
|
import { basename as basename2, resolve as resolve2 } from "path";
|
|
2832
|
-
import { defineCommand as
|
|
2833
|
-
|
|
2580
|
+
import { defineCommand as defineCommand17 } from "citty";
|
|
2581
|
+
function printFindings(findings, prefix = " ") {
|
|
2582
|
+
for (const f of findings) {
|
|
2583
|
+
const line = f.line ? ` line ${f.line}` : "";
|
|
2584
|
+
console.log(`${prefix}${f.severity}: ${f.code}${line} - ${f.message}`);
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
var listCmd8 = defineCommand17({
|
|
2834
2588
|
meta: { name: "list", description: "List installed skills (or those attached to an agent)" },
|
|
2835
2589
|
args: {
|
|
2836
2590
|
agent: { type: "string", description: "Filter to skills attached to this agent" }
|
|
@@ -2860,9 +2614,18 @@ var listCmd10 = defineCommand18({
|
|
|
2860
2614
|
s.parseError ? `(parse error: ${s.parseError})` : s.description
|
|
2861
2615
|
]);
|
|
2862
2616
|
for (const line of columnize(rows)) console.log(line);
|
|
2617
|
+
const flagged = skills.filter((s) => s.scanFindings && s.scanFindings.length > 0);
|
|
2618
|
+
if (flagged.length > 0) {
|
|
2619
|
+
console.log("");
|
|
2620
|
+
console.log("scan findings:");
|
|
2621
|
+
for (const s of flagged) {
|
|
2622
|
+
console.log(`${s.name}:`);
|
|
2623
|
+
printFindings(s.scanFindings ?? []);
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2863
2626
|
}
|
|
2864
2627
|
});
|
|
2865
|
-
var importCmd =
|
|
2628
|
+
var importCmd = defineCommand17({
|
|
2866
2629
|
meta: {
|
|
2867
2630
|
name: "import",
|
|
2868
2631
|
description: "Import skills from openclaw, a directory, or a local .zip archive"
|
|
@@ -2880,19 +2643,36 @@ var importCmd = defineCommand18({
|
|
|
2880
2643
|
const absFrom = resolve2(args.from);
|
|
2881
2644
|
const isLocalZip = args.from.toLowerCase().endsWith(".zip") && existsSync6(absFrom) && statSync(absFrom).isFile();
|
|
2882
2645
|
let result;
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2646
|
+
try {
|
|
2647
|
+
if (isLocalZip) {
|
|
2648
|
+
const bytes = readFileSync5(absFrom);
|
|
2649
|
+
const file = new File([bytes], basename2(absFrom), { type: "application/zip" });
|
|
2650
|
+
const fd = new FormData();
|
|
2651
|
+
fd.set("file", file);
|
|
2652
|
+
if (args.force) fd.set("force", "true");
|
|
2653
|
+
result = await client.postMultipart("/api/skills/import", fd);
|
|
2654
|
+
} else {
|
|
2655
|
+
const body = {
|
|
2656
|
+
source: args.from,
|
|
2657
|
+
force: args.force
|
|
2658
|
+
};
|
|
2659
|
+
result = await client.post("/api/skills/import", body);
|
|
2660
|
+
}
|
|
2661
|
+
} catch (err) {
|
|
2662
|
+
if (err instanceof ApiClientError && err.body.code === "skill_scan_blocked") {
|
|
2663
|
+
console.error(`error: ${err.body.error}`);
|
|
2664
|
+
if (err.body.findings && err.body.findings.length > 0) {
|
|
2665
|
+
console.error("scan findings:");
|
|
2666
|
+
for (const f of err.body.findings) {
|
|
2667
|
+
const line = f.line ? ` line ${f.line}` : "";
|
|
2668
|
+
console.error(` ${f.severity}: ${f.code}${line} - ${f.message}`);
|
|
2669
|
+
}
|
|
2670
|
+
}
|
|
2671
|
+
console.error(" hint: inspect the skill, then rerun with --force to confirm");
|
|
2672
|
+
process.exitCode = 1;
|
|
2673
|
+
return;
|
|
2674
|
+
}
|
|
2675
|
+
throw err;
|
|
2896
2676
|
}
|
|
2897
2677
|
if (result.imported.length === 0 && result.skipped.length === 0) {
|
|
2898
2678
|
console.log("(nothing to import)");
|
|
@@ -2904,9 +2684,17 @@ var importCmd = defineCommand18({
|
|
|
2904
2684
|
for (const s of result.skipped) {
|
|
2905
2685
|
console.log(`skipped ${s.name}: ${s.reason}`);
|
|
2906
2686
|
}
|
|
2687
|
+
if (result.findings && Object.keys(result.findings).length > 0) {
|
|
2688
|
+
console.log("");
|
|
2689
|
+
console.log("confirmed scan findings:");
|
|
2690
|
+
for (const [name, findings] of Object.entries(result.findings)) {
|
|
2691
|
+
console.log(`${name}:`);
|
|
2692
|
+
printFindings(findings);
|
|
2693
|
+
}
|
|
2694
|
+
}
|
|
2907
2695
|
}
|
|
2908
2696
|
});
|
|
2909
|
-
var
|
|
2697
|
+
var rmCmd4 = defineCommand17({
|
|
2910
2698
|
meta: { name: "rm", description: "Remove an installed skill" },
|
|
2911
2699
|
args: {
|
|
2912
2700
|
name: { type: "positional", required: true }
|
|
@@ -2917,18 +2705,844 @@ var rmCmd5 = defineCommand18({
|
|
|
2917
2705
|
console.log(`removed skill ${args.name}`);
|
|
2918
2706
|
}
|
|
2919
2707
|
});
|
|
2920
|
-
var skillCommand =
|
|
2708
|
+
var skillCommand = defineCommand17({
|
|
2921
2709
|
meta: { name: "skill", description: "Manage the skill library" },
|
|
2922
2710
|
subCommands: {
|
|
2923
|
-
list:
|
|
2711
|
+
list: listCmd8,
|
|
2924
2712
|
import: importCmd,
|
|
2925
|
-
rm:
|
|
2713
|
+
rm: rmCmd4
|
|
2926
2714
|
}
|
|
2927
2715
|
});
|
|
2928
2716
|
|
|
2929
|
-
// src/commands/
|
|
2717
|
+
// src/commands/team.ts
|
|
2718
|
+
import { readFileSync as readFileSync7 } from "fs";
|
|
2719
|
+
import { stdin as stdin2 } from "process";
|
|
2930
2720
|
import { defineCommand as defineCommand19 } from "citty";
|
|
2931
|
-
|
|
2721
|
+
|
|
2722
|
+
// src/commands/team-policy.ts
|
|
2723
|
+
import { readFileSync as readFileSync6 } from "fs";
|
|
2724
|
+
import { defineCommand as defineCommand18 } from "citty";
|
|
2725
|
+
|
|
2726
|
+
// src/team-interchange.ts
|
|
2727
|
+
var TEAM_POLICY_INTERCHANGE_VERSION = 1;
|
|
2728
|
+
var TEAM_DOCUMENT_KIND = "bazilion.team-template";
|
|
2729
|
+
var TEAM_POLICY_DOCUMENT_KIND = "bazilion.team-policy";
|
|
2730
|
+
var reasoning = /* @__PURE__ */ new Set(["off", "minimal", "low", "medium", "high", "xhigh"]);
|
|
2731
|
+
var templateKinds = /* @__PURE__ */ new Set(["user", "outside_team", "slot"]);
|
|
2732
|
+
var liveKinds = /* @__PURE__ */ new Set(["user", "outside_team", "agent"]);
|
|
2733
|
+
function object(value, label) {
|
|
2734
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
2735
|
+
throw new Error(`${label} must be an object`);
|
|
2736
|
+
return value;
|
|
2737
|
+
}
|
|
2738
|
+
function text(value, label) {
|
|
2739
|
+
if (typeof value !== "string" || !value.trim()) throw new Error(`${label} is required`);
|
|
2740
|
+
return value.trim();
|
|
2741
|
+
}
|
|
2742
|
+
function nullableText(value, label) {
|
|
2743
|
+
if (value === null || value === void 0) return null;
|
|
2744
|
+
if (typeof value !== "string") throw new Error(`${label} must be a string or null`);
|
|
2745
|
+
return value;
|
|
2746
|
+
}
|
|
2747
|
+
function endpointKey(kind, key) {
|
|
2748
|
+
return `${kind}:${key ?? "-"}`;
|
|
2749
|
+
}
|
|
2750
|
+
function exportTeamDocument(detail) {
|
|
2751
|
+
const keyById = new Map(detail.slots.map((slot, index) => [slot.slotId, `slot-${index + 1}`]));
|
|
2752
|
+
return {
|
|
2753
|
+
version: TEAM_POLICY_INTERCHANGE_VERSION,
|
|
2754
|
+
kind: TEAM_DOCUMENT_KIND,
|
|
2755
|
+
template: {
|
|
2756
|
+
id: detail.template.id,
|
|
2757
|
+
name: detail.template.name,
|
|
2758
|
+
userMd: detail.template.userMd
|
|
2759
|
+
},
|
|
2760
|
+
slots: detail.slots.map((slot) => ({
|
|
2761
|
+
key: keyById.get(slot.slotId),
|
|
2762
|
+
profileId: slot.profileId,
|
|
2763
|
+
agentName: slot.agentName,
|
|
2764
|
+
modelOverride: slot.modelOverride,
|
|
2765
|
+
reasoningLevel: slot.reasoningLevel,
|
|
2766
|
+
layoutPosition: slot.layoutPosition,
|
|
2767
|
+
display: slot.display
|
|
2768
|
+
})),
|
|
2769
|
+
edges: detail.edges.map((edge) => ({
|
|
2770
|
+
sourceKind: edge.sourceKind,
|
|
2771
|
+
sourceKey: edge.sourceKind === "slot" ? keyById.get(edge.sourceId ?? "") ?? null : null,
|
|
2772
|
+
targetKind: edge.targetKind,
|
|
2773
|
+
targetKey: edge.targetKind === "slot" ? keyById.get(edge.targetId ?? "") ?? null : null,
|
|
2774
|
+
posture: edge.posture
|
|
2775
|
+
}))
|
|
2776
|
+
};
|
|
2777
|
+
}
|
|
2778
|
+
function parseTeamDocument(value) {
|
|
2779
|
+
const root = object(value, "document");
|
|
2780
|
+
if (root.version !== TEAM_POLICY_INTERCHANGE_VERSION)
|
|
2781
|
+
throw new Error(`unsupported Team Policy document version: ${String(root.version)}`);
|
|
2782
|
+
if (root.kind !== TEAM_DOCUMENT_KIND)
|
|
2783
|
+
throw new Error(`invalid document kind: expected ${TEAM_DOCUMENT_KIND}`);
|
|
2784
|
+
const meta = object(root.template, "template");
|
|
2785
|
+
const rawSlots = Array.isArray(root.slots) ? root.slots : null;
|
|
2786
|
+
const rawEdges = Array.isArray(root.edges) ? root.edges : null;
|
|
2787
|
+
if (!rawSlots || !rawEdges) throw new Error("slots and edges must be arrays");
|
|
2788
|
+
const keys = /* @__PURE__ */ new Set();
|
|
2789
|
+
const slots = rawSlots.map((raw, index) => {
|
|
2790
|
+
const slot = object(raw, `slot ${index}`);
|
|
2791
|
+
const key = text(slot.key, `slot ${index} key`);
|
|
2792
|
+
if (keys.has(key)) throw new Error(`duplicate slot key: ${key}`);
|
|
2793
|
+
keys.add(key);
|
|
2794
|
+
const level = slot.reasoningLevel;
|
|
2795
|
+
if (level !== null && level !== void 0 && !reasoning.has(level))
|
|
2796
|
+
throw new Error(`slot ${index} has invalid reasoningLevel`);
|
|
2797
|
+
const position = slot.layoutPosition;
|
|
2798
|
+
if (position !== null && position !== void 0 && (!position || typeof position !== "object" || Array.isArray(position) || !Number.isFinite(position.x) || !Number.isFinite(position.y)))
|
|
2799
|
+
throw new Error(`slot ${index} has invalid layoutPosition`);
|
|
2800
|
+
const display = slot.display;
|
|
2801
|
+
if (display !== null && display !== void 0 && (!display || typeof display !== "object" || Array.isArray(display)))
|
|
2802
|
+
throw new Error(`slot ${index} has invalid display`);
|
|
2803
|
+
return {
|
|
2804
|
+
key,
|
|
2805
|
+
profileId: text(slot.profileId, `slot ${index} profileId`),
|
|
2806
|
+
agentName: text(slot.agentName, `slot ${index} agentName`),
|
|
2807
|
+
modelOverride: nullableText(slot.modelOverride, `slot ${index} modelOverride`),
|
|
2808
|
+
reasoningLevel: level ?? null,
|
|
2809
|
+
layoutPosition: position ?? null,
|
|
2810
|
+
display: display ?? null
|
|
2811
|
+
};
|
|
2812
|
+
});
|
|
2813
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2814
|
+
const edges = rawEdges.map((raw, index) => {
|
|
2815
|
+
const edge = object(raw, `edge ${index}`);
|
|
2816
|
+
if (!templateKinds.has(String(edge.sourceKind)) || !templateKinds.has(String(edge.targetKind)))
|
|
2817
|
+
throw new Error(`edge ${index} has invalid endpoint kind`);
|
|
2818
|
+
const sourceKind = edge.sourceKind;
|
|
2819
|
+
const targetKind = edge.targetKind;
|
|
2820
|
+
const sourceKey = nullableText(edge.sourceKey, `edge ${index} sourceKey`);
|
|
2821
|
+
const targetKey = nullableText(edge.targetKey, `edge ${index} targetKey`);
|
|
2822
|
+
const posture = edge.posture === void 0 || edge.posture === "allow" ? "allow" : edge.posture === "approval_required" ? "approval_required" : null;
|
|
2823
|
+
if (!posture) throw new Error(`edge ${index} has invalid posture`);
|
|
2824
|
+
if (sourceKind === "slot" !== Boolean(sourceKey))
|
|
2825
|
+
throw new Error(`edge ${index} source slot key is missing or invalid`);
|
|
2826
|
+
if (targetKind === "slot" !== Boolean(targetKey))
|
|
2827
|
+
throw new Error(`edge ${index} target slot key is missing or invalid`);
|
|
2828
|
+
if (sourceKey && !keys.has(sourceKey))
|
|
2829
|
+
throw new Error(`edge ${index} references missing slot ${sourceKey}`);
|
|
2830
|
+
if (targetKey && !keys.has(targetKey))
|
|
2831
|
+
throw new Error(`edge ${index} references missing slot ${targetKey}`);
|
|
2832
|
+
const signature = `${endpointKey(sourceKind, sourceKey)}->${endpointKey(targetKind, targetKey)}`;
|
|
2833
|
+
if (endpointKey(sourceKind, sourceKey) === endpointKey(targetKind, targetKey))
|
|
2834
|
+
throw new Error(`edge ${index} is a self edge`);
|
|
2835
|
+
if (seen.has(signature)) throw new Error(`duplicate edge: ${signature}`);
|
|
2836
|
+
seen.add(signature);
|
|
2837
|
+
return { sourceKind, sourceKey, targetKind, targetKey, posture };
|
|
2838
|
+
});
|
|
2839
|
+
return {
|
|
2840
|
+
version: 1,
|
|
2841
|
+
kind: TEAM_DOCUMENT_KIND,
|
|
2842
|
+
template: {
|
|
2843
|
+
id: text(meta.id, "template id"),
|
|
2844
|
+
name: text(meta.name, "template name"),
|
|
2845
|
+
userMd: nullableText(meta.userMd, "template userMd")
|
|
2846
|
+
},
|
|
2847
|
+
slots,
|
|
2848
|
+
edges
|
|
2849
|
+
};
|
|
2850
|
+
}
|
|
2851
|
+
function teamImportBody(document, existing) {
|
|
2852
|
+
const currentByKey = existing ? new Map(existing.slots.map((slot, index) => [`slot-${index + 1}`, slot.slotId])) : /* @__PURE__ */ new Map();
|
|
2853
|
+
const slots = document.slots.map((slot) => ({
|
|
2854
|
+
...currentByKey.has(slot.key) ? { slotId: currentByKey.get(slot.key) } : { clientKey: slot.key },
|
|
2855
|
+
profileId: slot.profileId,
|
|
2856
|
+
agentName: slot.agentName,
|
|
2857
|
+
modelOverride: slot.modelOverride,
|
|
2858
|
+
reasoningLevel: slot.reasoningLevel,
|
|
2859
|
+
layoutPosition: slot.layoutPosition,
|
|
2860
|
+
display: slot.display
|
|
2861
|
+
}));
|
|
2862
|
+
const idByKey = new Map(
|
|
2863
|
+
slots.map((slot, index) => [
|
|
2864
|
+
document.slots[index]?.key,
|
|
2865
|
+
slot.slotId ?? slot.clientKey ?? null
|
|
2866
|
+
])
|
|
2867
|
+
);
|
|
2868
|
+
const edges = document.edges.map((edge) => ({
|
|
2869
|
+
sourceKind: edge.sourceKind,
|
|
2870
|
+
sourceId: edge.sourceKind === "slot" ? idByKey.get(edge.sourceKey ?? "") : null,
|
|
2871
|
+
targetKind: edge.targetKind,
|
|
2872
|
+
targetId: edge.targetKind === "slot" ? idByKey.get(edge.targetKey ?? "") : null,
|
|
2873
|
+
posture: edge.posture
|
|
2874
|
+
}));
|
|
2875
|
+
return { slots, edges };
|
|
2876
|
+
}
|
|
2877
|
+
function parseTeamPolicyDocument(value) {
|
|
2878
|
+
const root = object(value, "document");
|
|
2879
|
+
if (root.version !== 1)
|
|
2880
|
+
throw new Error(`unsupported Team Policy document version: ${String(root.version)}`);
|
|
2881
|
+
if (root.kind !== TEAM_POLICY_DOCUMENT_KIND)
|
|
2882
|
+
throw new Error(`invalid document kind: expected ${TEAM_POLICY_DOCUMENT_KIND}`);
|
|
2883
|
+
if (!Number.isInteger(root.expectedRevision) || Number(root.expectedRevision) < 1)
|
|
2884
|
+
throw new Error("expectedRevision must be a positive integer");
|
|
2885
|
+
if (!Array.isArray(root.edges)) throw new Error("edges must be an array");
|
|
2886
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2887
|
+
const edges = root.edges.map((raw, index) => {
|
|
2888
|
+
const edge = object(raw, `edge ${index}`);
|
|
2889
|
+
if (!liveKinds.has(String(edge.sourceKind)) || !liveKinds.has(String(edge.targetKind)))
|
|
2890
|
+
throw new Error(`edge ${index} has invalid endpoint kind`);
|
|
2891
|
+
const sourceKind = edge.sourceKind;
|
|
2892
|
+
const targetKind = edge.targetKind;
|
|
2893
|
+
const sourceId = nullableText(edge.sourceId, `edge ${index} sourceId`);
|
|
2894
|
+
const targetId = nullableText(edge.targetId, `edge ${index} targetId`);
|
|
2895
|
+
if (sourceKind === "agent" !== Boolean(sourceId) || targetKind === "agent" !== Boolean(targetId))
|
|
2896
|
+
throw new Error(`edge ${index} Agent id is missing or invalid`);
|
|
2897
|
+
const signature = `${endpointKey(sourceKind, sourceId)}->${endpointKey(targetKind, targetId)}`;
|
|
2898
|
+
if (endpointKey(sourceKind, sourceId) === endpointKey(targetKind, targetId))
|
|
2899
|
+
throw new Error(`edge ${index} is a self edge`);
|
|
2900
|
+
if (seen.has(signature)) throw new Error(`duplicate edge: ${signature}`);
|
|
2901
|
+
seen.add(signature);
|
|
2902
|
+
return { sourceKind, sourceId, targetKind, targetId };
|
|
2903
|
+
});
|
|
2904
|
+
return {
|
|
2905
|
+
version: 1,
|
|
2906
|
+
kind: TEAM_POLICY_DOCUMENT_KIND,
|
|
2907
|
+
teamId: text(root.teamId, "teamId"),
|
|
2908
|
+
expectedRevision: Number(root.expectedRevision),
|
|
2909
|
+
edges
|
|
2910
|
+
};
|
|
2911
|
+
}
|
|
2912
|
+
function exportTeamPolicy(teamId, revision, edges) {
|
|
2913
|
+
return {
|
|
2914
|
+
version: 1,
|
|
2915
|
+
kind: TEAM_POLICY_DOCUMENT_KIND,
|
|
2916
|
+
teamId,
|
|
2917
|
+
expectedRevision: revision,
|
|
2918
|
+
edges: edges.map(({ sourceKind, sourceId, targetKind, targetId, posture }) => ({
|
|
2919
|
+
sourceKind,
|
|
2920
|
+
sourceId,
|
|
2921
|
+
targetKind,
|
|
2922
|
+
targetId,
|
|
2923
|
+
posture
|
|
2924
|
+
}))
|
|
2925
|
+
};
|
|
2926
|
+
}
|
|
2927
|
+
function edgeDiff(before, after) {
|
|
2928
|
+
const signature = (edge) => `${endpointKey(edge.sourceKind, edge.sourceId ?? null)} -> ${endpointKey(edge.targetKind, edge.targetId ?? null)} [${edge.posture ?? "allow"}]`;
|
|
2929
|
+
const left = new Set(before.map(signature));
|
|
2930
|
+
const right = new Set(after.map(signature));
|
|
2931
|
+
return {
|
|
2932
|
+
added: [...right].filter((value) => !left.has(value)).sort(),
|
|
2933
|
+
removed: [...left].filter((value) => !right.has(value)).sort()
|
|
2934
|
+
};
|
|
2935
|
+
}
|
|
2936
|
+
|
|
2937
|
+
// src/commands/team-policy.ts
|
|
2938
|
+
function readJson(path) {
|
|
2939
|
+
try {
|
|
2940
|
+
return JSON.parse(readFileSync6(path, "utf8"));
|
|
2941
|
+
} catch (error) {
|
|
2942
|
+
throw new Error(`invalid JSON: ${error.message}`);
|
|
2943
|
+
}
|
|
2944
|
+
}
|
|
2945
|
+
function endpoint2(value, teamId) {
|
|
2946
|
+
if (value === "user") return { kind: "user", teamId };
|
|
2947
|
+
if (value.startsWith("agent:") && value.length > 6) return { kind: "agent", id: value.slice(6) };
|
|
2948
|
+
if (value.startsWith("outside:") && value.length > 8)
|
|
2949
|
+
return { kind: "outside_team", teamId: value.slice(8) };
|
|
2950
|
+
throw new Error("endpoint must be user, agent:<id>, or outside:<team-id>");
|
|
2951
|
+
}
|
|
2952
|
+
function printPolicy(detail) {
|
|
2953
|
+
console.log(`# Team ${detail.teamPolicy.teamId} policy`);
|
|
2954
|
+
console.log(`revision: ${detail.teamPolicy.revision}`);
|
|
2955
|
+
console.log(
|
|
2956
|
+
`baseline: ${detail.baseline ? `${detail.baseline.templateId}@${detail.baseline.templateRevision}` : "(none)"}`
|
|
2957
|
+
);
|
|
2958
|
+
console.log(`members: ${detail.members.length}`);
|
|
2959
|
+
console.log(`edges: ${detail.edges.length}`);
|
|
2960
|
+
if (detail.edges.length) {
|
|
2961
|
+
console.log("");
|
|
2962
|
+
for (const line of columnize([
|
|
2963
|
+
["source", "target"],
|
|
2964
|
+
...detail.edges.map((edge) => [
|
|
2965
|
+
`${edge.sourceKind}:${edge.sourceId ?? "-"}`,
|
|
2966
|
+
`${edge.targetKind}:${edge.targetId ?? "-"}`
|
|
2967
|
+
])
|
|
2968
|
+
]))
|
|
2969
|
+
console.log(line);
|
|
2970
|
+
}
|
|
2971
|
+
}
|
|
2972
|
+
var show2 = defineCommand18({
|
|
2973
|
+
meta: { name: "show", description: "Show the one effective live policy for a Team" },
|
|
2974
|
+
args: {
|
|
2975
|
+
team: { type: "positional", required: true },
|
|
2976
|
+
json: { type: "boolean", description: "Emit the canonical aggregate as JSON" }
|
|
2977
|
+
},
|
|
2978
|
+
async run({ args }) {
|
|
2979
|
+
const detail = await createClient2().get(
|
|
2980
|
+
`/api/teams/${encodeURIComponent(args.team)}/policy`
|
|
2981
|
+
);
|
|
2982
|
+
if (args.json) console.log(JSON.stringify(detail, null, 2));
|
|
2983
|
+
else printPolicy(detail);
|
|
2984
|
+
}
|
|
2985
|
+
});
|
|
2986
|
+
var exportCommand = defineCommand18({
|
|
2987
|
+
meta: { name: "export", description: "Export a revisioned Team policy document" },
|
|
2988
|
+
args: { team: { type: "positional", required: true } },
|
|
2989
|
+
async run({ args }) {
|
|
2990
|
+
const detail = await createClient2().get(
|
|
2991
|
+
`/api/teams/${encodeURIComponent(args.team)}/policy`
|
|
2992
|
+
);
|
|
2993
|
+
console.log(
|
|
2994
|
+
JSON.stringify(
|
|
2995
|
+
exportTeamPolicy(args.team, detail.teamPolicy.revision, detail.edges),
|
|
2996
|
+
null,
|
|
2997
|
+
2
|
|
2998
|
+
)
|
|
2999
|
+
);
|
|
3000
|
+
}
|
|
3001
|
+
});
|
|
3002
|
+
function printEdgeDiff(current, edges) {
|
|
3003
|
+
const diff2 = edgeDiff(current.edges, edges);
|
|
3004
|
+
console.log(`Team: ${current.teamPolicy.teamId}`);
|
|
3005
|
+
console.log(`Revision: ${current.teamPolicy.revision}`);
|
|
3006
|
+
console.log(`Edges: +${diff2.added.length} -${diff2.removed.length}`);
|
|
3007
|
+
for (const value of diff2.added) console.log(` + ${value}`);
|
|
3008
|
+
for (const value of diff2.removed) console.log(` - ${value}`);
|
|
3009
|
+
}
|
|
3010
|
+
var importCommand = defineCommand18({
|
|
3011
|
+
meta: {
|
|
3012
|
+
name: "import",
|
|
3013
|
+
description: "Validate, diff, and explicitly replace a Team policy"
|
|
3014
|
+
},
|
|
3015
|
+
args: {
|
|
3016
|
+
team: { type: "positional", required: true },
|
|
3017
|
+
file: { type: "positional", required: true },
|
|
3018
|
+
"dry-run": { type: "boolean", description: "Validate and print the diff only" },
|
|
3019
|
+
apply: { type: "boolean", description: "Apply non-interactively after printing the diff" },
|
|
3020
|
+
"expected-revision": {
|
|
3021
|
+
type: "string",
|
|
3022
|
+
description: "Expected current Team revision (defaults to document revision)"
|
|
3023
|
+
},
|
|
3024
|
+
force: {
|
|
3025
|
+
type: "boolean",
|
|
3026
|
+
description: "Refetch current revision; requires --apply and still uses optimistic locking"
|
|
3027
|
+
},
|
|
3028
|
+
"confirm-current-revision": {
|
|
3029
|
+
type: "string",
|
|
3030
|
+
description: "Second force confirmation: the freshly displayed current revision"
|
|
3031
|
+
}
|
|
3032
|
+
},
|
|
3033
|
+
async run({ args }) {
|
|
3034
|
+
if (args.force && !args.apply)
|
|
3035
|
+
throw new Error("--force requires --apply (interactive force is intentionally unsupported)");
|
|
3036
|
+
const document = parseTeamPolicyDocument(readJson(args.file));
|
|
3037
|
+
if (document.teamId !== args.team)
|
|
3038
|
+
throw new Error(`document belongs to Team ${document.teamId}, not ${args.team}`);
|
|
3039
|
+
const client = createClient2();
|
|
3040
|
+
const current = await client.get(
|
|
3041
|
+
`/api/teams/${encodeURIComponent(args.team)}/policy`
|
|
3042
|
+
);
|
|
3043
|
+
printEdgeDiff(current, document.edges);
|
|
3044
|
+
if (args["dry-run"]) return console.log("valid: no changes applied");
|
|
3045
|
+
if (!args.apply) throw new Error("refusing mutation: review the diff, then pass --apply");
|
|
3046
|
+
const supplied = args["expected-revision"] ? Number.parseInt(args["expected-revision"], 10) : document.expectedRevision;
|
|
3047
|
+
const expectedRevision = args.force ? current.teamPolicy.revision : supplied;
|
|
3048
|
+
if (args.force && Number.parseInt(args["confirm-current-revision"] ?? "", 10) !== current.teamPolicy.revision)
|
|
3049
|
+
throw new Error(
|
|
3050
|
+
`--force requires --confirm-current-revision ${current.teamPolicy.revision} after reviewing the fresh diff`
|
|
3051
|
+
);
|
|
3052
|
+
if (!Number.isInteger(expectedRevision) || expectedRevision < 1)
|
|
3053
|
+
throw new Error("expected revision must be a positive integer");
|
|
3054
|
+
const body = {
|
|
3055
|
+
expectedRevision,
|
|
3056
|
+
edges: document.edges
|
|
3057
|
+
};
|
|
3058
|
+
const updated = await client.put(
|
|
3059
|
+
`/api/teams/${encodeURIComponent(args.team)}/policy`,
|
|
3060
|
+
body
|
|
3061
|
+
);
|
|
3062
|
+
console.log(`updated Team ${args.team} policy to revision ${updated.teamPolicy.revision}`);
|
|
3063
|
+
}
|
|
3064
|
+
});
|
|
3065
|
+
var diff = defineCommand18({
|
|
3066
|
+
meta: { name: "diff", description: "Compare live policy with its retained baseline source" },
|
|
3067
|
+
args: {
|
|
3068
|
+
team: { type: "positional", required: true },
|
|
3069
|
+
json: { type: "boolean", description: "Emit canonical diff JSON" }
|
|
3070
|
+
},
|
|
3071
|
+
async run({ args }) {
|
|
3072
|
+
const result = await createClient2().get(
|
|
3073
|
+
`/api/teams/${encodeURIComponent(args.team)}/policy/diff`
|
|
3074
|
+
);
|
|
3075
|
+
if (args.json) return console.log(JSON.stringify(result, null, 2));
|
|
3076
|
+
console.log(`# Team ${args.team} source diff`);
|
|
3077
|
+
console.log(
|
|
3078
|
+
`status: ${result.baseline ? result.sourceDiverged ? "source diverged" : "source current" : "no baseline"}`
|
|
3079
|
+
);
|
|
3080
|
+
console.log(`revision: ${result.liveRevision}`);
|
|
3081
|
+
console.log(
|
|
3082
|
+
`edges: +${result.comparison.addedSinceBaseline.length} -${result.comparison.removedSinceBaseline.length}`
|
|
3083
|
+
);
|
|
3084
|
+
console.log(
|
|
3085
|
+
`slots: +${result.comparison.currentSourceAddedSlotIds.length} -${result.comparison.currentSourceRemovedSlotIds.length}`
|
|
3086
|
+
);
|
|
3087
|
+
}
|
|
3088
|
+
});
|
|
3089
|
+
var evaluate = defineCommand18({
|
|
3090
|
+
meta: {
|
|
3091
|
+
name: "evaluate",
|
|
3092
|
+
description: "Evaluate a communication path without sending or recording a block"
|
|
3093
|
+
},
|
|
3094
|
+
args: {
|
|
3095
|
+
team: { type: "positional", required: true, description: "Owning Team for context" },
|
|
3096
|
+
source: { type: "string", required: true, description: "user | agent:<id> | outside:<team>" },
|
|
3097
|
+
target: { type: "string", required: true, description: "user | agent:<id> | outside:<team>" },
|
|
3098
|
+
origin: { type: "string", default: "cli-diagnostic" },
|
|
3099
|
+
json: { type: "boolean", description: "Emit decision JSON" }
|
|
3100
|
+
},
|
|
3101
|
+
async run({ args }) {
|
|
3102
|
+
const result = await createClient2().post(
|
|
3103
|
+
"/api/communication/evaluate",
|
|
3104
|
+
{
|
|
3105
|
+
source: endpoint2(args.source, args.team),
|
|
3106
|
+
target: endpoint2(args.target, args.team),
|
|
3107
|
+
origin: args.origin,
|
|
3108
|
+
attemptKind: "cli_evaluate",
|
|
3109
|
+
attemptId: `diagnostic:${args.team}`
|
|
3110
|
+
}
|
|
3111
|
+
);
|
|
3112
|
+
if (args.json) return console.log(JSON.stringify(result, null, 2));
|
|
3113
|
+
console.log(`${result.decision.toUpperCase()} ${result.channel}: ${result.reasonCode}`);
|
|
3114
|
+
console.log(result.reason);
|
|
3115
|
+
console.log(
|
|
3116
|
+
`policy revisions: ${result.policyRefs.map((ref) => `${ref.teamId}@${ref.revision}`).join(", ") || "-"}`
|
|
3117
|
+
);
|
|
3118
|
+
}
|
|
3119
|
+
});
|
|
3120
|
+
var blocks = defineCommand18({
|
|
3121
|
+
meta: { name: "blocks", description: "List paginated durable communication denials" },
|
|
3122
|
+
args: {
|
|
3123
|
+
team: { type: "positional", required: true },
|
|
3124
|
+
limit: { type: "string", default: "50" },
|
|
3125
|
+
cursor: { type: "string" },
|
|
3126
|
+
source: { type: "string" },
|
|
3127
|
+
target: { type: "string" },
|
|
3128
|
+
channel: { type: "string" },
|
|
3129
|
+
origin: { type: "string" },
|
|
3130
|
+
reason: { type: "string", description: "Reason code" },
|
|
3131
|
+
from: { type: "string", description: "Epoch milliseconds or ISO timestamp" },
|
|
3132
|
+
to: { type: "string", description: "Epoch milliseconds or ISO timestamp" },
|
|
3133
|
+
json: { type: "boolean", description: "Emit page JSON including nextCursor" }
|
|
3134
|
+
},
|
|
3135
|
+
async run({ args }) {
|
|
3136
|
+
const query = new URLSearchParams({ limit: args.limit });
|
|
3137
|
+
for (const [key, value] of [
|
|
3138
|
+
["cursor", args.cursor],
|
|
3139
|
+
["source", args.source],
|
|
3140
|
+
["target", args.target],
|
|
3141
|
+
["channel", args.channel],
|
|
3142
|
+
["origin", args.origin],
|
|
3143
|
+
["reasonCode", args.reason],
|
|
3144
|
+
["from", args.from],
|
|
3145
|
+
["to", args.to]
|
|
3146
|
+
])
|
|
3147
|
+
if (value) query.set(key, value);
|
|
3148
|
+
const page = await createClient2().get(
|
|
3149
|
+
`/api/teams/${encodeURIComponent(args.team)}/policy/blocks?${query}`
|
|
3150
|
+
);
|
|
3151
|
+
if (args.json) return console.log(JSON.stringify(page, null, 2));
|
|
3152
|
+
if (!page.blocks.length) console.log("(no blocks)");
|
|
3153
|
+
else
|
|
3154
|
+
for (const line of columnize([
|
|
3155
|
+
["time", "source", "target", "channel", "origin", "reason"],
|
|
3156
|
+
...page.blocks.map((block) => [
|
|
3157
|
+
new Date(block.created_at).toISOString(),
|
|
3158
|
+
`${block.source_kind}:${block.source_id ?? "-"}`,
|
|
3159
|
+
`${block.target_kind}:${block.target_id ?? "-"}`,
|
|
3160
|
+
block.channel,
|
|
3161
|
+
block.origin,
|
|
3162
|
+
block.reason_code
|
|
3163
|
+
])
|
|
3164
|
+
]))
|
|
3165
|
+
console.log(line);
|
|
3166
|
+
if (page.nextCursor) console.log(`next cursor: ${page.nextCursor}`);
|
|
3167
|
+
}
|
|
3168
|
+
});
|
|
3169
|
+
var teamPolicyCommand = defineCommand18({
|
|
3170
|
+
meta: { name: "policy", description: "Inspect and manage the Team-owned live policy" },
|
|
3171
|
+
subCommands: {
|
|
3172
|
+
show: show2,
|
|
3173
|
+
export: exportCommand,
|
|
3174
|
+
import: importCommand,
|
|
3175
|
+
diff,
|
|
3176
|
+
evaluate,
|
|
3177
|
+
blocks
|
|
3178
|
+
}
|
|
3179
|
+
});
|
|
3180
|
+
|
|
3181
|
+
// src/commands/team.ts
|
|
3182
|
+
var addCmd2 = defineCommand19({
|
|
3183
|
+
meta: {
|
|
3184
|
+
name: "add",
|
|
3185
|
+
description: "Register a team at ~/.bazilion/teams/<slug>/ (use --link to point at an existing tree)"
|
|
3186
|
+
},
|
|
3187
|
+
args: {
|
|
3188
|
+
id: { type: "positional", required: true, description: "Team slug" },
|
|
3189
|
+
name: { type: "string", description: "Display name (defaults to slug)" },
|
|
3190
|
+
link: {
|
|
3191
|
+
type: "string",
|
|
3192
|
+
description: "Absolute path of an existing directory; the team slot becomes a symlink to it"
|
|
3193
|
+
}
|
|
3194
|
+
},
|
|
3195
|
+
async run({ args }) {
|
|
3196
|
+
const client = createClient2();
|
|
3197
|
+
const body = {
|
|
3198
|
+
id: args.id,
|
|
3199
|
+
...args.name ? { name: args.name } : {},
|
|
3200
|
+
...args.link ? { link: args.link } : {}
|
|
3201
|
+
};
|
|
3202
|
+
const g = await client.post("/api/teams", body);
|
|
3203
|
+
console.log(`registered team ${g.id} at ${g.path}`);
|
|
3204
|
+
}
|
|
3205
|
+
});
|
|
3206
|
+
var listCmd9 = defineCommand19({
|
|
3207
|
+
meta: { name: "list", description: "List teams" },
|
|
3208
|
+
async run() {
|
|
3209
|
+
const client = createClient2();
|
|
3210
|
+
const list3 = await client.get("/api/teams");
|
|
3211
|
+
if (list3.length === 0) {
|
|
3212
|
+
console.log("(no teams)");
|
|
3213
|
+
return;
|
|
3214
|
+
}
|
|
3215
|
+
const rows = list3.map((g) => [g.id, g.path]);
|
|
3216
|
+
for (const line of columnize(rows)) console.log(line);
|
|
3217
|
+
}
|
|
3218
|
+
});
|
|
3219
|
+
var rmCmd5 = defineCommand19({
|
|
3220
|
+
meta: { name: "rm", description: "Remove a team registration" },
|
|
3221
|
+
args: {
|
|
3222
|
+
id: { type: "positional", required: true }
|
|
3223
|
+
},
|
|
3224
|
+
async run({ args }) {
|
|
3225
|
+
const client = createClient2();
|
|
3226
|
+
const policy = await client.get(
|
|
3227
|
+
`/api/teams/${encodeURIComponent(args.id)}/policy`
|
|
3228
|
+
);
|
|
3229
|
+
await client.del(
|
|
3230
|
+
`/api/teams/${encodeURIComponent(args.id)}?expectedTeamPolicyRevision=${policy.teamPolicy.revision}`
|
|
3231
|
+
);
|
|
3232
|
+
console.log(`removed team ${args.id}`);
|
|
3233
|
+
}
|
|
3234
|
+
});
|
|
3235
|
+
async function readStdin() {
|
|
3236
|
+
const chunks = [];
|
|
3237
|
+
for await (const chunk of stdin2) chunks.push(chunk);
|
|
3238
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
3239
|
+
}
|
|
3240
|
+
var userMdShowCmd = defineCommand19({
|
|
3241
|
+
meta: { name: "show", description: "Print the team's USER.md" },
|
|
3242
|
+
args: { id: { type: "positional", required: true } },
|
|
3243
|
+
async run({ args }) {
|
|
3244
|
+
const client = createClient2();
|
|
3245
|
+
const g = await client.get(`/api/teams/${args.id}`);
|
|
3246
|
+
process.stdout.write(g.userMd);
|
|
3247
|
+
if (g.userMd && !g.userMd.endsWith("\n")) process.stdout.write("\n");
|
|
3248
|
+
}
|
|
3249
|
+
});
|
|
3250
|
+
var userMdSetCmd = defineCommand19({
|
|
3251
|
+
meta: {
|
|
3252
|
+
name: "set",
|
|
3253
|
+
description: "Replace the team's USER.md (from --file, --from-stdin, or inline text)"
|
|
3254
|
+
},
|
|
3255
|
+
args: {
|
|
3256
|
+
id: { type: "positional", required: true },
|
|
3257
|
+
file: { type: "string", description: "Read content from a file path" },
|
|
3258
|
+
"from-stdin": { type: "boolean", description: "Read content from stdin" },
|
|
3259
|
+
text: { type: "string", description: "Inline content" }
|
|
3260
|
+
},
|
|
3261
|
+
async run({ args }) {
|
|
3262
|
+
let content;
|
|
3263
|
+
if (args["from-stdin"]) content = await readStdin();
|
|
3264
|
+
else if (args.file) content = readFileSync7(args.file, "utf8");
|
|
3265
|
+
else if (args.text !== void 0) content = args.text;
|
|
3266
|
+
else {
|
|
3267
|
+
console.error("team user-md set: provide --file, --from-stdin, or --text");
|
|
3268
|
+
process.exit(2);
|
|
3269
|
+
}
|
|
3270
|
+
const client = createClient2();
|
|
3271
|
+
const body = { userMd: content };
|
|
3272
|
+
await client.put(`/api/teams/${args.id}/user-md`, body);
|
|
3273
|
+
console.log(`updated USER.md for team ${args.id} (${content.length} bytes)`);
|
|
3274
|
+
}
|
|
3275
|
+
});
|
|
3276
|
+
var userMdClearCmd = defineCommand19({
|
|
3277
|
+
meta: { name: "clear", description: "Clear the team's USER.md to empty" },
|
|
3278
|
+
args: { id: { type: "positional", required: true } },
|
|
3279
|
+
async run({ args }) {
|
|
3280
|
+
const client = createClient2();
|
|
3281
|
+
const body = { userMd: "" };
|
|
3282
|
+
await client.put(`/api/teams/${args.id}/user-md`, body);
|
|
3283
|
+
console.log(`cleared USER.md for team ${args.id}`);
|
|
3284
|
+
}
|
|
3285
|
+
});
|
|
3286
|
+
var userMdCmd = defineCommand19({
|
|
3287
|
+
meta: { name: "user-md", description: "View or edit a team's USER.md" },
|
|
3288
|
+
subCommands: {
|
|
3289
|
+
show: userMdShowCmd,
|
|
3290
|
+
set: userMdSetCmd,
|
|
3291
|
+
clear: userMdClearCmd
|
|
3292
|
+
}
|
|
3293
|
+
});
|
|
3294
|
+
var topicFormatShowCmd = defineCommand19({
|
|
3295
|
+
meta: { name: "show", description: "Print the team's Telegram topic-name template" },
|
|
3296
|
+
args: { id: { type: "positional", required: true } },
|
|
3297
|
+
async run({ args }) {
|
|
3298
|
+
const client = createClient2();
|
|
3299
|
+
const g = await client.get(`/api/teams/${args.id}`);
|
|
3300
|
+
console.log(g.telegramTopicNameFormat ?? "(default naming)");
|
|
3301
|
+
}
|
|
3302
|
+
});
|
|
3303
|
+
var topicFormatSetCmd = defineCommand19({
|
|
3304
|
+
meta: {
|
|
3305
|
+
name: "set",
|
|
3306
|
+
description: "Set the topic-name template. Tokens: {agent.name} {team.name} {team.slug} (must include {agent.name})"
|
|
3307
|
+
},
|
|
3308
|
+
args: {
|
|
3309
|
+
id: { type: "positional", required: true },
|
|
3310
|
+
format: {
|
|
3311
|
+
type: "positional",
|
|
3312
|
+
required: true,
|
|
3313
|
+
description: 'e.g. "{team.name} / {agent.name}"'
|
|
3314
|
+
}
|
|
3315
|
+
},
|
|
3316
|
+
async run({ args }) {
|
|
3317
|
+
const client = createClient2();
|
|
3318
|
+
const body = { format: args.format };
|
|
3319
|
+
const g = await client.put(`/api/teams/${args.id}/topic-format`, body);
|
|
3320
|
+
console.log(`set topic-name template for team ${args.id}: ${g.telegramTopicNameFormat}`);
|
|
3321
|
+
}
|
|
3322
|
+
});
|
|
3323
|
+
var topicFormatClearCmd = defineCommand19({
|
|
3324
|
+
meta: { name: "clear", description: "Clear the template (revert to built-in naming)" },
|
|
3325
|
+
args: { id: { type: "positional", required: true } },
|
|
3326
|
+
async run({ args }) {
|
|
3327
|
+
const client = createClient2();
|
|
3328
|
+
const body = { format: null };
|
|
3329
|
+
await client.put(`/api/teams/${args.id}/topic-format`, body);
|
|
3330
|
+
console.log(`cleared topic-name template for team ${args.id}`);
|
|
3331
|
+
}
|
|
3332
|
+
});
|
|
3333
|
+
var topicFormatCmd = defineCommand19({
|
|
3334
|
+
meta: {
|
|
3335
|
+
name: "topic-format",
|
|
3336
|
+
description: "View or edit a team's Telegram forum-topic name template"
|
|
3337
|
+
},
|
|
3338
|
+
subCommands: {
|
|
3339
|
+
show: topicFormatShowCmd,
|
|
3340
|
+
set: topicFormatSetCmd,
|
|
3341
|
+
clear: topicFormatClearCmd
|
|
3342
|
+
}
|
|
3343
|
+
});
|
|
3344
|
+
var teamCommand = defineCommand19({
|
|
3345
|
+
meta: { name: "team", description: "Manage teams (collaboration contexts)" },
|
|
3346
|
+
subCommands: {
|
|
3347
|
+
add: addCmd2,
|
|
3348
|
+
list: listCmd9,
|
|
3349
|
+
rm: rmCmd5,
|
|
3350
|
+
"user-md": userMdCmd,
|
|
3351
|
+
"topic-format": topicFormatCmd,
|
|
3352
|
+
policy: teamPolicyCommand
|
|
3353
|
+
}
|
|
3354
|
+
});
|
|
3355
|
+
|
|
3356
|
+
// src/commands/team-template.ts
|
|
3357
|
+
import { readFileSync as readFileSync8 } from "fs";
|
|
3358
|
+
import { defineCommand as defineCommand20 } from "citty";
|
|
3359
|
+
function jsonFile(path) {
|
|
3360
|
+
try {
|
|
3361
|
+
return JSON.parse(readFileSync8(path, "utf8"));
|
|
3362
|
+
} catch (error) {
|
|
3363
|
+
throw new Error(`invalid JSON: ${error.message}`);
|
|
3364
|
+
}
|
|
3365
|
+
}
|
|
3366
|
+
function printTeam(detail) {
|
|
3367
|
+
console.log(`# ${detail.template.id} \u2014 ${detail.template.name}`);
|
|
3368
|
+
console.log(`revision: ${detail.template.currentRevision}`);
|
|
3369
|
+
console.log(`slots: ${detail.slots.length}`);
|
|
3370
|
+
console.log(`edges: ${detail.edges.length}`);
|
|
3371
|
+
if (detail.slots.length) {
|
|
3372
|
+
console.log("");
|
|
3373
|
+
for (const line of columnize([
|
|
3374
|
+
["slot", "profile", "Agent name", "model", "reasoning"],
|
|
3375
|
+
...detail.slots.map((slot, index) => [
|
|
3376
|
+
String(index + 1),
|
|
3377
|
+
slot.profileId,
|
|
3378
|
+
slot.agentName,
|
|
3379
|
+
slot.modelOverride ?? "-",
|
|
3380
|
+
slot.reasoningLevel ?? "-"
|
|
3381
|
+
])
|
|
3382
|
+
]))
|
|
3383
|
+
console.log(line);
|
|
3384
|
+
}
|
|
3385
|
+
}
|
|
3386
|
+
var list2 = defineCommand20({
|
|
3387
|
+
meta: { name: "list", description: "List canonical Team templates" },
|
|
3388
|
+
args: { json: { type: "boolean", description: "Emit stable JSON" } },
|
|
3389
|
+
async run({ args }) {
|
|
3390
|
+
const rows = await createClient2().get("/api/team-templates");
|
|
3391
|
+
if (args.json) return console.log(JSON.stringify(rows, null, 2));
|
|
3392
|
+
if (!rows.length) return console.log("(no Team templates)");
|
|
3393
|
+
for (const line of columnize([
|
|
3394
|
+
["id", "revision", "slots", "name"],
|
|
3395
|
+
...rows.map((row) => [row.id, String(row.currentRevision), String(row.slotCount), row.name])
|
|
3396
|
+
]))
|
|
3397
|
+
console.log(line);
|
|
3398
|
+
}
|
|
3399
|
+
});
|
|
3400
|
+
var show3 = defineCommand20({
|
|
3401
|
+
meta: { name: "show", description: "Show a canonical Team template" },
|
|
3402
|
+
args: {
|
|
3403
|
+
id: { type: "positional", required: true },
|
|
3404
|
+
json: { type: "boolean", description: "Emit the canonical API aggregate" }
|
|
3405
|
+
},
|
|
3406
|
+
async run({ args }) {
|
|
3407
|
+
const detail = await createClient2().get(
|
|
3408
|
+
`/api/team-templates/${encodeURIComponent(args.id)}`
|
|
3409
|
+
);
|
|
3410
|
+
if (args.json) console.log(JSON.stringify(detail, null, 2));
|
|
3411
|
+
else printTeam(detail);
|
|
3412
|
+
}
|
|
3413
|
+
});
|
|
3414
|
+
var exportCommand2 = defineCommand20({
|
|
3415
|
+
meta: {
|
|
3416
|
+
name: "export",
|
|
3417
|
+
description: "Export a portable versioned Team-template document to stdout"
|
|
3418
|
+
},
|
|
3419
|
+
args: { id: { type: "positional", required: true } },
|
|
3420
|
+
async run({ args }) {
|
|
3421
|
+
const detail = await createClient2().get(
|
|
3422
|
+
`/api/team-templates/${encodeURIComponent(args.id)}`
|
|
3423
|
+
);
|
|
3424
|
+
console.log(JSON.stringify(exportTeamDocument(detail), null, 2));
|
|
3425
|
+
}
|
|
3426
|
+
});
|
|
3427
|
+
function printImportDiff(current, document) {
|
|
3428
|
+
const before = current ? exportTeamDocument(current) : null;
|
|
3429
|
+
console.log(`Team: ${current ? current.template.id : "(new)"} -> ${document.template.id}`);
|
|
3430
|
+
console.log(`Roster: ${current?.slots.length ?? 0} -> ${document.slots.length}`);
|
|
3431
|
+
const previousSlots = new Map(before?.slots.map((slot) => [slot.key, slot]) ?? []);
|
|
3432
|
+
const nextSlots = new Map(document.slots.map((slot) => [slot.key, slot]));
|
|
3433
|
+
for (const [key, slot] of nextSlots) {
|
|
3434
|
+
const previous = previousSlots.get(key);
|
|
3435
|
+
if (!previous) console.log(` + ${key}: ${slot.profileId} / ${slot.agentName}`);
|
|
3436
|
+
else if (JSON.stringify(previous) !== JSON.stringify(slot))
|
|
3437
|
+
console.log(
|
|
3438
|
+
` ~ ${key}: ${previous.profileId} / ${previous.agentName} -> ${slot.profileId} / ${slot.agentName}`
|
|
3439
|
+
);
|
|
3440
|
+
}
|
|
3441
|
+
for (const [key, slot] of previousSlots)
|
|
3442
|
+
if (!nextSlots.has(key)) console.log(` - ${key}: ${slot.profileId} / ${slot.agentName}`);
|
|
3443
|
+
const toEdge = (edge) => ({
|
|
3444
|
+
sourceKind: edge.sourceKind,
|
|
3445
|
+
sourceId: edge.sourceKey,
|
|
3446
|
+
targetKind: edge.targetKind,
|
|
3447
|
+
targetId: edge.targetKey
|
|
3448
|
+
});
|
|
3449
|
+
const diff2 = edgeDiff(before?.edges.map(toEdge) ?? [], document.edges.map(toEdge));
|
|
3450
|
+
console.log(`Edges: +${diff2.added.length} -${diff2.removed.length}`);
|
|
3451
|
+
for (const value of diff2.added) console.log(` + ${value}`);
|
|
3452
|
+
for (const value of diff2.removed) console.log(` - ${value}`);
|
|
3453
|
+
}
|
|
3454
|
+
var importCommand2 = defineCommand20({
|
|
3455
|
+
meta: {
|
|
3456
|
+
name: "import",
|
|
3457
|
+
description: "Validate, diff, and explicitly apply a portable Team-template document"
|
|
3458
|
+
},
|
|
3459
|
+
args: {
|
|
3460
|
+
file: { type: "positional", required: true, description: "JSON document path" },
|
|
3461
|
+
"dry-run": { type: "boolean", description: "Validate and print the resolved diff only" },
|
|
3462
|
+
apply: { type: "boolean", description: "Apply non-interactively after printing the diff" },
|
|
3463
|
+
"expected-revision": {
|
|
3464
|
+
type: "string",
|
|
3465
|
+
description: "Required current revision when replacing an existing Team"
|
|
3466
|
+
},
|
|
3467
|
+
force: {
|
|
3468
|
+
type: "boolean",
|
|
3469
|
+
description: "Refetch current revision; requires --apply and still uses optimistic locking"
|
|
3470
|
+
},
|
|
3471
|
+
"confirm-current-revision": {
|
|
3472
|
+
type: "string",
|
|
3473
|
+
description: "Second force confirmation: the freshly displayed current revision"
|
|
3474
|
+
}
|
|
3475
|
+
},
|
|
3476
|
+
async run({ args }) {
|
|
3477
|
+
if (args.force && !args.apply)
|
|
3478
|
+
throw new Error("--force requires --apply (interactive force is intentionally unsupported)");
|
|
3479
|
+
const document = parseTeamDocument(jsonFile(args.file));
|
|
3480
|
+
const client = createClient2();
|
|
3481
|
+
let current = null;
|
|
3482
|
+
try {
|
|
3483
|
+
current = await client.get(
|
|
3484
|
+
`/api/team-templates/${encodeURIComponent(document.template.id)}`
|
|
3485
|
+
);
|
|
3486
|
+
} catch (error) {
|
|
3487
|
+
if (!(error instanceof ApiClientError) || error.status !== 404) throw error;
|
|
3488
|
+
}
|
|
3489
|
+
printImportDiff(current, document);
|
|
3490
|
+
if (args["dry-run"]) {
|
|
3491
|
+
console.log("valid: no changes applied");
|
|
3492
|
+
return;
|
|
3493
|
+
}
|
|
3494
|
+
if (!args.apply) throw new Error("refusing mutation: review the diff, then pass --apply");
|
|
3495
|
+
if (!current) {
|
|
3496
|
+
const body2 = teamImportBody(document);
|
|
3497
|
+
const created = await client.post("/api/team-templates/import", {
|
|
3498
|
+
id: document.template.id,
|
|
3499
|
+
name: document.template.name,
|
|
3500
|
+
userMd: document.template.userMd,
|
|
3501
|
+
slots: document.slots.map((slot, index) => ({
|
|
3502
|
+
...body2.slots[index],
|
|
3503
|
+
clientKey: slot.key
|
|
3504
|
+
})),
|
|
3505
|
+
edges: body2.edges
|
|
3506
|
+
});
|
|
3507
|
+
console.log(
|
|
3508
|
+
`created Team ${created.template.id} at revision ${created.template.currentRevision}`
|
|
3509
|
+
);
|
|
3510
|
+
return;
|
|
3511
|
+
}
|
|
3512
|
+
if (document.template.name !== current.template.name || document.template.userMd !== current.template.userMd)
|
|
3513
|
+
throw new Error(
|
|
3514
|
+
"replacement document metadata differs; update Team name/USER.md separately before import"
|
|
3515
|
+
);
|
|
3516
|
+
const supplied = Number.parseInt(args["expected-revision"] ?? "", 10);
|
|
3517
|
+
const expectedRevision = args.force ? current.template.currentRevision : supplied;
|
|
3518
|
+
if (args.force && Number.parseInt(args["confirm-current-revision"] ?? "", 10) !== current.template.currentRevision)
|
|
3519
|
+
throw new Error(
|
|
3520
|
+
`--force requires --confirm-current-revision ${current.template.currentRevision} after reviewing the fresh diff`
|
|
3521
|
+
);
|
|
3522
|
+
if (!Number.isInteger(expectedRevision) || expectedRevision < 1)
|
|
3523
|
+
throw new Error("--expected-revision is required when replacing an existing Team");
|
|
3524
|
+
const definition = teamImportBody(document, current);
|
|
3525
|
+
const body = { expectedRevision, ...definition };
|
|
3526
|
+
const updated = await client.put(
|
|
3527
|
+
`/api/team-templates/${encodeURIComponent(document.template.id)}/definition`,
|
|
3528
|
+
body
|
|
3529
|
+
);
|
|
3530
|
+
console.log(
|
|
3531
|
+
`updated Team ${updated.template.id} to revision ${updated.template.currentRevision}`
|
|
3532
|
+
);
|
|
3533
|
+
}
|
|
3534
|
+
});
|
|
3535
|
+
var teamTemplateCommand = defineCommand20({
|
|
3536
|
+
meta: {
|
|
3537
|
+
name: "team-template",
|
|
3538
|
+
description: "Inspect and exchange canonical Team templates"
|
|
3539
|
+
},
|
|
3540
|
+
subCommands: { list: list2, show: show3, export: exportCommand2, import: importCommand2 }
|
|
3541
|
+
});
|
|
3542
|
+
|
|
3543
|
+
// src/commands/telegram.ts
|
|
3544
|
+
import { defineCommand as defineCommand21 } from "citty";
|
|
3545
|
+
var setCmd2 = defineCommand21({
|
|
2932
3546
|
meta: {
|
|
2933
3547
|
name: "set",
|
|
2934
3548
|
description: "Save bot token + supergroup chat ID (paired write)"
|
|
@@ -2946,7 +3560,7 @@ var setCmd2 = defineCommand19({
|
|
|
2946
3560
|
console.log(`saved \xB7 token ${state.botTokenPreview} \xB7 chat ${state.chatId}`);
|
|
2947
3561
|
}
|
|
2948
3562
|
});
|
|
2949
|
-
var clearCmd =
|
|
3563
|
+
var clearCmd = defineCommand21({
|
|
2950
3564
|
meta: {
|
|
2951
3565
|
name: "clear",
|
|
2952
3566
|
description: "Remove stored bot token + chat ID"
|
|
@@ -2957,7 +3571,7 @@ var clearCmd = defineCommand19({
|
|
|
2957
3571
|
console.log("cleared");
|
|
2958
3572
|
}
|
|
2959
3573
|
});
|
|
2960
|
-
var
|
|
3574
|
+
var showCmd5 = defineCommand21({
|
|
2961
3575
|
meta: {
|
|
2962
3576
|
name: "show",
|
|
2963
3577
|
description: "Show what credentials are stored (token is masked)"
|
|
@@ -2978,7 +3592,7 @@ var showCmd6 = defineCommand19({
|
|
|
2978
3592
|
}
|
|
2979
3593
|
}
|
|
2980
3594
|
});
|
|
2981
|
-
var reconnectCmd =
|
|
3595
|
+
var reconnectCmd = defineCommand21({
|
|
2982
3596
|
meta: {
|
|
2983
3597
|
name: "reconnect",
|
|
2984
3598
|
description: "Apply a pending supergroup chat-id migration + re-activate the bot"
|
|
@@ -2989,7 +3603,7 @@ var reconnectCmd = defineCommand19({
|
|
|
2989
3603
|
console.log(`reconnected \xB7 chat ${state.chatId}`);
|
|
2990
3604
|
}
|
|
2991
3605
|
});
|
|
2992
|
-
var configCmd =
|
|
3606
|
+
var configCmd = defineCommand21({
|
|
2993
3607
|
meta: {
|
|
2994
3608
|
name: "config",
|
|
2995
3609
|
description: "Manage Telegram credentials (bot token + chat ID)"
|
|
@@ -2997,10 +3611,10 @@ var configCmd = defineCommand19({
|
|
|
2997
3611
|
subCommands: {
|
|
2998
3612
|
set: setCmd2,
|
|
2999
3613
|
clear: clearCmd,
|
|
3000
|
-
show:
|
|
3614
|
+
show: showCmd5
|
|
3001
3615
|
}
|
|
3002
3616
|
});
|
|
3003
|
-
var healthCmd =
|
|
3617
|
+
var healthCmd = defineCommand21({
|
|
3004
3618
|
meta: {
|
|
3005
3619
|
name: "health",
|
|
3006
3620
|
description: "Run the four-step preflight against the Telegram Bot API"
|
|
@@ -3034,7 +3648,7 @@ var healthCmd = defineCommand19({
|
|
|
3034
3648
|
if (!allOk) process.exitCode = 1;
|
|
3035
3649
|
}
|
|
3036
3650
|
});
|
|
3037
|
-
var botStatusCmd =
|
|
3651
|
+
var botStatusCmd = defineCommand21({
|
|
3038
3652
|
meta: {
|
|
3039
3653
|
name: "status",
|
|
3040
3654
|
description: "Show polling state of the live bot"
|
|
@@ -3059,7 +3673,7 @@ var botStatusCmd = defineCommand19({
|
|
|
3059
3673
|
if (!p.running) process.exitCode = 1;
|
|
3060
3674
|
}
|
|
3061
3675
|
});
|
|
3062
|
-
var botRestartCmd =
|
|
3676
|
+
var botRestartCmd = defineCommand21({
|
|
3063
3677
|
meta: {
|
|
3064
3678
|
name: "restart",
|
|
3065
3679
|
description: "Force-restart the bot (tears down + brings up from current creds)"
|
|
@@ -3070,7 +3684,7 @@ var botRestartCmd = defineCommand19({
|
|
|
3070
3684
|
console.log("restart requested");
|
|
3071
3685
|
}
|
|
3072
3686
|
});
|
|
3073
|
-
var botCmd =
|
|
3687
|
+
var botCmd = defineCommand21({
|
|
3074
3688
|
meta: {
|
|
3075
3689
|
name: "bot",
|
|
3076
3690
|
description: "Inspect / control the live polling bot"
|
|
@@ -3080,7 +3694,7 @@ var botCmd = defineCommand19({
|
|
|
3080
3694
|
restart: botRestartCmd
|
|
3081
3695
|
}
|
|
3082
3696
|
});
|
|
3083
|
-
var bindCmd =
|
|
3697
|
+
var bindCmd = defineCommand21({
|
|
3084
3698
|
meta: {
|
|
3085
3699
|
name: "bind",
|
|
3086
3700
|
description: "Create a Telegram topic for an agent (manual fallback for /talk)"
|
|
@@ -3098,7 +3712,7 @@ var bindCmd = defineCommand19({
|
|
|
3098
3712
|
console.log(` ${result.deepLink}`);
|
|
3099
3713
|
}
|
|
3100
3714
|
});
|
|
3101
|
-
var unbindCmd =
|
|
3715
|
+
var unbindCmd = defineCommand21({
|
|
3102
3716
|
meta: {
|
|
3103
3717
|
name: "unbind",
|
|
3104
3718
|
description: "Clear an agent's Telegram topic binding (topic stays in Telegram as orphan)"
|
|
@@ -3112,7 +3726,7 @@ var unbindCmd = defineCommand19({
|
|
|
3112
3726
|
console.log(`unbound agent ${args.agent}`);
|
|
3113
3727
|
}
|
|
3114
3728
|
});
|
|
3115
|
-
var listBindingsCmd =
|
|
3729
|
+
var listBindingsCmd = defineCommand21({
|
|
3116
3730
|
meta: {
|
|
3117
3731
|
name: "list",
|
|
3118
3732
|
description: "List agents and their Telegram topic bindings"
|
|
@@ -3129,18 +3743,18 @@ var listBindingsCmd = defineCommand19({
|
|
|
3129
3743
|
if (bound.length > 0) {
|
|
3130
3744
|
console.log("bound:");
|
|
3131
3745
|
for (const a of bound) {
|
|
3132
|
-
console.log(` #${a.telegramTopicId} ${a.name} (
|
|
3746
|
+
console.log(` #${a.telegramTopicId} ${a.name} (team: ${a.teamId})`);
|
|
3133
3747
|
}
|
|
3134
3748
|
}
|
|
3135
3749
|
if (unbound.length > 0) {
|
|
3136
3750
|
console.log("unbound:");
|
|
3137
3751
|
for (const a of unbound) {
|
|
3138
|
-
console.log(` \u2014 ${a.name} (
|
|
3752
|
+
console.log(` \u2014 ${a.name} (team: ${a.teamId})`);
|
|
3139
3753
|
}
|
|
3140
3754
|
}
|
|
3141
3755
|
}
|
|
3142
3756
|
});
|
|
3143
|
-
var allowCmd =
|
|
3757
|
+
var allowCmd = defineCommand21({
|
|
3144
3758
|
meta: { name: "allow", description: "Add a Telegram user id to the allowlist" },
|
|
3145
3759
|
args: {
|
|
3146
3760
|
userId: { type: "positional", required: true, description: "Numeric Telegram user id" },
|
|
@@ -3157,7 +3771,7 @@ var allowCmd = defineCommand19({
|
|
|
3157
3771
|
console.log(`allowed ${u.userId} (${u.role})`);
|
|
3158
3772
|
}
|
|
3159
3773
|
});
|
|
3160
|
-
var denyCmd =
|
|
3774
|
+
var denyCmd = defineCommand21({
|
|
3161
3775
|
meta: { name: "deny", description: "Remove a Telegram user id from the allowlist" },
|
|
3162
3776
|
args: { userId: { type: "positional", required: true } },
|
|
3163
3777
|
async run({ args }) {
|
|
@@ -3166,7 +3780,7 @@ var denyCmd = defineCommand19({
|
|
|
3166
3780
|
console.log(`removed ${args.userId}`);
|
|
3167
3781
|
}
|
|
3168
3782
|
});
|
|
3169
|
-
var allowedCmd =
|
|
3783
|
+
var allowedCmd = defineCommand21({
|
|
3170
3784
|
meta: { name: "allowed", description: "List allowlisted Telegram users" },
|
|
3171
3785
|
async run() {
|
|
3172
3786
|
const client = createClient2();
|
|
@@ -3181,7 +3795,7 @@ var allowedCmd = defineCommand19({
|
|
|
3181
3795
|
}
|
|
3182
3796
|
}
|
|
3183
3797
|
});
|
|
3184
|
-
var telegramCommand =
|
|
3798
|
+
var telegramCommand = defineCommand21({
|
|
3185
3799
|
meta: {
|
|
3186
3800
|
name: "telegram",
|
|
3187
3801
|
description: "Telegram integration: credentials, health, bot lifecycle, bindings, access"
|
|
@@ -3202,7 +3816,7 @@ var telegramCommand = defineCommand19({
|
|
|
3202
3816
|
|
|
3203
3817
|
// src/commands/token.ts
|
|
3204
3818
|
import { networkInterfaces } from "os";
|
|
3205
|
-
import { defineCommand as
|
|
3819
|
+
import { defineCommand as defineCommand22 } from "citty";
|
|
3206
3820
|
import qrcode from "qrcode-terminal";
|
|
3207
3821
|
function tokenRow(t) {
|
|
3208
3822
|
const last = t.lastUsedAt ? new Date(t.lastUsedAt).toISOString() : "(never)";
|
|
@@ -3236,7 +3850,7 @@ function resolveQrServer(override) {
|
|
|
3236
3850
|
if (detected.warning) console.warn(`\u26A0 ${detected.warning}`);
|
|
3237
3851
|
return detected.origin;
|
|
3238
3852
|
}
|
|
3239
|
-
var
|
|
3853
|
+
var createCmd3 = defineCommand22({
|
|
3240
3854
|
meta: { name: "create", description: "Mint a new web token (shown once)" },
|
|
3241
3855
|
args: {
|
|
3242
3856
|
label: { type: "positional", required: true, description: "Human-readable label" },
|
|
@@ -3267,7 +3881,7 @@ var createCmd4 = defineCommand20({
|
|
|
3267
3881
|
qrcode.generate(pairUrl, { small: true }, (qr) => console.log(qr));
|
|
3268
3882
|
}
|
|
3269
3883
|
});
|
|
3270
|
-
var
|
|
3884
|
+
var listCmd10 = defineCommand22({
|
|
3271
3885
|
meta: { name: "list", description: "List web tokens" },
|
|
3272
3886
|
args: {
|
|
3273
3887
|
all: { type: "boolean", description: "Include revoked tokens" }
|
|
@@ -3283,7 +3897,7 @@ var listCmd11 = defineCommand20({
|
|
|
3283
3897
|
for (const line of columnize(tokens.map(tokenRow))) console.log(line);
|
|
3284
3898
|
}
|
|
3285
3899
|
});
|
|
3286
|
-
var showLocalCmd =
|
|
3900
|
+
var showLocalCmd = defineCommand22({
|
|
3287
3901
|
meta: {
|
|
3288
3902
|
name: "show-local",
|
|
3289
3903
|
description: "Print the bootstrap web token stored in ~/.bazilion/auth.json"
|
|
@@ -3293,7 +3907,7 @@ var showLocalCmd = defineCommand20({
|
|
|
3293
3907
|
console.log(readAuthFile(paths.authFile).token);
|
|
3294
3908
|
}
|
|
3295
3909
|
});
|
|
3296
|
-
var revokeCmd =
|
|
3910
|
+
var revokeCmd = defineCommand22({
|
|
3297
3911
|
meta: { name: "revoke", description: "Revoke a web token" },
|
|
3298
3912
|
args: {
|
|
3299
3913
|
id: { type: "positional", required: true }
|
|
@@ -3304,19 +3918,19 @@ var revokeCmd = defineCommand20({
|
|
|
3304
3918
|
console.log(`revoked token ${args.id}`);
|
|
3305
3919
|
}
|
|
3306
3920
|
});
|
|
3307
|
-
var tokenCommand =
|
|
3921
|
+
var tokenCommand = defineCommand22({
|
|
3308
3922
|
meta: { name: "token", description: "Manage web tokens for API/CLI clients" },
|
|
3309
3923
|
subCommands: {
|
|
3310
|
-
create:
|
|
3311
|
-
list:
|
|
3924
|
+
create: createCmd3,
|
|
3925
|
+
list: listCmd10,
|
|
3312
3926
|
revoke: revokeCmd,
|
|
3313
3927
|
"show-local": showLocalCmd
|
|
3314
3928
|
}
|
|
3315
3929
|
});
|
|
3316
3930
|
|
|
3317
3931
|
// src/commands/trigger.ts
|
|
3318
|
-
import { defineCommand as
|
|
3319
|
-
var addCmd3 =
|
|
3932
|
+
import { defineCommand as defineCommand23 } from "citty";
|
|
3933
|
+
var addCmd3 = defineCommand23({
|
|
3320
3934
|
meta: { name: "add", description: "Add a heartbeat / cron trigger to an agent" },
|
|
3321
3935
|
args: {
|
|
3322
3936
|
agent: { type: "positional", required: true },
|
|
@@ -3364,7 +3978,7 @@ function triggerRow(t) {
|
|
|
3364
3978
|
const msgPreview = t.message.length > 60 ? `${t.message.slice(0, 60)}\u2026` : t.message;
|
|
3365
3979
|
return [t.id, state, spec, `last: ${last}`, `"${msgPreview}"`];
|
|
3366
3980
|
}
|
|
3367
|
-
var
|
|
3981
|
+
var listCmd11 = defineCommand23({
|
|
3368
3982
|
meta: { name: "list", description: "List triggers for an agent" },
|
|
3369
3983
|
args: {
|
|
3370
3984
|
agent: { type: "positional", required: true }
|
|
@@ -3381,7 +3995,7 @@ var listCmd12 = defineCommand21({
|
|
|
3381
3995
|
for (const line of columnize(triggers.map(triggerRow))) console.log(line);
|
|
3382
3996
|
}
|
|
3383
3997
|
});
|
|
3384
|
-
var rmCmd6 =
|
|
3998
|
+
var rmCmd6 = defineCommand23({
|
|
3385
3999
|
meta: { name: "rm", description: "Delete a trigger" },
|
|
3386
4000
|
args: {
|
|
3387
4001
|
id: { type: "positional", required: true }
|
|
@@ -3392,7 +4006,7 @@ var rmCmd6 = defineCommand21({
|
|
|
3392
4006
|
console.log(`removed trigger ${args.id}`);
|
|
3393
4007
|
}
|
|
3394
4008
|
});
|
|
3395
|
-
var enableCmd3 =
|
|
4009
|
+
var enableCmd3 = defineCommand23({
|
|
3396
4010
|
meta: { name: "enable", description: "Enable a trigger" },
|
|
3397
4011
|
args: {
|
|
3398
4012
|
id: { type: "positional", required: true }
|
|
@@ -3404,7 +4018,7 @@ var enableCmd3 = defineCommand21({
|
|
|
3404
4018
|
console.log(`enabled trigger ${args.id}`);
|
|
3405
4019
|
}
|
|
3406
4020
|
});
|
|
3407
|
-
var disableCmd3 =
|
|
4021
|
+
var disableCmd3 = defineCommand23({
|
|
3408
4022
|
meta: { name: "disable", description: "Disable a trigger" },
|
|
3409
4023
|
args: {
|
|
3410
4024
|
id: { type: "positional", required: true }
|
|
@@ -3416,11 +4030,11 @@ var disableCmd3 = defineCommand21({
|
|
|
3416
4030
|
console.log(`disabled trigger ${args.id}`);
|
|
3417
4031
|
}
|
|
3418
4032
|
});
|
|
3419
|
-
var triggerCommand =
|
|
4033
|
+
var triggerCommand = defineCommand23({
|
|
3420
4034
|
meta: { name: "trigger", description: "Manage agent heartbeats / cron triggers" },
|
|
3421
4035
|
subCommands: {
|
|
3422
4036
|
add: addCmd3,
|
|
3423
|
-
list:
|
|
4037
|
+
list: listCmd11,
|
|
3424
4038
|
rm: rmCmd6,
|
|
3425
4039
|
enable: enableCmd3,
|
|
3426
4040
|
disable: disableCmd3
|
|
@@ -3428,9 +4042,9 @@ var triggerCommand = defineCommand21({
|
|
|
3428
4042
|
});
|
|
3429
4043
|
|
|
3430
4044
|
// src/commands/uninstall.ts
|
|
3431
|
-
import { existsSync as existsSync7, readdirSync as readdirSync2, rmSync as
|
|
3432
|
-
import { join as
|
|
3433
|
-
import { defineCommand as
|
|
4045
|
+
import { existsSync as existsSync7, readdirSync as readdirSync2, rmSync as rmSync3 } from "fs";
|
|
4046
|
+
import { join as join5 } from "path";
|
|
4047
|
+
import { defineCommand as defineCommand24 } from "citty";
|
|
3434
4048
|
function makeLineReader() {
|
|
3435
4049
|
let buffer = "";
|
|
3436
4050
|
let ended = false;
|
|
@@ -3475,10 +4089,10 @@ async function askYes(readLine, prompt) {
|
|
|
3475
4089
|
}
|
|
3476
4090
|
function removePath(p) {
|
|
3477
4091
|
if (!existsSync7(p)) return false;
|
|
3478
|
-
|
|
4092
|
+
rmSync3(p, { recursive: true, force: true });
|
|
3479
4093
|
return true;
|
|
3480
4094
|
}
|
|
3481
|
-
var uninstallCommand =
|
|
4095
|
+
var uninstallCommand = defineCommand24({
|
|
3482
4096
|
meta: {
|
|
3483
4097
|
name: "uninstall",
|
|
3484
4098
|
description: "Wipe bazilion state from ~/.bazilion (or BAZILION_HOME)"
|
|
@@ -3496,26 +4110,19 @@ var uninstallCommand = defineCommand22({
|
|
|
3496
4110
|
},
|
|
3497
4111
|
async run({ args }) {
|
|
3498
4112
|
const paths = resolveCliPaths(args.home);
|
|
3499
|
-
const dbFile =
|
|
3500
|
-
const profilesDir =
|
|
3501
|
-
const agentsDir =
|
|
3502
|
-
const
|
|
3503
|
-
const skillsDir =
|
|
3504
|
-
const logsDir =
|
|
4113
|
+
const dbFile = join5(paths.home, "bazilion.db");
|
|
4114
|
+
const profilesDir = join5(paths.home, "profiles");
|
|
4115
|
+
const agentsDir = join5(paths.home, "agents");
|
|
4116
|
+
const teamsDir = join5(paths.home, "teams");
|
|
4117
|
+
const skillsDir = join5(paths.home, "skills");
|
|
4118
|
+
const logsDir = join5(paths.home, "logs");
|
|
3505
4119
|
if (!existsSync7(paths.home)) {
|
|
3506
4120
|
console.log(`nothing to remove: ${paths.home} does not exist`);
|
|
3507
4121
|
return;
|
|
3508
4122
|
}
|
|
3509
4123
|
console.log(`about to uninstall bazilion at ${paths.home}`);
|
|
3510
4124
|
console.log("");
|
|
3511
|
-
const dataTargets = [
|
|
3512
|
-
dbFile,
|
|
3513
|
-
`${dbFile}-wal`,
|
|
3514
|
-
`${dbFile}-shm`,
|
|
3515
|
-
profilesDir,
|
|
3516
|
-
agentsDir,
|
|
3517
|
-
groupsDir
|
|
3518
|
-
];
|
|
4125
|
+
const dataTargets = [dbFile, `${dbFile}-wal`, `${dbFile}-shm`, profilesDir, agentsDir, teamsDir];
|
|
3519
4126
|
const needsPrompt = !args.yes;
|
|
3520
4127
|
const readLine = needsPrompt ? makeLineReader() : null;
|
|
3521
4128
|
const wipeData = args.yes || await askYes(
|
|
@@ -3541,7 +4148,7 @@ var uninstallCommand = defineCommand22({
|
|
|
3541
4148
|
if (removePath(p)) console.log(`removed ${p}`);
|
|
3542
4149
|
}
|
|
3543
4150
|
if (readdirSync2(paths.home).length === 0) {
|
|
3544
|
-
|
|
4151
|
+
rmSync3(paths.home, { recursive: true, force: true });
|
|
3545
4152
|
console.log(`removed ${paths.home}`);
|
|
3546
4153
|
} else {
|
|
3547
4154
|
console.log(`${paths.home} still has unmanaged files; left in place`);
|
|
@@ -3556,7 +4163,7 @@ var uninstallCommand = defineCommand22({
|
|
|
3556
4163
|
|
|
3557
4164
|
// src/index.ts
|
|
3558
4165
|
var VERSION = package_default.version;
|
|
3559
|
-
var main =
|
|
4166
|
+
var main = defineCommand25({
|
|
3560
4167
|
meta: {
|
|
3561
4168
|
name: "bazilion",
|
|
3562
4169
|
version: VERSION,
|
|
@@ -3565,9 +4172,10 @@ var main = defineCommand23({
|
|
|
3565
4172
|
subCommands: {
|
|
3566
4173
|
login: loginCommand,
|
|
3567
4174
|
profile: profileCommand,
|
|
3568
|
-
|
|
3569
|
-
|
|
4175
|
+
team: teamCommand,
|
|
4176
|
+
"team-template": teamTemplateCommand,
|
|
3570
4177
|
agent: agentCommand,
|
|
4178
|
+
approval: approvalCommand,
|
|
3571
4179
|
skill: skillCommand,
|
|
3572
4180
|
memory: memoryCommand,
|
|
3573
4181
|
mcp: mcpCommand,
|
|
@@ -3622,12 +4230,22 @@ function printError(err) {
|
|
|
3622
4230
|
console.error(" hint: host not found. Check BAZILION_SERVER / ~/.bazilion/auth.json.");
|
|
3623
4231
|
}
|
|
3624
4232
|
}
|
|
4233
|
+
function exitCodeForError(err) {
|
|
4234
|
+
if (err instanceof ApiClientError) {
|
|
4235
|
+
if (err.status === 401 || err.status === 403) return 4;
|
|
4236
|
+
if (err.status === 409) return 3;
|
|
4237
|
+
if (err.status === 400 || err.status === 422) return 2;
|
|
4238
|
+
return 1;
|
|
4239
|
+
}
|
|
4240
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
4241
|
+
return /invalid|unsupported|must be|require|refusing mutation|document belongs/.test(message) ? 2 : 1;
|
|
4242
|
+
}
|
|
3625
4243
|
function printTopLevelHelp() {
|
|
3626
4244
|
console.log(`Multi-agent runtime (bazilion v${VERSION})`);
|
|
3627
4245
|
console.log("");
|
|
3628
4246
|
console.log("USAGE bazilion <command> [args]");
|
|
3629
4247
|
console.log("");
|
|
3630
|
-
const
|
|
4248
|
+
const teams = [
|
|
3631
4249
|
{
|
|
3632
4250
|
title: "setup",
|
|
3633
4251
|
items: [
|
|
@@ -3641,8 +4259,8 @@ function printTopLevelHelp() {
|
|
|
3641
4259
|
title: "catalog",
|
|
3642
4260
|
items: [
|
|
3643
4261
|
["profile", "Manage profiles (templates agents are spawned from)"],
|
|
3644
|
-
["
|
|
3645
|
-
["
|
|
4262
|
+
["team-template", "Inspect and exchange reusable Team Templates"],
|
|
4263
|
+
["team", "Manage teams (collaboration context \u2014 filesystem root + USER.md + roster)"],
|
|
3646
4264
|
["skill", "Manage the skill library"],
|
|
3647
4265
|
["provider", "Manage and test LLM providers"],
|
|
3648
4266
|
["config", "Manage service config (credentials + URLs/IDs)"],
|
|
@@ -3652,8 +4270,9 @@ function printTopLevelHelp() {
|
|
|
3652
4270
|
{
|
|
3653
4271
|
title: "agents",
|
|
3654
4272
|
items: [
|
|
4273
|
+
["approval", "Review and decide communication approval attempts"],
|
|
3655
4274
|
["agent", "Spawn, list, chat, archive agents"],
|
|
3656
|
-
["memory", "Read/write a
|
|
4275
|
+
["memory", "Read/write a team's shared memory"],
|
|
3657
4276
|
["send", "Send a message from one agent to another"],
|
|
3658
4277
|
["inbox", "Inspect agent inboxes"],
|
|
3659
4278
|
["trigger", "Manage agent heartbeats / cron triggers"]
|
|
@@ -3679,8 +4298,8 @@ function printTopLevelHelp() {
|
|
|
3679
4298
|
items: [["completion", "Print shell completion script (bash | zsh | fish)"]]
|
|
3680
4299
|
}
|
|
3681
4300
|
];
|
|
3682
|
-
const nameWidth =
|
|
3683
|
-
for (const g of
|
|
4301
|
+
const nameWidth = 15;
|
|
4302
|
+
for (const g of teams) {
|
|
3684
4303
|
console.log(` ${g.title}`);
|
|
3685
4304
|
for (const [name, desc] of g.items) {
|
|
3686
4305
|
console.log(` ${name.padEnd(nameWidth)}${desc}`);
|
|
@@ -3709,7 +4328,7 @@ async function entry() {
|
|
|
3709
4328
|
await runCommand(main, { rawArgs });
|
|
3710
4329
|
} catch (err) {
|
|
3711
4330
|
printError(err);
|
|
3712
|
-
process.exit(
|
|
4331
|
+
process.exit(exitCodeForError(err));
|
|
3713
4332
|
}
|
|
3714
4333
|
}
|
|
3715
4334
|
entry();
|