@commandgarden/cli 1.1.3 → 1.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/main.js CHANGED
@@ -12202,7 +12202,7 @@ var {
12202
12202
 
12203
12203
  // src/main.ts
12204
12204
  import { join as join4, dirname as dirname2, resolve } from "path";
12205
- import { readFileSync as readFileSync7 } from "fs";
12205
+ import { readFileSync as readFileSync8 } from "fs";
12206
12206
  import { homedir } from "os";
12207
12207
  import { fileURLToPath } from "url";
12208
12208
 
@@ -12640,7 +12640,7 @@ function stepSummary(step) {
12640
12640
  // src/commands/validate.ts
12641
12641
  import { readFileSync as readFileSync3 } from "fs";
12642
12642
 
12643
- // ../shared/dist/capabilities.js
12643
+ // node_modules/@commandgarden/shared/dist/capabilities.js
12644
12644
  var CAPABILITIES = [
12645
12645
  "navigate",
12646
12646
  "cookie_read",
@@ -16702,7 +16702,7 @@ var coerce = {
16702
16702
  };
16703
16703
  var NEVER = INVALID;
16704
16704
 
16705
- // ../shared/dist/pipeline.js
16705
+ // node_modules/@commandgarden/shared/dist/pipeline.js
16706
16706
  var STEP_CAPABILITY_MAP = {
16707
16707
  navigate: "navigate",
16708
16708
  wait: "navigate",
@@ -16795,7 +16795,7 @@ var pipelineStepSchema = external_exports.discriminatedUnion("step", [
16795
16795
  jsEvaluateStepSchema
16796
16796
  ]);
16797
16797
 
16798
- // ../shared/dist/connector.js
16798
+ // node_modules/@commandgarden/shared/dist/connector.js
16799
16799
  var capabilityEnum = external_exports.enum(CAPABILITIES);
16800
16800
  var connectorArgSchema = external_exports.object({
16801
16801
  name: external_exports.string(),
@@ -16822,7 +16822,7 @@ var connectorSchema = external_exports.object({
16822
16822
  pipeline: external_exports.array(pipelineStepSchema).min(1)
16823
16823
  });
16824
16824
 
16825
- // ../shared/dist/loader.js
16825
+ // node_modules/@commandgarden/shared/dist/loader.js
16826
16826
  var import_yaml = __toESM(require_dist(), 1);
16827
16827
  function parseConnectorYaml(yamlContent) {
16828
16828
  let parsed;
@@ -16893,7 +16893,7 @@ function validateConnectorSemantics(connector) {
16893
16893
  return errors;
16894
16894
  }
16895
16895
 
16896
- // ../shared/dist/events.js
16896
+ // node_modules/@commandgarden/shared/dist/events.js
16897
16897
  import { randomUUID } from "crypto";
16898
16898
 
16899
16899
  // src/commands/validate.ts
@@ -16932,8 +16932,47 @@ function executeValidate(filePath) {
16932
16932
 
16933
16933
  // src/commands/daemon-cmd.ts
16934
16934
  import { spawn } from "child_process";
16935
- import { readFileSync as readFileSync4, writeFileSync, existsSync as existsSync2, unlinkSync, mkdirSync } from "fs";
16935
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync2, existsSync as existsSync3, unlinkSync as unlinkSync2, mkdirSync, openSync, closeSync } from "fs";
16936
16936
  import { join as join2 } from "path";
16937
+
16938
+ // src/poll.ts
16939
+ async function pollUntilReady(opts) {
16940
+ for (let i = 0; i < opts.maxAttempts; i++) {
16941
+ if (!opts.isAlive()) return "died";
16942
+ if (await opts.checkReady()) return "ready";
16943
+ await new Promise((r) => setTimeout(r, opts.intervalMs));
16944
+ }
16945
+ return "timeout";
16946
+ }
16947
+
16948
+ // src/process-alive.ts
16949
+ function isProcessAlive(pid) {
16950
+ try {
16951
+ process.kill(pid, 0);
16952
+ return true;
16953
+ } catch {
16954
+ return false;
16955
+ }
16956
+ }
16957
+
16958
+ // src/lockfile.ts
16959
+ import { readFileSync as readFileSync4, writeFileSync, existsSync as existsSync2, unlinkSync } from "fs";
16960
+ function acquireLock(lockPath) {
16961
+ if (existsSync2(lockPath)) {
16962
+ const holderPid = parseInt(readFileSync4(lockPath, "utf-8").trim(), 10);
16963
+ if (isProcessAlive(holderPid)) return { acquired: false, holderPid };
16964
+ }
16965
+ writeFileSync(lockPath, String(process.pid));
16966
+ return { acquired: true };
16967
+ }
16968
+ function releaseLock(lockPath) {
16969
+ try {
16970
+ unlinkSync(lockPath);
16971
+ } catch {
16972
+ }
16973
+ }
16974
+
16975
+ // src/commands/daemon-cmd.ts
16937
16976
  async function executeDaemonStatus(baseUrl) {
16938
16977
  try {
16939
16978
  const resp = await fetch(`${baseUrl}/api/status`);
@@ -16950,33 +16989,82 @@ async function executeDaemonStatus(baseUrl) {
16950
16989
  async function executeDaemonStart(baseUrl, cgHome, daemonScript) {
16951
16990
  try {
16952
16991
  const resp = await fetch(`${baseUrl}/api/status`);
16953
- if (resp.ok) return "Daemon is already running.";
16992
+ if (resp.ok) return { status: "already-running", message: "Daemon is already running." };
16954
16993
  } catch {
16955
16994
  }
16956
- const pidPath = join2(cgHome, "daemon.pid");
16957
16995
  mkdirSync(cgHome, { recursive: true });
16958
- const child = spawn("node", [daemonScript], {
16959
- detached: true,
16960
- stdio: "ignore"
16961
- });
16962
- if (child.pid) {
16963
- writeFileSync(pidPath, String(child.pid));
16996
+ const lockPath = join2(cgHome, "daemon.lock");
16997
+ const lock = acquireLock(lockPath);
16998
+ if (!lock.acquired) {
16999
+ return {
17000
+ status: "locked",
17001
+ message: `Another cg up/daemon start is already in progress (PID ${lock.holderPid}).`
17002
+ };
17003
+ }
17004
+ try {
17005
+ const pidPath = join2(cgHome, "daemon.pid");
17006
+ const logPath = join2(cgHome, "daemon.log");
17007
+ console.error("Starting daemon...");
17008
+ const logFd = openSync(logPath, "a");
17009
+ const child = spawn("node", [daemonScript], { detached: true, stdio: ["ignore", logFd, logFd] });
17010
+ closeSync(logFd);
17011
+ let spawnFailed = false;
17012
+ child.on("error", () => {
17013
+ spawnFailed = true;
17014
+ });
17015
+ if (child.pid) writeFileSync2(pidPath, String(child.pid));
17016
+ child.unref();
17017
+ const outcome = await pollUntilReady({
17018
+ checkReady: async () => {
17019
+ try {
17020
+ const resp = await fetch(`${baseUrl}/api/status`);
17021
+ return resp.ok;
17022
+ } catch {
17023
+ return false;
17024
+ }
17025
+ },
17026
+ isAlive: () => !spawnFailed && (!child.pid || isProcessAlive(child.pid)),
17027
+ maxAttempts: 20,
17028
+ intervalMs: 500
17029
+ });
17030
+ if (outcome === "ready") {
17031
+ return { status: "started", message: `Daemon started (PID: ${child.pid ?? "unknown"}).`, pid: child.pid };
17032
+ }
17033
+ if (outcome === "died") {
17034
+ if (existsSync3(pidPath)) unlinkSync2(pidPath);
17035
+ const tail = readLogTail(logPath, 10);
17036
+ return { status: "failed", message: `Daemon failed to start.
17037
+ ${tail}` };
17038
+ }
17039
+ return {
17040
+ status: "unresponsive",
17041
+ message: `Daemon started (PID: ${child.pid ?? "unknown"}) but is not responding. Check ${logPath} for details.`,
17042
+ pid: child.pid
17043
+ };
17044
+ } finally {
17045
+ releaseLock(lockPath);
17046
+ }
17047
+ }
17048
+ function readLogTail(logPath, lines) {
17049
+ try {
17050
+ const content = readFileSync5(logPath, "utf-8");
17051
+ return content.split("\n").slice(-lines).join("\n").trim();
17052
+ } catch {
17053
+ return "(no log available)";
16964
17054
  }
16965
- child.unref();
16966
- return `Daemon started (PID: ${child.pid ?? "unknown"}).`;
16967
17055
  }
16968
17056
  async function executeDaemonStop(cgHome) {
16969
17057
  const pidPath = join2(cgHome, "daemon.pid");
16970
- if (!existsSync2(pidPath)) {
17058
+ if (!existsSync3(pidPath)) {
16971
17059
  return "Daemon is not running (no PID file found).";
16972
17060
  }
16973
- const pid = parseInt(readFileSync4(pidPath, "utf-8").trim(), 10);
17061
+ const pid = parseInt(readFileSync5(pidPath, "utf-8").trim(), 10);
16974
17062
  try {
16975
17063
  process.kill(pid, "SIGTERM");
16976
- unlinkSync(pidPath);
17064
+ unlinkSync2(pidPath);
16977
17065
  return `Daemon stopped (PID: ${pid}).`;
16978
17066
  } catch {
16979
- unlinkSync(pidPath);
17067
+ unlinkSync2(pidPath);
16980
17068
  return `Daemon process ${pid} not found (stale PID file cleaned up).`;
16981
17069
  }
16982
17070
  }
@@ -17106,16 +17194,16 @@ async function executeAuditShow(client, id) {
17106
17194
  }
17107
17195
 
17108
17196
  // src/commands/config-cmd.ts
17109
- import { readFileSync as readFileSync5, existsSync as existsSync3 } from "fs";
17197
+ import { readFileSync as readFileSync6, existsSync as existsSync4 } from "fs";
17110
17198
  function executeConfigShow(configPath) {
17111
- if (!existsSync3(configPath)) {
17199
+ if (!existsSync4(configPath)) {
17112
17200
  return [
17113
17201
  "No config file found.",
17114
17202
  `Expected at: ${configPath}`,
17115
17203
  'Using defaults. Run "commandgarden config set <key> <value>" to create one.'
17116
17204
  ].join("\n");
17117
17205
  }
17118
- return readFileSync5(configPath, "utf-8");
17206
+ return readFileSync6(configPath, "utf-8");
17119
17207
  }
17120
17208
  async function executeConfigSet(client, key, value) {
17121
17209
  try {
@@ -17129,12 +17217,12 @@ async function executeConfigSet(client, key, value) {
17129
17217
  // src/commands/gui-cmd.ts
17130
17218
  var import_yaml2 = __toESM(require_dist(), 1);
17131
17219
  import { spawn as spawn2 } from "child_process";
17132
- import { readFileSync as readFileSync6, writeFileSync as writeFileSync2, existsSync as existsSync4, unlinkSync as unlinkSync2, mkdirSync as mkdirSync2, openSync, closeSync } from "fs";
17220
+ import { readFileSync as readFileSync7, writeFileSync as writeFileSync3, existsSync as existsSync5, unlinkSync as unlinkSync3, mkdirSync as mkdirSync2, openSync as openSync2, closeSync as closeSync2 } from "fs";
17133
17221
  import { join as join3 } from "path";
17134
17222
  function readAppPort(configPath) {
17135
17223
  try {
17136
- if (existsSync4(configPath)) {
17137
- const config2 = (0, import_yaml2.parse)(readFileSync6(configPath, "utf-8"));
17224
+ if (existsSync5(configPath)) {
17225
+ const config2 = (0, import_yaml2.parse)(readFileSync7(configPath, "utf-8"));
17138
17226
  const port = config2?.app?.port;
17139
17227
  if (typeof port === "number") return port;
17140
17228
  }
@@ -17148,41 +17236,67 @@ async function executeGuiStart(baseUrl, cgHome, appScript, opts) {
17148
17236
  const resp = await fetch(`${baseUrl}/api/status`);
17149
17237
  if (!resp.ok) throw new Error();
17150
17238
  } catch {
17151
- return "Daemon is not running. Start it with: cg daemon start (or use cg up)";
17239
+ const message = "Daemon is not running. Start it with: cg daemon start (or use cg up)";
17240
+ return opts.background ? { status: "failed", message } : message;
17152
17241
  }
17153
17242
  const pidPath = join3(cgHome, "app.pid");
17154
- if (existsSync4(pidPath)) {
17155
- const pid = parseInt(readFileSync6(pidPath, "utf-8").trim(), 10);
17156
- try {
17157
- process.kill(pid, 0);
17158
- return "GUI is already running.";
17159
- } catch {
17160
- unlinkSync2(pidPath);
17243
+ if (existsSync5(pidPath)) {
17244
+ const pid = parseInt(readFileSync7(pidPath, "utf-8").trim(), 10);
17245
+ if (isProcessAlive(pid)) {
17246
+ const message = "GUI is already running.";
17247
+ return opts.background ? { status: "already-running", message } : message;
17161
17248
  }
17249
+ unlinkSync3(pidPath);
17162
17250
  }
17163
17251
  mkdirSync2(cgHome, { recursive: true });
17164
17252
  if (opts.background) {
17165
- const logPath = join3(cgHome, "app.log");
17166
- const logFd = openSync(logPath, "a");
17167
- const child2 = spawn2("node", [appScript], { detached: true, stdio: ["ignore", logFd, logFd] });
17168
- closeSync(logFd);
17169
- if (child2.pid) writeFileSync2(pidPath, String(child2.pid));
17170
- child2.unref();
17171
- if (!opts.noOpen) {
17253
+ const lockPath = join3(cgHome, "app.lock");
17254
+ const lock = acquireLock(lockPath);
17255
+ if (!lock.acquired) {
17256
+ return { status: "locked", message: `Another cg up/gui start is already in progress (PID ${lock.holderPid}).` };
17257
+ }
17258
+ try {
17259
+ console.error("Starting GUI...");
17260
+ const logPath = join3(cgHome, "app.log");
17261
+ const logFd = openSync2(logPath, "a");
17262
+ const child2 = spawn2("node", [appScript], { detached: true, stdio: ["ignore", logFd, logFd] });
17263
+ closeSync2(logFd);
17264
+ let spawnFailed = false;
17265
+ child2.on("error", () => {
17266
+ spawnFailed = true;
17267
+ });
17268
+ if (child2.pid) writeFileSync3(pidPath, String(child2.pid));
17269
+ child2.unref();
17270
+ if (opts.noOpen) {
17271
+ return { status: "started", message: `GUI started (PID: ${child2.pid ?? "unknown"}).`, pid: child2.pid };
17272
+ }
17172
17273
  const appUrl = `http://127.0.0.1:${appPort}`;
17173
- const ready = await waitForServer(appUrl, child2);
17174
- if (ready) {
17274
+ const outcome = await pollUntilReady({
17275
+ checkReady: async () => {
17276
+ try {
17277
+ await fetch(appUrl);
17278
+ return true;
17279
+ } catch {
17280
+ return false;
17281
+ }
17282
+ },
17283
+ isAlive: () => !spawnFailed && (!child2.pid || isProcessAlive(child2.pid)),
17284
+ maxAttempts: 40,
17285
+ intervalMs: 500
17286
+ });
17287
+ if (outcome === "ready") {
17175
17288
  openBrowser(appUrl);
17176
- } else {
17177
- if (child2.pid) try {
17178
- process.kill(child2.pid, "SIGTERM");
17179
- } catch {
17180
- }
17181
- if (existsSync4(pidPath)) unlinkSync2(pidPath);
17182
- return `GUI failed to start. Check ${logPath} for errors.`;
17289
+ return { status: "started", message: `GUI started (PID: ${child2.pid ?? "unknown"}).`, pid: child2.pid };
17290
+ }
17291
+ if (child2.pid) try {
17292
+ process.kill(child2.pid, "SIGTERM");
17293
+ } catch {
17183
17294
  }
17295
+ if (existsSync5(pidPath)) unlinkSync3(pidPath);
17296
+ return { status: "failed", message: `GUI failed to start. Check ${logPath} for errors.` };
17297
+ } finally {
17298
+ releaseLock(lockPath);
17184
17299
  }
17185
- return `GUI started (PID: ${child2.pid ?? "unknown"}).`;
17186
17300
  }
17187
17301
  const child = spawn2("node", [appScript], { stdio: "inherit" });
17188
17302
  if (!opts.noOpen) {
@@ -17195,21 +17309,21 @@ async function executeGuiStart(baseUrl, cgHome, appScript, opts) {
17195
17309
  }
17196
17310
  function executeGuiStop(cgHome) {
17197
17311
  const pidPath = join3(cgHome, "app.pid");
17198
- if (!existsSync4(pidPath)) return "GUI is not running (no PID file found).";
17199
- const pid = parseInt(readFileSync6(pidPath, "utf-8").trim(), 10);
17312
+ if (!existsSync5(pidPath)) return "GUI is not running (no PID file found).";
17313
+ const pid = parseInt(readFileSync7(pidPath, "utf-8").trim(), 10);
17200
17314
  try {
17201
17315
  process.kill(pid, "SIGTERM");
17202
- unlinkSync2(pidPath);
17316
+ unlinkSync3(pidPath);
17203
17317
  return `GUI stopped (PID: ${pid}).`;
17204
17318
  } catch {
17205
- unlinkSync2(pidPath);
17319
+ unlinkSync3(pidPath);
17206
17320
  return `GUI process ${pid} not found (stale PID file cleaned up).`;
17207
17321
  }
17208
17322
  }
17209
17323
  function executeGuiStatus(cgHome) {
17210
17324
  const pidPath = join3(cgHome, "app.pid");
17211
- if (!existsSync4(pidPath)) return "GUI: not running (no PID file found).";
17212
- const pid = parseInt(readFileSync6(pidPath, "utf-8").trim(), 10);
17325
+ if (!existsSync5(pidPath)) return "GUI: not running (no PID file found).";
17326
+ const pid = parseInt(readFileSync7(pidPath, "utf-8").trim(), 10);
17213
17327
  try {
17214
17328
  process.kill(pid, 0);
17215
17329
  return `GUI: running (PID: ${pid}).`;
@@ -17241,16 +17355,14 @@ function openBrowser(url) {
17241
17355
  // src/commands/up-down.ts
17242
17356
  async function executeUp(baseUrl, cgHome, daemonScript, appScript, configPath) {
17243
17357
  const lines = [];
17244
- lines.push(await executeDaemonStart(baseUrl, cgHome, daemonScript));
17245
- for (let i = 0; i < 10; i++) {
17246
- try {
17247
- const resp = await fetch(`${baseUrl}/api/status`);
17248
- if (resp.ok) break;
17249
- } catch {
17250
- }
17251
- await new Promise((r) => setTimeout(r, 500));
17358
+ const daemonResult = await executeDaemonStart(baseUrl, cgHome, daemonScript);
17359
+ lines.push(daemonResult.message);
17360
+ const canProceed = daemonResult.status === "started" || daemonResult.status === "already-running";
17361
+ if (!canProceed) {
17362
+ return lines.join("\n");
17252
17363
  }
17253
- lines.push(await executeGuiStart(baseUrl, cgHome, appScript, { background: true, configPath }));
17364
+ const guiResult = await executeGuiStart(baseUrl, cgHome, appScript, { background: true, configPath });
17365
+ lines.push(typeof guiResult === "string" ? guiResult : guiResult.message);
17254
17366
  return lines.join("\n");
17255
17367
  }
17256
17368
  async function executeDown(cgHome) {
@@ -17266,7 +17378,7 @@ var __filename = fileURLToPath(import.meta.url);
17266
17378
  var __dirname = dirname2(__filename);
17267
17379
  var CLI_VERSION = (() => {
17268
17380
  try {
17269
- const pkg = JSON.parse(readFileSync7(resolve(__dirname, "..", "package.json"), "utf-8"));
17381
+ const pkg = JSON.parse(readFileSync8(resolve(__dirname, "..", "package.json"), "utf-8"));
17270
17382
  return pkg.version ?? "0.0.0";
17271
17383
  } catch {
17272
17384
  return "0.0.0";
@@ -17316,7 +17428,8 @@ daemon.command("status").description("Check daemon status").action(async () => {
17316
17428
  console.log(await executeDaemonStatus(BASE_URL));
17317
17429
  });
17318
17430
  daemon.command("start").description("Start the daemon in background").action(async () => {
17319
- console.log(await executeDaemonStart(BASE_URL, CG_HOME, getDaemonScript()));
17431
+ const result = await executeDaemonStart(BASE_URL, CG_HOME, getDaemonScript());
17432
+ console.log(result.message);
17320
17433
  });
17321
17434
  daemon.command("stop").description("Stop the daemon").action(async () => {
17322
17435
  console.log(await executeDaemonStop(CG_HOME));
@@ -17353,11 +17466,12 @@ config.command("set <key> <value>").description("Set a configuration value (e.g.
17353
17466
  });
17354
17467
  var gui = program2.command("gui").description("Manage the GUI app server");
17355
17468
  gui.command("start", { isDefault: true }).description("Start the GUI (foreground by default)").option("-b, --background", "Run in background").option("--no-open", "Do not open browser").action(async (opts) => {
17356
- console.log(await executeGuiStart(BASE_URL, CG_HOME, getAppScript(), {
17469
+ const result = await executeGuiStart(BASE_URL, CG_HOME, getAppScript(), {
17357
17470
  background: opts.background,
17358
17471
  noOpen: opts.open === false,
17359
17472
  configPath: CONFIG_PATH
17360
- }));
17473
+ });
17474
+ console.log(typeof result === "string" ? result : result.message);
17361
17475
  });
17362
17476
  gui.command("stop").description("Stop the GUI").action(() => {
17363
17477
  console.log(executeGuiStop(CG_HOME));
@@ -34,7 +34,7 @@ async function start() {
34
34
  const port = readAppPort();
35
35
  const daemonUrl = 'http://127.0.0.1:19825';
36
36
  const daemon = new DaemonClient(daemonUrl, token);
37
- const store = new AppStore(join(CG_HOME, 'app.db'));
37
+ const store = await AppStore.create(join(CG_HOME, 'app.db'));
38
38
  const app = Fastify();
39
39
  registerRoutes(app, daemon, store);
40
40
  // Serve static SPA files in production
@@ -1,53 +1,97 @@
1
- import Database from 'better-sqlite3';
1
+ import initSqlJs from 'sql.js';
2
+ import { existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
2
4
  import { randomUUID } from 'node:crypto';
3
5
  export class AppStore {
4
6
  db;
5
- constructor(dbPath) {
6
- this.db = new Database(dbPath);
7
- this.db.pragma('journal_mode = WAL');
8
- this.migrate();
7
+ dbPath;
8
+ constructor(db, dbPath) {
9
+ this.db = db;
10
+ this.dbPath = dbPath;
11
+ }
12
+ static async create(dbPath) {
13
+ const SQL = await initSqlJs();
14
+ let db;
15
+ if (dbPath !== ':memory:' && existsSync(dbPath)) {
16
+ const buf = readFileSync(dbPath);
17
+ db = new SQL.Database(buf);
18
+ }
19
+ else {
20
+ db = new SQL.Database();
21
+ }
22
+ const store = new AppStore(db, dbPath);
23
+ store.migrate();
24
+ if (dbPath !== ':memory:')
25
+ store.persist();
26
+ return store;
27
+ }
28
+ // sql.js requires full-DB export on every write; acceptable for small app databases.
29
+ // Write to a temp file then atomically rename to prevent corruption on crash.
30
+ persist() {
31
+ if (this.dbPath === ':memory:')
32
+ return;
33
+ const data = this.db.export();
34
+ const dir = dirname(this.dbPath);
35
+ mkdirSync(dir, { recursive: true });
36
+ const tmpPath = this.dbPath + '.tmp';
37
+ writeFileSync(tmpPath, Buffer.from(data));
38
+ renameSync(tmpPath, this.dbPath);
39
+ }
40
+ query(sql, params = []) {
41
+ const results = this.db.exec(sql, params);
42
+ if (results.length === 0)
43
+ return [];
44
+ const { columns, values } = results[0];
45
+ return values.map(row => {
46
+ const obj = {};
47
+ columns.forEach((col, i) => { obj[col] = row[i]; });
48
+ return obj;
49
+ });
9
50
  }
10
51
  migrate() {
11
- this.db.exec(`
12
- CREATE TABLE IF NOT EXISTS preferences (
13
- key TEXT PRIMARY KEY,
14
- value TEXT NOT NULL
15
- );
16
- CREATE TABLE IF NOT EXISTS saved_views (
17
- id TEXT PRIMARY KEY,
18
- app TEXT NOT NULL,
19
- name TEXT NOT NULL,
20
- config TEXT NOT NULL,
21
- created_at TEXT NOT NULL DEFAULT (datetime('now'))
22
- );
23
- `);
52
+ this.db.run(`CREATE TABLE IF NOT EXISTS preferences (
53
+ key TEXT PRIMARY KEY,
54
+ value TEXT NOT NULL
55
+ )`);
56
+ this.db.run(`CREATE TABLE IF NOT EXISTS saved_views (
57
+ id TEXT PRIMARY KEY,
58
+ app TEXT NOT NULL,
59
+ name TEXT NOT NULL,
60
+ config TEXT NOT NULL,
61
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
62
+ )`);
24
63
  }
25
64
  getPreference(key) {
26
- const row = this.db.prepare('SELECT value FROM preferences WHERE key = ?').get(key);
27
- return row?.value;
65
+ const rows = this.query('SELECT value FROM preferences WHERE key = ?', [key]);
66
+ return rows.length > 0 ? rows[0].value : undefined;
28
67
  }
29
68
  setPreference(key, value) {
30
- this.db.prepare('INSERT OR REPLACE INTO preferences (key, value) VALUES (?, ?)').run(key, value);
69
+ this.db.run('INSERT OR REPLACE INTO preferences (key, value) VALUES (?, ?)', [key, value]);
70
+ this.persist();
31
71
  }
32
72
  getAllPreferences() {
33
- const rows = this.db.prepare('SELECT key, value FROM preferences').all();
73
+ const rows = this.query('SELECT key, value FROM preferences');
34
74
  const result = {};
35
75
  for (const row of rows)
36
76
  result[row.key] = row.value;
37
77
  return result;
38
78
  }
39
79
  listViews(app) {
40
- return this.db.prepare('SELECT * FROM saved_views WHERE app = ? ORDER BY created_at DESC').all(app);
80
+ return this.query('SELECT * FROM saved_views WHERE app = ? ORDER BY created_at DESC', [app]);
41
81
  }
42
82
  createView(app, name, config) {
43
83
  const id = randomUUID();
44
84
  const created_at = new Date().toISOString();
45
- this.db.prepare('INSERT INTO saved_views (id, app, name, config, created_at) VALUES (?, ?, ?, ?, ?)').run(id, app, name, config, created_at);
85
+ this.db.run('INSERT INTO saved_views (id, app, name, config, created_at) VALUES (?, ?, ?, ?, ?)', [id, app, name, config, created_at]);
86
+ this.persist();
46
87
  return { id, app, name, config, created_at };
47
88
  }
48
89
  deleteView(id) {
49
- const result = this.db.prepare('DELETE FROM saved_views WHERE id = ?').run(id);
50
- return result.changes > 0;
90
+ this.db.run('DELETE FROM saved_views WHERE id = ?', [id]);
91
+ const changes = this.db.getRowsModified();
92
+ if (changes > 0)
93
+ this.persist();
94
+ return changes > 0;
51
95
  }
52
96
  close() {
53
97
  this.db.close();
@@ -17,14 +17,13 @@
17
17
  "@commandgarden/shared": "*",
18
18
  "fastify": "^5.0.0",
19
19
  "@fastify/static": "^8.0.0",
20
- "better-sqlite3": "^11.0.0",
20
+ "sql.js": "^1.11.0",
21
21
  "yaml": "^2.4.0",
22
22
  "react": "^18.3.0",
23
23
  "react-dom": "^18.3.0",
24
24
  "react-router-dom": "^6.23.0"
25
25
  },
26
26
  "devDependencies": {
27
- "@types/better-sqlite3": "^7.6.0",
28
27
  "@types/node": "^22.0.0",
29
28
  "@types/react": "^18.3.0",
30
29
  "@types/react-dom": "^18.3.0",
@@ -1,7 +1,11 @@
1
1
  import type { AuditEvent } from '@commandgarden/shared';
2
2
  export declare class AuditStore {
3
3
  private db;
4
- constructor(dbPath: string);
4
+ private dbPath;
5
+ private constructor();
6
+ static create(dbPath: string): Promise<AuditStore>;
7
+ private persist;
8
+ private query;
5
9
  private migrate;
6
10
  insert(event: AuditEvent): void;
7
11
  list(opts?: {
@@ -1 +1 @@
1
- {"version":3,"file":"audit-store.d.ts","sourceRoot":"","sources":["../src/audit-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,uBAAuB,CAAC;AAErE,qBAAa,UAAU;IACrB,OAAO,CAAC,EAAE,CAAoB;gBAElB,MAAM,EAAE,MAAM;IAe1B,OAAO,CAAC,OAAO;IAmBf,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAkB/B,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,EAAE;IAW9F,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAK3C,KAAK,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM;IAKpC,KAAK,IAAI,IAAI;IAEb,OAAO,CAAC,OAAO;CAoBhB"}
1
+ {"version":3,"file":"audit-store.d.ts","sourceRoot":"","sources":["../src/audit-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,uBAAuB,CAAC;AAIrE,qBAAa,UAAU;IACrB,OAAO,CAAC,EAAE,CAAW;IACrB,OAAO,CAAC,MAAM,CAAS;IAEvB,OAAO;WAKM,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA0BxD,OAAO,CAAC,OAAO;IAUf,OAAO,CAAC,KAAK;IAWb,OAAO,CAAC,OAAO;IAoBf,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI;IAoB/B,IAAI,CAAC,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,IAAI,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,UAAU,EAAE;IAW9F,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS;IAK3C,KAAK,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM;IAQpC,KAAK,IAAI,IAAI;IAEb,OAAO,CAAC,OAAO;CAoBhB"}
@@ -1,27 +1,67 @@
1
1
  // src/audit-store.ts
2
- import Database from 'better-sqlite3';
3
- import { chmodSync } from 'node:fs';
2
+ import initSqlJs from 'sql.js';
3
+ import { chmodSync, existsSync, readFileSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
4
+ import { dirname } from 'node:path';
4
5
  export class AuditStore {
5
6
  db;
6
- constructor(dbPath) {
7
- this.db = new Database(dbPath);
8
- this.db.pragma('journal_mode = WAL');
9
- this.db.exec(`CREATE TABLE IF NOT EXISTS audit_events (
7
+ dbPath;
8
+ constructor(db, dbPath) {
9
+ this.db = db;
10
+ this.dbPath = dbPath;
11
+ }
12
+ static async create(dbPath) {
13
+ const SQL = await initSqlJs();
14
+ let db;
15
+ if (dbPath !== ':memory:' && existsSync(dbPath)) {
16
+ const buf = readFileSync(dbPath);
17
+ db = new SQL.Database(buf);
18
+ }
19
+ else {
20
+ db = new SQL.Database();
21
+ }
22
+ db.run(`CREATE TABLE IF NOT EXISTS audit_events (
10
23
  id TEXT PRIMARY KEY, timestamp TEXT NOT NULL, type TEXT NOT NULL,
11
24
  user TEXT NOT NULL, connector TEXT NOT NULL, args TEXT NOT NULL,
12
25
  domains TEXT NOT NULL, capabilities TEXT NOT NULL, row_count INTEGER,
13
26
  columns TEXT, duration_ms INTEGER NOT NULL, error TEXT, denial_reason TEXT
14
27
  )`);
15
- this.migrate();
28
+ const store = new AuditStore(db, dbPath);
29
+ store.migrate();
16
30
  if (dbPath !== ':memory:') {
31
+ store.persist();
17
32
  try {
18
33
  chmodSync(dbPath, 0o600);
19
34
  }
20
35
  catch { /* ignore for read-only fs */ }
21
36
  }
37
+ return store;
38
+ }
39
+ // sql.js requires full-DB export on every write; acceptable for small audit databases.
40
+ // Write to a temp file then atomically rename to prevent corruption on crash.
41
+ persist() {
42
+ if (this.dbPath === ':memory:')
43
+ return;
44
+ const data = this.db.export();
45
+ const dir = dirname(this.dbPath);
46
+ mkdirSync(dir, { recursive: true });
47
+ const tmpPath = this.dbPath + '.tmp';
48
+ writeFileSync(tmpPath, Buffer.from(data));
49
+ renameSync(tmpPath, this.dbPath);
50
+ }
51
+ query(sql, params = []) {
52
+ const results = this.db.exec(sql, params);
53
+ if (results.length === 0)
54
+ return [];
55
+ const { columns, values } = results[0];
56
+ return values.map(row => {
57
+ const obj = {};
58
+ columns.forEach((col, i) => { obj[col] = row[i]; });
59
+ return obj;
60
+ });
22
61
  }
23
62
  migrate() {
24
- const cols = new Set(this.db.pragma('table_info(audit_events)').map(c => c.name));
63
+ const colResults = this.db.exec('PRAGMA table_info(audit_events)');
64
+ const cols = new Set(colResults.length > 0 ? colResults[0].values.map(row => row[1]) : []);
25
65
  const additions = [
26
66
  ['correlation_id', 'TEXT'],
27
67
  ['connector_hash', 'TEXT'],
@@ -32,15 +72,25 @@ export class AuditStore {
32
72
  ];
33
73
  for (const [name, type] of additions) {
34
74
  if (!cols.has(name)) {
35
- this.db.exec(`ALTER TABLE audit_events ADD COLUMN ${name} ${type}`);
75
+ this.db.run(`ALTER TABLE audit_events ADD COLUMN ${name} ${type}`);
36
76
  }
37
77
  }
38
78
  }
39
79
  insert(event) {
40
- this.db.prepare(`INSERT INTO audit_events (id, timestamp, type, user, connector, args, domains,
80
+ this.db.run(`INSERT INTO audit_events (id, timestamp, type, user, connector, args, domains,
41
81
  capabilities, row_count, columns, duration_ms, error, denial_reason,
42
82
  correlation_id, connector_hash, steps, source, previous_value, new_value)
43
- VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`).run(event.id, event.timestamp, event.type, event.user, event.connector, JSON.stringify(event.args), JSON.stringify(event.domains), JSON.stringify(event.capabilities), event.rowCount ?? null, event.columns ? JSON.stringify(event.columns) : null, event.durationMs, event.error ?? null, event.denialReason ?? null, event.correlationId ?? null, event.connectorHash ?? null, event.steps ? JSON.stringify(event.steps) : null, event.source ?? null, event.previousValue ?? null, event.newValue ?? null);
83
+ VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)`, [
84
+ event.id, event.timestamp, event.type, event.user, event.connector,
85
+ JSON.stringify(event.args), JSON.stringify(event.domains),
86
+ JSON.stringify(event.capabilities), event.rowCount ?? null,
87
+ event.columns ? JSON.stringify(event.columns) : null,
88
+ event.durationMs, event.error ?? null, event.denialReason ?? null,
89
+ event.correlationId ?? null, event.connectorHash ?? null,
90
+ event.steps ? JSON.stringify(event.steps) : null,
91
+ event.source ?? null, event.previousValue ?? null, event.newValue ?? null,
92
+ ]);
93
+ this.persist();
44
94
  }
45
95
  list(opts) {
46
96
  let sql = 'SELECT * FROM audit_events WHERE 1=1';
@@ -62,15 +112,19 @@ export class AuditStore {
62
112
  sql += ' LIMIT ?';
63
113
  params.push(opts.limit);
64
114
  }
65
- return this.db.prepare(sql).all(...params).map(r => this.toEvent(r));
115
+ return this.query(sql, params).map(r => this.toEvent(r));
66
116
  }
67
117
  getById(id) {
68
- const row = this.db.prepare('SELECT * FROM audit_events WHERE id = ?').get(id);
69
- return row ? this.toEvent(row) : undefined;
118
+ const rows = this.query('SELECT * FROM audit_events WHERE id = ?', [id]);
119
+ return rows.length > 0 ? this.toEvent(rows[0]) : undefined;
70
120
  }
71
121
  prune(retentionDays) {
72
122
  const cutoff = new Date(Date.now() - retentionDays * 86_400_000).toISOString();
73
- return this.db.prepare('DELETE FROM audit_events WHERE timestamp < ?').run(cutoff).changes;
123
+ this.db.run('DELETE FROM audit_events WHERE timestamp < ?', [cutoff]);
124
+ const changes = this.db.getRowsModified();
125
+ if (changes > 0)
126
+ this.persist();
127
+ return changes;
74
128
  }
75
129
  close() { this.db.close(); }
76
130
  toEvent(r) {
@@ -1 +1 @@
1
- {"version":3,"file":"audit-store.js","sourceRoot":"","sources":["../src/audit-store.ts"],"names":[],"mappings":"AAAA,qBAAqB;AACrB,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAGpC,MAAM,OAAO,UAAU;IACb,EAAE,CAAoB;IAE9B,YAAY,MAAc;QACxB,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;;MAKX,CAAC,CAAC;QACJ,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;YAC1B,IAAI,CAAC;gBAAC,SAAS,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,6BAA6B,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAEO,OAAO;QACb,MAAM,IAAI,GAAG,IAAI,GAAG,CACjB,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,0BAA0B,CAAwB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CACpF,CAAC;QACF,MAAM,SAAS,GAAuB;YACpC,CAAC,gBAAgB,EAAE,MAAM,CAAC;YAC1B,CAAC,gBAAgB,EAAE,MAAM,CAAC;YAC1B,CAAC,OAAO,EAAE,MAAM,CAAC;YACjB,CAAC,QAAQ,EAAE,MAAM,CAAC;YAClB,CAAC,gBAAgB,EAAE,MAAM,CAAC;YAC1B,CAAC,WAAW,EAAE,MAAM,CAAC;SACtB,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,uCAAuC,IAAI,IAAI,IAAI,EAAE,CAAC,CAAC;YACtE,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,KAAiB;QACtB,IAAI,CAAC,EAAE,CAAC,OAAO,CACb;;;sDAGgD,CACjD,CAAC,GAAG,CACH,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,SAAS,EAClE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EACzD,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,EAC1D,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EACpD,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,KAAK,IAAI,IAAI,EAAE,KAAK,CAAC,YAAY,IAAI,IAAI,EACjE,KAAK,CAAC,aAAa,IAAI,IAAI,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI,EACxD,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAChD,KAAK,CAAC,MAAM,IAAI,IAAI,EAAE,KAAK,CAAC,aAAa,IAAI,IAAI,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI,CAC1E,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,IAA0E;QAC7E,IAAI,GAAG,GAAG,sCAAsC,CAAC;QACjD,MAAM,MAAM,GAAc,EAAE,CAAC;QAC7B,IAAI,IAAI,EAAE,SAAS,EAAE,CAAC;YAAC,GAAG,IAAI,uBAAuB,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAAC,CAAC;QACvG,IAAI,IAAI,EAAE,IAAI,EAAE,CAAC;YAAC,GAAG,IAAI,kBAAkB,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;QAAC,CAAC;QACxF,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;YAAC,GAAG,IAAI,qBAAqB,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QAAC,CAAC;QACzF,GAAG,IAAI,0BAA0B,CAAC;QAClC,IAAI,IAAI,EAAE,KAAK,EAAE,CAAC;YAAC,GAAG,IAAI,UAAU,CAAC;YAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAAC,CAAC;QAChE,OAAQ,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAA+B,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;IACtG,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAwC,CAAC;QACtH,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,aAAqB;QACzB,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,aAAa,GAAG,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/E,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,8CAA8C,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;IAC7F,CAAC;IAED,KAAK,KAAW,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAE1B,OAAO,CAAC,CAA0B;QACxC,OAAO;YACL,EAAE,EAAE,CAAC,CAAC,EAAY,EAAE,SAAS,EAAE,CAAC,CAAC,SAAmB;YACpD,IAAI,EAAE,CAAC,CAAC,IAA0B,EAAE,IAAI,EAAE,CAAC,CAAC,IAAc;YAC1D,SAAS,EAAE,CAAC,CAAC,SAAmB;YAChC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAc,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAiB,CAAC;YAC5E,YAAY,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAsB,CAAC;YAClD,QAAQ,EAAE,CAAC,CAAC,SAA+B;YAC3C,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,OAAiB,CAAC,CAAC,CAAC,CAAC,SAAS;YAChE,UAAU,EAAE,CAAC,CAAC,WAAqB;YACnC,KAAK,EAAE,CAAC,CAAC,KAA2B;YACpC,YAAY,EAAE,CAAC,CAAC,aAAmC;YACnD,aAAa,EAAE,CAAC,CAAC,cAAoC;YACrD,aAAa,EAAE,CAAC,CAAC,cAAoC;YACrD,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAe,CAAkB,CAAC,CAAC,CAAC,SAAS;YAC3E,MAAM,EAAE,CAAC,CAAC,MAA4B;YACtC,aAAa,EAAE,CAAC,CAAC,cAAoC;YACrD,QAAQ,EAAE,CAAC,CAAC,SAA+B;SAC5C,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"audit-store.js","sourceRoot":"","sources":["../src/audit-store.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,7 @@ async function main() {
19
19
  console.log(`Session token written to ${tokenPath}`);
20
20
  // Audit store
21
21
  const dbPath = expandHome(config.audit.dbPath);
22
- const auditStore = new AuditStore(dbPath);
22
+ const auditStore = await AuditStore.create(dbPath);
23
23
  const pruned = auditStore.prune(config.audit.retentionDays);
24
24
  if (pruned > 0) {
25
25
  console.log(`Pruned ${pruned} old audit events`);
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
@@ -15,13 +15,12 @@
15
15
  },
16
16
  "dependencies": {
17
17
  "@commandgarden/shared": "*",
18
- "better-sqlite3": "^11.0.0",
18
+ "sql.js": "^1.11.0",
19
19
  "fastify": "^5.0.0",
20
20
  "@fastify/websocket": "^11.0.0",
21
21
  "yaml": "^2.4.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@types/better-sqlite3": "^7.6.0",
25
24
  "@types/node": "^22.0.0",
26
25
  "@types/ws": "^8.5.0",
27
26
  "typescript": "^5.4.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@commandgarden/cli",
3
- "version": "1.1.3",
3
+ "version": "1.1.5",
4
4
  "description": "Enterprise browser automation CLI",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -39,7 +39,7 @@
39
39
  "@commandgarden/shared": "*",
40
40
  "@fastify/static": "^8.0.0",
41
41
  "@fastify/websocket": "^11.0.0",
42
- "better-sqlite3": "^11.0.0",
42
+ "sql.js": "^1.11.0",
43
43
  "cli-table3": "^0.6.0",
44
44
  "commander": "^12.0.0",
45
45
  "fastify": "^5.0.0",