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/agents/prometheus/identity-constraints.d.ts +1 -1
- package/dist/agents/prometheus/system-prompt.d.ts +1 -1
- package/dist/cli/index.js +884 -317
- package/dist/cli/run/agent-profile-colors.d.ts +2 -0
- package/dist/cli/run/continuation-state.d.ts +9 -0
- package/dist/cli/run/display-chars.d.ts +5 -0
- package/dist/cli/run/event-handlers.d.ts +1 -0
- package/dist/cli/run/event-state.d.ts +30 -0
- package/dist/cli/run/output-renderer.d.ts +7 -0
- package/dist/cli/run/tool-input-preview.d.ts +6 -0
- package/dist/cli/run/types.d.ts +12 -1
- package/dist/config/schema/hooks.d.ts +2 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +2 -0
- package/dist/create-hooks.d.ts +2 -0
- package/dist/features/run-continuation-state/constants.d.ts +1 -0
- package/dist/features/run-continuation-state/index.d.ts +3 -0
- package/dist/features/run-continuation-state/storage.d.ts +6 -0
- package/dist/features/run-continuation-state/types.d.ts +12 -0
- package/dist/hooks/index.d.ts +2 -0
- package/dist/hooks/json-error-recovery/hook.d.ts +15 -0
- package/dist/hooks/json-error-recovery/index.d.ts +1 -0
- package/dist/hooks/sisyphus-gpt-hephaestus-reminder/hook.d.ts +11 -0
- package/dist/hooks/sisyphus-gpt-hephaestus-reminder/index.d.ts +1 -0
- package/dist/hooks/stop-continuation-guard/hook.d.ts +1 -1
- package/dist/index.js +866 -686
- package/dist/plugin/hooks/create-core-hooks.d.ts +2 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -1
- package/package.json +8 -8
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
|
|
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
|
-
} =
|
|
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 =
|
|
629
|
-
const EXTGLOB_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
|
-
} =
|
|
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
|
|
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 =
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
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,
|
|
5754
|
-
this.code = optimizeExpr(this.code, names,
|
|
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,
|
|
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,
|
|
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,
|
|
5846
|
+
optimizeNames(names, constants19) {
|
|
5847
5847
|
var _a;
|
|
5848
|
-
this.else = (_a = this.else) === null || _a === undefined ? undefined : _a.optimizeNames(names,
|
|
5849
|
-
if (!(super.optimizeNames(names,
|
|
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,
|
|
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,
|
|
5877
|
-
if (!super.optimizeNames(names,
|
|
5876
|
+
optimizeNames(names, constants19) {
|
|
5877
|
+
if (!super.optimizeNames(names, constants19))
|
|
5878
5878
|
return;
|
|
5879
|
-
this.iteration = optimizeExpr(this.iteration, names,
|
|
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,
|
|
5918
|
-
if (!super.optimizeNames(names,
|
|
5917
|
+
optimizeNames(names, constants19) {
|
|
5918
|
+
if (!super.optimizeNames(names, constants19))
|
|
5919
5919
|
return;
|
|
5920
|
-
this.iterable = optimizeExpr(this.iterable, names,
|
|
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,
|
|
5965
|
+
optimizeNames(names, constants19) {
|
|
5966
5966
|
var _a, _b;
|
|
5967
|
-
super.optimizeNames(names,
|
|
5968
|
-
(_a = this.catch) === null || _a === undefined || _a.optimizeNames(names,
|
|
5969
|
-
(_b = this.finally) === null || _b === undefined || _b.optimizeNames(names,
|
|
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,
|
|
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 =
|
|
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 &&
|
|
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
|
|
6713
|
-
const hasNull =
|
|
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 (!
|
|
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
|
-
|
|
6722
|
+
types21.push("null");
|
|
6723
6723
|
}
|
|
6724
|
-
return
|
|
6724
|
+
return types21;
|
|
6725
6725
|
}
|
|
6726
6726
|
exports.getSchemaTypes = getSchemaTypes;
|
|
6727
6727
|
function getJSONTypes(ts) {
|
|
6728
|
-
const
|
|
6729
|
-
if (
|
|
6730
|
-
return
|
|
6731
|
-
throw new Error("type must be JSONType or JSONType[]: " +
|
|
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,
|
|
6734
|
+
function coerceAndCheckDataType(it, types21) {
|
|
6735
6735
|
const { gen, data, opts } = it;
|
|
6736
|
-
const coerceTo = coerceToTypes(
|
|
6737
|
-
const checkTypes =
|
|
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(
|
|
6739
|
+
const wrongType = checkDataTypes(types21, data, opts.strictNumbers, DataType.Wrong);
|
|
6740
6740
|
gen.if(wrongType, () => {
|
|
6741
6741
|
if (coerceTo.length)
|
|
6742
|
-
coerceData(it,
|
|
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(
|
|
6752
|
-
return coerceTypes ?
|
|
6751
|
+
function coerceToTypes(types21, coerceTypes) {
|
|
6752
|
+
return coerceTypes ? types21.filter((t) => COERCIBLE.has(t) || coerceTypes === "array" && t === "array") : [];
|
|
6753
6753
|
}
|
|
6754
|
-
function coerceData(it,
|
|
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(
|
|
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
|
|
6836
|
-
if (
|
|
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 =
|
|
6839
|
-
delete
|
|
6840
|
-
delete
|
|
6841
|
-
delete
|
|
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 (
|
|
6846
|
-
delete
|
|
6847
|
-
for (const t in
|
|
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
|
|
7636
|
-
const checkedTypes = (0, dataType_1.coerceAndCheckDataType)(it,
|
|
7637
|
-
schemaKeywords(it,
|
|
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,
|
|
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,
|
|
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 (
|
|
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,
|
|
7731
|
+
function checkStrictTypes(it, types21) {
|
|
7732
7732
|
if (it.schemaEnv.meta || !it.opts.strictTypes)
|
|
7733
7733
|
return;
|
|
7734
|
-
checkContextTypes(it,
|
|
7734
|
+
checkContextTypes(it, types21);
|
|
7735
7735
|
if (!it.opts.allowUnionTypes)
|
|
7736
|
-
checkMultipleTypes(it,
|
|
7736
|
+
checkMultipleTypes(it, types21);
|
|
7737
7737
|
checkKeywordTypes(it, it.dataTypes);
|
|
7738
7738
|
}
|
|
7739
|
-
function checkContextTypes(it,
|
|
7740
|
-
if (!
|
|
7739
|
+
function checkContextTypes(it, types21) {
|
|
7740
|
+
if (!types21.length)
|
|
7741
7741
|
return;
|
|
7742
7742
|
if (!it.dataTypes.length) {
|
|
7743
|
-
it.dataTypes =
|
|
7743
|
+
it.dataTypes = types21;
|
|
7744
7744
|
return;
|
|
7745
7745
|
}
|
|
7746
|
-
|
|
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,
|
|
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
|
|
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 &&
|
|
15014
|
+
if (customPath && existsSync2(customPath)) {
|
|
14966
15015
|
return customPath;
|
|
14967
15016
|
}
|
|
14968
15017
|
for (const path2 of defaultPaths) {
|
|
14969
|
-
if (
|
|
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
|
|
15098
|
-
import { join as
|
|
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
|
|
15167
|
+
return join3(cwd, filePath);
|
|
15119
15168
|
}
|
|
15120
15169
|
function readFileContent(resolvedPath) {
|
|
15121
|
-
if (!
|
|
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 =
|
|
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
|
|
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
|
|
15535
|
+
return join5(homedir3(), ".claude");
|
|
15487
15536
|
}
|
|
15488
15537
|
// src/shared/jsonc-parser.ts
|
|
15489
|
-
import { existsSync as
|
|
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 (
|
|
16412
|
+
if (existsSync4(jsoncPath)) {
|
|
16364
16413
|
return { format: "jsonc", path: jsoncPath };
|
|
16365
16414
|
}
|
|
16366
|
-
if (
|
|
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
|
|
16630
|
+
import { existsSync as existsSync5 } from "fs";
|
|
16582
16631
|
import { homedir as homedir4 } from "os";
|
|
16583
|
-
import { join as
|
|
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
|
|
16644
|
+
return join6(homedir4(), "Library", "Application Support", identifier);
|
|
16596
16645
|
case "win32": {
|
|
16597
|
-
const appData = process.env.APPDATA ||
|
|
16598
|
-
return
|
|
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 ||
|
|
16603
|
-
return
|
|
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 =
|
|
16614
|
-
const crossPlatformConfig =
|
|
16615
|
-
if (
|
|
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 ||
|
|
16619
|
-
const appdataDir =
|
|
16620
|
-
const appdataConfig =
|
|
16621
|
-
if (
|
|
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 ||
|
|
16627
|
-
return
|
|
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 =
|
|
16639
|
-
const legacyConfigC =
|
|
16640
|
-
if (
|
|
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:
|
|
16651
|
-
configJsonc:
|
|
16652
|
-
packageJson:
|
|
16653
|
-
omoConfig:
|
|
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
|
|
16706
|
-
import { join as
|
|
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 =
|
|
16718
|
-
return versionOk &&
|
|
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
|
|
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
|
|
16990
|
+
return existsSync8(binaryPath) ? binaryPath : null;
|
|
16942
16991
|
}
|
|
16943
16992
|
function ensureCacheDir(cacheDir) {
|
|
16944
|
-
if (!
|
|
16945
|
-
|
|
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 (
|
|
17022
|
+
if (existsSync8(archivePath)) {
|
|
16974
17023
|
unlinkSync(archivePath);
|
|
16975
17024
|
}
|
|
16976
17025
|
}
|
|
16977
17026
|
function ensureExecutable(binaryPath) {
|
|
16978
|
-
if (process.platform !== "win32" &&
|
|
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
|
|
17318
|
-
import { join as
|
|
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
|
|
17371
|
+
return join10(getOmoOpenCodeCacheDir(), filename);
|
|
17323
17372
|
}
|
|
17324
17373
|
function ensureCacheDir2() {
|
|
17325
17374
|
const cacheDir = getOmoOpenCodeCacheDir();
|
|
17326
|
-
if (!
|
|
17327
|
-
|
|
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 (!
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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 (!
|
|
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 =
|
|
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
|
|
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
|
-
|
|
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
|
|
17439
|
-
import { join as
|
|
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 =
|
|
17576
|
-
if (!
|
|
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 =
|
|
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 =
|
|
17633
|
-
return
|
|
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
|
|
17910
|
-
import { join as
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
18037
|
-
import { join as
|
|
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
|
|
18089
|
+
import { join as join13 } from "path";
|
|
18041
18090
|
var OPENCODE_STORAGE = getOpenCodeStorageDir();
|
|
18042
|
-
var MESSAGE_STORAGE =
|
|
18043
|
-
var PART_STORAGE =
|
|
18044
|
-
var SESSION_STORAGE =
|
|
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 (!
|
|
18104
|
+
if (!existsSync12(MESSAGE_STORAGE))
|
|
18056
18105
|
return null;
|
|
18057
|
-
const directPath =
|
|
18058
|
-
if (
|
|
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 =
|
|
18064
|
-
if (
|
|
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
|
|
18836
|
-
import { join as
|
|
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 =
|
|
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
|
|
20003
|
-
import { join as
|
|
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 || !
|
|
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 =
|
|
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
|
|
20031
|
-
import { join as
|
|
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 =
|
|
20043
|
-
if (!
|
|
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 =
|
|
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
|
|
20082
|
-
import { join as
|
|
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 =
|
|
20089
|
-
if (!
|
|
20090
|
-
|
|
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
|
-
|
|
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
|
|
20160
|
-
import { join as
|
|
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 =
|
|
20167
|
-
if (!
|
|
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 =
|
|
20175
|
-
const content =
|
|
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
|
-
|
|
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
|
|
20268
|
-
import { join as
|
|
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 =
|
|
20298
|
-
if (!
|
|
20299
|
-
|
|
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
|
-
|
|
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
|
|
20364
|
-
import { join as
|
|
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 =
|
|
20371
|
-
if (!
|
|
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 =
|
|
20379
|
-
const content =
|
|
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(
|
|
30916
|
+
function _mime(types4, params) {
|
|
30837
30917
|
return new $ZodCheckMimeType({
|
|
30838
30918
|
check: "mime_type",
|
|
30839
|
-
mime:
|
|
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 = (
|
|
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
|
|
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
|
|
33077
|
-
import { existsSync as
|
|
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
|
|
33083
|
-
import { join as
|
|
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 =
|
|
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 ||
|
|
33108
|
-
return
|
|
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 ||
|
|
33112
|
-
return
|
|
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 =
|
|
33139
|
-
if (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
33210
|
-
if (
|
|
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 &&
|
|
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 (!
|
|
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 &&
|
|
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
|
|
33545
|
+
import { join as join24 } from "path";
|
|
33466
33546
|
var DEBUG3 = process.env.COMMENT_CHECKER_DEBUG === "1";
|
|
33467
|
-
var DEBUG_FILE3 =
|
|
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
|
|
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
|
|
33631
|
-
import { dirname as dirname2, join as
|
|
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
|
|
33635
|
-
var AGENTS_INJECTOR_STORAGE =
|
|
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 =
|
|
33653
|
-
if (
|
|
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
|
|
33672
|
-
mkdirSync as
|
|
33673
|
-
readFileSync as
|
|
33751
|
+
existsSync as existsSync23,
|
|
33752
|
+
mkdirSync as mkdirSync7,
|
|
33753
|
+
readFileSync as readFileSync13,
|
|
33674
33754
|
unlinkSync as unlinkSync3,
|
|
33675
|
-
writeFileSync as
|
|
33755
|
+
writeFileSync as writeFileSync8
|
|
33676
33756
|
} from "fs";
|
|
33677
|
-
import { join as
|
|
33757
|
+
import { join as join27 } from "path";
|
|
33678
33758
|
function createInjectedPathsStorage(storageDir) {
|
|
33679
|
-
const getStoragePath = (sessionID) =>
|
|
33759
|
+
const getStoragePath = (sessionID) => join27(storageDir, `${sessionID}.json`);
|
|
33680
33760
|
const loadInjectedPaths = (sessionID) => {
|
|
33681
33761
|
const filePath = getStoragePath(sessionID);
|
|
33682
|
-
if (!
|
|
33762
|
+
if (!existsSync23(filePath))
|
|
33683
33763
|
return new Set;
|
|
33684
33764
|
try {
|
|
33685
|
-
const content =
|
|
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 (!
|
|
33694
|
-
|
|
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
|
-
|
|
33781
|
+
writeFileSync8(getStoragePath(sessionID), JSON.stringify(data, null, 2));
|
|
33702
33782
|
};
|
|
33703
33783
|
const clearInjectedPaths = (sessionID) => {
|
|
33704
33784
|
const filePath = getStoragePath(sessionID);
|
|
33705
|
-
if (
|
|
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 =
|
|
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
|
|
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
|
|
33809
|
-
import { dirname as dirname4, join as
|
|
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
|
|
33813
|
-
var README_INJECTOR_STORAGE =
|
|
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 =
|
|
33829
|
-
if (
|
|
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 =
|
|
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
|
|
34187
|
-
import { join as
|
|
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
|
|
34270
|
+
import { existsSync as existsSync25, readdirSync as readdirSync7 } from "fs";
|
|
34191
34271
|
function getMessageIds(sessionID) {
|
|
34192
34272
|
const messageDir = getMessageDir(sessionID);
|
|
34193
|
-
if (!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 =
|
|
34216
|
-
if (!
|
|
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 =
|
|
34223
|
-
const content =
|
|
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 =
|
|
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
|
-
|
|
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
|
|
34958
|
-
import { join as
|
|
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 =
|
|
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
|
|
35100
|
-
import { join as
|
|
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
|
|
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 =
|
|
35129
|
-
if (!
|
|
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 =
|
|
35214
|
+
const partPath = join32(partDir, file2);
|
|
35135
35215
|
try {
|
|
35136
|
-
const content =
|
|
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
|
|
35720
|
-
import { existsSync as
|
|
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
|
-
|
|
35747
|
-
|
|
35748
|
-
|
|
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 &&
|
|
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 (
|
|
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
|
|
35794
|
-
import { join as
|
|
35795
|
-
var USER_CONFIG_PATH =
|
|
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
|
|
35877
|
+
return join34(process.cwd(), ".opencode", "opencode-cc-plugin.json");
|
|
35798
35878
|
}
|
|
35799
35879
|
async function loadConfigFromPath(path5) {
|
|
35800
|
-
if (!
|
|
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
|
|
35943
|
-
import { mkdirSync as
|
|
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 =
|
|
36026
|
+
var TRANSCRIPT_DIR = join35(getClaudeConfigDir(), "transcripts");
|
|
35947
36027
|
function getTranscriptPath(sessionId) {
|
|
35948
|
-
return
|
|
36028
|
+
return join35(TRANSCRIPT_DIR, `${sessionId}.jsonl`);
|
|
35949
36029
|
}
|
|
35950
36030
|
function ensureTranscriptDir() {
|
|
35951
|
-
if (!
|
|
35952
|
-
|
|
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 =
|
|
36035
|
-
|
|
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 =
|
|
36046
|
-
|
|
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
|
|
36264
|
-
var TODO_DIR =
|
|
36343
|
+
import { join as join36 } from "path";
|
|
36344
|
+
var TODO_DIR = join36(getClaudeConfigDir(), "todos");
|
|
36265
36345
|
function getTodoPath(sessionId) {
|
|
36266
|
-
return
|
|
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
|
|
36842
|
-
mkdirSync as
|
|
36843
|
-
readFileSync as
|
|
36844
|
-
writeFileSync as
|
|
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
|
|
36927
|
+
import { join as join38 } from "path";
|
|
36848
36928
|
|
|
36849
36929
|
// src/hooks/rules-injector/constants.ts
|
|
36850
|
-
import { join as
|
|
36851
|
-
var RULES_INJECTOR_STORAGE =
|
|
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
|
|
36955
|
+
return join38(RULES_INJECTOR_STORAGE, `${sessionID}.json`);
|
|
36876
36956
|
}
|
|
36877
36957
|
function loadInjectedRules(sessionID) {
|
|
36878
36958
|
const filePath = getStoragePath(sessionID);
|
|
36879
|
-
if (!
|
|
36959
|
+
if (!existsSync31(filePath))
|
|
36880
36960
|
return { contentHashes: new Set, realPaths: new Set };
|
|
36881
36961
|
try {
|
|
36882
|
-
const content =
|
|
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 (!
|
|
36894
|
-
|
|
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
|
-
|
|
36982
|
+
writeFileSync11(getStoragePath(sessionID), JSON.stringify(storageData, null, 2));
|
|
36903
36983
|
}
|
|
36904
36984
|
function clearInjectedRules(sessionID) {
|
|
36905
36985
|
const filePath = getStoragePath(sessionID);
|
|
36906
|
-
if (
|
|
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
|
|
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
|
|
36934
|
-
import { dirname as dirname6, join as
|
|
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 =
|
|
36946
|
-
if (
|
|
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
|
|
36959
|
-
import { dirname as dirname7, join as
|
|
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
|
|
36963
|
-
import { join as
|
|
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 (!
|
|
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 =
|
|
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 =
|
|
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 =
|
|
37033
|
-
if (
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
38035
|
-
mkdirSync as
|
|
38036
|
-
readFileSync as
|
|
38037
|
-
writeFileSync as
|
|
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
|
|
38120
|
+
import { join as join47 } from "path";
|
|
38041
38121
|
|
|
38042
38122
|
// src/hooks/agent-usage-reminder/constants.ts
|
|
38043
|
-
import { join as
|
|
38044
|
-
var AGENT_USAGE_REMINDER_STORAGE =
|
|
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
|
|
38170
|
+
return join47(AGENT_USAGE_REMINDER_STORAGE, `${sessionID}.json`);
|
|
38091
38171
|
}
|
|
38092
38172
|
function loadAgentUsageState(sessionID) {
|
|
38093
38173
|
const filePath = getStoragePath2(sessionID);
|
|
38094
|
-
if (!
|
|
38174
|
+
if (!existsSync40(filePath))
|
|
38095
38175
|
return null;
|
|
38096
38176
|
try {
|
|
38097
|
-
const content =
|
|
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 (!
|
|
38105
|
-
|
|
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
|
-
|
|
38188
|
+
writeFileSync14(filePath, JSON.stringify(state3, null, 2));
|
|
38109
38189
|
}
|
|
38110
38190
|
function clearAgentUsageState(sessionID) {
|
|
38111
38191
|
const filePath = getStoragePath2(sessionID);
|
|
38112
|
-
if (
|
|
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
|
|
38897
|
+
const types5 = ["ultrawork", "search", "analyze"];
|
|
38818
38898
|
return KEYWORD_DETECTORS.map(({ pattern, message }, index) => ({
|
|
38819
38899
|
matches: pattern.test(textWithoutCode),
|
|
38820
|
-
type:
|
|
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
|
|
39003
|
-
mkdirSync as
|
|
39004
|
-
readFileSync as
|
|
39005
|
-
writeFileSync as
|
|
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
|
|
39088
|
+
import { join as join49 } from "path";
|
|
39009
39089
|
|
|
39010
39090
|
// src/hooks/interactive-bash-session/constants.ts
|
|
39011
|
-
import { join as
|
|
39012
|
-
var INTERACTIVE_BASH_SESSION_STORAGE =
|
|
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
|
|
39104
|
+
return join49(INTERACTIVE_BASH_SESSION_STORAGE, `${sessionID}.json`);
|
|
39025
39105
|
}
|
|
39026
39106
|
function loadInteractiveBashSessionState(sessionID) {
|
|
39027
39107
|
const filePath = getStoragePath3(sessionID);
|
|
39028
|
-
if (!
|
|
39108
|
+
if (!existsSync41(filePath))
|
|
39029
39109
|
return null;
|
|
39030
39110
|
try {
|
|
39031
|
-
const content =
|
|
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 (!
|
|
39044
|
-
|
|
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
|
-
|
|
39132
|
+
writeFileSync15(filePath, JSON.stringify(serialized, null, 2));
|
|
39053
39133
|
}
|
|
39054
39134
|
function clearInteractiveBashSessionState(sessionID) {
|
|
39055
39135
|
const filePath = getStoragePath3(sessionID);
|
|
39056
|
-
if (
|
|
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
|
|
39453
|
-
import { dirname as dirname10, join as
|
|
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 ?
|
|
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 (!
|
|
39539
|
+
if (!existsSync42(filePath)) {
|
|
39460
39540
|
return null;
|
|
39461
39541
|
}
|
|
39462
39542
|
try {
|
|
39463
|
-
const content =
|
|
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 (!
|
|
39498
|
-
|
|
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
|
-
|
|
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 (
|
|
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
|
|
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 (!
|
|
39735
|
+
if (!existsSync43(transcriptPath))
|
|
39656
39736
|
return false;
|
|
39657
|
-
const content =
|
|
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
|
|
40013
|
-
import { join as
|
|
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
|
|
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
|
|
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
|
|
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) =>
|
|
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
|
|
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 =
|
|
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 =
|
|
41614
|
+
const entryPath = join53(options.skillsDir, entry.name);
|
|
41508
41615
|
const resolvedPath = await resolveSymlinkAsync(entryPath);
|
|
41509
41616
|
const dirName = entry.name;
|
|
41510
|
-
const skillMdPath =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 (!
|
|
41812
|
+
if (!existsSync44(filePath))
|
|
41706
41813
|
return null;
|
|
41707
|
-
const content =
|
|
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
|
|
44030
|
+
import { readFileSync as readFileSync33 } from "fs";
|
|
43924
44031
|
function extractSkillTemplate(skill) {
|
|
43925
44032
|
if (skill.path) {
|
|
43926
|
-
const content =
|
|
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
|
|
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
|
|
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 (!
|
|
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 =
|
|
44232
|
+
const commandPath = join56(commandsDir, entry.name);
|
|
44126
44233
|
const commandName = basename2(entry.name, ".md");
|
|
44127
44234
|
try {
|
|
44128
|
-
const content =
|
|
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 =
|
|
44172
|
-
const projectCommandsDir =
|
|
44173
|
-
const opencodeGlobalDir =
|
|
44174
|
-
const opencodeProjectDir =
|
|
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
|
|
44483
|
-
import { dirname as dirname14, join as
|
|
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
|
|
44644
|
+
return join57(directory, BOULDER_DIR, BOULDER_FILE);
|
|
44486
44645
|
}
|
|
44487
44646
|
function readBoulderState(directory) {
|
|
44488
44647
|
const filePath = getBoulderFilePath(directory);
|
|
44489
|
-
if (!
|
|
44648
|
+
if (!existsSync46(filePath)) {
|
|
44490
44649
|
return null;
|
|
44491
44650
|
}
|
|
44492
44651
|
try {
|
|
44493
|
-
const content =
|
|
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 (!
|
|
44511
|
-
|
|
44669
|
+
if (!existsSync46(dir)) {
|
|
44670
|
+
mkdirSync13(dir, { recursive: true });
|
|
44512
44671
|
}
|
|
44513
|
-
|
|
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 (
|
|
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 =
|
|
44548
|
-
if (!
|
|
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) =>
|
|
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 (!
|
|
44722
|
+
if (!existsSync46(planPath)) {
|
|
44564
44723
|
return { total: 0, completed: 0, isComplete: true };
|
|
44565
44724
|
}
|
|
44566
44725
|
try {
|
|
44567
|
-
const content =
|
|
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(
|
|
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
|
|
46360
|
-
import { resolve as resolve7, isAbsolute as isAbsolute5, join as
|
|
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 (
|
|
46375
|
-
const sisyphusRoot =
|
|
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
|
|
47011
|
-
import { join as
|
|
47172
|
+
import { existsSync as existsSync48, readFileSync as readFileSync36 } from "fs";
|
|
47173
|
+
import { join as join59 } from "path";
|
|
47012
47174
|
function loadJsonFile(path10) {
|
|
47013
|
-
if (!
|
|
47175
|
+
if (!existsSync48(path10))
|
|
47014
47176
|
return null;
|
|
47015
47177
|
try {
|
|
47016
|
-
return parseJsonc(
|
|
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(
|
|
47026
|
-
user: detectConfigFile(
|
|
47027
|
-
opencode: detectConfigFile(
|
|
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
|
|
47097
|
-
import { join as
|
|
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 (
|
|
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 (
|
|
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 =
|
|
47294
|
+
const dataDir = join60(getDataDir(), "opencode");
|
|
47133
47295
|
const additionalBases = [
|
|
47134
|
-
|
|
47135
|
-
|
|
47136
|
-
|
|
47137
|
-
|
|
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 (
|
|
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
|
|
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 (!
|
|
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
|
|
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 =
|
|
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
|
|
48087
|
+
import { existsSync as existsSync51 } from "fs";
|
|
47926
48088
|
function findWorkspaceRoot(filePath) {
|
|
47927
48089
|
let dir = resolve9(filePath);
|
|
47928
|
-
if (!
|
|
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 (
|
|
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
|
|
48272
|
+
import { readFileSync as readFileSync38, writeFileSync as writeFileSync18 } from "fs";
|
|
48111
48273
|
function applyTextEditsToFile(filePath, edits) {
|
|
48112
48274
|
try {
|
|
48113
|
-
let content =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
48180
|
-
|
|
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
|
|
48462
|
-
import { existsSync as
|
|
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
|
|
48466
|
-
import { join as
|
|
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 ||
|
|
48494
|
-
return
|
|
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 ||
|
|
48498
|
-
return
|
|
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 =
|
|
48516
|
-
if (
|
|
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 =
|
|
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 =
|
|
48579
|
-
if (
|
|
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 =
|
|
48591
|
-
if (
|
|
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 (
|
|
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
|
|
48785
|
+
import { existsSync as existsSync55 } from "fs";
|
|
48624
48786
|
|
|
48625
48787
|
// src/tools/ast-grep/cli-binary-path-resolution.ts
|
|
48626
|
-
import { existsSync as
|
|
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 &&
|
|
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 &&
|
|
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 || !
|
|
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
|
|
48989
|
-
import { join as
|
|
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
|
|
48994
|
-
import { join as
|
|
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
|
|
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
|
|
49183
|
+
return join63(homeDir, ".cache", "oh-my-opencode", "bin");
|
|
49022
49184
|
}
|
|
49023
49185
|
function getRgPath() {
|
|
49024
49186
|
const isWindows2 = process.platform === "win32";
|
|
49025
|
-
return
|
|
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 =
|
|
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 (
|
|
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 =
|
|
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 (!
|
|
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
|
|
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
|
-
|
|
49109
|
-
|
|
49110
|
-
|
|
49111
|
-
|
|
49112
|
-
|
|
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 (
|
|
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
|
|
49582
|
-
import { basename as basename4, join as
|
|
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 (!
|
|
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 =
|
|
49753
|
+
const commandPath = join65(commandsDir, entry.name);
|
|
49592
49754
|
const commandName = basename4(entry.name, ".md");
|
|
49593
49755
|
try {
|
|
49594
|
-
const content =
|
|
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 =
|
|
49621
|
-
const projectCommandsDir =
|
|
49622
|
-
const opencodeGlobalDir =
|
|
49623
|
-
const opencodeProjectDir =
|
|
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
|
|
49832
|
-
var TODO_DIR2 =
|
|
49833
|
-
var TRANSCRIPT_DIR2 =
|
|
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
|
|
50068
|
+
import { existsSync as existsSync59 } from "fs";
|
|
49907
50069
|
import { readdir, readFile } from "fs/promises";
|
|
49908
|
-
import { join as
|
|
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 (!
|
|
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 =
|
|
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(
|
|
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 (!
|
|
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 =
|
|
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 || !
|
|
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(
|
|
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 =
|
|
50073
|
-
if (!
|
|
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(
|
|
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 (!
|
|
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(
|
|
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 (!
|
|
50297
|
+
if (!existsSync59(TRANSCRIPT_DIR2))
|
|
50136
50298
|
return 0;
|
|
50137
|
-
const transcriptFile =
|
|
50138
|
-
if (!
|
|
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
|
|
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
|
|
53789
|
-
import { existsSync as
|
|
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 :
|
|
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
|
|
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 (!
|
|
53818
|
-
|
|
53979
|
+
if (!existsSync60(dirPath)) {
|
|
53980
|
+
mkdirSync14(dirPath, { recursive: true });
|
|
53819
53981
|
}
|
|
53820
53982
|
}
|
|
53821
53983
|
function readJsonSafe(filePath, schema2) {
|
|
53822
53984
|
try {
|
|
53823
|
-
if (!
|
|
53985
|
+
if (!existsSync60(filePath)) {
|
|
53824
53986
|
return null;
|
|
53825
53987
|
}
|
|
53826
|
-
const content =
|
|
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
|
-
|
|
54004
|
+
writeFileSync19(tempPath, JSON.stringify(data, null, 2), "utf-8");
|
|
53843
54005
|
renameSync(tempPath, filePath);
|
|
53844
54006
|
} catch (error45) {
|
|
53845
54007
|
try {
|
|
53846
|
-
if (
|
|
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 =
|
|
54020
|
+
const lockPath = join68(dirPath, ".lock");
|
|
53859
54021
|
const lockId = randomUUID2();
|
|
53860
54022
|
const createLock = (timestamp2) => {
|
|
53861
|
-
|
|
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 =
|
|
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 (!
|
|
54068
|
+
if (!existsSync60(lockPath))
|
|
53907
54069
|
return;
|
|
53908
|
-
const lockContent =
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
54132
|
-
import { existsSync as
|
|
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 (!
|
|
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(
|
|
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
|
|
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 =
|
|
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
|
|
55110
|
-
import { join as
|
|
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 (!
|
|
56565
|
+
if (!existsSync62(MESSAGE_STORAGE))
|
|
56400
56566
|
return null;
|
|
56401
|
-
const directPath =
|
|
56402
|
-
if (
|
|
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 =
|
|
56406
|
-
if (
|
|
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 =
|
|
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 =
|
|
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
|
|
60438
|
-
import { dirname as dirname20, join as
|
|
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
|
|
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 (!
|
|
60644
|
+
if (!existsSync63(filePath)) {
|
|
60479
60645
|
return null;
|
|
60480
60646
|
}
|
|
60481
60647
|
try {
|
|
60482
|
-
const content =
|
|
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 (!
|
|
60493
|
-
|
|
60658
|
+
if (!existsSync63(dir)) {
|
|
60659
|
+
mkdirSync15(dir, { recursive: true });
|
|
60494
60660
|
}
|
|
60495
|
-
|
|
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
|
|
60664
|
-
|
|
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
|
|
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
|
|
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 (!
|
|
65863
|
+
if (!existsSync64(filePath)) {
|
|
65718
65864
|
return `[WARNING: Could not resolve file URI: ${promptAppend}]`;
|
|
65719
65865
|
}
|
|
65720
65866
|
try {
|
|
65721
|
-
return
|
|
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
|
|
66509
|
+
### 6.1 INCREMENTAL WRITE PROTOCOL (CRITICAL - Prevents Output Limit Stalls)
|
|
66364
66510
|
|
|
66365
66511
|
<write_protocol>
|
|
66366
|
-
**
|
|
66512
|
+
**Write OVERWRITES. Never call Write twice on the same file.**
|
|
66367
66513
|
|
|
66368
|
-
|
|
66369
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
66382
|
-
|
|
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
|
-
...
|
|
66393
|
-
|
|
66394
|
-
##
|
|
66395
|
-
|
|
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
|
-
|
|
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
|
-
**
|
|
66402
|
-
|
|
66403
|
-
|
|
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
|
|
67827
|
-
import { join as
|
|
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 (!
|
|
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 =
|
|
68019
|
+
const agentPath = join75(agentsDir, entry.name);
|
|
67850
68020
|
const agentName = basename7(entry.name, ".md");
|
|
67851
68021
|
try {
|
|
67852
|
-
const content =
|
|
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 =
|
|
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 =
|
|
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
|
|
68190
|
+
function getConfiguredDefaultAgent(config3) {
|
|
68021
68191
|
const defaultAgent = config3.default_agent;
|
|
68022
|
-
|
|
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 (
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
68303
|
-
import { join as
|
|
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:
|
|
68346
|
-
{ path:
|
|
68347
|
-
{ path:
|
|
68348
|
-
{ path:
|
|
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 (!
|
|
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 (!
|
|
68543
|
+
if (!existsSync66(path10))
|
|
68368
68544
|
continue;
|
|
68369
68545
|
try {
|
|
68370
|
-
const content =
|
|
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
|
|
68724
|
+
import { existsSync as existsSync67, readFileSync as readFileSync46 } from "fs";
|
|
68549
68725
|
import { homedir as homedir15 } from "os";
|
|
68550
|
-
import { join as
|
|
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
|
|
68731
|
+
return join78(homedir15(), ".claude", "plugins");
|
|
68556
68732
|
}
|
|
68557
68733
|
function getInstalledPluginsPath() {
|
|
68558
|
-
return
|
|
68734
|
+
return join78(getPluginsBaseDir(), "installed_plugins.json");
|
|
68559
68735
|
}
|
|
68560
68736
|
function loadInstalledPlugins() {
|
|
68561
68737
|
const dbPath = getInstalledPluginsPath();
|
|
68562
|
-
if (!
|
|
68738
|
+
if (!existsSync67(dbPath)) {
|
|
68563
68739
|
return null;
|
|
68564
68740
|
}
|
|
68565
68741
|
try {
|
|
68566
|
-
const content =
|
|
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
|
|
68753
|
+
return join78(homedir15(), ".claude", "settings.json");
|
|
68578
68754
|
}
|
|
68579
68755
|
function loadClaudeSettings() {
|
|
68580
68756
|
const settingsPath = getClaudeSettingsPath();
|
|
68581
|
-
if (!
|
|
68757
|
+
if (!existsSync67(settingsPath)) {
|
|
68582
68758
|
return null;
|
|
68583
68759
|
}
|
|
68584
68760
|
try {
|
|
68585
|
-
const content =
|
|
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 =
|
|
68594
|
-
if (!
|
|
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 =
|
|
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 (!
|
|
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 (
|
|
68661
|
-
loadedPlugin.commandsDir =
|
|
68836
|
+
if (existsSync67(join78(installPath, "commands"))) {
|
|
68837
|
+
loadedPlugin.commandsDir = join78(installPath, "commands");
|
|
68662
68838
|
}
|
|
68663
|
-
if (
|
|
68664
|
-
loadedPlugin.agentsDir =
|
|
68839
|
+
if (existsSync67(join78(installPath, "agents"))) {
|
|
68840
|
+
loadedPlugin.agentsDir = join78(installPath, "agents");
|
|
68665
68841
|
}
|
|
68666
|
-
if (
|
|
68667
|
-
loadedPlugin.skillsDir =
|
|
68842
|
+
if (existsSync67(join78(installPath, "skills"))) {
|
|
68843
|
+
loadedPlugin.skillsDir = join78(installPath, "skills");
|
|
68668
68844
|
}
|
|
68669
|
-
const hooksPath =
|
|
68670
|
-
if (
|
|
68845
|
+
const hooksPath = join78(installPath, "hooks", "hooks.json");
|
|
68846
|
+
if (existsSync67(hooksPath)) {
|
|
68671
68847
|
loadedPlugin.hooksPath = hooksPath;
|
|
68672
68848
|
}
|
|
68673
|
-
const mcpPath =
|
|
68674
|
-
if (
|
|
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
|
|
68688
|
-
import { basename as basename9, join as
|
|
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 || !
|
|
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 =
|
|
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 =
|
|
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
|
|
68735
|
-
import { join as
|
|
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 || !
|
|
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 =
|
|
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 =
|
|
68751
|
-
if (!
|
|
68926
|
+
const skillMdPath = join80(resolvedPath, "SKILL.md");
|
|
68927
|
+
if (!existsSync69(skillMdPath))
|
|
68752
68928
|
continue;
|
|
68753
68929
|
try {
|
|
68754
|
-
const content =
|
|
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
|
|
68790
|
-
import { basename as basename10, join as
|
|
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 || !
|
|
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 =
|
|
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 =
|
|
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
|
|
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 || !
|
|
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
|
|
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 || !
|
|
69084
|
+
if (!plugin.hooksPath || !existsSync72(plugin.hooksPath))
|
|
68909
69085
|
continue;
|
|
68910
69086
|
try {
|
|
68911
|
-
const content =
|
|
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",
|