@codedir/mimir-code 0.1.0 → 0.1.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.
@@ -1,852 +1,11 @@
1
1
  #!/usr/bin/env node
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
9
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
10
- }) : x)(function(x) {
11
- if (typeof require !== "undefined") return require.apply(this, arguments);
12
- throw Error('Dynamic require of "' + x + '" is not supported');
13
- });
14
- var __esm = (fn, res) => function __init() {
15
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
16
- };
17
- var __commonJS = (cb, mod) => function __require2() {
18
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
19
- };
20
- var __export = (target, all) => {
21
- for (var name in all)
22
- __defProp(target, name, { get: all[name], enumerable: true });
23
- };
24
- var __copyProps = (to, from, except, desc) => {
25
- if (from && typeof from === "object" || typeof from === "function") {
26
- for (let key of __getOwnPropNames(from))
27
- if (!__hasOwnProp.call(to, key) && key !== except)
28
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
29
- }
30
- return to;
31
- };
32
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
33
- // If the importer is in node compatibility mode or this is not an ESM
34
- // file that has been converted to a CommonJS file using a Babel-
35
- // compatible transform (i.e. "__esModule" has not been set), then set
36
- // "default" to the CommonJS "module.exports" for node compatibility.
37
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
38
- mod
39
- ));
40
-
41
- // node_modules/tsup/assets/esm_shims.js
42
- import path from "path";
43
- import { fileURLToPath } from "url";
44
- var getFilename, __filename;
45
- var init_esm_shims = __esm({
46
- "node_modules/tsup/assets/esm_shims.js"() {
47
- "use strict";
48
- getFilename = () => fileURLToPath(import.meta.url);
49
- __filename = /* @__PURE__ */ getFilename();
50
- }
51
- });
52
-
53
- // node_modules/better-sqlite3/lib/util.js
54
- var require_util = __commonJS({
55
- "node_modules/better-sqlite3/lib/util.js"(exports) {
56
- "use strict";
57
- init_esm_shims();
58
- exports.getBooleanOption = (options, key) => {
59
- let value = false;
60
- if (key in options && typeof (value = options[key]) !== "boolean") {
61
- throw new TypeError(`Expected the "${key}" option to be a boolean`);
62
- }
63
- return value;
64
- };
65
- exports.cppdb = Symbol();
66
- exports.inspect = Symbol.for("nodejs.util.inspect.custom");
67
- }
68
- });
69
-
70
- // node_modules/better-sqlite3/lib/sqlite-error.js
71
- var require_sqlite_error = __commonJS({
72
- "node_modules/better-sqlite3/lib/sqlite-error.js"(exports, module) {
73
- "use strict";
74
- init_esm_shims();
75
- var descriptor = { value: "SqliteError", writable: true, enumerable: false, configurable: true };
76
- function SqliteError(message, code) {
77
- if (new.target !== SqliteError) {
78
- return new SqliteError(message, code);
79
- }
80
- if (typeof code !== "string") {
81
- throw new TypeError("Expected second argument to be a string");
82
- }
83
- Error.call(this, message);
84
- descriptor.value = "" + message;
85
- Object.defineProperty(this, "message", descriptor);
86
- Error.captureStackTrace(this, SqliteError);
87
- this.code = code;
88
- }
89
- Object.setPrototypeOf(SqliteError, Error);
90
- Object.setPrototypeOf(SqliteError.prototype, Error.prototype);
91
- Object.defineProperty(SqliteError.prototype, "name", descriptor);
92
- module.exports = SqliteError;
93
- }
94
- });
95
-
96
- // node_modules/file-uri-to-path/index.js
97
- var require_file_uri_to_path = __commonJS({
98
- "node_modules/file-uri-to-path/index.js"(exports, module) {
99
- "use strict";
100
- init_esm_shims();
101
- var sep = __require("path").sep || "/";
102
- module.exports = fileUriToPath;
103
- function fileUriToPath(uri) {
104
- if ("string" != typeof uri || uri.length <= 7 || "file://" != uri.substring(0, 7)) {
105
- throw new TypeError("must pass in a file:// URI to convert to a file path");
106
- }
107
- var rest = decodeURI(uri.substring(7));
108
- var firstSlash = rest.indexOf("/");
109
- var host = rest.substring(0, firstSlash);
110
- var path9 = rest.substring(firstSlash + 1);
111
- if ("localhost" == host) host = "";
112
- if (host) {
113
- host = sep + sep + host;
114
- }
115
- path9 = path9.replace(/^(.+)\|/, "$1:");
116
- if (sep == "\\") {
117
- path9 = path9.replace(/\//g, "\\");
118
- }
119
- if (/^.+\:/.test(path9)) {
120
- } else {
121
- path9 = sep + path9;
122
- }
123
- return host + path9;
124
- }
125
- }
126
- });
127
-
128
- // node_modules/bindings/bindings.js
129
- var require_bindings = __commonJS({
130
- "node_modules/bindings/bindings.js"(exports, module) {
131
- "use strict";
132
- init_esm_shims();
133
- var fs4 = __require("fs");
134
- var path9 = __require("path");
135
- var fileURLToPath3 = require_file_uri_to_path();
136
- var join = path9.join;
137
- var dirname3 = path9.dirname;
138
- var exists = fs4.accessSync && function(path10) {
139
- try {
140
- fs4.accessSync(path10);
141
- } catch (e) {
142
- return false;
143
- }
144
- return true;
145
- } || fs4.existsSync || path9.existsSync;
146
- var defaults = {
147
- arrow: process.env.NODE_BINDINGS_ARROW || " \u2192 ",
148
- compiled: process.env.NODE_BINDINGS_COMPILED_DIR || "compiled",
149
- platform: process.platform,
150
- arch: process.arch,
151
- nodePreGyp: "node-v" + process.versions.modules + "-" + process.platform + "-" + process.arch,
152
- version: process.versions.node,
153
- bindings: "bindings.node",
154
- try: [
155
- // node-gyp's linked version in the "build" dir
156
- ["module_root", "build", "bindings"],
157
- // node-waf and gyp_addon (a.k.a node-gyp)
158
- ["module_root", "build", "Debug", "bindings"],
159
- ["module_root", "build", "Release", "bindings"],
160
- // Debug files, for development (legacy behavior, remove for node v0.9)
161
- ["module_root", "out", "Debug", "bindings"],
162
- ["module_root", "Debug", "bindings"],
163
- // Release files, but manually compiled (legacy behavior, remove for node v0.9)
164
- ["module_root", "out", "Release", "bindings"],
165
- ["module_root", "Release", "bindings"],
166
- // Legacy from node-waf, node <= 0.4.x
167
- ["module_root", "build", "default", "bindings"],
168
- // Production "Release" buildtype binary (meh...)
169
- ["module_root", "compiled", "version", "platform", "arch", "bindings"],
170
- // node-qbs builds
171
- ["module_root", "addon-build", "release", "install-root", "bindings"],
172
- ["module_root", "addon-build", "debug", "install-root", "bindings"],
173
- ["module_root", "addon-build", "default", "install-root", "bindings"],
174
- // node-pre-gyp path ./lib/binding/{node_abi}-{platform}-{arch}
175
- ["module_root", "lib", "binding", "nodePreGyp", "bindings"]
176
- ]
177
- };
178
- function bindings(opts) {
179
- if (typeof opts == "string") {
180
- opts = { bindings: opts };
181
- } else if (!opts) {
182
- opts = {};
183
- }
184
- Object.keys(defaults).map(function(i2) {
185
- if (!(i2 in opts)) opts[i2] = defaults[i2];
186
- });
187
- if (!opts.module_root) {
188
- opts.module_root = exports.getRoot(exports.getFileName());
189
- }
190
- if (path9.extname(opts.bindings) != ".node") {
191
- opts.bindings += ".node";
192
- }
193
- var requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : __require;
194
- var tries = [], i = 0, l = opts.try.length, n, b, err;
195
- for (; i < l; i++) {
196
- n = join.apply(
197
- null,
198
- opts.try[i].map(function(p) {
199
- return opts[p] || p;
200
- })
201
- );
202
- tries.push(n);
203
- try {
204
- b = opts.path ? requireFunc.resolve(n) : requireFunc(n);
205
- if (!opts.path) {
206
- b.path = n;
207
- }
208
- return b;
209
- } catch (e) {
210
- if (e.code !== "MODULE_NOT_FOUND" && e.code !== "QUALIFIED_PATH_RESOLUTION_FAILED" && !/not find/i.test(e.message)) {
211
- throw e;
212
- }
213
- }
214
- }
215
- err = new Error(
216
- "Could not locate the bindings file. Tried:\n" + tries.map(function(a) {
217
- return opts.arrow + a;
218
- }).join("\n")
219
- );
220
- err.tries = tries;
221
- throw err;
222
- }
223
- module.exports = exports = bindings;
224
- exports.getFileName = function getFileName(calling_file) {
225
- var origPST = Error.prepareStackTrace, origSTL = Error.stackTraceLimit, dummy = {}, fileName;
226
- Error.stackTraceLimit = 10;
227
- Error.prepareStackTrace = function(e, st) {
228
- for (var i = 0, l = st.length; i < l; i++) {
229
- fileName = st[i].getFileName();
230
- if (fileName !== __filename) {
231
- if (calling_file) {
232
- if (fileName !== calling_file) {
233
- return;
234
- }
235
- } else {
236
- return;
237
- }
238
- }
239
- }
240
- };
241
- Error.captureStackTrace(dummy);
242
- dummy.stack;
243
- Error.prepareStackTrace = origPST;
244
- Error.stackTraceLimit = origSTL;
245
- var fileSchema = "file://";
246
- if (fileName.indexOf(fileSchema) === 0) {
247
- fileName = fileURLToPath3(fileName);
248
- }
249
- return fileName;
250
- };
251
- exports.getRoot = function getRoot(file) {
252
- var dir = dirname3(file), prev;
253
- while (true) {
254
- if (dir === ".") {
255
- dir = process.cwd();
256
- }
257
- if (exists(join(dir, "package.json")) || exists(join(dir, "node_modules"))) {
258
- return dir;
259
- }
260
- if (prev === dir) {
261
- throw new Error(
262
- 'Could not find module root given file: "' + file + '". Do you have a `package.json` file? '
263
- );
264
- }
265
- prev = dir;
266
- dir = join(dir, "..");
267
- }
268
- };
269
- }
270
- });
271
-
272
- // node_modules/better-sqlite3/lib/methods/wrappers.js
273
- var require_wrappers = __commonJS({
274
- "node_modules/better-sqlite3/lib/methods/wrappers.js"(exports) {
275
- "use strict";
276
- init_esm_shims();
277
- var { cppdb } = require_util();
278
- exports.prepare = function prepare(sql2) {
279
- return this[cppdb].prepare(sql2, this, false);
280
- };
281
- exports.exec = function exec(sql2) {
282
- this[cppdb].exec(sql2);
283
- return this;
284
- };
285
- exports.close = function close() {
286
- this[cppdb].close();
287
- return this;
288
- };
289
- exports.loadExtension = function loadExtension(...args) {
290
- this[cppdb].loadExtension(...args);
291
- return this;
292
- };
293
- exports.defaultSafeIntegers = function defaultSafeIntegers(...args) {
294
- this[cppdb].defaultSafeIntegers(...args);
295
- return this;
296
- };
297
- exports.unsafeMode = function unsafeMode(...args) {
298
- this[cppdb].unsafeMode(...args);
299
- return this;
300
- };
301
- exports.getters = {
302
- name: {
303
- get: function name() {
304
- return this[cppdb].name;
305
- },
306
- enumerable: true
307
- },
308
- open: {
309
- get: function open() {
310
- return this[cppdb].open;
311
- },
312
- enumerable: true
313
- },
314
- inTransaction: {
315
- get: function inTransaction() {
316
- return this[cppdb].inTransaction;
317
- },
318
- enumerable: true
319
- },
320
- readonly: {
321
- get: function readonly() {
322
- return this[cppdb].readonly;
323
- },
324
- enumerable: true
325
- },
326
- memory: {
327
- get: function memory() {
328
- return this[cppdb].memory;
329
- },
330
- enumerable: true
331
- }
332
- };
333
- }
334
- });
335
-
336
- // node_modules/better-sqlite3/lib/methods/transaction.js
337
- var require_transaction = __commonJS({
338
- "node_modules/better-sqlite3/lib/methods/transaction.js"(exports, module) {
339
- "use strict";
340
- init_esm_shims();
341
- var { cppdb } = require_util();
342
- var controllers = /* @__PURE__ */ new WeakMap();
343
- module.exports = function transaction(fn) {
344
- if (typeof fn !== "function") throw new TypeError("Expected first argument to be a function");
345
- const db = this[cppdb];
346
- const controller = getController(db, this);
347
- const { apply } = Function.prototype;
348
- const properties = {
349
- default: { value: wrapTransaction(apply, fn, db, controller.default) },
350
- deferred: { value: wrapTransaction(apply, fn, db, controller.deferred) },
351
- immediate: { value: wrapTransaction(apply, fn, db, controller.immediate) },
352
- exclusive: { value: wrapTransaction(apply, fn, db, controller.exclusive) },
353
- database: { value: this, enumerable: true }
354
- };
355
- Object.defineProperties(properties.default.value, properties);
356
- Object.defineProperties(properties.deferred.value, properties);
357
- Object.defineProperties(properties.immediate.value, properties);
358
- Object.defineProperties(properties.exclusive.value, properties);
359
- return properties.default.value;
360
- };
361
- var getController = (db, self) => {
362
- let controller = controllers.get(db);
363
- if (!controller) {
364
- const shared = {
365
- commit: db.prepare("COMMIT", self, false),
366
- rollback: db.prepare("ROLLBACK", self, false),
367
- savepoint: db.prepare("SAVEPOINT ` _bs3. `", self, false),
368
- release: db.prepare("RELEASE ` _bs3. `", self, false),
369
- rollbackTo: db.prepare("ROLLBACK TO ` _bs3. `", self, false)
370
- };
371
- controllers.set(db, controller = {
372
- default: Object.assign({ begin: db.prepare("BEGIN", self, false) }, shared),
373
- deferred: Object.assign({ begin: db.prepare("BEGIN DEFERRED", self, false) }, shared),
374
- immediate: Object.assign({ begin: db.prepare("BEGIN IMMEDIATE", self, false) }, shared),
375
- exclusive: Object.assign({ begin: db.prepare("BEGIN EXCLUSIVE", self, false) }, shared)
376
- });
377
- }
378
- return controller;
379
- };
380
- var wrapTransaction = (apply, fn, db, { begin, commit, rollback, savepoint, release, rollbackTo }) => function sqliteTransaction() {
381
- let before, after, undo;
382
- if (db.inTransaction) {
383
- before = savepoint;
384
- after = release;
385
- undo = rollbackTo;
386
- } else {
387
- before = begin;
388
- after = commit;
389
- undo = rollback;
390
- }
391
- before.run();
392
- try {
393
- const result = apply.call(fn, this, arguments);
394
- if (result && typeof result.then === "function") {
395
- throw new TypeError("Transaction function cannot return a promise");
396
- }
397
- after.run();
398
- return result;
399
- } catch (ex) {
400
- if (db.inTransaction) {
401
- undo.run();
402
- if (undo !== rollback) after.run();
403
- }
404
- throw ex;
405
- }
406
- };
407
- }
408
- });
409
-
410
- // node_modules/better-sqlite3/lib/methods/pragma.js
411
- var require_pragma = __commonJS({
412
- "node_modules/better-sqlite3/lib/methods/pragma.js"(exports, module) {
413
- "use strict";
414
- init_esm_shims();
415
- var { getBooleanOption, cppdb } = require_util();
416
- module.exports = function pragma(source, options) {
417
- if (options == null) options = {};
418
- if (typeof source !== "string") throw new TypeError("Expected first argument to be a string");
419
- if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
420
- const simple = getBooleanOption(options, "simple");
421
- const stmt = this[cppdb].prepare(`PRAGMA ${source}`, this, true);
422
- return simple ? stmt.pluck().get() : stmt.all();
423
- };
424
- }
425
- });
426
-
427
- // node_modules/better-sqlite3/lib/methods/backup.js
428
- var require_backup = __commonJS({
429
- "node_modules/better-sqlite3/lib/methods/backup.js"(exports, module) {
430
- "use strict";
431
- init_esm_shims();
432
- var fs4 = __require("fs");
433
- var path9 = __require("path");
434
- var { promisify } = __require("util");
435
- var { cppdb } = require_util();
436
- var fsAccess = promisify(fs4.access);
437
- module.exports = async function backup(filename, options) {
438
- if (options == null) options = {};
439
- if (typeof filename !== "string") throw new TypeError("Expected first argument to be a string");
440
- if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
441
- filename = filename.trim();
442
- const attachedName = "attached" in options ? options.attached : "main";
443
- const handler = "progress" in options ? options.progress : null;
444
- if (!filename) throw new TypeError("Backup filename cannot be an empty string");
445
- if (filename === ":memory:") throw new TypeError('Invalid backup filename ":memory:"');
446
- if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
447
- if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
448
- if (handler != null && typeof handler !== "function") throw new TypeError('Expected the "progress" option to be a function');
449
- await fsAccess(path9.dirname(filename)).catch(() => {
450
- throw new TypeError("Cannot save backup because the directory does not exist");
451
- });
452
- const isNewFile = await fsAccess(filename).then(() => false, () => true);
453
- return runBackup(this[cppdb].backup(this, attachedName, filename, isNewFile), handler || null);
454
- };
455
- var runBackup = (backup, handler) => {
456
- let rate = 0;
457
- let useDefault = true;
458
- return new Promise((resolve, reject) => {
459
- setImmediate(function step() {
460
- try {
461
- const progress = backup.transfer(rate);
462
- if (!progress.remainingPages) {
463
- backup.close();
464
- resolve(progress);
465
- return;
466
- }
467
- if (useDefault) {
468
- useDefault = false;
469
- rate = 100;
470
- }
471
- if (handler) {
472
- const ret = handler(progress);
473
- if (ret !== void 0) {
474
- if (typeof ret === "number" && ret === ret) rate = Math.max(0, Math.min(2147483647, Math.round(ret)));
475
- else throw new TypeError("Expected progress callback to return a number or undefined");
476
- }
477
- }
478
- setImmediate(step);
479
- } catch (err) {
480
- backup.close();
481
- reject(err);
482
- }
483
- });
484
- });
485
- };
486
- }
487
- });
488
-
489
- // node_modules/better-sqlite3/lib/methods/serialize.js
490
- var require_serialize = __commonJS({
491
- "node_modules/better-sqlite3/lib/methods/serialize.js"(exports, module) {
492
- "use strict";
493
- init_esm_shims();
494
- var { cppdb } = require_util();
495
- module.exports = function serialize(options) {
496
- if (options == null) options = {};
497
- if (typeof options !== "object") throw new TypeError("Expected first argument to be an options object");
498
- const attachedName = "attached" in options ? options.attached : "main";
499
- if (typeof attachedName !== "string") throw new TypeError('Expected the "attached" option to be a string');
500
- if (!attachedName) throw new TypeError('The "attached" option cannot be an empty string');
501
- return this[cppdb].serialize(attachedName);
502
- };
503
- }
504
- });
505
-
506
- // node_modules/better-sqlite3/lib/methods/function.js
507
- var require_function = __commonJS({
508
- "node_modules/better-sqlite3/lib/methods/function.js"(exports, module) {
509
- "use strict";
510
- init_esm_shims();
511
- var { getBooleanOption, cppdb } = require_util();
512
- module.exports = function defineFunction(name, options, fn) {
513
- if (options == null) options = {};
514
- if (typeof options === "function") {
515
- fn = options;
516
- options = {};
517
- }
518
- if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
519
- if (typeof fn !== "function") throw new TypeError("Expected last argument to be a function");
520
- if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
521
- if (!name) throw new TypeError("User-defined function name cannot be an empty string");
522
- const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
523
- const deterministic = getBooleanOption(options, "deterministic");
524
- const directOnly = getBooleanOption(options, "directOnly");
525
- const varargs = getBooleanOption(options, "varargs");
526
- let argCount = -1;
527
- if (!varargs) {
528
- argCount = fn.length;
529
- if (!Number.isInteger(argCount) || argCount < 0) throw new TypeError("Expected function.length to be a positive integer");
530
- if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
531
- }
532
- this[cppdb].function(fn, name, argCount, safeIntegers, deterministic, directOnly);
533
- return this;
534
- };
535
- }
536
- });
537
-
538
- // node_modules/better-sqlite3/lib/methods/aggregate.js
539
- var require_aggregate = __commonJS({
540
- "node_modules/better-sqlite3/lib/methods/aggregate.js"(exports, module) {
541
- "use strict";
542
- init_esm_shims();
543
- var { getBooleanOption, cppdb } = require_util();
544
- module.exports = function defineAggregate(name, options) {
545
- if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
546
- if (typeof options !== "object" || options === null) throw new TypeError("Expected second argument to be an options object");
547
- if (!name) throw new TypeError("User-defined function name cannot be an empty string");
548
- const start = "start" in options ? options.start : null;
549
- const step = getFunctionOption(options, "step", true);
550
- const inverse = getFunctionOption(options, "inverse", false);
551
- const result = getFunctionOption(options, "result", false);
552
- const safeIntegers = "safeIntegers" in options ? +getBooleanOption(options, "safeIntegers") : 2;
553
- const deterministic = getBooleanOption(options, "deterministic");
554
- const directOnly = getBooleanOption(options, "directOnly");
555
- const varargs = getBooleanOption(options, "varargs");
556
- let argCount = -1;
557
- if (!varargs) {
558
- argCount = Math.max(getLength(step), inverse ? getLength(inverse) : 0);
559
- if (argCount > 0) argCount -= 1;
560
- if (argCount > 100) throw new RangeError("User-defined functions cannot have more than 100 arguments");
561
- }
562
- this[cppdb].aggregate(start, step, inverse, result, name, argCount, safeIntegers, deterministic, directOnly);
563
- return this;
564
- };
565
- var getFunctionOption = (options, key, required) => {
566
- const value = key in options ? options[key] : null;
567
- if (typeof value === "function") return value;
568
- if (value != null) throw new TypeError(`Expected the "${key}" option to be a function`);
569
- if (required) throw new TypeError(`Missing required option "${key}"`);
570
- return null;
571
- };
572
- var getLength = ({ length }) => {
573
- if (Number.isInteger(length) && length >= 0) return length;
574
- throw new TypeError("Expected function.length to be a positive integer");
575
- };
576
- }
577
- });
578
-
579
- // node_modules/better-sqlite3/lib/methods/table.js
580
- var require_table = __commonJS({
581
- "node_modules/better-sqlite3/lib/methods/table.js"(exports, module) {
582
- "use strict";
583
- init_esm_shims();
584
- var { cppdb } = require_util();
585
- module.exports = function defineTable(name, factory) {
586
- if (typeof name !== "string") throw new TypeError("Expected first argument to be a string");
587
- if (!name) throw new TypeError("Virtual table module name cannot be an empty string");
588
- let eponymous = false;
589
- if (typeof factory === "object" && factory !== null) {
590
- eponymous = true;
591
- factory = defer(parseTableDefinition(factory, "used", name));
592
- } else {
593
- if (typeof factory !== "function") throw new TypeError("Expected second argument to be a function or a table definition object");
594
- factory = wrapFactory(factory);
595
- }
596
- this[cppdb].table(factory, name, eponymous);
597
- return this;
598
- };
599
- function wrapFactory(factory) {
600
- return function virtualTableFactory(moduleName, databaseName, tableName, ...args) {
601
- const thisObject = {
602
- module: moduleName,
603
- database: databaseName,
604
- table: tableName
605
- };
606
- const def = apply.call(factory, thisObject, args);
607
- if (typeof def !== "object" || def === null) {
608
- throw new TypeError(`Virtual table module "${moduleName}" did not return a table definition object`);
609
- }
610
- return parseTableDefinition(def, "returned", moduleName);
611
- };
612
- }
613
- function parseTableDefinition(def, verb, moduleName) {
614
- if (!hasOwnProperty.call(def, "rows")) {
615
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "rows" property`);
616
- }
617
- if (!hasOwnProperty.call(def, "columns")) {
618
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition without a "columns" property`);
619
- }
620
- const rows = def.rows;
621
- if (typeof rows !== "function" || Object.getPrototypeOf(rows) !== GeneratorFunctionPrototype) {
622
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "rows" property (should be a generator function)`);
623
- }
624
- let columns = def.columns;
625
- if (!Array.isArray(columns) || !(columns = [...columns]).every((x) => typeof x === "string")) {
626
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "columns" property (should be an array of strings)`);
627
- }
628
- if (columns.length !== new Set(columns).size) {
629
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate column names`);
630
- }
631
- if (!columns.length) {
632
- throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with zero columns`);
633
- }
634
- let parameters;
635
- if (hasOwnProperty.call(def, "parameters")) {
636
- parameters = def.parameters;
637
- if (!Array.isArray(parameters) || !(parameters = [...parameters]).every((x) => typeof x === "string")) {
638
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "parameters" property (should be an array of strings)`);
639
- }
640
- } else {
641
- parameters = inferParameters(rows);
642
- }
643
- if (parameters.length !== new Set(parameters).size) {
644
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with duplicate parameter names`);
645
- }
646
- if (parameters.length > 32) {
647
- throw new RangeError(`Virtual table module "${moduleName}" ${verb} a table definition with more than the maximum number of 32 parameters`);
648
- }
649
- for (const parameter of parameters) {
650
- if (columns.includes(parameter)) {
651
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with column "${parameter}" which was ambiguously defined as both a column and parameter`);
652
- }
653
- }
654
- let safeIntegers = 2;
655
- if (hasOwnProperty.call(def, "safeIntegers")) {
656
- const bool = def.safeIntegers;
657
- if (typeof bool !== "boolean") {
658
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "safeIntegers" property (should be a boolean)`);
659
- }
660
- safeIntegers = +bool;
661
- }
662
- let directOnly = false;
663
- if (hasOwnProperty.call(def, "directOnly")) {
664
- directOnly = def.directOnly;
665
- if (typeof directOnly !== "boolean") {
666
- throw new TypeError(`Virtual table module "${moduleName}" ${verb} a table definition with an invalid "directOnly" property (should be a boolean)`);
667
- }
668
- }
669
- const columnDefinitions = [
670
- ...parameters.map(identifier).map((str) => `${str} HIDDEN`),
671
- ...columns.map(identifier)
672
- ];
673
- return [
674
- `CREATE TABLE x(${columnDefinitions.join(", ")});`,
675
- wrapGenerator(rows, new Map(columns.map((x, i) => [x, parameters.length + i])), moduleName),
676
- parameters,
677
- safeIntegers,
678
- directOnly
679
- ];
680
- }
681
- function wrapGenerator(generator, columnMap, moduleName) {
682
- return function* virtualTable(...args) {
683
- const output = args.map((x) => Buffer.isBuffer(x) ? Buffer.from(x) : x);
684
- for (let i = 0; i < columnMap.size; ++i) {
685
- output.push(null);
686
- }
687
- for (const row of generator(...args)) {
688
- if (Array.isArray(row)) {
689
- extractRowArray(row, output, columnMap.size, moduleName);
690
- yield output;
691
- } else if (typeof row === "object" && row !== null) {
692
- extractRowObject(row, output, columnMap, moduleName);
693
- yield output;
694
- } else {
695
- throw new TypeError(`Virtual table module "${moduleName}" yielded something that isn't a valid row object`);
696
- }
697
- }
698
- };
699
- }
700
- function extractRowArray(row, output, columnCount, moduleName) {
701
- if (row.length !== columnCount) {
702
- throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an incorrect number of columns`);
703
- }
704
- const offset = output.length - columnCount;
705
- for (let i = 0; i < columnCount; ++i) {
706
- output[i + offset] = row[i];
707
- }
708
- }
709
- function extractRowObject(row, output, columnMap, moduleName) {
710
- let count = 0;
711
- for (const key of Object.keys(row)) {
712
- const index2 = columnMap.get(key);
713
- if (index2 === void 0) {
714
- throw new TypeError(`Virtual table module "${moduleName}" yielded a row with an undeclared column "${key}"`);
715
- }
716
- output[index2] = row[key];
717
- count += 1;
718
- }
719
- if (count !== columnMap.size) {
720
- throw new TypeError(`Virtual table module "${moduleName}" yielded a row with missing columns`);
721
- }
722
- }
723
- function inferParameters({ length }) {
724
- if (!Number.isInteger(length) || length < 0) {
725
- throw new TypeError("Expected function.length to be a positive integer");
726
- }
727
- const params = [];
728
- for (let i = 0; i < length; ++i) {
729
- params.push(`$${i + 1}`);
730
- }
731
- return params;
732
- }
733
- var { hasOwnProperty } = Object.prototype;
734
- var { apply } = Function.prototype;
735
- var GeneratorFunctionPrototype = Object.getPrototypeOf(function* () {
736
- });
737
- var identifier = (str) => `"${str.replace(/"/g, '""')}"`;
738
- var defer = (x) => () => x;
739
- }
740
- });
741
-
742
- // node_modules/better-sqlite3/lib/methods/inspect.js
743
- var require_inspect = __commonJS({
744
- "node_modules/better-sqlite3/lib/methods/inspect.js"(exports, module) {
745
- "use strict";
746
- init_esm_shims();
747
- var DatabaseInspection = function Database2() {
748
- };
749
- module.exports = function inspect(depth, opts) {
750
- return Object.assign(new DatabaseInspection(), this);
751
- };
752
- }
753
- });
754
-
755
- // node_modules/better-sqlite3/lib/database.js
756
- var require_database = __commonJS({
757
- "node_modules/better-sqlite3/lib/database.js"(exports, module) {
758
- "use strict";
759
- init_esm_shims();
760
- var fs4 = __require("fs");
761
- var path9 = __require("path");
762
- var util = require_util();
763
- var SqliteError = require_sqlite_error();
764
- var DEFAULT_ADDON;
765
- function Database2(filenameGiven, options) {
766
- if (new.target == null) {
767
- return new Database2(filenameGiven, options);
768
- }
769
- let buffer;
770
- if (Buffer.isBuffer(filenameGiven)) {
771
- buffer = filenameGiven;
772
- filenameGiven = ":memory:";
773
- }
774
- if (filenameGiven == null) filenameGiven = "";
775
- if (options == null) options = {};
776
- if (typeof filenameGiven !== "string") throw new TypeError("Expected first argument to be a string");
777
- if (typeof options !== "object") throw new TypeError("Expected second argument to be an options object");
778
- if ("readOnly" in options) throw new TypeError('Misspelled option "readOnly" should be "readonly"');
779
- if ("memory" in options) throw new TypeError('Option "memory" was removed in v7.0.0 (use ":memory:" filename instead)');
780
- const filename = filenameGiven.trim();
781
- const anonymous = filename === "" || filename === ":memory:";
782
- const readonly = util.getBooleanOption(options, "readonly");
783
- const fileMustExist = util.getBooleanOption(options, "fileMustExist");
784
- const timeout = "timeout" in options ? options.timeout : 5e3;
785
- const verbose = "verbose" in options ? options.verbose : null;
786
- const nativeBinding = "nativeBinding" in options ? options.nativeBinding : null;
787
- if (readonly && anonymous && !buffer) throw new TypeError("In-memory/temporary databases cannot be readonly");
788
- if (!Number.isInteger(timeout) || timeout < 0) throw new TypeError('Expected the "timeout" option to be a positive integer');
789
- if (timeout > 2147483647) throw new RangeError('Option "timeout" cannot be greater than 2147483647');
790
- if (verbose != null && typeof verbose !== "function") throw new TypeError('Expected the "verbose" option to be a function');
791
- if (nativeBinding != null && typeof nativeBinding !== "string" && typeof nativeBinding !== "object") throw new TypeError('Expected the "nativeBinding" option to be a string or addon object');
792
- let addon;
793
- if (nativeBinding == null) {
794
- addon = DEFAULT_ADDON || (DEFAULT_ADDON = require_bindings()("better_sqlite3.node"));
795
- } else if (typeof nativeBinding === "string") {
796
- const requireFunc = typeof __non_webpack_require__ === "function" ? __non_webpack_require__ : __require;
797
- addon = requireFunc(path9.resolve(nativeBinding).replace(/(\.node)?$/, ".node"));
798
- } else {
799
- addon = nativeBinding;
800
- }
801
- if (!addon.isInitialized) {
802
- addon.setErrorConstructor(SqliteError);
803
- addon.isInitialized = true;
804
- }
805
- if (!anonymous && !fs4.existsSync(path9.dirname(filename))) {
806
- throw new TypeError("Cannot open database because the directory does not exist");
807
- }
808
- Object.defineProperties(this, {
809
- [util.cppdb]: { value: new addon.Database(filename, filenameGiven, anonymous, readonly, fileMustExist, timeout, verbose || null, buffer || null) },
810
- ...wrappers.getters
811
- });
812
- }
813
- var wrappers = require_wrappers();
814
- Database2.prototype.prepare = wrappers.prepare;
815
- Database2.prototype.transaction = require_transaction();
816
- Database2.prototype.pragma = require_pragma();
817
- Database2.prototype.backup = require_backup();
818
- Database2.prototype.serialize = require_serialize();
819
- Database2.prototype.function = require_function();
820
- Database2.prototype.aggregate = require_aggregate();
821
- Database2.prototype.table = require_table();
822
- Database2.prototype.loadExtension = wrappers.loadExtension;
823
- Database2.prototype.exec = wrappers.exec;
824
- Database2.prototype.close = wrappers.close;
825
- Database2.prototype.defaultSafeIntegers = wrappers.defaultSafeIntegers;
826
- Database2.prototype.unsafeMode = wrappers.unsafeMode;
827
- Database2.prototype[util.inspect] = require_inspect();
828
- module.exports = Database2;
829
- }
830
- });
831
-
832
- // node_modules/better-sqlite3/lib/index.js
833
- var require_lib = __commonJS({
834
- "node_modules/better-sqlite3/lib/index.js"(exports, module) {
835
- "use strict";
836
- init_esm_shims();
837
- module.exports = require_database();
838
- module.exports.SqliteError = require_sqlite_error();
839
- }
840
- });
841
2
 
