bazilion 0.14.0 → 0.14.2
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 +18 -6
- package/dist/cli.js +288 -89
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +514 -76
- package/dist/daemon.js.map +1 -1
- package/dist/web/client/assets/{ConfirmDialog-CyL9A20V.js → ConfirmDialog-_bmG-wVG.js} +1 -1
- package/dist/web/client/assets/{FieldRow-D6REbYUa.js → FieldRow-Do1cBkRc.js} +1 -1
- package/dist/web/client/assets/{ProductionTeamPolicyEditor-DBKnOezm.js → ProductionTeamPolicyEditor-XP-QJul4.js} +1 -1
- package/dist/web/client/assets/{ProfileCommunicationEditor-4RK2laqO.js → ProfileCommunicationEditor-CwdFPdpk.js} +1 -1
- package/dist/web/client/assets/{TeamTabs-CdtNEqt4.js → TeamTabs-DIRiKcqx.js} +1 -1
- package/dist/web/client/assets/{TemplatesTabs-CZyss2Y0.js → TemplatesTabs-D4WHvs6b.js} +1 -1
- package/dist/web/client/assets/{UnsavedChangesGuard-CEoK-ZcN.js → UnsavedChangesGuard-B1aLqiK5.js} +1 -1
- package/dist/web/client/assets/{_id-DIqtdQij.js → _id-3w4PFfma.js} +1 -1
- package/dist/web/client/assets/{_id-4ZS-w_Aj.js → _id-BH3v_vI_.js} +1 -1
- package/dist/web/client/assets/{_id-DbcC2E7F.js → _id-Cx7o4Zmf.js} +1 -1
- package/dist/web/client/assets/{_id-f_r5M0p3.js → _id-DIiVVxBl.js} +1 -1
- package/dist/web/client/assets/{activity-CB9Ufth-.js → activity-A_HrG1Tv.js} +1 -1
- package/dist/web/client/assets/{agents-D-JGXVg9.js → agents-BeeFCt2c.js} +1 -1
- package/dist/web/client/assets/{agents-DS2XafoA.js → agents-C8OVKq3N.js} +1 -1
- package/dist/web/client/assets/{approvals-Cke_mrJv.js → approvals-BIdZ9BSn.js} +1 -1
- package/dist/web/client/assets/{attention-PYwRM2wC.js → attention-B9bUrxiU.js} +1 -1
- package/dist/web/client/assets/chevron-right-VWrk_dTX.js +1 -0
- package/dist/web/client/assets/{config-DF9Gqmfa.js → config-By86S7k-.js} +2 -2
- package/dist/web/client/assets/{inbox-DC_HdOfI.js → inbox-DlXQCJLe.js} +1 -1
- package/dist/web/client/assets/{index-Cp6UHWr2.js → index-CLdmsmiN.js} +2 -2
- package/dist/web/client/assets/{learning-BfrQ4YZY.js → learning-BqZIw2nA.js} +1 -1
- package/dist/web/client/assets/{login-D4n3AcBR.js → login-CCMPXiny.js} +1 -1
- package/dist/web/client/assets/{mcp-CnjQc_JJ.js → mcp-DKSY2yVa.js} +1 -1
- package/dist/web/client/assets/{members-wxsVTJdW.js → members-9GuOiq6J.js} +1 -1
- package/dist/web/client/assets/{memory-Du60O3pE.js → memory-DiGMI6FC.js} +1 -1
- package/dist/web/client/assets/{policy-BOfnkJsL.js → policy-TBGQffw5.js} +1 -1
- package/dist/web/client/assets/{routes-B9CuhzUW.js → routes-g3yUOhCb.js} +1 -1
- package/dist/web/client/assets/{services-DyvqJqM2.js → services-1Z398CES.js} +1 -1
- package/dist/web/client/assets/{skills-DQo7ioW7.js → skills-BP2gciFt.js} +1 -1
- package/dist/web/client/assets/{teams-DPggy97H.js → teams-DBIivGT7.js} +1 -1
- package/dist/web/client/assets/{teams-DdawcfNR.js → teams-tNoMDJ_M.js} +1 -1
- package/dist/web/client/assets/{telegram-DcTeDpP5.js → telegram-CJG_DFdI.js} +1 -1
- package/dist/web/client/assets/{tokens-CIEKwZXc.js → tokens-eDWCGQQ2.js} +1 -1
- package/dist/web/client/assets/{triggers-Bc2RrUPm.js → triggers-DZME3IcK.js} +1 -1
- package/dist/web/client/assets/{welcome-DlhNXUIa.js → welcome-B49sh_uf.js} +1 -1
- package/dist/web/client/assets/{wire-constants-BzdHSc6A.js → wire-constants-zZ7Wjb9C.js} +1 -1
- package/dist/web/client/assets/{x-DAXGIe_Q.js → x-CHc7_-TH.js} +1 -1
- package/dist/web/server/assets/{_tanstack-start-manifest_v-C-OiOZeM.js → _tanstack-start-manifest_v-Duhf0z7H.js} +76 -76
- package/dist/web/server/assets/{config-ExacOzHX.js → config-BmLq53tq.js} +33 -11
- package/dist/web/server/assets/{config-BlMkHStx.js → config-Wy6hnZ-Z.js} +1 -1
- package/dist/web/server/assets/{router-pjH2t8Rl.js → router-CY_pCgP1.js} +4 -3
- package/dist/web/server/assets/{welcome-B8nchXdF.js → welcome-BdQGR68o.js} +1 -1
- package/dist/web/server/server.js +2 -2
- package/dist/worker.js +64 -19
- package/dist/worker.js.map +1 -1
- package/package.json +6 -6
- package/dist/web/client/assets/chevron-right-BG4OeFRQ.js +0 -1
package/dist/daemon.js
CHANGED
|
@@ -19122,6 +19122,7 @@ var init_client2 = __esm({
|
|
|
19122
19122
|
});
|
|
19123
19123
|
|
|
19124
19124
|
// ../daemon/src/index.ts
|
|
19125
|
+
import { writeSync as writeSync2 } from "fs";
|
|
19125
19126
|
import { serve } from "@hono/node-server";
|
|
19126
19127
|
|
|
19127
19128
|
// ../daemon/src/app.ts
|
|
@@ -20964,6 +20965,19 @@ function openDb(path) {
|
|
|
20964
20965
|
}
|
|
20965
20966
|
};
|
|
20966
20967
|
}
|
|
20968
|
+
function openInMemoryDb() {
|
|
20969
|
+
const raw2 = new DatabaseSync(":memory:");
|
|
20970
|
+
applyPragmas(raw2, false);
|
|
20971
|
+
return {
|
|
20972
|
+
raw: wrap(raw2),
|
|
20973
|
+
backupTo(path) {
|
|
20974
|
+
return backup(raw2, path);
|
|
20975
|
+
},
|
|
20976
|
+
close() {
|
|
20977
|
+
raw2.close();
|
|
20978
|
+
}
|
|
20979
|
+
};
|
|
20980
|
+
}
|
|
20967
20981
|
function inTx(db, fn) {
|
|
20968
20982
|
return db.raw.transaction(fn)();
|
|
20969
20983
|
}
|
|
@@ -20973,30 +20987,101 @@ import { readdirSync as readdirSync2, readFileSync as readFileSync5 } from "fs";
|
|
|
20973
20987
|
import { dirname, join as join8 } from "path";
|
|
20974
20988
|
import { fileURLToPath } from "url";
|
|
20975
20989
|
var migrationsDir = join8(dirname(fileURLToPath(import.meta.url)), "migrations");
|
|
20990
|
+
var schemaMigrationsSql = `
|
|
20991
|
+
CREATE TABLE IF NOT EXISTS schema_migrations (
|
|
20992
|
+
version TEXT PRIMARY KEY,
|
|
20993
|
+
applied_at INTEGER NOT NULL
|
|
20994
|
+
)
|
|
20995
|
+
`;
|
|
20996
|
+
var INCOMPATIBLE_DATABASE_MESSAGE = "Bazilion cannot start because this home uses an incompatible alpha database schema. Preserve the entire Bazilion home directory as a filesystem backup first, keeping bazilion.db and auth.json together. Then perform the reset with `bazilion uninstall --yes` (from the repository root of a source checkout: `pnpm tsx apps/cli/src/index.ts uninstall --yes`) and start Bazilion again. Use `--all` only if you also want to remove logs and installed skills.";
|
|
20997
|
+
var IncompatibleDatabaseError = class extends Error {
|
|
20998
|
+
constructor() {
|
|
20999
|
+
super(INCOMPATIBLE_DATABASE_MESSAGE);
|
|
21000
|
+
this.name = "IncompatibleDatabaseError";
|
|
21001
|
+
}
|
|
21002
|
+
};
|
|
21003
|
+
var canonicalSchemaObjects = null;
|
|
21004
|
+
function migrationFiles() {
|
|
21005
|
+
return readdirSync2(migrationsDir).filter((file) => file.endsWith(".sql")).sort().map((file) => ({
|
|
21006
|
+
version: file.replace(/\.sql$/, ""),
|
|
21007
|
+
sql: readFileSync5(join8(migrationsDir, file), "utf8")
|
|
21008
|
+
}));
|
|
21009
|
+
}
|
|
21010
|
+
function normalizeSql(sql) {
|
|
21011
|
+
return sql.replace(/\s+/g, " ").trim();
|
|
21012
|
+
}
|
|
21013
|
+
function schemaObjects(db) {
|
|
21014
|
+
return db.raw.query(
|
|
21015
|
+
`SELECT type, name, tbl_name, sql
|
|
21016
|
+
FROM sqlite_schema
|
|
21017
|
+
WHERE sql IS NOT NULL AND substr(name, 1, 7) <> 'sqlite_'
|
|
21018
|
+
ORDER BY type, name`
|
|
21019
|
+
).all();
|
|
21020
|
+
}
|
|
21021
|
+
function schemaPayload(rows) {
|
|
21022
|
+
return rows.map((row) => [row.type, row.name, row.tbl_name, normalizeSql(row.sql)].join("\0")).join("\n");
|
|
21023
|
+
}
|
|
21024
|
+
function expectedSchema(files) {
|
|
21025
|
+
if (canonicalSchemaObjects !== null) return canonicalSchemaObjects;
|
|
21026
|
+
const canonical = openInMemoryDb();
|
|
21027
|
+
try {
|
|
21028
|
+
canonical.raw.exec(schemaMigrationsSql);
|
|
21029
|
+
for (const file of files) canonical.raw.exec(file.sql);
|
|
21030
|
+
canonicalSchemaObjects = schemaObjects(canonical);
|
|
21031
|
+
return canonicalSchemaObjects;
|
|
21032
|
+
} finally {
|
|
21033
|
+
canonical.close();
|
|
21034
|
+
}
|
|
21035
|
+
}
|
|
21036
|
+
function assertMigrationCompatibility(db) {
|
|
21037
|
+
const files = migrationFiles();
|
|
21038
|
+
const expectedVersions = files.map((file) => file.version);
|
|
21039
|
+
let appliedVersions;
|
|
21040
|
+
try {
|
|
21041
|
+
appliedVersions = db.raw.query("SELECT version FROM schema_migrations ORDER BY version").all().map((row) => row.version);
|
|
21042
|
+
} catch {
|
|
21043
|
+
throw new IncompatibleDatabaseError();
|
|
21044
|
+
}
|
|
21045
|
+
const actualObjects = schemaObjects(db);
|
|
21046
|
+
const expectedObjects = expectedSchema(files);
|
|
21047
|
+
if (appliedVersions.length === 0) {
|
|
21048
|
+
const migrationTable = actualObjects.filter(
|
|
21049
|
+
(row) => row.type === "table" && row.name === "schema_migrations"
|
|
21050
|
+
);
|
|
21051
|
+
const expectedMigrationTable = expectedObjects.filter(
|
|
21052
|
+
(row) => row.type === "table" && row.name === "schema_migrations"
|
|
21053
|
+
);
|
|
21054
|
+
if (actualObjects.length !== 1 || migrationTable.length !== 1 || schemaPayload(migrationTable) !== schemaPayload(expectedMigrationTable)) {
|
|
21055
|
+
throw new IncompatibleDatabaseError();
|
|
21056
|
+
}
|
|
21057
|
+
return;
|
|
21058
|
+
}
|
|
21059
|
+
if (appliedVersions.length !== expectedVersions.length || appliedVersions.some((version2, index) => version2 !== expectedVersions[index]) || schemaPayload(actualObjects) !== schemaPayload(expectedObjects)) {
|
|
21060
|
+
throw new IncompatibleDatabaseError();
|
|
21061
|
+
}
|
|
21062
|
+
}
|
|
20976
21063
|
function runMigrations(db) {
|
|
20977
|
-
db
|
|
20978
|
-
|
|
20979
|
-
|
|
20980
|
-
|
|
20981
|
-
|
|
20982
|
-
|
|
21064
|
+
const existingObjects = schemaObjects(db);
|
|
21065
|
+
if (existingObjects.length > 0 && !existingObjects.some((row) => row.type === "table" && row.name === "schema_migrations")) {
|
|
21066
|
+
throw new IncompatibleDatabaseError();
|
|
21067
|
+
}
|
|
21068
|
+
db.raw.exec(schemaMigrationsSql);
|
|
21069
|
+
assertMigrationCompatibility(db);
|
|
20983
21070
|
const applied = new Set(
|
|
20984
21071
|
db.raw.query("SELECT version FROM schema_migrations").all().map((r) => r.version)
|
|
20985
21072
|
);
|
|
20986
|
-
const
|
|
20987
|
-
|
|
20988
|
-
const version2 = file.replace(/\.sql$/, "");
|
|
20989
|
-
if (applied.has(version2)) continue;
|
|
20990
|
-
const sql = readFileSync5(join8(migrationsDir, file), "utf8");
|
|
21073
|
+
for (const file of migrationFiles()) {
|
|
21074
|
+
if (applied.has(file.version)) continue;
|
|
20991
21075
|
const tx = db.raw.transaction(() => {
|
|
20992
|
-
db.raw.exec(sql);
|
|
21076
|
+
db.raw.exec(file.sql);
|
|
20993
21077
|
db.raw.run("INSERT INTO schema_migrations (version, applied_at) VALUES (?, ?)", [
|
|
20994
|
-
|
|
21078
|
+
file.version,
|
|
20995
21079
|
Date.now()
|
|
20996
21080
|
]);
|
|
20997
21081
|
});
|
|
20998
21082
|
tx();
|
|
20999
21083
|
}
|
|
21084
|
+
assertMigrationCompatibility(db);
|
|
21000
21085
|
}
|
|
21001
21086
|
|
|
21002
21087
|
// ../daemon/src/core/paths.ts
|
|
@@ -25150,20 +25235,61 @@ import {
|
|
|
25150
25235
|
} from "fs";
|
|
25151
25236
|
import { dirname as dirname3, isAbsolute, join as join13, relative, resolve as resolve3, sep as sep2 } from "path";
|
|
25152
25237
|
import { createStore, extractSnippet } from "@tobilu/qmd";
|
|
25238
|
+
|
|
25239
|
+
// ../daemon/src/lib/native-module-error.ts
|
|
25240
|
+
var NODE_MODULE_ABI_MISMATCH = /was compiled against a different Node\.js version using\s+NODE_MODULE_VERSION\s+(\d+)[\s\S]*?requires\s+NODE_MODULE_VERSION\s+(\d+)/i;
|
|
25241
|
+
function formatNativeModuleAbiMismatch(diagnostic, options = {}) {
|
|
25242
|
+
const mismatch = NODE_MODULE_ABI_MISMATCH.exec(diagnostic);
|
|
25243
|
+
if (!mismatch) return void 0;
|
|
25244
|
+
const builtAbi = mismatch[1];
|
|
25245
|
+
const requiredAbi = mismatch[2];
|
|
25246
|
+
const rebuildCommand = /better_sqlite3\.node|better-sqlite3/i.test(diagnostic) ? "`pnpm rebuild better-sqlite3`" : "`pnpm rebuild`";
|
|
25247
|
+
const subject = options.subject ?? "Bazilion";
|
|
25248
|
+
return `${subject} could not load a native dependency built for Node module ABI ${builtAbi}; the current ${process.version} runtime requires ABI ${requiredAbi}. Reinstall Bazilion with this same Node.js version, then restart it. From the repository root of a source checkout, run ${rebuildCommand} (or \`pnpm install --force\`).`;
|
|
25249
|
+
}
|
|
25250
|
+
var NativeModuleAbiMismatchError = class extends Error {
|
|
25251
|
+
code = "native_module_abi_mismatch";
|
|
25252
|
+
constructor(message) {
|
|
25253
|
+
super(message);
|
|
25254
|
+
this.name = "NativeModuleAbiMismatchError";
|
|
25255
|
+
}
|
|
25256
|
+
};
|
|
25257
|
+
function sanitizeNativeModuleError(error2, options = {}) {
|
|
25258
|
+
const diagnostic = error2 instanceof Error ? error2.message : String(error2);
|
|
25259
|
+
const formatted = formatNativeModuleAbiMismatch(diagnostic, options);
|
|
25260
|
+
if (!formatted) return error2;
|
|
25261
|
+
return new NativeModuleAbiMismatchError(formatted);
|
|
25262
|
+
}
|
|
25263
|
+
async function withNativeModuleErrorBoundary(operation, options = {}) {
|
|
25264
|
+
try {
|
|
25265
|
+
return await operation();
|
|
25266
|
+
} catch (error2) {
|
|
25267
|
+
throw sanitizeNativeModuleError(error2, options);
|
|
25268
|
+
}
|
|
25269
|
+
}
|
|
25270
|
+
|
|
25271
|
+
// ../daemon/src/runtime/memory/qmd.ts
|
|
25153
25272
|
var INDEX_FILENAME = ".qmd-index.sqlite";
|
|
25154
25273
|
var COLLECTION_NAME = "memory";
|
|
25155
25274
|
var PATTERN = "**/*.md";
|
|
25275
|
+
var QMD_NATIVE_ERROR_OPTIONS = { subject: "Bazilion memory" };
|
|
25156
25276
|
var storeCache = /* @__PURE__ */ new Map();
|
|
25157
|
-
function getStore(dir) {
|
|
25277
|
+
function getStore(dir, storeFactory) {
|
|
25158
25278
|
let p = storeCache.get(dir);
|
|
25159
25279
|
if (!p) {
|
|
25160
|
-
p =
|
|
25161
|
-
|
|
25162
|
-
|
|
25163
|
-
|
|
25164
|
-
|
|
25280
|
+
p = withNativeModuleErrorBoundary(
|
|
25281
|
+
() => storeFactory({
|
|
25282
|
+
dbPath: join13(dir, INDEX_FILENAME),
|
|
25283
|
+
config: {
|
|
25284
|
+
collections: {
|
|
25285
|
+
[COLLECTION_NAME]: { path: dir, pattern: PATTERN }
|
|
25286
|
+
}
|
|
25165
25287
|
}
|
|
25166
|
-
}
|
|
25288
|
+
}),
|
|
25289
|
+
QMD_NATIVE_ERROR_OPTIONS
|
|
25290
|
+
).catch((error2) => {
|
|
25291
|
+
storeCache.delete(dir);
|
|
25292
|
+
throw error2;
|
|
25167
25293
|
});
|
|
25168
25294
|
storeCache.set(dir, p);
|
|
25169
25295
|
}
|
|
@@ -25346,8 +25472,9 @@ function walkMd(root, dir, prefix, out) {
|
|
|
25346
25472
|
}
|
|
25347
25473
|
}
|
|
25348
25474
|
}
|
|
25349
|
-
function qmdBackend(root) {
|
|
25475
|
+
function qmdBackend(root, options = {}) {
|
|
25350
25476
|
let canonicalRoot;
|
|
25477
|
+
const storeFactory = options.createStore ?? createStore;
|
|
25351
25478
|
const safeRoot = () => {
|
|
25352
25479
|
if (!canonicalRoot) canonicalRoot = initializeSafeRoot(root);
|
|
25353
25480
|
else assertRootUnchanged(root, canonicalRoot);
|
|
@@ -25357,8 +25484,8 @@ function qmdBackend(root) {
|
|
|
25357
25484
|
async init() {
|
|
25358
25485
|
const safe = safeRoot();
|
|
25359
25486
|
assertSafeTree(safe);
|
|
25360
|
-
const store = await getStore(safe);
|
|
25361
|
-
await store.update();
|
|
25487
|
+
const store = await getStore(safe, storeFactory);
|
|
25488
|
+
await withNativeModuleErrorBoundary(() => store.update(), QMD_NATIVE_ERROR_OPTIONS);
|
|
25362
25489
|
},
|
|
25363
25490
|
async read(key2) {
|
|
25364
25491
|
const safe = safeRoot();
|
|
@@ -25376,19 +25503,22 @@ function qmdBackend(root) {
|
|
|
25376
25503
|
const path = safeKey(safe, key2);
|
|
25377
25504
|
const stats = writeSafeFile(safe, path, content);
|
|
25378
25505
|
assertSafeTree(safe);
|
|
25379
|
-
const store = await getStore(safe);
|
|
25380
|
-
await store.update();
|
|
25506
|
+
const store = await getStore(safe, storeFactory);
|
|
25507
|
+
await withNativeModuleErrorBoundary(() => store.update(), QMD_NATIVE_ERROR_OPTIONS);
|
|
25381
25508
|
return { key: key2, content, updatedAt: stats.mtimeMs };
|
|
25382
25509
|
},
|
|
25383
25510
|
async search(query, opts) {
|
|
25384
25511
|
const limit = opts?.limit ?? 10;
|
|
25385
25512
|
const safe = safeRoot();
|
|
25386
25513
|
assertSafeTree(safe);
|
|
25387
|
-
const store = await getStore(safe);
|
|
25388
|
-
const results = await
|
|
25389
|
-
|
|
25390
|
-
|
|
25391
|
-
|
|
25514
|
+
const store = await getStore(safe, storeFactory);
|
|
25515
|
+
const results = await withNativeModuleErrorBoundary(
|
|
25516
|
+
() => store.searchLex(query, {
|
|
25517
|
+
limit,
|
|
25518
|
+
collection: COLLECTION_NAME
|
|
25519
|
+
}),
|
|
25520
|
+
QMD_NATIVE_ERROR_OPTIONS
|
|
25521
|
+
);
|
|
25392
25522
|
const hits = [];
|
|
25393
25523
|
for (const r of results) {
|
|
25394
25524
|
const prefix = `${COLLECTION_NAME}/`;
|
|
@@ -25423,8 +25553,8 @@ function qmdBackend(root) {
|
|
|
25423
25553
|
rmSync10(path);
|
|
25424
25554
|
}
|
|
25425
25555
|
assertSafeTree(safe);
|
|
25426
|
-
const store = await getStore(safe);
|
|
25427
|
-
await store.update();
|
|
25556
|
+
const store = await getStore(safe, storeFactory);
|
|
25557
|
+
await withNativeModuleErrorBoundary(() => store.update(), QMD_NATIVE_ERROR_OPTIONS);
|
|
25428
25558
|
}
|
|
25429
25559
|
};
|
|
25430
25560
|
}
|
|
@@ -30821,7 +30951,7 @@ async function* spawnWorker(spec, opts) {
|
|
|
30821
30951
|
if (!emittedFatal && exit.code !== 0 && exit.code !== null) {
|
|
30822
30952
|
yield {
|
|
30823
30953
|
kind: "fatal",
|
|
30824
|
-
error:
|
|
30954
|
+
error: formatWorkerExitFailure(
|
|
30825
30955
|
`worker exited with code ${exit.code}${exit.signal ? ` (${exit.signal})` : ""}`,
|
|
30826
30956
|
diagnostic
|
|
30827
30957
|
)
|
|
@@ -30829,7 +30959,7 @@ async function* spawnWorker(spec, opts) {
|
|
|
30829
30959
|
} else if (!emittedFatal && exit.signal && exit.code === null) {
|
|
30830
30960
|
yield {
|
|
30831
30961
|
kind: "fatal",
|
|
30832
|
-
error:
|
|
30962
|
+
error: formatWorkerExitFailure(`worker killed by ${exit.signal}`, diagnostic)
|
|
30833
30963
|
};
|
|
30834
30964
|
}
|
|
30835
30965
|
} finally {
|
|
@@ -30924,7 +31054,9 @@ function spawnHosts(spec, opts, signal, onBashApproval, onApiKeyRefreshed) {
|
|
|
30924
31054
|
}
|
|
30925
31055
|
function parseFrame(line, accessTokens) {
|
|
30926
31056
|
try {
|
|
30927
|
-
return
|
|
31057
|
+
return normalizeWorkerDiagnosticFrame(
|
|
31058
|
+
redactJsonValue(JSON.parse(line), accessTokens)
|
|
31059
|
+
);
|
|
30928
31060
|
} catch {
|
|
30929
31061
|
return {
|
|
30930
31062
|
kind: "fatal",
|
|
@@ -31136,6 +31268,26 @@ async function pumpWorkerStderr(stderr, capture, redactor) {
|
|
|
31136
31268
|
function appendDiagnostic(message, diagnostic) {
|
|
31137
31269
|
return diagnostic ? `${message}: ${diagnostic}` : message;
|
|
31138
31270
|
}
|
|
31271
|
+
function formatWorkerExitFailure(message, diagnostic) {
|
|
31272
|
+
const formatted = formatWorkerDiagnostic(diagnostic);
|
|
31273
|
+
if (formatted !== diagnostic) return formatted;
|
|
31274
|
+
return appendDiagnostic(message, diagnostic);
|
|
31275
|
+
}
|
|
31276
|
+
function normalizeWorkerDiagnosticFrame(frame) {
|
|
31277
|
+
if (frame.kind === "fatal") {
|
|
31278
|
+
return { ...frame, error: formatWorkerDiagnostic(frame.error) };
|
|
31279
|
+
}
|
|
31280
|
+
if (frame.kind === "event" && frame.event.type === "error") {
|
|
31281
|
+
return {
|
|
31282
|
+
...frame,
|
|
31283
|
+
event: { ...frame.event, error: formatWorkerDiagnostic(frame.event.error) }
|
|
31284
|
+
};
|
|
31285
|
+
}
|
|
31286
|
+
return frame;
|
|
31287
|
+
}
|
|
31288
|
+
function formatWorkerDiagnostic(diagnostic) {
|
|
31289
|
+
return formatNativeModuleAbiMismatch(diagnostic, { subject: "worker" }) ?? diagnostic;
|
|
31290
|
+
}
|
|
31139
31291
|
|
|
31140
31292
|
// ../daemon/src/lib/api-key.ts
|
|
31141
31293
|
async function resolveAgentApiKey(db, authToken, agent, opts = {}) {
|
|
@@ -35970,8 +36122,20 @@ var _db = null;
|
|
|
35970
36122
|
var _paths = null;
|
|
35971
36123
|
var _authToken = null;
|
|
35972
36124
|
var _schedulerStarted = false;
|
|
36125
|
+
var INCOMPATIBLE_BOOTSTRAP_IDENTITY_MESSAGE = "Bazilion cannot start because auth.json does not match an active bootstrap credential in bazilion.db. Preserve the entire Bazilion home directory as a filesystem backup first, keeping bazilion.db and auth.json together. Then perform the reset with `bazilion uninstall --yes` (from the repository root of a source checkout: `pnpm tsx apps/cli/src/index.ts uninstall --yes`) and start Bazilion again. Use `--all` only if you also want to remove logs and installed skills.";
|
|
36126
|
+
var IncompatibleBootstrapIdentityError = class extends Error {
|
|
36127
|
+
constructor() {
|
|
36128
|
+
super(INCOMPATIBLE_BOOTSTRAP_IDENTITY_MESSAGE);
|
|
36129
|
+
this.name = "IncompatibleBootstrapIdentityError";
|
|
36130
|
+
}
|
|
36131
|
+
};
|
|
35973
36132
|
function bootstrap(paths) {
|
|
35974
36133
|
mkdirSync9(paths.home, { recursive: true });
|
|
36134
|
+
const databaseExists = existsSync17(paths.db);
|
|
36135
|
+
const authFileExists = existsSync17(paths.authFile);
|
|
36136
|
+
if (databaseExists !== authFileExists) {
|
|
36137
|
+
throw new IncompatibleBootstrapIdentityError();
|
|
36138
|
+
}
|
|
35975
36139
|
for (const d2 of [
|
|
35976
36140
|
paths.profilesDir,
|
|
35977
36141
|
paths.agentsDir,
|
|
@@ -35982,26 +36146,46 @@ function bootstrap(paths) {
|
|
|
35982
36146
|
mkdirSync9(d2, { recursive: true });
|
|
35983
36147
|
}
|
|
35984
36148
|
const db = openDb(paths.db);
|
|
35985
|
-
|
|
35986
|
-
|
|
35987
|
-
|
|
35988
|
-
|
|
35989
|
-
|
|
35990
|
-
|
|
35991
|
-
|
|
35992
|
-
|
|
36149
|
+
try {
|
|
36150
|
+
runMigrations(db);
|
|
36151
|
+
let existingAuthToken = null;
|
|
36152
|
+
if (authFileExists) {
|
|
36153
|
+
try {
|
|
36154
|
+
existingAuthToken = readAuthFile(paths.authFile).token;
|
|
36155
|
+
} catch {
|
|
36156
|
+
throw new IncompatibleBootstrapIdentityError();
|
|
36157
|
+
}
|
|
36158
|
+
const bootstrap2 = webTokens_exports.findActiveByToken(db, existingAuthToken);
|
|
36159
|
+
if (bootstrap2?.kind !== "bootstrap") {
|
|
36160
|
+
throw new IncompatibleBootstrapIdentityError();
|
|
36161
|
+
}
|
|
36162
|
+
}
|
|
36163
|
+
const refreshed = refreshDefaultProfileTemplates(paths);
|
|
36164
|
+
if (refreshed.length) {
|
|
36165
|
+
console.log(`bazilion: refreshed default profile templates \u2014 [${refreshed.join(", ")}]`);
|
|
36166
|
+
}
|
|
36167
|
+
if (existingAuthToken === null) {
|
|
36168
|
+
const created = webTokens_exports.create(db, "bootstrap", { kind: "bootstrap" });
|
|
36169
|
+
writeFileSync12(paths.authFile, `${JSON.stringify({ token: created.token }, null, 2)}
|
|
35993
36170
|
`, {
|
|
35994
|
-
|
|
35995
|
-
|
|
36171
|
+
mode: 384
|
|
36172
|
+
});
|
|
36173
|
+
try {
|
|
36174
|
+
chmodSync(paths.authFile, 384);
|
|
36175
|
+
} catch {
|
|
36176
|
+
}
|
|
36177
|
+
console.log(`bazilion auto-bootstrapped at ${paths.home}`);
|
|
36178
|
+
console.log(`bootstrap token written to ${paths.authFile}`);
|
|
36179
|
+
return { db, authToken: created.token };
|
|
36180
|
+
}
|
|
36181
|
+
return { db, authToken: existingAuthToken };
|
|
36182
|
+
} catch (error2) {
|
|
35996
36183
|
try {
|
|
35997
|
-
|
|
36184
|
+
db.close();
|
|
35998
36185
|
} catch {
|
|
35999
36186
|
}
|
|
36000
|
-
|
|
36001
|
-
console.log(`bootstrap token written to ${paths.authFile}`);
|
|
36002
|
-
return { db, authToken: created.token };
|
|
36187
|
+
throw error2;
|
|
36003
36188
|
}
|
|
36004
|
-
return { db, authToken: readAuthFile(paths.authFile).token };
|
|
36005
36189
|
}
|
|
36006
36190
|
function getCtx() {
|
|
36007
36191
|
if (!_paths) _paths = resolvePaths();
|
|
@@ -39947,9 +40131,227 @@ function mutate(c, acknowledged) {
|
|
|
39947
40131
|
}
|
|
39948
40132
|
|
|
39949
40133
|
// ../daemon/src/routes/auth-login.ts
|
|
39950
|
-
import { spawn as spawn4 } from "child_process";
|
|
39951
40134
|
import { Hono as Hono4 } from "hono";
|
|
39952
40135
|
import { deleteCookie, setCookie } from "hono/cookie";
|
|
40136
|
+
|
|
40137
|
+
// ../daemon/src/lib/openai-oauth-prompt.ts
|
|
40138
|
+
import { spawn as spawn4 } from "child_process";
|
|
40139
|
+
import { createServer as createServer2 } from "net";
|
|
40140
|
+
var OPENAI_CODEX_CALLBACK_PORT = 1455;
|
|
40141
|
+
var WEB_OPENAI_LOGIN_TIMEOUT_MS = 10 * 6e4;
|
|
40142
|
+
var DEVICE_CODE_FALLBACK = "`bazilion auth openai login --device-code` (or, from the repository root of a source checkout, `pnpm tsx apps/cli/src/index.ts auth openai login --device-code`)";
|
|
40143
|
+
var OpenAICodexCallbackUnavailableError = class extends Error {
|
|
40144
|
+
constructor(message) {
|
|
40145
|
+
super(message);
|
|
40146
|
+
this.name = "OpenAICodexCallbackUnavailableError";
|
|
40147
|
+
}
|
|
40148
|
+
};
|
|
40149
|
+
function abortReason(signal) {
|
|
40150
|
+
return signal.reason instanceof Error ? signal.reason : new DOMException("OpenAI browser login cancelled", "AbortError");
|
|
40151
|
+
}
|
|
40152
|
+
function callbackAddress(host2, port2) {
|
|
40153
|
+
return host2.includes(":") ? `[${host2}]:${port2}` : `${host2}:${port2}`;
|
|
40154
|
+
}
|
|
40155
|
+
function openAICodexCallbackHost(env = process.env) {
|
|
40156
|
+
return env.PI_OAUTH_CALLBACK_HOST?.trim() || "127.0.0.1";
|
|
40157
|
+
}
|
|
40158
|
+
function callbackUnavailable(error2, host2, port2) {
|
|
40159
|
+
const code = error2 instanceof Error && "code" in error2 && typeof error2.code === "string" ? error2.code : null;
|
|
40160
|
+
const address = callbackAddress(host2, port2);
|
|
40161
|
+
if (code === "EADDRINUSE") {
|
|
40162
|
+
return new OpenAICodexCallbackUnavailableError(
|
|
40163
|
+
`OpenAI browser login cannot start because callback address ${address} is already in use. Stop the process using that port and try again, or run ${DEVICE_CODE_FALLBACK} in a terminal.`
|
|
40164
|
+
);
|
|
40165
|
+
}
|
|
40166
|
+
return new OpenAICodexCallbackUnavailableError(
|
|
40167
|
+
`OpenAI browser login cannot bind callback address ${address}${code ? ` (${code})` : ""}. Check PI_OAUTH_CALLBACK_HOST and try again, or run ${DEVICE_CODE_FALLBACK} in a terminal.`
|
|
40168
|
+
);
|
|
40169
|
+
}
|
|
40170
|
+
function closeServer(server3) {
|
|
40171
|
+
if (!server3.listening) return Promise.resolve();
|
|
40172
|
+
return new Promise((resolve8) => server3.close(() => resolve8()));
|
|
40173
|
+
}
|
|
40174
|
+
async function preflightOpenAICodexCallback(options) {
|
|
40175
|
+
const host2 = options?.host ?? openAICodexCallbackHost();
|
|
40176
|
+
const port2 = options?.port ?? OPENAI_CODEX_CALLBACK_PORT;
|
|
40177
|
+
const server3 = createServer2();
|
|
40178
|
+
try {
|
|
40179
|
+
await new Promise((resolve8, reject2) => {
|
|
40180
|
+
const cleanup = () => {
|
|
40181
|
+
server3.removeListener("error", onError);
|
|
40182
|
+
server3.removeListener("listening", onListening);
|
|
40183
|
+
};
|
|
40184
|
+
const onError = (error2) => {
|
|
40185
|
+
cleanup();
|
|
40186
|
+
reject2(callbackUnavailable(error2, host2, port2));
|
|
40187
|
+
};
|
|
40188
|
+
const onListening = () => {
|
|
40189
|
+
cleanup();
|
|
40190
|
+
resolve8();
|
|
40191
|
+
};
|
|
40192
|
+
server3.once("error", onError);
|
|
40193
|
+
server3.once("listening", onListening);
|
|
40194
|
+
try {
|
|
40195
|
+
server3.listen({ host: host2, port: port2, exclusive: true });
|
|
40196
|
+
} catch (error2) {
|
|
40197
|
+
onError(error2 instanceof Error ? error2 : new Error(String(error2)));
|
|
40198
|
+
}
|
|
40199
|
+
});
|
|
40200
|
+
} finally {
|
|
40201
|
+
await closeServer(server3);
|
|
40202
|
+
}
|
|
40203
|
+
}
|
|
40204
|
+
function createWebOpenAILoginLifetime(requestSignal, timeoutMs = WEB_OPENAI_LOGIN_TIMEOUT_MS) {
|
|
40205
|
+
const controller = new AbortController();
|
|
40206
|
+
let disposed = false;
|
|
40207
|
+
const abort = (reason) => {
|
|
40208
|
+
if (!disposed && !controller.signal.aborted) controller.abort(reason);
|
|
40209
|
+
};
|
|
40210
|
+
const onRequestAbort = () => {
|
|
40211
|
+
if (requestSignal) abort(abortReason(requestSignal));
|
|
40212
|
+
};
|
|
40213
|
+
if (requestSignal?.aborted) onRequestAbort();
|
|
40214
|
+
else requestSignal?.addEventListener("abort", onRequestAbort, { once: true });
|
|
40215
|
+
const timeout = setTimeout(() => {
|
|
40216
|
+
abort(
|
|
40217
|
+
new DOMException(
|
|
40218
|
+
`OpenAI browser login timed out after 10 minutes. Try again, or run ${DEVICE_CODE_FALLBACK}.`,
|
|
40219
|
+
"TimeoutError"
|
|
40220
|
+
)
|
|
40221
|
+
);
|
|
40222
|
+
}, timeoutMs);
|
|
40223
|
+
timeout.unref();
|
|
40224
|
+
return {
|
|
40225
|
+
signal: controller.signal,
|
|
40226
|
+
abort,
|
|
40227
|
+
dispose() {
|
|
40228
|
+
if (disposed) return;
|
|
40229
|
+
disposed = true;
|
|
40230
|
+
clearTimeout(timeout);
|
|
40231
|
+
requestSignal?.removeEventListener("abort", onRequestAbort);
|
|
40232
|
+
}
|
|
40233
|
+
};
|
|
40234
|
+
}
|
|
40235
|
+
function defaultBrowserSpawn(command, args) {
|
|
40236
|
+
return spawn4(command, args, { stdio: "ignore", detached: true });
|
|
40237
|
+
}
|
|
40238
|
+
function browserLaunchFailure(command, detail3) {
|
|
40239
|
+
return new Error(
|
|
40240
|
+
`Could not open the OpenAI sign-in page with ${command}: ${detail3}. Run ${DEVICE_CODE_FALLBACK} in a terminal.`
|
|
40241
|
+
);
|
|
40242
|
+
}
|
|
40243
|
+
function launchOpenAICodexBrowser(url2, onFailure, options) {
|
|
40244
|
+
const platform = options?.platform ?? process.platform;
|
|
40245
|
+
const [command, ...args] = platform === "darwin" ? ["open", url2] : platform === "win32" ? ["rundll32.exe", "url.dll,FileProtocolHandler", url2] : ["xdg-open", url2];
|
|
40246
|
+
let failed = false;
|
|
40247
|
+
const fail3 = (error2) => {
|
|
40248
|
+
if (failed) return;
|
|
40249
|
+
failed = true;
|
|
40250
|
+
onFailure(error2);
|
|
40251
|
+
};
|
|
40252
|
+
try {
|
|
40253
|
+
const child = (options?.spawnBrowser ?? defaultBrowserSpawn)(command, args);
|
|
40254
|
+
child.once("error", (error2) => {
|
|
40255
|
+
fail3(browserLaunchFailure(command, error2.message));
|
|
40256
|
+
});
|
|
40257
|
+
child.once("exit", (code, signal) => {
|
|
40258
|
+
if (code === 0) return;
|
|
40259
|
+
const detail3 = code === null ? `terminated by ${signal ?? "an unknown signal"}` : `exited ${code}`;
|
|
40260
|
+
fail3(browserLaunchFailure(command, detail3));
|
|
40261
|
+
});
|
|
40262
|
+
child.unref();
|
|
40263
|
+
} catch (error2) {
|
|
40264
|
+
fail3(
|
|
40265
|
+
browserLaunchFailure(
|
|
40266
|
+
command,
|
|
40267
|
+
error2 instanceof Error ? error2.message : String(error2)
|
|
40268
|
+
)
|
|
40269
|
+
);
|
|
40270
|
+
}
|
|
40271
|
+
}
|
|
40272
|
+
var webOpenAILoginTail = Promise.resolve();
|
|
40273
|
+
function waitForLoginTurn(turn, signal) {
|
|
40274
|
+
if (!signal) return turn;
|
|
40275
|
+
if (signal.aborted) return Promise.reject(abortReason(signal));
|
|
40276
|
+
return new Promise((resolve8, reject2) => {
|
|
40277
|
+
const onAbort = () => {
|
|
40278
|
+
signal.removeEventListener("abort", onAbort);
|
|
40279
|
+
reject2(abortReason(signal));
|
|
40280
|
+
};
|
|
40281
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
40282
|
+
void turn.then(() => {
|
|
40283
|
+
signal.removeEventListener("abort", onAbort);
|
|
40284
|
+
resolve8();
|
|
40285
|
+
});
|
|
40286
|
+
});
|
|
40287
|
+
}
|
|
40288
|
+
async function acquireWebOpenAILogin(signal) {
|
|
40289
|
+
const previous = webOpenAILoginTail;
|
|
40290
|
+
let releaseGate = () => {
|
|
40291
|
+
};
|
|
40292
|
+
const gate = new Promise((resolve8) => {
|
|
40293
|
+
releaseGate = resolve8;
|
|
40294
|
+
});
|
|
40295
|
+
webOpenAILoginTail = previous.then(() => gate);
|
|
40296
|
+
try {
|
|
40297
|
+
await waitForLoginTurn(previous, signal);
|
|
40298
|
+
} catch (error2) {
|
|
40299
|
+
void previous.then(releaseGate);
|
|
40300
|
+
throw error2;
|
|
40301
|
+
}
|
|
40302
|
+
let released = false;
|
|
40303
|
+
return () => {
|
|
40304
|
+
if (released) return;
|
|
40305
|
+
released = true;
|
|
40306
|
+
releaseGate();
|
|
40307
|
+
};
|
|
40308
|
+
}
|
|
40309
|
+
function answerWebOpenAIPrompt(prompt, loginSignal) {
|
|
40310
|
+
if (prompt.type === "select") {
|
|
40311
|
+
const browser = prompt.options.find((option) => option.id === "browser");
|
|
40312
|
+
return browser ? Promise.resolve(browser.id) : Promise.reject(new Error("Pi openai-codex provider does not support browser login"));
|
|
40313
|
+
}
|
|
40314
|
+
if (prompt.type !== "manual_code") {
|
|
40315
|
+
return Promise.reject(
|
|
40316
|
+
new Error(
|
|
40317
|
+
"interactive paste not supported in the web flow \u2014 cancel and try again, or use `bazilion auth openai login`"
|
|
40318
|
+
)
|
|
40319
|
+
);
|
|
40320
|
+
}
|
|
40321
|
+
return new Promise((_resolve, reject2) => {
|
|
40322
|
+
const promptSignal = prompt.signal;
|
|
40323
|
+
if (!promptSignal && !loginSignal) return;
|
|
40324
|
+
let settled = false;
|
|
40325
|
+
const cleanup = () => {
|
|
40326
|
+
promptSignal?.removeEventListener("abort", onPromptAbort);
|
|
40327
|
+
loginSignal?.removeEventListener("abort", onLoginAbort);
|
|
40328
|
+
};
|
|
40329
|
+
const cancel3 = (signal) => {
|
|
40330
|
+
if (settled) return;
|
|
40331
|
+
settled = true;
|
|
40332
|
+
cleanup();
|
|
40333
|
+
reject2(abortReason(signal));
|
|
40334
|
+
};
|
|
40335
|
+
const onPromptAbort = () => {
|
|
40336
|
+
if (promptSignal) cancel3(promptSignal);
|
|
40337
|
+
};
|
|
40338
|
+
const onLoginAbort = () => {
|
|
40339
|
+
if (loginSignal) cancel3(loginSignal);
|
|
40340
|
+
};
|
|
40341
|
+
if (loginSignal?.aborted) {
|
|
40342
|
+
onLoginAbort();
|
|
40343
|
+
return;
|
|
40344
|
+
}
|
|
40345
|
+
if (promptSignal?.aborted) {
|
|
40346
|
+
onPromptAbort();
|
|
40347
|
+
return;
|
|
40348
|
+
}
|
|
40349
|
+
promptSignal?.addEventListener("abort", onPromptAbort, { once: true });
|
|
40350
|
+
loginSignal?.addEventListener("abort", onLoginAbort, { once: true });
|
|
40351
|
+
});
|
|
40352
|
+
}
|
|
40353
|
+
|
|
40354
|
+
// ../daemon/src/routes/auth-login.ts
|
|
39953
40355
|
var authRouter = new Hono4();
|
|
39954
40356
|
authRouter.get("/auth/whoami", (c) => {
|
|
39955
40357
|
const { db } = getCtx();
|
|
@@ -39988,21 +40390,30 @@ authRouter.delete("/auth/openai", (c) => {
|
|
|
39988
40390
|
});
|
|
39989
40391
|
authRouter.post("/auth/openai/login", async (c) => {
|
|
39990
40392
|
const { db, authToken } = getCtx();
|
|
40393
|
+
const lifetime = createWebOpenAILoginLifetime(c.req.raw.signal);
|
|
40394
|
+
let releaseLogin;
|
|
39991
40395
|
try {
|
|
40396
|
+
releaseLogin = await acquireWebOpenAILogin(lifetime.signal);
|
|
40397
|
+
if (lifetime.signal.aborted) throw lifetime.signal.reason;
|
|
40398
|
+
await preflightOpenAICodexCallback();
|
|
40399
|
+
if (lifetime.signal.aborted) throw lifetime.signal.reason;
|
|
39992
40400
|
const creds = await loginOpenAICodex({
|
|
40401
|
+
signal: lifetime.signal,
|
|
39993
40402
|
notify: (event2) => {
|
|
39994
|
-
if (event2.type === "auth_url")
|
|
40403
|
+
if (event2.type === "auth_url") {
|
|
40404
|
+
launchOpenAICodexBrowser(event2.url, (error2) => lifetime.abort(error2));
|
|
40405
|
+
}
|
|
39995
40406
|
},
|
|
39996
|
-
prompt: (prompt) => prompt
|
|
39997
|
-
new Error(
|
|
39998
|
-
"interactive paste not supported in the web flow \u2014 cancel and try again, or use `bazilion auth openai login`"
|
|
39999
|
-
)
|
|
40000
|
-
)
|
|
40407
|
+
prompt: (prompt) => answerWebOpenAIPrompt(prompt, lifetime.signal)
|
|
40001
40408
|
});
|
|
40409
|
+
if (lifetime.signal.aborted) throw lifetime.signal.reason;
|
|
40002
40410
|
saveLoginCredentials(db, authToken, creds);
|
|
40003
40411
|
return c.json(getStatus(db, authToken));
|
|
40004
40412
|
} catch (err) {
|
|
40005
40413
|
return c.json({ error: err.message }, 400);
|
|
40414
|
+
} finally {
|
|
40415
|
+
releaseLogin?.();
|
|
40416
|
+
lifetime.dispose();
|
|
40006
40417
|
}
|
|
40007
40418
|
});
|
|
40008
40419
|
authRouter.post("/providers/test", async (c) => {
|
|
@@ -40099,17 +40510,6 @@ authRouter.delete("/sessions/:id", (c) => {
|
|
|
40099
40510
|
}
|
|
40100
40511
|
return c.body(null, 204);
|
|
40101
40512
|
});
|
|
40102
|
-
function openBrowser(url2) {
|
|
40103
|
-
const platform = process.platform;
|
|
40104
|
-
const [cmd, ...args] = platform === "darwin" ? ["open", url2] : platform === "win32" ? ["cmd", "/c", "start", '""', url2] : ["xdg-open", url2];
|
|
40105
|
-
try {
|
|
40106
|
-
const child = spawn4(cmd, args, { stdio: "ignore", detached: true });
|
|
40107
|
-
child.unref();
|
|
40108
|
-
child.on("error", () => {
|
|
40109
|
-
});
|
|
40110
|
-
} catch {
|
|
40111
|
-
}
|
|
40112
|
-
}
|
|
40113
40513
|
|
|
40114
40514
|
// ../daemon/src/routes/communication.ts
|
|
40115
40515
|
import { Hono as Hono5 } from "hono";
|
|
@@ -40626,6 +41026,7 @@ function readExisting(path) {
|
|
|
40626
41026
|
"starting",
|
|
40627
41027
|
"listening",
|
|
40628
41028
|
"restoring",
|
|
41029
|
+
"uninstalling",
|
|
40629
41030
|
"swapping",
|
|
40630
41031
|
"installed",
|
|
40631
41032
|
"recovery-required"
|
|
@@ -40643,7 +41044,9 @@ function readExisting(path) {
|
|
|
40643
41044
|
if (typeof parsed.startedAt === "number" && Number.isFinite(parsed.startedAt)) {
|
|
40644
41045
|
startedAt = parsed.startedAt;
|
|
40645
41046
|
}
|
|
40646
|
-
const validOwnerState = owner === "daemon" && state3 !== void 0 && ["starting", "listening"].includes(state3) && (state3 !== "listening" || host2 !== void 0 && port2 !== void 0) || owner === "restore" && state3 !== void 0 && ["restoring", "
|
|
41047
|
+
const validOwnerState = owner === "daemon" && state3 !== void 0 && ["starting", "listening"].includes(state3) && (state3 !== "listening" || host2 !== void 0 && port2 !== void 0) || owner === "restore" && state3 !== void 0 && ["restoring", "uninstalling", "swapping", "installed", "recovery-required"].includes(
|
|
41048
|
+
state3
|
|
41049
|
+
) && (!["swapping", "recovery-required"].includes(state3) || recoveryPath !== void 0 && hadPrevious !== void 0);
|
|
40647
41050
|
if (!validOwnerState) {
|
|
40648
41051
|
owner = void 0;
|
|
40649
41052
|
state3 = void 0;
|
|
@@ -40737,6 +41140,16 @@ function acquireDaemonLiveness(paths) {
|
|
|
40737
41140
|
);
|
|
40738
41141
|
}
|
|
40739
41142
|
const livePid = pidIsAlive(existing.pid);
|
|
41143
|
+
if (existing.owner === "restore" && existing.state === "uninstalling") {
|
|
41144
|
+
if (livePid) {
|
|
41145
|
+
throw new Error(
|
|
41146
|
+
`uninstall process ${existing.pid} is modifying this home; wait for it to finish`
|
|
41147
|
+
);
|
|
41148
|
+
}
|
|
41149
|
+
throw new Error(
|
|
41150
|
+
"a previous Bazilion uninstall was interrupted for this home. Re-run the same `bazilion uninstall` command (including its `--all` choice) with the same BAZILION_HOME (or --home) to finish it before starting Bazilion again."
|
|
41151
|
+
);
|
|
41152
|
+
}
|
|
40740
41153
|
if (existing.owner === "restore" && ["swapping", "recovery-required"].includes(existing.state)) {
|
|
40741
41154
|
if (livePid) {
|
|
40742
41155
|
throw new Error(
|
|
@@ -42180,20 +42593,30 @@ teamsRouter.put("/:id/topic-format", async (c) => {
|
|
|
42180
42593
|
);
|
|
42181
42594
|
return c.json(teams_exports.get(db, id, paths));
|
|
42182
42595
|
});
|
|
42596
|
+
var TeamMemoryNotFoundError = class extends Error {
|
|
42597
|
+
};
|
|
42183
42598
|
async function openMemory(rawId) {
|
|
42184
42599
|
const { db, paths } = getCtx();
|
|
42185
42600
|
const team = teams_exports.get(db, rawId, paths);
|
|
42186
|
-
if (!team) throw new
|
|
42601
|
+
if (!team) throw new TeamMemoryNotFoundError(`team not found: ${rawId}`);
|
|
42187
42602
|
const mem = qmdBackend(join29(team.path, "memory"));
|
|
42188
42603
|
await mem.init();
|
|
42189
42604
|
return { mem, team };
|
|
42190
42605
|
}
|
|
42606
|
+
function teamMemoryError(c, error2) {
|
|
42607
|
+
const safe = sanitizeNativeModuleError(error2, { subject: "Bazilion memory" });
|
|
42608
|
+
const message = safe instanceof Error ? safe.message : String(safe);
|
|
42609
|
+
if (safe instanceof TeamMemoryNotFoundError || message.startsWith("memory entry not found:")) {
|
|
42610
|
+
return c.json({ error: message }, 404);
|
|
42611
|
+
}
|
|
42612
|
+
return c.json({ error: message }, 500);
|
|
42613
|
+
}
|
|
42191
42614
|
teamsRouter.get("/:id/memory", async (c) => {
|
|
42192
42615
|
try {
|
|
42193
42616
|
const { mem } = await openMemory(c.req.param("id"));
|
|
42194
42617
|
return c.json(await mem.list());
|
|
42195
42618
|
} catch (err) {
|
|
42196
|
-
return c
|
|
42619
|
+
return teamMemoryError(c, err);
|
|
42197
42620
|
}
|
|
42198
42621
|
});
|
|
42199
42622
|
teamsRouter.get("/:id/memory/search", async (c) => {
|
|
@@ -42204,7 +42627,7 @@ teamsRouter.get("/:id/memory/search", async (c) => {
|
|
|
42204
42627
|
const { mem } = await openMemory(c.req.param("id"));
|
|
42205
42628
|
return c.json(await mem.search(q2, { limit }));
|
|
42206
42629
|
} catch (err) {
|
|
42207
|
-
return c
|
|
42630
|
+
return teamMemoryError(c, err);
|
|
42208
42631
|
}
|
|
42209
42632
|
});
|
|
42210
42633
|
teamsRouter.get("/:id/memory/:key{.+}", async (c) => {
|
|
@@ -42212,7 +42635,7 @@ teamsRouter.get("/:id/memory/:key{.+}", async (c) => {
|
|
|
42212
42635
|
const { mem } = await openMemory(c.req.param("id"));
|
|
42213
42636
|
return c.json(await mem.read(c.req.param("key")));
|
|
42214
42637
|
} catch (err) {
|
|
42215
|
-
return c
|
|
42638
|
+
return teamMemoryError(c, err);
|
|
42216
42639
|
}
|
|
42217
42640
|
});
|
|
42218
42641
|
teamsRouter.put("/:id/memory/:key{.+}", async (c) => {
|
|
@@ -42223,7 +42646,7 @@ teamsRouter.put("/:id/memory/:key{.+}", async (c) => {
|
|
|
42223
42646
|
const { mem } = await openMemory(c.req.param("id"));
|
|
42224
42647
|
return c.json(await mem.write(c.req.param("key"), body.content));
|
|
42225
42648
|
} catch (err) {
|
|
42226
|
-
return c
|
|
42649
|
+
return teamMemoryError(c, err);
|
|
42227
42650
|
}
|
|
42228
42651
|
});
|
|
42229
42652
|
teamsRouter.delete("/:id/memory/:key{.+}", async (c) => {
|
|
@@ -42232,7 +42655,7 @@ teamsRouter.delete("/:id/memory/:key{.+}", async (c) => {
|
|
|
42232
42655
|
await mem.remove(c.req.param("key"));
|
|
42233
42656
|
return c.body(null, 204);
|
|
42234
42657
|
} catch (err) {
|
|
42235
|
-
return c
|
|
42658
|
+
return teamMemoryError(c, err);
|
|
42236
42659
|
}
|
|
42237
42660
|
});
|
|
42238
42661
|
function teamPolicyError(c, error2) {
|
|
@@ -42628,7 +43051,22 @@ try {
|
|
|
42628
43051
|
);
|
|
42629
43052
|
process.exit(1);
|
|
42630
43053
|
}
|
|
42631
|
-
|
|
43054
|
+
try {
|
|
43055
|
+
getCtx();
|
|
43056
|
+
} catch (error2) {
|
|
43057
|
+
const detail3 = error2 instanceof IncompatibleDatabaseError || error2 instanceof IncompatibleBootstrapIdentityError ? error2.message : error2 instanceof Error ? error2.stack ?? error2.message : String(error2);
|
|
43058
|
+
writeSync2(process.stderr.fd, `bazilion daemon failed to start: ${detail3}
|
|
43059
|
+
`);
|
|
43060
|
+
try {
|
|
43061
|
+
closeCtxForShutdown();
|
|
43062
|
+
} catch {
|
|
43063
|
+
}
|
|
43064
|
+
try {
|
|
43065
|
+
daemonLiveness.stop();
|
|
43066
|
+
} catch {
|
|
43067
|
+
}
|
|
43068
|
+
process.exit(1);
|
|
43069
|
+
}
|
|
42632
43070
|
var app = createApp();
|
|
42633
43071
|
var shuttingDown = false;
|
|
42634
43072
|
var server2 = serve({ fetch: app.fetch, hostname: host, port }, (info) => {
|