@learnrudi/cli 1.10.1 → 1.10.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1296,17 +1296,17 @@ var require_visit = __commonJS({
1296
1296
  visit.BREAK = BREAK;
1297
1297
  visit.SKIP = SKIP;
1298
1298
  visit.REMOVE = REMOVE;
1299
- function visit_(key, node, visitor, path35) {
1300
- const ctrl = callVisitor(key, node, visitor, path35);
1299
+ function visit_(key, node, visitor, path34) {
1300
+ const ctrl = callVisitor(key, node, visitor, path34);
1301
1301
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1302
- replaceNode(key, path35, ctrl);
1303
- return visit_(key, ctrl, visitor, path35);
1302
+ replaceNode(key, path34, ctrl);
1303
+ return visit_(key, ctrl, visitor, path34);
1304
1304
  }
1305
1305
  if (typeof ctrl !== "symbol") {
1306
1306
  if (identity.isCollection(node)) {
1307
- path35 = Object.freeze(path35.concat(node));
1307
+ path34 = Object.freeze(path34.concat(node));
1308
1308
  for (let i2 = 0; i2 < node.items.length; ++i2) {
1309
- const ci = visit_(i2, node.items[i2], visitor, path35);
1309
+ const ci = visit_(i2, node.items[i2], visitor, path34);
1310
1310
  if (typeof ci === "number")
1311
1311
  i2 = ci - 1;
1312
1312
  else if (ci === BREAK)
@@ -1317,13 +1317,13 @@ var require_visit = __commonJS({
1317
1317
  }
1318
1318
  }
1319
1319
  } else if (identity.isPair(node)) {
1320
- path35 = Object.freeze(path35.concat(node));
1321
- const ck = visit_("key", node.key, visitor, path35);
1320
+ path34 = Object.freeze(path34.concat(node));
1321
+ const ck = visit_("key", node.key, visitor, path34);
1322
1322
  if (ck === BREAK)
1323
1323
  return BREAK;
1324
1324
  else if (ck === REMOVE)
1325
1325
  node.key = null;
1326
- const cv = visit_("value", node.value, visitor, path35);
1326
+ const cv = visit_("value", node.value, visitor, path34);
1327
1327
  if (cv === BREAK)
1328
1328
  return BREAK;
1329
1329
  else if (cv === REMOVE)
@@ -1344,17 +1344,17 @@ var require_visit = __commonJS({
1344
1344
  visitAsync.BREAK = BREAK;
1345
1345
  visitAsync.SKIP = SKIP;
1346
1346
  visitAsync.REMOVE = REMOVE;
1347
- async function visitAsync_(key, node, visitor, path35) {
1348
- const ctrl = await callVisitor(key, node, visitor, path35);
1347
+ async function visitAsync_(key, node, visitor, path34) {
1348
+ const ctrl = await callVisitor(key, node, visitor, path34);
1349
1349
  if (identity.isNode(ctrl) || identity.isPair(ctrl)) {
1350
- replaceNode(key, path35, ctrl);
1351
- return visitAsync_(key, ctrl, visitor, path35);
1350
+ replaceNode(key, path34, ctrl);
1351
+ return visitAsync_(key, ctrl, visitor, path34);
1352
1352
  }
1353
1353
  if (typeof ctrl !== "symbol") {
1354
1354
  if (identity.isCollection(node)) {
1355
- path35 = Object.freeze(path35.concat(node));
1355
+ path34 = Object.freeze(path34.concat(node));
1356
1356
  for (let i2 = 0; i2 < node.items.length; ++i2) {
1357
- const ci = await visitAsync_(i2, node.items[i2], visitor, path35);
1357
+ const ci = await visitAsync_(i2, node.items[i2], visitor, path34);
1358
1358
  if (typeof ci === "number")
1359
1359
  i2 = ci - 1;
1360
1360
  else if (ci === BREAK)
@@ -1365,13 +1365,13 @@ var require_visit = __commonJS({
1365
1365
  }
1366
1366
  }
1367
1367
  } else if (identity.isPair(node)) {
1368
- path35 = Object.freeze(path35.concat(node));
1369
- const ck = await visitAsync_("key", node.key, visitor, path35);
1368
+ path34 = Object.freeze(path34.concat(node));
1369
+ const ck = await visitAsync_("key", node.key, visitor, path34);
1370
1370
  if (ck === BREAK)
1371
1371
  return BREAK;
1372
1372
  else if (ck === REMOVE)
1373
1373
  node.key = null;
1374
- const cv = await visitAsync_("value", node.value, visitor, path35);
1374
+ const cv = await visitAsync_("value", node.value, visitor, path34);
1375
1375
  if (cv === BREAK)
1376
1376
  return BREAK;
1377
1377
  else if (cv === REMOVE)
@@ -1398,23 +1398,23 @@ var require_visit = __commonJS({
1398
1398
  }
1399
1399
  return visitor;
1400
1400
  }
1401
- function callVisitor(key, node, visitor, path35) {
1401
+ function callVisitor(key, node, visitor, path34) {
1402
1402
  if (typeof visitor === "function")
1403
- return visitor(key, node, path35);
1403
+ return visitor(key, node, path34);
1404
1404
  if (identity.isMap(node))
1405
- return visitor.Map?.(key, node, path35);
1405
+ return visitor.Map?.(key, node, path34);
1406
1406
  if (identity.isSeq(node))
1407
- return visitor.Seq?.(key, node, path35);
1407
+ return visitor.Seq?.(key, node, path34);
1408
1408
  if (identity.isPair(node))
1409
- return visitor.Pair?.(key, node, path35);
1409
+ return visitor.Pair?.(key, node, path34);
1410
1410
  if (identity.isScalar(node))
1411
- return visitor.Scalar?.(key, node, path35);
1411
+ return visitor.Scalar?.(key, node, path34);
1412
1412
  if (identity.isAlias(node))
1413
- return visitor.Alias?.(key, node, path35);
1413
+ return visitor.Alias?.(key, node, path34);
1414
1414
  return void 0;
1415
1415
  }
1416
- function replaceNode(key, path35, node) {
1417
- const parent = path35[path35.length - 1];
1416
+ function replaceNode(key, path34, node) {
1417
+ const parent = path34[path34.length - 1];
1418
1418
  if (identity.isCollection(parent)) {
1419
1419
  parent.items[key] = node;
1420
1420
  } else if (identity.isPair(parent)) {
@@ -2022,10 +2022,10 @@ var require_Collection = __commonJS({
2022
2022
  var createNode = require_createNode();
2023
2023
  var identity = require_identity();
2024
2024
  var Node = require_Node();
2025
- function collectionFromPath(schema, path35, value) {
2025
+ function collectionFromPath(schema, path34, value) {
2026
2026
  let v2 = value;
2027
- for (let i2 = path35.length - 1; i2 >= 0; --i2) {
2028
- const k2 = path35[i2];
2027
+ for (let i2 = path34.length - 1; i2 >= 0; --i2) {
2028
+ const k2 = path34[i2];
2029
2029
  if (typeof k2 === "number" && Number.isInteger(k2) && k2 >= 0) {
2030
2030
  const a2 = [];
2031
2031
  a2[k2] = v2;
@@ -2044,7 +2044,7 @@ var require_Collection = __commonJS({
2044
2044
  sourceObjects: /* @__PURE__ */ new Map()
2045
2045
  });
2046
2046
  }
2047
- var isEmptyPath = (path35) => path35 == null || typeof path35 === "object" && !!path35[Symbol.iterator]().next().done;
2047
+ var isEmptyPath = (path34) => path34 == null || typeof path34 === "object" && !!path34[Symbol.iterator]().next().done;
2048
2048
  var Collection = class extends Node.NodeBase {
2049
2049
  constructor(type, schema) {
2050
2050
  super(type);
@@ -2074,11 +2074,11 @@ var require_Collection = __commonJS({
2074
2074
  * be a Pair instance or a `{ key, value }` object, which may not have a key
2075
2075
  * that already exists in the map.
2076
2076
  */
2077
- addIn(path35, value) {
2078
- if (isEmptyPath(path35))
2077
+ addIn(path34, value) {
2078
+ if (isEmptyPath(path34))
2079
2079
  this.add(value);
2080
2080
  else {
2081
- const [key, ...rest] = path35;
2081
+ const [key, ...rest] = path34;
2082
2082
  const node = this.get(key, true);
2083
2083
  if (identity.isCollection(node))
2084
2084
  node.addIn(rest, value);
@@ -2092,8 +2092,8 @@ var require_Collection = __commonJS({
2092
2092
  * Removes a value from the collection.
2093
2093
  * @returns `true` if the item was found and removed.
2094
2094
  */
2095
- deleteIn(path35) {
2096
- const [key, ...rest] = path35;
2095
+ deleteIn(path34) {
2096
+ const [key, ...rest] = path34;
2097
2097
  if (rest.length === 0)
2098
2098
  return this.delete(key);
2099
2099
  const node = this.get(key, true);
@@ -2107,8 +2107,8 @@ var require_Collection = __commonJS({
2107
2107
  * scalar values from their surrounding node; to disable set `keepScalar` to
2108
2108
  * `true` (collections are always returned intact).
2109
2109
  */
2110
- getIn(path35, keepScalar) {
2111
- const [key, ...rest] = path35;
2110
+ getIn(path34, keepScalar) {
2111
+ const [key, ...rest] = path34;
2112
2112
  const node = this.get(key, true);
2113
2113
  if (rest.length === 0)
2114
2114
  return !keepScalar && identity.isScalar(node) ? node.value : node;
@@ -2126,8 +2126,8 @@ var require_Collection = __commonJS({
2126
2126
  /**
2127
2127
  * Checks if the collection includes a value with the key `key`.
2128
2128
  */
2129
- hasIn(path35) {
2130
- const [key, ...rest] = path35;
2129
+ hasIn(path34) {
2130
+ const [key, ...rest] = path34;
2131
2131
  if (rest.length === 0)
2132
2132
  return this.has(key);
2133
2133
  const node = this.get(key, true);
@@ -2137,8 +2137,8 @@ var require_Collection = __commonJS({
2137
2137
  * Sets a value in this collection. For `!!set`, `value` needs to be a
2138
2138
  * boolean to add/remove the item from the set.
2139
2139
  */
2140
- setIn(path35, value) {
2141
- const [key, ...rest] = path35;
2140
+ setIn(path34, value) {
2141
+ const [key, ...rest] = path34;
2142
2142
  if (rest.length === 0) {
2143
2143
  this.set(key, value);
2144
2144
  } else {
@@ -4642,9 +4642,9 @@ var require_Document = __commonJS({
4642
4642
  this.contents.add(value);
4643
4643
  }
4644
4644
  /** Adds a value to the document. */
4645
- addIn(path35, value) {
4645
+ addIn(path34, value) {
4646
4646
  if (assertCollection(this.contents))
4647
- this.contents.addIn(path35, value);
4647
+ this.contents.addIn(path34, value);
4648
4648
  }
4649
4649
  /**
4650
4650
  * Create a new `Alias` node, ensuring that the target `node` has the required anchor.
@@ -4719,14 +4719,14 @@ var require_Document = __commonJS({
4719
4719
  * Removes a value from the document.
4720
4720
  * @returns `true` if the item was found and removed.
4721
4721
  */
4722
- deleteIn(path35) {
4723
- if (Collection.isEmptyPath(path35)) {
4722
+ deleteIn(path34) {
4723
+ if (Collection.isEmptyPath(path34)) {
4724
4724
  if (this.contents == null)
4725
4725
  return false;
4726
4726
  this.contents = null;
4727
4727
  return true;
4728
4728
  }
4729
- return assertCollection(this.contents) ? this.contents.deleteIn(path35) : false;
4729
+ return assertCollection(this.contents) ? this.contents.deleteIn(path34) : false;
4730
4730
  }
4731
4731
  /**
4732
4732
  * Returns item at `key`, or `undefined` if not found. By default unwraps
@@ -4741,10 +4741,10 @@ var require_Document = __commonJS({
4741
4741
  * scalar values from their surrounding node; to disable set `keepScalar` to
4742
4742
  * `true` (collections are always returned intact).
4743
4743
  */
4744
- getIn(path35, keepScalar) {
4745
- if (Collection.isEmptyPath(path35))
4744
+ getIn(path34, keepScalar) {
4745
+ if (Collection.isEmptyPath(path34))
4746
4746
  return !keepScalar && identity.isScalar(this.contents) ? this.contents.value : this.contents;
4747
- return identity.isCollection(this.contents) ? this.contents.getIn(path35, keepScalar) : void 0;
4747
+ return identity.isCollection(this.contents) ? this.contents.getIn(path34, keepScalar) : void 0;
4748
4748
  }
4749
4749
  /**
4750
4750
  * Checks if the document includes a value with the key `key`.
@@ -4755,10 +4755,10 @@ var require_Document = __commonJS({
4755
4755
  /**
4756
4756
  * Checks if the document includes a value at `path`.
4757
4757
  */
4758
- hasIn(path35) {
4759
- if (Collection.isEmptyPath(path35))
4758
+ hasIn(path34) {
4759
+ if (Collection.isEmptyPath(path34))
4760
4760
  return this.contents !== void 0;
4761
- return identity.isCollection(this.contents) ? this.contents.hasIn(path35) : false;
4761
+ return identity.isCollection(this.contents) ? this.contents.hasIn(path34) : false;
4762
4762
  }
4763
4763
  /**
4764
4764
  * Sets a value in this document. For `!!set`, `value` needs to be a
@@ -4775,13 +4775,13 @@ var require_Document = __commonJS({
4775
4775
  * Sets a value in this document. For `!!set`, `value` needs to be a
4776
4776
  * boolean to add/remove the item from the set.
4777
4777
  */
4778
- setIn(path35, value) {
4779
- if (Collection.isEmptyPath(path35)) {
4778
+ setIn(path34, value) {
4779
+ if (Collection.isEmptyPath(path34)) {
4780
4780
  this.contents = value;
4781
4781
  } else if (this.contents == null) {
4782
- this.contents = Collection.collectionFromPath(this.schema, Array.from(path35), value);
4782
+ this.contents = Collection.collectionFromPath(this.schema, Array.from(path34), value);
4783
4783
  } else if (assertCollection(this.contents)) {
4784
- this.contents.setIn(path35, value);
4784
+ this.contents.setIn(path34, value);
4785
4785
  }
4786
4786
  }
4787
4787
  /**
@@ -6733,9 +6733,9 @@ var require_cst_visit = __commonJS({
6733
6733
  visit.BREAK = BREAK;
6734
6734
  visit.SKIP = SKIP;
6735
6735
  visit.REMOVE = REMOVE;
6736
- visit.itemAtPath = (cst, path35) => {
6736
+ visit.itemAtPath = (cst, path34) => {
6737
6737
  let item = cst;
6738
- for (const [field, index] of path35) {
6738
+ for (const [field, index] of path34) {
6739
6739
  const tok = item?.[field];
6740
6740
  if (tok && "items" in tok) {
6741
6741
  item = tok.items[index];
@@ -6744,23 +6744,23 @@ var require_cst_visit = __commonJS({
6744
6744
  }
6745
6745
  return item;
6746
6746
  };
6747
- visit.parentCollection = (cst, path35) => {
6748
- const parent = visit.itemAtPath(cst, path35.slice(0, -1));
6749
- const field = path35[path35.length - 1][0];
6747
+ visit.parentCollection = (cst, path34) => {
6748
+ const parent = visit.itemAtPath(cst, path34.slice(0, -1));
6749
+ const field = path34[path34.length - 1][0];
6750
6750
  const coll = parent?.[field];
6751
6751
  if (coll && "items" in coll)
6752
6752
  return coll;
6753
6753
  throw new Error("Parent collection not found");
6754
6754
  };
6755
- function _visit(path35, item, visitor) {
6756
- let ctrl = visitor(item, path35);
6755
+ function _visit(path34, item, visitor) {
6756
+ let ctrl = visitor(item, path34);
6757
6757
  if (typeof ctrl === "symbol")
6758
6758
  return ctrl;
6759
6759
  for (const field of ["key", "value"]) {
6760
6760
  const token = item[field];
6761
6761
  if (token && "items" in token) {
6762
6762
  for (let i2 = 0; i2 < token.items.length; ++i2) {
6763
- const ci = _visit(Object.freeze(path35.concat([[field, i2]])), token.items[i2], visitor);
6763
+ const ci = _visit(Object.freeze(path34.concat([[field, i2]])), token.items[i2], visitor);
6764
6764
  if (typeof ci === "number")
6765
6765
  i2 = ci - 1;
6766
6766
  else if (ci === BREAK)
@@ -6771,10 +6771,10 @@ var require_cst_visit = __commonJS({
6771
6771
  }
6772
6772
  }
6773
6773
  if (typeof ctrl === "function" && field === "key")
6774
- ctrl = ctrl(item, path35);
6774
+ ctrl = ctrl(item, path34);
6775
6775
  }
6776
6776
  }
6777
- return typeof ctrl === "function" ? ctrl(item, path35) : ctrl;
6777
+ return typeof ctrl === "function" ? ctrl(item, path34) : ctrl;
6778
6778
  }
6779
6779
  exports2.visit = visit;
6780
6780
  }
@@ -8059,14 +8059,14 @@ var require_parser = __commonJS({
8059
8059
  case "scalar":
8060
8060
  case "single-quoted-scalar":
8061
8061
  case "double-quoted-scalar": {
8062
- const fs35 = this.flowScalar(this.type);
8062
+ const fs34 = this.flowScalar(this.type);
8063
8063
  if (atNextItem || it2.value) {
8064
- map.items.push({ start, key: fs35, sep: [] });
8064
+ map.items.push({ start, key: fs34, sep: [] });
8065
8065
  this.onKeyLine = true;
8066
8066
  } else if (it2.sep) {
8067
- this.stack.push(fs35);
8067
+ this.stack.push(fs34);
8068
8068
  } else {
8069
- Object.assign(it2, { key: fs35, sep: [] });
8069
+ Object.assign(it2, { key: fs34, sep: [] });
8070
8070
  this.onKeyLine = true;
8071
8071
  }
8072
8072
  return;
@@ -8194,13 +8194,13 @@ var require_parser = __commonJS({
8194
8194
  case "scalar":
8195
8195
  case "single-quoted-scalar":
8196
8196
  case "double-quoted-scalar": {
8197
- const fs35 = this.flowScalar(this.type);
8197
+ const fs34 = this.flowScalar(this.type);
8198
8198
  if (!it2 || it2.value)
8199
- fc.items.push({ start: [], key: fs35, sep: [] });
8199
+ fc.items.push({ start: [], key: fs34, sep: [] });
8200
8200
  else if (it2.sep)
8201
- this.stack.push(fs35);
8201
+ this.stack.push(fs34);
8202
8202
  else
8203
- Object.assign(it2, { key: fs35, sep: [] });
8203
+ Object.assign(it2, { key: fs34, sep: [] });
8204
8204
  return;
8205
8205
  }
8206
8206
  case "flow-map-end":
@@ -13605,8 +13605,8 @@ var require_utils = __commonJS({
13605
13605
  }
13606
13606
  return ind;
13607
13607
  }
13608
- function removeDotSegments(path35) {
13609
- let input = path35;
13608
+ function removeDotSegments(path34) {
13609
+ let input = path34;
13610
13610
  const output = [];
13611
13611
  let nextSlash = -1;
13612
13612
  let len = 0;
@@ -13805,8 +13805,8 @@ var require_schemes = __commonJS({
13805
13805
  wsComponent.secure = void 0;
13806
13806
  }
13807
13807
  if (wsComponent.resourceName) {
13808
- const [path35, query] = wsComponent.resourceName.split("?");
13809
- wsComponent.path = path35 && path35 !== "/" ? path35 : void 0;
13808
+ const [path34, query] = wsComponent.resourceName.split("?");
13809
+ wsComponent.path = path34 && path34 !== "/" ? path34 : void 0;
13810
13810
  wsComponent.query = query;
13811
13811
  wsComponent.resourceName = void 0;
13812
13812
  }
@@ -17159,12 +17159,12 @@ var require_dist2 = __commonJS({
17159
17159
  throw new Error(`Unknown format "${name}"`);
17160
17160
  return f2;
17161
17161
  };
17162
- function addFormats2(ajv2, list, fs35, exportName) {
17162
+ function addFormats2(ajv2, list, fs34, exportName) {
17163
17163
  var _a2;
17164
17164
  var _b;
17165
17165
  (_a2 = (_b = ajv2.opts.code).formats) !== null && _a2 !== void 0 ? _a2 : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
17166
17166
  for (const f2 of list)
17167
- ajv2.addFormat(f2, fs35[f2]);
17167
+ ajv2.addFormat(f2, fs34[f2]);
17168
17168
  }
17169
17169
  module2.exports = exports2 = formatsPlugin;
17170
17170
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -18864,14 +18864,14 @@ var require_url_state_machine = __commonJS({
18864
18864
  return url.replace(/\u0009|\u000A|\u000D/g, "");
18865
18865
  }
18866
18866
  function shortenPath(url) {
18867
- const path35 = url.path;
18868
- if (path35.length === 0) {
18867
+ const path34 = url.path;
18868
+ if (path34.length === 0) {
18869
18869
  return;
18870
18870
  }
18871
- if (url.scheme === "file" && path35.length === 1 && isNormalizedWindowsDriveLetter(path35[0])) {
18871
+ if (url.scheme === "file" && path34.length === 1 && isNormalizedWindowsDriveLetter(path34[0])) {
18872
18872
  return;
18873
18873
  }
18874
- path35.pop();
18874
+ path34.pop();
18875
18875
  }
18876
18876
  function includesCredentials(url) {
18877
18877
  return url.username !== "" || url.password !== "";
@@ -24855,14 +24855,14 @@ __export(fileFromPath_exports, {
24855
24855
  fileFromPathSync: () => fileFromPathSync,
24856
24856
  isFile: () => isFile
24857
24857
  });
24858
- function createFileFromPath(path35, { mtimeMs, size }, filenameOrOptions, options = {}) {
24858
+ function createFileFromPath(path34, { mtimeMs, size }, filenameOrOptions, options = {}) {
24859
24859
  let filename;
24860
24860
  if (isPlainObject_default2(filenameOrOptions)) {
24861
24861
  [options, filename] = [filenameOrOptions, void 0];
24862
24862
  } else {
24863
24863
  filename = filenameOrOptions;
24864
24864
  }
24865
- const file = new FileFromPath({ path: path35, size, lastModified: mtimeMs });
24865
+ const file = new FileFromPath({ path: path34, size, lastModified: mtimeMs });
24866
24866
  if (!filename) {
24867
24867
  filename = file.name;
24868
24868
  }
@@ -24871,13 +24871,13 @@ function createFileFromPath(path35, { mtimeMs, size }, filenameOrOptions, option
24871
24871
  lastModified: file.lastModified
24872
24872
  });
24873
24873
  }
24874
- function fileFromPathSync(path35, filenameOrOptions, options = {}) {
24875
- const stats = (0, import_fs16.statSync)(path35);
24876
- return createFileFromPath(path35, stats, filenameOrOptions, options);
24874
+ function fileFromPathSync(path34, filenameOrOptions, options = {}) {
24875
+ const stats = (0, import_fs16.statSync)(path34);
24876
+ return createFileFromPath(path34, stats, filenameOrOptions, options);
24877
24877
  }
24878
- async function fileFromPath2(path35, filenameOrOptions, options) {
24879
- const stats = await import_fs16.promises.stat(path35);
24880
- return createFileFromPath(path35, stats, filenameOrOptions, options);
24878
+ async function fileFromPath2(path34, filenameOrOptions, options) {
24879
+ const stats = await import_fs16.promises.stat(path34);
24880
+ return createFileFromPath(path34, stats, filenameOrOptions, options);
24881
24881
  }
24882
24882
  var import_fs16, import_path17, import_node_domexception, __classPrivateFieldSet4, __classPrivateFieldGet5, _FileFromPath_path, _FileFromPath_start, MESSAGE, FileFromPath;
24883
24883
  var init_fileFromPath = __esm({
@@ -24938,13 +24938,13 @@ var init_fileFromPath = __esm({
24938
24938
  });
24939
24939
 
24940
24940
  // node_modules/.pnpm/openai@4.104.0/node_modules/openai/_shims/node-runtime.mjs
24941
- async function fileFromPath3(path35, ...args) {
24941
+ async function fileFromPath3(path34, ...args) {
24942
24942
  const { fileFromPath: _fileFromPath } = await Promise.resolve().then(() => (init_fileFromPath(), fileFromPath_exports));
24943
24943
  if (!fileFromPathWarned) {
24944
- console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path35)}) instead`);
24944
+ console.warn(`fileFromPath is deprecated; use fs.createReadStream(${JSON.stringify(path34)}) instead`);
24945
24945
  fileFromPathWarned = true;
24946
24946
  }
24947
- return await _fileFromPath(path35, ...args);
24947
+ return await _fileFromPath(path34, ...args);
24948
24948
  }
24949
24949
  async function getMultipartRequestOptions2(form, opts) {
24950
24950
  const encoder = new FormDataEncoder(form);
@@ -25877,29 +25877,29 @@ var init_core = __esm({
25877
25877
  defaultIdempotencyKey() {
25878
25878
  return `stainless-node-retry-${uuid4()}`;
25879
25879
  }
25880
- get(path35, opts) {
25881
- return this.methodRequest("get", path35, opts);
25880
+ get(path34, opts) {
25881
+ return this.methodRequest("get", path34, opts);
25882
25882
  }
25883
- post(path35, opts) {
25884
- return this.methodRequest("post", path35, opts);
25883
+ post(path34, opts) {
25884
+ return this.methodRequest("post", path34, opts);
25885
25885
  }
25886
- patch(path35, opts) {
25887
- return this.methodRequest("patch", path35, opts);
25886
+ patch(path34, opts) {
25887
+ return this.methodRequest("patch", path34, opts);
25888
25888
  }
25889
- put(path35, opts) {
25890
- return this.methodRequest("put", path35, opts);
25889
+ put(path34, opts) {
25890
+ return this.methodRequest("put", path34, opts);
25891
25891
  }
25892
- delete(path35, opts) {
25893
- return this.methodRequest("delete", path35, opts);
25892
+ delete(path34, opts) {
25893
+ return this.methodRequest("delete", path34, opts);
25894
25894
  }
25895
- methodRequest(method, path35, opts) {
25895
+ methodRequest(method, path34, opts) {
25896
25896
  return this.request(Promise.resolve(opts).then(async (opts2) => {
25897
25897
  const body = opts2 && isBlobLike(opts2?.body) ? new DataView(await opts2.body.arrayBuffer()) : opts2?.body instanceof DataView ? opts2.body : opts2?.body instanceof ArrayBuffer ? new DataView(opts2.body) : opts2 && ArrayBuffer.isView(opts2?.body) ? new DataView(opts2.body.buffer) : opts2?.body;
25898
- return { method, path: path35, ...opts2, body };
25898
+ return { method, path: path34, ...opts2, body };
25899
25899
  }));
25900
25900
  }
25901
- getAPIList(path35, Page2, opts) {
25902
- return this.requestAPIList(Page2, { method: "get", path: path35, ...opts });
25901
+ getAPIList(path34, Page2, opts) {
25902
+ return this.requestAPIList(Page2, { method: "get", path: path34, ...opts });
25903
25903
  }
25904
25904
  calculateContentLength(body) {
25905
25905
  if (typeof body === "string") {
@@ -25918,10 +25918,10 @@ var init_core = __esm({
25918
25918
  }
25919
25919
  buildRequest(inputOptions, { retryCount = 0 } = {}) {
25920
25920
  const options = { ...inputOptions };
25921
- const { method, path: path35, query, headers = {} } = options;
25921
+ const { method, path: path34, query, headers = {} } = options;
25922
25922
  const body = ArrayBuffer.isView(options.body) || options.__binaryRequest && typeof options.body === "string" ? options.body : isMultipartBody(options.body) ? options.body.body : options.body ? JSON.stringify(options.body, null, 2) : null;
25923
25923
  const contentLength = this.calculateContentLength(body);
25924
- const url = this.buildURL(path35, query);
25924
+ const url = this.buildURL(path34, query);
25925
25925
  if ("timeout" in options)
25926
25926
  validatePositiveInteger("timeout", options.timeout);
25927
25927
  options.timeout = options.timeout ?? this.timeout;
@@ -26037,8 +26037,8 @@ var init_core = __esm({
26037
26037
  const request = this.makeRequest(options, null);
26038
26038
  return new PagePromise(this, request, Page2);
26039
26039
  }
26040
- buildURL(path35, query) {
26041
- const url = isAbsoluteURL(path35) ? new URL(path35) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path35.startsWith("/") ? path35.slice(1) : path35));
26040
+ buildURL(path34, query) {
26041
+ const url = isAbsoluteURL(path34) ? new URL(path34) : new URL(this.baseURL + (this.baseURL.endsWith("/") && path34.startsWith("/") ? path34.slice(1) : path34));
26042
26042
  const defaultQuery = this.defaultQuery();
26043
26043
  if (!isEmptyObj(defaultQuery)) {
26044
26044
  query = { ...defaultQuery, ...query };
@@ -31848,60 +31848,64 @@ USAGE
31848
31848
  SETUP
31849
31849
  init Bootstrap RUDI (download runtimes, create shims)
31850
31850
 
31851
- INTROSPECTION
31852
- home Show ~/.rudi structure and installed packages
31853
- stacks List installed stacks
31854
- runtimes List installed runtimes
31855
- binaries List installed binaries
31856
- agents List installed agents
31857
- prompts List installed prompts
31858
- doctor Check system health and dependencies
31859
- doctor --all Show all available runtimes/binaries from registry
31860
-
31861
- PACKAGE MANAGEMENT
31851
+ REGISTRY
31862
31852
  search <query> Search registry for packages
31863
31853
  search --all List all available packages
31864
31854
  install <pkg> Install a package
31865
31855
  remove <pkg> Remove a package
31866
31856
  update [pkg] Update packages
31867
- run <stack> Run a stack
31868
31857
 
31869
- DATABASE
31870
- db stats Show database statistics
31871
- db search <query> Search conversation history
31872
- db reset --force Delete all data
31873
- db vacuum Compact and reclaim space
31874
- db tables Show table row counts
31858
+ INSTALLED
31859
+ list [kind] List installed packages (stacks, prompts, runtimes, binaries, agents)
31860
+ home Show ~/.rudi structure and status
31861
+ doctor Check system health and dependencies
31862
+ which <cmd> Show path to a command
31863
+ info <pkg> Show package details
31875
31864
 
31876
- SESSION IMPORT
31877
- import sessions Import from AI providers (claude, codex, gemini)
31878
- import status Show import status
31865
+ AGENT INTEGRATION
31866
+ integrate <agent> Wire up RUDI router (claude, cursor, gemini, codex, all)
31867
+ integrate --list Show detected agents
31868
+ index Rebuild tool cache for router
31869
+
31870
+ RUN
31871
+ run <stack> Run a stack directly
31879
31872
 
31880
31873
  SECRETS
31881
31874
  secrets set <name> Set a secret
31882
31875
  secrets list List configured secrets
31883
31876
  secrets remove <name> Remove a secret
31884
31877
 
31878
+ DATABASE
31879
+ db stats Show database statistics
31880
+ db search <query> Search conversation history
31881
+ db tables Show table row counts
31882
+ db vacuum Compact and reclaim space
31883
+
31884
+ SESSIONS
31885
+ session list List sessions
31886
+ session search <q> Search session content
31887
+ session export <id> Export a session
31888
+ session index Build search embeddings
31889
+
31885
31890
  OPTIONS
31886
31891
  -h, --help Show help
31887
31892
  -v, --version Show version
31888
31893
  --verbose Verbose output
31889
31894
  --json Output as JSON
31890
- --force Force operation
31891
31895
 
31892
31896
  EXAMPLES
31893
- rudi home Show ~/.rudi structure
31894
- rudi runtimes List installed runtimes
31895
- rudi install runtime:python Install Python in ~/.rudi
31896
- rudi install binary:ffmpeg Install ffmpeg
31897
- rudi doctor --all Show all available deps
31897
+ rudi search --all List all available packages
31898
+ rudi install slack Install Slack stack
31899
+ rudi secrets set SLACK_TOKEN Configure secret
31900
+ rudi integrate claude Wire up Claude Desktop/Code
31901
+ rudi list Show installed packages
31898
31902
 
31899
31903
  PACKAGE TYPES
31900
- stack:name MCP server stack
31901
- runtime:name Node, Python, Deno, Bun
31902
- binary:name ffmpeg, ripgrep, etc.
31903
- agent:name Claude, Codex, Gemini CLIs
31904
- prompt:name Prompt template
31904
+ stack:<name> MCP server stack
31905
+ runtime:<name> Node, Python, Deno, Bun
31906
+ binary:<name> ffmpeg, ripgrep, etc.
31907
+ agent:<name> Claude, Codex, Gemini CLIs
31908
+ prompt:<name> Prompt template
31905
31909
  `);
31906
31910
  }
31907
31911
  function printCommandHelp(command) {
@@ -32119,6 +32123,38 @@ EXAMPLES
32119
32123
  rudi doctor
32120
32124
  rudi doctor --fix
32121
32125
  rudi doctor --all
32126
+ `,
32127
+ integrate: `
32128
+ rudi integrate - Wire RUDI router into agent configs
32129
+
32130
+ USAGE
32131
+ rudi integrate <agent> Integrate with specific agent
32132
+ rudi integrate all Integrate with all detected agents
32133
+ rudi integrate --list Show detected agents
32134
+
32135
+ AGENTS
32136
+ claude Claude Desktop + Claude Code
32137
+ cursor Cursor IDE
32138
+ windsurf Windsurf IDE
32139
+ vscode VS Code / GitHub Copilot
32140
+ gemini Gemini CLI
32141
+ codex OpenAI Codex CLI
32142
+ zed Zed Editor
32143
+
32144
+ OPTIONS
32145
+ --verbose Show detailed output
32146
+ --dry-run Show what would be done without making changes
32147
+
32148
+ WHAT IT DOES
32149
+ 1. Detects agent config files
32150
+ 2. Creates backup before modifying
32151
+ 3. Adds RUDI router entry (single MCP server for all stacks)
32152
+ 4. Cleans up old direct stack entries
32153
+
32154
+ EXAMPLES
32155
+ rudi integrate claude
32156
+ rudi integrate all
32157
+ rudi integrate --list
32122
32158
  `,
32123
32159
  logs: `
32124
32160
  rudi logs - Query agent visibility logs
@@ -33235,11 +33271,11 @@ async function runStack(id, options = {}) {
33235
33271
  const startTime = Date.now();
33236
33272
  const packagePath = getPackagePath2(id);
33237
33273
  const manifestPath = import_path11.default.join(packagePath, "manifest.json");
33238
- const { default: fs35 } = await import("fs");
33239
- if (!fs35.existsSync(manifestPath)) {
33274
+ const { default: fs34 } = await import("fs");
33275
+ if (!fs34.existsSync(manifestPath)) {
33240
33276
  throw new Error(`Stack manifest not found: ${id}`);
33241
33277
  }
33242
- const manifest = JSON.parse(fs35.readFileSync(manifestPath, "utf-8"));
33278
+ const manifest = JSON.parse(fs34.readFileSync(manifestPath, "utf-8"));
33243
33279
  const { command, args } = resolveCommandFromManifest(manifest, packagePath);
33244
33280
  const secrets = await getSecrets(manifest.requires?.secrets || []);
33245
33281
  const runEnv = {
@@ -34225,7 +34261,7 @@ var import_fs13 = __toESM(require("fs"), 1);
34225
34261
  init_src2();
34226
34262
 
34227
34263
  // packages/db/src/schema.js
34228
- var SCHEMA_VERSION = 5;
34264
+ var SCHEMA_VERSION = 6;
34229
34265
  var SCHEMA_SQL = `
34230
34266
  -- Schema version tracking
34231
34267
  CREATE TABLE IF NOT EXISTS schema_version (
@@ -34246,6 +34282,7 @@ CREATE TABLE IF NOT EXISTS projects (
34246
34282
  cross_project_id TEXT,
34247
34283
  session_count INTEGER DEFAULT 0,
34248
34284
  total_cost REAL DEFAULT 0,
34285
+ settings TEXT,
34249
34286
  created_at TEXT NOT NULL,
34250
34287
 
34251
34288
  UNIQUE(provider, name)
@@ -34267,15 +34304,17 @@ CREATE TABLE IF NOT EXISTS sessions (
34267
34304
 
34268
34305
  -- Display
34269
34306
  title TEXT,
34307
+ title_override TEXT,
34270
34308
  snippet TEXT,
34271
34309
 
34272
34310
  -- State
34273
34311
  status TEXT DEFAULT 'active' CHECK (status IN ('active', 'archived', 'deleted')),
34274
34312
  model TEXT,
34313
+ system_prompt TEXT,
34275
34314
 
34276
34315
  -- Context
34277
34316
  cwd TEXT,
34278
- dir_scope TEXT DEFAULT 'project',
34317
+ dir_scope TEXT DEFAULT 'project' CHECK (dir_scope IN ('project', 'home')),
34279
34318
  git_branch TEXT,
34280
34319
  native_storage_path TEXT,
34281
34320
 
@@ -34285,7 +34324,8 @@ CREATE TABLE IF NOT EXISTS sessions (
34285
34324
  parent_session_id TEXT,
34286
34325
  agent_id TEXT,
34287
34326
  is_sidechain INTEGER DEFAULT 0,
34288
- session_type TEXT DEFAULT 'task',
34327
+ session_type TEXT DEFAULT 'main',
34328
+ slug TEXT,
34289
34329
  version TEXT,
34290
34330
  user_type TEXT DEFAULT 'external',
34291
34331
 
@@ -34308,8 +34348,13 @@ CREATE INDEX IF NOT EXISTS idx_sessions_provider ON sessions(provider);
34308
34348
  CREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_id);
34309
34349
  CREATE INDEX IF NOT EXISTS idx_sessions_status ON sessions(status);
34310
34350
  CREATE INDEX IF NOT EXISTS idx_sessions_last_active ON sessions(last_active_at DESC);
34311
- CREATE INDEX IF NOT EXISTS idx_sessions_provider_session ON sessions(provider, provider_session_id);
34351
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_provider_session_unique
34352
+ ON sessions(provider, provider_session_id)
34353
+ WHERE provider_session_id IS NOT NULL AND status != 'deleted';
34312
34354
  CREATE INDEX IF NOT EXISTS idx_sessions_cwd ON sessions(cwd);
34355
+ CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session_id);
34356
+ CREATE INDEX IF NOT EXISTS idx_sessions_agent ON sessions(agent_id);
34357
+ CREATE INDEX IF NOT EXISTS idx_sessions_type ON sessions(session_type);
34313
34358
 
34314
34359
  -- Turns (individual user->assistant exchanges)
34315
34360
  CREATE TABLE IF NOT EXISTS turns (
@@ -34317,6 +34362,7 @@ CREATE TABLE IF NOT EXISTS turns (
34317
34362
  session_id TEXT NOT NULL,
34318
34363
  provider TEXT NOT NULL,
34319
34364
  provider_session_id TEXT,
34365
+ provider_turn_id TEXT,
34320
34366
 
34321
34367
  -- Sequence
34322
34368
  turn_number INTEGER NOT NULL,
@@ -34329,6 +34375,7 @@ CREATE TABLE IF NOT EXISTS turns (
34329
34375
  -- Config at time of turn
34330
34376
  model TEXT,
34331
34377
  permission_mode TEXT,
34378
+ system_prompt TEXT,
34332
34379
 
34333
34380
  -- Metrics
34334
34381
  cost REAL,
@@ -34345,9 +34392,33 @@ CREATE TABLE IF NOT EXISTS turns (
34345
34392
 
34346
34393
  -- Rich metadata (JSON)
34347
34394
  tools_used TEXT,
34395
+ tool_results TEXT,
34396
+ todos TEXT,
34397
+ thinking_config TEXT,
34398
+ image_ids TEXT,
34399
+ compact_metadata TEXT,
34400
+
34401
+ -- Turn linking
34402
+ parent_turn_id TEXT,
34403
+ uuid TEXT,
34404
+ logical_parent_id TEXT,
34405
+ leaf_uuid TEXT,
34406
+
34407
+ -- Message metadata
34408
+ user_type TEXT,
34409
+ is_meta INTEGER DEFAULT 0,
34410
+ display_only INTEGER DEFAULT 0,
34411
+
34412
+ -- API metadata
34413
+ service_tier TEXT,
34414
+ api_request_id TEXT,
34415
+
34416
+ -- Event classification
34417
+ kind TEXT DEFAULT 'message' CHECK (kind IN ('message', 'display', 'summary', 'tool', 'error')),
34348
34418
 
34349
34419
  -- Timestamps
34350
34420
  ts TEXT NOT NULL,
34421
+ ts_ms INTEGER,
34351
34422
 
34352
34423
  FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
34353
34424
  );
@@ -34356,6 +34427,9 @@ CREATE INDEX IF NOT EXISTS idx_turns_session ON turns(session_id);
34356
34427
  CREATE INDEX IF NOT EXISTS idx_turns_ts ON turns(ts DESC);
34357
34428
  CREATE INDEX IF NOT EXISTS idx_turns_model ON turns(model);
34358
34429
  CREATE INDEX IF NOT EXISTS idx_turns_session_number ON turns(session_id, turn_number);
34430
+ CREATE INDEX IF NOT EXISTS idx_turns_session_ts_ms ON turns(session_id, ts_ms);
34431
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_turns_provider_dedup
34432
+ ON turns(session_id, provider_turn_id) WHERE provider_turn_id IS NOT NULL;
34359
34433
 
34360
34434
  -- Full-text search on turns
34361
34435
  CREATE VIRTUAL TABLE IF NOT EXISTS turns_fts USING fts5(
@@ -34417,6 +34491,160 @@ CREATE TABLE IF NOT EXISTS model_pricing (
34417
34491
  CREATE INDEX IF NOT EXISTS idx_model_pricing_provider ON model_pricing(provider);
34418
34492
  CREATE INDEX IF NOT EXISTS idx_model_pricing_pattern ON model_pricing(model_pattern);
34419
34493
 
34494
+ -- =============================================================================
34495
+ -- FILE POSITIONS (session file tailing)
34496
+ -- =============================================================================
34497
+
34498
+ CREATE TABLE IF NOT EXISTS file_positions (
34499
+ file_path TEXT PRIMARY KEY,
34500
+ byte_offset INTEGER NOT NULL DEFAULT 0,
34501
+ file_size INTEGER NOT NULL DEFAULT 0,
34502
+ mtime_ms INTEGER NOT NULL DEFAULT 0,
34503
+ inode TEXT,
34504
+ provider TEXT NOT NULL CHECK (provider IN ('claude', 'codex', 'gemini', 'ollama')),
34505
+ last_synced_at TEXT NOT NULL,
34506
+ created_at TEXT NOT NULL
34507
+ );
34508
+
34509
+ CREATE INDEX IF NOT EXISTS idx_file_positions_provider ON file_positions(provider);
34510
+
34511
+ -- =============================================================================
34512
+ -- FILE HISTORY (tracked files / revisions)
34513
+ -- =============================================================================
34514
+
34515
+ CREATE TABLE IF NOT EXISTS tracked_files (
34516
+ id TEXT PRIMARY KEY,
34517
+ current_path TEXT NOT NULL,
34518
+ risk_level TEXT DEFAULT 'low' CHECK (risk_level IN ('low', 'medium', 'high')),
34519
+ created_at TEXT NOT NULL,
34520
+ deleted_at TEXT
34521
+ );
34522
+
34523
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_tracked_files_path_active
34524
+ ON tracked_files(current_path) WHERE deleted_at IS NULL;
34525
+ CREATE INDEX IF NOT EXISTS idx_tracked_files_path ON tracked_files(current_path);
34526
+ CREATE INDEX IF NOT EXISTS idx_tracked_files_active ON tracked_files(deleted_at) WHERE deleted_at IS NULL;
34527
+
34528
+ CREATE TABLE IF NOT EXISTS file_revisions (
34529
+ id TEXT PRIMARY KEY,
34530
+ file_id TEXT NOT NULL,
34531
+ revision_number INTEGER NOT NULL,
34532
+ parent_revision_id TEXT,
34533
+ content_hash TEXT NOT NULL,
34534
+ size_bytes INTEGER NOT NULL,
34535
+ kind TEXT NOT NULL CHECK (kind IN ('edit', 'revert', 'import', 'external', 'delete')),
34536
+ author TEXT NOT NULL CHECK (author IN ('agent', 'user', 'external', 'system')),
34537
+ summary TEXT,
34538
+ is_binary INTEGER DEFAULT 0 CHECK (is_binary IN (0, 1)),
34539
+ reverted_to_revision_id TEXT,
34540
+ created_at TEXT NOT NULL,
34541
+ path_at_revision TEXT NOT NULL,
34542
+ FOREIGN KEY (file_id) REFERENCES tracked_files(id) ON DELETE CASCADE,
34543
+ FOREIGN KEY (parent_revision_id) REFERENCES file_revisions(id),
34544
+ FOREIGN KEY (reverted_to_revision_id) REFERENCES file_revisions(id)
34545
+ );
34546
+
34547
+ CREATE INDEX IF NOT EXISTS idx_file_revisions_file ON file_revisions(file_id, created_at DESC);
34548
+ CREATE INDEX IF NOT EXISTS idx_file_revisions_file_rev ON file_revisions(file_id, revision_number DESC);
34549
+ CREATE INDEX IF NOT EXISTS idx_file_revisions_hash ON file_revisions(content_hash);
34550
+ CREATE INDEX IF NOT EXISTS idx_file_revisions_path ON file_revisions(path_at_revision);
34551
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_file_revisions_number ON file_revisions(file_id, revision_number);
34552
+
34553
+ -- =============================================================================
34554
+ -- FILE CHANGES / SYSTEM EVENTS
34555
+ -- =============================================================================
34556
+
34557
+ CREATE TABLE IF NOT EXISTS file_changes (
34558
+ id TEXT PRIMARY KEY,
34559
+ session_id TEXT NOT NULL,
34560
+ turn_id TEXT,
34561
+ file_path TEXT NOT NULL,
34562
+ operation TEXT NOT NULL,
34563
+ content_before_hash TEXT,
34564
+ content_after_hash TEXT,
34565
+ diff_summary TEXT,
34566
+ ts TEXT NOT NULL,
34567
+ ts_ms INTEGER,
34568
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
34569
+ );
34570
+
34571
+ CREATE INDEX IF NOT EXISTS idx_file_changes_session ON file_changes(session_id);
34572
+ CREATE INDEX IF NOT EXISTS idx_file_changes_path ON file_changes(file_path);
34573
+ CREATE INDEX IF NOT EXISTS idx_file_changes_ts ON file_changes(ts_ms);
34574
+
34575
+ CREATE TABLE IF NOT EXISTS system_events (
34576
+ id TEXT PRIMARY KEY,
34577
+ session_id TEXT NOT NULL,
34578
+ event_type TEXT NOT NULL,
34579
+ payload TEXT,
34580
+ ts TEXT NOT NULL,
34581
+ ts_ms INTEGER,
34582
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
34583
+ );
34584
+
34585
+ CREATE INDEX IF NOT EXISTS idx_system_events_session ON system_events(session_id);
34586
+ CREATE INDEX IF NOT EXISTS idx_system_events_type ON system_events(event_type);
34587
+
34588
+ -- =============================================================================
34589
+ -- SESSION RUNTIME
34590
+ -- =============================================================================
34591
+
34592
+ CREATE TABLE IF NOT EXISTS session_runtime_state (
34593
+ session_id TEXT PRIMARY KEY,
34594
+ status TEXT NOT NULL CHECK(status IN ('running','completed','error','stopped')),
34595
+ provider TEXT,
34596
+ provider_session_id TEXT,
34597
+ started_at TEXT NOT NULL,
34598
+ updated_at TEXT NOT NULL,
34599
+ completed_at TEXT,
34600
+ last_seq INTEGER NOT NULL DEFAULT 0,
34601
+ cost_total REAL NOT NULL DEFAULT 0,
34602
+ tokens_total INTEGER NOT NULL DEFAULT 0,
34603
+ unseen_completion INTEGER NOT NULL DEFAULT 0,
34604
+ last_error TEXT
34605
+ );
34606
+
34607
+ CREATE TABLE IF NOT EXISTS session_runtime_events (
34608
+ session_id TEXT NOT NULL,
34609
+ seq INTEGER NOT NULL,
34610
+ type TEXT NOT NULL,
34611
+ payload_json TEXT NOT NULL,
34612
+ ts TEXT NOT NULL,
34613
+ PRIMARY KEY (session_id, seq)
34614
+ );
34615
+
34616
+ CREATE INDEX IF NOT EXISTS idx_session_runtime_events_session_ts
34617
+ ON session_runtime_events(session_id, ts);
34618
+
34619
+ -- =============================================================================
34620
+ -- OBSERVABILITY LOGS
34621
+ -- =============================================================================
34622
+
34623
+ CREATE TABLE IF NOT EXISTS logs (
34624
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
34625
+ timestamp INTEGER NOT NULL,
34626
+ source TEXT NOT NULL,
34627
+ level TEXT NOT NULL CHECK (level IN ('debug', 'info', 'warn', 'error')),
34628
+ type TEXT NOT NULL,
34629
+ provider TEXT,
34630
+ cid TEXT,
34631
+ session_id TEXT,
34632
+ terminal_id INTEGER,
34633
+ feature TEXT,
34634
+ step TEXT,
34635
+ duration_ms INTEGER,
34636
+ data_json TEXT NOT NULL,
34637
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
34638
+ );
34639
+
34640
+ CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON logs(timestamp DESC);
34641
+ CREATE INDEX IF NOT EXISTS idx_logs_source ON logs(source);
34642
+ CREATE INDEX IF NOT EXISTS idx_logs_level ON logs(level);
34643
+ CREATE INDEX IF NOT EXISTS idx_logs_type ON logs(type);
34644
+ CREATE INDEX IF NOT EXISTS idx_logs_provider ON logs(provider);
34645
+ CREATE INDEX IF NOT EXISTS idx_logs_session ON logs(session_id);
34646
+ CREATE INDEX IF NOT EXISTS idx_logs_duration ON logs(duration_ms) WHERE duration_ms IS NOT NULL;
34647
+
34420
34648
  -- =============================================================================
34421
34649
  -- PACKAGES (stacks, prompts, runtimes, binaries, agents)
34422
34650
  -- =============================================================================
@@ -34532,16 +34760,15 @@ CREATE TABLE IF NOT EXISTS secrets_meta (
34532
34760
  last_used_at TEXT
34533
34761
  );
34534
34762
  `;
34535
- function initSchema() {
34536
- const db3 = getDb();
34763
+ function initSchemaWithDb(db3) {
34537
34764
  const hasVersionTable = db3.prepare(`
34538
34765
  SELECT name FROM sqlite_master WHERE type='table' AND name='schema_version'
34539
34766
  `).get();
34540
34767
  if (!hasVersionTable) {
34541
34768
  console.log("Initializing database schema...");
34542
34769
  db3.exec(SCHEMA_SQL);
34770
+ applySchemaUpdates(db3);
34543
34771
  db3.prepare("INSERT INTO schema_version (version, applied_at) VALUES (?, ?)").run(SCHEMA_VERSION, (/* @__PURE__ */ new Date()).toISOString());
34544
- seedModelPricing(db3);
34545
34772
  console.log(`Database initialized at schema version ${SCHEMA_VERSION}`);
34546
34773
  return { version: SCHEMA_VERSION, migrated: false };
34547
34774
  }
@@ -34550,8 +34777,380 @@ function initSchema() {
34550
34777
  runMigrations(db3, currentVersion, SCHEMA_VERSION);
34551
34778
  return { version: SCHEMA_VERSION, migrated: true, from: currentVersion };
34552
34779
  }
34780
+ db3.exec(SCHEMA_SQL);
34781
+ applySchemaUpdates(db3);
34553
34782
  return { version: currentVersion, migrated: false };
34554
34783
  }
34784
+ function initSchema() {
34785
+ return initSchemaWithDb(getDb());
34786
+ }
34787
+ function applySchemaUpdates(db3) {
34788
+ if (tableExists(db3, "projects")) {
34789
+ ensureColumn(db3, "projects", "settings", "ALTER TABLE projects ADD COLUMN settings TEXT");
34790
+ }
34791
+ if (tableExists(db3, "sessions")) {
34792
+ ensureColumn(db3, "sessions", "title_override", "ALTER TABLE sessions ADD COLUMN title_override TEXT");
34793
+ ensureColumn(db3, "sessions", "system_prompt", "ALTER TABLE sessions ADD COLUMN system_prompt TEXT");
34794
+ ensureColumn(
34795
+ db3,
34796
+ "sessions",
34797
+ "dir_scope",
34798
+ "ALTER TABLE sessions ADD COLUMN dir_scope TEXT DEFAULT 'project' CHECK (dir_scope IN ('project', 'home'))"
34799
+ );
34800
+ ensureColumn(
34801
+ db3,
34802
+ "sessions",
34803
+ "inherit_project_prompt",
34804
+ "ALTER TABLE sessions ADD COLUMN inherit_project_prompt INTEGER DEFAULT 1"
34805
+ );
34806
+ ensureColumn(db3, "sessions", "is_warmup", "ALTER TABLE sessions ADD COLUMN is_warmup INTEGER DEFAULT 0");
34807
+ ensureColumn(db3, "sessions", "parent_session_id", "ALTER TABLE sessions ADD COLUMN parent_session_id TEXT");
34808
+ ensureColumn(db3, "sessions", "agent_id", "ALTER TABLE sessions ADD COLUMN agent_id TEXT");
34809
+ ensureColumn(db3, "sessions", "is_sidechain", "ALTER TABLE sessions ADD COLUMN is_sidechain INTEGER DEFAULT 0");
34810
+ ensureColumn(
34811
+ db3,
34812
+ "sessions",
34813
+ "session_type",
34814
+ "ALTER TABLE sessions ADD COLUMN session_type TEXT DEFAULT 'main'"
34815
+ );
34816
+ ensureColumn(db3, "sessions", "slug", "ALTER TABLE sessions ADD COLUMN slug TEXT");
34817
+ ensureColumn(db3, "sessions", "version", "ALTER TABLE sessions ADD COLUMN version TEXT");
34818
+ ensureColumn(
34819
+ db3,
34820
+ "sessions",
34821
+ "user_type",
34822
+ "ALTER TABLE sessions ADD COLUMN user_type TEXT DEFAULT 'external'"
34823
+ );
34824
+ if (columnExists(db3, "sessions", "session_type")) {
34825
+ db3.exec("UPDATE sessions SET session_type = 'main' WHERE session_type = 'task'");
34826
+ }
34827
+ ensureIndex(db3, "idx_sessions_parent", "CREATE INDEX IF NOT EXISTS idx_sessions_parent ON sessions(parent_session_id)");
34828
+ ensureIndex(db3, "idx_sessions_agent", "CREATE INDEX IF NOT EXISTS idx_sessions_agent ON sessions(agent_id)");
34829
+ ensureIndex(db3, "idx_sessions_type", "CREATE INDEX IF NOT EXISTS idx_sessions_type ON sessions(session_type)");
34830
+ if (!indexExists(db3, "idx_sessions_provider_session_unique")) {
34831
+ dedupeProviderSessions(db3);
34832
+ db3.exec("DROP INDEX IF EXISTS idx_sessions_provider_session");
34833
+ db3.exec(`
34834
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_sessions_provider_session_unique
34835
+ ON sessions(provider, provider_session_id)
34836
+ WHERE provider_session_id IS NOT NULL AND status != 'deleted'
34837
+ `);
34838
+ }
34839
+ }
34840
+ if (tableExists(db3, "turns")) {
34841
+ ensureColumn(db3, "turns", "provider_turn_id", "ALTER TABLE turns ADD COLUMN provider_turn_id TEXT");
34842
+ ensureColumn(db3, "turns", "system_prompt", "ALTER TABLE turns ADD COLUMN system_prompt TEXT");
34843
+ ensureColumn(db3, "turns", "parent_turn_id", "ALTER TABLE turns ADD COLUMN parent_turn_id TEXT");
34844
+ ensureColumn(db3, "turns", "uuid", "ALTER TABLE turns ADD COLUMN uuid TEXT");
34845
+ ensureColumn(db3, "turns", "service_tier", "ALTER TABLE turns ADD COLUMN service_tier TEXT");
34846
+ ensureColumn(db3, "turns", "api_request_id", "ALTER TABLE turns ADD COLUMN api_request_id TEXT");
34847
+ ensureColumn(db3, "turns", "tool_results", "ALTER TABLE turns ADD COLUMN tool_results TEXT");
34848
+ ensureColumn(db3, "turns", "user_type", "ALTER TABLE turns ADD COLUMN user_type TEXT");
34849
+ ensureColumn(db3, "turns", "is_meta", "ALTER TABLE turns ADD COLUMN is_meta INTEGER DEFAULT 0");
34850
+ ensureColumn(db3, "turns", "display_only", "ALTER TABLE turns ADD COLUMN display_only INTEGER DEFAULT 0");
34851
+ ensureColumn(db3, "turns", "todos", "ALTER TABLE turns ADD COLUMN todos TEXT");
34852
+ ensureColumn(db3, "turns", "thinking_config", "ALTER TABLE turns ADD COLUMN thinking_config TEXT");
34853
+ ensureColumn(db3, "turns", "image_ids", "ALTER TABLE turns ADD COLUMN image_ids TEXT");
34854
+ ensureColumn(db3, "turns", "compact_metadata", "ALTER TABLE turns ADD COLUMN compact_metadata TEXT");
34855
+ ensureColumn(db3, "turns", "logical_parent_id", "ALTER TABLE turns ADD COLUMN logical_parent_id TEXT");
34856
+ ensureColumn(db3, "turns", "leaf_uuid", "ALTER TABLE turns ADD COLUMN leaf_uuid TEXT");
34857
+ if (!columnExists(db3, "turns", "ts_ms")) {
34858
+ db3.exec("ALTER TABLE turns ADD COLUMN ts_ms INTEGER");
34859
+ db3.exec(`
34860
+ UPDATE turns
34861
+ SET ts_ms = CASE
34862
+ WHEN ts GLOB '[0-9]*' AND LENGTH(ts) >= 13 THEN CAST(ts AS INTEGER)
34863
+ WHEN ts LIKE '____-__-__T__:__:__*' THEN
34864
+ CAST((julianday(SUBSTR(ts, 1, 19)) - julianday('1970-01-01')) * 86400000 AS INTEGER)
34865
+ ELSE CAST((julianday(ts) - julianday('1970-01-01')) * 86400000 AS INTEGER)
34866
+ END
34867
+ WHERE ts_ms IS NULL AND ts IS NOT NULL
34868
+ `);
34869
+ }
34870
+ if (columnExists(db3, "turns", "ts_ms")) {
34871
+ ensureIndex(
34872
+ db3,
34873
+ "idx_turns_session_ts_ms",
34874
+ "CREATE INDEX IF NOT EXISTS idx_turns_session_ts_ms ON turns(session_id, ts_ms)"
34875
+ );
34876
+ }
34877
+ if (!columnExists(db3, "turns", "kind")) {
34878
+ db3.exec("ALTER TABLE turns ADD COLUMN kind TEXT DEFAULT 'message' CHECK (kind IN ('message', 'display', 'summary', 'tool', 'error'))");
34879
+ db3.exec(`
34880
+ UPDATE turns SET kind = 'display'
34881
+ WHERE user_message LIKE '[display: %]' AND assistant_response IS NULL
34882
+ `);
34883
+ }
34884
+ if (columnExists(db3, "turns", "provider_turn_id")) {
34885
+ ensureIndex(
34886
+ db3,
34887
+ "idx_turns_provider_dedup",
34888
+ "CREATE UNIQUE INDEX IF NOT EXISTS idx_turns_provider_dedup ON turns(session_id, provider_turn_id) WHERE provider_turn_id IS NOT NULL"
34889
+ );
34890
+ }
34891
+ }
34892
+ ensureTable(db3, "file_positions", `
34893
+ CREATE TABLE IF NOT EXISTS file_positions (
34894
+ file_path TEXT PRIMARY KEY,
34895
+ byte_offset INTEGER NOT NULL DEFAULT 0,
34896
+ file_size INTEGER NOT NULL DEFAULT 0,
34897
+ mtime_ms INTEGER NOT NULL DEFAULT 0,
34898
+ inode TEXT,
34899
+ provider TEXT NOT NULL CHECK (provider IN ('claude', 'codex', 'gemini', 'ollama')),
34900
+ last_synced_at TEXT NOT NULL,
34901
+ created_at TEXT NOT NULL
34902
+ );
34903
+ `);
34904
+ ensureIndex(
34905
+ db3,
34906
+ "idx_file_positions_provider",
34907
+ "CREATE INDEX IF NOT EXISTS idx_file_positions_provider ON file_positions(provider)"
34908
+ );
34909
+ ensureTable(db3, "tracked_files", `
34910
+ CREATE TABLE IF NOT EXISTS tracked_files (
34911
+ id TEXT PRIMARY KEY,
34912
+ current_path TEXT NOT NULL,
34913
+ risk_level TEXT DEFAULT 'low' CHECK (risk_level IN ('low', 'medium', 'high')),
34914
+ created_at TEXT NOT NULL,
34915
+ deleted_at TEXT
34916
+ );
34917
+ `);
34918
+ ensureIndex(
34919
+ db3,
34920
+ "idx_tracked_files_path_active",
34921
+ "CREATE UNIQUE INDEX IF NOT EXISTS idx_tracked_files_path_active ON tracked_files(current_path) WHERE deleted_at IS NULL"
34922
+ );
34923
+ ensureIndex(
34924
+ db3,
34925
+ "idx_tracked_files_path",
34926
+ "CREATE INDEX IF NOT EXISTS idx_tracked_files_path ON tracked_files(current_path)"
34927
+ );
34928
+ ensureIndex(
34929
+ db3,
34930
+ "idx_tracked_files_active",
34931
+ "CREATE INDEX IF NOT EXISTS idx_tracked_files_active ON tracked_files(deleted_at) WHERE deleted_at IS NULL"
34932
+ );
34933
+ ensureTable(db3, "file_revisions", `
34934
+ CREATE TABLE IF NOT EXISTS file_revisions (
34935
+ id TEXT PRIMARY KEY,
34936
+ file_id TEXT NOT NULL,
34937
+ revision_number INTEGER NOT NULL,
34938
+ parent_revision_id TEXT,
34939
+ content_hash TEXT NOT NULL,
34940
+ size_bytes INTEGER NOT NULL,
34941
+ kind TEXT NOT NULL CHECK (kind IN ('edit', 'revert', 'import', 'external', 'delete')),
34942
+ author TEXT NOT NULL CHECK (author IN ('agent', 'user', 'external', 'system')),
34943
+ summary TEXT,
34944
+ is_binary INTEGER DEFAULT 0 CHECK (is_binary IN (0, 1)),
34945
+ reverted_to_revision_id TEXT,
34946
+ created_at TEXT NOT NULL,
34947
+ path_at_revision TEXT NOT NULL,
34948
+ FOREIGN KEY (file_id) REFERENCES tracked_files(id) ON DELETE CASCADE,
34949
+ FOREIGN KEY (parent_revision_id) REFERENCES file_revisions(id),
34950
+ FOREIGN KEY (reverted_to_revision_id) REFERENCES file_revisions(id)
34951
+ );
34952
+ `);
34953
+ ensureIndex(
34954
+ db3,
34955
+ "idx_file_revisions_file",
34956
+ "CREATE INDEX IF NOT EXISTS idx_file_revisions_file ON file_revisions(file_id, created_at DESC)"
34957
+ );
34958
+ ensureIndex(
34959
+ db3,
34960
+ "idx_file_revisions_file_rev",
34961
+ "CREATE INDEX IF NOT EXISTS idx_file_revisions_file_rev ON file_revisions(file_id, revision_number DESC)"
34962
+ );
34963
+ ensureIndex(
34964
+ db3,
34965
+ "idx_file_revisions_hash",
34966
+ "CREATE INDEX IF NOT EXISTS idx_file_revisions_hash ON file_revisions(content_hash)"
34967
+ );
34968
+ ensureIndex(
34969
+ db3,
34970
+ "idx_file_revisions_path",
34971
+ "CREATE INDEX IF NOT EXISTS idx_file_revisions_path ON file_revisions(path_at_revision)"
34972
+ );
34973
+ ensureIndex(
34974
+ db3,
34975
+ "idx_file_revisions_number",
34976
+ "CREATE UNIQUE INDEX IF NOT EXISTS idx_file_revisions_number ON file_revisions(file_id, revision_number)"
34977
+ );
34978
+ if (tableExists(db3, "file_revisions")) {
34979
+ ensureColumn(
34980
+ db3,
34981
+ "file_revisions",
34982
+ "is_binary",
34983
+ "ALTER TABLE file_revisions ADD COLUMN is_binary INTEGER DEFAULT 0 CHECK (is_binary IN (0, 1))"
34984
+ );
34985
+ }
34986
+ ensureTable(db3, "file_changes", `
34987
+ CREATE TABLE IF NOT EXISTS file_changes (
34988
+ id TEXT PRIMARY KEY,
34989
+ session_id TEXT NOT NULL,
34990
+ turn_id TEXT,
34991
+ file_path TEXT NOT NULL,
34992
+ operation TEXT NOT NULL,
34993
+ content_before_hash TEXT,
34994
+ content_after_hash TEXT,
34995
+ diff_summary TEXT,
34996
+ ts TEXT NOT NULL,
34997
+ ts_ms INTEGER,
34998
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
34999
+ );
35000
+ `);
35001
+ ensureIndex(
35002
+ db3,
35003
+ "idx_file_changes_session",
35004
+ "CREATE INDEX IF NOT EXISTS idx_file_changes_session ON file_changes(session_id)"
35005
+ );
35006
+ ensureIndex(
35007
+ db3,
35008
+ "idx_file_changes_path",
35009
+ "CREATE INDEX IF NOT EXISTS idx_file_changes_path ON file_changes(file_path)"
35010
+ );
35011
+ ensureIndex(
35012
+ db3,
35013
+ "idx_file_changes_ts",
35014
+ "CREATE INDEX IF NOT EXISTS idx_file_changes_ts ON file_changes(ts_ms)"
35015
+ );
35016
+ ensureTable(db3, "system_events", `
35017
+ CREATE TABLE IF NOT EXISTS system_events (
35018
+ id TEXT PRIMARY KEY,
35019
+ session_id TEXT NOT NULL,
35020
+ event_type TEXT NOT NULL,
35021
+ payload TEXT,
35022
+ ts TEXT NOT NULL,
35023
+ ts_ms INTEGER,
35024
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
35025
+ );
35026
+ `);
35027
+ ensureIndex(
35028
+ db3,
35029
+ "idx_system_events_session",
35030
+ "CREATE INDEX IF NOT EXISTS idx_system_events_session ON system_events(session_id)"
35031
+ );
35032
+ ensureIndex(
35033
+ db3,
35034
+ "idx_system_events_type",
35035
+ "CREATE INDEX IF NOT EXISTS idx_system_events_type ON system_events(event_type)"
35036
+ );
35037
+ ensureTable(db3, "session_runtime_state", `
35038
+ CREATE TABLE IF NOT EXISTS session_runtime_state (
35039
+ session_id TEXT PRIMARY KEY,
35040
+ status TEXT NOT NULL CHECK(status IN ('running','completed','error','stopped')),
35041
+ provider TEXT,
35042
+ provider_session_id TEXT,
35043
+ started_at TEXT NOT NULL,
35044
+ updated_at TEXT NOT NULL,
35045
+ completed_at TEXT,
35046
+ last_seq INTEGER NOT NULL DEFAULT 0,
35047
+ cost_total REAL NOT NULL DEFAULT 0,
35048
+ tokens_total INTEGER NOT NULL DEFAULT 0,
35049
+ unseen_completion INTEGER NOT NULL DEFAULT 0,
35050
+ last_error TEXT
35051
+ )
35052
+ `);
35053
+ ensureTable(db3, "session_runtime_events", `
35054
+ CREATE TABLE IF NOT EXISTS session_runtime_events (
35055
+ session_id TEXT NOT NULL,
35056
+ seq INTEGER NOT NULL,
35057
+ type TEXT NOT NULL,
35058
+ payload_json TEXT NOT NULL,
35059
+ ts TEXT NOT NULL,
35060
+ PRIMARY KEY (session_id, seq)
35061
+ );
35062
+ `);
35063
+ ensureIndex(
35064
+ db3,
35065
+ "idx_session_runtime_events_session_ts",
35066
+ "CREATE INDEX IF NOT EXISTS idx_session_runtime_events_session_ts ON session_runtime_events(session_id, ts)"
35067
+ );
35068
+ ensureTable(db3, "logs", `
35069
+ CREATE TABLE IF NOT EXISTS logs (
35070
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
35071
+ timestamp INTEGER NOT NULL,
35072
+ source TEXT NOT NULL,
35073
+ level TEXT NOT NULL CHECK (level IN ('debug', 'info', 'warn', 'error')),
35074
+ type TEXT NOT NULL,
35075
+ provider TEXT,
35076
+ cid TEXT,
35077
+ session_id TEXT,
35078
+ terminal_id INTEGER,
35079
+ feature TEXT,
35080
+ step TEXT,
35081
+ duration_ms INTEGER,
35082
+ data_json TEXT NOT NULL,
35083
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
35084
+ );
35085
+ `);
35086
+ ensureIndex(
35087
+ db3,
35088
+ "idx_logs_timestamp",
35089
+ "CREATE INDEX IF NOT EXISTS idx_logs_timestamp ON logs(timestamp DESC)"
35090
+ );
35091
+ ensureIndex(
35092
+ db3,
35093
+ "idx_logs_source",
35094
+ "CREATE INDEX IF NOT EXISTS idx_logs_source ON logs(source)"
35095
+ );
35096
+ ensureIndex(
35097
+ db3,
35098
+ "idx_logs_level",
35099
+ "CREATE INDEX IF NOT EXISTS idx_logs_level ON logs(level)"
35100
+ );
35101
+ ensureIndex(
35102
+ db3,
35103
+ "idx_logs_type",
35104
+ "CREATE INDEX IF NOT EXISTS idx_logs_type ON logs(type)"
35105
+ );
35106
+ ensureIndex(
35107
+ db3,
35108
+ "idx_logs_provider",
35109
+ "CREATE INDEX IF NOT EXISTS idx_logs_provider ON logs(provider)"
35110
+ );
35111
+ ensureIndex(
35112
+ db3,
35113
+ "idx_logs_session",
35114
+ "CREATE INDEX IF NOT EXISTS idx_logs_session ON logs(session_id)"
35115
+ );
35116
+ ensureIndex(
35117
+ db3,
35118
+ "idx_logs_duration",
35119
+ "CREATE INDEX IF NOT EXISTS idx_logs_duration ON logs(duration_ms) WHERE duration_ms IS NOT NULL"
35120
+ );
35121
+ ensureTable(db3, "model_pricing", `
35122
+ CREATE TABLE IF NOT EXISTS model_pricing (
35123
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
35124
+ provider TEXT NOT NULL CHECK (provider IN ('claude', 'codex', 'gemini', 'openai', 'ollama')),
35125
+ model_pattern TEXT NOT NULL,
35126
+ display_name TEXT,
35127
+ input_cost_per_mtok REAL NOT NULL,
35128
+ output_cost_per_mtok REAL NOT NULL,
35129
+ cache_read_cost_per_mtok REAL DEFAULT 0,
35130
+ cache_write_cost_per_mtok REAL DEFAULT 0,
35131
+ effective_from TEXT NOT NULL,
35132
+ effective_until TEXT,
35133
+ notes TEXT,
35134
+ UNIQUE(provider, model_pattern, effective_from)
35135
+ );
35136
+ `);
35137
+ ensureIndex(
35138
+ db3,
35139
+ "idx_model_pricing_provider",
35140
+ "CREATE INDEX IF NOT EXISTS idx_model_pricing_provider ON model_pricing(provider)"
35141
+ );
35142
+ ensureIndex(
35143
+ db3,
35144
+ "idx_model_pricing_pattern",
35145
+ "CREATE INDEX IF NOT EXISTS idx_model_pricing_pattern ON model_pricing(model_pattern)"
35146
+ );
35147
+ if (tableExists(db3, "model_pricing")) {
35148
+ const count = db3.prepare("SELECT COUNT(*) as count FROM model_pricing").get();
35149
+ if (count && count.count === 0) {
35150
+ seedModelPricing(db3);
35151
+ }
35152
+ }
35153
+ }
34555
35154
  function runMigrations(db3, from, to) {
34556
35155
  console.log(`Migrating database from v${from} to v${to}...`);
34557
35156
  const migrations = {
@@ -34715,17 +35314,64 @@ function runMigrations(db3, from, to) {
34715
35314
  },
34716
35315
  // Version 5: Add session metadata columns for Claude import
34717
35316
  5: (db4) => {
34718
- db4.exec(`
34719
- ALTER TABLE sessions ADD COLUMN dir_scope TEXT DEFAULT 'project';
34720
- ALTER TABLE sessions ADD COLUMN inherit_project_prompt INTEGER DEFAULT 1;
34721
- ALTER TABLE sessions ADD COLUMN is_warmup INTEGER DEFAULT 0;
34722
- ALTER TABLE sessions ADD COLUMN parent_session_id TEXT;
34723
- ALTER TABLE sessions ADD COLUMN agent_id TEXT;
34724
- ALTER TABLE sessions ADD COLUMN is_sidechain INTEGER DEFAULT 0;
34725
- ALTER TABLE sessions ADD COLUMN session_type TEXT DEFAULT 'task';
34726
- ALTER TABLE sessions ADD COLUMN version TEXT;
34727
- ALTER TABLE sessions ADD COLUMN user_type TEXT DEFAULT 'external';
34728
- `);
35317
+ ensureColumn(
35318
+ db4,
35319
+ "sessions",
35320
+ "dir_scope",
35321
+ "ALTER TABLE sessions ADD COLUMN dir_scope TEXT DEFAULT 'project' CHECK (dir_scope IN ('project', 'home'))"
35322
+ );
35323
+ ensureColumn(
35324
+ db4,
35325
+ "sessions",
35326
+ "inherit_project_prompt",
35327
+ "ALTER TABLE sessions ADD COLUMN inherit_project_prompt INTEGER DEFAULT 1"
35328
+ );
35329
+ ensureColumn(
35330
+ db4,
35331
+ "sessions",
35332
+ "is_warmup",
35333
+ "ALTER TABLE sessions ADD COLUMN is_warmup INTEGER DEFAULT 0"
35334
+ );
35335
+ ensureColumn(
35336
+ db4,
35337
+ "sessions",
35338
+ "parent_session_id",
35339
+ "ALTER TABLE sessions ADD COLUMN parent_session_id TEXT"
35340
+ );
35341
+ ensureColumn(
35342
+ db4,
35343
+ "sessions",
35344
+ "agent_id",
35345
+ "ALTER TABLE sessions ADD COLUMN agent_id TEXT"
35346
+ );
35347
+ ensureColumn(
35348
+ db4,
35349
+ "sessions",
35350
+ "is_sidechain",
35351
+ "ALTER TABLE sessions ADD COLUMN is_sidechain INTEGER DEFAULT 0"
35352
+ );
35353
+ ensureColumn(
35354
+ db4,
35355
+ "sessions",
35356
+ "session_type",
35357
+ "ALTER TABLE sessions ADD COLUMN session_type TEXT DEFAULT 'main'"
35358
+ );
35359
+ ensureColumn(
35360
+ db4,
35361
+ "sessions",
35362
+ "version",
35363
+ "ALTER TABLE sessions ADD COLUMN version TEXT"
35364
+ );
35365
+ ensureColumn(
35366
+ db4,
35367
+ "sessions",
35368
+ "user_type",
35369
+ "ALTER TABLE sessions ADD COLUMN user_type TEXT DEFAULT 'external'"
35370
+ );
35371
+ },
35372
+ // Version 6: Bring schema to Studio parity
35373
+ 6: (db4) => {
35374
+ applySchemaUpdates(db4);
34729
35375
  }
34730
35376
  };
34731
35377
  for (let v2 = from + 1; v2 <= to; v2++) {
@@ -34744,6 +35390,72 @@ function runMigrations(db3, from, to) {
34744
35390
  }
34745
35391
  console.log("Migrations complete.");
34746
35392
  }
35393
+ function tableExists(db3, table) {
35394
+ const result = db3.prepare(`
35395
+ SELECT name FROM sqlite_master WHERE type='table' AND name=?
35396
+ `).get(table);
35397
+ return !!result;
35398
+ }
35399
+ function columnExists(db3, table, column) {
35400
+ try {
35401
+ const columns = db3.pragma(`table_info(${table})`);
35402
+ return columns.some((col) => col.name === column);
35403
+ } catch {
35404
+ return false;
35405
+ }
35406
+ }
35407
+ function indexExists(db3, indexName) {
35408
+ const result = db3.prepare(`
35409
+ SELECT name FROM sqlite_master WHERE type='index' AND name=?
35410
+ `).get(indexName);
35411
+ return !!result;
35412
+ }
35413
+ function ensureColumn(db3, table, column, statement) {
35414
+ if (!columnExists(db3, table, column)) {
35415
+ db3.exec(statement);
35416
+ }
35417
+ }
35418
+ function ensureIndex(db3, indexName, statement) {
35419
+ if (!indexExists(db3, indexName)) {
35420
+ db3.exec(statement);
35421
+ }
35422
+ }
35423
+ function ensureTable(db3, table, statement) {
35424
+ if (!tableExists(db3, table)) {
35425
+ db3.exec(statement);
35426
+ }
35427
+ }
35428
+ function dedupeProviderSessions(db3) {
35429
+ const duplicates = db3.prepare(`
35430
+ SELECT provider, provider_session_id, COUNT(*) as cnt
35431
+ FROM sessions
35432
+ WHERE provider_session_id IS NOT NULL
35433
+ GROUP BY provider, provider_session_id
35434
+ HAVING COUNT(*) > 1
35435
+ `).all();
35436
+ if (!duplicates.length) {
35437
+ return;
35438
+ }
35439
+ for (const dup of duplicates) {
35440
+ const sessions = db3.prepare(`
35441
+ SELECT id, turn_count, created_at
35442
+ FROM sessions
35443
+ WHERE provider = ? AND provider_session_id = ?
35444
+ ORDER BY turn_count DESC, created_at ASC
35445
+ `).all(dup.provider, dup.provider_session_id);
35446
+ const keepId = sessions[0].id;
35447
+ const deleteIds = sessions.slice(1).map((s2) => s2.id);
35448
+ for (const id of deleteIds) {
35449
+ db3.prepare(`
35450
+ UPDATE sessions
35451
+ SET status = 'deleted',
35452
+ deleted_at = datetime('now'),
35453
+ provider_session_id = provider_session_id || '-dup-' || id
35454
+ WHERE id = ?
35455
+ `).run(id);
35456
+ }
35457
+ }
35458
+ }
34747
35459
  function seedModelPricing(db3) {
34748
35460
  const insert = db3.prepare(`
34749
35461
  INSERT OR REPLACE INTO model_pricing
@@ -35978,9 +36690,9 @@ async function sessionExport(args, flags) {
35978
36690
  };
35979
36691
  const json = JSON.stringify(exportData, null, 2);
35980
36692
  if (flags.output || flags.o) {
35981
- const fs35 = await import("fs");
36693
+ const fs34 = await import("fs");
35982
36694
  const outputFile = flags.output || flags.o;
35983
- fs35.writeFileSync(outputFile, json);
36695
+ fs34.writeFileSync(outputFile, json);
35984
36696
  console.log(`\u2713 Exported session to: ${outputFile}`);
35985
36697
  } else {
35986
36698
  console.log(json);
@@ -36370,8 +37082,7 @@ Analyzing ${sessions.length} sessions...
36370
37082
  const projectSuggestions = [];
36371
37083
  const moveSuggestions = [];
36372
37084
  const knownProjects = {
36373
- "studio": "Prompt Stack Studio",
36374
- "prompt-stack": "Prompt Stack Studio",
37085
+ "studio": "RUDI Studio",
36375
37086
  "RUDI": "RUDI",
36376
37087
  "rudi": "RUDI",
36377
37088
  "cli": "RUDI",
@@ -36459,8 +37170,8 @@ Proposed actions:`);
36459
37170
  console.log(` ... and ${titleSuggestions.length - 5} more`);
36460
37171
  }
36461
37172
  }
36462
- const { writeFileSync: writeFileSync7 } = await import("fs");
36463
- writeFileSync7(outputFile, JSON.stringify(plan, null, 2));
37173
+ const { writeFileSync: writeFileSync6 } = await import("fs");
37174
+ writeFileSync6(outputFile, JSON.stringify(plan, null, 2));
36464
37175
  console.log(`
36465
37176
  \u2713 Plan saved to: ${outputFile}`);
36466
37177
  console.log("\nTo apply this plan:");
@@ -38410,281 +39121,6 @@ Wiring up RUDI router...`);
38410
39121
  console.log(" rudi index # Rebuild tool cache");
38411
39122
  }
38412
39123
 
38413
- // src/commands/migrate.js
38414
- var fs30 = __toESM(require("fs"), 1);
38415
- var path30 = __toESM(require("path"), 1);
38416
- var import_os7 = __toESM(require("os"), 1);
38417
- init_src();
38418
- var HOME3 = import_os7.default.homedir();
38419
- var OLD_PROMPT_STACK = path30.join(HOME3, ".prompt-stack");
38420
- var SHIM_PATH = path30.join(PATHS.home, "shims", "rudi-mcp");
38421
- function getOldStacks() {
38422
- const stacksDir = path30.join(OLD_PROMPT_STACK, "stacks");
38423
- if (!fs30.existsSync(stacksDir)) return [];
38424
- return fs30.readdirSync(stacksDir, { withFileTypes: true }).filter((d2) => d2.isDirectory() && !d2.name.startsWith(".")).filter((d2) => {
38425
- const hasManifest = fs30.existsSync(path30.join(stacksDir, d2.name, "manifest.json"));
38426
- const hasPackage = fs30.existsSync(path30.join(stacksDir, d2.name, "package.json"));
38427
- return hasManifest || hasPackage;
38428
- }).map((d2) => d2.name);
38429
- }
38430
- function copyStack(stackName) {
38431
- const oldPath = path30.join(OLD_PROMPT_STACK, "stacks", stackName);
38432
- const newPath = path30.join(PATHS.stacks, stackName);
38433
- if (!fs30.existsSync(oldPath)) {
38434
- return { success: false, error: "Source not found" };
38435
- }
38436
- if (fs30.existsSync(newPath)) {
38437
- return { success: true, skipped: true, reason: "Already exists" };
38438
- }
38439
- if (!fs30.existsSync(PATHS.stacks)) {
38440
- fs30.mkdirSync(PATHS.stacks, { recursive: true });
38441
- }
38442
- copyRecursive(oldPath, newPath);
38443
- return { success: true, copied: true };
38444
- }
38445
- function copyRecursive(src, dest) {
38446
- const stat = fs30.statSync(src);
38447
- if (stat.isDirectory()) {
38448
- fs30.mkdirSync(dest, { recursive: true });
38449
- for (const child of fs30.readdirSync(src)) {
38450
- copyRecursive(path30.join(src, child), path30.join(dest, child));
38451
- }
38452
- } else {
38453
- fs30.copyFileSync(src, dest);
38454
- }
38455
- }
38456
- function ensureShim() {
38457
- const shimsDir = path30.dirname(SHIM_PATH);
38458
- if (!fs30.existsSync(shimsDir)) {
38459
- fs30.mkdirSync(shimsDir, { recursive: true });
38460
- }
38461
- const shimContent = `#!/usr/bin/env bash
38462
- set -euo pipefail
38463
- if command -v rudi &> /dev/null; then
38464
- exec rudi mcp "$1"
38465
- else
38466
- exec npx --yes @learnrudi/cli mcp "$1"
38467
- fi
38468
- `;
38469
- fs30.writeFileSync(SHIM_PATH, shimContent, { mode: 493 });
38470
- }
38471
- function buildNewEntry(stackName, agentId) {
38472
- const base = {
38473
- command: SHIM_PATH,
38474
- args: [stackName]
38475
- };
38476
- if (agentId === "claude-desktop" || agentId === "claude-code") {
38477
- return { type: "stdio", ...base };
38478
- }
38479
- return base;
38480
- }
38481
- function isOldEntry(entry) {
38482
- if (!entry) return false;
38483
- const command = entry.command || "";
38484
- const args = entry.args || [];
38485
- const cwd = entry.cwd || "";
38486
- return command.includes(".prompt-stack") || args.some((a2) => typeof a2 === "string" && a2.includes(".prompt-stack")) || cwd.includes(".prompt-stack");
38487
- }
38488
- function migrateAgentConfig(agentConfig, installedStacks, flags) {
38489
- const configPath = findAgentConfig(agentConfig);
38490
- if (!configPath) return { skipped: true, reason: "Config not found" };
38491
- let config;
38492
- try {
38493
- config = JSON.parse(fs30.readFileSync(configPath, "utf-8"));
38494
- } catch {
38495
- return { skipped: true, reason: "Could not parse config" };
38496
- }
38497
- const key = agentConfig.key;
38498
- const mcpServers = config[key] || {};
38499
- let updated = 0;
38500
- let removed = 0;
38501
- const changes = [];
38502
- for (const [name, entry] of Object.entries(mcpServers)) {
38503
- if (isOldEntry(entry)) {
38504
- if (installedStacks.includes(name)) {
38505
- const newEntry = buildNewEntry(name, agentConfig.id);
38506
- mcpServers[name] = newEntry;
38507
- updated++;
38508
- changes.push({ name, action: "updated" });
38509
- } else if (flags.removeOrphans) {
38510
- delete mcpServers[name];
38511
- removed++;
38512
- changes.push({ name, action: "removed (not installed)" });
38513
- } else {
38514
- changes.push({ name, action: "skipped (not installed in .rudi)" });
38515
- }
38516
- }
38517
- }
38518
- if (updated > 0 || removed > 0) {
38519
- const backupPath = configPath + ".backup." + Date.now();
38520
- fs30.copyFileSync(configPath, backupPath);
38521
- config[key] = mcpServers;
38522
- fs30.writeFileSync(configPath, JSON.stringify(config, null, 2));
38523
- }
38524
- return { updated, removed, changes };
38525
- }
38526
- async function cmdMigrate(args, flags) {
38527
- const subcommand = args[0];
38528
- if (!subcommand || subcommand === "help") {
38529
- console.log(`
38530
- rudi migrate - Migrate from .prompt-stack to .rudi
38531
-
38532
- USAGE
38533
- rudi migrate status Show what needs to be migrated
38534
- rudi migrate stacks Copy stacks from .prompt-stack to .rudi
38535
- rudi migrate configs Update agent configs to use new shim
38536
- rudi migrate all Do everything
38537
-
38538
- OPTIONS
38539
- --remove-orphans Remove entries for stacks not installed in .rudi
38540
- --dry-run Show what would be done without making changes
38541
- `);
38542
- return;
38543
- }
38544
- if (subcommand === "status") {
38545
- await migrateStatus();
38546
- return;
38547
- }
38548
- if (subcommand === "stacks") {
38549
- await migrateStacks(flags);
38550
- return;
38551
- }
38552
- if (subcommand === "configs") {
38553
- await migrateConfigs(flags);
38554
- return;
38555
- }
38556
- if (subcommand === "all") {
38557
- await migrateStacks(flags);
38558
- console.log("");
38559
- await migrateConfigs(flags);
38560
- return;
38561
- }
38562
- console.error(`Unknown subcommand: ${subcommand}`);
38563
- console.error("Run: rudi migrate help");
38564
- }
38565
- async function migrateStatus() {
38566
- console.log("\n=== Migration Status ===\n");
38567
- const oldStacks = getOldStacks();
38568
- console.log(`Old .prompt-stack stacks: ${oldStacks.length}`);
38569
- if (oldStacks.length > 0) {
38570
- for (const name of oldStacks) {
38571
- const existsInRudi = fs30.existsSync(path30.join(PATHS.stacks, name));
38572
- const status = existsInRudi ? "\u2713 (already in .rudi)" : "\u25CB (needs migration)";
38573
- console.log(` ${status} ${name}`);
38574
- }
38575
- }
38576
- const newStacksDir = PATHS.stacks;
38577
- let newStacks = [];
38578
- if (fs30.existsSync(newStacksDir)) {
38579
- newStacks = fs30.readdirSync(newStacksDir, { withFileTypes: true }).filter((d2) => d2.isDirectory() && !d2.name.startsWith(".")).map((d2) => d2.name);
38580
- }
38581
- console.log(`
38582
- New .rudi stacks: ${newStacks.length}`);
38583
- if (newStacks.length > 0) {
38584
- for (const name of newStacks) {
38585
- console.log(` \u2713 ${name}`);
38586
- }
38587
- }
38588
- console.log("\n=== Agent Configs ===\n");
38589
- for (const agentConfig of AGENT_CONFIGS) {
38590
- const configPath = findAgentConfig(agentConfig);
38591
- if (!configPath) continue;
38592
- let config;
38593
- try {
38594
- config = JSON.parse(fs30.readFileSync(configPath, "utf-8"));
38595
- } catch {
38596
- continue;
38597
- }
38598
- const mcpServers = config[agentConfig.key] || {};
38599
- const entries = Object.entries(mcpServers);
38600
- const oldEntries = entries.filter(([_2, e2]) => isOldEntry(e2));
38601
- const newEntries = entries.filter(([_2, e2]) => !isOldEntry(e2));
38602
- if (entries.length === 0) continue;
38603
- console.log(`${agentConfig.name}:`);
38604
- console.log(` Config: ${configPath}`);
38605
- console.log(` Old entries: ${oldEntries.length}`);
38606
- console.log(` New entries: ${newEntries.length}`);
38607
- if (oldEntries.length > 0) {
38608
- console.log(" Needs update:");
38609
- for (const [name] of oldEntries) {
38610
- const installed = newStacks.includes(name);
38611
- const status = installed ? "(ready)" : "(not in .rudi)";
38612
- console.log(` - ${name} ${status}`);
38613
- }
38614
- }
38615
- console.log("");
38616
- }
38617
- console.log("Run: rudi migrate all");
38618
- }
38619
- async function migrateStacks(flags) {
38620
- console.log("=== Migrating Stacks ===\n");
38621
- const oldStacks = getOldStacks();
38622
- if (oldStacks.length === 0) {
38623
- console.log("No stacks found in .prompt-stack");
38624
- return;
38625
- }
38626
- console.log(`Found ${oldStacks.length} stack(s) in .prompt-stack
38627
- `);
38628
- for (const name of oldStacks) {
38629
- if (flags.dryRun) {
38630
- const exists = fs30.existsSync(path30.join(PATHS.stacks, name));
38631
- console.log(` [dry-run] ${name}: ${exists ? "would skip (exists)" : "would copy"}`);
38632
- } else {
38633
- const result = copyStack(name);
38634
- if (result.skipped) {
38635
- console.log(` \u25CB ${name}: skipped (${result.reason})`);
38636
- } else if (result.copied) {
38637
- console.log(` \u2713 ${name}: copied to .rudi/stacks/`);
38638
- } else {
38639
- console.log(` \u2717 ${name}: ${result.error}`);
38640
- }
38641
- }
38642
- }
38643
- if (!flags.dryRun) {
38644
- console.log(`
38645
- Stacks migrated to: ${PATHS.stacks}`);
38646
- }
38647
- }
38648
- async function migrateConfigs(flags) {
38649
- console.log("=== Updating Agent Configs ===\n");
38650
- if (!flags.dryRun) {
38651
- ensureShim();
38652
- console.log(`Shim ready: ${SHIM_PATH}
38653
- `);
38654
- }
38655
- let installedStacks = [];
38656
- if (fs30.existsSync(PATHS.stacks)) {
38657
- installedStacks = fs30.readdirSync(PATHS.stacks, { withFileTypes: true }).filter((d2) => d2.isDirectory() && !d2.name.startsWith(".")).map((d2) => d2.name);
38658
- }
38659
- for (const agentConfig of AGENT_CONFIGS) {
38660
- const configPath = findAgentConfig(agentConfig);
38661
- if (!configPath) continue;
38662
- if (flags.dryRun) {
38663
- console.log(`${agentConfig.name}:`);
38664
- console.log(` [dry-run] Would update entries using .prompt-stack paths`);
38665
- continue;
38666
- }
38667
- const result = migrateAgentConfig(agentConfig, installedStacks, flags);
38668
- if (result.skipped) {
38669
- continue;
38670
- }
38671
- console.log(`${agentConfig.name}:`);
38672
- console.log(` Config: ${configPath}`);
38673
- if (result.changes && result.changes.length > 0) {
38674
- for (const change of result.changes) {
38675
- console.log(` ${change.action}: ${change.name}`);
38676
- }
38677
- }
38678
- if (result.updated > 0 || result.removed > 0) {
38679
- console.log(` Updated: ${result.updated}, Removed: ${result.removed}`);
38680
- } else {
38681
- console.log(` No changes needed`);
38682
- }
38683
- console.log("");
38684
- }
38685
- console.log("Restart your agents to use the updated configs.");
38686
- }
38687
-
38688
39124
  // src/commands/index-tools.js
38689
39125
  init_src4();
38690
39126
  init_src4();
@@ -38824,7 +39260,7 @@ init_src4();
38824
39260
  var import_child_process11 = require("child_process");
38825
39261
  var import_fs24 = __toESM(require("fs"), 1);
38826
39262
  var import_path22 = __toESM(require("path"), 1);
38827
- var import_os8 = __toESM(require("os"), 1);
39263
+ var import_os7 = __toESM(require("os"), 1);
38828
39264
  var AGENTS = [
38829
39265
  {
38830
39266
  id: "claude",
@@ -38869,7 +39305,7 @@ var BINARIES = [
38869
39305
  { id: "jq", name: "jq", command: "jq", versionFlag: "--version" }
38870
39306
  ];
38871
39307
  function fileExists(filePath) {
38872
- const resolved = filePath.replace("~", import_os8.default.homedir());
39308
+ const resolved = filePath.replace("~", import_os7.default.homedir());
38873
39309
  return import_fs24.default.existsSync(resolved);
38874
39310
  }
38875
39311
  function checkKeychain(service) {
@@ -39120,7 +39556,7 @@ init_src4();
39120
39556
  var import_child_process12 = require("child_process");
39121
39557
  var import_fs25 = __toESM(require("fs"), 1);
39122
39558
  var import_path23 = __toESM(require("path"), 1);
39123
- var import_os9 = __toESM(require("os"), 1);
39559
+ var import_os8 = __toESM(require("os"), 1);
39124
39560
  var AGENT_CREDENTIALS = {
39125
39561
  claude: { type: "keychain", service: "Claude Code-credentials" },
39126
39562
  codex: { type: "file", path: "~/.codex/auth.json" },
@@ -39128,7 +39564,7 @@ var AGENT_CREDENTIALS = {
39128
39564
  copilot: { type: "file", path: "~/.config/github-copilot/hosts.json" }
39129
39565
  };
39130
39566
  function fileExists2(filePath) {
39131
- const resolved = filePath.replace("~", import_os9.default.homedir());
39567
+ const resolved = filePath.replace("~", import_os8.default.homedir());
39132
39568
  return import_fs25.default.existsSync(resolved);
39133
39569
  }
39134
39570
  function checkKeychain2(service) {
@@ -39637,7 +40073,7 @@ Lockfile: ${lockPath}`);
39637
40073
  // src/commands/apply.js
39638
40074
  var import_fs28 = require("fs");
39639
40075
  var import_path26 = require("path");
39640
- var import_os10 = require("os");
40076
+ var import_os9 = require("os");
39641
40077
  var import_crypto3 = require("crypto");
39642
40078
  async function cmdApply(args, flags) {
39643
40079
  const planFile = args[0];
@@ -39820,10 +40256,10 @@ Applying plan ${planId}...
39820
40256
  }
39821
40257
  console.log(` \u2713 Updated ${updated} titles`);
39822
40258
  }
39823
- const undoDir = (0, import_path26.join)((0, import_os10.homedir)(), ".rudi", "plans");
39824
- const { mkdirSync: mkdirSync5 } = await import("fs");
40259
+ const undoDir = (0, import_path26.join)((0, import_os9.homedir)(), ".rudi", "plans");
40260
+ const { mkdirSync: mkdirSync4 } = await import("fs");
39825
40261
  try {
39826
- mkdirSync5(undoDir, { recursive: true });
40262
+ mkdirSync4(undoDir, { recursive: true });
39827
40263
  } catch (e2) {
39828
40264
  }
39829
40265
  const undoFile = (0, import_path26.join)(undoDir, `${planId}.undo.json`);
@@ -40087,9 +40523,6 @@ async function main() {
40087
40523
  case "integrate":
40088
40524
  await cmdIntegrate(args, flags);
40089
40525
  break;
40090
- case "migrate":
40091
- await cmdMigrate(args, flags);
40092
- break;
40093
40526
  case "index":
40094
40527
  await cmdIndex(args, flags);
40095
40528
  break;