842
3
  // src/cli.ts
843
- init_esm_shims();
844
4
  import { Command } from "commander";
845
5
 
846
6
  // src/platform/FileSystemAdapter.ts
847
- init_esm_shims();
848
7
  import fs from "fs/promises";
849
- import { globby } from "globby";
8
+ import fg from "fast-glob";
850
9
  var FileSystemAdapter = class {
851
10
  async readFile(path9, encoding = "utf-8") {
852
11
  return fs.readFile(path9, encoding);
@@ -887,18 +46,102 @@ var FileSystemAdapter = class {
887
46
  await fs.copyFile(src, dest);
888
47
  }
889
48
  async glob(pattern, options) {
890
- return globby(pattern, {
49
+ return fg(pattern, {
891
50
  cwd: options?.cwd,
892
51
  ignore: options?.ignore
893
52
  });
894
53
  }
895
54
  };
896
55
 
897
- // src/config/ConfigLoader.ts
898
- init_esm_shims();
56
+ // src/platform/ProcessExecutorAdapter.ts
57
+ import { execa, execaCommand } from "execa";
58
+ var ProcessExecutorAdapter = class {
59
+ /**
60
+ * Execute command and wait for completion
61
+ */
62
+ async execute(command, args = [], options = {}) {
63
+ try {
64
+ const result = await execa(command, args, {
65
+ cwd: options.cwd,
66
+ env: options.env,
67
+ timeout: options.timeout,
68
+ shell: options.shell,
69
+ input: options.input,
70
+ reject: false
71
+ // Don't throw on non-zero exit codes
72
+ });
73
+ return {
74
+ stdout: result.stdout,
75
+ stderr: result.stderr,
76
+ exitCode: result.exitCode ?? (result.failed ? 1 : 0),
77
+ command: result.command,
78
+ timedOut: result.timedOut ?? false
79
+ };
80
+ } catch (error) {
81
+ const exitCode = error.code === "ENOENT" ? 127 : error.exitCode || 1;
82
+ return {
83
+ stdout: error.stdout || "",
84
+ stderr: error.stderr || error.message || String(error),
85
+ exitCode,
86
+ command: error.command || `${command} ${args.join(" ")}`,
87
+ timedOut: error.timedOut ?? false
88
+ };
89
+ }
90
+ }
91
+ /**
92
+ * Spawn process (doesn't wait for completion)
93
+ */
94
+ spawn(command, args = [], options = {}) {
95
+ const subprocess = execa(command, args, {
96
+ cwd: options.cwd,
97
+ env: options.env,
98
+ timeout: options.timeout,
99
+ shell: options.shell,
100
+ stdin: options.input ? "pipe" : "inherit",
101
+ stdout: "pipe",
102
+ stderr: "pipe"
103
+ });
104
+ if (options.input && subprocess.stdin) {
105
+ subprocess.stdin.write(options.input);
106
+ subprocess.stdin.end();
107
+ }
108
+ return subprocess;
109
+ }
110
+ /**
111
+ * Execute command in shell
112
+ */
113
+ async executeShell(command, options = {}) {
114
+ try {
115
+ const result = await execaCommand(command, {
116
+ cwd: options.cwd,
117
+ env: options.env,
118
+ timeout: options.timeout,
119
+ shell: true,
120
+ input: options.input,
121
+ reject: false
122
+ // Don't throw on non-zero exit codes
123
+ });
124
+ return {
125
+ stdout: result.stdout,
126
+ stderr: result.stderr,
127
+ exitCode: result.exitCode ?? (result.failed ? 1 : 0),
128
+ command: result.command,
129
+ timedOut: result.timedOut ?? false
130
+ };
131
+ } catch (error) {
132
+ const exitCode = error.code === "ENOENT" ? 127 : error.exitCode || 1;
133
+ return {
134
+ stdout: error.stdout || "",
135
+ stderr: error.stderr || error.message || String(error),
136
+ exitCode,
137
+ command: error.command || command,
138
+ timedOut: error.timedOut ?? false
139
+ };
140
+ }
141
+ }
142
+ };
899
143
 
900
144
  // src/config/schemas.ts
901
- init_esm_shims();
902
145
  import { z } from "zod";
903
146
  var ThemeSchema = z.enum([
904
147
  "mimir",
@@ -994,21 +237,17 @@ var ConfigSchema = z.object({
994
237
  rateLimit: RateLimitConfigSchema
995
238
  });
996
239
 
997
- // src/config/AllowlistLoader.ts
998
- init_esm_shims();
999
-
1000
240
  // src/utils/logger.ts
1001
- init_esm_shims();
1002
241
  import winston from "winston";
1003
242
  import DailyRotateFile from "winston-daily-rotate-file";
1004
243
  import fs2 from "fs";
1005
- import path2 from "path";
244
+ import path from "path";
1006
245
  var Logger = class {
1007
246
  logger;
1008
247
  fileLoggingEnabled = false;
1009
248
  consoleTransport;
1010
249
  constructor(logDir = ".mimir/logs") {
1011
- const absoluteLogDir = path2.resolve(process.cwd(), logDir);
250
+ const absoluteLogDir = path.resolve(process.cwd(), logDir);
1012
251
  try {
1013
252
  if (!fs2.existsSync(absoluteLogDir)) {
1014
253
  fs2.mkdirSync(absoluteLogDir, { recursive: true });
@@ -1094,7 +333,7 @@ var logger = new Logger();
1094
333
 
1095
334
  // src/config/AllowlistLoader.ts
1096
335
  import yaml from "yaml";
1097
- import path3 from "path";
336
+ import path2 from "path";
1098
337
  import { z as z2 } from "zod";
1099
338
  var AllowlistSchema = z2.object({
1100
339
  // Command patterns that are always allowed
@@ -1116,7 +355,7 @@ var AllowlistLoader = class {
1116
355
  * Load allowlist from project .mimir/allowlist.yml
1117
356
  */
1118
357
  async loadProjectAllowlist(projectRoot) {
1119
- const allowlistPath = path3.join(projectRoot, ".mimir", "allowlist.yml");
358
+ const allowlistPath = path2.join(projectRoot, ".mimir", "allowlist.yml");
1120
359
  return await this.loadAllowlistFile(allowlistPath, "project");
1121
360
  }
1122
361
  /**
@@ -1124,7 +363,7 @@ var AllowlistLoader = class {
1124
363
  */
1125
364
  async loadGlobalAllowlist() {
1126
365
  const homeDir = process.env.HOME || process.env.USERPROFILE || "~";
1127
- const allowlistPath = path3.join(homeDir, ".mimir", "allowlist.yml");
366
+ const allowlistPath = path2.join(homeDir, ".mimir", "allowlist.yml");
1128
367
  return await this.loadAllowlistFile(allowlistPath, "global");
1129
368
  }
1130
369
  /**
@@ -1188,7 +427,7 @@ var AllowlistLoader = class {
1188
427
  async createExample(filePath, scope) {
1189
428
  const exampleContent = scope === "global" ? this.getGlobalExample() : this.getProjectExample();
1190
429
  try {
1191
- const dir = path3.dirname(filePath);
430
+ const dir = path2.dirname(filePath);
1192
431
  if (!await this.fs.exists(dir)) {
1193
432
  await this.fs.mkdir(dir, { recursive: true });
1194
433
  }
@@ -1294,7 +533,7 @@ envVars:
1294
533
 
1295
534
  // src/config/ConfigLoader.ts
1296
535
  import yaml2 from "yaml";
1297
- import path4 from "path";
536
+ import path3 from "path";
1298
537
  import os from "os";
1299
538
  import dotenv from "dotenv";
1300
539
  var ConfigLoader = class {
@@ -1414,7 +653,7 @@ var ConfigLoader = class {
1414
653
  }
1415
654
  async loadGlobalConfig() {
1416
655
  try {
1417
- const configPath = path4.join(os.homedir(), ".mimir", "config.yml");
656
+ const configPath = path3.join(os.homedir(), ".mimir", "config.yml");
1418
657
  if (!await this.fs.exists(configPath)) {
1419
658
  return null;
1420
659
  }
@@ -1427,7 +666,7 @@ var ConfigLoader = class {
1427
666
  }
1428
667
  async loadProjectConfig(projectRoot) {
1429
668
  try {
1430
- const configPath = path4.join(projectRoot, ".mimir", "config.yml");
669
+ const configPath = path3.join(projectRoot, ".mimir", "config.yml");
1431
670
  if (!await this.fs.exists(configPath)) {
1432
671
  return null;
1433
672
  }
@@ -1440,7 +679,7 @@ var ConfigLoader = class {
1440
679
  }
1441
680
  loadEnvConfig(projectRoot) {
1442
681
  try {
1443
- const envPath = projectRoot ? path4.join(projectRoot, ".env") : ".env";
682
+ const envPath = projectRoot ? path3.join(projectRoot, ".env") : ".env";
1444
683
  dotenv.config({ path: envPath });
1445
684
  const envConfig = {};
1446
685
  if (process.env.DEEPSEEK_API_KEY || process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY) {
@@ -1483,8 +722,8 @@ var ConfigLoader = class {
1483
722
  };
1484
723
  }
1485
724
  async save(config, scope, projectRoot) {
1486
- const configPath = scope === "global" ? path4.join(os.homedir(), ".mimir", "config.yml") : path4.join(projectRoot || process.cwd(), ".mimir", "config.yml");
1487
- const configDir = path4.dirname(configPath);
725
+ const configPath = scope === "global" ? path3.join(os.homedir(), ".mimir", "config.yml") : path3.join(projectRoot || process.cwd(), ".mimir", "config.yml");
726
+ const configDir = path3.dirname(configPath);
1488
727
  if (!await this.fs.exists(configDir)) {
1489
728
  await this.fs.mkdir(configDir, { recursive: true });
1490
729
  }
@@ -1498,8 +737,7 @@ var ConfigLoader = class {
1498
737
  };
1499
738
 
1500
739
  // src/cli/utils/firstRunDetector.ts
1501
- init_esm_shims();
1502
- import path5 from "path";
740
+ import path4 from "path";
1503
741
  import os2 from "os";
1504
742
  var FirstRunDetector = class {
1505
743
  constructor(fs4) {
@@ -1512,35 +750,30 @@ var FirstRunDetector = class {
1512
750
  }
1513
751
  getGlobalConfigPath() {
1514
752
  const homeDir = os2.homedir();
1515
- return path5.join(homeDir, ".mimir", "config.yml");
753
+ return path4.join(homeDir, ".mimir", "config.yml");
1516
754
  }
1517
755
  async getGlobalConfigDir() {
1518
756
  const homeDir = os2.homedir();
1519
- return path5.join(homeDir, ".mimir");
757
+ return path4.join(homeDir, ".mimir");
1520
758
  }
1521
759
  };
1522
760
 
1523
761
  // src/cli/commands/SetupCommand.ts
1524
- init_esm_shims();
1525
762
  import React4 from "react";
1526
763
  import { render } from "ink";
1527
764
 
1528
765
  // src/cli/components/SetupWizard.tsx
1529
- init_esm_shims();
1530
766
  import { useState as useState2 } from "react";
1531
767
  import { Box as Box5 } from "ink";
1532
768
 
1533
769
  // src/cli/components/WizardLayout.tsx
1534
- init_esm_shims();
1535
770
  import { Box as Box2, Text as Text2 } from "ink";
1536
771
 
1537
772
  // src/cli/components/WizardHead.tsx
1538
- init_esm_shims();
1539
773
  import { Box, Text } from "ink";
1540
774
  import chalk from "chalk";
1541
775
 
1542
776
  // src/cli/theme-colors.ts
1543
- init_esm_shims();
1544
777
  var MimirColors = {
1545
778
  // Polar Night (dark backgrounds)
1546
779
  polarNight1: "#2E3440",
@@ -1569,14 +802,13 @@ var MimirColors = {
1569
802
  };
1570
803
 
1571
804
  // src/cli/components/logo.ts
1572
- init_esm_shims();
1573
805
  var MIMIR_LOGO = ["\u2597\u2588\u2597\u2588\u2596", "\u2588\u2588\u2588\u2588\u2588", "\u259C\u2586\u2588\u2586\u259B", " \u2586\u2585\u2586 "];
1574
806
 
1575
807
  // src/cli/components/WizardHead.tsx
1576
808
  import { jsx } from "react/jsx-runtime";
1577
809
  var WizardHead = () => {
1578
810
  const nordFrost = chalk.hex(MimirColors.frost3);
1579
- return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, alignItems: "center", children: MIMIR_LOGO.map((line, index2) => /* @__PURE__ */ jsx(Text, { children: nordFrost.bold(line) }, index2)) });
811
+ return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginBottom: 1, alignItems: "center", children: MIMIR_LOGO.map((line, index) => /* @__PURE__ */ jsx(Text, { children: nordFrost.bold(line) }, index)) });
1580
812
  };
1581
813
 
1582
814
  // src/cli/components/WizardLayout.tsx
@@ -1590,14 +822,12 @@ var WizardLayout = ({ title, children }) => {
1590
822
  };
1591
823
 
1592
824
  // src/cli/components/SecurityWarning.tsx
1593
- init_esm_shims();
1594
825
  import { useMemo } from "react";
1595
826
  import { Box as Box3, Text as Text3, useInput } from "ink";
1596
827
  import figures from "figures";
1597
828
  import chalk2 from "chalk";
1598
829
 
1599
830
  // src/utils/keyboardFormatter.ts
1600
- init_esm_shims();
1601
831
  import os3 from "os";
1602
832
  var KEY_ICONS = {
1603
833
  // Arrow keys
@@ -1665,8 +895,8 @@ function formatSingleShortcut(shortcut, options) {
1665
895
  let normalized = normalizeKeyName(shortcut);
1666
896
  normalized = applyPlatformModifiers(normalized, platform);
1667
897
  const parts = normalized.split("+").map((p) => p.trim());
1668
- const formatted = parts.map((part, index2) => {
1669
- const isModifier = index2 < parts.length - 1;
898
+ const formatted = parts.map((part, index) => {
899
+ const isModifier = index < parts.length - 1;
1670
900
  const icon = KEY_ICONS[part];
1671
901
  if (useIcons && icon) {
1672
902
  if (isModifier && !useModifierIcons) {
@@ -1760,17 +990,12 @@ var SecurityWarning = ({
1760
990
  };
1761
991
 
1762
992
  // src/cli/components/ThemeSelector.tsx
1763
- init_esm_shims();
1764
993
  import { useState, useMemo as useMemo2 } from "react";
1765
994
  import { Box as Box4, Text as Text4 } from "ink";
1766
995
  import SelectInput from "ink-select-input";
1767
996
  import chalk4 from "chalk";
1768
997
 
1769
- // src/config/themes/index.ts
1770
- init_esm_shims();
1771
-
1772
998
  // src/config/themes/theme-schema.ts
1773
- init_esm_shims();
1774
999
  import chalk3 from "chalk";
1775
1000
  function parseColor(color) {
1776
1001
  let result = chalk3;
@@ -2147,7 +1372,6 @@ Object.entries(themeDefinitions).forEach(([key, json]) => {
2147
1372
  });
2148
1373
 
2149
1374
  // src/cli/utils/syntaxHighlight.ts
2150
- init_esm_shims();
2151
1375
  function getPreviewWithDiff() {
2152
1376
  return [
2153
1377
  { type: "remove", line: "function getRandomNumber() {" },
@@ -2178,7 +1402,7 @@ var ThemeSelector = ({
2178
1402
  const themeColors = getTheme(currentThemeKey);
2179
1403
  const preview = getPreviewWithDiff();
2180
1404
  const bg = chalk4.bgHex("#1e1e1e");
2181
- const fg = chalk4.hex("#eceff4");
1405
+ const fg2 = chalk4.hex("#eceff4");
2182
1406
  const footerText = useMemo2(() => {
2183
1407
  const navUp = keyBindings.navigateUp[0] ?? "ArrowUp";
2184
1408
  const navDown = keyBindings.navigateDown[0] ?? "ArrowDown";
@@ -2189,7 +1413,7 @@ var ThemeSelector = ({
2189
1413
  ]);
2190
1414
  }, [keyBindings]);
2191
1415
  return /* @__PURE__ */ jsxs3(Box4, { flexDirection: "column", children: [
2192
- /* @__PURE__ */ jsx4(Text4, { children: bg(fg.bold(" Select your theme: ")) }),
1416
+ /* @__PURE__ */ jsx4(Text4, { children: bg(fg2.bold(" Select your theme: ")) }),
2193
1417
  /* @__PURE__ */ jsx4(Text4, { children: bg(" ") }),
2194
1418
  /* @__PURE__ */ jsx4(Box4, { flexDirection: "column", children: /* @__PURE__ */ jsx4(
2195
1419
  SelectInput,
@@ -2197,18 +1421,18 @@ var ThemeSelector = ({
2197
1421
  items,
2198
1422
  onSelect: (item) => onSelect(item.value),
2199
1423
  onHighlight: (item) => {
2200
- const index2 = availableThemes.findIndex((t) => t === item.value);
2201
- if (index2 !== -1) setHighlightedIndex(index2);
1424
+ const index = availableThemes.findIndex((t) => t === item.value);
1425
+ if (index !== -1) setHighlightedIndex(index);
2202
1426
  }
2203
1427
  }
2204
1428
  ) }),
2205
1429
  /* @__PURE__ */ jsx4(Text4, { children: bg(" ") }),
2206
- /* @__PURE__ */ jsx4(Text4, { children: bg(fg(" Preview: ")) }),
1430
+ /* @__PURE__ */ jsx4(Text4, { children: bg(fg2(" Preview: ")) }),
2207
1431
  preview.map((item, idx) => /* @__PURE__ */ jsxs3(Text4, { children: [
2208
1432
  item.type === "remove" && bg(themeColors.colors.diffRemoveLine(`- ${item.line}`)),
2209
1433
  item.type === "add" && bg(themeColors.colors.diffAddLine(`+ ${item.line}`)),
2210
1434
  item.type === "normal" && bg(
2211
- fg(
1435
+ fg2(
2212
1436
  ` ${themeColors.colors.keyword(item.line.match(/return/)?.[0] || "")}${item.line.replace(/return/, "")}`
2213
1437
  )
2214
1438
  )
@@ -2311,22 +1535,18 @@ var SetupCommand = class {
2311
1535
  };
2312
1536
 
2313
1537
  // src/cli/commands/ChatCommand.ts
2314
- init_esm_shims();
2315
1538
  import React10 from "react";
2316
1539
  import { render as render2 } from "ink";
2317
1540
 
2318
1541
  // src/cli/components/ChatApp.tsx
2319
- init_esm_shims();
2320
1542
  import { useEffect as useEffect7 } from "react";
2321
1543
  import { useStdin } from "ink";
2322
1544
 
2323
1545
  // src/cli/components/ChatInterface.tsx
2324
- init_esm_shims();
2325
1546
  import { useState as useState7, useMemo as useMemo4, useCallback as useCallback2, useRef as useRef2, useEffect as useEffect6 } from "react";
2326
1547
  import { Box as Box11, Text as Text10 } from "ink";
2327
1548
 
2328
1549
  // src/cli/components/MimirHeader.tsx
2329
- init_esm_shims();
2330
1550
  import { Box as Box6, Text as Text5 } from "ink";
2331
1551
  import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
2332
1552
  var MimirHeader = ({
@@ -2349,18 +1569,17 @@ var MimirHeader = ({
2349
1569
  themeDefinition.colors.info(`Theme: ${themeDefinition.name}`)
2350
1570
  ];
2351
1571
  const LOGO_WIDTH = 7;
2352
- return /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", height: MIMIR_LOGO.length, flexShrink: 0, children: MIMIR_LOGO.map((logoLine, index2) => /* @__PURE__ */ jsxs5(Box6, { children: [
1572
+ return /* @__PURE__ */ jsx6(Box6, { flexDirection: "column", height: MIMIR_LOGO.length, flexShrink: 0, children: MIMIR_LOGO.map((logoLine, index) => /* @__PURE__ */ jsxs5(Box6, { children: [
2353
1573
  /* @__PURE__ */ jsx6(Box6, { width: LOGO_WIDTH, children: /* @__PURE__ */ jsx6(Text5, { children: logoColor.bold(logoLine) }) }),
2354
- infoLines[index2] && /* @__PURE__ */ jsx6(Text5, { children: infoLines[index2] })
2355
- ] }, index2)) });
1574
+ infoLines[index] && /* @__PURE__ */ jsx6(Text5, { children: infoLines[index] })
1575
+ ] }, index)) });
2356
1576
  };
2357
1577
 
2358
1578
  // src/cli/components/MessageList.tsx
2359
- init_esm_shims();
2360
1579
  import { Box as Box7, Text as Text6, Static } from "ink";
2361
1580
  import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
2362
1581
  var MessageList = ({
2363
- messages: messages2,
1582
+ messages,
2364
1583
  theme,
2365
1584
  syntaxHighlighting: _syntaxHighlighting
2366
1585
  }) => {
@@ -2412,25 +1631,23 @@ var MessageList = ({
2412
1631
  ")"
2413
1632
  ] }) });
2414
1633
  };
2415
- const renderMessage = (message, index2) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", marginBottom: 1, children: [
1634
+ const renderMessage = (message, index) => /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", marginBottom: 1, children: [
2416
1635
  /* @__PURE__ */ jsx7(Text6, { children: getRoleChalk(message.role).bold(`[${message.role.toUpperCase()}]:`) }),
2417
1636
  /* @__PURE__ */ jsx7(Text6, { children: message.content }),
2418
1637
  message.role === "assistant" && renderThinkingIndicator(message)
2419
- ] }, index2);
1638
+ ] }, index);
2420
1639
  return /* @__PURE__ */ jsxs6(Box7, { flexDirection: "column", paddingX: 1, paddingY: 1, flexGrow: 1, children: [
2421
- messages2.length === 0 && /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "No messages yet. Start typing below..." }),
2422
- messages2.length > 0 && /* @__PURE__ */ jsx7(Static, { items: messages2, children: (message, index2) => renderMessage(message, index2) })
1640
+ messages.length === 0 && /* @__PURE__ */ jsx7(Text6, { dimColor: true, children: "No messages yet. Start typing below..." }),
1641
+ messages.length > 0 && /* @__PURE__ */ jsx7(Static, { items: messages, children: (message, index) => renderMessage(message, index) })
2423
1642
  ] });
2424
1643
  };
2425
1644
 
2426
1645
  // src/cli/components/InputBox.tsx
2427
- init_esm_shims();
2428
1646
  import React6, { useState as useState4, useCallback, useEffect as useEffect2 } from "react";
2429
1647
  import { Box as Box9, Text as Text8 } from "ink";
2430
1648
  import TextInput from "ink-text-input";
2431
1649
 
2432
1650
  // src/core/SlashCommandParser.ts
2433
- init_esm_shims();
2434
1651
  var SlashCommandParser = class {
2435
1652
  static COMMAND_REGEX = /^\/(\w+)(?:\s+(.*))?$/;
2436
1653
  /**
@@ -2484,13 +1701,11 @@ var SlashCommandParser = class {
2484
1701
  };
2485
1702
 
2486
1703
  // src/cli/components/CommandAutocomplete.tsx
2487
- init_esm_shims();
2488
1704
  import React5, { useMemo as useMemo3 } from "react";
2489
1705
  import { Box as Box8, Text as Text7 } from "ink";
2490
1706
  import chalk5 from "chalk";
2491
1707
 
2492
1708
  // src/cli/hooks/useTerminalSize.ts
2493
- init_esm_shims();
2494
1709
  import { useEffect, useState as useState3 } from "react";
2495
1710
  import { useStdout } from "ink";
2496
1711
  var useTerminalSize = () => {
@@ -2559,8 +1774,8 @@ var CommandAutocomplete = ({
2559
1774
  const paramBg = chalk5.bgHex(paramBgHex);
2560
1775
  const { width: terminalWidth } = useTerminalSize();
2561
1776
  const maxAllowedWidth = Math.max(30, terminalWidth - 4);
2562
- const truncateText = (text2, maxLen) => {
2563
- const stripped = text2.replace(/\x1B\[[0-9;]*m/g, "");
1777
+ const truncateText = (text, maxLen) => {
1778
+ const stripped = text.replace(/\x1B\[[0-9;]*m/g, "");
2564
1779
  if (stripped.length <= maxLen) {
2565
1780
  return stripped;
2566
1781
  }
@@ -3085,12 +2300,10 @@ var InputBox = React6.memo(
3085
2300
  InputBox.displayName = "InputBox";
3086
2301
 
3087
2302
  // src/cli/components/Footer.tsx
3088
- init_esm_shims();
3089
2303
  import { useState as useState5, useEffect as useEffect3 } from "react";
3090
2304
  import { Box as Box10, Text as Text9 } from "ink";
3091
2305
 
3092
2306
  // src/cli/components/tips.ts
3093
- init_esm_shims();
3094
2307
  function generateTips(keyBindings) {
3095
2308
  const modeSwitchKey = formatKeyboardShortcut(keyBindings.modeSwitch, { showFirstOnly: true });
3096
2309
  const editKey = formatKeyboardShortcut(keyBindings.editCommand, { showFirstOnly: true });
@@ -3176,11 +2389,7 @@ var Footer = ({
3176
2389
  ] });
3177
2390
  };
3178
2391
 
3179
- // src/cli/keyboard/index.ts
3180
- init_esm_shims();
3181
-
3182
2392
  // src/cli/keyboard/KeyboardEventBus.ts
3183
- init_esm_shims();
3184
2393
  import { EventEmitter } from "events";
3185
2394
  var KeyboardEventBus = class extends EventEmitter {
3186
2395
  constructor(bindingsManager) {
@@ -3224,9 +2433,9 @@ var KeyboardEventBus = class extends EventEmitter {
3224
2433
  return () => {
3225
2434
  const handlers2 = this.handlers.get(action);
3226
2435
  if (handlers2) {
3227
- const index2 = handlers2.findIndex((h) => h.id === handlerObj.id);
3228
- if (index2 !== -1) {
3229
- handlers2.splice(index2, 1);
2436
+ const index = handlers2.findIndex((h) => h.id === handlerObj.id);
2437
+ if (index !== -1) {
2438
+ handlers2.splice(index, 1);
3230
2439
  }
3231
2440
  }
3232
2441
  };
@@ -3309,11 +2518,9 @@ var KeyboardEventBus = class extends EventEmitter {
3309
2518
  };
3310
2519
 
3311
2520
  // src/cli/keyboard/KeyboardContext.tsx
3312
- init_esm_shims();
3313
2521
  import { createContext, useContext, useEffect as useEffect4, useState as useState6 } from "react";
3314
2522
 
3315
2523
  // src/utils/KeyBindings.ts
3316
- init_esm_shims();
3317
2524
  import os4 from "os";
3318
2525
  var KeyBindingsManager = class _KeyBindingsManager {
3319
2526
  constructor(config) {
@@ -3523,7 +2730,6 @@ function useKeyboard() {
3523
2730
  }
3524
2731
 
3525
2732
  // src/cli/keyboard/useKeyboardAction.ts
3526
- init_esm_shims();
3527
2733
  import { useEffect as useEffect5, useRef } from "react";
3528
2734
  function useKeyboardAction(action, handler, options = {}) {
3529
2735
  const { eventBus } = useKeyboard();
@@ -3546,7 +2752,6 @@ function useKeyboardAction(action, handler, options = {}) {
3546
2752
  }
3547
2753
 
3548
2754
  // src/cli/keyboard/useKeyboardInput.ts
3549
- init_esm_shims();
3550
2755
  import { useInput as useInput2 } from "ink";
3551
2756
  var CONTROL_CHAR_MAP = {
3552
2757
  0: "Space",
@@ -3641,7 +2846,7 @@ function useKeyboardInput(options = {}) {
3641
2846
  import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
3642
2847
  var ChatInterface = ({
3643
2848
  config,
3644
- messages: messages2,
2849
+ messages,
3645
2850
  onUserInput,
3646
2851
  onExit,
3647
2852
  currentMode,
@@ -3831,9 +3036,9 @@ var ChatInterface = ({
3831
3036
  currentMode: mode,
3832
3037
  currentProvider: config.llm.provider,
3833
3038
  currentModel: config.llm.model,
3834
- messageCount: messages2.length
3039
+ messageCount: messages.length
3835
3040
  }),
3836
- [mode, config.llm.provider, config.llm.model, messages2.length]
3041
+ [mode, config.llm.provider, config.llm.model, messages.length]
3837
3042
  );
3838
3043
  const fixedUIHeight = 8;
3839
3044
  const minMessageLines = 3;
@@ -3866,7 +3071,7 @@ var ChatInterface = ({
3866
3071
  /* @__PURE__ */ jsx12(Box11, { height: messageAreaHeight, children: /* @__PURE__ */ jsx12(
3867
3072
  MessageList,
3868
3073
  {
3869
- messages: messages2,
3074
+ messages,
3870
3075
  theme: config.ui.theme,
3871
3076
  syntaxHighlighting: config.ui.syntaxHighlighting
3872
3077
  }
@@ -3941,7 +3146,6 @@ function ChatApp({ fs: fs4, projectRoot, ...chatProps }) {
3941
3146
  }
3942
3147
 
3943
3148
  // src/core/SlashCommand.ts
3944
- init_esm_shims();
3945
3149
  var SlashCommandRegistry = class {
3946
3150
  commands = /* @__PURE__ */ new Map();
3947
3151
  aliases = /* @__PURE__ */ new Map();
@@ -4006,10 +3210,9 @@ var SlashCommandRegistry = class {
4006
3210
  };
4007
3211
 
4008
3212
  // src/core/CustomCommandLoader.ts
4009
- init_esm_shims();
4010
3213
  import { z as z3 } from "zod";
4011
3214
  import yaml3 from "yaml";
4012
- import path6 from "path";
3215
+ import path5 from "path";
4013
3216
  import os5 from "os";
4014
3217
  var CustomCommandSchema = z3.object({
4015
3218
  name: z3.string().regex(/^[a-z][a-z0-9-]*$/, "Command name must be lowercase alphanumeric with hyphens"),
@@ -4036,8 +3239,8 @@ var CustomCommand = class {
4036
3239
  }
4037
3240
  async execute(args, context) {
4038
3241
  let prompt = this.definition.prompt;
4039
- args.forEach((arg, index2) => {
4040
- const placeholder = `$${index2 + 1}`;
3242
+ args.forEach((arg, index) => {
3243
+ const placeholder = `$${index + 1}`;
4041
3244
  prompt = prompt.replace(new RegExp(`\\${placeholder}`, "g"), arg);
4042
3245
  });
4043
3246
  const allArgs = args.join(" ");
@@ -4066,12 +3269,12 @@ var CustomCommandLoader = class {
4066
3269
  async loadAll(projectRoot) {
4067
3270
  const commandMap = /* @__PURE__ */ new Map();
4068
3271
  const globalCommands = await this.loadFromDirectory(
4069
- path6.join(os5.homedir(), ".mimir", "commands")
3272
+ path5.join(os5.homedir(), ".mimir", "commands")
4070
3273
  );
4071
3274
  globalCommands.forEach((cmd) => commandMap.set(cmd.name, cmd));
4072
3275
  if (projectRoot) {
4073
3276
  const projectCommands = await this.loadFromDirectory(
4074
- path6.join(projectRoot, ".mimir", "commands")
3277
+ path5.join(projectRoot, ".mimir", "commands")
4075
3278
  );
4076
3279
  projectCommands.forEach((cmd) => {
4077
3280
  if (commandMap.has(cmd.name)) {
@@ -4093,7 +3296,7 @@ var CustomCommandLoader = class {
4093
3296
  }
4094
3297
  const files = await this.fs.glob("*.yml", { cwd: dirPath });
4095
3298
  for (const file of files) {
4096
- const fullPath = path6.join(dirPath, file);
3299
+ const fullPath = path5.join(dirPath, file);
4097
3300
  const command = await this.loadCommand(fullPath);
4098
3301
  if (command) {
4099
3302
  commands.push(command);
@@ -4147,7 +3350,6 @@ var CustomCommandLoader = class {
4147
3350
  };
4148
3351
 
4149
3352
  // src/cli/utils/signalHandler.ts
4150
- init_esm_shims();
4151
3353
  var SignalHandler = class {
4152
3354
  sigintCount = 0;
4153
3355
  cleanupTimeout = null;
@@ -4308,11 +3510,7 @@ function installSignalHandlers(options = {}) {
4308
3510
  return handler;
4309
3511
  }
4310
3512
 
4311
- // src/cli/commands/slashCommands/index.ts
4312
- init_esm_shims();
4313
-
4314
3513
  // src/cli/commands/slashCommands/NewCommand.ts
4315
- init_esm_shims();
4316
3514
  var NewCommand = class {
4317
3515
  name = "new";
4318
3516
  description = "Start a new chat conversation";
@@ -4334,7 +3532,6 @@ var NewCommand = class {
4334
3532
  };
4335
3533
 
4336
3534
  // src/cli/commands/slashCommands/ModelCommand.ts
4337
- init_esm_shims();
4338
3535
  import { z as z4 } from "zod";
4339
3536
  var ModelCommand = class {
4340
3537
  name = "model";
@@ -4405,7 +3602,6 @@ var ModelCommand = class {
4405
3602
  };
4406
3603
 
4407
3604
  // src/cli/commands/slashCommands/ModeCommand.ts
4408
- init_esm_shims();
4409
3605
  import { z as z5 } from "zod";
4410
3606
  var ModeCommand = class {
4411
3607
  name = "mode";
@@ -4450,7 +3646,6 @@ var ModeCommand = class {
4450
3646
  };
4451
3647
 
4452
3648
  // src/cli/commands/slashCommands/HelpCommand.ts
4453
- init_esm_shims();
4454
3649
  var HelpCommand = class {
4455
3650
  constructor(registry) {
4456
3651
  this.registry = registry;
@@ -4508,7 +3703,6 @@ var HelpCommand = class {
4508
3703
  };
4509
3704
 
4510
3705
  // src/cli/commands/slashCommands/ThemeCommand.ts
4511
- init_esm_shims();
4512
3706
  var ThemeCommand = class {
4513
3707
  name = "theme";
4514
3708
  description = "Show available themes or change to specified theme";
@@ -4574,250 +3768,10 @@ Use /theme <name> to switch (e.g., /theme dark)`;
4574
3768
  }
4575
3769
  };
4576
3770
 
4577
- // src/core/MimirInitializer.ts
4578
- init_esm_shims();
4579
-
4580
3771
  // src/storage/Database.ts
4581
- init_esm_shims();
4582
- var import_better_sqlite3 = __toESM(require_lib(), 1);
4583
- import { drizzle } from "drizzle-orm/better-sqlite3";
4584
- import { migrate } from "drizzle-orm/better-sqlite3/migrator";
4585
-
4586
- // src/storage/schema.ts
4587
- var schema_exports = {};
4588
- __export(schema_exports, {
4589
- checkpoints: () => checkpoints,
4590
- conversations: () => conversations,
4591
- costSummary: () => costSummary,
4592
- messages: () => messages,
4593
- metrics: () => metrics,
4594
- migrations: () => migrations,
4595
- permissions: () => permissions,
4596
- pricing: () => pricing,
4597
- sessionState: () => sessionState,
4598
- toolCalls: () => toolCalls
4599
- });
4600
- init_esm_shims();
4601
- import { sqliteTable, text, integer, real, index, uniqueIndex } from "drizzle-orm/sqlite-core";
4602
- import { sql } from "drizzle-orm";
4603
- var migrations = sqliteTable("migrations", {
4604
- id: integer("id").primaryKey({ autoIncrement: true }),
4605
- version: text("version").notNull().unique(),
4606
- appliedAt: integer("applied_at", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`)
4607
- });
4608
- var conversations = sqliteTable(
4609
- "conversations",
4610
- {
4611
- id: text("id").primaryKey(),
4612
- title: text("title"),
4613
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`),
4614
- updatedAt: integer("updated_at", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`),
4615
- totalTokens: integer("total_tokens").default(0),
4616
- totalCost: real("total_cost").default(0),
4617
- provider: text("provider"),
4618
- model: text("model"),
4619
- status: text("status", { enum: ["active", "archived", "deleted"] }).default("active")
4620
- },
4621
- (table) => ({
4622
- createdAtIdx: index("idx_conversations_created_at").on(table.createdAt),
4623
- statusIdx: index("idx_conversations_status").on(table.status)
4624
- })
4625
- );
4626
- var messages = sqliteTable(
4627
- "messages",
4628
- {
4629
- id: text("id").primaryKey(),
4630
- conversationId: text("conversation_id").notNull().references(() => conversations.id, { onDelete: "cascade" }),
4631
- role: text("role", { enum: ["system", "user", "assistant"] }).notNull(),
4632
- content: text("content").notNull(),
4633
- timestamp: integer("timestamp", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`),
4634
- inputTokens: integer("input_tokens").default(0),
4635
- outputTokens: integer("output_tokens").default(0),
4636
- cost: real("cost").default(0),
4637
- metadata: text("metadata")
4638
- // JSON string
4639
- },
4640
- (table) => ({
4641
- conversationIdIdx: index("idx_messages_conversation_id").on(table.conversationId),
4642
- timestampIdx: index("idx_messages_timestamp").on(table.timestamp)
4643
- })
4644
- );
4645
- var toolCalls = sqliteTable(
4646
- "tool_calls",
4647
- {
4648
- id: text("id").primaryKey(),
4649
- conversationId: text("conversation_id").notNull().references(() => conversations.id, { onDelete: "cascade" }),
4650
- messageId: text("message_id").references(() => messages.id, { onDelete: "set null" }),
4651
- toolName: text("tool_name").notNull(),
4652
- arguments: text("arguments").notNull(),
4653
- // JSON string
4654
- result: text("result"),
4655
- // JSON string
4656
- status: text("status", { enum: ["pending", "running", "success", "failed"] }).default(
4657
- "pending"
4658
- ),
4659
- error: text("error"),
4660
- startedAt: integer("started_at", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`),
4661
- completedAt: integer("completed_at", { mode: "timestamp" }),
4662
- durationMs: integer("duration_ms")
4663
- },
4664
- (table) => ({
4665
- conversationIdIdx: index("idx_tool_calls_conversation_id").on(table.conversationId),
4666
- statusIdx: index("idx_tool_calls_status").on(table.status),
4667
- startedAtIdx: index("idx_tool_calls_started_at").on(table.startedAt)
4668
- })
4669
- );
4670
- var permissions = sqliteTable(
4671
- "permissions",
4672
- {
4673
- id: integer("id").primaryKey({ autoIncrement: true }),
4674
- conversationId: text("conversation_id").references(() => conversations.id, {
4675
- onDelete: "set null"
4676
- }),
4677
- command: text("command").notNull(),
4678
- riskLevel: text("risk_level", { enum: ["low", "medium", "high", "critical"] }).notNull(),
4679
- decision: text("decision", { enum: ["allow", "deny", "always", "never"] }).notNull(),
4680
- userConfirmed: integer("user_confirmed", { mode: "boolean" }).default(false),
4681
- timestamp: integer("timestamp", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`),
4682
- context: text("context")
4683
- // JSON string
4684
- },
4685
- (table) => ({
4686
- conversationIdIdx: index("idx_permissions_conversation_id").on(table.conversationId),
4687
- timestampIdx: index("idx_permissions_timestamp").on(table.timestamp),
4688
- decisionIdx: index("idx_permissions_decision").on(table.decision)
4689
- })
4690
- );
4691
- var checkpoints = sqliteTable(
4692
- "checkpoints",
4693
- {
4694
- id: text("id").primaryKey(),
4695
- conversationId: text("conversation_id").notNull().references(() => conversations.id, { onDelete: "cascade" }),
4696
- description: text("description"),
4697
- filesSnapshot: text("files_snapshot").notNull(),
4698
- // JSON string
4699
- gitDiff: text("git_diff"),
4700
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`)
4701
- },
4702
- (table) => ({
4703
- conversationIdIdx: index("idx_checkpoints_conversation_id").on(table.conversationId),
4704
- createdAtIdx: index("idx_checkpoints_created_at").on(table.createdAt)
4705
- })
4706
- );
4707
- var costSummary = sqliteTable(
4708
- "cost_summary",
4709
- {
4710
- id: integer("id").primaryKey({ autoIncrement: true }),
4711
- date: text("date").notNull(),
4712
- // YYYY-MM-DD format
4713
- provider: text("provider").notNull(),
4714
- model: text("model").notNull(),
4715
- totalTokens: integer("total_tokens").default(0),
4716
- inputTokens: integer("input_tokens").default(0),
4717
- outputTokens: integer("output_tokens").default(0),
4718
- totalCost: real("total_cost").default(0),
4719
- requestCount: integer("request_count").default(0)
4720
- },
4721
- (table) => ({
4722
- dateIdx: index("idx_cost_summary_date").on(table.date),
4723
- providerIdx: index("idx_cost_summary_provider").on(table.provider),
4724
- uniqueIdx: uniqueIndex("unique_date_provider_model").on(
4725
- table.date,
4726
- table.provider,
4727
- table.model
4728
- )
4729
- })
4730
- );
4731
- var sessionState = sqliteTable(
4732
- "session_state",
4733
- {
4734
- id: text("id").primaryKey(),
4735
- conversationId: text("conversation_id").notNull().references(() => conversations.id, { onDelete: "cascade" }),
4736
- agentState: text("agent_state").notNull(),
4737
- // JSON string
4738
- iteration: integer("iteration").default(0),
4739
- createdAt: integer("created_at", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`)
4740
- },
4741
- (table) => ({
4742
- conversationIdIdx: index("idx_session_state_conversation_id").on(table.conversationId)
4743
- })
4744
- );
4745
- var metrics = sqliteTable(
4746
- "metrics",
4747
- {
4748
- id: integer("id").primaryKey({ autoIncrement: true }),
4749
- timestamp: integer("timestamp", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`),
4750
- operation: text("operation").notNull(),
4751
- // 'llm.chat', 'tool.execute', 'db.query'
4752
- durationMs: integer("duration_ms").notNull(),
4753
- // Context
4754
- conversationId: text("conversation_id"),
4755
- sessionId: text("session_id"),
4756
- // LLM specific
4757
- provider: text("provider"),
4758
- model: text("model"),
4759
- inputTokens: integer("input_tokens"),
4760
- outputTokens: integer("output_tokens"),
4761
- totalTokens: integer("total_tokens"),
4762
- cost: real("cost"),
4763
- // Tool specific
4764
- toolName: text("tool_name"),
4765
- toolArgs: text("tool_args"),
4766
- // JSON
4767
- toolResultSize: integer("tool_result_size"),
4768
- // bytes
4769
- // DB specific
4770
- queryType: text("query_type"),
4771
- // 'SELECT', 'INSERT', etc.
4772
- tableName: text("table_name"),
4773
- rowsAffected: integer("rows_affected"),
4774
- // Result
4775
- success: integer("success", { mode: "boolean" }).default(true),
4776
- error: text("error"),
4777
- // Resource usage
4778
- memoryMb: real("memory_mb"),
4779
- cpuPercent: real("cpu_percent"),
4780
- // Additional metadata
4781
- metadata: text("metadata")
4782
- // JSON for extensibility
4783
- },
4784
- (table) => ({
4785
- timestampIdx: index("idx_metrics_timestamp").on(table.timestamp),
4786
- operationIdx: index("idx_metrics_operation").on(table.operation),
4787
- conversationIdIdx: index("idx_metrics_conversation_id").on(table.conversationId),
4788
- providerIdx: index("idx_metrics_provider").on(table.provider),
4789
- successIdx: index("idx_metrics_success").on(table.success)
4790
- })
4791
- );
4792
- var pricing = sqliteTable(
4793
- "pricing",
4794
- {
4795
- id: integer("id").primaryKey({ autoIncrement: true }),
4796
- provider: text("provider").notNull(),
4797
- model: text("model").notNull(),
4798
- inputPricePer1M: real("input_price_per_1m").notNull(),
4799
- // USD per 1M input tokens
4800
- outputPricePer1M: real("output_price_per_1m").notNull(),
4801
- // USD per 1M output tokens
4802
- effectiveFrom: integer("effective_from", { mode: "timestamp" }).notNull().default(sql`(strftime('%s', 'now'))`),
4803
- effectiveUntil: integer("effective_until", { mode: "timestamp" }),
4804
- // NULL = current price
4805
- currency: text("currency").default("USD"),
4806
- notes: text("notes")
4807
- },
4808
- (table) => ({
4809
- providerModelIdx: index("idx_pricing_provider_model").on(table.provider, table.model),
4810
- effectiveIdx: index("idx_pricing_effective").on(table.effectiveFrom),
4811
- uniqueIdx: uniqueIndex("unique_provider_model_effective").on(
4812
- table.provider,
4813
- table.model,
4814
- table.effectiveFrom
4815
- )
4816
- })
4817
- );
3772
+ import initSqlJs from "sql.js";
4818
3773
 
4819
3774
  // src/storage/seed.ts
4820
- init_esm_shims();
4821
3775
  var defaultPricing = [
4822
3776
  // DeepSeek
4823
3777
  {
@@ -4947,24 +3901,67 @@ var defaultPricing = [
4947
3901
  ];
4948
3902
 
4949
3903
  // src/storage/Database.ts
4950
- import { dirname } from "path";
3904
+ import { dirname, join } from "path";
3905
+ import { fileURLToPath } from "url";
3906
+ import { readFileSync, existsSync } from "fs";
3907
+ function locateWasmFile() {
3908
+ const wasmFileName = "sql-wasm.wasm";
3909
+ const executablePath = process.argv[0] || process.execPath;
3910
+ const binaryDir = dirname(executablePath);
3911
+ const resourcesPaths = [
3912
+ // Next to the binary (same directory) - most common for our installers
3913
+ join(binaryDir, "resources", wasmFileName),
3914
+ // For development/testing
3915
+ join(process.cwd(), "resources", wasmFileName),
3916
+ // Parent directory of binary (for some install layouts)
3917
+ join(binaryDir, "..", "resources", wasmFileName)
3918
+ ];
3919
+ for (const resourcePath of resourcesPaths) {
3920
+ if (existsSync(resourcePath)) {
3921
+ const buffer = readFileSync(resourcePath);
3922
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
3923
+ }
3924
+ }
3925
+ const currentDir = dirname(fileURLToPath(import.meta.url));
3926
+ const nodeModulesPaths = [
3927
+ join(currentDir, "..", "..", "node_modules", "sql.js", "dist", wasmFileName),
3928
+ join(process.cwd(), "node_modules", "sql.js", "dist", wasmFileName)
3929
+ ];
3930
+ for (const modulePath of nodeModulesPaths) {
3931
+ if (existsSync(modulePath)) {
3932
+ const buffer = readFileSync(modulePath);
3933
+ return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
3934
+ }
3935
+ }
3936
+ const diagnostics = [
3937
+ `process.argv[0]: ${process.argv[0]}`,
3938
+ `process.execPath: ${process.execPath}`,
3939
+ `executablePath: ${executablePath}`,
3940
+ `binaryDir: ${binaryDir}`,
3941
+ `currentDir: ${currentDir}`,
3942
+ `process.cwd(): ${process.cwd()}`
3943
+ ];
3944
+ throw new Error(
3945
+ `Could not locate ${wasmFileName}.
3946
+
3947
+ Diagnostics:
3948
+ ${diagnostics.join("\n")}
3949
+
3950
+ Tried:
3951
+ ` + [...resourcesPaths, ...nodeModulesPaths].map((p) => ` - ${p}`).join("\n")
3952
+ );
3953
+ }
4951
3954
  var DatabaseManager = class _DatabaseManager {
4952
- sqlite;
4953
3955
  db;
4954
3956
  config;
4955
- constructor(config) {
3957
+ SQL;
3958
+ nodeFs = null;
3959
+ constructor(config, SQL) {
4956
3960
  this.config = config;
4957
- this.sqlite = new import_better_sqlite3.default(config.path, {
4958
- verbose: config.verbose ? console.log : void 0
4959
- });
4960
- this.sqlite.pragma("journal_mode = WAL");
4961
- this.sqlite.pragma("foreign_keys = ON");
4962
- this.db = drizzle(this.sqlite, { schema: schema_exports });
4963
- this.initialize();
3961
+ this.SQL = SQL;
4964
3962
  }
4965
3963
  /**
4966
3964
  * Create DatabaseManager instance with proper directory setup
4967
- * Use this factory method instead of constructor for proper async initialization
4968
3965
  */
4969
3966
  static async create(config) {
4970
3967
  const dbDir = dirname(config.path);
@@ -4974,72 +3971,103 @@ var DatabaseManager = class _DatabaseManager {
4974
3971
  await config.fileSystem.mkdir(dbDir, { recursive: true });
4975
3972
  }
4976
3973
  } else {
4977
- const { existsSync, mkdirSync } = await import("fs");
4978
- if (!existsSync(dbDir)) {
3974
+ const { existsSync: existsSync2, mkdirSync } = await import("fs");
3975
+ if (!existsSync2(dbDir)) {
4979
3976
  mkdirSync(dbDir, { recursive: true });
4980
3977
  }
4981
3978
  }
4982
- return new _DatabaseManager(config);
4983
- }
4984
- /**
4985
- * Initialize database with migrations and seed data
4986
- */
4987
- initialize() {
4988
- try {
4989
- this.runMigrations();
4990
- this.seedDatabase();
4991
- } catch (error) {
4992
- console.error("Database initialization failed:", error);
4993
- throw error;
4994
- }
3979
+ const wasmBinary = locateWasmFile();
3980
+ const SQL = await initSqlJs({
3981
+ wasmBinary
3982
+ });
3983
+ const manager = new _DatabaseManager(config, SQL);
3984
+ manager.nodeFs = await import("fs");
3985
+ await manager.loadDatabase();
3986
+ manager.initialize();
3987
+ await manager.save();
3988
+ return manager;
4995
3989
  }
4996
3990
  /**
4997
- * Run Drizzle migrations
3991
+ * Load database from file or create new
4998
3992
  */
4999
- runMigrations() {
3993
+ async loadDatabase() {
5000
3994
  try {
5001
- const migrationsFolder = "./drizzle";
5002
- const { existsSync } = __require("fs");
5003
- if (existsSync(migrationsFolder)) {
5004
- migrate(this.db, { migrationsFolder });
3995
+ if (this.config.fileSystem) {
3996
+ const exists = await this.config.fileSystem.exists(this.config.path);
3997
+ if (exists) {
3998
+ const buffer = await this.config.fileSystem.readFile(
3999
+ this.config.path,
4000
+ "binary"
4001
+ );
4002
+ const uint8Array = new Uint8Array(Buffer.from(buffer, "binary"));
4003
+ this.db = new this.SQL.Database(uint8Array);
4004
+ if (this.config.verbose) {
4005
+ console.log("Loaded existing database from", this.config.path);
4006
+ }
4007
+ } else {
4008
+ this.db = new this.SQL.Database();
4009
+ if (this.config.verbose) {
4010
+ console.log("Created new database");
4011
+ }
4012
+ }
5005
4013
  } else {
4014
+ const { existsSync: existsSync2, readFileSync: readFileSync2 } = await import("fs");
4015
+ if (existsSync2(this.config.path)) {
4016
+ const buffer = readFileSync2(this.config.path);
4017
+ this.db = new this.SQL.Database(buffer);
4018
+ } else {
4019
+ this.db = new this.SQL.Database();
4020
+ }
5006
4021
  }
5007
4022
  } catch (error) {
4023
+ this.db = new this.SQL.Database();
5008
4024
  if (this.config.verbose) {
5009
- console.log("No migrations to run, will use manual initialization");
4025
+ console.log("Created new database after error:", error);
5010
4026
  }
5011
4027
  }
5012
4028
  }
5013
4029
  /**
5014
- * Seed database with initial data
4030
+ * Save database to disk (async version)
5015
4031
  */
5016
- seedDatabase() {
5017
- const pricingCount = this.sqlite.prepare("SELECT COUNT(*) as count FROM sqlite_master WHERE type='table' AND name='pricing'").get();
5018
- if (pricingCount.count === 0) {
5019
- this.createTablesManually();
4032
+ async save() {
4033
+ const data = this.db.export();
4034
+ const buffer = Buffer.from(data);
4035
+ if (this.config.fileSystem) {
4036
+ await this.config.fileSystem.writeFile(
4037
+ this.config.path,
4038
+ buffer.toString("binary"),
4039
+ "binary"
4040
+ );
4041
+ } else {
4042
+ const { writeFileSync } = await import("fs");
4043
+ writeFileSync(this.config.path, buffer);
5020
4044
  }
5021
- const existingPricing = this.sqlite.prepare("SELECT COUNT(*) as count FROM pricing").get();
5022
- if (existingPricing.count === 0) {
5023
- this.db.transaction((tx) => {
5024
- for (const price of defaultPricing) {
5025
- tx.insert(pricing).values(price).run();
5026
- }
5027
- });
5028
- if (this.config.verbose) {
5029
- console.log(`Seeded ${defaultPricing.length} pricing entries`);
5030
- }
4045
+ }
4046
+ /**
4047
+ * Save database to disk (sync version for auto-save)
4048
+ * Uses sync fs operations to avoid async in execute/transaction
4049
+ */
4050
+ saveSync() {
4051
+ const data = this.db.export();
4052
+ const buffer = Buffer.from(data);
4053
+ if (this.nodeFs) {
4054
+ this.nodeFs.writeFileSync(this.config.path, buffer);
5031
4055
  }
4056
+ }
4057
+ /**
4058
+ * Initialize database with migrations and seed data
4059
+ */
4060
+ initialize() {
5032
4061
  try {
5033
- const migrationExists = this.sqlite.prepare("SELECT COUNT(*) as count FROM migrations WHERE version = ?").get("1.0.0");
5034
- if (migrationExists.count === 0) {
5035
- this.db.insert(migrations).values({ version: "1.0.0" }).run();
5036
- }
4062
+ this.createTablesManually();
4063
+ this.seedDatabase();
5037
4064
  } catch (error) {
4065
+ console.error("Database initialization failed:", error);
4066
+ throw error;
5038
4067
  }
5039
4068
  }
5040
4069
  /**
5041
- * Manually create tables from Drizzle schema
5042
- * This is a fallback for when migrations don't exist yet
4070
+ * Manually create tables from schema
5043
4071
  */
5044
4072
  createTablesManually() {
5045
4073
  const createTablesSQL = `
@@ -5207,7 +4235,7 @@ var DatabaseManager = class _DatabaseManager {
5207
4235
  const statements = createTablesSQL.split(";").filter((s) => s.trim());
5208
4236
  for (const statement of statements) {
5209
4237
  try {
5210
- this.sqlite.exec(statement);
4238
+ this.db.run(statement);
5211
4239
  } catch (error) {
5212
4240
  if (this.config.verbose) {
5213
4241
  console.log("Table creation warning:", error);
@@ -5219,83 +4247,149 @@ var DatabaseManager = class _DatabaseManager {
5219
4247
  }
5220
4248
  }
5221
4249
  /**
5222
- * Get Drizzle database instance
4250
+ * Seed database with initial data
5223
4251
  */
5224
- getDb() {
5225
- return this.db;
4252
+ seedDatabase() {
4253
+ const pricingCount = this.db.exec(
4254
+ "SELECT COUNT(*) as count FROM sqlite_master WHERE type='table' AND name='pricing'"
4255
+ );
4256
+ if (pricingCount.length === 0 || pricingCount[0]?.values[0]?.[0] === 0) {
4257
+ this.createTablesManually();
4258
+ }
4259
+ const existingPricing = this.db.exec("SELECT COUNT(*) as count FROM pricing");
4260
+ const count = existingPricing.length > 0 ? existingPricing[0]?.values[0]?.[0] : 0;
4261
+ if (count === 0) {
4262
+ for (const price of defaultPricing) {
4263
+ const stmt = this.db.prepare(
4264
+ `INSERT INTO pricing (provider, model, input_price_per_1m, output_price_per_1m, effective_from, currency)
4265
+ VALUES (?, ?, ?, ?, ?, ?)`
4266
+ );
4267
+ const effectiveFrom = price.effectiveFrom ? typeof price.effectiveFrom === "number" ? price.effectiveFrom : Math.floor(price.effectiveFrom.getTime() / 1e3) : Math.floor(Date.now() / 1e3);
4268
+ stmt.run([
4269
+ price.provider,
4270
+ price.model,
4271
+ price.inputPricePer1M,
4272
+ price.outputPricePer1M,
4273
+ effectiveFrom,
4274
+ price.currency ?? "USD"
4275
+ ]);
4276
+ stmt.free();
4277
+ }
4278
+ if (this.config.verbose) {
4279
+ console.log(`Seeded ${defaultPricing.length} pricing entries`);
4280
+ }
4281
+ }
4282
+ try {
4283
+ const migrationExists = this.db.exec(
4284
+ "SELECT COUNT(*) as count FROM migrations WHERE version = '1.0.0'"
4285
+ );
4286
+ const migCount = migrationExists.length > 0 ? migrationExists[0]?.values[0]?.[0] : 0;
4287
+ if (migCount === 0) {
4288
+ this.db.run("INSERT INTO migrations (version) VALUES ('1.0.0')");
4289
+ }
4290
+ } catch (error) {
4291
+ }
5226
4292
  }
5227
4293
  /**
5228
- * Get raw SQLite database instance (for legacy code)
4294
+ * Execute a raw SQL query (auto-saves for write operations)
5229
4295
  */
5230
- getSqlite() {
5231
- return this.sqlite;
4296
+ execute(sql, params) {
4297
+ const stmt = this.db.prepare(sql);
4298
+ stmt.bind(params || []);
4299
+ stmt.step();
4300
+ const info = this.db.getRowsModified();
4301
+ stmt.free();
4302
+ const isWrite = /^\s*(INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)/i.test(sql);
4303
+ if (isWrite && info > 0) {
4304
+ this.saveSync();
4305
+ }
4306
+ return {
4307
+ changes: info,
4308
+ lastInsertRowid: 0
4309
+ // sql.js doesn't provide this easily
4310
+ };
5232
4311
  }
5233
4312
  /**
5234
- * Execute a raw SQL query (for backward compatibility)
4313
+ * Query a raw SQL statement
5235
4314
  */
5236
- execute(sql2, params) {
5237
- const stmt = this.sqlite.prepare(sql2);
5238
- return stmt.run(...params || []);
4315
+ query(sql, params) {
4316
+ const stmt = this.db.prepare(sql);
4317
+ stmt.bind(params || []);
4318
+ const results = [];
4319
+ while (stmt.step()) {
4320
+ const row = stmt.getAsObject();
4321
+ results.push(row);
4322
+ }
4323
+ stmt.free();
4324
+ return results;
5239
4325
  }
5240
4326
  /**
5241
- * Query a raw SQL statement (for backward compatibility)
4327
+ * Execute a query and return a single row
5242
4328
  */
5243
- query(sql2, params) {
5244
- const stmt = this.sqlite.prepare(sql2);
5245
- return stmt.all(...params || []);
4329
+ queryOne(sql, params) {
4330
+ try {
4331
+ const stmt = this.db.prepare(sql);
4332
+ stmt.bind(params || []);
4333
+ if (stmt.step()) {
4334
+ const row = stmt.getAsObject();
4335
+ stmt.free();
4336
+ return row;
4337
+ }
4338
+ stmt.free();
4339
+ return null;
4340
+ } catch (error) {
4341
+ console.error("Query failed:", error);
4342
+ return null;
4343
+ }
5246
4344
  }
5247
4345
  /**
5248
- * Run a transaction
4346
+ * Run a transaction (auto-saves after commit)
5249
4347
  */
5250
4348
  transaction(fn) {
5251
- return this.db.transaction((tx) => fn(tx));
4349
+ this.db.run("BEGIN TRANSACTION");
4350
+ try {
4351
+ const result = fn(this);
4352
+ this.db.run("COMMIT");
4353
+ this.saveSync();
4354
+ return result;
4355
+ } catch (error) {
4356
+ this.db.run("ROLLBACK");
4357
+ throw error;
4358
+ }
5252
4359
  }
5253
4360
  /**
5254
4361
  * Close database connection
5255
4362
  */
5256
4363
  close() {
5257
- this.sqlite.close();
4364
+ this.db.close();
5258
4365
  }
5259
4366
  /**
5260
4367
  * Vacuum database to optimize storage
5261
4368
  */
5262
4369
  vacuum() {
5263
- this.sqlite.exec("VACUUM");
4370
+ this.db.run("VACUUM");
5264
4371
  }
5265
4372
  /**
5266
4373
  * Get database statistics
5267
4374
  */
5268
4375
  getStats() {
5269
- const pageCount = this.sqlite.pragma("page_count", { simple: true });
5270
- const pageSize = this.sqlite.pragma("page_size", { simple: true });
5271
- const journalMode = this.sqlite.pragma("journal_mode", { simple: true });
4376
+ const pageCount = this.queryOne("PRAGMA page_count");
4377
+ const pageSize = this.queryOne("PRAGMA page_size");
5272
4378
  return {
5273
- pageCount,
5274
- pageSize,
5275
- sizeBytes: pageCount * pageSize,
5276
- walMode: journalMode.toLowerCase() === "wal"
4379
+ pageCount: pageCount?.page_count || 0,
4380
+ pageSize: pageSize?.page_size || 0,
4381
+ sizeBytes: (pageCount?.page_count || 0) * (pageSize?.page_size || 0),
4382
+ walMode: false
4383
+ // sql.js doesn't support WAL mode
5277
4384
  };
5278
4385
  }
5279
- /**
5280
- * Execute a query and return a single row
5281
- */
5282
- queryOne(sql2, params) {
5283
- try {
5284
- const stmt = this.sqlite.prepare(sql2);
5285
- const result = params ? stmt.get(...params) : stmt.get();
5286
- return result || null;
5287
- } catch (error) {
5288
- console.error("Query failed:", error);
5289
- return null;
5290
- }
5291
- }
5292
4386
  /**
5293
4387
  * Perform a database health check
5294
4388
  */
5295
4389
  async healthCheck() {
5296
4390
  try {
5297
- const result = this.sqlite.pragma("integrity_check", { simple: true });
5298
- return result === "ok";
4391
+ const result = this.queryOne("PRAGMA integrity_check");
4392
+ return result?.integrity_check === "ok";
5299
4393
  } catch (error) {
5300
4394
  console.error("Health check failed:", error);
5301
4395
  return false;
@@ -5320,9 +4414,7 @@ function closeDatabaseManager() {
5320
4414
  }
5321
4415
 
5322
4416
  // src/core/MimirInitializer.ts
5323
- import path7 from "path";
5324
- import { fileURLToPath as fileURLToPath2 } from "url";
5325
- import { dirname as dirname2 } from "path";
4417
+ import path6, { dirname as dirname2 } from "path";
5326
4418
  var MimirInitializer = class {
5327
4419
  constructor(fs4, configLoader2) {
5328
4420
  this.fs = fs4;
@@ -5341,7 +4433,7 @@ var MimirInitializer = class {
5341
4433
  configCreated: false
5342
4434
  };
5343
4435
  try {
5344
- const mimirDir = path7.join(workspaceRoot, ".mimir");
4436
+ const mimirDir = path6.join(workspaceRoot, ".mimir");
5345
4437
  if (!await this.fs.exists(mimirDir)) {
5346
4438
  await this.fs.mkdir(mimirDir, { recursive: true });
5347
4439
  result.created.push(".mimir/");
@@ -5354,7 +4446,7 @@ var MimirInitializer = class {
5354
4446
  { name: "themes", purpose: "UI theme definitions" }
5355
4447
  ];
5356
4448
  for (const { name, purpose } of subdirs) {
5357
- const subdir = path7.join(mimirDir, name);
4449
+ const subdir = path6.join(mimirDir, name);
5358
4450
  if (!await this.fs.exists(subdir)) {
5359
4451
  await this.fs.mkdir(subdir, { recursive: true });
5360
4452
  result.created.push(`.mimir/${name}/`);
@@ -5380,15 +4472,15 @@ var MimirInitializer = class {
5380
4472
  * Check if workspace is initialized
5381
4473
  */
5382
4474
  async isWorkspaceInitialized(workspaceRoot) {
5383
- const mimirDir = path7.join(workspaceRoot, ".mimir");
5384
- const dbPath = path7.join(mimirDir, "mimir.db");
4475
+ const mimirDir = path6.join(workspaceRoot, ".mimir");
4476
+ const dbPath = path6.join(mimirDir, "mimir.db");
5385
4477
  return await this.fs.exists(mimirDir) && await this.fs.exists(dbPath);
5386
4478
  }
5387
4479
  /**
5388
4480
  * Create .gitignore inside .mimir directory
5389
4481
  */
5390
4482
  async createMimirGitignore(mimirDir, result) {
5391
- const gitignorePath = path7.join(mimirDir, ".gitignore");
4483
+ const gitignorePath = path6.join(mimirDir, ".gitignore");
5392
4484
  if (await this.fs.exists(gitignorePath)) {
5393
4485
  return;
5394
4486
  }
@@ -5433,7 +4525,7 @@ checkpoints/
5433
4525
  * Copy default theme files to .mimir/themes/ directory
5434
4526
  */
5435
4527
  async copyDefaultThemes(mimirDir, result) {
5436
- const themesDir = path7.join(mimirDir, "themes");
4528
+ const themesDir = path6.join(mimirDir, "themes");
5437
4529
  const defaultThemes = [
5438
4530
  "mimir.json",
5439
4531
  "dark.json",
@@ -5442,22 +4534,39 @@ checkpoints/
5442
4534
  "light-colorblind.json"
5443
4535
  ];
5444
4536
  try {
5445
- const __filename2 = fileURLToPath2(import.meta.url);
5446
- const __dirname2 = dirname2(__filename2);
5447
- const sourceThemesDir = path7.join(__dirname2, "../cli/themes");
4537
+ const executablePath = process.argv[0] || process.execPath;
4538
+ const binaryDir = dirname2(executablePath);
4539
+ const possibleSourceDirs = [
4540
+ path6.join(binaryDir, "resources", "themes"),
4541
+ // Compiled binary: ~/.local/bin/resources/themes/
4542
+ path6.join(binaryDir, "../cli/themes"),
4543
+ // Development: dist/core/../cli/themes
4544
+ path6.join(binaryDir, "../../src/cli/themes")
4545
+ // Development: dist/core/../../src/cli/themes
4546
+ ];
5448
4547
  for (const themeFile of defaultThemes) {
5449
- const destPath = path7.join(themesDir, themeFile);
4548
+ const destPath = path6.join(themesDir, themeFile);
5450
4549
  if (await this.fs.exists(destPath)) {
5451
4550
  continue;
5452
4551
  }
5453
- try {
5454
- const sourcePath = path7.join(sourceThemesDir, themeFile);
5455
- const themeContent = await this.fs.readFile(sourcePath, "utf-8");
5456
- await this.fs.writeFile(destPath, themeContent);
5457
- result.created.push(`.mimir/themes/${themeFile}`);
5458
- logger.info("Copied default theme", { theme: themeFile });
5459
- } catch (error) {
5460
- logger.warn(`Failed to copy theme ${themeFile}, will use built-in fallback`, { error });
4552
+ let copied = false;
4553
+ for (const sourceDir of possibleSourceDirs) {
4554
+ try {
4555
+ const sourcePath = path6.join(sourceDir, themeFile);
4556
+ const themeContent = await this.fs.readFile(sourcePath, "utf-8");
4557
+ await this.fs.writeFile(destPath, themeContent);
4558
+ result.created.push(`.mimir/themes/${themeFile}`);
4559
+ logger.info("Copied default theme", { theme: themeFile, from: sourceDir });
4560
+ copied = true;
4561
+ break;
4562
+ } catch (error) {
4563
+ continue;
4564
+ }
4565
+ }
4566
+ if (!copied) {
4567
+ logger.warn(`Failed to copy theme ${themeFile}, will use built-in fallback`, {
4568
+ triedLocations: possibleSourceDirs
4569
+ });
5461
4570
  }
5462
4571
  }
5463
4572
  } catch (error) {
@@ -5471,32 +4580,42 @@ checkpoints/
5471
4580
  * Copy example command files to .mimir/commands/ directory
5472
4581
  */
5473
4582
  async copyExampleCommands(mimirDir, result) {
5474
- const commandsDir = path7.join(mimirDir, "commands");
5475
- const exampleCommands = [
5476
- "security.yml",
5477
- "refactor.yml",
5478
- "test.yml",
5479
- "docs.yml",
5480
- "review.yml",
5481
- "perf.yml"
5482
- ];
4583
+ const commandsDir = path6.join(mimirDir, "commands");
4584
+ const exampleCommands = ["update-docs.yml"];
5483
4585
  try {
5484
- const __filename2 = fileURLToPath2(import.meta.url);
5485
- const __dirname2 = dirname2(__filename2);
5486
- const sourceCommandsDir = path7.join(__dirname2, "../../scripts/templates/commands");
4586
+ const executablePath = process.argv[0] || process.execPath;
4587
+ const binaryDir = dirname2(executablePath);
4588
+ const possibleSourceDirs = [
4589
+ path6.join(binaryDir, "resources", "commands"),
4590
+ // Compiled binary: ~/.local/bin/resources/commands/
4591
+ path6.join(binaryDir, "../../scripts/templates/commands"),
4592
+ // Development: dist/core/../../scripts/templates/commands
4593
+ path6.join(binaryDir, "../../../scripts/templates/commands")
4594
+ // Alternative dev path
4595
+ ];
5487
4596
  for (const commandFile of exampleCommands) {
5488
- const destPath = path7.join(commandsDir, commandFile);
4597
+ const destPath = path6.join(commandsDir, commandFile);
5489
4598
  if (await this.fs.exists(destPath)) {
5490
4599
  continue;
5491
4600
  }
5492
- try {
5493
- const sourcePath = path7.join(sourceCommandsDir, commandFile);
5494
- const commandContent = await this.fs.readFile(sourcePath, "utf-8");
5495
- await this.fs.writeFile(destPath, commandContent);
5496
- result.created.push(`.mimir/commands/${commandFile}`);
5497
- logger.info("Copied example command", { command: commandFile });
5498
- } catch (error) {
5499
- logger.warn(`Failed to copy command ${commandFile}, continuing`, { error });
4601
+ let copied = false;
4602
+ for (const sourceDir of possibleSourceDirs) {
4603
+ try {
4604
+ const sourcePath = path6.join(sourceDir, commandFile);
4605
+ const commandContent = await this.fs.readFile(sourcePath, "utf-8");
4606
+ await this.fs.writeFile(destPath, commandContent);
4607
+ result.created.push(`.mimir/commands/${commandFile}`);
4608
+ logger.info("Copied example command", { command: commandFile, from: sourceDir });
4609
+ copied = true;
4610
+ break;
4611
+ } catch (error) {
4612
+ continue;
4613
+ }
4614
+ }
4615
+ if (!copied) {
4616
+ logger.warn(`Failed to copy command ${commandFile}, continuing`, {
4617
+ triedLocations: possibleSourceDirs
4618
+ });
5500
4619
  }
5501
4620
  }
5502
4621
  } catch (error) {
@@ -5510,7 +4629,7 @@ checkpoints/
5510
4629
  * Initialize SQLite database with Drizzle ORM
5511
4630
  */
5512
4631
  async initializeDatabase(mimirDir, result) {
5513
- const dbPath = path7.join(mimirDir, "mimir.db");
4632
+ const dbPath = path6.join(mimirDir, "mimir.db");
5514
4633
  if (await this.fs.exists(dbPath)) {
5515
4634
  logger.info("Database already exists, skipping initialization", { path: dbPath });
5516
4635
  return;
@@ -5562,7 +4681,7 @@ checkpoints/
5562
4681
  * Create config.yml if it doesn't exist
5563
4682
  */
5564
4683
  async createConfigIfNeeded(mimirDir, result) {
5565
- const configPath = path7.join(mimirDir, "config.yml");
4684
+ const configPath = path6.join(mimirDir, "config.yml");
5566
4685
  if (await this.fs.exists(configPath)) {
5567
4686
  return;
5568
4687
  }
@@ -5660,7 +4779,7 @@ rateLimit:
5660
4779
  * Create README in .mimir directory
5661
4780
  */
5662
4781
  async createReadme(mimirDir, result) {
5663
- const readmePath = path7.join(mimirDir, "README.md");
4782
+ const readmePath = path6.join(mimirDir, "README.md");
5664
4783
  if (await this.fs.exists(readmePath)) {
5665
4784
  return;
5666
4785
  }
@@ -5825,7 +4944,7 @@ See the theme documentation for creating custom themes.
5825
4944
  result.errors.forEach((error) => console.log(` ! ${error}`));
5826
4945
  }
5827
4946
  console.log("\n\u{1F4C1} Workspace structure:");
5828
- console.log(` ${path7.join(workspaceRoot, ".mimir")}`);
4947
+ console.log(` ${path6.join(workspaceRoot, ".mimir")}`);
5829
4948
  console.log(" \u251C\u2500\u2500 config.yml (tracked in git)");
5830
4949
  console.log(" \u251C\u2500\u2500 mimir.db (ignored)");
5831
4950
  console.log(" \u251C\u2500\u2500 logs/ (ignored)");
@@ -5845,18 +4964,10 @@ See the theme documentation for creating custom themes.
5845
4964
  }
5846
4965
  };
5847
4966
 
5848
- // src/providers/ProviderFactory.ts
5849
- init_esm_shims();
5850
-
5851
4967
  // src/providers/DeepSeekProvider.ts
5852
- init_esm_shims();
5853
- import { encoding_for_model } from "tiktoken";
5854
-
5855
- // src/providers/BaseLLMProvider.ts
5856
- init_esm_shims();
4968
+ import { encode } from "gpt-tokenizer";
5857
4969
 
5858
4970
  // src/utils/errors.ts
5859
- init_esm_shims();
5860
4971
  var MimirError = class extends Error {
5861
4972
  constructor(message) {
5862
4973
  super(message);
@@ -5939,7 +5050,6 @@ var BaseLLMProvider = class {
5939
5050
  };
5940
5051
 
5941
5052
  // src/providers/utils/apiClient.ts
5942
- init_esm_shims();
5943
5053
  import axios from "axios";
5944
5054
  var APIClient = class {
5945
5055
  axiosInstance;
@@ -6047,7 +5157,6 @@ var APIClient = class {
6047
5157
  };
6048
5158
 
6049
5159
  // src/providers/pricing/pricingData.ts
6050
- init_esm_shims();
6051
5160
  var STATIC_PRICING_TABLE = {
6052
5161
  deepseek: {
6053
5162
  "deepseek-chat": {
@@ -6100,7 +5209,6 @@ function getStaticPricing(provider, model) {
6100
5209
  }
6101
5210
 
6102
5211
  // src/providers/utils/toolFormatters.ts
6103
- init_esm_shims();
6104
5212
  function toOpenAITools(tools) {
6105
5213
  return tools.map((tool) => ({
6106
5214
  type: "function",
@@ -6124,8 +5232,8 @@ function toAnthropicTools(tools) {
6124
5232
  }));
6125
5233
  }
6126
5234
  function parseOpenAIToolCalls(response) {
6127
- const toolCalls2 = response.choices?.[0]?.message?.tool_calls || [];
6128
- return toolCalls2.map((tc) => {
5235
+ const toolCalls = response.choices?.[0]?.message?.tool_calls || [];
5236
+ return toolCalls.map((tc) => {
6129
5237
  let parsedArgs;
6130
5238
  try {
6131
5239
  parsedArgs = JSON.parse(tc.function.arguments);
@@ -6180,7 +5288,6 @@ function mapAnthropicFinishReason(reason) {
6180
5288
  }
6181
5289
 
6182
5290
  // src/providers/utils/streamParsers.ts
6183
- init_esm_shims();
6184
5291
  async function* parseOpenAIStream(stream) {
6185
5292
  let buffer = "";
6186
5293
  for await (const chunk of stream) {
@@ -6275,7 +5382,6 @@ async function* parseAnthropicStream(stream) {
6275
5382
  // src/providers/DeepSeekProvider.ts
6276
5383
  var DeepSeekProvider = class extends BaseLLMProvider {
6277
5384
  apiClient;
6278
- encoder;
6279
5385
  constructor(config) {
6280
5386
  super(config);
6281
5387
  const apiKey = config.apiKey || process.env.DEEPSEEK_API_KEY;
@@ -6293,13 +5399,12 @@ var DeepSeekProvider = class extends BaseLLMProvider {
6293
5399
  },
6294
5400
  timeout: 6e4
6295
5401
  });
6296
- this.encoder = encoding_for_model("gpt-4");
6297
5402
  }
6298
- async chat(messages2, tools) {
5403
+ async chat(messages, tools) {
6299
5404
  return this.withRetry(async () => {
6300
5405
  const requestBody = {
6301
5406
  model: this.config.model,
6302
- messages: this.formatMessages(messages2),
5407
+ messages: this.formatMessages(messages),
6303
5408
  tools: tools ? toOpenAITools(tools) : void 0,
6304
5409
  temperature: this.config.temperature,
6305
5410
  max_tokens: this.config.maxTokens
@@ -6311,10 +5416,10 @@ var DeepSeekProvider = class extends BaseLLMProvider {
6311
5416
  return this.parseResponse(response);
6312
5417
  });
6313
5418
  }
6314
- async *streamChat(messages2, tools) {
5419
+ async *streamChat(messages, tools) {
6315
5420
  const requestBody = {
6316
5421
  model: this.config.model,
6317
- messages: this.formatMessages(messages2),
5422
+ messages: this.formatMessages(messages),
6318
5423
  tools: tools ? toOpenAITools(tools) : void 0,
6319
5424
  temperature: this.config.temperature,
6320
5425
  max_tokens: this.config.maxTokens,
@@ -6325,21 +5430,21 @@ var DeepSeekProvider = class extends BaseLLMProvider {
6325
5430
  yield chunk;
6326
5431
  }
6327
5432
  }
6328
- countTokens(text2) {
6329
- return this.encoder.encode(text2).length;
5433
+ countTokens(text) {
5434
+ return encode(text).length;
6330
5435
  }
6331
5436
  calculateCost(inputTokens, outputTokens) {
6332
- const pricing2 = getStaticPricing("deepseek", this.config.model);
6333
- if (!pricing2) {
5437
+ const pricing = getStaticPricing("deepseek", this.config.model);
5438
+ if (!pricing) {
6334
5439
  return 0;
6335
5440
  }
6336
- return inputTokens / 1e6 * pricing2.inputPerMillionTokens + outputTokens / 1e6 * pricing2.outputPerMillionTokens;
5441
+ return inputTokens / 1e6 * pricing.inputPerMillionTokens + outputTokens / 1e6 * pricing.outputPerMillionTokens;
6337
5442
  }
6338
5443
  /**
6339
5444
  * Format messages for OpenAI-compatible API
6340
5445
  */
6341
- formatMessages(messages2) {
6342
- return messages2.map((msg) => ({
5446
+ formatMessages(messages) {
5447
+ return messages.map((msg) => ({
6343
5448
  role: msg.role,
6344
5449
  content: msg.content,
6345
5450
  name: msg.name
@@ -6369,11 +5474,9 @@ var DeepSeekProvider = class extends BaseLLMProvider {
6369
5474
  };
6370
5475
 
6371
5476
  // src/providers/AnthropicProvider.ts
6372
- init_esm_shims();
6373
- import { encoding_for_model as encoding_for_model2 } from "tiktoken";
5477
+ import { encode as encode2 } from "gpt-tokenizer";
6374
5478
  var AnthropicProvider = class extends BaseLLMProvider {
6375
5479
  apiClient;
6376
- encoder;
6377
5480
  constructor(config) {
6378
5481
  super(config);
6379
5482
  const apiKey = config.apiKey || process.env.ANTHROPIC_API_KEY;
@@ -6392,11 +5495,10 @@ var AnthropicProvider = class extends BaseLLMProvider {
6392
5495
  },
6393
5496
  timeout: 6e4
6394
5497
  });
6395
- this.encoder = encoding_for_model2("gpt-4");
6396
5498
  }
6397
- async chat(messages2, tools) {
5499
+ async chat(messages, tools) {
6398
5500
  return this.withRetry(async () => {
6399
- const { system, messages: userMessages } = this.formatAnthropicMessages(messages2);
5501
+ const { system, messages: userMessages } = this.formatAnthropicMessages(messages);
6400
5502
  const requestBody = {
6401
5503
  model: this.config.model,
6402
5504
  messages: userMessages,
@@ -6416,8 +5518,8 @@ var AnthropicProvider = class extends BaseLLMProvider {
6416
5518
  return this.parseResponse(response);
6417
5519
  });
6418
5520
  }
6419
- async *streamChat(messages2, tools) {
6420
- const { system, messages: userMessages } = this.formatAnthropicMessages(messages2);
5521
+ async *streamChat(messages, tools) {
5522
+ const { system, messages: userMessages } = this.formatAnthropicMessages(messages);
6421
5523
  const requestBody = {
6422
5524
  model: this.config.model,
6423
5525
  messages: userMessages,
@@ -6436,23 +5538,23 @@ var AnthropicProvider = class extends BaseLLMProvider {
6436
5538
  yield chunk;
6437
5539
  }
6438
5540
  }
6439
- countTokens(text2) {
6440
- return this.encoder.encode(text2).length;
5541
+ countTokens(text) {
5542
+ return encode2(text).length;
6441
5543
  }
6442
5544
  calculateCost(inputTokens, outputTokens) {
6443
- const pricing2 = getStaticPricing("anthropic", this.config.model);
6444
- if (!pricing2) {
5545
+ const pricing = getStaticPricing("anthropic", this.config.model);
5546
+ if (!pricing) {
6445
5547
  return 0;
6446
5548
  }
6447
- return inputTokens / 1e6 * pricing2.inputPerMillionTokens + outputTokens / 1e6 * pricing2.outputPerMillionTokens;
5549
+ return inputTokens / 1e6 * pricing.inputPerMillionTokens + outputTokens / 1e6 * pricing.outputPerMillionTokens;
6448
5550
  }
6449
5551
  /**
6450
5552
  * Format messages for Anthropic API
6451
5553
  * Extracts system messages into separate parameter
6452
5554
  */
6453
- formatAnthropicMessages(messages2) {
6454
- const systemMessages = messages2.filter((m) => m.role === "system");
6455
- const userMessages = messages2.filter((m) => m.role !== "system");
5555
+ formatAnthropicMessages(messages) {
5556
+ const systemMessages = messages.filter((m) => m.role === "system");
5557
+ const userMessages = messages.filter((m) => m.role !== "system");
6456
5558
  const system = systemMessages.length > 0 ? systemMessages.map((m) => m.content).join("\n\n") : void 0;
6457
5559
  return {
6458
5560
  system,
@@ -6510,7 +5612,7 @@ var ProviderFactory = class {
6510
5612
  };
6511
5613
 
6512
5614
  // src/cli/commands/ChatCommand.ts
6513
- import path8 from "path";
5615
+ import path7 from "path";
6514
5616
  import yaml4 from "yaml";
6515
5617
  var ChatCommand = class {
6516
5618
  constructor(configLoader2, firstRunDetector2, setupCommand2, fs4) {
@@ -6562,7 +5664,7 @@ var ChatCommand = class {
6562
5664
  */
6563
5665
  async saveConfig(projectRoot, config) {
6564
5666
  try {
6565
- const configPath = path8.join(projectRoot, ".mimir", "config.yml");
5667
+ const configPath = path7.join(projectRoot, ".mimir", "config.yml");
6566
5668
  const yamlContent = yaml4.stringify(config);
6567
5669
  await this.fs.writeFile(configPath, yamlContent);
6568
5670
  logger.info("Config saved", { path: configPath });
@@ -6574,15 +5676,15 @@ var ChatCommand = class {
6574
5676
  /**
6575
5677
  * Process user message through LLM provider
6576
5678
  */
6577
- async processMessage(provider, messages2, userInput) {
5679
+ async processMessage(provider, messages, userInput) {
6578
5680
  const startTime = Date.now();
6579
5681
  try {
6580
5682
  const userMessage = {
6581
5683
  role: "user",
6582
5684
  content: userInput
6583
5685
  };
6584
- messages2.push(userMessage);
6585
- const response = await provider.chat(messages2);
5686
+ messages.push(userMessage);
5687
+ const response = await provider.chat(messages);
6586
5688
  const duration = Date.now() - startTime;
6587
5689
  const assistantMessage = {
6588
5690
  role: "assistant",
@@ -6596,7 +5698,7 @@ var ChatCommand = class {
6596
5698
  provider: provider.getProviderName()
6597
5699
  }
6598
5700
  };
6599
- messages2.push(assistantMessage);
5701
+ messages.push(assistantMessage);
6600
5702
  return assistantMessage;
6601
5703
  } catch (error) {
6602
5704
  const duration = Date.now() - startTime;
@@ -6611,7 +5713,7 @@ var ChatCommand = class {
6611
5713
  provider: provider.getProviderName()
6612
5714
  }
6613
5715
  };
6614
- messages2.push(errorMessage);
5716
+ messages.push(errorMessage);
6615
5717
  return errorMessage;
6616
5718
  }
6617
5719
  }
@@ -7019,35 +6121,484 @@ Available providers: deepseek, anthropic`
7019
6121
  };
7020
6122
 
7021
6123
  // src/cli/commands/InitCommand.ts
7022
- init_esm_shims();
7023
6124
  var InitCommand = class {
7024
6125
  initializer;
7025
6126
  constructor(_fs, _configLoader) {
7026
6127
  this.initializer = new MimirInitializer(_fs, _configLoader);
7027
6128
  }
7028
- async execute(projectRoot) {
6129
+ async execute(projectRoot, options = {}) {
7029
6130
  const root = projectRoot || process.cwd();
7030
- logger.info("Initializing Mimir workspace", { projectRoot: root });
6131
+ if (!options.quiet) {
6132
+ logger.info("Initializing Mimir workspace", { projectRoot: root });
6133
+ }
7031
6134
  if (await this.initializer.isWorkspaceInitialized(root)) {
7032
- logger.info("Mimir workspace is already initialized in this directory.");
7033
- logger.info('Run "mimir" to start an interactive chat session.');
6135
+ if (!options.quiet) {
6136
+ logger.info("Mimir workspace is already initialized in this directory.");
6137
+ logger.info('Run "mimir" to start an interactive chat session.');
6138
+ }
7034
6139
  return;
7035
6140
  }
7036
6141
  const result = await this.initializer.initializeWorkspace(root);
7037
- this.initializer.printSummary(result, root);
6142
+ if (!options.quiet) {
6143
+ this.initializer.printSummary(result, root);
6144
+ }
7038
6145
  if (!result.success) {
7039
6146
  process.exit(1);
7040
6147
  }
7041
6148
  }
7042
6149
  };
7043
6150
 
6151
+ // src/cli/commands/UninstallCommand.ts
6152
+ import path8 from "path";
6153
+ import os6 from "os";
6154
+ import React11 from "react";
6155
+ import { render as render3, Box as Box12, Text as Text11 } from "ink";
6156
+ import Spinner from "ink-spinner";
6157
+ import TextInput2 from "ink-text-input";
6158
+ var UninstallCommand = class {
6159
+ constructor(fs4, executor2) {
6160
+ this.fs = fs4;
6161
+ this.executor = executor2;
6162
+ }
6163
+ async execute(options = {}) {
6164
+ try {
6165
+ const autoConfirm = options.yes || options.quiet;
6166
+ let confirmed = autoConfirm;
6167
+ if (!autoConfirm) {
6168
+ confirmed = await this.promptConfirmation();
6169
+ }
6170
+ if (!confirmed) {
6171
+ if (!options.quiet) {
6172
+ logger.info("Uninstall cancelled.");
6173
+ }
6174
+ return;
6175
+ }
6176
+ let keepConfig;
6177
+ if (options.removeConfig !== void 0) {
6178
+ keepConfig = !options.removeConfig;
6179
+ } else if (options.keepConfig !== void 0) {
6180
+ keepConfig = options.keepConfig;
6181
+ } else if (autoConfirm) {
6182
+ keepConfig = true;
6183
+ } else {
6184
+ keepConfig = await this.promptKeepConfig();
6185
+ }
6186
+ const result = await this.uninstall(keepConfig, options.quiet);
6187
+ if (!options.quiet) {
6188
+ this.printSummary(result);
6189
+ }
6190
+ if (!result.success) {
6191
+ process.exit(1);
6192
+ }
6193
+ } catch (error) {
6194
+ if (!options.quiet) {
6195
+ logger.error("Uninstall failed", { error });
6196
+ }
6197
+ process.exit(1);
6198
+ }
6199
+ }
6200
+ async promptConfirmation() {
6201
+ return new Promise((resolve) => {
6202
+ const ConfirmPrompt = () => {
6203
+ const [input, setInput] = React11.useState("");
6204
+ const [submitted, setSubmitted] = React11.useState(false);
6205
+ React11.useEffect(() => {
6206
+ if (submitted) {
6207
+ const answer = input.toLowerCase();
6208
+ resolve(answer === "y" || answer === "yes");
6209
+ }
6210
+ }, [submitted, input]);
6211
+ if (submitted) {
6212
+ return null;
6213
+ }
6214
+ return React11.createElement(
6215
+ Box12,
6216
+ { flexDirection: "column", marginY: 1 },
6217
+ React11.createElement(
6218
+ Box12,
6219
+ { marginBottom: 1 },
6220
+ React11.createElement(
6221
+ Text11,
6222
+ { bold: true, color: "yellow" },
6223
+ "\u26A0\uFE0F WARNING: This will uninstall Mimir from your system."
6224
+ )
6225
+ ),
6226
+ React11.createElement(
6227
+ Box12,
6228
+ null,
6229
+ React11.createElement(Text11, null, "Are you sure you want to continue? (y/N): "),
6230
+ React11.createElement(TextInput2, {
6231
+ value: input,
6232
+ onChange: setInput,
6233
+ onSubmit: () => setSubmitted(true)
6234
+ })
6235
+ )
6236
+ );
6237
+ };
6238
+ render3(React11.createElement(ConfirmPrompt));
6239
+ });
6240
+ }
6241
+ async promptKeepConfig() {
6242
+ return new Promise((resolve) => {
6243
+ const ConfigPrompt = () => {
6244
+ const [input, setInput] = React11.useState("");
6245
+ const [submitted, setSubmitted] = React11.useState(false);
6246
+ React11.useEffect(() => {
6247
+ if (submitted) {
6248
+ const answer = input.toLowerCase();
6249
+ resolve(answer !== "n" && answer !== "no");
6250
+ }
6251
+ }, [submitted, input]);
6252
+ if (submitted) {
6253
+ return null;
6254
+ }
6255
+ return React11.createElement(
6256
+ Box12,
6257
+ { flexDirection: "column", marginY: 1 },
6258
+ React11.createElement(
6259
+ Box12,
6260
+ { marginBottom: 1 },
6261
+ React11.createElement(
6262
+ Text11,
6263
+ null,
6264
+ "Do you want to keep your Mimir configuration and data in ~/.mimir?"
6265
+ )
6266
+ ),
6267
+ React11.createElement(
6268
+ Box12,
6269
+ null,
6270
+ React11.createElement(Text11, null, "Keep configuration? (Y/n): "),
6271
+ React11.createElement(TextInput2, {
6272
+ value: input,
6273
+ onChange: setInput,
6274
+ onSubmit: () => setSubmitted(true)
6275
+ })
6276
+ )
6277
+ );
6278
+ };
6279
+ render3(React11.createElement(ConfigPrompt));
6280
+ });
6281
+ }
6282
+ async uninstall(keepConfig, quiet = false) {
6283
+ const result = {
6284
+ success: true,
6285
+ removed: [],
6286
+ errors: [],
6287
+ keepConfig
6288
+ };
6289
+ let clear;
6290
+ if (!quiet) {
6291
+ const UninstallProgress = () => React11.createElement(
6292
+ Box12,
6293
+ null,
6294
+ React11.createElement(
6295
+ Text11,
6296
+ { color: "cyan" },
6297
+ React11.createElement(Spinner, { type: "dots" }),
6298
+ " Uninstalling Mimir..."
6299
+ )
6300
+ );
6301
+ const rendered = render3(React11.createElement(UninstallProgress));
6302
+ clear = rendered.clear;
6303
+ }
6304
+ try {
6305
+ const homeDir = os6.homedir();
6306
+ const installType = await this.detectInstallType();
6307
+ if (!quiet) {
6308
+ logger.info(`Detected installation type: ${installType}`);
6309
+ }
6310
+ if (installType === "binary") {
6311
+ await this.removeBinaryInstallation(homeDir, result, quiet);
6312
+ }
6313
+ if (installType === "npm") {
6314
+ await this.removeNpmInstallation(result, quiet);
6315
+ }
6316
+ if (!keepConfig) {
6317
+ await this.removeGlobalConfig(homeDir, result, quiet);
6318
+ } else if (!quiet) {
6319
+ logger.info("Keeping global configuration at ~/.mimir");
6320
+ }
6321
+ } catch (error) {
6322
+ result.success = false;
6323
+ result.errors.push(
6324
+ `Uninstall failed: ${error instanceof Error ? error.message : String(error)}`
6325
+ );
6326
+ if (!quiet) {
6327
+ logger.error("Uninstall error", { error });
6328
+ }
6329
+ } finally {
6330
+ if (clear) {
6331
+ clear();
6332
+ }
6333
+ }
6334
+ return result;
6335
+ }
6336
+ async detectInstallType() {
6337
+ try {
6338
+ const scriptPath = process.argv[1];
6339
+ if (!scriptPath) {
6340
+ logger.debug("No script path found in process.argv[1]");
6341
+ return "unknown";
6342
+ }
6343
+ logger.debug(`Detecting install type from script path: ${scriptPath}`);
6344
+ const normalizedPath = path8.normalize(scriptPath).toLowerCase();
6345
+ if (normalizedPath.includes("node_modules")) {
6346
+ logger.debug("Detected npm installation (node_modules in path)");
6347
+ return "npm";
6348
+ }
6349
+ const homeDir = os6.homedir();
6350
+ const mimirBinPath = path8.normalize(path8.join(homeDir, ".mimir", "bin")).toLowerCase();
6351
+ const localBinPath = path8.normalize(path8.join(homeDir, ".local", "bin")).toLowerCase();
6352
+ if (normalizedPath.includes(mimirBinPath)) {
6353
+ logger.debug("Detected binary installation (.mimir/bin in path)");
6354
+ return "binary";
6355
+ }
6356
+ if (normalizedPath.includes(localBinPath)) {
6357
+ logger.debug("Detected binary installation (.local/bin in path)");
6358
+ return "binary";
6359
+ }
6360
+ const binaryPaths = [
6361
+ // Unix binary locations
6362
+ path8.join(homeDir, ".local", "bin", "mimir"),
6363
+ path8.join(homeDir, ".mimir", "bin", "mimir"),
6364
+ // Windows binary locations (.exe, .cmd variants)
6365
+ path8.join(homeDir, ".local", "bin", "mimir.exe"),
6366
+ path8.join(homeDir, ".local", "bin", "mimir.cmd"),
6367
+ path8.join(homeDir, ".mimir", "bin", "mimir.exe"),
6368
+ path8.join(homeDir, ".mimir", "bin", "mimir.cmd")
6369
+ ];
6370
+ for (const binPath of binaryPaths) {
6371
+ if (await this.fs.exists(binPath)) {
6372
+ logger.debug(`Detected binary installation (found file at ${binPath})`);
6373
+ return "binary";
6374
+ }
6375
+ }
6376
+ logger.debug("Could not detect installation type - defaulting to unknown");
6377
+ return "unknown";
6378
+ } catch (error) {
6379
+ logger.debug("Error detecting installation type", { error });
6380
+ return "unknown";
6381
+ }
6382
+ }
6383
+ async removeNpmInstallation(result, quiet = false) {
6384
+ if (!this.executor) {
6385
+ if (!quiet) {
6386
+ logger.warn("Cannot automatically uninstall npm package.");
6387
+ logger.info("Please run manually: npm uninstall -g @codedir/mimir-code");
6388
+ }
6389
+ return;
6390
+ }
6391
+ try {
6392
+ if (!quiet) {
6393
+ logger.info("Removing npm global package...");
6394
+ }
6395
+ const npmResult = await this.executor.execute(
6396
+ "npm",
6397
+ ["uninstall", "-g", "@codedir/mimir-code"],
6398
+ {
6399
+ cwd: process.cwd()
6400
+ }
6401
+ );
6402
+ if (npmResult.exitCode === 0) {
6403
+ result.removed.push("npm global package (@codedir/mimir-code)");
6404
+ if (!quiet) {
6405
+ logger.info("Successfully uninstalled npm package");
6406
+ }
6407
+ } else {
6408
+ throw new Error(`npm uninstall failed: ${npmResult.stderr}`);
6409
+ }
6410
+ } catch (error) {
6411
+ if (!quiet) {
6412
+ logger.error("Failed to uninstall npm package", { error });
6413
+ logger.info("Please run manually: npm uninstall -g @codedir/mimir-code");
6414
+ }
6415
+ result.errors.push(
6416
+ `npm uninstall failed: ${error instanceof Error ? error.message : String(error)}`
6417
+ );
6418
+ }
6419
+ }
6420
+ async removeBinaryInstallation(homeDir, result, quiet = false) {
6421
+ const isWindows = process.platform === "win32";
6422
+ const localBinPath = path8.join(homeDir, ".local", "bin", "mimir");
6423
+ const mimirBinDir = path8.join(homeDir, ".mimir", "bin");
6424
+ if (isWindows) {
6425
+ await this.spawnWindowsCleanup(localBinPath, mimirBinDir, quiet);
6426
+ await this.removeFromWindowsPath(quiet);
6427
+ result.removed.push("Binary (scheduled for deletion after exit)");
6428
+ result.removed.push("PATH entry");
6429
+ if (!quiet) {
6430
+ logger.info("\u2713 Scheduled binary deletion");
6431
+ logger.info("\u2713 Removed from PATH");
6432
+ logger.warn("\u26A0 Cleanup will complete in ~3 seconds");
6433
+ }
6434
+ } else {
6435
+ if (await this.fs.exists(localBinPath)) {
6436
+ await this.fs.unlink(localBinPath);
6437
+ result.removed.push("~/.local/bin/mimir");
6438
+ if (!quiet) {
6439
+ logger.info("Removed binary from ~/.local/bin");
6440
+ }
6441
+ }
6442
+ if (await this.fs.exists(mimirBinDir)) {
6443
+ await this.fs.rmdir(mimirBinDir, { recursive: true });
6444
+ result.removed.push("~/.mimir/bin/");
6445
+ if (!quiet) {
6446
+ logger.info("Removed binary directory");
6447
+ }
6448
+ }
6449
+ if (!quiet) {
6450
+ logger.info("\u2713 Binary uninstalled");
6451
+ logger.warn("\u26A0 Current terminal still has mimir cached");
6452
+ logger.info(" Run: hash -r (to clear shell cache)");
6453
+ }
6454
+ }
6455
+ }
6456
+ async spawnWindowsCleanup(binPath, binDir, quiet) {
6457
+ if (!this.executor) {
6458
+ if (!quiet) {
6459
+ logger.warn("Cannot spawn cleanup process - no executor available");
6460
+ }
6461
+ return;
6462
+ }
6463
+ try {
6464
+ const cleanupScript = `@echo off
6465
+ REM Wait for parent process to exit
6466
+ timeout /t 3 /nobreak >nul 2>&1
6467
+
6468
+ REM Delete binary if it exists
6469
+ if exist "${binPath}" (
6470
+ del /f /q "${binPath}" >nul 2>&1
6471
+ )
6472
+ if exist "${binPath}.exe" (
6473
+ del /f /q "${binPath}.exe" >nul 2>&1
6474
+ )
6475
+ if exist "${binPath}.cmd" (
6476
+ del /f /q "${binPath}.cmd" >nul 2>&1
6477
+ )
6478
+
6479
+ REM Delete binary directory
6480
+ if exist "${binDir}" (
6481
+ rmdir /s /q "${binDir}" >nul 2>&1
6482
+ )
6483
+
6484
+ REM Delete this cleanup script
6485
+ del /f /q "%~f0" >nul 2>&1
6486
+ `;
6487
+ const tempDir = os6.tmpdir();
6488
+ const cleanupPath = path8.join(tempDir, `mimir-cleanup-${Date.now()}.bat`);
6489
+ await this.fs.writeFile(cleanupPath, cleanupScript);
6490
+ const { spawn } = await import("child_process");
6491
+ const child = spawn("cmd", ["/c", cleanupPath], {
6492
+ detached: true,
6493
+ stdio: "ignore",
6494
+ windowsHide: true
6495
+ });
6496
+ child.unref();
6497
+ if (!quiet) {
6498
+ logger.info("Spawned background cleanup process");
6499
+ }
6500
+ } catch (error) {
6501
+ if (!quiet) {
6502
+ logger.error("Failed to spawn cleanup process", { error });
6503
+ }
6504
+ }
6505
+ }
6506
+ async removeFromWindowsPath(quiet) {
6507
+ if (!this.executor) return;
6508
+ try {
6509
+ const result = await this.executor.execute(
6510
+ "powershell",
6511
+ ["-NoProfile", "-Command", '[Environment]::GetEnvironmentVariable("Path", "User")'],
6512
+ { cwd: process.cwd() }
6513
+ );
6514
+ if (result.exitCode !== 0) {
6515
+ throw new Error("Failed to read PATH");
6516
+ }
6517
+ const currentPath = result.stdout.trim();
6518
+ const pathEntries = currentPath.split(";").filter(Boolean);
6519
+ const filteredEntries = pathEntries.filter((entry) => {
6520
+ const normalizedEntry = path8.normalize(entry.trim()).toLowerCase();
6521
+ return !normalizedEntry.includes("mimir");
6522
+ });
6523
+ if (filteredEntries.length < pathEntries.length) {
6524
+ const newPath = filteredEntries.join(";");
6525
+ await this.executor.execute(
6526
+ "powershell",
6527
+ [
6528
+ "-NoProfile",
6529
+ "-Command",
6530
+ `[Environment]::SetEnvironmentVariable("Path", "${newPath}", "User")`
6531
+ ],
6532
+ { cwd: process.cwd() }
6533
+ );
6534
+ const removedCount = pathEntries.length - filteredEntries.length;
6535
+ if (!quiet) {
6536
+ logger.info(`Removed ${removedCount} PATH entry/entries containing 'mimir'`);
6537
+ }
6538
+ }
6539
+ } catch (error) {
6540
+ if (!quiet) {
6541
+ logger.warn("Failed to remove from PATH", { error });
6542
+ logger.info("You may need to manually remove from PATH");
6543
+ }
6544
+ }
6545
+ }
6546
+ async removeGlobalConfig(homeDir, result, quiet = false) {
6547
+ const mimirDir = path8.join(homeDir, ".mimir");
6548
+ if (await this.fs.exists(mimirDir)) {
6549
+ await this.fs.rmdir(mimirDir, { recursive: true });
6550
+ result.removed.push("~/.mimir/");
6551
+ if (!quiet) {
6552
+ logger.info("Removed configuration directory: ~/.mimir");
6553
+ logger.info("All Mimir data has been deleted.");
6554
+ }
6555
+ }
6556
+ }
6557
+ /* eslint-disable no-console */
6558
+ printSummary(result) {
6559
+ console.log("");
6560
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
6561
+ if (result.success) {
6562
+ console.log("\u2705 Mimir has been uninstalled");
6563
+ } else {
6564
+ console.log("\u274C Uninstall completed with errors");
6565
+ }
6566
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
6567
+ if (result.removed.length > 0) {
6568
+ console.log("");
6569
+ console.log("Removed:");
6570
+ result.removed.forEach((item) => console.log(` - ${item}`));
6571
+ }
6572
+ if (result.keepConfig) {
6573
+ console.log("");
6574
+ console.log("Configuration preserved:");
6575
+ console.log(" - ~/.mimir/ (your settings and data)");
6576
+ console.log("");
6577
+ console.log("To remove it later, run:");
6578
+ console.log(" mimir uninstall --yes --remove-config");
6579
+ console.log(" or manually: rm -rf ~/.mimir");
6580
+ }
6581
+ if (result.errors.length > 0) {
6582
+ console.log("");
6583
+ console.log("Errors:");
6584
+ result.errors.forEach((error) => console.log(` - ${error}`));
6585
+ }
6586
+ console.log("");
6587
+ console.log("Thank you for using Mimir! \u{1F44B}");
6588
+ console.log("");
6589
+ }
6590
+ /* eslint-enable no-console */
6591
+ };
6592
+
7044
6593
  // src/cli.ts
7045
6594
  var fs3 = new FileSystemAdapter();
6595
+ var executor = new ProcessExecutorAdapter();
7046
6596
  var configLoader = new ConfigLoader(fs3);
7047
6597
  var firstRunDetector = new FirstRunDetector(fs3);
7048
6598
  var setupCommand = new SetupCommand(configLoader);
7049
6599
  var chatCommand = new ChatCommand(configLoader, firstRunDetector, setupCommand, fs3);
7050
6600
  var initCommand = new InitCommand(fs3, configLoader);
6601
+ var uninstallCommand = new UninstallCommand(fs3, executor);
7051
6602
  var program = new Command();
7052
6603
  program.name("mimir").description("Platform-agnostic, BYOK AI coding agent CLI").version("0.1.0");
7053
6604
  program.command("setup").description("Run setup wizard").action(async () => {
@@ -7058,10 +6609,16 @@ program.command("chat", { isDefault: true }).description("Start interactive chat
7058
6609
  await chatCommand.execute();
7059
6610
  process.exit(0);
7060
6611
  });
7061
- program.command("init").description("Initialize Mimir in current project").action(async () => {
7062
- await initCommand.execute();
6612
+ program.command("init").description("Initialize Mimir in current project").option("--no-interactive", "Run without interactive prompts (for automated setup)").option("-q, --quiet", "Suppress output").action(async (options) => {
6613
+ await initCommand.execute(void 0, options);
7063
6614
  process.exit(0);
7064
6615
  });
6616
+ program.command("uninstall").description("Uninstall Mimir from your system").option("-y, --yes", "Skip confirmation prompts").option("--keep-config", "Keep configuration directory (~/.mimir)").option("--remove-config", "Remove configuration directory (~/.mimir)").option("-q, --quiet", "Suppress output (implies --yes)").action(
6617
+ async (options) => {
6618
+ await uninstallCommand.execute(options);
6619
+ process.exit(0);
6620
+ }
6621
+ );
7065
6622
  var history = program.command("history").description("Manage conversation history");
7066
6623
  history.command("list").description("List recent conversations").action(() => {
7067
6624
  logger.warn("Listing conversations... (not implemented yet)");
@@ -7091,15 +6648,15 @@ cost.command("compare").description("Compare provider costs").action(() => {
7091
6648
  program.command("doctor").description("Run diagnostics").action(() => {
7092
6649
  logger.warn("Running diagnostics... (not implemented yet)");
7093
6650
  });
7094
- var permissions2 = program.command("permissions").description("Manage command permissions");
7095
- permissions2.command("list").description("List allowed commands").action(() => {
6651
+ var permissions = program.command("permissions").description("Manage command permissions");
6652
+ permissions.command("list").description("List allowed commands").action(() => {
7096
6653
  logger.warn("Listing permissions... (not implemented yet)");
7097
6654
  });
7098
- permissions2.command("add <pattern>").description("Add command to allowlist").action((pattern) => {
6655
+ permissions.command("add <pattern>").description("Add command to allowlist").action((pattern) => {
7099
6656
  logger.warn(`Adding ${pattern} to allowlist... (not implemented yet)`);
7100
6657
  });
7101
- permissions2.command("remove <pattern>").description("Remove command from allowlist").action((pattern) => {
6658
+ permissions.command("remove <pattern>").description("Remove command from allowlist").action((pattern) => {
7102
6659
  logger.warn(`Removing ${pattern} from allowlist... (not implemented yet)`);
7103
6660
  });
7104
6661
  program.parse();
7105
- //# sourceMappingURL=cli.js.map
6662
+ //# sourceMappingURL=cli.mjs.map