oh-my-opencode 3.7.1 → 3.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -586,7 +586,7 @@ var require_scan = __commonJS((exports, module) => {
586
586
 
587
587
  // node_modules/picomatch/lib/parse.js
588
588
  var require_parse = __commonJS((exports, module) => {
589
- var constants2 = require_constants();
589
+ var constants3 = require_constants();
590
590
  var utils = require_utils();
591
591
  var {
592
592
  MAX_LENGTH,
@@ -594,7 +594,7 @@ var require_parse = __commonJS((exports, module) => {
594
594
  REGEX_NON_SPECIAL_CHARS,
595
595
  REGEX_SPECIAL_CHARS_BACKREF,
596
596
  REPLACEMENTS
597
- } = constants2;
597
+ } = constants3;
598
598
  var expandRange = (args, options) => {
599
599
  if (typeof options.expandRange === "function") {
600
600
  return options.expandRange(...args, options);
@@ -625,8 +625,8 @@ var require_parse = __commonJS((exports, module) => {
625
625
  const bos = { type: "bos", value: "", output: opts.prepend || "" };
626
626
  const tokens = [bos];
627
627
  const capture = opts.capture ? "" : "?:";
628
- const PLATFORM_CHARS = constants2.globChars(opts.windows);
629
- const EXTGLOB_CHARS = constants2.extglobChars(PLATFORM_CHARS);
628
+ const PLATFORM_CHARS = constants3.globChars(opts.windows);
629
+ const EXTGLOB_CHARS = constants3.extglobChars(PLATFORM_CHARS);
630
630
  const {
631
631
  DOT_LITERAL,
632
632
  PLUS_LITERAL,
@@ -1304,7 +1304,7 @@ var require_parse = __commonJS((exports, module) => {
1304
1304
  NO_DOTS_SLASH,
1305
1305
  STAR,
1306
1306
  START_ANCHOR
1307
- } = constants2.globChars(opts.windows);
1307
+ } = constants3.globChars(opts.windows);
1308
1308
  const nodot = opts.dot ? NO_DOTS : NO_DOT;
1309
1309
  const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
1310
1310
  const capture = opts.capture ? "" : "?:";
@@ -1362,7 +1362,7 @@ var require_picomatch = __commonJS((exports, module) => {
1362
1362
  var scan = require_scan();
1363
1363
  var parse7 = require_parse();
1364
1364
  var utils = require_utils();
1365
- var constants2 = require_constants();
1365
+ var constants3 = require_constants();
1366
1366
  var isObject3 = (val) => val && typeof val === "object" && !Array.isArray(val);
1367
1367
  var picomatch = (glob, options, returnState = false) => {
1368
1368
  if (Array.isArray(glob)) {
@@ -1493,7 +1493,7 @@ var require_picomatch = __commonJS((exports, module) => {
1493
1493
  return /$^/;
1494
1494
  }
1495
1495
  };
1496
- picomatch.constants = constants2;
1496
+ picomatch.constants = constants3;
1497
1497
  module.exports = picomatch;
1498
1498
  });
1499
1499
 
@@ -5659,11 +5659,11 @@ var require_codegen = __commonJS((exports) => {
5659
5659
  const rhs = this.rhs === undefined ? "" : ` = ${this.rhs}`;
5660
5660
  return `${varKind} ${this.name}${rhs};` + _n;
5661
5661
  }
5662
- optimizeNames(names, constants18) {
5662
+ optimizeNames(names, constants19) {
5663
5663
  if (!names[this.name.str])
5664
5664
  return;
5665
5665
  if (this.rhs)
5666
- this.rhs = optimizeExpr(this.rhs, names, constants18);
5666
+ this.rhs = optimizeExpr(this.rhs, names, constants19);
5667
5667
  return this;
5668
5668
  }
5669
5669
  get names() {
@@ -5681,10 +5681,10 @@ var require_codegen = __commonJS((exports) => {
5681
5681
  render({ _n }) {
5682
5682
  return `${this.lhs} = ${this.rhs};` + _n;
5683
5683
  }
5684
- optimizeNames(names, constants18) {
5684
+ optimizeNames(names, constants19) {
5685
5685
  if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
5686
5686
  return;
5687
- this.rhs = optimizeExpr(this.rhs, names, constants18);
5687
+ this.rhs = optimizeExpr(this.rhs, names, constants19);
5688
5688
  return this;
5689
5689
  }
5690
5690
  get names() {
@@ -5750,8 +5750,8 @@ var require_codegen = __commonJS((exports) => {
5750
5750
  optimizeNodes() {
5751
5751
  return `${this.code}` ? this : undefined;
5752
5752
  }
5753
- optimizeNames(names, constants18) {
5754
- this.code = optimizeExpr(this.code, names, constants18);
5753
+ optimizeNames(names, constants19) {
5754
+ this.code = optimizeExpr(this.code, names, constants19);
5755
5755
  return this;
5756
5756
  }
5757
5757
  get names() {
@@ -5781,12 +5781,12 @@ var require_codegen = __commonJS((exports) => {
5781
5781
  }
5782
5782
  return nodes.length > 0 ? this : undefined;
5783
5783
  }
5784
- optimizeNames(names, constants18) {
5784
+ optimizeNames(names, constants19) {
5785
5785
  const { nodes } = this;
5786
5786
  let i2 = nodes.length;
5787
5787
  while (i2--) {
5788
5788
  const n = nodes[i2];
5789
- if (n.optimizeNames(names, constants18))
5789
+ if (n.optimizeNames(names, constants19))
5790
5790
  continue;
5791
5791
  subtractNames(names, n.names);
5792
5792
  nodes.splice(i2, 1);
@@ -5843,12 +5843,12 @@ var require_codegen = __commonJS((exports) => {
5843
5843
  return;
5844
5844
  return this;
5845
5845
  }
5846
- optimizeNames(names, constants18) {
5846
+ optimizeNames(names, constants19) {
5847
5847
  var _a;
5848
- this.else = (_a = this.else) === null || _a === undefined ? undefined : _a.optimizeNames(names, constants18);
5849
- if (!(super.optimizeNames(names, constants18) || this.else))
5848
+ this.else = (_a = this.else) === null || _a === undefined ? undefined : _a.optimizeNames(names, constants19);
5849
+ if (!(super.optimizeNames(names, constants19) || this.else))
5850
5850
  return;
5851
- this.condition = optimizeExpr(this.condition, names, constants18);
5851
+ this.condition = optimizeExpr(this.condition, names, constants19);
5852
5852
  return this;
5853
5853
  }
5854
5854
  get names() {
@@ -5873,10 +5873,10 @@ var require_codegen = __commonJS((exports) => {
5873
5873
  render(opts) {
5874
5874
  return `for(${this.iteration})` + super.render(opts);
5875
5875
  }
5876
- optimizeNames(names, constants18) {
5877
- if (!super.optimizeNames(names, constants18))
5876
+ optimizeNames(names, constants19) {
5877
+ if (!super.optimizeNames(names, constants19))
5878
5878
  return;
5879
- this.iteration = optimizeExpr(this.iteration, names, constants18);
5879
+ this.iteration = optimizeExpr(this.iteration, names, constants19);
5880
5880
  return this;
5881
5881
  }
5882
5882
  get names() {
@@ -5914,10 +5914,10 @@ var require_codegen = __commonJS((exports) => {
5914
5914
  render(opts) {
5915
5915
  return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
5916
5916
  }
5917
- optimizeNames(names, constants18) {
5918
- if (!super.optimizeNames(names, constants18))
5917
+ optimizeNames(names, constants19) {
5918
+ if (!super.optimizeNames(names, constants19))
5919
5919
  return;
5920
- this.iterable = optimizeExpr(this.iterable, names, constants18);
5920
+ this.iterable = optimizeExpr(this.iterable, names, constants19);
5921
5921
  return this;
5922
5922
  }
5923
5923
  get names() {
@@ -5962,11 +5962,11 @@ var require_codegen = __commonJS((exports) => {
5962
5962
  (_b = this.finally) === null || _b === undefined || _b.optimizeNodes();
5963
5963
  return this;
5964
5964
  }
5965
- optimizeNames(names, constants18) {
5965
+ optimizeNames(names, constants19) {
5966
5966
  var _a, _b;
5967
- super.optimizeNames(names, constants18);
5968
- (_a = this.catch) === null || _a === undefined || _a.optimizeNames(names, constants18);
5969
- (_b = this.finally) === null || _b === undefined || _b.optimizeNames(names, constants18);
5967
+ super.optimizeNames(names, constants19);
5968
+ (_a = this.catch) === null || _a === undefined || _a.optimizeNames(names, constants19);
5969
+ (_b = this.finally) === null || _b === undefined || _b.optimizeNames(names, constants19);
5970
5970
  return this;
5971
5971
  }
5972
5972
  get names() {
@@ -6240,7 +6240,7 @@ var require_codegen = __commonJS((exports) => {
6240
6240
  function addExprNames(names, from) {
6241
6241
  return from instanceof code_1._CodeOrName ? addNames(names, from.names) : names;
6242
6242
  }
6243
- function optimizeExpr(expr, names, constants18) {
6243
+ function optimizeExpr(expr, names, constants19) {
6244
6244
  if (expr instanceof code_1.Name)
6245
6245
  return replaceName(expr);
6246
6246
  if (!canOptimize(expr))
@@ -6255,14 +6255,14 @@ var require_codegen = __commonJS((exports) => {
6255
6255
  return items;
6256
6256
  }, []));
6257
6257
  function replaceName(n) {
6258
- const c = constants18[n.str];
6258
+ const c = constants19[n.str];
6259
6259
  if (c === undefined || names[n.str] !== 1)
6260
6260
  return n;
6261
6261
  delete names[n.str];
6262
6262
  return c;
6263
6263
  }
6264
6264
  function canOptimize(e) {
6265
- return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants18[c.str] !== undefined);
6265
+ return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants19[c.str] !== undefined);
6266
6266
  }
6267
6267
  }
6268
6268
  function subtractNames(names, from) {
@@ -6709,37 +6709,37 @@ var require_dataType = __commonJS((exports) => {
6709
6709
  DataType2[DataType2["Wrong"] = 1] = "Wrong";
6710
6710
  })(DataType || (exports.DataType = DataType = {}));
6711
6711
  function getSchemaTypes(schema2) {
6712
- const types20 = getJSONTypes(schema2.type);
6713
- const hasNull = types20.includes("null");
6712
+ const types21 = getJSONTypes(schema2.type);
6713
+ const hasNull = types21.includes("null");
6714
6714
  if (hasNull) {
6715
6715
  if (schema2.nullable === false)
6716
6716
  throw new Error("type: null contradicts nullable: false");
6717
6717
  } else {
6718
- if (!types20.length && schema2.nullable !== undefined) {
6718
+ if (!types21.length && schema2.nullable !== undefined) {
6719
6719
  throw new Error('"nullable" cannot be used without "type"');
6720
6720
  }
6721
6721
  if (schema2.nullable === true)
6722
- types20.push("null");
6722
+ types21.push("null");
6723
6723
  }
6724
- return types20;
6724
+ return types21;
6725
6725
  }
6726
6726
  exports.getSchemaTypes = getSchemaTypes;
6727
6727
  function getJSONTypes(ts) {
6728
- const types20 = Array.isArray(ts) ? ts : ts ? [ts] : [];
6729
- if (types20.every(rules_1.isJSONType))
6730
- return types20;
6731
- throw new Error("type must be JSONType or JSONType[]: " + types20.join(","));
6728
+ const types21 = Array.isArray(ts) ? ts : ts ? [ts] : [];
6729
+ if (types21.every(rules_1.isJSONType))
6730
+ return types21;
6731
+ throw new Error("type must be JSONType or JSONType[]: " + types21.join(","));
6732
6732
  }
6733
6733
  exports.getJSONTypes = getJSONTypes;
6734
- function coerceAndCheckDataType(it, types20) {
6734
+ function coerceAndCheckDataType(it, types21) {
6735
6735
  const { gen, data, opts } = it;
6736
- const coerceTo = coerceToTypes(types20, opts.coerceTypes);
6737
- const checkTypes = types20.length > 0 && !(coerceTo.length === 0 && types20.length === 1 && (0, applicability_1.schemaHasRulesForType)(it, types20[0]));
6736
+ const coerceTo = coerceToTypes(types21, opts.coerceTypes);
6737
+ const checkTypes = types21.length > 0 && !(coerceTo.length === 0 && types21.length === 1 && (0, applicability_1.schemaHasRulesForType)(it, types21[0]));
6738
6738
  if (checkTypes) {
6739
- const wrongType = checkDataTypes(types20, data, opts.strictNumbers, DataType.Wrong);
6739
+ const wrongType = checkDataTypes(types21, data, opts.strictNumbers, DataType.Wrong);
6740
6740
  gen.if(wrongType, () => {
6741
6741
  if (coerceTo.length)
6742
- coerceData(it, types20, coerceTo);
6742
+ coerceData(it, types21, coerceTo);
6743
6743
  else
6744
6744
  reportTypeError(it);
6745
6745
  });
@@ -6748,15 +6748,15 @@ var require_dataType = __commonJS((exports) => {
6748
6748
  }
6749
6749
  exports.coerceAndCheckDataType = coerceAndCheckDataType;
6750
6750
  var COERCIBLE = new Set(["string", "number", "integer", "boolean", "null"]);
6751
- function coerceToTypes(types20, coerceTypes) {
6752
- return coerceTypes ? types20.filter((t) => COERCIBLE.has(t) || coerceTypes === "array" && t === "array") : [];
6751
+ function coerceToTypes(types21, coerceTypes) {
6752
+ return coerceTypes ? types21.filter((t) => COERCIBLE.has(t) || coerceTypes === "array" && t === "array") : [];
6753
6753
  }
6754
- function coerceData(it, types20, coerceTo) {
6754
+ function coerceData(it, types21, coerceTo) {
6755
6755
  const { gen, data, opts } = it;
6756
6756
  const dataType = gen.let("dataType", (0, codegen_1._)`typeof ${data}`);
6757
6757
  const coerced = gen.let("coerced", (0, codegen_1._)`undefined`);
6758
6758
  if (opts.coerceTypes === "array") {
6759
- gen.if((0, codegen_1._)`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen.assign(data, (0, codegen_1._)`${data}[0]`).assign(dataType, (0, codegen_1._)`typeof ${data}`).if(checkDataTypes(types20, data, opts.strictNumbers), () => gen.assign(coerced, data)));
6759
+ gen.if((0, codegen_1._)`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen.assign(data, (0, codegen_1._)`${data}[0]`).assign(dataType, (0, codegen_1._)`typeof ${data}`).if(checkDataTypes(types21, data, opts.strictNumbers), () => gen.assign(coerced, data)));
6760
6760
  }
6761
6761
  gen.if((0, codegen_1._)`${coerced} !== undefined`);
6762
6762
  for (const t of coerceTo) {
@@ -6832,19 +6832,19 @@ var require_dataType = __commonJS((exports) => {
6832
6832
  return checkDataType(dataTypes[0], data, strictNums, correct);
6833
6833
  }
6834
6834
  let cond;
6835
- const types20 = (0, util_1.toHash)(dataTypes);
6836
- if (types20.array && types20.object) {
6835
+ const types21 = (0, util_1.toHash)(dataTypes);
6836
+ if (types21.array && types21.object) {
6837
6837
  const notObj = (0, codegen_1._)`typeof ${data} != "object"`;
6838
- cond = types20.null ? notObj : (0, codegen_1._)`!${data} || ${notObj}`;
6839
- delete types20.null;
6840
- delete types20.array;
6841
- delete types20.object;
6838
+ cond = types21.null ? notObj : (0, codegen_1._)`!${data} || ${notObj}`;
6839
+ delete types21.null;
6840
+ delete types21.array;
6841
+ delete types21.object;
6842
6842
  } else {
6843
6843
  cond = codegen_1.nil;
6844
6844
  }
6845
- if (types20.number)
6846
- delete types20.integer;
6847
- for (const t in types20)
6845
+ if (types21.number)
6846
+ delete types21.integer;
6847
+ for (const t in types21)
6848
6848
  cond = (0, codegen_1.and)(cond, checkDataType(t, data, strictNums, correct));
6849
6849
  return cond;
6850
6850
  }
@@ -7632,9 +7632,9 @@ var require_validate = __commonJS((exports) => {
7632
7632
  function typeAndKeywords(it, errsCount) {
7633
7633
  if (it.opts.jtd)
7634
7634
  return schemaKeywords(it, [], false, errsCount);
7635
- const types20 = (0, dataType_1.getSchemaTypes)(it.schema);
7636
- const checkedTypes = (0, dataType_1.coerceAndCheckDataType)(it, types20);
7637
- schemaKeywords(it, types20, !checkedTypes, errsCount);
7635
+ const types21 = (0, dataType_1.getSchemaTypes)(it.schema);
7636
+ const checkedTypes = (0, dataType_1.coerceAndCheckDataType)(it, types21);
7637
+ schemaKeywords(it, types21, !checkedTypes, errsCount);
7638
7638
  }
7639
7639
  function checkRefsAndKeywords(it) {
7640
7640
  const { schema: schema2, errSchemaPath, opts, self } = it;
@@ -7684,7 +7684,7 @@ var require_validate = __commonJS((exports) => {
7684
7684
  if (items instanceof codegen_1.Name)
7685
7685
  gen.assign((0, codegen_1._)`${evaluated}.items`, items);
7686
7686
  }
7687
- function schemaKeywords(it, types20, typeErrors, errsCount) {
7687
+ function schemaKeywords(it, types21, typeErrors, errsCount) {
7688
7688
  const { gen, schema: schema2, data, allErrors, opts, self } = it;
7689
7689
  const { RULES } = self;
7690
7690
  if (schema2.$ref && (opts.ignoreKeywordsWithRef || !(0, util_1.schemaHasRulesButRef)(schema2, RULES))) {
@@ -7692,7 +7692,7 @@ var require_validate = __commonJS((exports) => {
7692
7692
  return;
7693
7693
  }
7694
7694
  if (!opts.jtd)
7695
- checkStrictTypes(it, types20);
7695
+ checkStrictTypes(it, types21);
7696
7696
  gen.block(() => {
7697
7697
  for (const group of RULES.rules)
7698
7698
  groupKeywords(group);
@@ -7704,7 +7704,7 @@ var require_validate = __commonJS((exports) => {
7704
7704
  if (group.type) {
7705
7705
  gen.if((0, dataType_2.checkDataType)(group.type, data, opts.strictNumbers));
7706
7706
  iterateKeywords(it, group);
7707
- if (types20.length === 1 && types20[0] === group.type && typeErrors) {
7707
+ if (types21.length === 1 && types21[0] === group.type && typeErrors) {
7708
7708
  gen.else();
7709
7709
  (0, dataType_2.reportTypeError)(it);
7710
7710
  }
@@ -7728,27 +7728,27 @@ var require_validate = __commonJS((exports) => {
7728
7728
  }
7729
7729
  });
7730
7730
  }
7731
- function checkStrictTypes(it, types20) {
7731
+ function checkStrictTypes(it, types21) {
7732
7732
  if (it.schemaEnv.meta || !it.opts.strictTypes)
7733
7733
  return;
7734
- checkContextTypes(it, types20);
7734
+ checkContextTypes(it, types21);
7735
7735
  if (!it.opts.allowUnionTypes)
7736
- checkMultipleTypes(it, types20);
7736
+ checkMultipleTypes(it, types21);
7737
7737
  checkKeywordTypes(it, it.dataTypes);
7738
7738
  }
7739
- function checkContextTypes(it, types20) {
7740
- if (!types20.length)
7739
+ function checkContextTypes(it, types21) {
7740
+ if (!types21.length)
7741
7741
  return;
7742
7742
  if (!it.dataTypes.length) {
7743
- it.dataTypes = types20;
7743
+ it.dataTypes = types21;
7744
7744
  return;
7745
7745
  }
7746
- types20.forEach((t) => {
7746
+ types21.forEach((t) => {
7747
7747
  if (!includesType(it.dataTypes, t)) {
7748
7748
  strictTypesError(it, `type "${t}" not allowed by context "${it.dataTypes.join(",")}"`);
7749
7749
  }
7750
7750
  });
7751
- narrowSchemaTypes(it, types20);
7751
+ narrowSchemaTypes(it, types21);
7752
7752
  }
7753
7753
  function checkMultipleTypes(it, ts) {
7754
7754
  if (ts.length > 1 && !(ts.length === 2 && ts.includes("null"))) {
@@ -12242,7 +12242,56 @@ var ABORT_WINDOW_MS = 3000;
12242
12242
  var CONTINUATION_COOLDOWN_MS = 30000;
12243
12243
  var MAX_CONSECUTIVE_FAILURES = 5;
12244
12244
  var FAILURE_RESET_WINDOW_MS = 5 * 60 * 1000;
12245
-
12245
+ // src/features/run-continuation-state/constants.ts
12246
+ var CONTINUATION_MARKER_DIR = ".sisyphus/run-continuation";
12247
+ // src/features/run-continuation-state/storage.ts
12248
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "fs";
12249
+ import { join as join2 } from "path";
12250
+ function getMarkerPath(directory, sessionID) {
12251
+ return join2(directory, CONTINUATION_MARKER_DIR, `${sessionID}.json`);
12252
+ }
12253
+ function readContinuationMarker(directory, sessionID) {
12254
+ const markerPath = getMarkerPath(directory, sessionID);
12255
+ if (!existsSync(markerPath))
12256
+ return null;
12257
+ try {
12258
+ const raw = readFileSync(markerPath, "utf-8");
12259
+ const parsed = JSON.parse(raw);
12260
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
12261
+ return null;
12262
+ return parsed;
12263
+ } catch {
12264
+ return null;
12265
+ }
12266
+ }
12267
+ function setContinuationMarkerSource(directory, sessionID, source, state, reason) {
12268
+ const now = new Date().toISOString();
12269
+ const existing = readContinuationMarker(directory, sessionID);
12270
+ const next = {
12271
+ sessionID,
12272
+ updatedAt: now,
12273
+ sources: {
12274
+ ...existing?.sources ?? {},
12275
+ [source]: {
12276
+ state,
12277
+ ...reason ? { reason } : {},
12278
+ updatedAt: now
12279
+ }
12280
+ }
12281
+ };
12282
+ const markerPath = getMarkerPath(directory, sessionID);
12283
+ mkdirSync(join2(directory, CONTINUATION_MARKER_DIR), { recursive: true });
12284
+ writeFileSync(markerPath, JSON.stringify(next, null, 2), "utf-8");
12285
+ return next;
12286
+ }
12287
+ function clearContinuationMarker(directory, sessionID) {
12288
+ const markerPath = getMarkerPath(directory, sessionID);
12289
+ if (!existsSync(markerPath))
12290
+ return;
12291
+ try {
12292
+ rmSync(markerPath);
12293
+ } catch {}
12294
+ }
12246
12295
  // src/hooks/todo-continuation-enforcer/handler.ts
12247
12296
  init_logger();
12248
12297
 
@@ -14896,7 +14945,7 @@ var load = loader.load;
14896
14945
  var loadAll = loader.loadAll;
14897
14946
  var dump = dumper.dump;
14898
14947
  var YAMLException = exception;
14899
- var types = {
14948
+ var types2 = {
14900
14949
  binary,
14901
14950
  float,
14902
14951
  map,
@@ -14925,7 +14974,7 @@ var jsYaml = {
14925
14974
  loadAll,
14926
14975
  dump,
14927
14976
  YAMLException,
14928
- types,
14977
+ types: types2,
14929
14978
  safeLoad,
14930
14979
  safeLoadAll,
14931
14980
  safeDump
@@ -14958,15 +15007,15 @@ function getHomeDirectory() {
14958
15007
  }
14959
15008
 
14960
15009
  // src/shared/command-executor/shell-path.ts
14961
- import { existsSync } from "fs";
15010
+ import { existsSync as existsSync2 } from "fs";
14962
15011
  var DEFAULT_ZSH_PATHS = ["/bin/zsh", "/usr/bin/zsh", "/usr/local/bin/zsh"];
14963
15012
  var DEFAULT_BASH_PATHS = ["/bin/bash", "/usr/bin/bash", "/usr/local/bin/bash"];
14964
15013
  function findShellPath(defaultPaths, customPath) {
14965
- if (customPath && existsSync(customPath)) {
15014
+ if (customPath && existsSync2(customPath)) {
14966
15015
  return customPath;
14967
15016
  }
14968
15017
  for (const path2 of defaultPaths) {
14969
- if (existsSync(path2)) {
15018
+ if (existsSync2(path2)) {
14970
15019
  return path2;
14971
15020
  }
14972
15021
  }
@@ -15094,8 +15143,8 @@ async function resolveCommandsInText(text, depth = 0, maxDepth = 3) {
15094
15143
  return resolved;
15095
15144
  }
15096
15145
  // src/shared/file-reference-resolver.ts
15097
- import { existsSync as existsSync2, readFileSync, statSync } from "fs";
15098
- import { join as join2, isAbsolute } from "path";
15146
+ import { existsSync as existsSync3, readFileSync as readFileSync2, statSync } from "fs";
15147
+ import { join as join3, isAbsolute } from "path";
15099
15148
  var FILE_REFERENCE_PATTERN = /@([^\s@]+)/g;
15100
15149
  function findFileReferences(text) {
15101
15150
  const matches = [];
@@ -15115,17 +15164,17 @@ function resolveFilePath(filePath, cwd) {
15115
15164
  if (isAbsolute(filePath)) {
15116
15165
  return filePath;
15117
15166
  }
15118
- return join2(cwd, filePath);
15167
+ return join3(cwd, filePath);
15119
15168
  }
15120
15169
  function readFileContent(resolvedPath) {
15121
- if (!existsSync2(resolvedPath)) {
15170
+ if (!existsSync3(resolvedPath)) {
15122
15171
  return `[file not found: ${resolvedPath}]`;
15123
15172
  }
15124
15173
  const stat = statSync(resolvedPath);
15125
15174
  if (stat.isDirectory()) {
15126
15175
  return `[cannot read directory: ${resolvedPath}]`;
15127
15176
  }
15128
- const content = readFileSync(resolvedPath, "utf-8");
15177
+ const content = readFileSync2(resolvedPath, "utf-8");
15129
15178
  return content;
15130
15179
  }
15131
15180
  async function resolveFileReferencesInText(text, cwd = process.cwd(), depth = 0, maxDepth = 3) {
@@ -15477,16 +15526,16 @@ function addConfigLoadError(error) {
15477
15526
  }
15478
15527
  // src/shared/claude-config-dir.ts
15479
15528
  import { homedir as homedir3 } from "os";
15480
- import { join as join4 } from "path";
15529
+ import { join as join5 } from "path";
15481
15530
  function getClaudeConfigDir() {
15482
15531
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
15483
15532
  if (envConfigDir) {
15484
15533
  return envConfigDir;
15485
15534
  }
15486
- return join4(homedir3(), ".claude");
15535
+ return join5(homedir3(), ".claude");
15487
15536
  }
15488
15537
  // src/shared/jsonc-parser.ts
15489
- import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
15538
+ import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
15490
15539
 
15491
15540
  // node_modules/jsonc-parser/lib/esm/impl/scanner.js
15492
15541
  function createScanner(text, ignoreTrivia = false) {
@@ -16360,10 +16409,10 @@ function parseJsoncSafe(content) {
16360
16409
  function detectConfigFile(basePath) {
16361
16410
  const jsoncPath = `${basePath}.jsonc`;
16362
16411
  const jsonPath = `${basePath}.json`;
16363
- if (existsSync3(jsoncPath)) {
16412
+ if (existsSync4(jsoncPath)) {
16364
16413
  return { format: "jsonc", path: jsoncPath };
16365
16414
  }
16366
- if (existsSync3(jsonPath)) {
16415
+ if (existsSync4(jsonPath)) {
16367
16416
  return { format: "json", path: jsonPath };
16368
16417
  }
16369
16418
  return { format: "none", path: jsonPath };
@@ -16578,9 +16627,9 @@ function migrateConfigFile(configPath, rawConfig) {
16578
16627
  return needsWrite;
16579
16628
  }
16580
16629
  // src/shared/opencode-config-dir.ts
16581
- import { existsSync as existsSync4 } from "fs";
16630
+ import { existsSync as existsSync5 } from "fs";
16582
16631
  import { homedir as homedir4 } from "os";
16583
- import { join as join5, resolve } from "path";
16632
+ import { join as join6, resolve } from "path";
16584
16633
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop";
16585
16634
  var TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
16586
16635
  function isDevBuild(version) {
@@ -16592,15 +16641,15 @@ function getTauriConfigDir(identifier) {
16592
16641
  const platform = process.platform;
16593
16642
  switch (platform) {
16594
16643
  case "darwin":
16595
- return join5(homedir4(), "Library", "Application Support", identifier);
16644
+ return join6(homedir4(), "Library", "Application Support", identifier);
16596
16645
  case "win32": {
16597
- const appData = process.env.APPDATA || join5(homedir4(), "AppData", "Roaming");
16598
- return join5(appData, identifier);
16646
+ const appData = process.env.APPDATA || join6(homedir4(), "AppData", "Roaming");
16647
+ return join6(appData, identifier);
16599
16648
  }
16600
16649
  case "linux":
16601
16650
  default: {
16602
- const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir4(), ".config");
16603
- return join5(xdgConfig, identifier);
16651
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join6(homedir4(), ".config");
16652
+ return join6(xdgConfig, identifier);
16604
16653
  }
16605
16654
  }
16606
16655
  }
@@ -16610,21 +16659,21 @@ function getCliConfigDir() {
16610
16659
  return resolve(envConfigDir);
16611
16660
  }
16612
16661
  if (process.platform === "win32") {
16613
- const crossPlatformDir = join5(homedir4(), ".config", "opencode");
16614
- const crossPlatformConfig = join5(crossPlatformDir, "opencode.json");
16615
- if (existsSync4(crossPlatformConfig)) {
16662
+ const crossPlatformDir = join6(homedir4(), ".config", "opencode");
16663
+ const crossPlatformConfig = join6(crossPlatformDir, "opencode.json");
16664
+ if (existsSync5(crossPlatformConfig)) {
16616
16665
  return crossPlatformDir;
16617
16666
  }
16618
- const appData = process.env.APPDATA || join5(homedir4(), "AppData", "Roaming");
16619
- const appdataDir = join5(appData, "opencode");
16620
- const appdataConfig = join5(appdataDir, "opencode.json");
16621
- if (existsSync4(appdataConfig)) {
16667
+ const appData = process.env.APPDATA || join6(homedir4(), "AppData", "Roaming");
16668
+ const appdataDir = join6(appData, "opencode");
16669
+ const appdataConfig = join6(appdataDir, "opencode.json");
16670
+ if (existsSync5(appdataConfig)) {
16622
16671
  return appdataDir;
16623
16672
  }
16624
16673
  return crossPlatformDir;
16625
16674
  }
16626
- const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir4(), ".config");
16627
- return join5(xdgConfig, "opencode");
16675
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join6(homedir4(), ".config");
16676
+ return join6(xdgConfig, "opencode");
16628
16677
  }
16629
16678
  function getOpenCodeConfigDir(options) {
16630
16679
  const { binary: binary2, version, checkExisting = true } = options;
@@ -16635,9 +16684,9 @@ function getOpenCodeConfigDir(options) {
16635
16684
  const tauriDir = getTauriConfigDir(identifier);
16636
16685
  if (checkExisting) {
16637
16686
  const legacyDir = getCliConfigDir();
16638
- const legacyConfig = join5(legacyDir, "opencode.json");
16639
- const legacyConfigC = join5(legacyDir, "opencode.jsonc");
16640
- if (existsSync4(legacyConfig) || existsSync4(legacyConfigC)) {
16687
+ const legacyConfig = join6(legacyDir, "opencode.json");
16688
+ const legacyConfigC = join6(legacyDir, "opencode.jsonc");
16689
+ if (existsSync5(legacyConfig) || existsSync5(legacyConfigC)) {
16641
16690
  return legacyDir;
16642
16691
  }
16643
16692
  }
@@ -16647,10 +16696,10 @@ function getOpenCodeConfigPaths(options) {
16647
16696
  const configDir = getOpenCodeConfigDir(options);
16648
16697
  return {
16649
16698
  configDir,
16650
- configJson: join5(configDir, "opencode.json"),
16651
- configJsonc: join5(configDir, "opencode.jsonc"),
16652
- packageJson: join5(configDir, "package.json"),
16653
- omoConfig: join5(configDir, "oh-my-opencode.json")
16699
+ configJson: join6(configDir, "opencode.json"),
16700
+ configJsonc: join6(configDir, "opencode.jsonc"),
16701
+ packageJson: join6(configDir, "package.json"),
16702
+ omoConfig: join6(configDir, "oh-my-opencode.json")
16654
16703
  };
16655
16704
  }
16656
16705
  // src/shared/opencode-version.ts
@@ -16702,8 +16751,8 @@ function isOpenCodeVersionAtLeast(version) {
16702
16751
  return compareVersions(current, version) >= 0;
16703
16752
  }
16704
16753
  // src/shared/opencode-storage-detection.ts
16705
- import { existsSync as existsSync5 } from "fs";
16706
- import { join as join6 } from "path";
16754
+ import { existsSync as existsSync6 } from "fs";
16755
+ import { join as join7 } from "path";
16707
16756
  var NOT_CACHED2 = Symbol("NOT_CACHED");
16708
16757
  var FALSE_PENDING_RETRY = Symbol("FALSE_PENDING_RETRY");
16709
16758
  var cachedResult = NOT_CACHED2;
@@ -16714,8 +16763,8 @@ function isSqliteBackend() {
16714
16763
  return false;
16715
16764
  const check = () => {
16716
16765
  const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
16717
- const dbPath = join6(getDataDir(), "opencode", "opencode.db");
16718
- return versionOk && existsSync5(dbPath);
16766
+ const dbPath = join7(getDataDir(), "opencode", "opencode.db");
16767
+ return versionOk && existsSync6(dbPath);
16719
16768
  };
16720
16769
  if (cachedResult === FALSE_PENDING_RETRY) {
16721
16770
  const result2 = check();
@@ -16933,16 +16982,16 @@ async function extractZip(archivePath, destDir) {
16933
16982
  }
16934
16983
  }
16935
16984
  // src/shared/binary-downloader.ts
16936
- import { chmodSync, existsSync as existsSync7, mkdirSync, unlinkSync } from "fs";
16985
+ import { chmodSync, existsSync as existsSync8, mkdirSync as mkdirSync2, unlinkSync } from "fs";
16937
16986
  import * as path4 from "path";
16938
16987
  var {spawn: spawn3 } = globalThis.Bun;
16939
16988
  function getCachedBinaryPath(cacheDir, binaryName) {
16940
16989
  const binaryPath = path4.join(cacheDir, binaryName);
16941
- return existsSync7(binaryPath) ? binaryPath : null;
16990
+ return existsSync8(binaryPath) ? binaryPath : null;
16942
16991
  }
16943
16992
  function ensureCacheDir(cacheDir) {
16944
- if (!existsSync7(cacheDir)) {
16945
- mkdirSync(cacheDir, { recursive: true });
16993
+ if (!existsSync8(cacheDir)) {
16994
+ mkdirSync2(cacheDir, { recursive: true });
16946
16995
  }
16947
16996
  }
16948
16997
  async function downloadArchive(downloadUrl, archivePath) {
@@ -16970,12 +17019,12 @@ async function extractZipArchive(archivePath, destDir) {
16970
17019
  await extractZip(archivePath, destDir);
16971
17020
  }
16972
17021
  function cleanupArchive(archivePath) {
16973
- if (existsSync7(archivePath)) {
17022
+ if (existsSync8(archivePath)) {
16974
17023
  unlinkSync(archivePath);
16975
17024
  }
16976
17025
  }
16977
17026
  function ensureExecutable(binaryPath) {
16978
- if (process.platform !== "win32" && existsSync7(binaryPath)) {
17027
+ if (process.platform !== "win32" && existsSync8(binaryPath)) {
16979
17028
  chmodSync(binaryPath, 493);
16980
17029
  }
16981
17030
  }
@@ -17314,27 +17363,27 @@ init_logger();
17314
17363
 
17315
17364
  // src/shared/connected-providers-cache.ts
17316
17365
  init_logger();
17317
- import { existsSync as existsSync8, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
17318
- import { join as join9 } from "path";
17366
+ import { existsSync as existsSync9, readFileSync as readFileSync5, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
17367
+ import { join as join10 } from "path";
17319
17368
  var CONNECTED_PROVIDERS_CACHE_FILE = "connected-providers.json";
17320
17369
  var PROVIDER_MODELS_CACHE_FILE = "provider-models.json";
17321
17370
  function getCacheFilePath(filename) {
17322
- return join9(getOmoOpenCodeCacheDir(), filename);
17371
+ return join10(getOmoOpenCodeCacheDir(), filename);
17323
17372
  }
17324
17373
  function ensureCacheDir2() {
17325
17374
  const cacheDir = getOmoOpenCodeCacheDir();
17326
- if (!existsSync8(cacheDir)) {
17327
- mkdirSync2(cacheDir, { recursive: true });
17375
+ if (!existsSync9(cacheDir)) {
17376
+ mkdirSync3(cacheDir, { recursive: true });
17328
17377
  }
17329
17378
  }
17330
17379
  function readConnectedProvidersCache() {
17331
17380
  const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
17332
- if (!existsSync8(cacheFile)) {
17381
+ if (!existsSync9(cacheFile)) {
17333
17382
  log("[connected-providers-cache] Cache file not found", { cacheFile });
17334
17383
  return null;
17335
17384
  }
17336
17385
  try {
17337
- const content = readFileSync4(cacheFile, "utf-8");
17386
+ const content = readFileSync5(cacheFile, "utf-8");
17338
17387
  const data = JSON.parse(content);
17339
17388
  log("[connected-providers-cache] Read cache", { count: data.connected.length, updatedAt: data.updatedAt });
17340
17389
  return data.connected;
@@ -17345,7 +17394,7 @@ function readConnectedProvidersCache() {
17345
17394
  }
17346
17395
  function hasConnectedProvidersCache() {
17347
17396
  const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
17348
- return existsSync8(cacheFile);
17397
+ return existsSync9(cacheFile);
17349
17398
  }
17350
17399
  function writeConnectedProvidersCache(connected) {
17351
17400
  ensureCacheDir2();
@@ -17355,7 +17404,7 @@ function writeConnectedProvidersCache(connected) {
17355
17404
  updatedAt: new Date().toISOString()
17356
17405
  };
17357
17406
  try {
17358
- writeFileSync2(cacheFile, JSON.stringify(data, null, 2));
17407
+ writeFileSync3(cacheFile, JSON.stringify(data, null, 2));
17359
17408
  log("[connected-providers-cache] Cache written", { count: connected.length });
17360
17409
  } catch (err) {
17361
17410
  log("[connected-providers-cache] Error writing cache", { error: String(err) });
@@ -17363,12 +17412,12 @@ function writeConnectedProvidersCache(connected) {
17363
17412
  }
17364
17413
  function readProviderModelsCache() {
17365
17414
  const cacheFile = getCacheFilePath(PROVIDER_MODELS_CACHE_FILE);
17366
- if (!existsSync8(cacheFile)) {
17415
+ if (!existsSync9(cacheFile)) {
17367
17416
  log("[connected-providers-cache] Provider-models cache file not found", { cacheFile });
17368
17417
  return null;
17369
17418
  }
17370
17419
  try {
17371
- const content = readFileSync4(cacheFile, "utf-8");
17420
+ const content = readFileSync5(cacheFile, "utf-8");
17372
17421
  const data = JSON.parse(content);
17373
17422
  log("[connected-providers-cache] Read provider-models cache", {
17374
17423
  providerCount: Object.keys(data.models).length,
@@ -17382,7 +17431,7 @@ function readProviderModelsCache() {
17382
17431
  }
17383
17432
  function hasProviderModelsCache() {
17384
17433
  const cacheFile = getCacheFilePath(PROVIDER_MODELS_CACHE_FILE);
17385
- return existsSync8(cacheFile);
17434
+ return existsSync9(cacheFile);
17386
17435
  }
17387
17436
  function writeProviderModelsCache(data) {
17388
17437
  ensureCacheDir2();
@@ -17392,7 +17441,7 @@ function writeProviderModelsCache(data) {
17392
17441
  updatedAt: new Date().toISOString()
17393
17442
  };
17394
17443
  try {
17395
- writeFileSync2(cacheFile, JSON.stringify(cacheData, null, 2));
17444
+ writeFileSync3(cacheFile, JSON.stringify(cacheData, null, 2));
17396
17445
  log("[connected-providers-cache] Provider-models cache written", {
17397
17446
  providerCount: Object.keys(data.models).length
17398
17447
  });
@@ -17435,8 +17484,8 @@ async function updateConnectedProvidersCache(client) {
17435
17484
 
17436
17485
  // src/shared/model-availability.ts
17437
17486
  init_logger();
17438
- import { existsSync as existsSync9, readFileSync as readFileSync5 } from "fs";
17439
- import { join as join10 } from "path";
17487
+ import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
17488
+ import { join as join11 } from "path";
17440
17489
  function normalizeModelName(name) {
17441
17490
  return name.toLowerCase().replace(/claude-(opus|sonnet|haiku)-(\d+)[.-](\d+)/g, "claude-$1-$2.$3");
17442
17491
  }
@@ -17572,12 +17621,12 @@ async function fetchAvailableModels(client, options) {
17572
17621
  }
17573
17622
  }
17574
17623
  log("[fetchAvailableModels] provider-models cache not found, falling back to models.json");
17575
- const cacheFile = join10(getOpenCodeCacheDir(), "models.json");
17576
- if (!existsSync9(cacheFile)) {
17624
+ const cacheFile = join11(getOpenCodeCacheDir(), "models.json");
17625
+ if (!existsSync10(cacheFile)) {
17577
17626
  log("[fetchAvailableModels] models.json cache file not found, falling back to client");
17578
17627
  } else {
17579
17628
  try {
17580
- const content = readFileSync5(cacheFile, "utf-8");
17629
+ const content = readFileSync6(cacheFile, "utf-8");
17581
17630
  const data = JSON.parse(content);
17582
17631
  const providerIds = Object.keys(data);
17583
17632
  log("[fetchAvailableModels] providers found in models.json", { count: providerIds.length, providers: providerIds.slice(0, 10) });
@@ -17629,8 +17678,8 @@ function isModelCacheAvailable() {
17629
17678
  if (hasProviderModelsCache()) {
17630
17679
  return true;
17631
17680
  }
17632
- const cacheFile = join10(getOpenCodeCacheDir(), "models.json");
17633
- return existsSync9(cacheFile);
17681
+ const cacheFile = join11(getOpenCodeCacheDir(), "models.json");
17682
+ return existsSync10(cacheFile);
17634
17683
  }
17635
17684
 
17636
17685
  // src/shared/model-resolution-pipeline.ts
@@ -17906,8 +17955,8 @@ function isAnyProviderConnected(providers, availableModels) {
17906
17955
  return false;
17907
17956
  }
17908
17957
  // src/features/hook-message-injector/injector.ts
17909
- import { existsSync as existsSync10, mkdirSync as mkdirSync3, readFileSync as readFileSync6, readdirSync, writeFileSync as writeFileSync3 } from "fs";
17910
- import { join as join11 } from "path";
17958
+ import { existsSync as existsSync11, mkdirSync as mkdirSync4, readFileSync as readFileSync7, readdirSync, writeFileSync as writeFileSync4 } from "fs";
17959
+ import { join as join12 } from "path";
17911
17960
  init_logger();
17912
17961
  function convertSDKMessageToStoredMessage(msg) {
17913
17962
  const info = msg.info;
@@ -17975,7 +18024,7 @@ function findNearestMessageWithFields(messageDir) {
17975
18024
  const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort().reverse();
17976
18025
  for (const file of files) {
17977
18026
  try {
17978
- const content = readFileSync6(join11(messageDir, file), "utf-8");
18027
+ const content = readFileSync7(join12(messageDir, file), "utf-8");
17979
18028
  const msg = JSON.parse(content);
17980
18029
  if (msg.agent && msg.model?.providerID && msg.model?.modelID) {
17981
18030
  return msg;
@@ -17986,7 +18035,7 @@ function findNearestMessageWithFields(messageDir) {
17986
18035
  }
17987
18036
  for (const file of files) {
17988
18037
  try {
17989
- const content = readFileSync6(join11(messageDir, file), "utf-8");
18038
+ const content = readFileSync7(join12(messageDir, file), "utf-8");
17990
18039
  const msg = JSON.parse(content);
17991
18040
  if (msg.agent || msg.model?.providerID && msg.model?.modelID) {
17992
18041
  return msg;
@@ -18008,7 +18057,7 @@ function findFirstMessageWithAgent(messageDir) {
18008
18057
  const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort();
18009
18058
  for (const file of files) {
18010
18059
  try {
18011
- const content = readFileSync6(join11(messageDir, file), "utf-8");
18060
+ const content = readFileSync7(join12(messageDir, file), "utf-8");
18012
18061
  const msg = JSON.parse(content);
18013
18062
  if (msg.agent) {
18014
18063
  return msg.agent;
@@ -18033,15 +18082,15 @@ async function resolveMessageContext(sessionID, client, messageDir) {
18033
18082
  return { prevMessage, firstMessageAgent };
18034
18083
  }
18035
18084
  // src/shared/opencode-message-dir.ts
18036
- import { existsSync as existsSync11, readdirSync as readdirSync2 } from "fs";
18037
- import { join as join13 } from "path";
18085
+ import { existsSync as existsSync12, readdirSync as readdirSync2 } from "fs";
18086
+ import { join as join14 } from "path";
18038
18087
 
18039
18088
  // src/shared/opencode-storage-paths.ts
18040
- import { join as join12 } from "path";
18089
+ import { join as join13 } from "path";
18041
18090
  var OPENCODE_STORAGE = getOpenCodeStorageDir();
18042
- var MESSAGE_STORAGE = join12(OPENCODE_STORAGE, "message");
18043
- var PART_STORAGE = join12(OPENCODE_STORAGE, "part");
18044
- var SESSION_STORAGE = join12(OPENCODE_STORAGE, "session");
18091
+ var MESSAGE_STORAGE = join13(OPENCODE_STORAGE, "message");
18092
+ var PART_STORAGE = join13(OPENCODE_STORAGE, "part");
18093
+ var SESSION_STORAGE = join13(OPENCODE_STORAGE, "session");
18045
18094
 
18046
18095
  // src/shared/opencode-message-dir.ts
18047
18096
  init_logger();
@@ -18052,16 +18101,16 @@ function getMessageDir(sessionID) {
18052
18101
  return null;
18053
18102
  if (isSqliteBackend())
18054
18103
  return null;
18055
- if (!existsSync11(MESSAGE_STORAGE))
18104
+ if (!existsSync12(MESSAGE_STORAGE))
18056
18105
  return null;
18057
- const directPath = join13(MESSAGE_STORAGE, sessionID);
18058
- if (existsSync11(directPath)) {
18106
+ const directPath = join14(MESSAGE_STORAGE, sessionID);
18107
+ if (existsSync12(directPath)) {
18059
18108
  return directPath;
18060
18109
  }
18061
18110
  try {
18062
18111
  for (const dir of readdirSync2(MESSAGE_STORAGE)) {
18063
- const sessionPath = join13(MESSAGE_STORAGE, dir, sessionID);
18064
- if (existsSync11(sessionPath)) {
18112
+ const sessionPath = join14(MESSAGE_STORAGE, dir, sessionID);
18113
+ if (existsSync12(sessionPath)) {
18065
18114
  return sessionPath;
18066
18115
  }
18067
18116
  }
@@ -18774,6 +18823,31 @@ async function deletePart(client, sessionID, messageID, partID) {
18774
18823
  return false;
18775
18824
  }
18776
18825
  }
18826
+ // src/shared/port-utils.ts
18827
+ var DEFAULT_SERVER_PORT = 4096;
18828
+ var MAX_PORT_ATTEMPTS = 20;
18829
+ async function isPortAvailable(port, hostname = "127.0.0.1") {
18830
+ try {
18831
+ const server = Bun.serve({
18832
+ port,
18833
+ hostname,
18834
+ fetch: () => new Response
18835
+ });
18836
+ server.stop(true);
18837
+ return true;
18838
+ } catch {
18839
+ return false;
18840
+ }
18841
+ }
18842
+ async function findAvailablePort(startPort = DEFAULT_SERVER_PORT, hostname = "127.0.0.1") {
18843
+ for (let attempt = 0;attempt < MAX_PORT_ATTEMPTS; attempt++) {
18844
+ const port = startPort + attempt;
18845
+ if (await isPortAvailable(port, hostname)) {
18846
+ return port;
18847
+ }
18848
+ }
18849
+ throw new Error(`No available port found in range ${startPort}-${startPort + MAX_PORT_ATTEMPTS - 1}`);
18850
+ }
18777
18851
  // src/shared/git-worktree/parse-status-porcelain-line.ts
18778
18852
  function toGitFileStatus(statusToken) {
18779
18853
  if (statusToken === "A" || statusToken === "??")
@@ -18832,8 +18906,8 @@ function parseGitDiffNumstat(output, statusMap) {
18832
18906
  }
18833
18907
  // src/shared/git-worktree/collect-git-diff-stats.ts
18834
18908
  import { execFileSync } from "child_process";
18835
- import { readFileSync as readFileSync7 } from "fs";
18836
- import { join as join14 } from "path";
18909
+ import { readFileSync as readFileSync8 } from "fs";
18910
+ import { join as join15 } from "path";
18837
18911
  function collectGitDiffStats(directory) {
18838
18912
  try {
18839
18913
  const diffOutput = execFileSync("git", ["diff", "--numstat", "HEAD"], {
@@ -18857,7 +18931,7 @@ function collectGitDiffStats(directory) {
18857
18931
  const untrackedNumstat = untrackedOutput ? untrackedOutput.split(`
18858
18932
  `).filter(Boolean).map((filePath) => {
18859
18933
  try {
18860
- const content = readFileSync7(join14(directory, filePath), "utf-8");
18934
+ const content = readFileSync8(join15(directory, filePath), "utf-8");
18861
18935
  const lineCount = content.split(`
18862
18936
  `).length - (content.endsWith(`
18863
18937
  `) ? 1 : 0);
@@ -19362,6 +19436,12 @@ function createTodoContinuationHandler(args) {
19362
19436
  });
19363
19437
  return;
19364
19438
  }
19439
+ if (event.type === "session.deleted") {
19440
+ const sessionInfo = props?.info;
19441
+ if (sessionInfo?.id) {
19442
+ clearContinuationMarker(ctx.directory, sessionInfo.id);
19443
+ }
19444
+ }
19365
19445
  handleNonIdleEvent({
19366
19446
  eventType: event.type,
19367
19447
  properties: props,
@@ -19999,20 +20079,20 @@ function generatePartId() {
19999
20079
  return `prt_${timestamp2}${random}`;
20000
20080
  }
20001
20081
  // src/hooks/session-recovery/storage/messages-reader.ts
20002
- import { existsSync as existsSync12, readdirSync as readdirSync3, readFileSync as readFileSync8 } from "fs";
20003
- import { join as join15 } from "path";
20082
+ import { existsSync as existsSync13, readdirSync as readdirSync3, readFileSync as readFileSync9 } from "fs";
20083
+ import { join as join16 } from "path";
20004
20084
  function readMessages(sessionID) {
20005
20085
  if (isSqliteBackend())
20006
20086
  return [];
20007
20087
  const messageDir = getMessageDir(sessionID);
20008
- if (!messageDir || !existsSync12(messageDir))
20088
+ if (!messageDir || !existsSync13(messageDir))
20009
20089
  return [];
20010
20090
  const messages = [];
20011
20091
  for (const file of readdirSync3(messageDir)) {
20012
20092
  if (!file.endsWith(".json"))
20013
20093
  continue;
20014
20094
  try {
20015
- const content = readFileSync8(join15(messageDir, file), "utf-8");
20095
+ const content = readFileSync9(join16(messageDir, file), "utf-8");
20016
20096
  messages.push(JSON.parse(content));
20017
20097
  } catch {
20018
20098
  continue;
@@ -20027,8 +20107,8 @@ function readMessages(sessionID) {
20027
20107
  });
20028
20108
  }
20029
20109
  // src/hooks/session-recovery/storage/parts-reader.ts
20030
- import { existsSync as existsSync13, readdirSync as readdirSync4, readFileSync as readFileSync9 } from "fs";
20031
- import { join as join16 } from "path";
20110
+ import { existsSync as existsSync14, readdirSync as readdirSync4, readFileSync as readFileSync10 } from "fs";
20111
+ import { join as join17 } from "path";
20032
20112
 
20033
20113
  // src/hooks/session-recovery/constants.ts
20034
20114
  var THINKING_TYPES = new Set(["thinking", "redacted_thinking", "reasoning"]);
@@ -20039,15 +20119,15 @@ var CONTENT_TYPES = new Set(["text", "tool", "tool_use", "tool_result"]);
20039
20119
  function readParts(messageID) {
20040
20120
  if (isSqliteBackend())
20041
20121
  return [];
20042
- const partDir = join16(PART_STORAGE, messageID);
20043
- if (!existsSync13(partDir))
20122
+ const partDir = join17(PART_STORAGE, messageID);
20123
+ if (!existsSync14(partDir))
20044
20124
  return [];
20045
20125
  const parts = [];
20046
20126
  for (const file of readdirSync4(partDir)) {
20047
20127
  if (!file.endsWith(".json"))
20048
20128
  continue;
20049
20129
  try {
20050
- const content = readFileSync9(join16(partDir, file), "utf-8");
20130
+ const content = readFileSync10(join17(partDir, file), "utf-8");
20051
20131
  parts.push(JSON.parse(content));
20052
20132
  } catch {
20053
20133
  continue;
@@ -20078,16 +20158,16 @@ function messageHasContent(messageID) {
20078
20158
  return parts.some(hasContent);
20079
20159
  }
20080
20160
  // src/hooks/session-recovery/storage/text-part-injector.ts
20081
- import { existsSync as existsSync14, mkdirSync as mkdirSync4, writeFileSync as writeFileSync4 } from "fs";
20082
- import { join as join17 } from "path";
20161
+ import { existsSync as existsSync15, mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "fs";
20162
+ import { join as join18 } from "path";
20083
20163
  function injectTextPart(sessionID, messageID, text) {
20084
20164
  if (isSqliteBackend()) {
20085
20165
  log("[session-recovery] Disabled on SQLite backend: injectTextPart (use async variant)");
20086
20166
  return false;
20087
20167
  }
20088
- const partDir = join17(PART_STORAGE, messageID);
20089
- if (!existsSync14(partDir)) {
20090
- mkdirSync4(partDir, { recursive: true });
20168
+ const partDir = join18(PART_STORAGE, messageID);
20169
+ if (!existsSync15(partDir)) {
20170
+ mkdirSync5(partDir, { recursive: true });
20091
20171
  }
20092
20172
  const partId = generatePartId();
20093
20173
  const part = {
@@ -20099,7 +20179,7 @@ function injectTextPart(sessionID, messageID, text) {
20099
20179
  synthetic: true
20100
20180
  };
20101
20181
  try {
20102
- writeFileSync4(join17(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
20182
+ writeFileSync5(join18(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
20103
20183
  return true;
20104
20184
  } catch {
20105
20185
  return false;
@@ -20156,30 +20236,30 @@ function findEmptyMessageByIndex(sessionID, targetIndex) {
20156
20236
  return null;
20157
20237
  }
20158
20238
  // src/hooks/session-recovery/storage/empty-text.ts
20159
- import { existsSync as existsSync15, readdirSync as readdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync5 } from "fs";
20160
- import { join as join18 } from "path";
20239
+ import { existsSync as existsSync16, readdirSync as readdirSync5, readFileSync as readFileSync11, writeFileSync as writeFileSync6 } from "fs";
20240
+ import { join as join19 } from "path";
20161
20241
  function replaceEmptyTextParts(messageID, replacementText) {
20162
20242
  if (isSqliteBackend()) {
20163
20243
  log("[session-recovery] Disabled on SQLite backend: replaceEmptyTextParts (use async variant)");
20164
20244
  return false;
20165
20245
  }
20166
- const partDir = join18(PART_STORAGE, messageID);
20167
- if (!existsSync15(partDir))
20246
+ const partDir = join19(PART_STORAGE, messageID);
20247
+ if (!existsSync16(partDir))
20168
20248
  return false;
20169
20249
  let anyReplaced = false;
20170
20250
  for (const file of readdirSync5(partDir)) {
20171
20251
  if (!file.endsWith(".json"))
20172
20252
  continue;
20173
20253
  try {
20174
- const filePath = join18(partDir, file);
20175
- const content = readFileSync10(filePath, "utf-8");
20254
+ const filePath = join19(partDir, file);
20255
+ const content = readFileSync11(filePath, "utf-8");
20176
20256
  const part = JSON.parse(content);
20177
20257
  if (part.type === "text") {
20178
20258
  const textPart = part;
20179
20259
  if (!textPart.text?.trim()) {
20180
20260
  textPart.text = replacementText;
20181
20261
  textPart.synthetic = true;
20182
- writeFileSync5(filePath, JSON.stringify(textPart, null, 2));
20262
+ writeFileSync6(filePath, JSON.stringify(textPart, null, 2));
20183
20263
  anyReplaced = true;
20184
20264
  }
20185
20265
  }
@@ -20264,8 +20344,8 @@ function findMessageByIndexNeedingThinking(sessionID, targetIndex) {
20264
20344
  return firstIsThinking ? null : targetMessage.id;
20265
20345
  }
20266
20346
  // src/hooks/session-recovery/storage/thinking-prepend.ts
20267
- import { existsSync as existsSync16, mkdirSync as mkdirSync5, writeFileSync as writeFileSync6 } from "fs";
20268
- import { join as join19 } from "path";
20347
+ import { existsSync as existsSync17, mkdirSync as mkdirSync6, writeFileSync as writeFileSync7 } from "fs";
20348
+ import { join as join20 } from "path";
20269
20349
  function findLastThinkingContent(sessionID, beforeMessageID) {
20270
20350
  const messages = readMessages(sessionID);
20271
20351
  const currentIndex = messages.findIndex((message) => message.id === beforeMessageID);
@@ -20294,9 +20374,9 @@ function prependThinkingPart(sessionID, messageID) {
20294
20374
  log("[session-recovery] Disabled on SQLite backend: prependThinkingPart (use async variant)");
20295
20375
  return false;
20296
20376
  }
20297
- const partDir = join19(PART_STORAGE, messageID);
20298
- if (!existsSync16(partDir)) {
20299
- mkdirSync5(partDir, { recursive: true });
20377
+ const partDir = join20(PART_STORAGE, messageID);
20378
+ if (!existsSync17(partDir)) {
20379
+ mkdirSync6(partDir, { recursive: true });
20300
20380
  }
20301
20381
  const previousThinking = findLastThinkingContent(sessionID, messageID);
20302
20382
  const partId = `prt_0000000000_${messageID}_thinking`;
@@ -20309,7 +20389,7 @@ function prependThinkingPart(sessionID, messageID) {
20309
20389
  synthetic: true
20310
20390
  };
20311
20391
  try {
20312
- writeFileSync6(join19(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
20392
+ writeFileSync7(join20(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
20313
20393
  return true;
20314
20394
  } catch {
20315
20395
  return false;
@@ -20360,23 +20440,23 @@ async function prependThinkingPartAsync(client, sessionID, messageID) {
20360
20440
  }
20361
20441
  }
20362
20442
  // src/hooks/session-recovery/storage/thinking-strip.ts
20363
- import { existsSync as existsSync17, readdirSync as readdirSync6, readFileSync as readFileSync11, unlinkSync as unlinkSync2 } from "fs";
20364
- import { join as join20 } from "path";
20443
+ import { existsSync as existsSync18, readdirSync as readdirSync6, readFileSync as readFileSync12, unlinkSync as unlinkSync2 } from "fs";
20444
+ import { join as join21 } from "path";
20365
20445
  function stripThinkingParts(messageID) {
20366
20446
  if (isSqliteBackend()) {
20367
20447
  log("[session-recovery] Disabled on SQLite backend: stripThinkingParts (use async variant)");
20368
20448
  return false;
20369
20449
  }
20370
- const partDir = join20(PART_STORAGE, messageID);
20371
- if (!existsSync17(partDir))
20450
+ const partDir = join21(PART_STORAGE, messageID);
20451
+ if (!existsSync18(partDir))
20372
20452
  return false;
20373
20453
  let anyRemoved = false;
20374
20454
  for (const file of readdirSync6(partDir)) {
20375
20455
  if (!file.endsWith(".json"))
20376
20456
  continue;
20377
20457
  try {
20378
- const filePath = join20(partDir, file);
20379
- const content = readFileSync11(filePath, "utf-8");
20458
+ const filePath = join21(partDir, file);
20459
+ const content = readFileSync12(filePath, "utf-8");
20380
20460
  const part = JSON.parse(content);
20381
20461
  if (THINKING_TYPES.has(part.type)) {
20382
20462
  unlinkSync2(filePath);
@@ -30833,10 +30913,10 @@ function _property(property, schema2, params) {
30833
30913
  ...normalizeParams(params)
30834
30914
  });
30835
30915
  }
30836
- function _mime(types3, params) {
30916
+ function _mime(types4, params) {
30837
30917
  return new $ZodCheckMimeType({
30838
30918
  check: "mime_type",
30839
- mime: types3,
30919
+ mime: types4,
30840
30920
  ...normalizeParams(params)
30841
30921
  });
30842
30922
  }
@@ -32746,7 +32826,7 @@ var ZodFile = /* @__PURE__ */ $constructor("ZodFile", (inst, def) => {
32746
32826
  ZodType.init(inst, def);
32747
32827
  inst.min = (size, params) => inst.check(_minSize(size, params));
32748
32828
  inst.max = (size, params) => inst.check(_maxSize(size, params));
32749
- inst.mime = (types3, params) => inst.check(_mime(Array.isArray(types3) ? types3 : [types3], params));
32829
+ inst.mime = (types4, params) => inst.check(_mime(Array.isArray(types4) ? types4 : [types4], params));
32750
32830
  });
32751
32831
  function file(params) {
32752
32832
  return _file(ZodFile, params);
@@ -33068,24 +33148,24 @@ config(en_default());
33068
33148
  var zod_default = exports_external;
33069
33149
 
33070
33150
  // src/hooks/comment-checker/cli-runner.ts
33071
- import { existsSync as existsSync20 } from "fs";
33151
+ import { existsSync as existsSync21 } from "fs";
33072
33152
 
33073
33153
  // src/hooks/comment-checker/cli.ts
33074
33154
  var {spawn: spawn9 } = globalThis.Bun;
33075
33155
  import { createRequire as createRequire2 } from "module";
33076
- import { dirname, join as join22 } from "path";
33077
- import { existsSync as existsSync19 } from "fs";
33156
+ import { dirname, join as join23 } from "path";
33157
+ import { existsSync as existsSync20 } from "fs";
33078
33158
  import * as fs5 from "fs";
33079
33159
  import { tmpdir as tmpdir3 } from "os";
33080
33160
 
33081
33161
  // src/hooks/comment-checker/downloader.ts
33082
- import { existsSync as existsSync18, appendFileSync as appendFileSync2 } from "fs";
33083
- import { join as join21 } from "path";
33162
+ import { existsSync as existsSync19, appendFileSync as appendFileSync2 } from "fs";
33163
+ import { join as join22 } from "path";
33084
33164
  import { homedir as homedir6, tmpdir as tmpdir2 } from "os";
33085
33165
  import { createRequire } from "module";
33086
33166
  init_logger();
33087
33167
  var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
33088
- var DEBUG_FILE = join21(tmpdir2(), "comment-checker-debug.log");
33168
+ var DEBUG_FILE = join22(tmpdir2(), "comment-checker-debug.log");
33089
33169
  function debugLog(...args) {
33090
33170
  if (DEBUG) {
33091
33171
  const msg = `[${new Date().toISOString()}] [comment-checker:downloader] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
@@ -33104,12 +33184,12 @@ var PLATFORM_MAP = {
33104
33184
  function getCacheDir2() {
33105
33185
  if (process.platform === "win32") {
33106
33186
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
33107
- const base2 = localAppData || join21(homedir6(), "AppData", "Local");
33108
- return join21(base2, "oh-my-opencode", "bin");
33187
+ const base2 = localAppData || join22(homedir6(), "AppData", "Local");
33188
+ return join22(base2, "oh-my-opencode", "bin");
33109
33189
  }
33110
33190
  const xdgCache = process.env.XDG_CACHE_HOME;
33111
- const base = xdgCache || join21(homedir6(), ".cache");
33112
- return join21(base, "oh-my-opencode", "bin");
33191
+ const base = xdgCache || join22(homedir6(), ".cache");
33192
+ return join22(base, "oh-my-opencode", "bin");
33113
33193
  }
33114
33194
  function getBinaryName() {
33115
33195
  return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
@@ -33135,8 +33215,8 @@ async function downloadCommentChecker() {
33135
33215
  }
33136
33216
  const cacheDir = getCacheDir2();
33137
33217
  const binaryName = getBinaryName();
33138
- const binaryPath = join21(cacheDir, binaryName);
33139
- if (existsSync18(binaryPath)) {
33218
+ const binaryPath = join22(cacheDir, binaryName);
33219
+ if (existsSync19(binaryPath)) {
33140
33220
  debugLog("Binary already cached at:", binaryPath);
33141
33221
  return binaryPath;
33142
33222
  }
@@ -33148,7 +33228,7 @@ async function downloadCommentChecker() {
33148
33228
  log(`[oh-my-opencode] Downloading comment-checker binary...`);
33149
33229
  try {
33150
33230
  ensureCacheDir(cacheDir);
33151
- const archivePath = join21(cacheDir, assetName);
33231
+ const archivePath = join22(cacheDir, assetName);
33152
33232
  await downloadArchive(downloadUrl, archivePath);
33153
33233
  debugLog(`Downloaded archive to: ${archivePath}`);
33154
33234
  if (ext === "tar.gz") {
@@ -33180,7 +33260,7 @@ async function ensureCommentCheckerBinary() {
33180
33260
 
33181
33261
  // src/hooks/comment-checker/cli.ts
33182
33262
  var DEBUG2 = process.env.COMMENT_CHECKER_DEBUG === "1";
33183
- var DEBUG_FILE2 = join22(tmpdir3(), "comment-checker-debug.log");
33263
+ var DEBUG_FILE2 = join23(tmpdir3(), "comment-checker-debug.log");
33184
33264
  function debugLog2(...args) {
33185
33265
  if (DEBUG2) {
33186
33266
  const msg = `[${new Date().toISOString()}] [comment-checker:cli] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
@@ -33206,8 +33286,8 @@ function findCommentCheckerPathSync() {
33206
33286
  const require2 = createRequire2(import.meta.url);
33207
33287
  const cliPkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
33208
33288
  const cliDir = dirname(cliPkgPath);
33209
- const binaryPath = join22(cliDir, "bin", binaryName);
33210
- if (existsSync19(binaryPath)) {
33289
+ const binaryPath = join23(cliDir, "bin", binaryName);
33290
+ if (existsSync20(binaryPath)) {
33211
33291
  debugLog2("found binary in main package:", binaryPath);
33212
33292
  return binaryPath;
33213
33293
  }
@@ -33228,7 +33308,7 @@ async function getCommentCheckerPath() {
33228
33308
  }
33229
33309
  initPromise2 = (async () => {
33230
33310
  const syncPath = findCommentCheckerPathSync();
33231
- if (syncPath && existsSync19(syncPath)) {
33311
+ if (syncPath && existsSync20(syncPath)) {
33232
33312
  resolvedCliPath = syncPath;
33233
33313
  debugLog2("using sync-resolved path:", syncPath);
33234
33314
  return syncPath;
@@ -33264,7 +33344,7 @@ async function runCommentChecker(input, cliPath, customPrompt) {
33264
33344
  debugLog2("comment-checker binary not found");
33265
33345
  return { hasComments: false, message: "" };
33266
33346
  }
33267
- if (!existsSync19(binaryPath)) {
33347
+ if (!existsSync20(binaryPath)) {
33268
33348
  debugLog2("comment-checker binary does not exist:", binaryPath);
33269
33349
  return { hasComments: false, message: "" };
33270
33350
  }
@@ -33423,7 +33503,7 @@ ${result.message}`;
33423
33503
  }
33424
33504
  }
33425
33505
  function isCliPathUsable(cliPath) {
33426
- return Boolean(cliPath && existsSync20(cliPath));
33506
+ return Boolean(cliPath && existsSync21(cliPath));
33427
33507
  }
33428
33508
 
33429
33509
  // src/hooks/comment-checker/pending-calls.ts
@@ -33462,9 +33542,9 @@ function takePendingCall(callID) {
33462
33542
  // src/hooks/comment-checker/hook.ts
33463
33543
  import * as fs6 from "fs";
33464
33544
  import { tmpdir as tmpdir4 } from "os";
33465
- import { join as join23 } from "path";
33545
+ import { join as join24 } from "path";
33466
33546
  var DEBUG3 = process.env.COMMENT_CHECKER_DEBUG === "1";
33467
- var DEBUG_FILE3 = join23(tmpdir4(), "comment-checker-debug.log");
33547
+ var DEBUG_FILE3 = join24(tmpdir4(), "comment-checker-debug.log");
33468
33548
  function debugLog3(...args) {
33469
33549
  if (DEBUG3) {
33470
33550
  const msg = `[${new Date().toISOString()}] [comment-checker:hook] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
@@ -33623,16 +33703,16 @@ function createToolOutputTruncatorHook(ctx, options) {
33623
33703
  };
33624
33704
  }
33625
33705
  // src/hooks/directory-agents-injector/injector.ts
33626
- import { readFileSync as readFileSync13 } from "fs";
33706
+ import { readFileSync as readFileSync14 } from "fs";
33627
33707
  import { dirname as dirname3 } from "path";
33628
33708
 
33629
33709
  // src/hooks/directory-agents-injector/finder.ts
33630
- import { existsSync as existsSync21 } from "fs";
33631
- import { dirname as dirname2, join as join25, resolve as resolve2 } from "path";
33710
+ import { existsSync as existsSync22 } from "fs";
33711
+ import { dirname as dirname2, join as join26, resolve as resolve2 } from "path";
33632
33712
 
33633
33713
  // src/hooks/directory-agents-injector/constants.ts
33634
- import { join as join24 } from "path";
33635
- var AGENTS_INJECTOR_STORAGE = join24(OPENCODE_STORAGE, "directory-agents");
33714
+ import { join as join25 } from "path";
33715
+ var AGENTS_INJECTOR_STORAGE = join25(OPENCODE_STORAGE, "directory-agents");
33636
33716
  var AGENTS_FILENAME = "AGENTS.md";
33637
33717
 
33638
33718
  // src/hooks/directory-agents-injector/finder.ts
@@ -33649,8 +33729,8 @@ function findAgentsMdUp(input) {
33649
33729
  while (true) {
33650
33730
  const isRootDir = current === input.rootDir;
33651
33731
  if (!isRootDir) {
33652
- const agentsPath = join25(current, AGENTS_FILENAME);
33653
- if (existsSync21(agentsPath)) {
33732
+ const agentsPath = join26(current, AGENTS_FILENAME);
33733
+ if (existsSync22(agentsPath)) {
33654
33734
  found.push(agentsPath);
33655
33735
  }
33656
33736
  }
@@ -33668,21 +33748,21 @@ function findAgentsMdUp(input) {
33668
33748
 
33669
33749
  // src/shared/session-injected-paths.ts
33670
33750
  import {
33671
- existsSync as existsSync22,
33672
- mkdirSync as mkdirSync6,
33673
- readFileSync as readFileSync12,
33751
+ existsSync as existsSync23,
33752
+ mkdirSync as mkdirSync7,
33753
+ readFileSync as readFileSync13,
33674
33754
  unlinkSync as unlinkSync3,
33675
- writeFileSync as writeFileSync7
33755
+ writeFileSync as writeFileSync8
33676
33756
  } from "fs";
33677
- import { join as join26 } from "path";
33757
+ import { join as join27 } from "path";
33678
33758
  function createInjectedPathsStorage(storageDir) {
33679
- const getStoragePath = (sessionID) => join26(storageDir, `${sessionID}.json`);
33759
+ const getStoragePath = (sessionID) => join27(storageDir, `${sessionID}.json`);
33680
33760
  const loadInjectedPaths = (sessionID) => {
33681
33761
  const filePath = getStoragePath(sessionID);
33682
- if (!existsSync22(filePath))
33762
+ if (!existsSync23(filePath))
33683
33763
  return new Set;
33684
33764
  try {
33685
- const content = readFileSync12(filePath, "utf-8");
33765
+ const content = readFileSync13(filePath, "utf-8");
33686
33766
  const data = JSON.parse(content);
33687
33767
  return new Set(data.injectedPaths);
33688
33768
  } catch {
@@ -33690,19 +33770,19 @@ function createInjectedPathsStorage(storageDir) {
33690
33770
  }
33691
33771
  };
33692
33772
  const saveInjectedPaths = (sessionID, paths) => {
33693
- if (!existsSync22(storageDir)) {
33694
- mkdirSync6(storageDir, { recursive: true });
33773
+ if (!existsSync23(storageDir)) {
33774
+ mkdirSync7(storageDir, { recursive: true });
33695
33775
  }
33696
33776
  const data = {
33697
33777
  sessionID,
33698
33778
  injectedPaths: [...paths],
33699
33779
  updatedAt: Date.now()
33700
33780
  };
33701
- writeFileSync7(getStoragePath(sessionID), JSON.stringify(data, null, 2));
33781
+ writeFileSync8(getStoragePath(sessionID), JSON.stringify(data, null, 2));
33702
33782
  };
33703
33783
  const clearInjectedPaths = (sessionID) => {
33704
33784
  const filePath = getStoragePath(sessionID);
33705
- if (existsSync22(filePath)) {
33785
+ if (existsSync23(filePath)) {
33706
33786
  unlinkSync3(filePath);
33707
33787
  }
33708
33788
  };
@@ -33740,7 +33820,7 @@ async function processFilePathForAgentsInjection(input) {
33740
33820
  if (cache.has(agentsDir))
33741
33821
  continue;
33742
33822
  try {
33743
- const content = readFileSync13(agentsPath, "utf-8");
33823
+ const content = readFileSync14(agentsPath, "utf-8");
33744
33824
  const { result, truncated } = await input.truncator.truncate(input.sessionID, content);
33745
33825
  const truncationNotice = truncated ? `
33746
33826
 
@@ -33801,16 +33881,16 @@ function createDirectoryAgentsInjectorHook(ctx, modelCacheState) {
33801
33881
  };
33802
33882
  }
33803
33883
  // src/hooks/directory-readme-injector/injector.ts
33804
- import { readFileSync as readFileSync14 } from "fs";
33884
+ import { readFileSync as readFileSync15 } from "fs";
33805
33885
  import { dirname as dirname5 } from "path";
33806
33886
 
33807
33887
  // src/hooks/directory-readme-injector/finder.ts
33808
- import { existsSync as existsSync23 } from "fs";
33809
- import { dirname as dirname4, join as join28, resolve as resolve3 } from "path";
33888
+ import { existsSync as existsSync24 } from "fs";
33889
+ import { dirname as dirname4, join as join29, resolve as resolve3 } from "path";
33810
33890
 
33811
33891
  // src/hooks/directory-readme-injector/constants.ts
33812
- import { join as join27 } from "path";
33813
- var README_INJECTOR_STORAGE = join27(OPENCODE_STORAGE, "directory-readme");
33892
+ import { join as join28 } from "path";
33893
+ var README_INJECTOR_STORAGE = join28(OPENCODE_STORAGE, "directory-readme");
33814
33894
  var README_FILENAME = "README.md";
33815
33895
 
33816
33896
  // src/hooks/directory-readme-injector/finder.ts
@@ -33825,8 +33905,8 @@ function findReadmeMdUp(input) {
33825
33905
  const found = [];
33826
33906
  let current = input.startDir;
33827
33907
  while (true) {
33828
- const readmePath = join28(current, README_FILENAME);
33829
- if (existsSync23(readmePath)) {
33908
+ const readmePath = join29(current, README_FILENAME);
33909
+ if (existsSync24(readmePath)) {
33830
33910
  found.push(readmePath);
33831
33911
  }
33832
33912
  if (current === input.rootDir)
@@ -33868,7 +33948,7 @@ async function processFilePathForReadmeInjection(input) {
33868
33948
  if (cache.has(readmeDir))
33869
33949
  continue;
33870
33950
  try {
33871
- const content = readFileSync14(readmePath, "utf-8");
33951
+ const content = readFileSync15(readmePath, "utf-8");
33872
33952
  const { result, truncated } = await input.truncator.truncate(input.sessionID, content);
33873
33953
  const truncationNotice = truncated ? `
33874
33954
 
@@ -34183,14 +34263,14 @@ function incrementEmptyContentAttempt(autoCompactState, sessionID) {
34183
34263
  }
34184
34264
 
34185
34265
  // src/hooks/anthropic-context-window-limit-recovery/tool-result-storage.ts
34186
- import { existsSync as existsSync25, readdirSync as readdirSync8, readFileSync as readFileSync15, writeFileSync as writeFileSync8 } from "fs";
34187
- import { join as join29 } from "path";
34266
+ import { existsSync as existsSync26, readdirSync as readdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync9 } from "fs";
34267
+ import { join as join30 } from "path";
34188
34268
 
34189
34269
  // src/hooks/anthropic-context-window-limit-recovery/message-storage-directory.ts
34190
- import { existsSync as existsSync24, readdirSync as readdirSync7 } from "fs";
34270
+ import { existsSync as existsSync25, readdirSync as readdirSync7 } from "fs";
34191
34271
  function getMessageIds(sessionID) {
34192
34272
  const messageDir = getMessageDir(sessionID);
34193
- if (!messageDir || !existsSync24(messageDir))
34273
+ if (!messageDir || !existsSync25(messageDir))
34194
34274
  return [];
34195
34275
  const messageIds = [];
34196
34276
  for (const file2 of readdirSync7(messageDir)) {
@@ -34212,15 +34292,15 @@ function findToolResultsBySize(sessionID) {
34212
34292
  const messageIds = getMessageIds(sessionID);
34213
34293
  const results = [];
34214
34294
  for (const messageID of messageIds) {
34215
- const partDir = join29(PART_STORAGE, messageID);
34216
- if (!existsSync25(partDir))
34295
+ const partDir = join30(PART_STORAGE, messageID);
34296
+ if (!existsSync26(partDir))
34217
34297
  continue;
34218
34298
  for (const file2 of readdirSync8(partDir)) {
34219
34299
  if (!file2.endsWith(".json"))
34220
34300
  continue;
34221
34301
  try {
34222
- const partPath = join29(partDir, file2);
34223
- const content = readFileSync15(partPath, "utf-8");
34302
+ const partPath = join30(partDir, file2);
34303
+ const content = readFileSync16(partPath, "utf-8");
34224
34304
  const part = JSON.parse(content);
34225
34305
  if (part.type === "tool" && part.state?.output && !part.truncated) {
34226
34306
  results.push({
@@ -34247,7 +34327,7 @@ function truncateToolResult(partPath) {
34247
34327
  return { success: false };
34248
34328
  }
34249
34329
  try {
34250
- const content = readFileSync15(partPath, "utf-8");
34330
+ const content = readFileSync16(partPath, "utf-8");
34251
34331
  const part = JSON.parse(content);
34252
34332
  if (!part.state?.output) {
34253
34333
  return { success: false };
@@ -34261,7 +34341,7 @@ function truncateToolResult(partPath) {
34261
34341
  part.state.time = { start: Date.now() };
34262
34342
  }
34263
34343
  part.state.time.compacted = Date.now();
34264
- writeFileSync8(partPath, JSON.stringify(part, null, 2));
34344
+ writeFileSync9(partPath, JSON.stringify(part, null, 2));
34265
34345
  return { success: true, toolName, originalSize };
34266
34346
  } catch {
34267
34347
  return { success: false };
@@ -34954,8 +35034,8 @@ async function executeCompact(sessionID, msg, autoCompactState, client, director
34954
35034
  }
34955
35035
 
34956
35036
  // src/hooks/anthropic-context-window-limit-recovery/pruning-deduplication.ts
34957
- import { readdirSync as readdirSync9, readFileSync as readFileSync16 } from "fs";
34958
- import { join as join30 } from "path";
35037
+ import { readdirSync as readdirSync9, readFileSync as readFileSync17 } from "fs";
35038
+ import { join as join31 } from "path";
34959
35039
 
34960
35040
  // src/hooks/anthropic-context-window-limit-recovery/pruning-types.ts
34961
35041
  var CHARS_PER_TOKEN = 4;
@@ -34991,7 +35071,7 @@ function readMessages2(sessionID) {
34991
35071
  try {
34992
35072
  const files = readdirSync9(messageDir).filter((f) => f.endsWith(".json"));
34993
35073
  for (const file2 of files) {
34994
- const content = readFileSync16(join30(messageDir, file2), "utf-8");
35074
+ const content = readFileSync17(join31(messageDir, file2), "utf-8");
34995
35075
  const data = JSON.parse(content);
34996
35076
  if (data.parts) {
34997
35077
  messages.push(data);
@@ -35096,11 +35176,11 @@ function findToolOutput(messages, callID) {
35096
35176
  }
35097
35177
 
35098
35178
  // src/hooks/anthropic-context-window-limit-recovery/pruning-tool-output-truncation.ts
35099
- import { existsSync as existsSync26, readdirSync as readdirSync10, readFileSync as readFileSync17 } from "fs";
35100
- import { join as join31 } from "path";
35179
+ import { existsSync as existsSync27, readdirSync as readdirSync10, readFileSync as readFileSync18 } from "fs";
35180
+ import { join as join32 } from "path";
35101
35181
  init_logger();
35102
35182
  function getPartStorage() {
35103
- return join31(getOpenCodeStorageDir(), "part");
35183
+ return join32(getOpenCodeStorageDir(), "part");
35104
35184
  }
35105
35185
  function getMessageIds2(sessionID) {
35106
35186
  const messageDir = getMessageDir(sessionID);
@@ -35125,15 +35205,15 @@ async function truncateToolOutputsByCallId(sessionID, callIds, client) {
35125
35205
  return { truncatedCount: 0 };
35126
35206
  let truncatedCount = 0;
35127
35207
  for (const messageID of messageIds) {
35128
- const partDir = join31(getPartStorage(), messageID);
35129
- if (!existsSync26(partDir))
35208
+ const partDir = join32(getPartStorage(), messageID);
35209
+ if (!existsSync27(partDir))
35130
35210
  continue;
35131
35211
  for (const file2 of readdirSync10(partDir)) {
35132
35212
  if (!file2.endsWith(".json"))
35133
35213
  continue;
35134
- const partPath = join31(partDir, file2);
35214
+ const partPath = join32(partDir, file2);
35135
35215
  try {
35136
- const content = readFileSync17(partPath, "utf-8");
35216
+ const content = readFileSync18(partPath, "utf-8");
35137
35217
  const part = JSON.parse(content);
35138
35218
  if (part.type !== "tool" || !part.callID)
35139
35219
  continue;
@@ -35716,8 +35796,8 @@ function createThinkModeHook() {
35716
35796
  };
35717
35797
  }
35718
35798
  // src/hooks/claude-code-hooks/config.ts
35719
- import { join as join32 } from "path";
35720
- import { existsSync as existsSync27 } from "fs";
35799
+ import { join as join33 } from "path";
35800
+ import { existsSync as existsSync28 } from "fs";
35721
35801
  function normalizeHookMatcher(raw) {
35722
35802
  return {
35723
35803
  matcher: raw.matcher ?? raw.pattern ?? "*",
@@ -35743,11 +35823,11 @@ function normalizeHooksConfig(raw) {
35743
35823
  function getClaudeSettingsPaths(customPath) {
35744
35824
  const claudeConfigDir = getClaudeConfigDir();
35745
35825
  const paths = [
35746
- join32(claudeConfigDir, "settings.json"),
35747
- join32(process.cwd(), ".claude", "settings.json"),
35748
- join32(process.cwd(), ".claude", "settings.local.json")
35826
+ join33(claudeConfigDir, "settings.json"),
35827
+ join33(process.cwd(), ".claude", "settings.json"),
35828
+ join33(process.cwd(), ".claude", "settings.local.json")
35749
35829
  ];
35750
- if (customPath && existsSync27(customPath)) {
35830
+ if (customPath && existsSync28(customPath)) {
35751
35831
  paths.unshift(customPath);
35752
35832
  }
35753
35833
  return [...new Set(paths)];
@@ -35772,7 +35852,7 @@ async function loadClaudeHooksConfig(customSettingsPath) {
35772
35852
  const paths = getClaudeSettingsPaths(customSettingsPath);
35773
35853
  let mergedConfig = {};
35774
35854
  for (const settingsPath of paths) {
35775
- if (existsSync27(settingsPath)) {
35855
+ if (existsSync28(settingsPath)) {
35776
35856
  try {
35777
35857
  const content = await Bun.file(settingsPath).text();
35778
35858
  const settings = JSON.parse(content);
@@ -35790,14 +35870,14 @@ async function loadClaudeHooksConfig(customSettingsPath) {
35790
35870
 
35791
35871
  // src/hooks/claude-code-hooks/config-loader.ts
35792
35872
  init_logger();
35793
- import { existsSync as existsSync28 } from "fs";
35794
- import { join as join33 } from "path";
35795
- var USER_CONFIG_PATH = join33(getOpenCodeConfigDir({ binary: "opencode" }), "opencode-cc-plugin.json");
35873
+ import { existsSync as existsSync29 } from "fs";
35874
+ import { join as join34 } from "path";
35875
+ var USER_CONFIG_PATH = join34(getOpenCodeConfigDir({ binary: "opencode" }), "opencode-cc-plugin.json");
35796
35876
  function getProjectConfigPath() {
35797
- return join33(process.cwd(), ".opencode", "opencode-cc-plugin.json");
35877
+ return join34(process.cwd(), ".opencode", "opencode-cc-plugin.json");
35798
35878
  }
35799
35879
  async function loadConfigFromPath(path5) {
35800
- if (!existsSync28(path5)) {
35880
+ if (!existsSync29(path5)) {
35801
35881
  return null;
35802
35882
  }
35803
35883
  try {
@@ -35939,17 +36019,17 @@ ${USER_PROMPT_SUBMIT_TAG_CLOSE}`);
35939
36019
  }
35940
36020
 
35941
36021
  // src/hooks/claude-code-hooks/transcript.ts
35942
- import { join as join34 } from "path";
35943
- import { mkdirSync as mkdirSync7, appendFileSync as appendFileSync5, existsSync as existsSync29, writeFileSync as writeFileSync9, unlinkSync as unlinkSync4 } from "fs";
36022
+ import { join as join35 } from "path";
36023
+ import { mkdirSync as mkdirSync8, appendFileSync as appendFileSync5, existsSync as existsSync30, writeFileSync as writeFileSync10, unlinkSync as unlinkSync4 } from "fs";
35944
36024
  import { tmpdir as tmpdir5 } from "os";
35945
36025
  import { randomUUID } from "crypto";
35946
- var TRANSCRIPT_DIR = join34(getClaudeConfigDir(), "transcripts");
36026
+ var TRANSCRIPT_DIR = join35(getClaudeConfigDir(), "transcripts");
35947
36027
  function getTranscriptPath(sessionId) {
35948
- return join34(TRANSCRIPT_DIR, `${sessionId}.jsonl`);
36028
+ return join35(TRANSCRIPT_DIR, `${sessionId}.jsonl`);
35949
36029
  }
35950
36030
  function ensureTranscriptDir() {
35951
- if (!existsSync29(TRANSCRIPT_DIR)) {
35952
- mkdirSync7(TRANSCRIPT_DIR, { recursive: true });
36031
+ if (!existsSync30(TRANSCRIPT_DIR)) {
36032
+ mkdirSync8(TRANSCRIPT_DIR, { recursive: true });
35953
36033
  }
35954
36034
  }
35955
36035
  function appendTranscriptEntry(sessionId, entry) {
@@ -36031,8 +36111,8 @@ async function buildTranscriptFromSession(client, sessionId, directory, currentT
36031
36111
  });
36032
36112
  }
36033
36113
  const allEntries = [...baseEntries, buildCurrentEntry(currentToolName, currentToolInput)];
36034
- const tempPath = join34(tmpdir5(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
36035
- writeFileSync9(tempPath, allEntries.join(`
36114
+ const tempPath = join35(tmpdir5(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
36115
+ writeFileSync10(tempPath, allEntries.join(`
36036
36116
  `) + `
36037
36117
  `);
36038
36118
  const cacheEntry = transcriptCache.get(sessionId);
@@ -36042,8 +36122,8 @@ async function buildTranscriptFromSession(client, sessionId, directory, currentT
36042
36122
  return tempPath;
36043
36123
  } catch {
36044
36124
  try {
36045
- const tempPath = join34(tmpdir5(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
36046
- writeFileSync9(tempPath, buildCurrentEntry(currentToolName, currentToolInput) + `
36125
+ const tempPath = join35(tmpdir5(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
36126
+ writeFileSync10(tempPath, buildCurrentEntry(currentToolName, currentToolInput) + `
36047
36127
  `);
36048
36128
  return tempPath;
36049
36129
  } catch {
@@ -36260,10 +36340,10 @@ function createPreCompactHandler(ctx, config2) {
36260
36340
  }
36261
36341
 
36262
36342
  // src/hooks/claude-code-hooks/todo.ts
36263
- import { join as join35 } from "path";
36264
- var TODO_DIR = join35(getClaudeConfigDir(), "todos");
36343
+ import { join as join36 } from "path";
36344
+ var TODO_DIR = join36(getClaudeConfigDir(), "todos");
36265
36345
  function getTodoPath(sessionId) {
36266
- return join35(TODO_DIR, `${sessionId}-agent-${sessionId}.json`);
36346
+ return join36(TODO_DIR, `${sessionId}-agent-${sessionId}.json`);
36267
36347
  }
36268
36348
 
36269
36349
  // src/hooks/claude-code-hooks/stop.ts
@@ -36838,17 +36918,17 @@ function getRuleInjectionFilePath(output) {
36838
36918
 
36839
36919
  // src/hooks/rules-injector/storage.ts
36840
36920
  import {
36841
- existsSync as existsSync30,
36842
- mkdirSync as mkdirSync8,
36843
- readFileSync as readFileSync18,
36844
- writeFileSync as writeFileSync10,
36921
+ existsSync as existsSync31,
36922
+ mkdirSync as mkdirSync9,
36923
+ readFileSync as readFileSync19,
36924
+ writeFileSync as writeFileSync11,
36845
36925
  unlinkSync as unlinkSync5
36846
36926
  } from "fs";
36847
- import { join as join37 } from "path";
36927
+ import { join as join38 } from "path";
36848
36928
 
36849
36929
  // src/hooks/rules-injector/constants.ts
36850
- import { join as join36 } from "path";
36851
- var RULES_INJECTOR_STORAGE = join36(OPENCODE_STORAGE, "rules-injector");
36930
+ import { join as join37 } from "path";
36931
+ var RULES_INJECTOR_STORAGE = join37(OPENCODE_STORAGE, "rules-injector");
36852
36932
  var PROJECT_MARKERS = [
36853
36933
  ".git",
36854
36934
  "pyproject.toml",
@@ -36872,14 +36952,14 @@ var RULE_EXTENSIONS = [".md", ".mdc"];
36872
36952
 
36873
36953
  // src/hooks/rules-injector/storage.ts
36874
36954
  function getStoragePath(sessionID) {
36875
- return join37(RULES_INJECTOR_STORAGE, `${sessionID}.json`);
36955
+ return join38(RULES_INJECTOR_STORAGE, `${sessionID}.json`);
36876
36956
  }
36877
36957
  function loadInjectedRules(sessionID) {
36878
36958
  const filePath = getStoragePath(sessionID);
36879
- if (!existsSync30(filePath))
36959
+ if (!existsSync31(filePath))
36880
36960
  return { contentHashes: new Set, realPaths: new Set };
36881
36961
  try {
36882
- const content = readFileSync18(filePath, "utf-8");
36962
+ const content = readFileSync19(filePath, "utf-8");
36883
36963
  const data = JSON.parse(content);
36884
36964
  return {
36885
36965
  contentHashes: new Set(data.injectedHashes),
@@ -36890,8 +36970,8 @@ function loadInjectedRules(sessionID) {
36890
36970
  }
36891
36971
  }
36892
36972
  function saveInjectedRules(sessionID, data) {
36893
- if (!existsSync30(RULES_INJECTOR_STORAGE)) {
36894
- mkdirSync8(RULES_INJECTOR_STORAGE, { recursive: true });
36973
+ if (!existsSync31(RULES_INJECTOR_STORAGE)) {
36974
+ mkdirSync9(RULES_INJECTOR_STORAGE, { recursive: true });
36895
36975
  }
36896
36976
  const storageData = {
36897
36977
  sessionID,
@@ -36899,11 +36979,11 @@ function saveInjectedRules(sessionID, data) {
36899
36979
  injectedRealPaths: [...data.realPaths],
36900
36980
  updatedAt: Date.now()
36901
36981
  };
36902
- writeFileSync10(getStoragePath(sessionID), JSON.stringify(storageData, null, 2));
36982
+ writeFileSync11(getStoragePath(sessionID), JSON.stringify(storageData, null, 2));
36903
36983
  }
36904
36984
  function clearInjectedRules(sessionID) {
36905
36985
  const filePath = getStoragePath(sessionID);
36906
- if (existsSync30(filePath)) {
36986
+ if (existsSync31(filePath)) {
36907
36987
  unlinkSync5(filePath);
36908
36988
  }
36909
36989
  }
@@ -36925,13 +37005,13 @@ function createSessionCacheStore() {
36925
37005
  }
36926
37006
 
36927
37007
  // src/hooks/rules-injector/injector.ts
36928
- import { readFileSync as readFileSync19, statSync as statSync4 } from "fs";
37008
+ import { readFileSync as readFileSync20, statSync as statSync4 } from "fs";
36929
37009
  import { homedir as homedir7 } from "os";
36930
37010
  import { relative as relative2, resolve as resolve4 } from "path";
36931
37011
 
36932
37012
  // src/hooks/rules-injector/project-root-finder.ts
36933
- import { existsSync as existsSync31, statSync as statSync2 } from "fs";
36934
- import { dirname as dirname6, join as join38 } from "path";
37013
+ import { existsSync as existsSync32, statSync as statSync2 } from "fs";
37014
+ import { dirname as dirname6, join as join39 } from "path";
36935
37015
  function findProjectRoot(startPath) {
36936
37016
  let current;
36937
37017
  try {
@@ -36942,8 +37022,8 @@ function findProjectRoot(startPath) {
36942
37022
  }
36943
37023
  while (true) {
36944
37024
  for (const marker of PROJECT_MARKERS) {
36945
- const markerPath = join38(current, marker);
36946
- if (existsSync31(markerPath)) {
37025
+ const markerPath = join39(current, marker);
37026
+ if (existsSync32(markerPath)) {
36947
37027
  return current;
36948
37028
  }
36949
37029
  }
@@ -36955,12 +37035,12 @@ function findProjectRoot(startPath) {
36955
37035
  }
36956
37036
  }
36957
37037
  // src/hooks/rules-injector/rule-file-finder.ts
36958
- import { existsSync as existsSync33, statSync as statSync3 } from "fs";
36959
- import { dirname as dirname7, join as join40 } from "path";
37038
+ import { existsSync as existsSync34, statSync as statSync3 } from "fs";
37039
+ import { dirname as dirname7, join as join41 } from "path";
36960
37040
 
36961
37041
  // src/hooks/rules-injector/rule-file-scanner.ts
36962
- import { existsSync as existsSync32, readdirSync as readdirSync11, realpathSync as realpathSync2 } from "fs";
36963
- import { join as join39 } from "path";
37042
+ import { existsSync as existsSync33, readdirSync as readdirSync11, realpathSync as realpathSync2 } from "fs";
37043
+ import { join as join40 } from "path";
36964
37044
  function isGitHubInstructionsDir(dir) {
36965
37045
  return dir.includes(".github/instructions") || dir.endsWith(".github/instructions");
36966
37046
  }
@@ -36971,12 +37051,12 @@ function isValidRuleFile(fileName, dir) {
36971
37051
  return RULE_EXTENSIONS.some((ext) => fileName.endsWith(ext));
36972
37052
  }
36973
37053
  function findRuleFilesRecursive(dir, results) {
36974
- if (!existsSync32(dir))
37054
+ if (!existsSync33(dir))
36975
37055
  return;
36976
37056
  try {
36977
37057
  const entries = readdirSync11(dir, { withFileTypes: true });
36978
37058
  for (const entry of entries) {
36979
- const fullPath = join39(dir, entry.name);
37059
+ const fullPath = join40(dir, entry.name);
36980
37060
  if (entry.isDirectory()) {
36981
37061
  findRuleFilesRecursive(fullPath, results);
36982
37062
  } else if (entry.isFile()) {
@@ -37003,7 +37083,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
37003
37083
  let distance = 0;
37004
37084
  while (true) {
37005
37085
  for (const [parent, subdir] of PROJECT_RULE_SUBDIRS) {
37006
- const ruleDir = join40(currentDir, parent, subdir);
37086
+ const ruleDir = join41(currentDir, parent, subdir);
37007
37087
  const files = [];
37008
37088
  findRuleFilesRecursive(ruleDir, files);
37009
37089
  for (const filePath of files) {
@@ -37029,8 +37109,8 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
37029
37109
  }
37030
37110
  if (projectRoot) {
37031
37111
  for (const ruleFile of PROJECT_RULE_FILES) {
37032
- const filePath = join40(projectRoot, ruleFile);
37033
- if (existsSync33(filePath)) {
37112
+ const filePath = join41(projectRoot, ruleFile);
37113
+ if (existsSync34(filePath)) {
37034
37114
  try {
37035
37115
  const stat = statSync3(filePath);
37036
37116
  if (stat.isFile()) {
@@ -37050,7 +37130,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
37050
37130
  }
37051
37131
  }
37052
37132
  }
37053
- const userRuleDir = join40(homeDir, USER_RULE_DIR);
37133
+ const userRuleDir = join41(homeDir, USER_RULE_DIR);
37054
37134
  const userFiles = [];
37055
37135
  findRuleFilesRecursive(userRuleDir, userFiles);
37056
37136
  for (const filePath of userFiles) {
@@ -37245,7 +37325,7 @@ function getCachedParsedRule(filePath, realPath) {
37245
37325
  if (cached2 && cached2.mtimeMs === stat.mtimeMs && cached2.size === stat.size) {
37246
37326
  return { metadata: cached2.metadata, body: cached2.body };
37247
37327
  }
37248
- const rawContent = readFileSync19(filePath, "utf-8");
37328
+ const rawContent = readFileSync20(filePath, "utf-8");
37249
37329
  const { metadata, body } = parseRuleFrontmatter(rawContent);
37250
37330
  parsedRuleCache.set(realPath, {
37251
37331
  mtimeMs: stat.mtimeMs,
@@ -37255,7 +37335,7 @@ function getCachedParsedRule(filePath, realPath) {
37255
37335
  });
37256
37336
  return { metadata, body };
37257
37337
  } catch {
37258
- const rawContent = readFileSync19(filePath, "utf-8");
37338
+ const rawContent = readFileSync20(filePath, "utf-8");
37259
37339
  return parseRuleFrontmatter(rawContent);
37260
37340
  }
37261
37341
  }
@@ -38031,17 +38111,17 @@ v${latestVersion} available. Restart OpenCode to apply.` : "OpenCode is now on S
38031
38111
  }
38032
38112
  // src/hooks/agent-usage-reminder/storage.ts
38033
38113
  import {
38034
- existsSync as existsSync39,
38035
- mkdirSync as mkdirSync9,
38036
- readFileSync as readFileSync27,
38037
- writeFileSync as writeFileSync13,
38114
+ existsSync as existsSync40,
38115
+ mkdirSync as mkdirSync10,
38116
+ readFileSync as readFileSync28,
38117
+ writeFileSync as writeFileSync14,
38038
38118
  unlinkSync as unlinkSync6
38039
38119
  } from "fs";
38040
- import { join as join46 } from "path";
38120
+ import { join as join47 } from "path";
38041
38121
 
38042
38122
  // src/hooks/agent-usage-reminder/constants.ts
38043
- import { join as join45 } from "path";
38044
- var AGENT_USAGE_REMINDER_STORAGE = join45(OPENCODE_STORAGE, "agent-usage-reminder");
38123
+ import { join as join46 } from "path";
38124
+ var AGENT_USAGE_REMINDER_STORAGE = join46(OPENCODE_STORAGE, "agent-usage-reminder");
38045
38125
  var TARGET_TOOLS = new Set([
38046
38126
  "grep",
38047
38127
  "safe_grep",
@@ -38087,29 +38167,29 @@ ALWAYS prefer: Multiple parallel task calls > Direct tool calls
38087
38167
 
38088
38168
  // src/hooks/agent-usage-reminder/storage.ts
38089
38169
  function getStoragePath2(sessionID) {
38090
- return join46(AGENT_USAGE_REMINDER_STORAGE, `${sessionID}.json`);
38170
+ return join47(AGENT_USAGE_REMINDER_STORAGE, `${sessionID}.json`);
38091
38171
  }
38092
38172
  function loadAgentUsageState(sessionID) {
38093
38173
  const filePath = getStoragePath2(sessionID);
38094
- if (!existsSync39(filePath))
38174
+ if (!existsSync40(filePath))
38095
38175
  return null;
38096
38176
  try {
38097
- const content = readFileSync27(filePath, "utf-8");
38177
+ const content = readFileSync28(filePath, "utf-8");
38098
38178
  return JSON.parse(content);
38099
38179
  } catch {
38100
38180
  return null;
38101
38181
  }
38102
38182
  }
38103
38183
  function saveAgentUsageState(state3) {
38104
- if (!existsSync39(AGENT_USAGE_REMINDER_STORAGE)) {
38105
- mkdirSync9(AGENT_USAGE_REMINDER_STORAGE, { recursive: true });
38184
+ if (!existsSync40(AGENT_USAGE_REMINDER_STORAGE)) {
38185
+ mkdirSync10(AGENT_USAGE_REMINDER_STORAGE, { recursive: true });
38106
38186
  }
38107
38187
  const filePath = getStoragePath2(state3.sessionID);
38108
- writeFileSync13(filePath, JSON.stringify(state3, null, 2));
38188
+ writeFileSync14(filePath, JSON.stringify(state3, null, 2));
38109
38189
  }
38110
38190
  function clearAgentUsageState(sessionID) {
38111
38191
  const filePath = getStoragePath2(sessionID);
38112
- if (existsSync39(filePath)) {
38192
+ if (existsSync40(filePath)) {
38113
38193
  unlinkSync6(filePath);
38114
38194
  }
38115
38195
  }
@@ -38814,10 +38894,10 @@ function resolveMessage(message, agentName, modelID) {
38814
38894
  }
38815
38895
  function detectKeywordsWithType(text, agentName, modelID) {
38816
38896
  const textWithoutCode = removeCodeBlocks2(text);
38817
- const types4 = ["ultrawork", "search", "analyze"];
38897
+ const types5 = ["ultrawork", "search", "analyze"];
38818
38898
  return KEYWORD_DETECTORS.map(({ pattern, message }, index) => ({
38819
38899
  matches: pattern.test(textWithoutCode),
38820
- type: types4[index],
38900
+ type: types5[index],
38821
38901
  message: resolveMessage(message, agentName, modelID)
38822
38902
  })).filter((result) => result.matches).map(({ type: type2, message }) => ({ type: type2, message }));
38823
38903
  }
@@ -38999,17 +39079,17 @@ function createNonInteractiveEnvHook(_ctx) {
38999
39079
  }
39000
39080
  // src/hooks/interactive-bash-session/storage.ts
39001
39081
  import {
39002
- existsSync as existsSync40,
39003
- mkdirSync as mkdirSync10,
39004
- readFileSync as readFileSync28,
39005
- writeFileSync as writeFileSync14,
39082
+ existsSync as existsSync41,
39083
+ mkdirSync as mkdirSync11,
39084
+ readFileSync as readFileSync29,
39085
+ writeFileSync as writeFileSync15,
39006
39086
  unlinkSync as unlinkSync7
39007
39087
  } from "fs";
39008
- import { join as join48 } from "path";
39088
+ import { join as join49 } from "path";
39009
39089
 
39010
39090
  // src/hooks/interactive-bash-session/constants.ts
39011
- import { join as join47 } from "path";
39012
- var INTERACTIVE_BASH_SESSION_STORAGE = join47(OPENCODE_STORAGE, "interactive-bash-session");
39091
+ import { join as join48 } from "path";
39092
+ var INTERACTIVE_BASH_SESSION_STORAGE = join48(OPENCODE_STORAGE, "interactive-bash-session");
39013
39093
  var OMO_SESSION_PREFIX = "omo-";
39014
39094
  function buildSessionReminderMessage(sessions) {
39015
39095
  if (sessions.length === 0)
@@ -39021,14 +39101,14 @@ function buildSessionReminderMessage(sessions) {
39021
39101
 
39022
39102
  // src/hooks/interactive-bash-session/storage.ts
39023
39103
  function getStoragePath3(sessionID) {
39024
- return join48(INTERACTIVE_BASH_SESSION_STORAGE, `${sessionID}.json`);
39104
+ return join49(INTERACTIVE_BASH_SESSION_STORAGE, `${sessionID}.json`);
39025
39105
  }
39026
39106
  function loadInteractiveBashSessionState(sessionID) {
39027
39107
  const filePath = getStoragePath3(sessionID);
39028
- if (!existsSync40(filePath))
39108
+ if (!existsSync41(filePath))
39029
39109
  return null;
39030
39110
  try {
39031
- const content = readFileSync28(filePath, "utf-8");
39111
+ const content = readFileSync29(filePath, "utf-8");
39032
39112
  const serialized = JSON.parse(content);
39033
39113
  return {
39034
39114
  sessionID: serialized.sessionID,
@@ -39040,8 +39120,8 @@ function loadInteractiveBashSessionState(sessionID) {
39040
39120
  }
39041
39121
  }
39042
39122
  function saveInteractiveBashSessionState(state3) {
39043
- if (!existsSync40(INTERACTIVE_BASH_SESSION_STORAGE)) {
39044
- mkdirSync10(INTERACTIVE_BASH_SESSION_STORAGE, { recursive: true });
39123
+ if (!existsSync41(INTERACTIVE_BASH_SESSION_STORAGE)) {
39124
+ mkdirSync11(INTERACTIVE_BASH_SESSION_STORAGE, { recursive: true });
39045
39125
  }
39046
39126
  const filePath = getStoragePath3(state3.sessionID);
39047
39127
  const serialized = {
@@ -39049,11 +39129,11 @@ function saveInteractiveBashSessionState(state3) {
39049
39129
  tmuxSessions: Array.from(state3.tmuxSessions),
39050
39130
  updatedAt: state3.updatedAt
39051
39131
  };
39052
- writeFileSync14(filePath, JSON.stringify(serialized, null, 2));
39132
+ writeFileSync15(filePath, JSON.stringify(serialized, null, 2));
39053
39133
  }
39054
39134
  function clearInteractiveBashSessionState(sessionID) {
39055
39135
  const filePath = getStoragePath3(sessionID);
39056
- if (existsSync40(filePath)) {
39136
+ if (existsSync41(filePath)) {
39057
39137
  unlinkSync7(filePath);
39058
39138
  }
39059
39139
  }
@@ -39449,18 +39529,18 @@ var DEFAULT_STATE_FILE = ".sisyphus/ralph-loop.local.md";
39449
39529
  var DEFAULT_MAX_ITERATIONS = 100;
39450
39530
  var DEFAULT_COMPLETION_PROMISE = "DONE";
39451
39531
  // src/hooks/ralph-loop/storage.ts
39452
- import { existsSync as existsSync41, readFileSync as readFileSync29, writeFileSync as writeFileSync15, unlinkSync as unlinkSync8, mkdirSync as mkdirSync11 } from "fs";
39453
- import { dirname as dirname10, join as join49 } from "path";
39532
+ import { existsSync as existsSync42, readFileSync as readFileSync30, writeFileSync as writeFileSync16, unlinkSync as unlinkSync8, mkdirSync as mkdirSync12 } from "fs";
39533
+ import { dirname as dirname10, join as join50 } from "path";
39454
39534
  function getStateFilePath(directory, customPath) {
39455
- return customPath ? join49(directory, customPath) : join49(directory, DEFAULT_STATE_FILE);
39535
+ return customPath ? join50(directory, customPath) : join50(directory, DEFAULT_STATE_FILE);
39456
39536
  }
39457
39537
  function readState(directory, customPath) {
39458
39538
  const filePath = getStateFilePath(directory, customPath);
39459
- if (!existsSync41(filePath)) {
39539
+ if (!existsSync42(filePath)) {
39460
39540
  return null;
39461
39541
  }
39462
39542
  try {
39463
- const content = readFileSync29(filePath, "utf-8");
39543
+ const content = readFileSync30(filePath, "utf-8");
39464
39544
  const { data, body } = parseFrontmatter(content);
39465
39545
  const active = data.active;
39466
39546
  const iteration = data.iteration;
@@ -39494,8 +39574,8 @@ function writeState(directory, state3, customPath) {
39494
39574
  const filePath = getStateFilePath(directory, customPath);
39495
39575
  try {
39496
39576
  const dir = dirname10(filePath);
39497
- if (!existsSync41(dir)) {
39498
- mkdirSync11(dir, { recursive: true });
39577
+ if (!existsSync42(dir)) {
39578
+ mkdirSync12(dir, { recursive: true });
39499
39579
  }
39500
39580
  const sessionIdLine = state3.session_id ? `session_id: "${state3.session_id}"
39501
39581
  ` : "";
@@ -39510,7 +39590,7 @@ started_at: "${state3.started_at}"
39510
39590
  ${sessionIdLine}${ultraworkLine}---
39511
39591
  ${state3.prompt}
39512
39592
  `;
39513
- writeFileSync15(filePath, content, "utf-8");
39593
+ writeFileSync16(filePath, content, "utf-8");
39514
39594
  return true;
39515
39595
  } catch {
39516
39596
  return false;
@@ -39519,7 +39599,7 @@ ${state3.prompt}
39519
39599
  function clearState(directory, customPath) {
39520
39600
  const filePath = getStateFilePath(directory, customPath);
39521
39601
  try {
39522
- if (existsSync41(filePath)) {
39602
+ if (existsSync42(filePath)) {
39523
39603
  unlinkSync8(filePath);
39524
39604
  }
39525
39605
  return true;
@@ -39622,7 +39702,7 @@ init_logger();
39622
39702
 
39623
39703
  // src/hooks/ralph-loop/completion-promise-detector.ts
39624
39704
  init_logger();
39625
- import { existsSync as existsSync42, readFileSync as readFileSync30 } from "fs";
39705
+ import { existsSync as existsSync43, readFileSync as readFileSync31 } from "fs";
39626
39706
 
39627
39707
  // src/hooks/ralph-loop/with-timeout.ts
39628
39708
  async function withTimeout(promise2, timeoutMs) {
@@ -39652,9 +39732,9 @@ function detectCompletionInTranscript(transcriptPath, promise2) {
39652
39732
  if (!transcriptPath)
39653
39733
  return false;
39654
39734
  try {
39655
- if (!existsSync42(transcriptPath))
39735
+ if (!existsSync43(transcriptPath))
39656
39736
  return false;
39657
- const content = readFileSync30(transcriptPath, "utf-8");
39737
+ const content = readFileSync31(transcriptPath, "utf-8");
39658
39738
  const pattern = buildPromisePattern(promise2);
39659
39739
  const lines = content.split(`
39660
39740
  `).filter((line) => line.trim());
@@ -39936,6 +40016,33 @@ function createRalphLoopHook(ctx, options) {
39936
40016
  getState: loopState.getState
39937
40017
  };
39938
40018
  }
40019
+ // src/hooks/sisyphus-gpt-hephaestus-reminder/hook.ts
40020
+ var TOAST_TITLE = "Use Hephaestus for GPT Models";
40021
+ var TOAST_MESSAGE = "Sisyphus is using a GPT model. Use Hephaestus and include 'ulw' in your prompt.";
40022
+ function createSisyphusGptHephaestusReminderHook(ctx) {
40023
+ return {
40024
+ "chat.message": async (input) => {
40025
+ const agentName = (input.agent ?? getSessionAgent(input.sessionID) ?? "").toLowerCase();
40026
+ const modelID = input.model?.modelID?.toLowerCase() ?? "";
40027
+ if (agentName !== "sisyphus" || !modelID.includes("gpt")) {
40028
+ return;
40029
+ }
40030
+ await ctx.client.tui.showToast({
40031
+ body: {
40032
+ title: TOAST_TITLE,
40033
+ message: TOAST_MESSAGE,
40034
+ variant: "error",
40035
+ duration: 5000
40036
+ }
40037
+ }).catch((error45) => {
40038
+ log("[sisyphus-gpt-hephaestus-reminder] Failed to show toast", {
40039
+ sessionID: input.sessionID,
40040
+ error: error45
40041
+ });
40042
+ });
40043
+ }
40044
+ };
40045
+ }
39939
40046
  // src/hooks/auto-slash-command/constants.ts
39940
40047
  var AUTO_SLASH_COMMAND_TAG_OPEN = "<auto-slash-command>";
39941
40048
  var AUTO_SLASH_COMMAND_TAG_CLOSE = "</auto-slash-command>";
@@ -40009,8 +40116,8 @@ function findSlashCommandPartIndex(parts) {
40009
40116
  return -1;
40010
40117
  }
40011
40118
  // src/hooks/auto-slash-command/executor.ts
40012
- import { existsSync as existsSync44, readdirSync as readdirSync12, readFileSync as readFileSync33 } from "fs";
40013
- import { join as join55, basename as basename2, dirname as dirname13 } from "path";
40119
+ import { existsSync as existsSync45, readdirSync as readdirSync12, readFileSync as readFileSync34 } from "fs";
40120
+ import { join as join56, basename as basename2, dirname as dirname13 } from "path";
40014
40121
  // src/features/builtin-commands/templates/init-deep.ts
40015
40122
  var INIT_DEEP_TEMPLATE = `# /init-deep
40016
40123
 
@@ -41346,7 +41453,7 @@ function loadBuiltinCommands(disabledCommands) {
41346
41453
  return commands;
41347
41454
  }
41348
41455
  // src/features/opencode-skill-loader/loader.ts
41349
- import { join as join53 } from "path";
41456
+ import { join as join54 } from "path";
41350
41457
  import { homedir as homedir10 } from "os";
41351
41458
 
41352
41459
  // src/features/opencode-skill-loader/skill-definition-record.ts
@@ -41374,17 +41481,17 @@ function deduplicateSkillsByName(skills) {
41374
41481
 
41375
41482
  // src/features/opencode-skill-loader/skill-directory-loader.ts
41376
41483
  import { promises as fs16 } from "fs";
41377
- import { join as join52 } from "path";
41484
+ import { join as join53 } from "path";
41378
41485
 
41379
41486
  // src/features/opencode-skill-loader/loaded-skill-from-path.ts
41380
41487
  import { promises as fs15 } from "fs";
41381
41488
  import { basename } from "path";
41382
41489
 
41383
41490
  // src/shared/skill-path-resolver.ts
41384
- import { join as join50 } from "path";
41491
+ import { join as join51 } from "path";
41385
41492
  function resolveSkillPathReferences(content, basePath) {
41386
41493
  const normalizedBase = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
41387
- return content.replace(/(?<![a-zA-Z0-9])@([a-zA-Z0-9_-]+\/[a-zA-Z0-9_.\-\/]*)/g, (_, relativePath) => join50(normalizedBase, relativePath));
41494
+ return content.replace(/(?<![a-zA-Z0-9])@([a-zA-Z0-9_-]+\/[a-zA-Z0-9_.\-\/]*)/g, (_, relativePath) => join51(normalizedBase, relativePath));
41388
41495
  }
41389
41496
 
41390
41497
  // src/features/opencode-skill-loader/allowed-tools-parser.ts
@@ -41399,7 +41506,7 @@ function parseAllowedTools(allowedTools) {
41399
41506
 
41400
41507
  // src/features/opencode-skill-loader/skill-mcp-config.ts
41401
41508
  import { promises as fs14 } from "fs";
41402
- import { join as join51 } from "path";
41509
+ import { join as join52 } from "path";
41403
41510
  function parseSkillMcpConfigFromFrontmatter(content) {
41404
41511
  const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
41405
41512
  if (!frontmatterMatch)
@@ -41415,7 +41522,7 @@ function parseSkillMcpConfigFromFrontmatter(content) {
41415
41522
  return;
41416
41523
  }
41417
41524
  async function loadMcpJsonFromDir(skillDir) {
41418
- const mcpJsonPath = join51(skillDir, "mcp.json");
41525
+ const mcpJsonPath = join52(skillDir, "mcp.json");
41419
41526
  try {
41420
41527
  const content = await fs14.readFile(mcpJsonPath, "utf-8");
41421
41528
  const parsed = JSON.parse(content);
@@ -41504,10 +41611,10 @@ async function loadSkillsFromDir(options) {
41504
41611
  const directories = entries.filter((entry) => !entry.name.startsWith(".") && (entry.isDirectory() || entry.isSymbolicLink()));
41505
41612
  const files = entries.filter((entry) => !entry.name.startsWith(".") && !entry.isDirectory() && !entry.isSymbolicLink() && isMarkdownFile(entry));
41506
41613
  for (const entry of directories) {
41507
- const entryPath = join52(options.skillsDir, entry.name);
41614
+ const entryPath = join53(options.skillsDir, entry.name);
41508
41615
  const resolvedPath = await resolveSymlinkAsync(entryPath);
41509
41616
  const dirName = entry.name;
41510
- const skillMdPath = join52(resolvedPath, "SKILL.md");
41617
+ const skillMdPath = join53(resolvedPath, "SKILL.md");
41511
41618
  try {
41512
41619
  await fs16.access(skillMdPath);
41513
41620
  const skill = await loadSkillFromPath({
@@ -41522,7 +41629,7 @@ async function loadSkillsFromDir(options) {
41522
41629
  }
41523
41630
  continue;
41524
41631
  } catch {}
41525
- const namedSkillMdPath = join52(resolvedPath, `${dirName}.md`);
41632
+ const namedSkillMdPath = join53(resolvedPath, `${dirName}.md`);
41526
41633
  try {
41527
41634
  await fs16.access(namedSkillMdPath);
41528
41635
  const skill = await loadSkillFromPath({
@@ -41554,7 +41661,7 @@ async function loadSkillsFromDir(options) {
41554
41661
  }
41555
41662
  }
41556
41663
  for (const entry of files) {
41557
- const entryPath = join52(options.skillsDir, entry.name);
41664
+ const entryPath = join53(options.skillsDir, entry.name);
41558
41665
  const baseName = inferSkillNameFromFileName(entryPath);
41559
41666
  const skill = await loadSkillFromPath({
41560
41667
  skillPath: entryPath,
@@ -41572,23 +41679,23 @@ async function loadSkillsFromDir(options) {
41572
41679
 
41573
41680
  // src/features/opencode-skill-loader/loader.ts
41574
41681
  async function loadUserSkills() {
41575
- const userSkillsDir = join53(getClaudeConfigDir(), "skills");
41682
+ const userSkillsDir = join54(getClaudeConfigDir(), "skills");
41576
41683
  const skills = await loadSkillsFromDir({ skillsDir: userSkillsDir, scope: "user" });
41577
41684
  return skillsToCommandDefinitionRecord(skills);
41578
41685
  }
41579
41686
  async function loadProjectSkills(directory) {
41580
- const projectSkillsDir = join53(directory ?? process.cwd(), ".claude", "skills");
41687
+ const projectSkillsDir = join54(directory ?? process.cwd(), ".claude", "skills");
41581
41688
  const skills = await loadSkillsFromDir({ skillsDir: projectSkillsDir, scope: "project" });
41582
41689
  return skillsToCommandDefinitionRecord(skills);
41583
41690
  }
41584
41691
  async function loadOpencodeGlobalSkills() {
41585
41692
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
41586
- const opencodeSkillsDir = join53(configDir, "skills");
41693
+ const opencodeSkillsDir = join54(configDir, "skills");
41587
41694
  const skills = await loadSkillsFromDir({ skillsDir: opencodeSkillsDir, scope: "opencode" });
41588
41695
  return skillsToCommandDefinitionRecord(skills);
41589
41696
  }
41590
41697
  async function loadOpencodeProjectSkills(directory) {
41591
- const opencodeProjectDir = join53(directory ?? process.cwd(), ".opencode", "skills");
41698
+ const opencodeProjectDir = join54(directory ?? process.cwd(), ".opencode", "skills");
41592
41699
  const skills = await loadSkillsFromDir({ skillsDir: opencodeProjectDir, scope: "opencode-project" });
41593
41700
  return skillsToCommandDefinitionRecord(skills);
41594
41701
  }
@@ -41635,28 +41742,28 @@ async function discoverSkills(options = {}) {
41635
41742
  ]);
41636
41743
  }
41637
41744
  async function discoverUserClaudeSkills() {
41638
- const userSkillsDir = join53(getClaudeConfigDir(), "skills");
41745
+ const userSkillsDir = join54(getClaudeConfigDir(), "skills");
41639
41746
  return loadSkillsFromDir({ skillsDir: userSkillsDir, scope: "user" });
41640
41747
  }
41641
41748
  async function discoverProjectClaudeSkills(directory) {
41642
- const projectSkillsDir = join53(directory ?? process.cwd(), ".claude", "skills");
41749
+ const projectSkillsDir = join54(directory ?? process.cwd(), ".claude", "skills");
41643
41750
  return loadSkillsFromDir({ skillsDir: projectSkillsDir, scope: "project" });
41644
41751
  }
41645
41752
  async function discoverOpencodeGlobalSkills() {
41646
41753
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
41647
- const opencodeSkillsDir = join53(configDir, "skills");
41754
+ const opencodeSkillsDir = join54(configDir, "skills");
41648
41755
  return loadSkillsFromDir({ skillsDir: opencodeSkillsDir, scope: "opencode" });
41649
41756
  }
41650
41757
  async function discoverOpencodeProjectSkills(directory) {
41651
- const opencodeProjectDir = join53(directory ?? process.cwd(), ".opencode", "skills");
41758
+ const opencodeProjectDir = join54(directory ?? process.cwd(), ".opencode", "skills");
41652
41759
  return loadSkillsFromDir({ skillsDir: opencodeProjectDir, scope: "opencode-project" });
41653
41760
  }
41654
41761
  async function discoverProjectAgentsSkills(directory) {
41655
- const agentsProjectDir = join53(directory ?? process.cwd(), ".agents", "skills");
41762
+ const agentsProjectDir = join54(directory ?? process.cwd(), ".agents", "skills");
41656
41763
  return loadSkillsFromDir({ skillsDir: agentsProjectDir, scope: "project" });
41657
41764
  }
41658
41765
  async function discoverGlobalAgentsSkills() {
41659
- const agentsGlobalDir = join53(homedir10(), ".agents", "skills");
41766
+ const agentsGlobalDir = join54(homedir10(), ".agents", "skills");
41660
41767
  return loadSkillsFromDir({ skillsDir: agentsGlobalDir, scope: "user" });
41661
41768
  }
41662
41769
  // src/features/opencode-skill-loader/merger/builtin-skill-converter.ts
@@ -41683,7 +41790,7 @@ function builtinToLoadedSkill(builtin) {
41683
41790
  }
41684
41791
 
41685
41792
  // src/features/opencode-skill-loader/merger/config-skill-entry-loader.ts
41686
- import { existsSync as existsSync43, readFileSync as readFileSync31 } from "fs";
41793
+ import { existsSync as existsSync44, readFileSync as readFileSync32 } from "fs";
41687
41794
  import { dirname as dirname11, isAbsolute as isAbsolute2, resolve as resolve5 } from "path";
41688
41795
  import { homedir as homedir11 } from "os";
41689
41796
  function resolveFilePath5(from, configDir) {
@@ -41702,9 +41809,9 @@ function resolveFilePath5(from, configDir) {
41702
41809
  }
41703
41810
  function loadSkillFromFile(filePath) {
41704
41811
  try {
41705
- if (!existsSync43(filePath))
41812
+ if (!existsSync44(filePath))
41706
41813
  return null;
41707
- const content = readFileSync31(filePath, "utf-8");
41814
+ const content = readFileSync32(filePath, "utf-8");
41708
41815
  const { data, body } = parseFrontmatter(content);
41709
41816
  return { template: body, metadata: data };
41710
41817
  } catch {
@@ -43920,10 +44027,10 @@ async function getAllSkills(options) {
43920
44027
  return allSkills;
43921
44028
  }
43922
44029
  // src/features/opencode-skill-loader/loaded-skill-template-extractor.ts
43923
- import { readFileSync as readFileSync32 } from "fs";
44030
+ import { readFileSync as readFileSync33 } from "fs";
43924
44031
  function extractSkillTemplate(skill) {
43925
44032
  if (skill.path) {
43926
- const content = readFileSync32(skill.path, "utf-8");
44033
+ const content = readFileSync33(skill.path, "utf-8");
43927
44034
  const { body } = parseFrontmatter(content);
43928
44035
  return body.trim();
43929
44036
  }
@@ -44034,7 +44141,7 @@ async function resolveMultipleSkillsAsync(skillNames, options) {
44034
44141
  // src/features/opencode-skill-loader/config-source-discovery.ts
44035
44142
  var import_picomatch2 = __toESM(require_picomatch2(), 1);
44036
44143
  import { promises as fs17 } from "fs";
44037
- import { dirname as dirname12, extname, isAbsolute as isAbsolute3, join as join54, relative as relative3 } from "path";
44144
+ import { dirname as dirname12, extname, isAbsolute as isAbsolute3, join as join55, relative as relative3 } from "path";
44038
44145
  var MAX_RECURSIVE_DEPTH = 10;
44039
44146
  function isHttpUrl(path10) {
44040
44147
  return path10.startsWith("http://") || path10.startsWith("https://");
@@ -44043,7 +44150,7 @@ function toAbsolutePath(path10, configDir) {
44043
44150
  if (isAbsolute3(path10)) {
44044
44151
  return path10;
44045
44152
  }
44046
- return join54(configDir, path10);
44153
+ return join55(configDir, path10);
44047
44154
  }
44048
44155
  function isMarkdownPath(path10) {
44049
44156
  return extname(path10).toLowerCase() === ".md";
@@ -44114,7 +44221,7 @@ async function discoverConfigSourceSkills(options) {
44114
44221
  }
44115
44222
  // src/hooks/auto-slash-command/executor.ts
44116
44223
  function discoverCommandsFromDir(commandsDir, scope) {
44117
- if (!existsSync44(commandsDir)) {
44224
+ if (!existsSync45(commandsDir)) {
44118
44225
  return [];
44119
44226
  }
44120
44227
  const entries = readdirSync12(commandsDir, { withFileTypes: true });
@@ -44122,10 +44229,10 @@ function discoverCommandsFromDir(commandsDir, scope) {
44122
44229
  for (const entry of entries) {
44123
44230
  if (!isMarkdownFile(entry))
44124
44231
  continue;
44125
- const commandPath = join55(commandsDir, entry.name);
44232
+ const commandPath = join56(commandsDir, entry.name);
44126
44233
  const commandName = basename2(entry.name, ".md");
44127
44234
  try {
44128
- const content = readFileSync33(commandPath, "utf-8");
44235
+ const content = readFileSync34(commandPath, "utf-8");
44129
44236
  const { data, body } = parseFrontmatter(content);
44130
44237
  const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
44131
44238
  const metadata = {
@@ -44168,10 +44275,10 @@ function skillToCommandInfo(skill) {
44168
44275
  }
44169
44276
  async function discoverAllCommands(options) {
44170
44277
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
44171
- const userCommandsDir = join55(getClaudeConfigDir(), "commands");
44172
- const projectCommandsDir = join55(process.cwd(), ".claude", "commands");
44173
- const opencodeGlobalDir = join55(configDir, "command");
44174
- const opencodeProjectDir = join55(process.cwd(), ".opencode", "command");
44278
+ const userCommandsDir = join56(getClaudeConfigDir(), "commands");
44279
+ const projectCommandsDir = join56(process.cwd(), ".claude", "commands");
44280
+ const opencodeGlobalDir = join56(configDir, "command");
44281
+ const opencodeProjectDir = join56(process.cwd(), ".opencode", "command");
44175
44282
  const userCommands = discoverCommandsFromDir(userCommandsDir, "user");
44176
44283
  const opencodeGlobalCommands = discoverCommandsFromDir(opencodeGlobalDir, "opencode");
44177
44284
  const projectCommands = discoverCommandsFromDir(projectCommandsDir, "project");
@@ -44400,6 +44507,58 @@ ${EDIT_ERROR_REMINDER}`;
44400
44507
  }
44401
44508
  };
44402
44509
  }
44510
+ // src/hooks/json-error-recovery/hook.ts
44511
+ var JSON_ERROR_TOOL_EXCLUDE_LIST = [
44512
+ "bash",
44513
+ "read",
44514
+ "glob",
44515
+ "grep",
44516
+ "webfetch",
44517
+ "look_at",
44518
+ "grep_app_searchgithub",
44519
+ "websearch_web_search_exa"
44520
+ ];
44521
+ var JSON_ERROR_PATTERNS = [
44522
+ /json parse error/i,
44523
+ /failed to parse json/i,
44524
+ /invalid json/i,
44525
+ /malformed json/i,
44526
+ /unexpected end of json input/i,
44527
+ /syntaxerror:\s*unexpected token.*json/i,
44528
+ /json[^\n]*expected '\}'/i,
44529
+ /json[^\n]*unexpected eof/i
44530
+ ];
44531
+ var JSON_ERROR_REMINDER_MARKER = "[JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]";
44532
+ var JSON_ERROR_EXCLUDED_TOOLS = new Set(JSON_ERROR_TOOL_EXCLUDE_LIST);
44533
+ var JSON_ERROR_REMINDER = `
44534
+ [JSON PARSE ERROR - IMMEDIATE ACTION REQUIRED]
44535
+
44536
+ You sent invalid JSON arguments. The system could not parse your tool call.
44537
+ STOP and do this NOW:
44538
+
44539
+ 1. LOOK at the error message above to see what was expected vs what you sent.
44540
+ 2. CORRECT your JSON syntax (missing braces, unescaped quotes, trailing commas, etc).
44541
+ 3. RETRY the tool call with valid JSON.
44542
+
44543
+ DO NOT repeat the exact same invalid call.
44544
+ `;
44545
+ function createJsonErrorRecoveryHook(_ctx) {
44546
+ return {
44547
+ "tool.execute.after": async (input, output) => {
44548
+ if (JSON_ERROR_EXCLUDED_TOOLS.has(input.tool.toLowerCase()))
44549
+ return;
44550
+ if (typeof output.output !== "string")
44551
+ return;
44552
+ if (output.output.includes(JSON_ERROR_REMINDER_MARKER))
44553
+ return;
44554
+ const hasJsonError = JSON_ERROR_PATTERNS.some((pattern) => pattern.test(output.output));
44555
+ if (hasJsonError) {
44556
+ output.output += `
44557
+ ${JSON_ERROR_REMINDER}`;
44558
+ }
44559
+ }
44560
+ };
44561
+ }
44403
44562
  // src/hooks/prometheus-md-only/constants.ts
44404
44563
  var HOOK_NAME4 = "prometheus-md-only";
44405
44564
  var PROMETHEUS_AGENT = "prometheus";
@@ -44479,18 +44638,18 @@ var NOTEPAD_DIR = "notepads";
44479
44638
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
44480
44639
  var PROMETHEUS_PLANS_DIR = ".sisyphus/plans";
44481
44640
  // src/features/boulder-state/storage.ts
44482
- import { existsSync as existsSync45, readFileSync as readFileSync34, writeFileSync as writeFileSync16, mkdirSync as mkdirSync12, readdirSync as readdirSync13 } from "fs";
44483
- import { dirname as dirname14, join as join56, basename as basename3 } from "path";
44641
+ import { existsSync as existsSync46, readFileSync as readFileSync35, writeFileSync as writeFileSync17, mkdirSync as mkdirSync13, readdirSync as readdirSync13 } from "fs";
44642
+ import { dirname as dirname14, join as join57, basename as basename3 } from "path";
44484
44643
  function getBoulderFilePath(directory) {
44485
- return join56(directory, BOULDER_DIR, BOULDER_FILE);
44644
+ return join57(directory, BOULDER_DIR, BOULDER_FILE);
44486
44645
  }
44487
44646
  function readBoulderState(directory) {
44488
44647
  const filePath = getBoulderFilePath(directory);
44489
- if (!existsSync45(filePath)) {
44648
+ if (!existsSync46(filePath)) {
44490
44649
  return null;
44491
44650
  }
44492
44651
  try {
44493
- const content = readFileSync34(filePath, "utf-8");
44652
+ const content = readFileSync35(filePath, "utf-8");
44494
44653
  const parsed = JSON.parse(content);
44495
44654
  if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
44496
44655
  return null;
@@ -44507,10 +44666,10 @@ function writeBoulderState(directory, state3) {
44507
44666
  const filePath = getBoulderFilePath(directory);
44508
44667
  try {
44509
44668
  const dir = dirname14(filePath);
44510
- if (!existsSync45(dir)) {
44511
- mkdirSync12(dir, { recursive: true });
44669
+ if (!existsSync46(dir)) {
44670
+ mkdirSync13(dir, { recursive: true });
44512
44671
  }
44513
- writeFileSync16(filePath, JSON.stringify(state3, null, 2), "utf-8");
44672
+ writeFileSync17(filePath, JSON.stringify(state3, null, 2), "utf-8");
44514
44673
  return true;
44515
44674
  } catch {
44516
44675
  return false;
@@ -44534,7 +44693,7 @@ function appendSessionId(directory, sessionId) {
44534
44693
  function clearBoulderState(directory) {
44535
44694
  const filePath = getBoulderFilePath(directory);
44536
44695
  try {
44537
- if (existsSync45(filePath)) {
44696
+ if (existsSync46(filePath)) {
44538
44697
  const { unlinkSync: unlinkSync9 } = __require("fs");
44539
44698
  unlinkSync9(filePath);
44540
44699
  }
@@ -44544,13 +44703,13 @@ function clearBoulderState(directory) {
44544
44703
  }
44545
44704
  }
44546
44705
  function findPrometheusPlans(directory) {
44547
- const plansDir = join56(directory, PROMETHEUS_PLANS_DIR);
44548
- if (!existsSync45(plansDir)) {
44706
+ const plansDir = join57(directory, PROMETHEUS_PLANS_DIR);
44707
+ if (!existsSync46(plansDir)) {
44549
44708
  return [];
44550
44709
  }
44551
44710
  try {
44552
44711
  const files = readdirSync13(plansDir);
44553
- return files.filter((f) => f.endsWith(".md")).map((f) => join56(plansDir, f)).sort((a, b) => {
44712
+ return files.filter((f) => f.endsWith(".md")).map((f) => join57(plansDir, f)).sort((a, b) => {
44554
44713
  const aStat = __require("fs").statSync(a);
44555
44714
  const bStat = __require("fs").statSync(b);
44556
44715
  return bStat.mtimeMs - aStat.mtimeMs;
@@ -44560,11 +44719,11 @@ function findPrometheusPlans(directory) {
44560
44719
  }
44561
44720
  }
44562
44721
  function getPlanProgress(planPath) {
44563
- if (!existsSync45(planPath)) {
44722
+ if (!existsSync46(planPath)) {
44564
44723
  return { total: 0, completed: 0, isComplete: true };
44565
44724
  }
44566
44725
  try {
44567
- const content = readFileSync34(planPath, "utf-8");
44726
+ const content = readFileSync35(planPath, "utf-8");
44568
44727
  const uncheckedMatches = content.match(/^[-*]\s*\[\s*\]/gm) || [];
44569
44728
  const checkedMatches = content.match(/^[-*]\s*\[[xX]\]/gm) || [];
44570
44729
  const total = uncheckedMatches.length + checkedMatches.length;
@@ -45845,10 +46004,11 @@ function createQuestionLabelTruncatorHook() {
45845
46004
  // src/hooks/stop-continuation-guard/hook.ts
45846
46005
  init_logger();
45847
46006
  var HOOK_NAME8 = "stop-continuation-guard";
45848
- function createStopContinuationGuardHook(_ctx) {
46007
+ function createStopContinuationGuardHook(ctx) {
45849
46008
  const stoppedSessions = new Set;
45850
46009
  const stop = (sessionID) => {
45851
46010
  stoppedSessions.add(sessionID);
46011
+ setContinuationMarkerSource(ctx.directory, sessionID, "stop", "stopped", "continuation stopped");
45852
46012
  log(`[${HOOK_NAME8}] Continuation stopped for session`, { sessionID });
45853
46013
  };
45854
46014
  const isStopped = (sessionID) => {
@@ -45856,6 +46016,7 @@ function createStopContinuationGuardHook(_ctx) {
45856
46016
  };
45857
46017
  const clear = (sessionID) => {
45858
46018
  stoppedSessions.delete(sessionID);
46019
+ setContinuationMarkerSource(ctx.directory, sessionID, "stop", "idle");
45859
46020
  log(`[${HOOK_NAME8}] Continuation guard cleared for session`, { sessionID });
45860
46021
  };
45861
46022
  const event = async ({
@@ -45866,6 +46027,7 @@ function createStopContinuationGuardHook(_ctx) {
45866
46027
  const sessionInfo = props?.info;
45867
46028
  if (sessionInfo?.id) {
45868
46029
  clear(sessionInfo.id);
46030
+ clearContinuationMarker(ctx.directory, sessionInfo.id);
45869
46031
  log(`[${HOOK_NAME8}] Session deleted: cleaned up`, { sessionID: sessionInfo.id });
45870
46032
  }
45871
46033
  }
@@ -46356,8 +46518,8 @@ function createTasksTodowriteDisablerHook(config2) {
46356
46518
  };
46357
46519
  }
46358
46520
  // src/hooks/write-existing-file-guard/hook.ts
46359
- import { existsSync as existsSync46 } from "fs";
46360
- import { resolve as resolve7, isAbsolute as isAbsolute5, join as join57, normalize, sep } from "path";
46521
+ import { existsSync as existsSync47 } from "fs";
46522
+ import { resolve as resolve7, isAbsolute as isAbsolute5, join as join58, normalize, sep } from "path";
46361
46523
  function createWriteExistingFileGuardHook(ctx) {
46362
46524
  return {
46363
46525
  "tool.execute.before": async (input, output) => {
@@ -46371,8 +46533,8 @@ function createWriteExistingFileGuardHook(ctx) {
46371
46533
  return;
46372
46534
  }
46373
46535
  const resolvedPath = normalize(isAbsolute5(filePath) ? filePath : resolve7(ctx.directory, filePath));
46374
- if (existsSync46(resolvedPath)) {
46375
- const sisyphusRoot = join57(ctx.directory, ".sisyphus") + sep;
46536
+ if (existsSync47(resolvedPath)) {
46537
+ const sisyphusRoot = join58(ctx.directory, ".sisyphus") + sep;
46376
46538
  const isSisyphusMarkdown = resolvedPath.startsWith(sisyphusRoot) && resolvedPath.endsWith(".md");
46377
46539
  if (isSisyphusMarkdown) {
46378
46540
  log("[write-existing-file-guard] Allowing .sisyphus/*.md overwrite", {
@@ -47007,13 +47169,13 @@ var DEFAULT_MAX_REFERENCES = 200;
47007
47169
  var DEFAULT_MAX_SYMBOLS = 200;
47008
47170
  var DEFAULT_MAX_DIAGNOSTICS = 200;
47009
47171
  // src/tools/lsp/server-config-loader.ts
47010
- import { existsSync as existsSync47, readFileSync as readFileSync35 } from "fs";
47011
- import { join as join58 } from "path";
47172
+ import { existsSync as existsSync48, readFileSync as readFileSync36 } from "fs";
47173
+ import { join as join59 } from "path";
47012
47174
  function loadJsonFile(path10) {
47013
- if (!existsSync47(path10))
47175
+ if (!existsSync48(path10))
47014
47176
  return null;
47015
47177
  try {
47016
- return parseJsonc(readFileSync35(path10, "utf-8"));
47178
+ return parseJsonc(readFileSync36(path10, "utf-8"));
47017
47179
  } catch {
47018
47180
  return null;
47019
47181
  }
@@ -47022,9 +47184,9 @@ function getConfigPaths3() {
47022
47184
  const cwd = process.cwd();
47023
47185
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
47024
47186
  return {
47025
- project: detectConfigFile(join58(cwd, ".opencode", "oh-my-opencode")).path,
47026
- user: detectConfigFile(join58(configDir, "oh-my-opencode")).path,
47027
- opencode: detectConfigFile(join58(configDir, "opencode")).path
47187
+ project: detectConfigFile(join59(cwd, ".opencode", "oh-my-opencode")).path,
47188
+ user: detectConfigFile(join59(configDir, "oh-my-opencode")).path,
47189
+ opencode: detectConfigFile(join59(configDir, "opencode")).path
47028
47190
  };
47029
47191
  }
47030
47192
  function loadAllConfigs() {
@@ -47093,14 +47255,14 @@ function getMergedServers() {
47093
47255
  }
47094
47256
 
47095
47257
  // src/tools/lsp/server-installation.ts
47096
- import { existsSync as existsSync48 } from "fs";
47097
- import { join as join59 } from "path";
47258
+ import { existsSync as existsSync49 } from "fs";
47259
+ import { join as join60 } from "path";
47098
47260
  function isServerInstalled(command) {
47099
47261
  if (command.length === 0)
47100
47262
  return false;
47101
47263
  const cmd = command[0];
47102
47264
  if (cmd.includes("/") || cmd.includes("\\")) {
47103
- if (existsSync48(cmd))
47265
+ if (existsSync49(cmd))
47104
47266
  return true;
47105
47267
  }
47106
47268
  const isWindows2 = process.platform === "win32";
@@ -47122,23 +47284,23 @@ function isServerInstalled(command) {
47122
47284
  const paths = pathEnv.split(pathSeparator);
47123
47285
  for (const p of paths) {
47124
47286
  for (const suffix of exts) {
47125
- if (existsSync48(join59(p, cmd + suffix))) {
47287
+ if (existsSync49(join60(p, cmd + suffix))) {
47126
47288
  return true;
47127
47289
  }
47128
47290
  }
47129
47291
  }
47130
47292
  const cwd = process.cwd();
47131
47293
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
47132
- const dataDir = join59(getDataDir(), "opencode");
47294
+ const dataDir = join60(getDataDir(), "opencode");
47133
47295
  const additionalBases = [
47134
- join59(cwd, "node_modules", ".bin"),
47135
- join59(configDir, "bin"),
47136
- join59(configDir, "node_modules", ".bin"),
47137
- join59(dataDir, "bin")
47296
+ join60(cwd, "node_modules", ".bin"),
47297
+ join60(configDir, "bin"),
47298
+ join60(configDir, "node_modules", ".bin"),
47299
+ join60(dataDir, "bin")
47138
47300
  ];
47139
47301
  for (const base of additionalBases) {
47140
47302
  for (const suffix of exts) {
47141
- if (existsSync48(join59(base, cmd + suffix))) {
47303
+ if (existsSync49(join60(base, cmd + suffix))) {
47142
47304
  return true;
47143
47305
  }
47144
47306
  }
@@ -47196,13 +47358,13 @@ function getLanguageId(ext) {
47196
47358
  init_logger();
47197
47359
  var {spawn: bunSpawn } = globalThis.Bun;
47198
47360
  import { spawn as nodeSpawn } from "child_process";
47199
- import { existsSync as existsSync49, statSync as statSync6 } from "fs";
47361
+ import { existsSync as existsSync50, statSync as statSync6 } from "fs";
47200
47362
  function shouldUseNodeSpawn() {
47201
47363
  return process.platform === "win32";
47202
47364
  }
47203
47365
  function validateCwd(cwd) {
47204
47366
  try {
47205
- if (!existsSync49(cwd)) {
47367
+ if (!existsSync50(cwd)) {
47206
47368
  return { valid: false, error: `Working directory does not exist: ${cwd}` };
47207
47369
  }
47208
47370
  const stats = statSync6(cwd);
@@ -47383,7 +47545,7 @@ async function cleanupTempDirectoryLspClients(clients) {
47383
47545
  }
47384
47546
 
47385
47547
  // src/tools/lsp/lsp-client.ts
47386
- import { readFileSync as readFileSync36 } from "fs";
47548
+ import { readFileSync as readFileSync37 } from "fs";
47387
47549
  import { extname as extname2, resolve as resolve8 } from "path";
47388
47550
  import { pathToFileURL as pathToFileURL2 } from "url";
47389
47551
 
@@ -47647,7 +47809,7 @@ class LSPClient extends LSPClientConnection {
47647
47809
  async openFile(filePath) {
47648
47810
  const absPath = resolve8(filePath);
47649
47811
  const uri = pathToFileURL2(absPath).href;
47650
- const text = readFileSync36(absPath, "utf-8");
47812
+ const text = readFileSync37(absPath, "utf-8");
47651
47813
  if (!this.openedFiles.has(absPath)) {
47652
47814
  const ext = extname2(absPath);
47653
47815
  const languageId = getLanguageId(ext);
@@ -47922,17 +48084,17 @@ var lspManager = LSPServerManager.getInstance();
47922
48084
  // src/tools/lsp/lsp-client-wrapper.ts
47923
48085
  import { extname as extname3, resolve as resolve9 } from "path";
47924
48086
  import { fileURLToPath as fileURLToPath3 } from "url";
47925
- import { existsSync as existsSync50 } from "fs";
48087
+ import { existsSync as existsSync51 } from "fs";
47926
48088
  function findWorkspaceRoot(filePath) {
47927
48089
  let dir = resolve9(filePath);
47928
- if (!existsSync50(dir) || !__require("fs").statSync(dir).isDirectory()) {
48090
+ if (!existsSync51(dir) || !__require("fs").statSync(dir).isDirectory()) {
47929
48091
  dir = __require("path").dirname(dir);
47930
48092
  }
47931
48093
  const markers = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
47932
48094
  let prevDir = "";
47933
48095
  while (dir !== prevDir) {
47934
48096
  for (const marker of markers) {
47935
- if (existsSync50(__require("path").join(dir, marker))) {
48097
+ if (existsSync51(__require("path").join(dir, marker))) {
47936
48098
  return dir;
47937
48099
  }
47938
48100
  }
@@ -48107,10 +48269,10 @@ function formatApplyResult(result) {
48107
48269
  `);
48108
48270
  }
48109
48271
  // src/tools/lsp/workspace-edit.ts
48110
- import { readFileSync as readFileSync37, writeFileSync as writeFileSync17 } from "fs";
48272
+ import { readFileSync as readFileSync38, writeFileSync as writeFileSync18 } from "fs";
48111
48273
  function applyTextEditsToFile(filePath, edits) {
48112
48274
  try {
48113
- let content = readFileSync37(filePath, "utf-8");
48275
+ let content = readFileSync38(filePath, "utf-8");
48114
48276
  const lines = content.split(`
48115
48277
  `);
48116
48278
  const sortedEdits = [...edits].sort((a, b) => {
@@ -48135,7 +48297,7 @@ function applyTextEditsToFile(filePath, edits) {
48135
48297
  `));
48136
48298
  }
48137
48299
  }
48138
- writeFileSync17(filePath, lines.join(`
48300
+ writeFileSync18(filePath, lines.join(`
48139
48301
  `), "utf-8");
48140
48302
  return { success: true, editCount: edits.length };
48141
48303
  } catch (err) {
@@ -48166,7 +48328,7 @@ function applyWorkspaceEdit(edit) {
48166
48328
  if (change.kind === "create") {
48167
48329
  try {
48168
48330
  const filePath = uriToPath(change.uri);
48169
- writeFileSync17(filePath, "", "utf-8");
48331
+ writeFileSync18(filePath, "", "utf-8");
48170
48332
  result.filesModified.push(filePath);
48171
48333
  } catch (err) {
48172
48334
  result.success = false;
@@ -48176,8 +48338,8 @@ function applyWorkspaceEdit(edit) {
48176
48338
  try {
48177
48339
  const oldPath = uriToPath(change.oldUri);
48178
48340
  const newPath = uriToPath(change.newUri);
48179
- const content = readFileSync37(oldPath, "utf-8");
48180
- writeFileSync17(newPath, content, "utf-8");
48341
+ const content = readFileSync38(oldPath, "utf-8");
48342
+ writeFileSync18(newPath, content, "utf-8");
48181
48343
  __require("fs").unlinkSync(oldPath);
48182
48344
  result.filesModified.push(newPath);
48183
48345
  } catch (err) {
@@ -48458,12 +48620,12 @@ var DEFAULT_MAX_MATCHES = 500;
48458
48620
 
48459
48621
  // src/tools/ast-grep/sg-cli-path.ts
48460
48622
  import { createRequire as createRequire4 } from "module";
48461
- import { dirname as dirname15, join as join61 } from "path";
48462
- import { existsSync as existsSync52, statSync as statSync7 } from "fs";
48623
+ import { dirname as dirname15, join as join62 } from "path";
48624
+ import { existsSync as existsSync53, statSync as statSync7 } from "fs";
48463
48625
 
48464
48626
  // src/tools/ast-grep/downloader.ts
48465
- import { existsSync as existsSync51 } from "fs";
48466
- import { join as join60 } from "path";
48627
+ import { existsSync as existsSync52 } from "fs";
48628
+ import { join as join61 } from "path";
48467
48629
  import { homedir as homedir12 } from "os";
48468
48630
  import { createRequire as createRequire3 } from "module";
48469
48631
  init_logger();
@@ -48490,12 +48652,12 @@ var PLATFORM_MAP2 = {
48490
48652
  function getCacheDir4() {
48491
48653
  if (process.platform === "win32") {
48492
48654
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
48493
- const base2 = localAppData || join60(homedir12(), "AppData", "Local");
48494
- return join60(base2, "oh-my-opencode", "bin");
48655
+ const base2 = localAppData || join61(homedir12(), "AppData", "Local");
48656
+ return join61(base2, "oh-my-opencode", "bin");
48495
48657
  }
48496
48658
  const xdgCache = process.env.XDG_CACHE_HOME;
48497
- const base = xdgCache || join60(homedir12(), ".cache");
48498
- return join60(base, "oh-my-opencode", "bin");
48659
+ const base = xdgCache || join61(homedir12(), ".cache");
48660
+ return join61(base, "oh-my-opencode", "bin");
48499
48661
  }
48500
48662
  function getBinaryName3() {
48501
48663
  return process.platform === "win32" ? "sg.exe" : "sg";
@@ -48512,8 +48674,8 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
48512
48674
  }
48513
48675
  const cacheDir = getCacheDir4();
48514
48676
  const binaryName = getBinaryName3();
48515
- const binaryPath = join60(cacheDir, binaryName);
48516
- if (existsSync51(binaryPath)) {
48677
+ const binaryPath = join61(cacheDir, binaryName);
48678
+ if (existsSync52(binaryPath)) {
48517
48679
  return binaryPath;
48518
48680
  }
48519
48681
  const { arch, os: os6 } = platformInfo;
@@ -48521,7 +48683,7 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
48521
48683
  const downloadUrl = `https://github.com/${REPO2}/releases/download/${version2}/${assetName}`;
48522
48684
  log(`[oh-my-opencode] Downloading ast-grep binary...`);
48523
48685
  try {
48524
- const archivePath = join60(cacheDir, assetName);
48686
+ const archivePath = join61(cacheDir, assetName);
48525
48687
  ensureCacheDir(cacheDir);
48526
48688
  await downloadArchive(downloadUrl, archivePath);
48527
48689
  await extractZipArchive(archivePath, cacheDir);
@@ -48575,8 +48737,8 @@ function findSgCliPathSync() {
48575
48737
  const require2 = createRequire4(import.meta.url);
48576
48738
  const cliPackageJsonPath = require2.resolve("@ast-grep/cli/package.json");
48577
48739
  const cliDirectory = dirname15(cliPackageJsonPath);
48578
- const sgPath = join61(cliDirectory, binaryName);
48579
- if (existsSync52(sgPath) && isValidBinary(sgPath)) {
48740
+ const sgPath = join62(cliDirectory, binaryName);
48741
+ if (existsSync53(sgPath) && isValidBinary(sgPath)) {
48580
48742
  return sgPath;
48581
48743
  }
48582
48744
  } catch {}
@@ -48587,8 +48749,8 @@ function findSgCliPathSync() {
48587
48749
  const packageJsonPath = require2.resolve(`${platformPackage}/package.json`);
48588
48750
  const packageDirectory = dirname15(packageJsonPath);
48589
48751
  const astGrepBinaryName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
48590
- const binaryPath = join61(packageDirectory, astGrepBinaryName);
48591
- if (existsSync52(binaryPath) && isValidBinary(binaryPath)) {
48752
+ const binaryPath = join62(packageDirectory, astGrepBinaryName);
48753
+ if (existsSync53(binaryPath) && isValidBinary(binaryPath)) {
48592
48754
  return binaryPath;
48593
48755
  }
48594
48756
  } catch {}
@@ -48596,7 +48758,7 @@ function findSgCliPathSync() {
48596
48758
  if (process.platform === "darwin") {
48597
48759
  const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
48598
48760
  for (const path10 of homebrewPaths) {
48599
- if (existsSync52(path10) && isValidBinary(path10)) {
48761
+ if (existsSync53(path10) && isValidBinary(path10)) {
48600
48762
  return path10;
48601
48763
  }
48602
48764
  }
@@ -48620,14 +48782,14 @@ function setSgCliPath(path10) {
48620
48782
  }
48621
48783
  // src/tools/ast-grep/cli.ts
48622
48784
  var {spawn: spawn10 } = globalThis.Bun;
48623
- import { existsSync as existsSync54 } from "fs";
48785
+ import { existsSync as existsSync55 } from "fs";
48624
48786
 
48625
48787
  // src/tools/ast-grep/cli-binary-path-resolution.ts
48626
- import { existsSync as existsSync53 } from "fs";
48788
+ import { existsSync as existsSync54 } from "fs";
48627
48789
  var resolvedCliPath3 = null;
48628
48790
  var initPromise3 = null;
48629
48791
  async function getAstGrepPath() {
48630
- if (resolvedCliPath3 !== null && existsSync53(resolvedCliPath3)) {
48792
+ if (resolvedCliPath3 !== null && existsSync54(resolvedCliPath3)) {
48631
48793
  return resolvedCliPath3;
48632
48794
  }
48633
48795
  if (initPromise3) {
@@ -48635,7 +48797,7 @@ async function getAstGrepPath() {
48635
48797
  }
48636
48798
  initPromise3 = (async () => {
48637
48799
  const syncPath = findSgCliPathSync();
48638
- if (syncPath && existsSync53(syncPath)) {
48800
+ if (syncPath && existsSync54(syncPath)) {
48639
48801
  resolvedCliPath3 = syncPath;
48640
48802
  setSgCliPath(syncPath);
48641
48803
  return syncPath;
@@ -48734,7 +48896,7 @@ async function runSg(options) {
48734
48896
  const paths = options.paths && options.paths.length > 0 ? options.paths : ["."];
48735
48897
  args.push(...paths);
48736
48898
  let cliPath = getSgCliPath();
48737
- if (!cliPath || !existsSync54(cliPath)) {
48899
+ if (!cliPath || !existsSync55(cliPath)) {
48738
48900
  const downloadedPath = await getAstGrepPath();
48739
48901
  if (downloadedPath) {
48740
48902
  cliPath = downloadedPath;
@@ -48985,19 +49147,19 @@ ${hint}`;
48985
49147
  var {spawn: spawn11 } = globalThis.Bun;
48986
49148
 
48987
49149
  // src/tools/grep/constants.ts
48988
- import { existsSync as existsSync56 } from "fs";
48989
- import { join as join63, dirname as dirname16 } from "path";
49150
+ import { existsSync as existsSync57 } from "fs";
49151
+ import { join as join64, dirname as dirname16 } from "path";
48990
49152
  import { spawnSync as spawnSync2 } from "child_process";
48991
49153
 
48992
49154
  // src/tools/grep/downloader.ts
48993
- import { existsSync as existsSync55, readdirSync as readdirSync14 } from "fs";
48994
- import { join as join62 } from "path";
49155
+ import { existsSync as existsSync56, readdirSync as readdirSync14 } from "fs";
49156
+ import { join as join63 } from "path";
48995
49157
  function findFileRecursive(dir, filename) {
48996
49158
  try {
48997
49159
  const entries = readdirSync14(dir, { withFileTypes: true, recursive: true });
48998
49160
  for (const entry of entries) {
48999
49161
  if (entry.isFile() && entry.name === filename) {
49000
- return join62(entry.parentPath ?? dir, entry.name);
49162
+ return join63(entry.parentPath ?? dir, entry.name);
49001
49163
  }
49002
49164
  }
49003
49165
  } catch {
@@ -49018,11 +49180,11 @@ function getPlatformKey() {
49018
49180
  }
49019
49181
  function getInstallDir() {
49020
49182
  const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
49021
- return join62(homeDir, ".cache", "oh-my-opencode", "bin");
49183
+ return join63(homeDir, ".cache", "oh-my-opencode", "bin");
49022
49184
  }
49023
49185
  function getRgPath() {
49024
49186
  const isWindows2 = process.platform === "win32";
49025
- return join62(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
49187
+ return join63(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
49026
49188
  }
49027
49189
  async function extractTarGz2(archivePath, destDir) {
49028
49190
  const platformKey = getPlatformKey();
@@ -49039,7 +49201,7 @@ async function extractZip2(archivePath, destDir) {
49039
49201
  const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
49040
49202
  const foundPath = findFileRecursive(destDir, binaryName);
49041
49203
  if (foundPath) {
49042
- const destPath = join62(destDir, binaryName);
49204
+ const destPath = join63(destDir, binaryName);
49043
49205
  if (foundPath !== destPath) {
49044
49206
  const { renameSync } = await import("fs");
49045
49207
  renameSync(foundPath, destPath);
@@ -49054,13 +49216,13 @@ async function downloadAndInstallRipgrep() {
49054
49216
  }
49055
49217
  const installDir = getInstallDir();
49056
49218
  const rgPath = getRgPath();
49057
- if (existsSync55(rgPath)) {
49219
+ if (existsSync56(rgPath)) {
49058
49220
  return rgPath;
49059
49221
  }
49060
49222
  ensureCacheDir(installDir);
49061
49223
  const filename = `ripgrep-${RG_VERSION}-${config3.platform}.${config3.extension}`;
49062
49224
  const url2 = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
49063
- const archivePath = join62(installDir, filename);
49225
+ const archivePath = join63(installDir, filename);
49064
49226
  try {
49065
49227
  await downloadArchive(url2, archivePath);
49066
49228
  if (config3.extension === "tar.gz") {
@@ -49069,7 +49231,7 @@ async function downloadAndInstallRipgrep() {
49069
49231
  await extractZip2(archivePath, installDir);
49070
49232
  }
49071
49233
  ensureExecutable(rgPath);
49072
- if (!existsSync55(rgPath)) {
49234
+ if (!existsSync56(rgPath)) {
49073
49235
  throw new Error("ripgrep binary not found after extraction");
49074
49236
  }
49075
49237
  return rgPath;
@@ -49081,7 +49243,7 @@ async function downloadAndInstallRipgrep() {
49081
49243
  }
49082
49244
  function getInstalledRipgrepPath() {
49083
49245
  const rgPath = getRgPath();
49084
- return existsSync55(rgPath) ? rgPath : null;
49246
+ return existsSync56(rgPath) ? rgPath : null;
49085
49247
  }
49086
49248
 
49087
49249
  // src/tools/grep/constants.ts
@@ -49105,14 +49267,14 @@ function getOpenCodeBundledRg() {
49105
49267
  const isWindows2 = process.platform === "win32";
49106
49268
  const rgName = isWindows2 ? "rg.exe" : "rg";
49107
49269
  const candidates = [
49108
- join63(getDataDir(), "opencode", "bin", rgName),
49109
- join63(execDir, rgName),
49110
- join63(execDir, "bin", rgName),
49111
- join63(execDir, "..", "bin", rgName),
49112
- join63(execDir, "..", "libexec", rgName)
49270
+ join64(getDataDir(), "opencode", "bin", rgName),
49271
+ join64(execDir, rgName),
49272
+ join64(execDir, "bin", rgName),
49273
+ join64(execDir, "..", "bin", rgName),
49274
+ join64(execDir, "..", "libexec", rgName)
49113
49275
  ];
49114
49276
  for (const candidate of candidates) {
49115
- if (existsSync56(candidate)) {
49277
+ if (existsSync57(candidate)) {
49116
49278
  return candidate;
49117
49279
  }
49118
49280
  }
@@ -49578,20 +49740,20 @@ function createGlobTools(ctx) {
49578
49740
  return { glob };
49579
49741
  }
49580
49742
  // src/tools/slashcommand/command-discovery.ts
49581
- import { existsSync as existsSync57, readdirSync as readdirSync15, readFileSync as readFileSync38 } from "fs";
49582
- import { basename as basename4, join as join64 } from "path";
49743
+ import { existsSync as existsSync58, readdirSync as readdirSync15, readFileSync as readFileSync39 } from "fs";
49744
+ import { basename as basename4, join as join65 } from "path";
49583
49745
  function discoverCommandsFromDir2(commandsDir, scope) {
49584
- if (!existsSync57(commandsDir))
49746
+ if (!existsSync58(commandsDir))
49585
49747
  return [];
49586
49748
  const entries = readdirSync15(commandsDir, { withFileTypes: true });
49587
49749
  const commands2 = [];
49588
49750
  for (const entry of entries) {
49589
49751
  if (!isMarkdownFile(entry))
49590
49752
  continue;
49591
- const commandPath = join64(commandsDir, entry.name);
49753
+ const commandPath = join65(commandsDir, entry.name);
49592
49754
  const commandName = basename4(entry.name, ".md");
49593
49755
  try {
49594
- const content = readFileSync38(commandPath, "utf-8");
49756
+ const content = readFileSync39(commandPath, "utf-8");
49595
49757
  const { data, body } = parseFrontmatter(content);
49596
49758
  const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
49597
49759
  const metadata = {
@@ -49617,10 +49779,10 @@ function discoverCommandsFromDir2(commandsDir, scope) {
49617
49779
  }
49618
49780
  function discoverCommandsSync(directory) {
49619
49781
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
49620
- const userCommandsDir = join64(getClaudeConfigDir(), "commands");
49621
- const projectCommandsDir = join64(directory ?? process.cwd(), ".claude", "commands");
49622
- const opencodeGlobalDir = join64(configDir, "command");
49623
- const opencodeProjectDir = join64(directory ?? process.cwd(), ".opencode", "command");
49782
+ const userCommandsDir = join65(getClaudeConfigDir(), "commands");
49783
+ const projectCommandsDir = join65(directory ?? process.cwd(), ".claude", "commands");
49784
+ const opencodeGlobalDir = join65(configDir, "command");
49785
+ const opencodeProjectDir = join65(directory ?? process.cwd(), ".opencode", "command");
49624
49786
  const userCommands = discoverCommandsFromDir2(userCommandsDir, "user");
49625
49787
  const opencodeGlobalCommands = discoverCommandsFromDir2(opencodeGlobalDir, "opencode");
49626
49788
  const projectCommands = discoverCommandsFromDir2(projectCommandsDir, "project");
@@ -49828,9 +49990,9 @@ Try a different name.`;
49828
49990
  }
49829
49991
  var slashcommand = createSlashcommandTool();
49830
49992
  // src/tools/session-manager/constants.ts
49831
- import { join as join65 } from "path";
49832
- var TODO_DIR2 = join65(getClaudeConfigDir(), "todos");
49833
- var TRANSCRIPT_DIR2 = join65(getClaudeConfigDir(), "transcripts");
49993
+ import { join as join66 } from "path";
49994
+ var TODO_DIR2 = join66(getClaudeConfigDir(), "todos");
49995
+ var TRANSCRIPT_DIR2 = join66(getClaudeConfigDir(), "transcripts");
49834
49996
  var SESSION_LIST_DESCRIPTION = `List all OpenCode sessions with optional filtering.
49835
49997
 
49836
49998
  Returns a list of available session IDs with metadata including message count, date range, and agents used.
@@ -49903,9 +50065,9 @@ Has Todos: Yes (12 items, 8 completed)
49903
50065
  Has Transcript: Yes (234 entries)`;
49904
50066
 
49905
50067
  // src/tools/session-manager/storage.ts
49906
- import { existsSync as existsSync58 } from "fs";
50068
+ import { existsSync as existsSync59 } from "fs";
49907
50069
  import { readdir, readFile } from "fs/promises";
49908
- import { join as join66 } from "path";
50070
+ import { join as join67 } from "path";
49909
50071
  var sdkClient = null;
49910
50072
  function setStorageClient(client2) {
49911
50073
  sdkClient = client2;
@@ -49924,7 +50086,7 @@ async function getMainSessions(options) {
49924
50086
  return [];
49925
50087
  }
49926
50088
  }
49927
- if (!existsSync58(SESSION_STORAGE))
50089
+ if (!existsSync59(SESSION_STORAGE))
49928
50090
  return [];
49929
50091
  const sessions = [];
49930
50092
  try {
@@ -49932,13 +50094,13 @@ async function getMainSessions(options) {
49932
50094
  for (const projectDir of projectDirs) {
49933
50095
  if (!projectDir.isDirectory())
49934
50096
  continue;
49935
- const projectPath = join66(SESSION_STORAGE, projectDir.name);
50097
+ const projectPath = join67(SESSION_STORAGE, projectDir.name);
49936
50098
  const sessionFiles = await readdir(projectPath);
49937
50099
  for (const file2 of sessionFiles) {
49938
50100
  if (!file2.endsWith(".json"))
49939
50101
  continue;
49940
50102
  try {
49941
- const content = await readFile(join66(projectPath, file2), "utf-8");
50103
+ const content = await readFile(join67(projectPath, file2), "utf-8");
49942
50104
  const meta = JSON.parse(content);
49943
50105
  if (meta.parentID)
49944
50106
  continue;
@@ -49965,7 +50127,7 @@ async function getAllSessions() {
49965
50127
  return [];
49966
50128
  }
49967
50129
  }
49968
- if (!existsSync58(MESSAGE_STORAGE))
50130
+ if (!existsSync59(MESSAGE_STORAGE))
49969
50131
  return [];
49970
50132
  const sessions = [];
49971
50133
  async function scanDirectory(dir) {
@@ -49973,7 +50135,7 @@ async function getAllSessions() {
49973
50135
  const entries = await readdir(dir, { withFileTypes: true });
49974
50136
  for (const entry of entries) {
49975
50137
  if (entry.isDirectory()) {
49976
- const sessionPath = join66(dir, entry.name);
50138
+ const sessionPath = join67(dir, entry.name);
49977
50139
  const files = await readdir(sessionPath);
49978
50140
  if (files.some((f) => f.endsWith(".json"))) {
49979
50141
  sessions.push(entry.name);
@@ -50034,7 +50196,7 @@ async function readSessionMessages(sessionID) {
50034
50196
  }
50035
50197
  }
50036
50198
  const messageDir = getMessageDir(sessionID);
50037
- if (!messageDir || !existsSync58(messageDir))
50199
+ if (!messageDir || !existsSync59(messageDir))
50038
50200
  return [];
50039
50201
  const messages = [];
50040
50202
  try {
@@ -50043,7 +50205,7 @@ async function readSessionMessages(sessionID) {
50043
50205
  if (!file2.endsWith(".json"))
50044
50206
  continue;
50045
50207
  try {
50046
- const content = await readFile(join66(messageDir, file2), "utf-8");
50208
+ const content = await readFile(join67(messageDir, file2), "utf-8");
50047
50209
  const meta = JSON.parse(content);
50048
50210
  const parts = await readParts2(meta.id);
50049
50211
  messages.push({
@@ -50069,8 +50231,8 @@ async function readSessionMessages(sessionID) {
50069
50231
  });
50070
50232
  }
50071
50233
  async function readParts2(messageID) {
50072
- const partDir = join66(PART_STORAGE, messageID);
50073
- if (!existsSync58(partDir))
50234
+ const partDir = join67(PART_STORAGE, messageID);
50235
+ if (!existsSync59(partDir))
50074
50236
  return [];
50075
50237
  const parts = [];
50076
50238
  try {
@@ -50079,7 +50241,7 @@ async function readParts2(messageID) {
50079
50241
  if (!file2.endsWith(".json"))
50080
50242
  continue;
50081
50243
  try {
50082
- const content = await readFile(join66(partDir, file2), "utf-8");
50244
+ const content = await readFile(join67(partDir, file2), "utf-8");
50083
50245
  parts.push(JSON.parse(content));
50084
50246
  } catch {
50085
50247
  continue;
@@ -50105,14 +50267,14 @@ async function readSessionTodos(sessionID) {
50105
50267
  return [];
50106
50268
  }
50107
50269
  }
50108
- if (!existsSync58(TODO_DIR2))
50270
+ if (!existsSync59(TODO_DIR2))
50109
50271
  return [];
50110
50272
  try {
50111
50273
  const allFiles = await readdir(TODO_DIR2);
50112
50274
  const todoFiles = allFiles.filter((f) => f.includes(sessionID) && f.endsWith(".json"));
50113
50275
  for (const file2 of todoFiles) {
50114
50276
  try {
50115
- const content = await readFile(join66(TODO_DIR2, file2), "utf-8");
50277
+ const content = await readFile(join67(TODO_DIR2, file2), "utf-8");
50116
50278
  const data = JSON.parse(content);
50117
50279
  if (Array.isArray(data)) {
50118
50280
  return data.map((item) => ({
@@ -50132,10 +50294,10 @@ async function readSessionTodos(sessionID) {
50132
50294
  return [];
50133
50295
  }
50134
50296
  async function readSessionTranscript(sessionID) {
50135
- if (!existsSync58(TRANSCRIPT_DIR2))
50297
+ if (!existsSync59(TRANSCRIPT_DIR2))
50136
50298
  return 0;
50137
- const transcriptFile = join66(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
50138
- if (!existsSync58(transcriptFile))
50299
+ const transcriptFile = join67(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
50300
+ if (!existsSync59(transcriptFile))
50139
50301
  return 0;
50140
50302
  try {
50141
50303
  const content = await readFile(transcriptFile, "utf-8");
@@ -53731,7 +53893,7 @@ Prompts MUST be in English.`;
53731
53893
  // src/tools/delegate-task/index.ts
53732
53894
  init_constants();
53733
53895
  // src/tools/task/task-create.ts
53734
- import { join as join68 } from "path";
53896
+ import { join as join69 } from "path";
53735
53897
 
53736
53898
  // src/tools/task/types.ts
53737
53899
  var TaskStatusSchema = exports_external.enum(["pending", "in_progress", "completed", "deleted"]);
@@ -53785,18 +53947,18 @@ var TaskDeleteInputSchema = exports_external.object({
53785
53947
  });
53786
53948
 
53787
53949
  // src/features/claude-tasks/storage.ts
53788
- import { join as join67, dirname as dirname19, basename as basename6, isAbsolute as isAbsolute6 } from "path";
53789
- import { existsSync as existsSync59, mkdirSync as mkdirSync13, readFileSync as readFileSync39, writeFileSync as writeFileSync18, renameSync, unlinkSync as unlinkSync9, readdirSync as readdirSync16 } from "fs";
53950
+ import { join as join68, dirname as dirname19, basename as basename6, isAbsolute as isAbsolute6 } from "path";
53951
+ import { existsSync as existsSync60, mkdirSync as mkdirSync14, readFileSync as readFileSync40, writeFileSync as writeFileSync19, renameSync, unlinkSync as unlinkSync9, readdirSync as readdirSync16 } from "fs";
53790
53952
  import { randomUUID as randomUUID2 } from "crypto";
53791
53953
  function getTaskDir(config3 = {}) {
53792
53954
  const tasksConfig = config3.sisyphus?.tasks;
53793
53955
  const storagePath = tasksConfig?.storage_path;
53794
53956
  if (storagePath) {
53795
- return isAbsolute6(storagePath) ? storagePath : join67(process.cwd(), storagePath);
53957
+ return isAbsolute6(storagePath) ? storagePath : join68(process.cwd(), storagePath);
53796
53958
  }
53797
53959
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
53798
53960
  const listId = resolveTaskListId(config3);
53799
- return join67(configDir, "tasks", listId);
53961
+ return join68(configDir, "tasks", listId);
53800
53962
  }
53801
53963
  function sanitizePathSegment(value) {
53802
53964
  return value.replace(/[^a-zA-Z0-9_-]/g, "-") || "default";
@@ -53814,16 +53976,16 @@ function resolveTaskListId(config3 = {}) {
53814
53976
  return sanitizePathSegment(basename6(process.cwd()));
53815
53977
  }
53816
53978
  function ensureDir(dirPath) {
53817
- if (!existsSync59(dirPath)) {
53818
- mkdirSync13(dirPath, { recursive: true });
53979
+ if (!existsSync60(dirPath)) {
53980
+ mkdirSync14(dirPath, { recursive: true });
53819
53981
  }
53820
53982
  }
53821
53983
  function readJsonSafe(filePath, schema2) {
53822
53984
  try {
53823
- if (!existsSync59(filePath)) {
53985
+ if (!existsSync60(filePath)) {
53824
53986
  return null;
53825
53987
  }
53826
- const content = readFileSync39(filePath, "utf-8");
53988
+ const content = readFileSync40(filePath, "utf-8");
53827
53989
  const parsed = JSON.parse(content);
53828
53990
  const result = schema2.safeParse(parsed);
53829
53991
  if (!result.success) {
@@ -53839,11 +54001,11 @@ function writeJsonAtomic(filePath, data) {
53839
54001
  ensureDir(dir);
53840
54002
  const tempPath = `${filePath}.tmp.${Date.now()}`;
53841
54003
  try {
53842
- writeFileSync18(tempPath, JSON.stringify(data, null, 2), "utf-8");
54004
+ writeFileSync19(tempPath, JSON.stringify(data, null, 2), "utf-8");
53843
54005
  renameSync(tempPath, filePath);
53844
54006
  } catch (error45) {
53845
54007
  try {
53846
- if (existsSync59(tempPath)) {
54008
+ if (existsSync60(tempPath)) {
53847
54009
  unlinkSync9(tempPath);
53848
54010
  }
53849
54011
  } catch {}
@@ -53855,17 +54017,17 @@ function generateTaskId() {
53855
54017
  return `T-${randomUUID2()}`;
53856
54018
  }
53857
54019
  function acquireLock(dirPath) {
53858
- const lockPath = join67(dirPath, ".lock");
54020
+ const lockPath = join68(dirPath, ".lock");
53859
54021
  const lockId = randomUUID2();
53860
54022
  const createLock = (timestamp2) => {
53861
- writeFileSync18(lockPath, JSON.stringify({ id: lockId, timestamp: timestamp2 }), {
54023
+ writeFileSync19(lockPath, JSON.stringify({ id: lockId, timestamp: timestamp2 }), {
53862
54024
  encoding: "utf-8",
53863
54025
  flag: "wx"
53864
54026
  });
53865
54027
  };
53866
54028
  const isStale = () => {
53867
54029
  try {
53868
- const lockContent = readFileSync39(lockPath, "utf-8");
54030
+ const lockContent = readFileSync40(lockPath, "utf-8");
53869
54031
  const lockData = JSON.parse(lockContent);
53870
54032
  const lockAge = Date.now() - lockData.timestamp;
53871
54033
  return lockAge > STALE_LOCK_THRESHOLD_MS;
@@ -53903,9 +54065,9 @@ function acquireLock(dirPath) {
53903
54065
  acquired: true,
53904
54066
  release: () => {
53905
54067
  try {
53906
- if (!existsSync59(lockPath))
54068
+ if (!existsSync60(lockPath))
53907
54069
  return;
53908
- const lockContent = readFileSync39(lockPath, "utf-8");
54070
+ const lockContent = readFileSync40(lockPath, "utf-8");
53909
54071
  const lockData = JSON.parse(lockContent);
53910
54072
  if (lockData.id !== lockId)
53911
54073
  return;
@@ -54068,7 +54230,7 @@ async function handleCreate(args, config3, ctx, context) {
54068
54230
  threadID: context.sessionID
54069
54231
  };
54070
54232
  const validatedTask = TaskObjectSchema.parse(task);
54071
- writeJsonAtomic(join68(taskDir, `${taskId}.json`), validatedTask);
54233
+ writeJsonAtomic(join69(taskDir, `${taskId}.json`), validatedTask);
54072
54234
  await syncTaskTodoUpdate(ctx, validatedTask, context.sessionID);
54073
54235
  return JSON.stringify({
54074
54236
  task: {
@@ -54090,7 +54252,7 @@ async function handleCreate(args, config3, ctx, context) {
54090
54252
  }
54091
54253
  }
54092
54254
  // src/tools/task/task-get.ts
54093
- import { join as join69 } from "path";
54255
+ import { join as join70 } from "path";
54094
54256
  var TASK_ID_PATTERN = /^T-[A-Za-z0-9-]+$/;
54095
54257
  function parseTaskId(id) {
54096
54258
  if (!TASK_ID_PATTERN.test(id))
@@ -54115,7 +54277,7 @@ Returns null if the task does not exist or the file is invalid.`,
54115
54277
  return JSON.stringify({ error: "invalid_task_id" });
54116
54278
  }
54117
54279
  const taskDir = getTaskDir(config3);
54118
- const taskPath = join69(taskDir, `${taskId}.json`);
54280
+ const taskPath = join70(taskDir, `${taskId}.json`);
54119
54281
  const task = readJsonSafe(taskPath, TaskObjectSchema);
54120
54282
  return JSON.stringify({ task: task ?? null });
54121
54283
  } catch (error45) {
@@ -54128,8 +54290,8 @@ Returns null if the task does not exist or the file is invalid.`,
54128
54290
  });
54129
54291
  }
54130
54292
  // src/tools/task/task-list.ts
54131
- import { join as join70 } from "path";
54132
- import { existsSync as existsSync60, readdirSync as readdirSync17 } from "fs";
54293
+ import { join as join71 } from "path";
54294
+ import { existsSync as existsSync61, readdirSync as readdirSync17 } from "fs";
54133
54295
  function createTaskList(config3) {
54134
54296
  return tool({
54135
54297
  description: `List all active tasks with summary information.
@@ -54140,7 +54302,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
54140
54302
  args: {},
54141
54303
  execute: async () => {
54142
54304
  const taskDir = getTaskDir(config3);
54143
- if (!existsSync60(taskDir)) {
54305
+ if (!existsSync61(taskDir)) {
54144
54306
  return JSON.stringify({ tasks: [] });
54145
54307
  }
54146
54308
  const files = readdirSync17(taskDir).filter((f) => f.endsWith(".json") && f.startsWith("T-")).map((f) => f.replace(".json", ""));
@@ -54149,7 +54311,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
54149
54311
  }
54150
54312
  const allTasks = [];
54151
54313
  for (const fileId of files) {
54152
- const task = readJsonSafe(join70(taskDir, `${fileId}.json`), TaskObjectSchema);
54314
+ const task = readJsonSafe(join71(taskDir, `${fileId}.json`), TaskObjectSchema);
54153
54315
  if (task) {
54154
54316
  allTasks.push(task);
54155
54317
  }
@@ -54176,7 +54338,7 @@ Returns summary format: id, subject, status, owner, blockedBy (not full descript
54176
54338
  });
54177
54339
  }
54178
54340
  // src/tools/task/task-update.ts
54179
- import { join as join71 } from "path";
54341
+ import { join as join72 } from "path";
54180
54342
  var TASK_ID_PATTERN2 = /^T-[A-Za-z0-9-]+$/;
54181
54343
  function parseTaskId2(id) {
54182
54344
  if (!TASK_ID_PATTERN2.test(id))
@@ -54224,7 +54386,7 @@ async function handleUpdate(args, config3, ctx, context) {
54224
54386
  return JSON.stringify({ error: "task_lock_unavailable" });
54225
54387
  }
54226
54388
  try {
54227
- const taskPath = join71(taskDir, `${taskId}.json`);
54389
+ const taskPath = join72(taskDir, `${taskId}.json`);
54228
54390
  const task = readJsonSafe(taskPath, TaskObjectSchema);
54229
54391
  if (!task) {
54230
54392
  return JSON.stringify({ error: "task_not_found" });
@@ -54544,10 +54706,12 @@ function createSessionHooks(args) {
54544
54706
  checkSessionExists: async (sessionId) => await sessionExists(sessionId)
54545
54707
  })) : null;
54546
54708
  const editErrorRecovery = isHookEnabled("edit-error-recovery") ? safeHook("edit-error-recovery", () => createEditErrorRecoveryHook(ctx)) : null;
54709
+ const jsonErrorRecovery = isHookEnabled("json-error-recovery") ? safeHook("json-error-recovery", () => createJsonErrorRecoveryHook(ctx)) : null;
54547
54710
  const delegateTaskRetry = isHookEnabled("delegate-task-retry") ? safeHook("delegate-task-retry", () => createDelegateTaskRetryHook(ctx)) : null;
54548
54711
  const startWork = isHookEnabled("start-work") ? safeHook("start-work", () => createStartWorkHook(ctx)) : null;
54549
54712
  const prometheusMdOnly = isHookEnabled("prometheus-md-only") ? safeHook("prometheus-md-only", () => createPrometheusMdOnlyHook(ctx)) : null;
54550
54713
  const sisyphusJuniorNotepad = isHookEnabled("sisyphus-junior-notepad") ? safeHook("sisyphus-junior-notepad", () => createSisyphusJuniorNotepadHook(ctx)) : null;
54714
+ const sisyphusGptHephaestusReminder = isHookEnabled("sisyphus-gpt-hephaestus-reminder") ? safeHook("sisyphus-gpt-hephaestus-reminder", () => createSisyphusGptHephaestusReminderHook(ctx)) : null;
54551
54715
  const questionLabelTruncator = createQuestionLabelTruncatorHook();
54552
54716
  const taskResumeInfo = createTaskResumeInfoHook();
54553
54717
  const anthropicEffort = isHookEnabled("anthropic-effort") ? safeHook("anthropic-effort", () => createAnthropicEffortHook()) : null;
@@ -54564,10 +54728,12 @@ function createSessionHooks(args) {
54564
54728
  interactiveBashSession,
54565
54729
  ralphLoop,
54566
54730
  editErrorRecovery,
54731
+ jsonErrorRecovery,
54567
54732
  delegateTaskRetry,
54568
54733
  startWork,
54569
54734
  prometheusMdOnly,
54570
54735
  sisyphusJuniorNotepad,
54736
+ sisyphusGptHephaestusReminder,
54571
54737
  questionLabelTruncator,
54572
54738
  taskResumeInfo,
54573
54739
  anthropicEffort
@@ -55106,8 +55272,8 @@ var POLLING_INTERVAL_MS = 3000;
55106
55272
  var TASK_CLEANUP_DELAY_MS = 10 * 60 * 1000;
55107
55273
 
55108
55274
  // src/features/background-agent/manager.ts
55109
- import { existsSync as existsSync61, readFileSync as readFileSync40, readdirSync as readdirSync18 } from "fs";
55110
- import { join as join72 } from "path";
55275
+ import { existsSync as existsSync62, readFileSync as readFileSync41, readdirSync as readdirSync18 } from "fs";
55276
+ import { join as join73 } from "path";
55111
55277
 
55112
55278
  class BackgroundManager {
55113
55279
  static cleanupManagers = new Set;
@@ -56396,14 +56562,14 @@ function registerProcessSignal(signal, handler, exitAfter) {
56396
56562
  return listener;
56397
56563
  }
56398
56564
  function getMessageDir2(sessionID) {
56399
- if (!existsSync61(MESSAGE_STORAGE))
56565
+ if (!existsSync62(MESSAGE_STORAGE))
56400
56566
  return null;
56401
- const directPath = join72(MESSAGE_STORAGE, sessionID);
56402
- if (existsSync61(directPath))
56567
+ const directPath = join73(MESSAGE_STORAGE, sessionID);
56568
+ if (existsSync62(directPath))
56403
56569
  return directPath;
56404
56570
  for (const dir of readdirSync18(MESSAGE_STORAGE)) {
56405
- const sessionPath = join72(MESSAGE_STORAGE, dir, sessionID);
56406
- if (existsSync61(sessionPath))
56571
+ const sessionPath = join73(MESSAGE_STORAGE, dir, sessionID);
56572
+ if (existsSync62(sessionPath))
56407
56573
  return sessionPath;
56408
56574
  }
56409
56575
  return null;
@@ -56424,7 +56590,7 @@ function findNearestMessageExcludingCompaction(messageDir) {
56424
56590
  const files = readdirSync18(messageDir).filter((name) => name.endsWith(".json")).sort().reverse();
56425
56591
  for (const file2 of files) {
56426
56592
  try {
56427
- const content = readFileSync40(join72(messageDir, file2), "utf-8");
56593
+ const content = readFileSync41(join73(messageDir, file2), "utf-8");
56428
56594
  const parsed = JSON.parse(content);
56429
56595
  if (hasFullAgentAndModel(parsed)) {
56430
56596
  return parsed;
@@ -56435,7 +56601,7 @@ function findNearestMessageExcludingCompaction(messageDir) {
56435
56601
  }
56436
56602
  for (const file2 of files) {
56437
56603
  try {
56438
- const content = readFileSync40(join72(messageDir, file2), "utf-8");
56604
+ const content = readFileSync41(join73(messageDir, file2), "utf-8");
56439
56605
  const parsed = JSON.parse(content);
56440
56606
  if (hasPartialAgentOrModel(parsed)) {
56441
56607
  return parsed;
@@ -60434,11 +60600,11 @@ class StreamableHTTPClientTransport {
60434
60600
  }
60435
60601
 
60436
60602
  // src/features/mcp-oauth/storage.ts
60437
- import { chmodSync as chmodSync2, existsSync as existsSync62, mkdirSync as mkdirSync14, readFileSync as readFileSync41, unlinkSync as unlinkSync10, writeFileSync as writeFileSync19 } from "fs";
60438
- import { dirname as dirname20, join as join73 } from "path";
60603
+ import { chmodSync as chmodSync2, existsSync as existsSync63, mkdirSync as mkdirSync15, readFileSync as readFileSync42, unlinkSync as unlinkSync10, writeFileSync as writeFileSync20 } from "fs";
60604
+ import { dirname as dirname20, join as join74 } from "path";
60439
60605
  var STORAGE_FILE_NAME = "mcp-oauth.json";
60440
60606
  function getMcpOauthStoragePath() {
60441
- return join73(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
60607
+ return join74(getOpenCodeConfigDir({ binary: "opencode" }), STORAGE_FILE_NAME);
60442
60608
  }
60443
60609
  function normalizeHost(serverHost) {
60444
60610
  let host = serverHost.trim();
@@ -60475,11 +60641,11 @@ function buildKey(serverHost, resource) {
60475
60641
  }
60476
60642
  function readStore() {
60477
60643
  const filePath = getMcpOauthStoragePath();
60478
- if (!existsSync62(filePath)) {
60644
+ if (!existsSync63(filePath)) {
60479
60645
  return null;
60480
60646
  }
60481
60647
  try {
60482
- const content = readFileSync41(filePath, "utf-8");
60648
+ const content = readFileSync42(filePath, "utf-8");
60483
60649
  return JSON.parse(content);
60484
60650
  } catch {
60485
60651
  return null;
@@ -60489,10 +60655,10 @@ function writeStore(store2) {
60489
60655
  const filePath = getMcpOauthStoragePath();
60490
60656
  try {
60491
60657
  const dir = dirname20(filePath);
60492
- if (!existsSync62(dir)) {
60493
- mkdirSync14(dir, { recursive: true });
60658
+ if (!existsSync63(dir)) {
60659
+ mkdirSync15(dir, { recursive: true });
60494
60660
  }
60495
- writeFileSync19(filePath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
60661
+ writeFileSync20(filePath, JSON.stringify(store2, null, 2), { encoding: "utf-8", mode: 384 });
60496
60662
  chmodSync2(filePath, 384);
60497
60663
  return true;
60498
60664
  } catch {
@@ -60658,29 +60824,9 @@ function isRecord4(value) {
60658
60824
 
60659
60825
  // src/features/mcp-oauth/callback-server.ts
60660
60826
  var DEFAULT_PORT = 19877;
60661
- var MAX_PORT_ATTEMPTS = 20;
60662
60827
  var TIMEOUT_MS = 5 * 60 * 1000;
60663
- async function isPortAvailable(port) {
60664
- try {
60665
- const server = Bun.serve({
60666
- port,
60667
- hostname: "127.0.0.1",
60668
- fetch: () => new Response
60669
- });
60670
- server.stop(true);
60671
- return true;
60672
- } catch {
60673
- return false;
60674
- }
60675
- }
60676
- async function findAvailablePort(startPort = DEFAULT_PORT) {
60677
- for (let attempt = 0;attempt < MAX_PORT_ATTEMPTS; attempt++) {
60678
- const port = startPort + attempt;
60679
- if (await isPortAvailable(port)) {
60680
- return port;
60681
- }
60682
- }
60683
- throw new Error(`No available port found in range ${startPort}-${startPort + MAX_PORT_ATTEMPTS - 1}`);
60828
+ async function findAvailablePort2(startPort = DEFAULT_PORT) {
60829
+ return findAvailablePort(startPort);
60684
60830
  }
60685
60831
 
60686
60832
  // src/features/mcp-oauth/oauth-authorization-flow.ts
@@ -60835,7 +60981,7 @@ class McpOAuthProvider {
60835
60981
  throw new Error("No client information available. Run login() or register a client first.");
60836
60982
  }
60837
60983
  if (this.callbackPort === null) {
60838
- this.callbackPort = await findAvailablePort();
60984
+ this.callbackPort = await findAvailablePort2();
60839
60985
  }
60840
60986
  const result = await runAuthorizationCodeRedirect({
60841
60987
  authorizationEndpoint: metadata.authorizationEndpoint,
@@ -65699,7 +65845,7 @@ function buildAgent(source, model, categories, gitMasterConfig, browserProvider,
65699
65845
  }
65700
65846
 
65701
65847
  // src/agents/builtin-agents/resolve-file-uri.ts
65702
- import { existsSync as existsSync63, readFileSync as readFileSync42 } from "fs";
65848
+ import { existsSync as existsSync64, readFileSync as readFileSync43 } from "fs";
65703
65849
  import { homedir as homedir13 } from "os";
65704
65850
  import { isAbsolute as isAbsolute7, resolve as resolve10 } from "path";
65705
65851
  function resolvePromptAppend(promptAppend, configDir) {
@@ -65714,11 +65860,11 @@ function resolvePromptAppend(promptAppend, configDir) {
65714
65860
  } catch {
65715
65861
  return `[WARNING: Malformed file URI (invalid percent-encoding): ${promptAppend}]`;
65716
65862
  }
65717
- if (!existsSync63(filePath)) {
65863
+ if (!existsSync64(filePath)) {
65718
65864
  return `[WARNING: Could not resolve file URI: ${promptAppend}]`;
65719
65865
  }
65720
65866
  try {
65721
- return readFileSync42(filePath, "utf8");
65867
+ return readFileSync43(filePath, "utf8");
65722
65868
  } catch {
65723
65869
  return `[WARNING: Could not read file: ${promptAppend}]`;
65724
65870
  }
@@ -66360,47 +66506,71 @@ unblocking maximum parallelism in subsequent waves.
66360
66506
 
66361
66507
  **The plan can have 50+ TODOs. That's OK. ONE PLAN.**
66362
66508
 
66363
- ### 6.1 SINGLE ATOMIC WRITE (CRITICAL - Prevents Content Loss)
66509
+ ### 6.1 INCREMENTAL WRITE PROTOCOL (CRITICAL - Prevents Output Limit Stalls)
66364
66510
 
66365
66511
  <write_protocol>
66366
- **The Write tool OVERWRITES files. It does NOT append.**
66512
+ **Write OVERWRITES. Never call Write twice on the same file.**
66367
66513
 
66368
- **MANDATORY PROTOCOL:**
66369
- 1. **Prepare ENTIRE plan content in memory FIRST**
66370
- 2. **Write ONCE with complete content**
66371
- 3. **NEVER split into multiple Write calls**
66514
+ Plans with many tasks will exceed your output token limit if you try to generate everything at once.
66515
+ Split into: **one Write** (skeleton) + **multiple Edits** (tasks in batches).
66372
66516
 
66373
- **IF plan is too large for single output:**
66374
- 1. First Write: Create file with initial sections (TL;DR through first TODOs)
66375
- 2. Subsequent: Use **Edit tool** to APPEND remaining sections
66376
- - Target the END of the file
66377
- - Edit replaces text, so include last line + new content
66517
+ **Step 1 \u2014 Write skeleton (all sections EXCEPT individual task details):**
66378
66518
 
66379
- **FORBIDDEN (causes content loss):**
66380
66519
  \`\`\`
66381
- \u274C Write(".sisyphus/plans/x.md", "# Part 1...")
66382
- \u274C Write(".sisyphus/plans/x.md", "# Part 2...") // Part 1 is GONE!
66383
- \`\`\`
66384
-
66385
- **CORRECT (preserves content):**
66386
- \`\`\`
66387
- \u2705 Write(".sisyphus/plans/x.md", "# Complete plan content...") // Single write
66520
+ Write(".sisyphus/plans/{name}.md", content=\`
66521
+ # {Plan Title}
66388
66522
 
66389
- // OR if too large:
66390
- \u2705 Write(".sisyphus/plans/x.md", "# Plan
66391
66523
  ## TL;DR
66392
- ...") // First chunk
66393
- \u2705 Edit(".sisyphus/plans/x.md", oldString="---
66394
- ## Success Criteria", newString="---
66395
- ## More TODOs
66524
+ > ...
66525
+
66526
+ ## Context
66527
+ ...
66528
+
66529
+ ## Work Objectives
66530
+ ...
66531
+
66532
+ ## Verification Strategy
66396
66533
  ...
66534
+
66535
+ ## Execution Strategy
66536
+ ...
66537
+
66397
66538
  ---
66398
- ## Success Criteria") // Append via Edit
66539
+
66540
+ ## TODOs
66541
+
66542
+ ---
66543
+
66544
+ ## Final Verification Wave
66545
+ ...
66546
+
66547
+ ## Commit Strategy
66548
+ ...
66549
+
66550
+ ## Success Criteria
66551
+ ...
66552
+ \`)
66399
66553
  \`\`\`
66400
66554
 
66401
- **SELF-CHECK before Write:**
66402
- - [ ] Is this the FIRST write to this file? \u2192 Write is OK
66403
- - [ ] File already exists with my content? \u2192 Use Edit to append, NOT Write
66555
+ **Step 2 \u2014 Edit-append tasks in batches of 2-4:**
66556
+
66557
+ Use Edit to insert each batch of tasks before the Final Verification section:
66558
+
66559
+ \`\`\`
66560
+ Edit(".sisyphus/plans/{name}.md",
66561
+ oldString="---\\n\\n## Final Verification Wave",
66562
+ newString="- [ ] 1. Task Title\\n\\n **What to do**: ...\\n **QA Scenarios**: ...\\n\\n- [ ] 2. Task Title\\n\\n **What to do**: ...\\n **QA Scenarios**: ...\\n\\n---\\n\\n## Final Verification Wave")
66563
+ \`\`\`
66564
+
66565
+ Repeat until all tasks are written. 2-4 tasks per Edit call balances speed and output limits.
66566
+
66567
+ **Step 3 \u2014 Verify completeness:**
66568
+
66569
+ After all Edits, Read the plan file to confirm all tasks are present and no content was lost.
66570
+
66571
+ **FORBIDDEN:**
66572
+ - \`Write()\` twice to the same file \u2014 second call erases the first
66573
+ - Generating ALL tasks in a single Write \u2014 hits output limits, causes stalls
66404
66574
  </write_protocol>
66405
66575
 
66406
66576
  ### 7. DRAFT AS WORKING MEMORY (MANDATORY)
@@ -67823,8 +67993,8 @@ function createSisyphusJuniorAgentWithOverrides(override, systemDefaultModel, us
67823
67993
  }
67824
67994
  createSisyphusJuniorAgentWithOverrides.mode = MODE10;
67825
67995
  // src/features/claude-code-agent-loader/loader.ts
67826
- import { existsSync as existsSync64, readdirSync as readdirSync19, readFileSync as readFileSync43 } from "fs";
67827
- import { join as join74, basename as basename7 } from "path";
67996
+ import { existsSync as existsSync65, readdirSync as readdirSync19, readFileSync as readFileSync44 } from "fs";
67997
+ import { join as join75, basename as basename7 } from "path";
67828
67998
  function parseToolsConfig(toolsStr) {
67829
67999
  if (!toolsStr)
67830
68000
  return;
@@ -67838,7 +68008,7 @@ function parseToolsConfig(toolsStr) {
67838
68008
  return result;
67839
68009
  }
67840
68010
  function loadAgentsFromDir(agentsDir, scope) {
67841
- if (!existsSync64(agentsDir)) {
68011
+ if (!existsSync65(agentsDir)) {
67842
68012
  return [];
67843
68013
  }
67844
68014
  const entries = readdirSync19(agentsDir, { withFileTypes: true });
@@ -67846,10 +68016,10 @@ function loadAgentsFromDir(agentsDir, scope) {
67846
68016
  for (const entry of entries) {
67847
68017
  if (!isMarkdownFile(entry))
67848
68018
  continue;
67849
- const agentPath = join74(agentsDir, entry.name);
68019
+ const agentPath = join75(agentsDir, entry.name);
67850
68020
  const agentName = basename7(entry.name, ".md");
67851
68021
  try {
67852
- const content = readFileSync43(agentPath, "utf-8");
68022
+ const content = readFileSync44(agentPath, "utf-8");
67853
68023
  const { data, body } = parseFrontmatter(content);
67854
68024
  const name = data.name || agentName;
67855
68025
  const originalDescription = data.description || "";
@@ -67876,7 +68046,7 @@ function loadAgentsFromDir(agentsDir, scope) {
67876
68046
  return agents;
67877
68047
  }
67878
68048
  function loadUserAgents() {
67879
- const userAgentsDir = join74(getClaudeConfigDir(), "agents");
68049
+ const userAgentsDir = join75(getClaudeConfigDir(), "agents");
67880
68050
  const agents = loadAgentsFromDir(userAgentsDir, "user");
67881
68051
  const result = {};
67882
68052
  for (const agent of agents) {
@@ -67885,7 +68055,7 @@ function loadUserAgents() {
67885
68055
  return result;
67886
68056
  }
67887
68057
  function loadProjectAgents(directory) {
67888
- const projectAgentsDir = join74(directory ?? process.cwd(), ".claude", "agents");
68058
+ const projectAgentsDir = join75(directory ?? process.cwd(), ".claude", "agents");
67889
68059
  const agents = loadAgentsFromDir(projectAgentsDir, "project");
67890
68060
  const result = {};
67891
68061
  for (const agent of agents) {
@@ -68017,9 +68187,12 @@ function buildPlanDemoteConfig(prometheusConfig, planOverride) {
68017
68187
  }
68018
68188
 
68019
68189
  // src/plugin-handlers/agent-config-handler.ts
68020
- function hasConfiguredDefaultAgent(config3) {
68190
+ function getConfiguredDefaultAgent(config3) {
68021
68191
  const defaultAgent = config3.default_agent;
68022
- return typeof defaultAgent === "string" && defaultAgent.trim().length > 0;
68192
+ if (typeof defaultAgent !== "string")
68193
+ return;
68194
+ const trimmedDefaultAgent = defaultAgent.trim();
68195
+ return trimmedDefaultAgent.length > 0 ? trimmedDefaultAgent : undefined;
68023
68196
  }
68024
68197
  async function applyAgentConfig(params) {
68025
68198
  const migratedDisabledAgents = (params.pluginConfig.disabled_agents ?? []).map((agent) => {
@@ -68067,9 +68240,12 @@ async function applyAgentConfig(params) {
68067
68240
  const plannerEnabled = params.pluginConfig.sisyphus_agent?.planner_enabled ?? true;
68068
68241
  const replacePlan = params.pluginConfig.sisyphus_agent?.replace_plan ?? true;
68069
68242
  const shouldDemotePlan = plannerEnabled && replacePlan;
68243
+ const configuredDefaultAgent = getConfiguredDefaultAgent(params.config);
68070
68244
  const configAgent = params.config.agent;
68071
68245
  if (isSisyphusEnabled && builtinAgents.sisyphus) {
68072
- if (!hasConfiguredDefaultAgent(params.config)) {
68246
+ if (configuredDefaultAgent) {
68247
+ params.config.default_agent = getAgentDisplayName(configuredDefaultAgent);
68248
+ } else {
68073
68249
  params.config.default_agent = getAgentDisplayName("sisyphus");
68074
68250
  }
68075
68251
  const agentConfig = {
@@ -68138,7 +68314,7 @@ async function applyAgentConfig(params) {
68138
68314
  }
68139
68315
  // src/features/claude-code-command-loader/loader.ts
68140
68316
  import { promises as fs18 } from "fs";
68141
- import { join as join75, basename as basename8 } from "path";
68317
+ import { join as join76, basename as basename8 } from "path";
68142
68318
  init_logger();
68143
68319
  async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix = "") {
68144
68320
  try {
@@ -68169,7 +68345,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
68169
68345
  if (entry.isDirectory()) {
68170
68346
  if (entry.name.startsWith("."))
68171
68347
  continue;
68172
- const subDirPath = join75(commandsDir, entry.name);
68348
+ const subDirPath = join76(commandsDir, entry.name);
68173
68349
  const subPrefix = prefix ? `${prefix}:${entry.name}` : entry.name;
68174
68350
  const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
68175
68351
  commands2.push(...subCommands);
@@ -68177,7 +68353,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
68177
68353
  }
68178
68354
  if (!isMarkdownFile(entry))
68179
68355
  continue;
68180
- const commandPath = join75(commandsDir, entry.name);
68356
+ const commandPath = join76(commandsDir, entry.name);
68181
68357
  const baseCommandName = basename8(entry.name, ".md");
68182
68358
  const commandName = prefix ? `${prefix}:${baseCommandName}` : baseCommandName;
68183
68359
  try {
@@ -68224,23 +68400,23 @@ function commandsToRecord(commands2) {
68224
68400
  return result;
68225
68401
  }
68226
68402
  async function loadUserCommands() {
68227
- const userCommandsDir = join75(getClaudeConfigDir(), "commands");
68403
+ const userCommandsDir = join76(getClaudeConfigDir(), "commands");
68228
68404
  const commands2 = await loadCommandsFromDir(userCommandsDir, "user");
68229
68405
  return commandsToRecord(commands2);
68230
68406
  }
68231
68407
  async function loadProjectCommands(directory) {
68232
- const projectCommandsDir = join75(directory ?? process.cwd(), ".claude", "commands");
68408
+ const projectCommandsDir = join76(directory ?? process.cwd(), ".claude", "commands");
68233
68409
  const commands2 = await loadCommandsFromDir(projectCommandsDir, "project");
68234
68410
  return commandsToRecord(commands2);
68235
68411
  }
68236
68412
  async function loadOpencodeGlobalCommands() {
68237
68413
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
68238
- const opencodeCommandsDir = join75(configDir, "command");
68414
+ const opencodeCommandsDir = join76(configDir, "command");
68239
68415
  const commands2 = await loadCommandsFromDir(opencodeCommandsDir, "opencode");
68240
68416
  return commandsToRecord(commands2);
68241
68417
  }
68242
68418
  async function loadOpencodeProjectCommands(directory) {
68243
- const opencodeProjectDir = join75(directory ?? process.cwd(), ".opencode", "command");
68419
+ const opencodeProjectDir = join76(directory ?? process.cwd(), ".opencode", "command");
68244
68420
  const commands2 = await loadCommandsFromDir(opencodeProjectDir, "opencode-project");
68245
68421
  return commandsToRecord(commands2);
68246
68422
  }
@@ -68299,8 +68475,8 @@ function remapCommandAgentFields(commands2) {
68299
68475
  }
68300
68476
  }
68301
68477
  // src/features/claude-code-mcp-loader/loader.ts
68302
- import { existsSync as existsSync65, readFileSync as readFileSync44 } from "fs";
68303
- import { join as join76 } from "path";
68478
+ import { existsSync as existsSync66, readFileSync as readFileSync45 } from "fs";
68479
+ import { join as join77 } from "path";
68304
68480
  import { homedir as homedir14 } from "os";
68305
68481
 
68306
68482
  // src/features/claude-code-mcp-loader/transformer.ts
@@ -68342,14 +68518,14 @@ function getMcpConfigPaths() {
68342
68518
  const claudeConfigDir = getClaudeConfigDir();
68343
68519
  const cwd = process.cwd();
68344
68520
  return [
68345
- { path: join76(homedir14(), ".claude.json"), scope: "user" },
68346
- { path: join76(claudeConfigDir, ".mcp.json"), scope: "user" },
68347
- { path: join76(cwd, ".mcp.json"), scope: "project" },
68348
- { path: join76(cwd, ".claude", ".mcp.json"), scope: "local" }
68521
+ { path: join77(homedir14(), ".claude.json"), scope: "user" },
68522
+ { path: join77(claudeConfigDir, ".mcp.json"), scope: "user" },
68523
+ { path: join77(cwd, ".mcp.json"), scope: "project" },
68524
+ { path: join77(cwd, ".claude", ".mcp.json"), scope: "local" }
68349
68525
  ];
68350
68526
  }
68351
68527
  async function loadMcpConfigFile(filePath) {
68352
- if (!existsSync65(filePath)) {
68528
+ if (!existsSync66(filePath)) {
68353
68529
  return null;
68354
68530
  }
68355
68531
  try {
@@ -68364,10 +68540,10 @@ function getSystemMcpServerNames() {
68364
68540
  const names = new Set;
68365
68541
  const paths = getMcpConfigPaths();
68366
68542
  for (const { path: path10 } of paths) {
68367
- if (!existsSync65(path10))
68543
+ if (!existsSync66(path10))
68368
68544
  continue;
68369
68545
  try {
68370
- const content = readFileSync44(path10, "utf-8");
68546
+ const content = readFileSync45(path10, "utf-8");
68371
68547
  const config3 = JSON.parse(content);
68372
68548
  if (!config3?.mcpServers)
68373
68549
  continue;
@@ -68545,25 +68721,25 @@ init_logger();
68545
68721
 
68546
68722
  // src/features/claude-code-plugin-loader/discovery.ts
68547
68723
  init_logger();
68548
- import { existsSync as existsSync66, readFileSync as readFileSync45 } from "fs";
68724
+ import { existsSync as existsSync67, readFileSync as readFileSync46 } from "fs";
68549
68725
  import { homedir as homedir15 } from "os";
68550
- import { join as join77 } from "path";
68726
+ import { join as join78 } from "path";
68551
68727
  function getPluginsBaseDir() {
68552
68728
  if (process.env.CLAUDE_PLUGINS_HOME) {
68553
68729
  return process.env.CLAUDE_PLUGINS_HOME;
68554
68730
  }
68555
- return join77(homedir15(), ".claude", "plugins");
68731
+ return join78(homedir15(), ".claude", "plugins");
68556
68732
  }
68557
68733
  function getInstalledPluginsPath() {
68558
- return join77(getPluginsBaseDir(), "installed_plugins.json");
68734
+ return join78(getPluginsBaseDir(), "installed_plugins.json");
68559
68735
  }
68560
68736
  function loadInstalledPlugins() {
68561
68737
  const dbPath = getInstalledPluginsPath();
68562
- if (!existsSync66(dbPath)) {
68738
+ if (!existsSync67(dbPath)) {
68563
68739
  return null;
68564
68740
  }
68565
68741
  try {
68566
- const content = readFileSync45(dbPath, "utf-8");
68742
+ const content = readFileSync46(dbPath, "utf-8");
68567
68743
  return JSON.parse(content);
68568
68744
  } catch (error45) {
68569
68745
  log("Failed to load installed plugins database", error45);
@@ -68574,15 +68750,15 @@ function getClaudeSettingsPath() {
68574
68750
  if (process.env.CLAUDE_SETTINGS_PATH) {
68575
68751
  return process.env.CLAUDE_SETTINGS_PATH;
68576
68752
  }
68577
- return join77(homedir15(), ".claude", "settings.json");
68753
+ return join78(homedir15(), ".claude", "settings.json");
68578
68754
  }
68579
68755
  function loadClaudeSettings() {
68580
68756
  const settingsPath = getClaudeSettingsPath();
68581
- if (!existsSync66(settingsPath)) {
68757
+ if (!existsSync67(settingsPath)) {
68582
68758
  return null;
68583
68759
  }
68584
68760
  try {
68585
- const content = readFileSync45(settingsPath, "utf-8");
68761
+ const content = readFileSync46(settingsPath, "utf-8");
68586
68762
  return JSON.parse(content);
68587
68763
  } catch (error45) {
68588
68764
  log("Failed to load Claude settings", error45);
@@ -68590,12 +68766,12 @@ function loadClaudeSettings() {
68590
68766
  }
68591
68767
  }
68592
68768
  function loadPluginManifest(installPath) {
68593
- const manifestPath = join77(installPath, ".claude-plugin", "plugin.json");
68594
- if (!existsSync66(manifestPath)) {
68769
+ const manifestPath = join78(installPath, ".claude-plugin", "plugin.json");
68770
+ if (!existsSync67(manifestPath)) {
68595
68771
  return null;
68596
68772
  }
68597
68773
  try {
68598
- const content = readFileSync45(manifestPath, "utf-8");
68774
+ const content = readFileSync46(manifestPath, "utf-8");
68599
68775
  return JSON.parse(content);
68600
68776
  } catch (error45) {
68601
68777
  log(`Failed to load plugin manifest from ${manifestPath}`, error45);
@@ -68639,7 +68815,7 @@ function discoverInstalledPlugins(options) {
68639
68815
  continue;
68640
68816
  }
68641
68817
  const { installPath, scope, version: version2 } = installation;
68642
- if (!existsSync66(installPath)) {
68818
+ if (!existsSync67(installPath)) {
68643
68819
  errors3.push({
68644
68820
  pluginKey,
68645
68821
  installPath,
@@ -68657,21 +68833,21 @@ function discoverInstalledPlugins(options) {
68657
68833
  pluginKey,
68658
68834
  manifest: manifest ?? undefined
68659
68835
  };
68660
- if (existsSync66(join77(installPath, "commands"))) {
68661
- loadedPlugin.commandsDir = join77(installPath, "commands");
68836
+ if (existsSync67(join78(installPath, "commands"))) {
68837
+ loadedPlugin.commandsDir = join78(installPath, "commands");
68662
68838
  }
68663
- if (existsSync66(join77(installPath, "agents"))) {
68664
- loadedPlugin.agentsDir = join77(installPath, "agents");
68839
+ if (existsSync67(join78(installPath, "agents"))) {
68840
+ loadedPlugin.agentsDir = join78(installPath, "agents");
68665
68841
  }
68666
- if (existsSync66(join77(installPath, "skills"))) {
68667
- loadedPlugin.skillsDir = join77(installPath, "skills");
68842
+ if (existsSync67(join78(installPath, "skills"))) {
68843
+ loadedPlugin.skillsDir = join78(installPath, "skills");
68668
68844
  }
68669
- const hooksPath = join77(installPath, "hooks", "hooks.json");
68670
- if (existsSync66(hooksPath)) {
68845
+ const hooksPath = join78(installPath, "hooks", "hooks.json");
68846
+ if (existsSync67(hooksPath)) {
68671
68847
  loadedPlugin.hooksPath = hooksPath;
68672
68848
  }
68673
- const mcpPath = join77(installPath, ".mcp.json");
68674
- if (existsSync66(mcpPath)) {
68849
+ const mcpPath = join78(installPath, ".mcp.json");
68850
+ if (existsSync67(mcpPath)) {
68675
68851
  loadedPlugin.mcpPath = mcpPath;
68676
68852
  }
68677
68853
  plugins.push(loadedPlugin);
@@ -68684,23 +68860,23 @@ function discoverInstalledPlugins(options) {
68684
68860
  }
68685
68861
 
68686
68862
  // src/features/claude-code-plugin-loader/command-loader.ts
68687
- import { existsSync as existsSync67, readdirSync as readdirSync20, readFileSync as readFileSync46 } from "fs";
68688
- import { basename as basename9, join as join78 } from "path";
68863
+ import { existsSync as existsSync68, readdirSync as readdirSync20, readFileSync as readFileSync47 } from "fs";
68864
+ import { basename as basename9, join as join79 } from "path";
68689
68865
  init_logger();
68690
68866
  function loadPluginCommands(plugins) {
68691
68867
  const commands2 = {};
68692
68868
  for (const plugin of plugins) {
68693
- if (!plugin.commandsDir || !existsSync67(plugin.commandsDir))
68869
+ if (!plugin.commandsDir || !existsSync68(plugin.commandsDir))
68694
68870
  continue;
68695
68871
  const entries = readdirSync20(plugin.commandsDir, { withFileTypes: true });
68696
68872
  for (const entry of entries) {
68697
68873
  if (!isMarkdownFile(entry))
68698
68874
  continue;
68699
- const commandPath = join78(plugin.commandsDir, entry.name);
68875
+ const commandPath = join79(plugin.commandsDir, entry.name);
68700
68876
  const commandName = basename9(entry.name, ".md");
68701
68877
  const namespacedName = `${plugin.name}:${commandName}`;
68702
68878
  try {
68703
- const content = readFileSync46(commandPath, "utf-8");
68879
+ const content = readFileSync47(commandPath, "utf-8");
68704
68880
  const { data, body } = parseFrontmatter(content);
68705
68881
  const wrappedTemplate = `<command-instruction>
68706
68882
  ${body.trim()}
@@ -68731,27 +68907,27 @@ $ARGUMENTS
68731
68907
  }
68732
68908
 
68733
68909
  // src/features/claude-code-plugin-loader/skill-loader.ts
68734
- import { existsSync as existsSync68, readdirSync as readdirSync21, readFileSync as readFileSync47 } from "fs";
68735
- import { join as join79 } from "path";
68910
+ import { existsSync as existsSync69, readdirSync as readdirSync21, readFileSync as readFileSync48 } from "fs";
68911
+ import { join as join80 } from "path";
68736
68912
  init_logger();
68737
68913
  function loadPluginSkillsAsCommands(plugins) {
68738
68914
  const skills = {};
68739
68915
  for (const plugin of plugins) {
68740
- if (!plugin.skillsDir || !existsSync68(plugin.skillsDir))
68916
+ if (!plugin.skillsDir || !existsSync69(plugin.skillsDir))
68741
68917
  continue;
68742
68918
  const entries = readdirSync21(plugin.skillsDir, { withFileTypes: true });
68743
68919
  for (const entry of entries) {
68744
68920
  if (entry.name.startsWith("."))
68745
68921
  continue;
68746
- const skillPath = join79(plugin.skillsDir, entry.name);
68922
+ const skillPath = join80(plugin.skillsDir, entry.name);
68747
68923
  if (!entry.isDirectory() && !entry.isSymbolicLink())
68748
68924
  continue;
68749
68925
  const resolvedPath = resolveSymlink(skillPath);
68750
- const skillMdPath = join79(resolvedPath, "SKILL.md");
68751
- if (!existsSync68(skillMdPath))
68926
+ const skillMdPath = join80(resolvedPath, "SKILL.md");
68927
+ if (!existsSync69(skillMdPath))
68752
68928
  continue;
68753
68929
  try {
68754
- const content = readFileSync47(skillMdPath, "utf-8");
68930
+ const content = readFileSync48(skillMdPath, "utf-8");
68755
68931
  const { data, body } = parseFrontmatter(content);
68756
68932
  const skillName = data.name || entry.name;
68757
68933
  const namespacedName = `${plugin.name}:${skillName}`;
@@ -68786,8 +68962,8 @@ $ARGUMENTS
68786
68962
  }
68787
68963
 
68788
68964
  // src/features/claude-code-plugin-loader/agent-loader.ts
68789
- import { existsSync as existsSync69, readdirSync as readdirSync22, readFileSync as readFileSync48 } from "fs";
68790
- import { basename as basename10, join as join80 } from "path";
68965
+ import { existsSync as existsSync70, readdirSync as readdirSync22, readFileSync as readFileSync49 } from "fs";
68966
+ import { basename as basename10, join as join81 } from "path";
68791
68967
  init_logger();
68792
68968
  function parseToolsConfig2(toolsStr) {
68793
68969
  if (!toolsStr)
@@ -68804,17 +68980,17 @@ function parseToolsConfig2(toolsStr) {
68804
68980
  function loadPluginAgents(plugins) {
68805
68981
  const agents = {};
68806
68982
  for (const plugin of plugins) {
68807
- if (!plugin.agentsDir || !existsSync69(plugin.agentsDir))
68983
+ if (!plugin.agentsDir || !existsSync70(plugin.agentsDir))
68808
68984
  continue;
68809
68985
  const entries = readdirSync22(plugin.agentsDir, { withFileTypes: true });
68810
68986
  for (const entry of entries) {
68811
68987
  if (!isMarkdownFile(entry))
68812
68988
  continue;
68813
- const agentPath = join80(plugin.agentsDir, entry.name);
68989
+ const agentPath = join81(plugin.agentsDir, entry.name);
68814
68990
  const agentName = basename10(entry.name, ".md");
68815
68991
  const namespacedName = `${plugin.name}:${agentName}`;
68816
68992
  try {
68817
- const content = readFileSync48(agentPath, "utf-8");
68993
+ const content = readFileSync49(agentPath, "utf-8");
68818
68994
  const { data, body } = parseFrontmatter(content);
68819
68995
  const originalDescription = data.description || "";
68820
68996
  const formattedDescription = `(plugin: ${plugin.name}) ${originalDescription}`;
@@ -68838,7 +69014,7 @@ function loadPluginAgents(plugins) {
68838
69014
  }
68839
69015
 
68840
69016
  // src/features/claude-code-plugin-loader/mcp-server-loader.ts
68841
- import { existsSync as existsSync70 } from "fs";
69017
+ import { existsSync as existsSync71 } from "fs";
68842
69018
  init_logger();
68843
69019
 
68844
69020
  // src/features/claude-code-plugin-loader/plugin-path-resolver.ts
@@ -68869,7 +69045,7 @@ function resolvePluginPaths(obj, pluginRoot) {
68869
69045
  async function loadPluginMcpServers(plugins) {
68870
69046
  const servers = {};
68871
69047
  for (const plugin of plugins) {
68872
- if (!plugin.mcpPath || !existsSync70(plugin.mcpPath))
69048
+ if (!plugin.mcpPath || !existsSync71(plugin.mcpPath))
68873
69049
  continue;
68874
69050
  try {
68875
69051
  const content = await Bun.file(plugin.mcpPath).text();
@@ -68901,14 +69077,14 @@ async function loadPluginMcpServers(plugins) {
68901
69077
 
68902
69078
  // src/features/claude-code-plugin-loader/hook-loader.ts
68903
69079
  init_logger();
68904
- import { existsSync as existsSync71, readFileSync as readFileSync49 } from "fs";
69080
+ import { existsSync as existsSync72, readFileSync as readFileSync50 } from "fs";
68905
69081
  function loadPluginHooksConfigs(plugins) {
68906
69082
  const configs = [];
68907
69083
  for (const plugin of plugins) {
68908
- if (!plugin.hooksPath || !existsSync71(plugin.hooksPath))
69084
+ if (!plugin.hooksPath || !existsSync72(plugin.hooksPath))
68909
69085
  continue;
68910
69086
  try {
68911
- const content = readFileSync49(plugin.hooksPath, "utf-8");
69087
+ const content = readFileSync50(plugin.hooksPath, "utf-8");
68912
69088
  let config3 = JSON.parse(content);
68913
69089
  config3 = resolvePluginPaths(config3, plugin.installPath);
68914
69090
  configs.push(config3);
@@ -69441,6 +69617,7 @@ function createChatMessageHandler2(args) {
69441
69617
  await hooks.keywordDetector?.["chat.message"]?.(input, output);
69442
69618
  await hooks.claudeCodeHooks?.["chat.message"]?.(input, output);
69443
69619
  await hooks.autoSlashCommand?.["chat.message"]?.(input, output);
69620
+ await hooks.sisyphusGptHephaestusReminder?.["chat.message"]?.(input);
69444
69621
  if (hooks.startWork && isStartWorkHookOutput(output)) {
69445
69622
  await hooks.startWork["chat.message"]?.(input, output);
69446
69623
  }
@@ -69665,6 +69842,7 @@ function createToolExecuteAfterHandler3(args) {
69665
69842
  await hooks.categorySkillReminder?.["tool.execute.after"]?.(input, output);
69666
69843
  await hooks.interactiveBashSession?.["tool.execute.after"]?.(input, output);
69667
69844
  await hooks.editErrorRecovery?.["tool.execute.after"]?.(input, output);
69845
+ await hooks.jsonErrorRecovery?.["tool.execute.after"]?.(input, output);
69668
69846
  await hooks.delegateTaskRetry?.["tool.execute.after"]?.(input, output);
69669
69847
  await hooks.atlasHook?.["tool.execute.after"]?.(input, output);
69670
69848
  await hooks.taskResumeInfo?.["tool.execute.after"]?.(input, output);
@@ -70050,9 +70228,11 @@ var HookNameSchema = exports_external.enum([
70050
70228
  "claude-code-hooks",
70051
70229
  "auto-slash-command",
70052
70230
  "edit-error-recovery",
70231
+ "json-error-recovery",
70053
70232
  "delegate-task-retry",
70054
70233
  "prometheus-md-only",
70055
70234
  "sisyphus-junior-notepad",
70235
+ "sisyphus-gpt-hephaestus-reminder",
70056
70236
  "start-work",
70057
70237
  "atlas",
70058
70238
  "unstable-agent-babysitter",