bazilion 0.20.0 → 0.21.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +307 -288
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +567 -300
- package/dist/daemon.js.map +1 -1
- package/dist/migrations/0002_device_token_scopes.sql +8 -0
- package/dist/migrations/0003_web_pairing_tokens.sql +18 -0
- package/dist/web/client/assets/{ChatPane-CGCtAuD3.js → ChatPane--0BWZYHD.js} +1 -1
- package/dist/web/client/assets/{ConfirmDialog-Br19uXWH.js → ConfirmDialog-D9AiLH_Z.js} +1 -1
- package/dist/web/client/assets/{FieldRow-Csy3_cH5.js → FieldRow-Cd0EUpYd.js} +1 -1
- package/dist/web/client/assets/{ProductionTeamPolicyEditor-DG1x4Cqz.js → ProductionTeamPolicyEditor-BR5_1Wyv.js} +1 -1
- package/dist/web/client/assets/{ProfileCommunicationEditor-C3odNVkK.js → ProfileCommunicationEditor-K2wGbGky.js} +1 -1
- package/dist/web/client/assets/{ResultSourceConversation-5PFWqXTY.js → ResultSourceConversation-Y9VTd-nz.js} +1 -1
- package/dist/web/client/assets/{TeamTabs-BHB_COm0.js → TeamTabs-Yuc_lSZ9.js} +1 -1
- package/dist/web/client/assets/{TemplatesTabs-YyytjW7k.js → TemplatesTabs-Pj00chC7.js} +1 -1
- package/dist/web/client/assets/{UnsavedChangesGuard-CredyC3E.js → UnsavedChangesGuard-BSfJZH7E.js} +1 -1
- package/dist/web/client/assets/{_id-CIkPtQY0.js → _id-B4yPnTNN.js} +1 -1
- package/dist/web/client/assets/{_id-KXX6nuKc.js → _id-CUbb0F4l.js} +1 -1
- package/dist/web/client/assets/{_id-BZ_-4M4s.js → _id-D2l33vb6.js} +1 -1
- package/dist/web/client/assets/{_id-BLm9LVlZ.js → _id-DCFRZAJN.js} +1 -1
- package/dist/web/client/assets/{_id-nDbQY7f_.js → _id-UniNI3bQ.js} +1 -1
- package/dist/web/client/assets/{activity-BE7jG1Mz.js → activity-C5QG0Wgv.js} +1 -1
- package/dist/web/client/assets/{agents-S9lzXrrs.js → agents-CQo9V1lc.js} +1 -1
- package/dist/web/client/assets/{agents-vOPd-upn.js → agents-DVVPYxPM.js} +1 -1
- package/dist/web/client/assets/{approvals-BUfhlUAX.js → approvals-DQz6TJE8.js} +1 -1
- package/dist/web/client/assets/{attention-C3r-2GSp.js → attention-BtCLaWhZ.js} +1 -1
- package/dist/web/client/assets/chevron-right-BGFokHDA.js +1 -0
- package/dist/web/client/assets/{config-AL_EM57n.js → config-DuhKvD0X.js} +1 -1
- package/dist/web/client/assets/{inbox-LlCpJrMH.js → inbox-Cr7iGkrF.js} +1 -1
- package/dist/web/client/assets/{index-CwMw0pnV.js → index-ChXVa4eb.js} +2 -2
- package/dist/web/client/assets/{learning-zvTJ_9vM.js → learning-5eO_SZUP.js} +1 -1
- package/dist/web/client/assets/{login-BpQ54z8Y.js → login-Cn9mf44C.js} +1 -1
- package/dist/web/client/assets/{mcp-BD6VzXg_.js → mcp-0COajQD4.js} +1 -1
- package/dist/web/client/assets/{members-SEDi8SFo.js → members-9eTmy1QM.js} +1 -1
- package/dist/web/client/assets/{memory-zi_dPlMA.js → memory-CExQd_vP.js} +1 -1
- package/dist/web/client/assets/{policy-URjQAAdN.js → policy-B-zDlt_G.js} +1 -1
- package/dist/web/client/assets/{results-Bcuy4Flp.js → results-BUmKkuHo.js} +1 -1
- package/dist/web/client/assets/{review-CVH7X9-d.js → review-BUTz_zRX.js} +1 -1
- package/dist/web/client/assets/{routes-BJEX6yAE.js → routes-b1FscQsH.js} +1 -1
- package/dist/web/client/assets/{services-BTG4F5FL.js → services-D-RdMc8g.js} +1 -1
- package/dist/web/client/assets/{skills-DwiHS7eD.js → skills-CNbkY2ji.js} +1 -1
- package/dist/web/client/assets/{teams-DfpwQu1i.js → teams-Dn9o_-P-.js} +1 -1
- package/dist/web/client/assets/{teams-DcROmSGB.js → teams-H4OTWt8E.js} +1 -1
- package/dist/web/client/assets/{telegram-BLyaaUXE.js → telegram-BnM54CPN.js} +1 -1
- package/dist/web/client/assets/tokens-C-I23fVZ.js +1 -0
- package/dist/web/client/assets/{triggers-CtVhrAGA.js → triggers-DG9YoC7B.js} +1 -1
- package/dist/web/client/assets/{verifications-TC0ccGLY.js → verifications-CzToBSUN.js} +1 -1
- package/dist/web/client/assets/{welcome-DML3X1ha.js → welcome-REp-dEfY.js} +1 -1
- package/dist/web/client/assets/{x-D8yuCam7.js → x-C-BpLdcp.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-BGSoO6CK.js → _tanstack-start-manifest_v-BfURdqEL.js} +82 -82
- package/dist/web/server/assets/{router-BVhdWkwP.js → router-CyZ-GH8M.js} +1 -1
- package/dist/web/server/assets/{tokens-_2hptHP6.js → tokens-BFhrz5qd.js} +1 -1
- package/dist/web/server/assets/{tokens-DDwtO15P.js → tokens-DO_eDpv_.js} +96 -3
- package/dist/web/server/server.js +2 -2
- package/dist/worker.js +34 -19
- package/dist/worker.js.map +1 -1
- package/package.json +3 -3
- package/dist/web/client/assets/chevron-right-C7P3Z105.js +0 -1
- package/dist/web/client/assets/tokens-Dp9Vwvfx.js +0 -1
package/dist/cli.js
CHANGED
|
@@ -6,7 +6,7 @@ import { defineCommand as defineCommand39, runCommand, showUsage } from "citty";
|
|
|
6
6
|
// package.json
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "bazilion",
|
|
9
|
-
version: "0.
|
|
9
|
+
version: "0.21.0-beta.1",
|
|
10
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: {
|
|
@@ -1387,69 +1387,34 @@ var chatCmd = defineCommand5({
|
|
|
1387
1387
|
}
|
|
1388
1388
|
return;
|
|
1389
1389
|
}
|
|
1390
|
+
if (bashApprovalMode === "interactive") {
|
|
1391
|
+
console.error(
|
|
1392
|
+
`usage: bazilion agent chat ${args2.id} --message "..." (one-shot) \u2014 for a conversational surface, use the web UI`
|
|
1393
|
+
);
|
|
1394
|
+
process.exitCode = 1;
|
|
1395
|
+
return;
|
|
1396
|
+
}
|
|
1390
1397
|
console.log(`chatting with ${resolved.agent.name} (${resolved.model})`);
|
|
1391
|
-
console.log("(type /exit to quit)");
|
|
1398
|
+
console.log("(type /exit to quit; input is piped, commands run with auto_deny)");
|
|
1392
1399
|
const rl = createInterface({ input: stdin, output: stdout });
|
|
1393
1400
|
try {
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
let line;
|
|
1401
|
-
try {
|
|
1402
|
-
const answer = rl.question("> ");
|
|
1403
|
-
if (retryDraft) {
|
|
1404
|
-
rl.write(retryDraft);
|
|
1405
|
-
retryDraft = "";
|
|
1406
|
-
}
|
|
1407
|
-
line = await answer;
|
|
1408
|
-
} catch {
|
|
1409
|
-
break;
|
|
1410
|
-
}
|
|
1411
|
-
const trimmed = line.trim();
|
|
1412
|
-
if (trimmed === "/exit" || trimmed === "/quit") break;
|
|
1413
|
-
if (!trimmed) continue;
|
|
1414
|
-
try {
|
|
1415
|
-
await streamTurn(client, resolved.agent.id, trimmed, void 0, {
|
|
1416
|
-
bashApprovalMode,
|
|
1417
|
-
expectedSelection: observed.selection,
|
|
1418
|
-
questionPrompt: {
|
|
1419
|
-
question: (text2, signal) => rl.question(text2, { signal }),
|
|
1420
|
-
write: (line2) => console.log(line2)
|
|
1421
|
-
},
|
|
1422
|
-
approvalPrompt: {
|
|
1423
|
-
question: (question) => rl.question(question),
|
|
1424
|
-
write: (output4) => console.log(output4)
|
|
1425
|
-
}
|
|
1426
|
-
});
|
|
1427
|
-
} catch (err) {
|
|
1428
|
-
retryDraft = trimmed;
|
|
1429
|
-
console.error(
|
|
1430
|
-
`error: ${err.message}. Review the preserved draft before retrying.`
|
|
1431
|
-
);
|
|
1432
|
-
}
|
|
1433
|
-
}
|
|
1434
|
-
} else {
|
|
1435
|
-
rl.setPrompt("> ");
|
|
1436
|
-
rl.prompt();
|
|
1437
|
-
for await (const line of rl) {
|
|
1438
|
-
const trimmed = line.trim();
|
|
1439
|
-
if (trimmed === "/exit" || trimmed === "/quit") break;
|
|
1440
|
-
if (!trimmed) {
|
|
1441
|
-
rl.prompt();
|
|
1442
|
-
continue;
|
|
1443
|
-
}
|
|
1444
|
-
try {
|
|
1445
|
-
await streamTurn(client, resolved.agent.id, trimmed, void 0, {
|
|
1446
|
-
bashApprovalMode
|
|
1447
|
-
});
|
|
1448
|
-
} catch (err) {
|
|
1449
|
-
console.error(`error: ${err.message}`);
|
|
1450
|
-
}
|
|
1401
|
+
rl.setPrompt("> ");
|
|
1402
|
+
rl.prompt();
|
|
1403
|
+
for await (const line of rl) {
|
|
1404
|
+
const trimmed = line.trim();
|
|
1405
|
+
if (trimmed === "/exit" || trimmed === "/quit") break;
|
|
1406
|
+
if (!trimmed) {
|
|
1451
1407
|
rl.prompt();
|
|
1408
|
+
continue;
|
|
1452
1409
|
}
|
|
1410
|
+
try {
|
|
1411
|
+
await streamTurn(client, resolved.agent.id, trimmed, void 0, {
|
|
1412
|
+
bashApprovalMode
|
|
1413
|
+
});
|
|
1414
|
+
} catch (err) {
|
|
1415
|
+
console.error(`error: ${err.message}`);
|
|
1416
|
+
}
|
|
1417
|
+
rl.prompt();
|
|
1453
1418
|
}
|
|
1454
1419
|
} finally {
|
|
1455
1420
|
rl.close();
|
|
@@ -2318,16 +2283,16 @@ import {
|
|
|
2318
2283
|
mkdirSync as mkdirSync2,
|
|
2319
2284
|
mkdtempSync,
|
|
2320
2285
|
openSync as openSync2,
|
|
2321
|
-
readdirSync,
|
|
2322
|
-
readFileSync as
|
|
2286
|
+
readdirSync as readdirSync2,
|
|
2287
|
+
readFileSync as readFileSync6,
|
|
2323
2288
|
readSync,
|
|
2324
2289
|
renameSync as renameSync2,
|
|
2325
2290
|
rmSync as rmSync2,
|
|
2326
2291
|
writeFileSync as writeFileSync2
|
|
2327
2292
|
} from "fs";
|
|
2328
2293
|
import { tmpdir } from "os";
|
|
2329
|
-
import { basename as basename4, dirname as
|
|
2330
|
-
import { DatabaseSync as
|
|
2294
|
+
import { basename as basename4, dirname as dirname3, isAbsolute, parse, posix, relative, resolve as resolve3 } from "path";
|
|
2295
|
+
import { DatabaseSync as DatabaseSync4, backup as sqliteBackup } from "node:sqlite";
|
|
2331
2296
|
import { Readable } from "stream";
|
|
2332
2297
|
import { pipeline } from "stream/promises";
|
|
2333
2298
|
import { Decrypter, Encrypter } from "age-encryption";
|
|
@@ -2475,174 +2440,180 @@ function pauseRestoredUserQueue(database) {
|
|
|
2475
2440
|
|
|
2476
2441
|
// src/backup-schema.ts
|
|
2477
2442
|
import { createHash } from "crypto";
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
|
|
2555
|
-
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
["table", "trigger_dispatches"],
|
|
2596
|
-
["table", "web_tokens"],
|
|
2597
|
-
["table", "web_sessions"],
|
|
2598
|
-
["trigger", "create_team_policy"],
|
|
2599
|
-
["trigger", "prevent_detached_team_policy_delete"],
|
|
2600
|
-
["trigger", "validate_source_binding_insert"],
|
|
2601
|
-
["trigger", "validate_team_agent_state_insert"],
|
|
2602
|
-
["trigger", "validate_team_policy_baseline_update"],
|
|
2603
|
-
["trigger", "validate_team_policy_edge_insert"],
|
|
2604
|
-
["trigger", "validate_team_template_edge_insert"],
|
|
2605
|
-
// BAZ-046: one operator-approved publication of a reviewed revision to a code host.
|
|
2606
|
-
["table", "publications"],
|
|
2607
|
-
["index", "publications_team_time"],
|
|
2608
|
-
["index", "publications_packet_published"],
|
|
2609
|
-
["index", "publications_lease"]
|
|
2610
|
-
];
|
|
2443
|
+
|
|
2444
|
+
// ../daemon/src/core/db/migrate.ts
|
|
2445
|
+
import { readdirSync, readFileSync as readFileSync4 } from "fs";
|
|
2446
|
+
import { dirname, join as join2 } from "path";
|
|
2447
|
+
import { DatabaseSync as DatabaseSync3 } from "node:sqlite";
|
|
2448
|
+
import { fileURLToPath } from "url";
|
|
2449
|
+
|
|
2450
|
+
// ../daemon/src/core/db/client.ts
|
|
2451
|
+
import { backup, DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
2452
|
+
function wrap(rawDb) {
|
|
2453
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2454
|
+
let transactionDepth = 0;
|
|
2455
|
+
let savepointSequence = 0;
|
|
2456
|
+
function getStmt(sql) {
|
|
2457
|
+
let s = cache.get(sql);
|
|
2458
|
+
if (!s) {
|
|
2459
|
+
s = rawDb.prepare(sql);
|
|
2460
|
+
cache.set(sql, s);
|
|
2461
|
+
}
|
|
2462
|
+
return s;
|
|
2463
|
+
}
|
|
2464
|
+
return {
|
|
2465
|
+
query(sql) {
|
|
2466
|
+
const stmt = getStmt(sql);
|
|
2467
|
+
return {
|
|
2468
|
+
get(...params) {
|
|
2469
|
+
const result = stmt.get(...params);
|
|
2470
|
+
return result ?? null;
|
|
2471
|
+
},
|
|
2472
|
+
all(...params) {
|
|
2473
|
+
return stmt.all(...params);
|
|
2474
|
+
},
|
|
2475
|
+
run(...params) {
|
|
2476
|
+
return stmt.run(...params);
|
|
2477
|
+
}
|
|
2478
|
+
};
|
|
2479
|
+
},
|
|
2480
|
+
run(sql, params) {
|
|
2481
|
+
const stmt = getStmt(sql);
|
|
2482
|
+
return stmt.run(...params ?? []);
|
|
2483
|
+
},
|
|
2484
|
+
exec(sql) {
|
|
2485
|
+
rawDb.exec(sql);
|
|
2486
|
+
},
|
|
2487
|
+
// node:sqlite has no callable `transaction` wrapper; use manual BEGIN/COMMIT/ROLLBACK.
|
|
2488
|
+
transaction(fn) {
|
|
2489
|
+
return () => {
|
|
2490
|
+
const outermost = transactionDepth === 0;
|
|
2491
|
+
const savepoint = outermost ? null : `bazilion_nested_${++savepointSequence}`;
|
|
2492
|
+
if (outermost) rawDb.exec("BEGIN");
|
|
2493
|
+
else rawDb.exec(`SAVEPOINT ${savepoint}`);
|
|
2494
|
+
transactionDepth++;
|
|
2495
|
+
try {
|
|
2496
|
+
const result = fn();
|
|
2497
|
+
if (outermost) rawDb.exec("COMMIT");
|
|
2498
|
+
else rawDb.exec(`RELEASE SAVEPOINT ${savepoint}`);
|
|
2499
|
+
return result;
|
|
2500
|
+
} catch (err) {
|
|
2501
|
+
if (outermost) rawDb.exec("ROLLBACK");
|
|
2502
|
+
else {
|
|
2503
|
+
rawDb.exec(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
2504
|
+
rawDb.exec(`RELEASE SAVEPOINT ${savepoint}`);
|
|
2505
|
+
}
|
|
2506
|
+
throw err;
|
|
2507
|
+
} finally {
|
|
2508
|
+
transactionDepth--;
|
|
2509
|
+
}
|
|
2510
|
+
};
|
|
2511
|
+
}
|
|
2512
|
+
};
|
|
2513
|
+
}
|
|
2514
|
+
function applyPragmas(rawDb, includeWal) {
|
|
2515
|
+
if (includeWal) {
|
|
2516
|
+
try {
|
|
2517
|
+
rawDb.exec("PRAGMA journal_mode = WAL");
|
|
2518
|
+
} catch {
|
|
2519
|
+
}
|
|
2520
|
+
}
|
|
2521
|
+
rawDb.exec("PRAGMA foreign_keys = ON");
|
|
2522
|
+
}
|
|
2523
|
+
function openInMemoryDb() {
|
|
2524
|
+
const raw = new DatabaseSync2(":memory:");
|
|
2525
|
+
applyPragmas(raw, false);
|
|
2526
|
+
return {
|
|
2527
|
+
raw: wrap(raw),
|
|
2528
|
+
backupTo(path) {
|
|
2529
|
+
return backup(raw, path);
|
|
2530
|
+
},
|
|
2531
|
+
close() {
|
|
2532
|
+
raw.close();
|
|
2533
|
+
}
|
|
2534
|
+
};
|
|
2535
|
+
}
|
|
2536
|
+
|
|
2537
|
+
// ../daemon/src/core/db/migrate.ts
|
|
2538
|
+
var migrationsDir = join2(dirname(fileURLToPath(import.meta.url)), "migrations");
|
|
2539
|
+
var schemaMigrationsSql = `
|
|
2540
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
2541
|
+
version TEXT PRIMARY KEY,
|
|
2542
|
+
applied_at INTEGER NOT NULL
|
|
2543
|
+
)
|
|
2544
|
+
`;
|
|
2545
|
+
function listMigrations() {
|
|
2546
|
+
return readdirSync(migrationsDir).filter((file) => file.endsWith(".sql")).sort().map((file) => ({
|
|
2547
|
+
version: file.replace(/\.sql$/, ""),
|
|
2548
|
+
sql: readFileSync4(join2(migrationsDir, file), "utf8")
|
|
2549
|
+
}));
|
|
2550
|
+
}
|
|
2551
|
+
var canonicalSchemaObjectsByPrefix = /* @__PURE__ */ new Map();
|
|
2552
|
+
function schemaObjects(db) {
|
|
2553
|
+
return db.raw.query(
|
|
2554
|
+
`SELECT type, name, tbl_name, sql
|
|
2555
|
+
FROM sqlite_schema
|
|
2556
|
+
WHERE sql IS NOT NULL AND substr(name, 1, 7) <> 'sqlite_'
|
|
2557
|
+
ORDER BY type, name`
|
|
2558
|
+
).all();
|
|
2559
|
+
}
|
|
2611
2560
|
function normalizeSql(sql) {
|
|
2612
2561
|
return sql.replace(/\s+/g, " ").trim();
|
|
2613
2562
|
}
|
|
2614
|
-
function
|
|
2615
|
-
const
|
|
2616
|
-
if (
|
|
2563
|
+
function expectedSchema(files, prefixLength) {
|
|
2564
|
+
const cached = canonicalSchemaObjectsByPrefix.get(prefixLength);
|
|
2565
|
+
if (cached) return cached;
|
|
2566
|
+
const canonical = openInMemoryDb();
|
|
2567
|
+
try {
|
|
2568
|
+
canonical.raw.exec(schemaMigrationsSql);
|
|
2569
|
+
for (const file of files.slice(0, prefixLength)) canonical.raw.exec(file.sql);
|
|
2570
|
+
const objects = schemaObjects(canonical);
|
|
2571
|
+
canonicalSchemaObjectsByPrefix.set(prefixLength, objects);
|
|
2572
|
+
return objects;
|
|
2573
|
+
} finally {
|
|
2574
|
+
canonical.close();
|
|
2575
|
+
}
|
|
2576
|
+
}
|
|
2577
|
+
function assertSchemaMatchesCanonicalChain(raw) {
|
|
2578
|
+
const files = listMigrations();
|
|
2579
|
+
const expectedVersions = files.map((file) => file.version);
|
|
2580
|
+
const applied = raw.prepare("SELECT version FROM schema_migrations ORDER BY version").all().map((row2) => row2.version);
|
|
2581
|
+
if (applied.length !== expectedVersions.length || applied.some((version, index) => version !== expectedVersions[index])) {
|
|
2617
2582
|
throw new Error(
|
|
2618
|
-
`schema_migrations must contain exactly ${
|
|
2583
|
+
`schema_migrations must contain exactly ${expectedVersions.join(", ")}; found ` + (applied.join(", ") || "none")
|
|
2619
2584
|
);
|
|
2620
2585
|
}
|
|
2621
|
-
const rows =
|
|
2586
|
+
const rows = raw.prepare(
|
|
2622
2587
|
`SELECT type, name, tbl_name, sql
|
|
2623
2588
|
FROM sqlite_schema
|
|
2624
|
-
WHERE sql IS NOT NULL AND name
|
|
2589
|
+
WHERE sql IS NOT NULL AND substr(name, 1, 7) <> 'sqlite_'
|
|
2590
|
+
ORDER BY type, name`
|
|
2625
2591
|
).all();
|
|
2626
|
-
const
|
|
2627
|
-
const canonicalKeys = new Set(
|
|
2592
|
+
const canonical = expectedSchema(files, files.length);
|
|
2593
|
+
const canonicalKeys = new Set(canonical.map((row2) => `${row2.type}\0${row2.name}`));
|
|
2594
|
+
const actualKeys = new Map(rows.map((row2) => [`${row2.type}\0${row2.name}`, row2]));
|
|
2595
|
+
for (const row2 of canonical) {
|
|
2596
|
+
if (!actualKeys.has(`${row2.type}\0${row2.name}`)) {
|
|
2597
|
+
throw new Error(`required canonical schema ${row2.type} is missing: ${row2.name}`);
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2628
2600
|
for (const row2 of rows) {
|
|
2629
2601
|
if (!canonicalKeys.has(`${row2.type}\0${row2.name}`)) {
|
|
2630
2602
|
throw new Error(`unexpected schema ${row2.type} is not canonical: ${row2.name}`);
|
|
2631
2603
|
}
|
|
2632
2604
|
}
|
|
2633
|
-
const
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
if (!row2) throw new Error(`required canonical schema ${type} is missing: ${name}`);
|
|
2637
|
-
canonicalRows.push(row2);
|
|
2638
|
-
}
|
|
2639
|
-
const payload = canonicalRows.map((row2) => [row2.type, row2.name, row2.tbl_name, normalizeSql(row2.sql)].join("\0")).join("\n");
|
|
2640
|
-
const actualHash = createHash("sha256").update(payload).digest("hex");
|
|
2641
|
-
if (actualHash !== CANONICAL_SCHEMA_HASH) {
|
|
2605
|
+
const payload = rows.map((row2) => [row2.type, row2.name, row2.tbl_name, normalizeSql(row2.sql)].join("\0")).join("\n");
|
|
2606
|
+
const canonicalPayload = canonical.map((row2) => [row2.type, row2.name, row2.tbl_name, normalizeSql(row2.sql)].join("\0")).join("\n");
|
|
2607
|
+
if (payload !== canonicalPayload) {
|
|
2642
2608
|
throw new Error(
|
|
2643
|
-
"
|
|
2609
|
+
"database schema does not match this release\u2019s canonical migration chain; restore a backup created from the current release"
|
|
2644
2610
|
);
|
|
2645
2611
|
}
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
// src/backup-schema.ts
|
|
2615
|
+
function assertCanonicalBackupSchema(db) {
|
|
2616
|
+
assertSchemaMatchesCanonicalChain(db);
|
|
2646
2617
|
for (const row2 of db.prepare("SELECT id, bytes, byte_length, sha256 FROM agent_results WHERE deleted_at IS NULL").iterate()) {
|
|
2647
2618
|
const bytes = row2.bytes;
|
|
2648
2619
|
if (!(bytes instanceof Uint8Array) || bytes.byteLength !== row2.byte_length || createHash("sha256").update(bytes).digest("hex") !== row2.sha256) {
|
|
@@ -2663,13 +2634,13 @@ import {
|
|
|
2663
2634
|
lstatSync as lstatSync2,
|
|
2664
2635
|
mkdirSync,
|
|
2665
2636
|
openSync,
|
|
2666
|
-
readFileSync as
|
|
2637
|
+
readFileSync as readFileSync5,
|
|
2667
2638
|
realpathSync,
|
|
2668
2639
|
renameSync,
|
|
2669
2640
|
rmSync,
|
|
2670
2641
|
writeSync
|
|
2671
2642
|
} from "fs";
|
|
2672
|
-
import { basename as basename3, dirname, join as
|
|
2643
|
+
import { basename as basename3, dirname as dirname2, join as join3, resolve as resolve2 } from "path";
|
|
2673
2644
|
var DAEMON_LIVENESS_FILENAME = "daemon-runtime.json";
|
|
2674
2645
|
var STALE_AFTER_MS = 6e4;
|
|
2675
2646
|
var PROBE_TIMEOUT_MS = 750;
|
|
@@ -2679,15 +2650,15 @@ function canonicalHomeIdentity(home) {
|
|
|
2679
2650
|
return realpathSync.native(absolute);
|
|
2680
2651
|
} catch (error) {
|
|
2681
2652
|
if (errorCode(error) !== "ENOENT") throw error;
|
|
2682
|
-
const parent =
|
|
2653
|
+
const parent = dirname2(absolute);
|
|
2683
2654
|
if (parent === absolute) throw error;
|
|
2684
|
-
return
|
|
2655
|
+
return join3(canonicalHomeIdentity(parent), basename3(absolute));
|
|
2685
2656
|
}
|
|
2686
2657
|
}
|
|
2687
2658
|
function daemonLivenessPath(home) {
|
|
2688
2659
|
const canonicalHome = canonicalHomeIdentity(home);
|
|
2689
2660
|
const identity = createHash2("sha256").update(canonicalHome).digest("hex").slice(0, 24);
|
|
2690
|
-
return
|
|
2661
|
+
return join3(dirname2(canonicalHome), `.bazilion-runtime-${identity}.json`);
|
|
2691
2662
|
}
|
|
2692
2663
|
function errorCode(error) {
|
|
2693
2664
|
return error instanceof Error && "code" in error && typeof error.code === "string" ? error.code : void 0;
|
|
@@ -2725,7 +2696,7 @@ function parseRecord(raw) {
|
|
|
2725
2696
|
function readRecord(path) {
|
|
2726
2697
|
try {
|
|
2727
2698
|
const stat = lstatSync2(path);
|
|
2728
|
-
const raw = stat.isFile() ?
|
|
2699
|
+
const raw = stat.isFile() ? readFileSync5(path, "utf8") : "";
|
|
2729
2700
|
return { raw, stat, record: stat.isFile() ? parseRecord(raw) : null };
|
|
2730
2701
|
} catch (error) {
|
|
2731
2702
|
if (errorCode(error) === "ENOENT") return null;
|
|
@@ -2782,7 +2753,7 @@ function writeRecord(fd, record) {
|
|
|
2782
2753
|
function fsyncParentDirectory(path) {
|
|
2783
2754
|
let directoryFd = null;
|
|
2784
2755
|
try {
|
|
2785
|
-
directoryFd = openSync(
|
|
2756
|
+
directoryFd = openSync(dirname2(path), "r");
|
|
2786
2757
|
fsyncSync(directoryFd);
|
|
2787
2758
|
} catch (error) {
|
|
2788
2759
|
if (process.platform !== "win32") throw error;
|
|
@@ -2804,7 +2775,7 @@ function reclaimRecord(path, existing) {
|
|
|
2804
2775
|
return null;
|
|
2805
2776
|
}
|
|
2806
2777
|
try {
|
|
2807
|
-
renameSync(path,
|
|
2778
|
+
renameSync(path, join3(claim, "stale-record.json"));
|
|
2808
2779
|
return claim;
|
|
2809
2780
|
} catch (error) {
|
|
2810
2781
|
if (errorCode(error) === "ENOENT") return null;
|
|
@@ -2813,9 +2784,9 @@ function reclaimRecord(path, existing) {
|
|
|
2813
2784
|
}
|
|
2814
2785
|
async function acquireHomeRestoreLock(home, operation = "restoring") {
|
|
2815
2786
|
const targetHome = resolve2(home);
|
|
2816
|
-
mkdirSync(
|
|
2787
|
+
mkdirSync(dirname2(targetHome), { recursive: true });
|
|
2817
2788
|
const path = daemonLivenessPath(targetHome);
|
|
2818
|
-
mkdirSync(
|
|
2789
|
+
mkdirSync(dirname2(path), { recursive: true });
|
|
2819
2790
|
const instanceId = randomUUID6();
|
|
2820
2791
|
let fd = null;
|
|
2821
2792
|
let reclaimClaim = null;
|
|
@@ -3060,7 +3031,7 @@ var createCmd = defineCommand9({
|
|
|
3060
3031
|
} catch (error) {
|
|
3061
3032
|
if (!(error instanceof Error) || !("code" in error) || error.code !== "EXDEV") throw error;
|
|
3062
3033
|
const installPartial = resolve3(
|
|
3063
|
-
|
|
3034
|
+
dirname3(outAbs),
|
|
3064
3035
|
`.${basename4(outAbs)}.${randomUUID7()}.installing`
|
|
3065
3036
|
);
|
|
3066
3037
|
try {
|
|
@@ -3247,7 +3218,7 @@ function validateArchiveEntries(entries) {
|
|
|
3247
3218
|
function validateAuthFile(path) {
|
|
3248
3219
|
let parsed;
|
|
3249
3220
|
try {
|
|
3250
|
-
parsed = JSON.parse(
|
|
3221
|
+
parsed = JSON.parse(readFileSync6(path, "utf8"));
|
|
3251
3222
|
} catch (error) {
|
|
3252
3223
|
const detail = error instanceof Error ? error.message : String(error);
|
|
3253
3224
|
throw new Error(`backup auth.json is invalid: ${detail}`);
|
|
@@ -3260,7 +3231,7 @@ function validateAuthFile(path) {
|
|
|
3260
3231
|
function validateDatabase(path, authToken) {
|
|
3261
3232
|
let db = null;
|
|
3262
3233
|
try {
|
|
3263
|
-
db = new
|
|
3234
|
+
db = new DatabaseSync4(path, { readOnly: true });
|
|
3264
3235
|
const integrity = db.prepare("PRAGMA integrity_check").all();
|
|
3265
3236
|
if (integrity.length !== 1 || integrity[0]?.integrity_check !== "ok") {
|
|
3266
3237
|
const detail = integrity.map((row2) => row2.integrity_check).join("; ") || "no result";
|
|
@@ -3324,7 +3295,7 @@ function requireExtractedTeamSlot(path, rowLabel) {
|
|
|
3324
3295
|
function rebaseRestoredHomeDirectories(database, payload, targetHome) {
|
|
3325
3296
|
let db = null;
|
|
3326
3297
|
try {
|
|
3327
|
-
db = new
|
|
3298
|
+
db = new DatabaseSync4(database);
|
|
3328
3299
|
db.exec("PRAGMA foreign_keys = ON");
|
|
3329
3300
|
const profiles = db.prepare("SELECT id FROM profiles ORDER BY id").all();
|
|
3330
3301
|
const agents = db.prepare("SELECT id FROM agents ORDER BY id").all();
|
|
@@ -3401,11 +3372,11 @@ function rebaseRestoredHomeDirectories(database, payload, targetHome) {
|
|
|
3401
3372
|
function removeRebuildableQmdIndexes(payload) {
|
|
3402
3373
|
const teamsDir = resolve3(payload, "teams");
|
|
3403
3374
|
if (!existsSync2(teamsDir) || !lstatSync3(teamsDir).isDirectory()) return;
|
|
3404
|
-
for (const team of
|
|
3375
|
+
for (const team of readdirSync2(teamsDir, { withFileTypes: true })) {
|
|
3405
3376
|
if (!team.isDirectory() || team.isSymbolicLink()) continue;
|
|
3406
3377
|
const memoryDir = resolve3(teamsDir, team.name, "memory");
|
|
3407
3378
|
if (!existsSync2(memoryDir) || !lstatSync3(memoryDir).isDirectory()) continue;
|
|
3408
|
-
for (const entry3 of
|
|
3379
|
+
for (const entry3 of readdirSync2(memoryDir, { withFileTypes: true })) {
|
|
3409
3380
|
if (entry3.isFile() && entry3.name.startsWith(".qmd-index.sqlite")) {
|
|
3410
3381
|
rmSync2(resolve3(memoryDir, entry3.name), { force: true });
|
|
3411
3382
|
}
|
|
@@ -3413,7 +3384,7 @@ function removeRebuildableQmdIndexes(payload) {
|
|
|
3413
3384
|
}
|
|
3414
3385
|
}
|
|
3415
3386
|
function revokeRestoredBrowserSessions(database) {
|
|
3416
|
-
const db = new
|
|
3387
|
+
const db = new DatabaseSync4(database);
|
|
3417
3388
|
try {
|
|
3418
3389
|
db.prepare("UPDATE web_sessions SET revoked_at = ? WHERE revoked_at IS NULL").run(Date.now());
|
|
3419
3390
|
} finally {
|
|
@@ -3423,7 +3394,7 @@ function revokeRestoredBrowserSessions(database) {
|
|
|
3423
3394
|
function installValidatedPayload(payload, targetHome, staging, lifecycle, operations = { rename: renameSync2 }) {
|
|
3424
3395
|
const previous = resolve3(staging, "previous-home");
|
|
3425
3396
|
const hadPrevious = existsSync2(targetHome);
|
|
3426
|
-
const targetParent =
|
|
3397
|
+
const targetParent = dirname3(targetHome);
|
|
3427
3398
|
const syncDirectory = operations.fsyncDirectory ?? fsyncDirectory;
|
|
3428
3399
|
const recoveryError = (message, recoveryPath, cause) => {
|
|
3429
3400
|
let markerError;
|
|
@@ -3558,7 +3529,7 @@ function readAgeIdentity(rawPath) {
|
|
|
3558
3529
|
if (process.platform !== "win32" && (entry3.mode & 63) !== 0) {
|
|
3559
3530
|
throw new Error(`age identity must be owner-only (chmod 600): ${path}`);
|
|
3560
3531
|
}
|
|
3561
|
-
const identities =
|
|
3532
|
+
const identities = readFileSync6(path, "utf8").split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
3562
3533
|
if (identities.length !== 1 || !identities[0]?.startsWith("AGE-SECRET-KEY-")) {
|
|
3563
3534
|
throw new Error("age identity file must contain exactly one supported AGE-SECRET-KEY entry");
|
|
3564
3535
|
}
|
|
@@ -3593,7 +3564,7 @@ var restoreCmd = defineCommand9({
|
|
|
3593
3564
|
if (targetHome === parse(targetHome).root) {
|
|
3594
3565
|
throw new Error(`refusing to restore over filesystem root: ${targetHome}`);
|
|
3595
3566
|
}
|
|
3596
|
-
const targetParent =
|
|
3567
|
+
const targetParent = dirname3(targetHome);
|
|
3597
3568
|
mkdirSync2(targetParent, { recursive: true });
|
|
3598
3569
|
const restoreLock = await acquireHomeRestoreLock(targetHome);
|
|
3599
3570
|
try {
|
|
@@ -3611,7 +3582,7 @@ var restoreCmd = defineCommand9({
|
|
|
3611
3582
|
if (!lstatSync3(targetHome).isDirectory()) {
|
|
3612
3583
|
throw new Error(`${targetHome} exists and is not a directory`);
|
|
3613
3584
|
}
|
|
3614
|
-
const entries =
|
|
3585
|
+
const entries = readdirSync2(targetHome);
|
|
3615
3586
|
if (entries.length > 0 && !args2.force) {
|
|
3616
3587
|
throw new Error(
|
|
3617
3588
|
`${targetHome} is not empty. Pass --force to overwrite (destroys existing data).`
|
|
@@ -3734,7 +3705,7 @@ function credentialInventory(home) {
|
|
|
3734
3705
|
const database = resolve3(home, "bazilion.db");
|
|
3735
3706
|
const token = validateAuthFile(authFile);
|
|
3736
3707
|
validateDatabase(database, token);
|
|
3737
|
-
const db = new
|
|
3708
|
+
const db = new DatabaseSync4(database, { readOnly: true });
|
|
3738
3709
|
try {
|
|
3739
3710
|
const activeTokens = db.prepare(
|
|
3740
3711
|
"SELECT COUNT(*) AS count FROM web_tokens WHERE revoked_at IS NULL AND kind = 'device' AND expires_at > ?"
|
|
@@ -3793,7 +3764,7 @@ var rotateBootstrapCmd = defineCommand9({
|
|
|
3793
3764
|
throw new Error(`refusing to rotate filesystem root: ${targetHome}`);
|
|
3794
3765
|
}
|
|
3795
3766
|
const lock = await acquireHomeRestoreLock(targetHome);
|
|
3796
|
-
const parent =
|
|
3767
|
+
const parent = dirname3(targetHome);
|
|
3797
3768
|
const staging = mkdtempSync(resolve3(parent, ".bazilion-rotate-"));
|
|
3798
3769
|
const payload = resolve3(staging, "payload");
|
|
3799
3770
|
let preserveStaging = false;
|
|
@@ -3803,7 +3774,7 @@ var rotateBootstrapCmd = defineCommand9({
|
|
|
3803
3774
|
throw new Error(`bazilion server appears to be running at ${serverUrl} \u2014 stop it first.`);
|
|
3804
3775
|
}
|
|
3805
3776
|
}
|
|
3806
|
-
const oldAuth = JSON.parse(
|
|
3777
|
+
const oldAuth = JSON.parse(readFileSync6(paths.authFile, "utf8"));
|
|
3807
3778
|
if (typeof oldAuth.token !== "string" || !oldAuth.token) {
|
|
3808
3779
|
throw new Error("auth.json is missing the bootstrap token");
|
|
3809
3780
|
}
|
|
@@ -3816,7 +3787,7 @@ var rotateBootstrapCmd = defineCommand9({
|
|
|
3816
3787
|
});
|
|
3817
3788
|
const stagedDb = resolve3(payload, "bazilion.db");
|
|
3818
3789
|
rmSync2(stagedDb, { force: true });
|
|
3819
|
-
const sourceDb = new
|
|
3790
|
+
const sourceDb = new DatabaseSync4(resolve3(targetHome, "bazilion.db"), { readOnly: true });
|
|
3820
3791
|
try {
|
|
3821
3792
|
await sqliteBackup(sourceDb, stagedDb);
|
|
3822
3793
|
} finally {
|
|
@@ -3825,7 +3796,7 @@ var rotateBootstrapCmd = defineCommand9({
|
|
|
3825
3796
|
for (const suffix of ["-wal", "-shm", "-journal"])
|
|
3826
3797
|
rmSync2(`${stagedDb}${suffix}`, { force: true });
|
|
3827
3798
|
const newToken = randomBytes(24).toString("hex");
|
|
3828
|
-
const db = new
|
|
3799
|
+
const db = new DatabaseSync4(stagedDb);
|
|
3829
3800
|
try {
|
|
3830
3801
|
db.exec("PRAGMA foreign_keys = ON; BEGIN IMMEDIATE");
|
|
3831
3802
|
try {
|
|
@@ -4122,16 +4093,16 @@ var configCommand = defineCommand11({
|
|
|
4122
4093
|
import { spawn } from "child_process";
|
|
4123
4094
|
import { existsSync as existsSync3 } from "fs";
|
|
4124
4095
|
import { connect } from "net";
|
|
4125
|
-
import { join as
|
|
4096
|
+
import { join as join4 } from "path";
|
|
4126
4097
|
import { defineCommand as defineCommand12 } from "citty";
|
|
4127
|
-
var bundledDaemonEntry =
|
|
4128
|
-
var sourceDaemonEntry =
|
|
4098
|
+
var bundledDaemonEntry = join4(import.meta.dirname, "daemon.js");
|
|
4099
|
+
var sourceDaemonEntry = join4(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
|
|
4129
4100
|
var daemonEntry = existsSync3(bundledDaemonEntry) ? bundledDaemonEntry : sourceDaemonEntry;
|
|
4130
|
-
var bundledWebServerEntry =
|
|
4131
|
-
var sourceWebServerEntry =
|
|
4101
|
+
var bundledWebServerEntry = join4(import.meta.dirname, "web-server.js");
|
|
4102
|
+
var sourceWebServerEntry = join4(import.meta.dirname, "..", "web-server.ts");
|
|
4132
4103
|
var webServerEntry = existsSync3(bundledWebServerEntry) ? bundledWebServerEntry : sourceWebServerEntry;
|
|
4133
|
-
var bundledWebDist =
|
|
4134
|
-
var sourceWebDist =
|
|
4104
|
+
var bundledWebDist = join4(import.meta.dirname, "web");
|
|
4105
|
+
var sourceWebDist = join4(import.meta.dirname, "..", "..", "..", "web", "dist");
|
|
4135
4106
|
var webDist = existsSync3(bundledWebDist) ? bundledWebDist : sourceWebDist;
|
|
4136
4107
|
function nodeArgs(entry3) {
|
|
4137
4108
|
return entry3.endsWith(".ts") ? ["--import", "tsx/esm", entry3] : [entry3];
|
|
@@ -4294,7 +4265,7 @@ var dashboardCommand = defineCommand12({
|
|
|
4294
4265
|
`web UI port ${webPort} is already in use. Re-run with --port <free-port>.`
|
|
4295
4266
|
);
|
|
4296
4267
|
}
|
|
4297
|
-
if (!existsSync3(
|
|
4268
|
+
if (!existsSync3(join4(webDist, "server", "server.js"))) {
|
|
4298
4269
|
throw new Error(
|
|
4299
4270
|
`bazilion web UI bundle not found at ${webDist}. Run "pnpm --filter @bazilion/web build" from the repository root of a source checkout, or reinstall the published package.`
|
|
4300
4271
|
);
|
|
@@ -4699,7 +4670,7 @@ var inboxCommand = defineCommand15({
|
|
|
4699
4670
|
});
|
|
4700
4671
|
|
|
4701
4672
|
// src/commands/login.ts
|
|
4702
|
-
import { existsSync as existsSync4, readFileSync as
|
|
4673
|
+
import { existsSync as existsSync4, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
|
|
4703
4674
|
import { defineCommand as defineCommand16 } from "citty";
|
|
4704
4675
|
function normalizeServer(raw) {
|
|
4705
4676
|
let url;
|
|
@@ -4742,7 +4713,7 @@ var loginCommand = defineCommand16({
|
|
|
4742
4713
|
`${paths.authFile} not found. Start the daemon with "bazilion serve" first \u2014 login stores the remote there.`
|
|
4743
4714
|
);
|
|
4744
4715
|
}
|
|
4745
|
-
const auth = JSON.parse(
|
|
4716
|
+
const auth = JSON.parse(readFileSync7(paths.authFile, "utf8"));
|
|
4746
4717
|
if (args2.clear) {
|
|
4747
4718
|
if (!auth.remote) {
|
|
4748
4719
|
console.log("no remote stored \u2014 nothing to clear");
|
|
@@ -4992,9 +4963,9 @@ var memoryCommand = defineCommand18({
|
|
|
4992
4963
|
// src/commands/profile.ts
|
|
4993
4964
|
import { spawn as spawn2 } from "child_process";
|
|
4994
4965
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
4995
|
-
import { readFileSync as
|
|
4966
|
+
import { readFileSync as readFileSync8, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
|
|
4996
4967
|
import { tmpdir as tmpdir2 } from "os";
|
|
4997
|
-
import { join as
|
|
4968
|
+
import { join as join5 } from "path";
|
|
4998
4969
|
|
|
4999
4970
|
// ../../packages/api-types/src/git-review.ts
|
|
5000
4971
|
var REVIEW_LIMITS = {
|
|
@@ -5071,7 +5042,7 @@ var createCmd2 = defineCommand19({
|
|
|
5071
5042
|
},
|
|
5072
5043
|
async run({ args: args2 }) {
|
|
5073
5044
|
const skillsMode = parseSkillsMode(args2["skills-mode"]);
|
|
5074
|
-
const readTemplate = (path) => path ?
|
|
5045
|
+
const readTemplate = (path) => path ? readFileSync8(path, "utf8") : void 0;
|
|
5075
5046
|
const body = {
|
|
5076
5047
|
id: args2.id,
|
|
5077
5048
|
name: args2.name,
|
|
@@ -5146,7 +5117,7 @@ var editCmd2 = defineCommand19({
|
|
|
5146
5117
|
const { content } = await client.get(
|
|
5147
5118
|
`/api/profiles/${args2.id}/files/${file}`
|
|
5148
5119
|
);
|
|
5149
|
-
const tmpPath =
|
|
5120
|
+
const tmpPath = join5(tmpdir2(), `bazilion-${args2.id}-${file}-${randomBytes2(4).toString("hex")}`);
|
|
5150
5121
|
writeFileSync4(tmpPath, content);
|
|
5151
5122
|
try {
|
|
5152
5123
|
const editor = process.env.EDITOR ?? process.env.VISUAL ?? "vi";
|
|
@@ -5156,7 +5127,7 @@ var editCmd2 = defineCommand19({
|
|
|
5156
5127
|
child.on("close", (c) => resolve6(c ?? 0));
|
|
5157
5128
|
});
|
|
5158
5129
|
if (code !== 0) throw new Error(`editor exited with code ${code}`);
|
|
5159
|
-
const updated =
|
|
5130
|
+
const updated = readFileSync8(tmpPath, "utf8");
|
|
5160
5131
|
if (updated === content) {
|
|
5161
5132
|
console.log("(no changes)");
|
|
5162
5133
|
return;
|
|
@@ -5502,10 +5473,10 @@ var sendCommand = defineCommand22({
|
|
|
5502
5473
|
// src/commands/serve.ts
|
|
5503
5474
|
import { spawn as spawn3 } from "child_process";
|
|
5504
5475
|
import { existsSync as existsSync5 } from "fs";
|
|
5505
|
-
import { join as
|
|
5476
|
+
import { join as join6 } from "path";
|
|
5506
5477
|
import { defineCommand as defineCommand23 } from "citty";
|
|
5507
|
-
var bundledDaemonEntry2 =
|
|
5508
|
-
var sourceDaemonEntry2 =
|
|
5478
|
+
var bundledDaemonEntry2 = join6(import.meta.dirname, "daemon.js");
|
|
5479
|
+
var sourceDaemonEntry2 = join6(import.meta.dirname, "..", "..", "..", "daemon", "src", "index.ts");
|
|
5509
5480
|
var daemonEntry2 = existsSync5(bundledDaemonEntry2) ? bundledDaemonEntry2 : sourceDaemonEntry2;
|
|
5510
5481
|
var serveCommand = defineCommand23({
|
|
5511
5482
|
meta: {
|
|
@@ -5611,7 +5582,7 @@ var sessionCommand = defineCommand24({
|
|
|
5611
5582
|
});
|
|
5612
5583
|
|
|
5613
5584
|
// src/commands/skill.ts
|
|
5614
|
-
import { existsSync as existsSync6, readFileSync as
|
|
5585
|
+
import { existsSync as existsSync6, readFileSync as readFileSync9, statSync as statSync2 } from "fs";
|
|
5615
5586
|
import { basename as basename5, resolve as resolve4 } from "path";
|
|
5616
5587
|
import { defineCommand as defineCommand25 } from "citty";
|
|
5617
5588
|
function printFindings(findings, prefix = " ") {
|
|
@@ -5681,7 +5652,7 @@ var importCmd = defineCommand25({
|
|
|
5681
5652
|
let result;
|
|
5682
5653
|
try {
|
|
5683
5654
|
if (isLocalZip) {
|
|
5684
|
-
const bytes =
|
|
5655
|
+
const bytes = readFileSync9(absFrom);
|
|
5685
5656
|
const file = new File([bytes], basename5(absFrom), { type: "application/zip" });
|
|
5686
5657
|
const fd = new FormData();
|
|
5687
5658
|
fd.set("file", file);
|
|
@@ -5751,7 +5722,7 @@ var skillCommand = defineCommand25({
|
|
|
5751
5722
|
});
|
|
5752
5723
|
|
|
5753
5724
|
// src/commands/team.ts
|
|
5754
|
-
import { readFileSync as
|
|
5725
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
5755
5726
|
import { stdin as stdin2 } from "process";
|
|
5756
5727
|
import { defineCommand as defineCommand33 } from "citty";
|
|
5757
5728
|
|
|
@@ -5813,7 +5784,7 @@ var teamCodingLogCommand = defineCommand26({
|
|
|
5813
5784
|
});
|
|
5814
5785
|
|
|
5815
5786
|
// src/commands/team-environment.ts
|
|
5816
|
-
import { readFileSync as
|
|
5787
|
+
import { readFileSync as readFileSync10 } from "fs";
|
|
5817
5788
|
import { defineCommand as defineCommand27 } from "citty";
|
|
5818
5789
|
var args = { id: { type: "positional", required: true, description: "Team slug" } };
|
|
5819
5790
|
var teamEnvironmentCommand = defineCommand27({
|
|
@@ -5839,7 +5810,7 @@ var teamEnvironmentCommand = defineCommand27({
|
|
|
5839
5810
|
},
|
|
5840
5811
|
async run({ args: args2 }) {
|
|
5841
5812
|
const input = JSON.parse(
|
|
5842
|
-
|
|
5813
|
+
readFileSync10(args2.file, "utf8")
|
|
5843
5814
|
);
|
|
5844
5815
|
console.log(
|
|
5845
5816
|
JSON.stringify(await createClient2().codingEnvironment.configure(args2.id, input), null, 2)
|
|
@@ -5850,7 +5821,7 @@ var teamEnvironmentCommand = defineCommand27({
|
|
|
5850
5821
|
});
|
|
5851
5822
|
|
|
5852
5823
|
// src/commands/team-policy.ts
|
|
5853
|
-
import { readFileSync as
|
|
5824
|
+
import { readFileSync as readFileSync11 } from "fs";
|
|
5854
5825
|
import { defineCommand as defineCommand28 } from "citty";
|
|
5855
5826
|
|
|
5856
5827
|
// src/team-interchange.ts
|
|
@@ -6067,7 +6038,7 @@ function edgeDiff(before, after) {
|
|
|
6067
6038
|
// src/commands/team-policy.ts
|
|
6068
6039
|
function readJson(path) {
|
|
6069
6040
|
try {
|
|
6070
|
-
return JSON.parse(
|
|
6041
|
+
return JSON.parse(readFileSync11(path, "utf8"));
|
|
6071
6042
|
} catch (error) {
|
|
6072
6043
|
throw new Error(`invalid JSON: ${error.message}`);
|
|
6073
6044
|
}
|
|
@@ -7357,7 +7328,7 @@ var userMdSetCmd = defineCommand33({
|
|
|
7357
7328
|
async run({ args: args2 }) {
|
|
7358
7329
|
let content;
|
|
7359
7330
|
if (args2["from-stdin"]) content = await readStdin();
|
|
7360
|
-
else if (args2.file) content =
|
|
7331
|
+
else if (args2.file) content = readFileSync12(args2.file, "utf8");
|
|
7361
7332
|
else if (args2.text !== void 0) content = args2.text;
|
|
7362
7333
|
else {
|
|
7363
7334
|
console.error("team user-md set: provide --file, --from-stdin, or --text");
|
|
@@ -7503,11 +7474,11 @@ var teamCommand = defineCommand33({
|
|
|
7503
7474
|
});
|
|
7504
7475
|
|
|
7505
7476
|
// src/commands/team-template.ts
|
|
7506
|
-
import { readFileSync as
|
|
7477
|
+
import { readFileSync as readFileSync13 } from "fs";
|
|
7507
7478
|
import { defineCommand as defineCommand34 } from "citty";
|
|
7508
7479
|
function jsonFile(path) {
|
|
7509
7480
|
try {
|
|
7510
|
-
return JSON.parse(
|
|
7481
|
+
return JSON.parse(readFileSync13(path, "utf8"));
|
|
7511
7482
|
} catch (error) {
|
|
7512
7483
|
throw new Error(`invalid JSON: ${error.message}`);
|
|
7513
7484
|
}
|
|
@@ -8025,7 +7996,7 @@ function tokenRow(t) {
|
|
|
8025
7996
|
const expired = t.expiresAt !== null && t.expiresAt <= Date.now();
|
|
8026
7997
|
const state = t.revokedAt ? "revoked" : expired ? "expired" : "active";
|
|
8027
7998
|
const expires = t.expiresAt ? new Date(t.expiresAt).toISOString() : "(never)";
|
|
8028
|
-
return [t.id, t.kind, state, t.label, `expires: ${expires}`, `last: ${last}`];
|
|
7999
|
+
return [t.id, t.kind, state, t.label, t.scopes.join(" "), `expires: ${expires}`, `last: ${last}`];
|
|
8029
8000
|
}
|
|
8030
8001
|
function resolveQrServer(override) {
|
|
8031
8002
|
const raw = override ?? loadClientConfig().serverUrl;
|
|
@@ -8062,19 +8033,29 @@ var createCmd6 = defineCommand36({
|
|
|
8062
8033
|
expiresDays: {
|
|
8063
8034
|
type: "string",
|
|
8064
8035
|
description: "Device lifetime in days (default 90, maximum 365)"
|
|
8036
|
+
},
|
|
8037
|
+
scope: {
|
|
8038
|
+
type: "string",
|
|
8039
|
+
description: "Authorization scope; repeat for more (read, write, approvals, admin). Default: all scopes."
|
|
8065
8040
|
}
|
|
8066
8041
|
},
|
|
8067
|
-
async run({ args: args2 }) {
|
|
8042
|
+
async run({ args: args2, rawArgs }) {
|
|
8068
8043
|
const client = createClient2();
|
|
8069
8044
|
const expiresInDays = args2.expiresDays === void 0 ? void 0 : Number(args2.expiresDays);
|
|
8070
8045
|
if (expiresInDays !== void 0 && !Number.isInteger(expiresInDays)) {
|
|
8071
8046
|
throw new Error("--expires-days must be an integer");
|
|
8072
8047
|
}
|
|
8073
|
-
const
|
|
8048
|
+
const scopes = collectFlagValues(rawArgs, "scope");
|
|
8049
|
+
const body = {
|
|
8050
|
+
label: args2.label,
|
|
8051
|
+
expiresInDays,
|
|
8052
|
+
...scopes.length > 0 ? { scopes } : {}
|
|
8053
|
+
};
|
|
8074
8054
|
const res = await client.post("/api/tokens", body);
|
|
8075
|
-
console.log(`id:
|
|
8076
|
-
console.log(`label:
|
|
8077
|
-
console.log(`kind:
|
|
8055
|
+
console.log(`id: ${res.meta.id}`);
|
|
8056
|
+
console.log(`label: ${res.meta.label}`);
|
|
8057
|
+
console.log(`kind: ${res.meta.kind}`);
|
|
8058
|
+
console.log(`scopes: ${res.meta.scopes.join(" ")}`);
|
|
8078
8059
|
console.log(
|
|
8079
8060
|
`expires: ${res.meta.expiresAt ? new Date(res.meta.expiresAt).toISOString() : "(never)"}`
|
|
8080
8061
|
);
|
|
@@ -8090,6 +8071,43 @@ var createCmd6 = defineCommand36({
|
|
|
8090
8071
|
qrcode.generate(pairUrl, { small: true }, (qr) => console.log(qr));
|
|
8091
8072
|
}
|
|
8092
8073
|
});
|
|
8074
|
+
var pairCmd = defineCommand36({
|
|
8075
|
+
meta: {
|
|
8076
|
+
name: "pair",
|
|
8077
|
+
description: "Mint a one-paste pairing setup code for a new device (10 min, single use)"
|
|
8078
|
+
},
|
|
8079
|
+
args: {
|
|
8080
|
+
scope: {
|
|
8081
|
+
type: "string",
|
|
8082
|
+
description: "Authorization scope for the minted device credential; repeat for more. Default: all scopes."
|
|
8083
|
+
},
|
|
8084
|
+
server: {
|
|
8085
|
+
type: "string",
|
|
8086
|
+
description: "Server URL to embed in the setup code (default: detect LAN IP; pass the gateway HTTPS origin for remote devices)"
|
|
8087
|
+
}
|
|
8088
|
+
},
|
|
8089
|
+
async run({ args: args2, rawArgs }) {
|
|
8090
|
+
const client = createClient2();
|
|
8091
|
+
const scopes = collectFlagValues(rawArgs, "scope");
|
|
8092
|
+
const res = await client.post("/api/pair/codes", {
|
|
8093
|
+
...scopes.length > 0 ? { scopes } : {}
|
|
8094
|
+
});
|
|
8095
|
+
let setupUrl = res.setupUrl;
|
|
8096
|
+
if (args2.server) {
|
|
8097
|
+
const serverUrl = resolveQrServer(args2.server);
|
|
8098
|
+
setupUrl = `bazilion-pair://pair?server=${encodeURIComponent(serverUrl)}&code=${encodeURIComponent(res.code)}`;
|
|
8099
|
+
}
|
|
8100
|
+
console.log(`id: ${res.meta.id}`);
|
|
8101
|
+
console.log(`scopes: ${res.meta.scopes.join(" ")}`);
|
|
8102
|
+
console.log(`expires: ${new Date(res.meta.expiresAt).toISOString()} (10 minutes, single use)`);
|
|
8103
|
+
console.log("");
|
|
8104
|
+
console.log(`setup URL (paste or scan on the new device):`);
|
|
8105
|
+
console.log(setupUrl);
|
|
8106
|
+
console.log("");
|
|
8107
|
+
console.log("the code admits exactly one credential exchange; after that it is inert.");
|
|
8108
|
+
qrcode.generate(setupUrl, { small: true }, (qr) => console.log(qr));
|
|
8109
|
+
}
|
|
8110
|
+
});
|
|
8093
8111
|
var listCmd14 = defineCommand36({
|
|
8094
8112
|
meta: { name: "list", description: "List web tokens" },
|
|
8095
8113
|
args: {
|
|
@@ -8131,6 +8149,7 @@ var tokenCommand = defineCommand36({
|
|
|
8131
8149
|
meta: { name: "token", description: "Manage web tokens for API/CLI clients" },
|
|
8132
8150
|
subCommands: {
|
|
8133
8151
|
create: createCmd6,
|
|
8152
|
+
pair: pairCmd,
|
|
8134
8153
|
list: listCmd14,
|
|
8135
8154
|
revoke: revokeCmd2,
|
|
8136
8155
|
"show-local": showLocalCmd
|
|
@@ -8280,9 +8299,9 @@ var triggerCommand = defineCommand37({
|
|
|
8280
8299
|
});
|
|
8281
8300
|
|
|
8282
8301
|
// src/commands/uninstall.ts
|
|
8283
|
-
import { existsSync as existsSync7, lstatSync as lstatSync4, readdirSync as
|
|
8302
|
+
import { existsSync as existsSync7, lstatSync as lstatSync4, readdirSync as readdirSync3, realpathSync as realpathSync2, rmSync as rmSync4 } from "fs";
|
|
8284
8303
|
import { homedir as homedir2 } from "os";
|
|
8285
|
-
import { isAbsolute as isAbsolute2, join as
|
|
8304
|
+
import { isAbsolute as isAbsolute2, join as join7, parse as parse2, relative as relative2, resolve as resolve5, sep } from "path";
|
|
8286
8305
|
import { defineCommand as defineCommand38 } from "citty";
|
|
8287
8306
|
function makeLineReader() {
|
|
8288
8307
|
let buffer = "";
|
|
@@ -8389,15 +8408,15 @@ var uninstallCommand = defineCommand38({
|
|
|
8389
8408
|
async run({ args: args2 }) {
|
|
8390
8409
|
const paths = resolveCliPaths(args2.home);
|
|
8391
8410
|
const targetHome = assertSafeUninstallHome(paths.home);
|
|
8392
|
-
const dbFile =
|
|
8393
|
-
const profilesDir =
|
|
8394
|
-
const agentsDir =
|
|
8395
|
-
const teamsDir =
|
|
8396
|
-
const legacyGroupsDir =
|
|
8397
|
-
const skillsDir =
|
|
8398
|
-
const logsDir =
|
|
8399
|
-
const legacyConfigFile =
|
|
8400
|
-
const legacySecretsFile =
|
|
8411
|
+
const dbFile = join7(targetHome, "bazilion.db");
|
|
8412
|
+
const profilesDir = join7(targetHome, "profiles");
|
|
8413
|
+
const agentsDir = join7(targetHome, "agents");
|
|
8414
|
+
const teamsDir = join7(targetHome, "teams");
|
|
8415
|
+
const legacyGroupsDir = join7(targetHome, "groups");
|
|
8416
|
+
const skillsDir = join7(targetHome, "skills");
|
|
8417
|
+
const logsDir = join7(targetHome, "logs");
|
|
8418
|
+
const legacyConfigFile = join7(targetHome, "config.json");
|
|
8419
|
+
const legacySecretsFile = join7(targetHome, "secrets.enc");
|
|
8401
8420
|
if (!existsSync7(targetHome)) {
|
|
8402
8421
|
const uninstallLock2 = await acquireHomeRestoreLock(targetHome, "uninstalling");
|
|
8403
8422
|
try {
|
|
@@ -8416,7 +8435,7 @@ var uninstallCommand = defineCommand38({
|
|
|
8416
8435
|
`${dbFile}-wal`,
|
|
8417
8436
|
`${dbFile}-shm`,
|
|
8418
8437
|
`${dbFile}-journal`,
|
|
8419
|
-
|
|
8438
|
+
join7(targetHome, "auth.json"),
|
|
8420
8439
|
legacyConfigFile,
|
|
8421
8440
|
legacySecretsFile,
|
|
8422
8441
|
profilesDir,
|
|
@@ -8450,10 +8469,10 @@ var uninstallCommand = defineCommand38({
|
|
|
8450
8469
|
for (const p of fullWipeTargets) {
|
|
8451
8470
|
if (removePath(p)) console.log(`removed ${p}`);
|
|
8452
8471
|
}
|
|
8453
|
-
if (
|
|
8472
|
+
if (readdirSync3(targetHome).length === 0 && !homeIsSymlink) {
|
|
8454
8473
|
rmSync4(targetHome, { recursive: true, force: true });
|
|
8455
8474
|
console.log(`removed ${targetHome}`);
|
|
8456
|
-
} else if (homeIsSymlink &&
|
|
8475
|
+
} else if (homeIsSymlink && readdirSync3(targetHome).length === 0) {
|
|
8457
8476
|
console.log(`kept ${targetHome}: symlinked BAZILION_HOME root is now empty`);
|
|
8458
8477
|
} else {
|
|
8459
8478
|
console.log(`${targetHome} still has unmanaged files; left in place`);
|