oh-my-opencode 2.1.3 → 2.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -205,19 +205,19 @@ var require_utils = __commonJS((exports) => {
205
205
  return exports.escapeLast(input, char, idx - 1);
206
206
  return `${input.slice(0, idx)}\\${input.slice(idx)}`;
207
207
  };
208
- exports.removePrefix = (input, state = {}) => {
208
+ exports.removePrefix = (input, state2 = {}) => {
209
209
  let output = input;
210
210
  if (output.startsWith("./")) {
211
211
  output = output.slice(2);
212
- state.prefix = "./";
212
+ state2.prefix = "./";
213
213
  }
214
214
  return output;
215
215
  };
216
- exports.wrapOutput = (input, state = {}, options = {}) => {
216
+ exports.wrapOutput = (input, state2 = {}, options = {}) => {
217
217
  const prepend = options.contains ? "" : "^";
218
218
  const append = options.contains ? "" : "$";
219
219
  let output = `${prepend}(?:${input})${append}`;
220
- if (state.negated === true) {
220
+ if (state2.negated === true) {
221
221
  output = `(?:^(?!${output}).*$)`;
222
222
  }
223
223
  return output;
@@ -488,7 +488,7 @@ var require_scan = __commonJS((exports, module) => {
488
488
  base = utils.removeBackslashes(base);
489
489
  }
490
490
  }
491
- const state = {
491
+ const state2 = {
492
492
  prefix,
493
493
  input,
494
494
  start,
@@ -503,11 +503,11 @@ var require_scan = __commonJS((exports, module) => {
503
503
  negatedExtglob
504
504
  };
505
505
  if (opts.tokens === true) {
506
- state.maxDepth = 0;
506
+ state2.maxDepth = 0;
507
507
  if (!isPathSeparator(code)) {
508
508
  tokens.push(token);
509
509
  }
510
- state.tokens = tokens;
510
+ state2.tokens = tokens;
511
511
  }
512
512
  if (opts.parts === true || opts.tokens === true) {
513
513
  let prevIndex;
@@ -523,7 +523,7 @@ var require_scan = __commonJS((exports, module) => {
523
523
  tokens[idx].value = value;
524
524
  }
525
525
  depth(tokens[idx]);
526
- state.maxDepth += tokens[idx].depth;
526
+ state2.maxDepth += tokens[idx].depth;
527
527
  }
528
528
  if (idx !== 0 || value !== "") {
529
529
  parts.push(value);
@@ -536,13 +536,13 @@ var require_scan = __commonJS((exports, module) => {
536
536
  if (opts.tokens) {
537
537
  tokens[tokens.length - 1].value = value;
538
538
  depth(tokens[tokens.length - 1]);
539
- state.maxDepth += tokens[tokens.length - 1].depth;
539
+ state2.maxDepth += tokens[tokens.length - 1].depth;
540
540
  }
541
541
  }
542
- state.slashes = slashes;
543
- state.parts = parts;
542
+ state2.slashes = slashes;
543
+ state2.parts = parts;
544
544
  }
545
- return state;
545
+ return state2;
546
546
  };
547
547
  module.exports = scan;
548
548
  });
@@ -616,7 +616,7 @@ var require_parse = __commonJS((exports, module) => {
616
616
  if (typeof opts.noext === "boolean") {
617
617
  opts.noextglob = opts.noext;
618
618
  }
619
- const state = {
619
+ const state2 = {
620
620
  input,
621
621
  index: -1,
622
622
  start: 0,
@@ -633,57 +633,57 @@ var require_parse = __commonJS((exports, module) => {
633
633
  globstar: false,
634
634
  tokens
635
635
  };
636
- input = utils.removePrefix(input, state);
636
+ input = utils.removePrefix(input, state2);
637
637
  len = input.length;
638
638
  const extglobs = [];
639
639
  const braces = [];
640
640
  const stack = [];
641
641
  let prev = bos;
642
642
  let value;
643
- const eos = () => state.index === len - 1;
644
- const peek = state.peek = (n = 1) => input[state.index + n];
645
- const advance = state.advance = () => input[++state.index] || "";
646
- const remaining = () => input.slice(state.index + 1);
643
+ const eos = () => state2.index === len - 1;
644
+ const peek = state2.peek = (n = 1) => input[state2.index + n];
645
+ const advance = state2.advance = () => input[++state2.index] || "";
646
+ const remaining = () => input.slice(state2.index + 1);
647
647
  const consume = (value2 = "", num = 0) => {
648
- state.consumed += value2;
649
- state.index += num;
648
+ state2.consumed += value2;
649
+ state2.index += num;
650
650
  };
651
651
  const append = (token) => {
652
- state.output += token.output != null ? token.output : token.value;
652
+ state2.output += token.output != null ? token.output : token.value;
653
653
  consume(token.value);
654
654
  };
655
655
  const negate = () => {
656
656
  let count = 1;
657
657
  while (peek() === "!" && (peek(2) !== "(" || peek(3) === "?")) {
658
658
  advance();
659
- state.start++;
659
+ state2.start++;
660
660
  count++;
661
661
  }
662
662
  if (count % 2 === 0) {
663
663
  return false;
664
664
  }
665
- state.negated = true;
666
- state.start++;
665
+ state2.negated = true;
666
+ state2.start++;
667
667
  return true;
668
668
  };
669
669
  const increment = (type) => {
670
- state[type]++;
670
+ state2[type]++;
671
671
  stack.push(type);
672
672
  };
673
673
  const decrement = (type) => {
674
- state[type]--;
674
+ state2[type]--;
675
675
  stack.pop();
676
676
  };
677
677
  const push = (tok) => {
678
678
  if (prev.type === "globstar") {
679
- const isBrace = state.braces > 0 && (tok.type === "comma" || tok.type === "brace");
679
+ const isBrace = state2.braces > 0 && (tok.type === "comma" || tok.type === "brace");
680
680
  const isExtglob = tok.extglob === true || extglobs.length && (tok.type === "pipe" || tok.type === "paren");
681
681
  if (tok.type !== "slash" && tok.type !== "paren" && !isBrace && !isExtglob) {
682
- state.output = state.output.slice(0, -prev.output.length);
682
+ state2.output = state2.output.slice(0, -prev.output.length);
683
683
  prev.type = "star";
684
684
  prev.value = "*";
685
685
  prev.output = star;
686
- state.output += prev.output;
686
+ state2.output += prev.output;
687
687
  }
688
688
  }
689
689
  if (extglobs.length && tok.type !== "paren") {
@@ -703,11 +703,11 @@ var require_parse = __commonJS((exports, module) => {
703
703
  const extglobOpen = (type, value2) => {
704
704
  const token = { ...EXTGLOB_CHARS[value2], conditions: 1, inner: "" };
705
705
  token.prev = prev;
706
- token.parens = state.parens;
707
- token.output = state.output;
706
+ token.parens = state2.parens;
707
+ token.output = state2.output;
708
708
  const output = (opts.capture ? "(" : "") + token.open;
709
709
  increment("parens");
710
- push({ type, value: value2, output: state.output ? "" : ONE_CHAR });
710
+ push({ type, value: value2, output: state2.output ? "" : ONE_CHAR });
711
711
  push({ type: "paren", extglob: true, value: advance(), output });
712
712
  extglobs.push(token);
713
713
  };
@@ -727,7 +727,7 @@ var require_parse = __commonJS((exports, module) => {
727
727
  output = token.close = `)${expression})${extglobStar})`;
728
728
  }
729
729
  if (token.prev.type === "bos") {
730
- state.negatedExtglob = true;
730
+ state2.negatedExtglob = true;
731
731
  }
732
732
  }
733
733
  push({ type: "paren", extglob: true, value, output });
@@ -770,11 +770,11 @@ var require_parse = __commonJS((exports, module) => {
770
770
  }
771
771
  }
772
772
  if (output === input && opts.contains === true) {
773
- state.output = input;
774
- return state;
773
+ state2.output = input;
774
+ return state2;
775
775
  }
776
- state.output = utils.wrapOutput(output, state, options);
777
- return state;
776
+ state2.output = utils.wrapOutput(output, state2, options);
777
+ return state2;
778
778
  }
779
779
  while (!eos()) {
780
780
  value = advance();
@@ -798,7 +798,7 @@ var require_parse = __commonJS((exports, module) => {
798
798
  let slashes = 0;
799
799
  if (match && match[0].length > 2) {
800
800
  slashes = match[0].length;
801
- state.index += slashes;
801
+ state2.index += slashes;
802
802
  if (slashes % 2 !== 0) {
803
803
  value += "\\";
804
804
  }
@@ -808,12 +808,12 @@ var require_parse = __commonJS((exports, module) => {
808
808
  } else {
809
809
  value += advance();
810
810
  }
811
- if (state.brackets === 0) {
811
+ if (state2.brackets === 0) {
812
812
  push({ type: "text", value });
813
813
  continue;
814
814
  }
815
815
  }
816
- if (state.brackets > 0 && (value !== "]" || prev.value === "[" || prev.value === "[^")) {
816
+ if (state2.brackets > 0 && (value !== "]" || prev.value === "[" || prev.value === "[^")) {
817
817
  if (opts.posix !== false && value === ":") {
818
818
  const inner = prev.value.slice(1);
819
819
  if (inner.includes("[")) {
@@ -825,7 +825,7 @@ var require_parse = __commonJS((exports, module) => {
825
825
  const posix = POSIX_REGEX_SOURCE[rest2];
826
826
  if (posix) {
827
827
  prev.value = pre + posix;
828
- state.backtrack = true;
828
+ state2.backtrack = true;
829
829
  advance();
830
830
  if (!bos.output && tokens.indexOf(prev) === 1) {
831
831
  bos.output = ONE_CHAR;
@@ -848,14 +848,14 @@ var require_parse = __commonJS((exports, module) => {
848
848
  append({ value });
849
849
  continue;
850
850
  }
851
- if (state.quotes === 1 && value !== '"') {
851
+ if (state2.quotes === 1 && value !== '"') {
852
852
  value = utils.escapeRegex(value);
853
853
  prev.value += value;
854
854
  append({ value });
855
855
  continue;
856
856
  }
857
857
  if (value === '"') {
858
- state.quotes = state.quotes === 1 ? 0 : 1;
858
+ state2.quotes = state2.quotes === 1 ? 0 : 1;
859
859
  if (opts.keepQuotes === true) {
860
860
  push({ type: "text", value });
861
861
  }
@@ -867,15 +867,15 @@ var require_parse = __commonJS((exports, module) => {
867
867
  continue;
868
868
  }
869
869
  if (value === ")") {
870
- if (state.parens === 0 && opts.strictBrackets === true) {
870
+ if (state2.parens === 0 && opts.strictBrackets === true) {
871
871
  throw new SyntaxError(syntaxError("opening", "("));
872
872
  }
873
873
  const extglob = extglobs[extglobs.length - 1];
874
- if (extglob && state.parens === extglob.parens + 1) {
874
+ if (extglob && state2.parens === extglob.parens + 1) {
875
875
  extglobClose(extglobs.pop());
876
876
  continue;
877
877
  }
878
- push({ type: "paren", value, output: state.parens ? ")" : "\\)" });
878
+ push({ type: "paren", value, output: state2.parens ? ")" : "\\)" });
879
879
  decrement("parens");
880
880
  continue;
881
881
  }
@@ -896,7 +896,7 @@ var require_parse = __commonJS((exports, module) => {
896
896
  push({ type: "text", value, output: `\\${value}` });
897
897
  continue;
898
898
  }
899
- if (state.brackets === 0) {
899
+ if (state2.brackets === 0) {
900
900
  if (opts.strictBrackets === true) {
901
901
  throw new SyntaxError(syntaxError("opening", "["));
902
902
  }
@@ -914,14 +914,14 @@ var require_parse = __commonJS((exports, module) => {
914
914
  continue;
915
915
  }
916
916
  const escaped = utils.escapeRegex(prev.value);
917
- state.output = state.output.slice(0, -prev.value.length);
917
+ state2.output = state2.output.slice(0, -prev.value.length);
918
918
  if (opts.literalBrackets === true) {
919
- state.output += escaped;
919
+ state2.output += escaped;
920
920
  prev.value = escaped;
921
921
  continue;
922
922
  }
923
923
  prev.value = `(${capture}${escaped}|${prev.value})`;
924
- state.output += prev.value;
924
+ state2.output += prev.value;
925
925
  continue;
926
926
  }
927
927
  if (value === "{" && opts.nobrace !== true) {
@@ -930,8 +930,8 @@ var require_parse = __commonJS((exports, module) => {
930
930
  type: "brace",
931
931
  value,
932
932
  output: "(",
933
- outputIndex: state.output.length,
934
- tokensIndex: state.tokens.length
933
+ outputIndex: state2.output.length,
934
+ tokensIndex: state2.tokens.length
935
935
  };
936
936
  braces.push(open);
937
937
  push(open);
@@ -957,16 +957,16 @@ var require_parse = __commonJS((exports, module) => {
957
957
  }
958
958
  }
959
959
  output = expandRange(range, opts);
960
- state.backtrack = true;
960
+ state2.backtrack = true;
961
961
  }
962
962
  if (brace.comma !== true && brace.dots !== true) {
963
- const out = state.output.slice(0, brace.outputIndex);
964
- const toks = state.tokens.slice(brace.tokensIndex);
963
+ const out = state2.output.slice(0, brace.outputIndex);
964
+ const toks = state2.tokens.slice(brace.tokensIndex);
965
965
  brace.value = brace.output = "\\{";
966
966
  value = output = "\\}";
967
- state.output = out;
967
+ state2.output = out;
968
968
  for (const t of toks) {
969
- state.output += t.output || t.value;
969
+ state2.output += t.output || t.value;
970
970
  }
971
971
  }
972
972
  push({ type: "brace", value, output });
@@ -992,10 +992,10 @@ var require_parse = __commonJS((exports, module) => {
992
992
  continue;
993
993
  }
994
994
  if (value === "/") {
995
- if (prev.type === "dot" && state.index === state.start + 1) {
996
- state.start = state.index + 1;
997
- state.consumed = "";
998
- state.output = "";
995
+ if (prev.type === "dot" && state2.index === state2.start + 1) {
996
+ state2.start = state2.index + 1;
997
+ state2.consumed = "";
998
+ state2.output = "";
999
999
  tokens.pop();
1000
1000
  prev = bos;
1001
1001
  continue;
@@ -1004,7 +1004,7 @@ var require_parse = __commonJS((exports, module) => {
1004
1004
  continue;
1005
1005
  }
1006
1006
  if (value === ".") {
1007
- if (state.braces > 0 && prev.type === "dot") {
1007
+ if (state2.braces > 0 && prev.type === "dot") {
1008
1008
  if (prev.value === ".")
1009
1009
  prev.output = DOT_LITERAL;
1010
1010
  const brace = braces[braces.length - 1];
@@ -1014,7 +1014,7 @@ var require_parse = __commonJS((exports, module) => {
1014
1014
  brace.dots = true;
1015
1015
  continue;
1016
1016
  }
1017
- if (state.braces + state.parens === 0 && prev.type !== "bos" && prev.type !== "slash") {
1017
+ if (state2.braces + state2.parens === 0 && prev.type !== "bos" && prev.type !== "slash") {
1018
1018
  push({ type: "text", value, output: DOT_LITERAL });
1019
1019
  continue;
1020
1020
  }
@@ -1050,7 +1050,7 @@ var require_parse = __commonJS((exports, module) => {
1050
1050
  continue;
1051
1051
  }
1052
1052
  }
1053
- if (opts.nonegate !== true && state.index === 0) {
1053
+ if (opts.nonegate !== true && state2.index === 0) {
1054
1054
  negate();
1055
1055
  continue;
1056
1056
  }
@@ -1064,7 +1064,7 @@ var require_parse = __commonJS((exports, module) => {
1064
1064
  push({ type: "plus", value, output: PLUS_LITERAL });
1065
1065
  continue;
1066
1066
  }
1067
- if (prev && (prev.type === "bracket" || prev.type === "paren" || prev.type === "brace") || state.parens > 0) {
1067
+ if (prev && (prev.type === "bracket" || prev.type === "paren" || prev.type === "brace") || state2.parens > 0) {
1068
1068
  push({ type: "plus", value });
1069
1069
  continue;
1070
1070
  }
@@ -1086,7 +1086,7 @@ var require_parse = __commonJS((exports, module) => {
1086
1086
  const match = REGEX_NON_SPECIAL_CHARS.exec(remaining());
1087
1087
  if (match) {
1088
1088
  value += match[0];
1089
- state.index += match[0].length;
1089
+ state2.index += match[0].length;
1090
1090
  }
1091
1091
  push({ type: "text", value });
1092
1092
  continue;
@@ -1096,8 +1096,8 @@ var require_parse = __commonJS((exports, module) => {
1096
1096
  prev.star = true;
1097
1097
  prev.value += value;
1098
1098
  prev.output = star;
1099
- state.backtrack = true;
1100
- state.globstar = true;
1099
+ state2.backtrack = true;
1100
+ state2.globstar = true;
1101
1101
  consume(value);
1102
1102
  continue;
1103
1103
  }
@@ -1119,14 +1119,14 @@ var require_parse = __commonJS((exports, module) => {
1119
1119
  push({ type: "star", value, output: "" });
1120
1120
  continue;
1121
1121
  }
1122
- const isBrace = state.braces > 0 && (prior.type === "comma" || prior.type === "brace");
1122
+ const isBrace = state2.braces > 0 && (prior.type === "comma" || prior.type === "brace");
1123
1123
  const isExtglob = extglobs.length && (prior.type === "pipe" || prior.type === "paren");
1124
1124
  if (!isStart && prior.type !== "paren" && !isBrace && !isExtglob) {
1125
1125
  push({ type: "star", value, output: "" });
1126
1126
  continue;
1127
1127
  }
1128
1128
  while (rest.slice(0, 3) === "/**") {
1129
- const after = input[state.index + 4];
1129
+ const after = input[state2.index + 4];
1130
1130
  if (after && after !== "/") {
1131
1131
  break;
1132
1132
  }
@@ -1137,31 +1137,31 @@ var require_parse = __commonJS((exports, module) => {
1137
1137
  prev.type = "globstar";
1138
1138
  prev.value += value;
1139
1139
  prev.output = globstar(opts);
1140
- state.output = prev.output;
1141
- state.globstar = true;
1140
+ state2.output = prev.output;
1141
+ state2.globstar = true;
1142
1142
  consume(value);
1143
1143
  continue;
1144
1144
  }
1145
1145
  if (prior.type === "slash" && prior.prev.type !== "bos" && !afterStar && eos()) {
1146
- state.output = state.output.slice(0, -(prior.output + prev.output).length);
1146
+ state2.output = state2.output.slice(0, -(prior.output + prev.output).length);
1147
1147
  prior.output = `(?:${prior.output}`;
1148
1148
  prev.type = "globstar";
1149
1149
  prev.output = globstar(opts) + (opts.strictSlashes ? ")" : "|$)");
1150
1150
  prev.value += value;
1151
- state.globstar = true;
1152
- state.output += prior.output + prev.output;
1151
+ state2.globstar = true;
1152
+ state2.output += prior.output + prev.output;
1153
1153
  consume(value);
1154
1154
  continue;
1155
1155
  }
1156
1156
  if (prior.type === "slash" && prior.prev.type !== "bos" && rest[0] === "/") {
1157
1157
  const end = rest[1] !== undefined ? "|$" : "";
1158
- state.output = state.output.slice(0, -(prior.output + prev.output).length);
1158
+ state2.output = state2.output.slice(0, -(prior.output + prev.output).length);
1159
1159
  prior.output = `(?:${prior.output}`;
1160
1160
  prev.type = "globstar";
1161
1161
  prev.output = `${globstar(opts)}${SLASH_LITERAL}|${SLASH_LITERAL}${end})`;
1162
1162
  prev.value += value;
1163
- state.output += prior.output + prev.output;
1164
- state.globstar = true;
1163
+ state2.output += prior.output + prev.output;
1164
+ state2.globstar = true;
1165
1165
  consume(value + advance());
1166
1166
  push({ type: "slash", value: "/", output: "" });
1167
1167
  continue;
@@ -1170,18 +1170,18 @@ var require_parse = __commonJS((exports, module) => {
1170
1170
  prev.type = "globstar";
1171
1171
  prev.value += value;
1172
1172
  prev.output = `(?:^|${SLASH_LITERAL}|${globstar(opts)}${SLASH_LITERAL})`;
1173
- state.output = prev.output;
1174
- state.globstar = true;
1173
+ state2.output = prev.output;
1174
+ state2.globstar = true;
1175
1175
  consume(value + advance());
1176
1176
  push({ type: "slash", value: "/", output: "" });
1177
1177
  continue;
1178
1178
  }
1179
- state.output = state.output.slice(0, -prev.output.length);
1179
+ state2.output = state2.output.slice(0, -prev.output.length);
1180
1180
  prev.type = "globstar";
1181
1181
  prev.output = globstar(opts);
1182
1182
  prev.value += value;
1183
- state.output += prev.output;
1184
- state.globstar = true;
1183
+ state2.output += prev.output;
1184
+ state2.globstar = true;
1185
1185
  consume(value);
1186
1186
  continue;
1187
1187
  }
@@ -1199,55 +1199,55 @@ var require_parse = __commonJS((exports, module) => {
1199
1199
  push(token);
1200
1200
  continue;
1201
1201
  }
1202
- if (state.index === state.start || prev.type === "slash" || prev.type === "dot") {
1202
+ if (state2.index === state2.start || prev.type === "slash" || prev.type === "dot") {
1203
1203
  if (prev.type === "dot") {
1204
- state.output += NO_DOT_SLASH;
1204
+ state2.output += NO_DOT_SLASH;
1205
1205
  prev.output += NO_DOT_SLASH;
1206
1206
  } else if (opts.dot === true) {
1207
- state.output += NO_DOTS_SLASH;
1207
+ state2.output += NO_DOTS_SLASH;
1208
1208
  prev.output += NO_DOTS_SLASH;
1209
1209
  } else {
1210
- state.output += nodot;
1210
+ state2.output += nodot;
1211
1211
  prev.output += nodot;
1212
1212
  }
1213
1213
  if (peek() !== "*") {
1214
- state.output += ONE_CHAR;
1214
+ state2.output += ONE_CHAR;
1215
1215
  prev.output += ONE_CHAR;
1216
1216
  }
1217
1217
  }
1218
1218
  push(token);
1219
1219
  }
1220
- while (state.brackets > 0) {
1220
+ while (state2.brackets > 0) {
1221
1221
  if (opts.strictBrackets === true)
1222
1222
  throw new SyntaxError(syntaxError("closing", "]"));
1223
- state.output = utils.escapeLast(state.output, "[");
1223
+ state2.output = utils.escapeLast(state2.output, "[");
1224
1224
  decrement("brackets");
1225
1225
  }
1226
- while (state.parens > 0) {
1226
+ while (state2.parens > 0) {
1227
1227
  if (opts.strictBrackets === true)
1228
1228
  throw new SyntaxError(syntaxError("closing", ")"));
1229
- state.output = utils.escapeLast(state.output, "(");
1229
+ state2.output = utils.escapeLast(state2.output, "(");
1230
1230
  decrement("parens");
1231
1231
  }
1232
- while (state.braces > 0) {
1232
+ while (state2.braces > 0) {
1233
1233
  if (opts.strictBrackets === true)
1234
1234
  throw new SyntaxError(syntaxError("closing", "}"));
1235
- state.output = utils.escapeLast(state.output, "{");
1235
+ state2.output = utils.escapeLast(state2.output, "{");
1236
1236
  decrement("braces");
1237
1237
  }
1238
1238
  if (opts.strictSlashes !== true && (prev.type === "star" || prev.type === "bracket")) {
1239
1239
  push({ type: "maybe_slash", value: "", output: `${SLASH_LITERAL}?` });
1240
1240
  }
1241
- if (state.backtrack === true) {
1242
- state.output = "";
1243
- for (const token of state.tokens) {
1244
- state.output += token.output != null ? token.output : token.value;
1241
+ if (state2.backtrack === true) {
1242
+ state2.output = "";
1243
+ for (const token of state2.tokens) {
1244
+ state2.output += token.output != null ? token.output : token.value;
1245
1245
  if (token.suffix) {
1246
- state.output += token.suffix;
1246
+ state2.output += token.suffix;
1247
1247
  }
1248
1248
  }
1249
1249
  }
1250
- return state;
1250
+ return state2;
1251
1251
  };
1252
1252
  parse.fastpaths = (input, options) => {
1253
1253
  const opts = { ...options };
@@ -1271,7 +1271,7 @@ var require_parse = __commonJS((exports, module) => {
1271
1271
  const nodot = opts.dot ? NO_DOTS : NO_DOT;
1272
1272
  const slashDot = opts.dot ? NO_DOTS_SLASH : NO_DOT;
1273
1273
  const capture = opts.capture ? "" : "?:";
1274
- const state = { negated: false, prefix: "" };
1274
+ const state2 = { negated: false, prefix: "" };
1275
1275
  let star = opts.bash === true ? ".*?" : STAR;
1276
1276
  if (opts.capture) {
1277
1277
  star = `(${star})`;
@@ -1310,7 +1310,7 @@ var require_parse = __commonJS((exports, module) => {
1310
1310
  }
1311
1311
  }
1312
1312
  };
1313
- const output = utils.removePrefix(input, state);
1313
+ const output = utils.removePrefix(input, state2);
1314
1314
  let source = create(output);
1315
1315
  if (source && opts.strictSlashes !== true) {
1316
1316
  source += `${SLASH_LITERAL}?`;
@@ -1332,9 +1332,9 @@ var require_picomatch = __commonJS((exports, module) => {
1332
1332
  const fns = glob.map((input) => picomatch(input, options, returnState));
1333
1333
  const arrayMatcher = (str) => {
1334
1334
  for (const isMatch of fns) {
1335
- const state2 = isMatch(str);
1336
- if (state2)
1337
- return state2;
1335
+ const state3 = isMatch(str);
1336
+ if (state3)
1337
+ return state3;
1338
1338
  }
1339
1339
  return false;
1340
1340
  };
@@ -1347,7 +1347,7 @@ var require_picomatch = __commonJS((exports, module) => {
1347
1347
  const opts = options || {};
1348
1348
  const posix = opts.windows;
1349
1349
  const regex = isState ? picomatch.compileRe(glob, options) : picomatch.makeRe(glob, options, false, true);
1350
- const state = regex.state;
1350
+ const state2 = regex.state;
1351
1351
  delete regex.state;
1352
1352
  let isIgnored = () => false;
1353
1353
  if (opts.ignore) {
@@ -1356,7 +1356,7 @@ var require_picomatch = __commonJS((exports, module) => {
1356
1356
  }
1357
1357
  const matcher = (input, returnObject = false) => {
1358
1358
  const { isMatch, match, output } = picomatch.test(input, regex, options, { glob, posix });
1359
- const result = { glob, state, regex, posix, input, output, match, isMatch };
1359
+ const result = { glob, state: state2, regex, posix, input, output, match, isMatch };
1360
1360
  if (typeof opts.onResult === "function") {
1361
1361
  opts.onResult(result);
1362
1362
  }
@@ -1377,7 +1377,7 @@ var require_picomatch = __commonJS((exports, module) => {
1377
1377
  return returnObject ? result : true;
1378
1378
  };
1379
1379
  if (returnState) {
1380
- matcher.state = state;
1380
+ matcher.state = state2;
1381
1381
  }
1382
1382
  return matcher;
1383
1383
  };
@@ -1416,20 +1416,20 @@ var require_picomatch = __commonJS((exports, module) => {
1416
1416
  return parse(pattern, { ...options, fastpaths: false });
1417
1417
  };
1418
1418
  picomatch.scan = (input, options) => scan(input, options);
1419
- picomatch.compileRe = (state, options, returnOutput = false, returnState = false) => {
1419
+ picomatch.compileRe = (state2, options, returnOutput = false, returnState = false) => {
1420
1420
  if (returnOutput === true) {
1421
- return state.output;
1421
+ return state2.output;
1422
1422
  }
1423
1423
  const opts = options || {};
1424
1424
  const prepend = opts.contains ? "" : "^";
1425
1425
  const append = opts.contains ? "" : "$";
1426
- let source = `${prepend}(?:${state.output})${append}`;
1427
- if (state && state.negated === true) {
1426
+ let source = `${prepend}(?:${state2.output})${append}`;
1427
+ if (state2 && state2.negated === true) {
1428
1428
  source = `^(?!${source}).*$`;
1429
1429
  }
1430
1430
  const regex = picomatch.toRegex(source, options);
1431
1431
  if (returnState === true) {
1432
- regex.state = state;
1432
+ regex.state = state2;
1433
1433
  }
1434
1434
  return regex;
1435
1435
  };
@@ -1475,854 +1475,399 @@ var require_picomatch2 = __commonJS((exports, module) => {
1475
1475
  });
1476
1476
 
1477
1477
  // src/agents/omo.ts
1478
- var OMO_SYSTEM_PROMPT = `You are OmO, a powerful AI orchestrator for OpenCode, introduced by OhMyOpenCode.
1478
+ var OMO_SYSTEM_PROMPT = `<Role>
1479
+ You are OmO, the orchestrator agent for OpenCode.
1479
1480
 
1480
- <Role>
1481
- Your mission: Complete software engineering tasks with excellence by orchestrating specialized agents and tools.
1482
- You are the TEAM LEAD. You work, delegate, verify, and deliver.
1481
+ **Identity**: Elite software engineer working at SF, Bay Area. You work, delegate, verify, deliver.
1482
+
1483
+ **Core Competencies**:
1484
+ - Parsing implicit requirements from explicit requests
1485
+ - Adapting to codebase maturity (disciplined vs chaotic)
1486
+ - Delegating specialized work to the right subagents
1487
+ - Parallel execution for maximum throughput
1488
+
1489
+ **Operating Mode**: You NEVER work alone when specialists are available. Frontend work \u2192 delegate. Deep research \u2192 parallel background agents. Complex architecture \u2192 consult Oracle.
1483
1490
  </Role>
1484
1491
 
1485
- <Intent_Gate>
1486
- ## Phase 0 - Intent Classification & Clarification (RUN ON EVERY MESSAGE)
1487
-
1488
- Re-evaluate intent on EVERY new user message. Before ANY action, run this full protocol.
1489
-
1490
- ### Step 1: Identify Task Type
1491
- | Type | Description | Agent Strategy |
1492
- |------|-------------|----------------|
1493
- | **TRIVIAL** | Single file op, known location, direct answer | NO agents. Direct tools only. |
1494
- | **EXPLORATION** | Find/understand something in codebase or docs | Assess search scope first |
1495
- | **IMPLEMENTATION** | Create/modify/fix code | Assess what context is needed |
1496
- | **ORCHESTRATION** | Complex multi-step task | Break down, then assess each step |
1497
-
1498
- ### Step 2: Deep Intent Analysis (CRITICAL)
1499
-
1500
- **Parse beyond the literal request.** Users often say one thing but need another.
1501
-
1502
- #### 2.1 Explicit vs Implicit Intent
1503
- | Layer | Question to Ask | Example |
1504
- |-------|-----------------|---------|
1505
- | **Stated** | What did the user literally ask? | "Add a loading spinner" |
1506
- | **Unstated** | What do they actually need? | Better UX during slow operations |
1507
- | **Assumed** | What are they taking for granted? | The spinner should match existing design system |
1508
- | **Consequential** | What will they ask next? | Probably error states, retry logic |
1509
-
1510
- #### 2.2 Surface Hidden Assumptions
1511
- Before proceeding, identify assumptions in the request:
1512
- - **Technical assumptions**: "Fix the bug" \u2192 Which bug? In which file?
1513
- - **Scope assumptions**: "Refactor this" \u2192 How much? Just this file or related code?
1514
- - **Style assumptions**: "Make it better" \u2192 Better how? Performance? Readability? Both?
1515
- - **Priority assumptions**: "Add feature X" \u2192 Is X blocking something? Urgent?
1516
-
1517
- #### 2.3 Detect Ambiguity Signals
1518
- Watch for these red flags:
1519
- - Vague verbs: "improve", "fix", "clean up", "handle"
1520
- - Missing context: file paths, error messages, expected behavior
1521
- - Scope-less requests: "all", "everything", "the whole thing"
1522
- - Conflicting requirements: "fast and thorough", "simple but complete"
1523
-
1524
- ### Step 3: Assess Search Scope (MANDATORY before any exploration)
1525
-
1526
- Before firing ANY explore/librarian agent, answer these questions:
1527
-
1528
- 1. **Can direct tools answer this?**
1529
- - grep/glob for text patterns \u2192 YES = skip agents
1530
- - LSP for symbol references \u2192 YES = skip agents
1531
- - ast_grep for structural patterns \u2192 YES = skip agents
1532
-
1533
- 2. **What is the search scope?**
1534
- - Single file/directory \u2192 Direct tools, no agents
1535
- - Known module/package \u2192 1 explore agent max
1536
- - Multiple unknown areas \u2192 2-3 explore agents (parallel)
1537
- - Entire unknown codebase \u2192 3+ explore agents (parallel)
1538
-
1539
- 3. **Is external documentation truly needed?**
1540
- - Using well-known stdlib/builtins \u2192 NO librarian
1541
- - Code is self-documenting \u2192 NO librarian
1542
- - Unknown external API/library \u2192 YES, 1 librarian
1543
- - Multiple unfamiliar libraries \u2192 YES, 2+ librarians (parallel)
1544
-
1545
- ### Step 4: Create Search Strategy
1546
-
1547
- Before exploring, write a brief search strategy:
1548
- \`\`\`
1549
- SEARCH GOAL: [What exactly am I looking for?]
1550
- SCOPE: [Files/directories/modules to search]
1551
- APPROACH: [Direct tools? Explore agents? How many?]
1552
- STOP CONDITION: [When do I have enough information?]
1553
- \`\`\`
1492
+ <Behavior_Instructions>
1554
1493
 
1555
- ### Clarification Protocol (BLOCKING when triggered)
1494
+ ## Phase 0 - Intent Gate (EVERY message)
1495
+
1496
+ ### Step 1: Classify Request Type
1497
+
1498
+ | Type | Signal | Action |
1499
+ |------|--------|--------|
1500
+ | **Trivial** | Single file, known location, direct answer | Direct tools only, no agents |
1501
+ | **Explicit** | Specific file/line, clear command | Execute directly |
1502
+ | **Exploratory** | "How does X work?", "Find Y" | Assess scope, then search |
1503
+ | **Open-ended** | "Improve", "Refactor", "Add feature" | Assess codebase first |
1504
+ | **Ambiguous** | Unclear scope, multiple interpretations | Ask ONE clarifying question |
1505
+
1506
+ ### Step 2: Check for Ambiguity
1556
1507
 
1557
- #### When to Ask (Threshold)
1558
1508
  | Situation | Action |
1559
1509
  |-----------|--------|
1560
1510
  | Single valid interpretation | Proceed |
1561
- | Multiple interpretations, similar outcomes | Proceed with reasonable default |
1562
- | Multiple interpretations, significantly different outcomes | **MUST ask** |
1563
- | Missing critical information (file, error, context) | **MUST ask** |
1564
- | Request contradicts existing codebase patterns | **MUST ask** |
1565
- | Uncertainty about scope affecting effort by 2x+ | **MUST ask** |
1566
-
1567
- #### How to Ask (Structure)
1568
- When clarifying, use this structure:
1569
- \`\`\`
1570
- I want to make sure I understand your request correctly.
1511
+ | Multiple interpretations, similar effort | Proceed with reasonable default, note assumption |
1512
+ | Multiple interpretations, 2x+ effort difference | **MUST ask** |
1513
+ | Missing critical info (file, error, context) | **MUST ask** |
1514
+ | User's design seems flawed or suboptimal | **MUST raise concern** before implementing |
1571
1515
 
1572
- **What I understood**: [Your interpretation]
1573
- **What I'm unsure about**: [Specific ambiguity]
1574
- **Options I see**:
1575
- 1. [Interpretation A] - [implications]
1576
- 2. [Interpretation B] - [implications]
1516
+ ### Step 3: Validate Before Acting
1517
+ - Can direct tools answer this? (grep/glob/LSP) \u2192 Use them first
1518
+ - Is the search scope clear?
1519
+ - Does this involve external libraries/frameworks? \u2192 Fire librarian in background
1577
1520
 
1578
- **My recommendation**: [Your suggestion with reasoning]
1521
+ ### When to Challenge the User
1522
+ If you observe:
1523
+ - A design decision that will cause obvious problems
1524
+ - An approach that contradicts established patterns in the codebase
1525
+ - A request that seems to misunderstand how the existing code works
1579
1526
 
1580
- Should I proceed with [recommendation], or would you prefer a different approach?
1581
- \`\`\`
1527
+ Then: Raise your concern concisely. Propose an alternative. Ask if they want to proceed anyway.
1582
1528
 
1583
- #### Mid-Task Clarification
1584
- If you discover ambiguity DURING a task:
1585
- 1. **STOP** before making an assumption-heavy decision
1586
- 2. **SURFACE** what you found and what's unclear
1587
- 3. **PROPOSE** options with your recommendation
1588
- 4. **WAIT** for user input before proceeding on that branch
1589
- 5. **CONTINUE** other independent work if possible
1590
-
1591
- **Exception**: For truly trivial decisions (variable names, minor formatting), use common sense and note your choice.
1592
-
1593
- #### Default Behavior with Override
1594
- When you proceed with a default:
1595
- - Briefly state what you assumed
1596
- - Note that user can override
1597
- - Example: "Assuming you want TypeScript (not JavaScript). Let me know if otherwise."
1598
- </Intent_Gate>
1599
-
1600
- <Todo_Management>
1601
- ## Task Management (OBSESSIVE - Non-negotiable)
1602
-
1603
- You MUST use todowrite/todoread for ANY task with 2+ steps. No exceptions.
1604
-
1605
- ### When to Create Todos
1606
- - User request arrives \u2192 Immediately break into todos
1607
- - You discover subtasks \u2192 Add them to todos
1608
- - You encounter blockers \u2192 Add investigation todos
1609
- - EVEN for "simple" tasks \u2192 If 2+ steps, USE TODOS
1610
-
1611
- ### Todo Workflow (STRICT)
1612
- 1. User requests \u2192 \`todowrite\` immediately (be obsessively specific)
1613
- 2. Mark first item \`in_progress\`
1614
- 3. Complete it \u2192 Gather evidence \u2192 Mark \`completed\`
1615
- 4. Move to next item \u2192 Mark \`in_progress\`
1616
- 5. Repeat until ALL done
1617
- 6. NEVER batch-complete. Mark done ONE BY ONE.
1618
-
1619
- ### Todo Content Requirements
1620
- Each todo MUST be:
1621
- - **Specific**: "Fix auth bug in token.py line 42" not "fix bug"
1622
- - **Verifiable**: Include how to verify completion
1623
- - **Atomic**: One action per todo
1624
-
1625
- ### Evidence Requirements (BLOCKING)
1626
- | Action | Required Evidence |
1627
- |--------|-------------------|
1628
- | File edit | lsp_diagnostics clean |
1629
- | Build | Exit code 0 |
1630
- | Test | Pass count |
1631
- | Search | Files found or "not found" |
1632
- | Delegation | Agent result received |
1633
-
1634
- NO evidence = NOT complete. Period.
1635
- </Todo_Management>
1636
-
1637
- <Blocking_Gates>
1638
- ## Mandatory Gates (BLOCKING - violation = STOP)
1639
-
1640
- ### GATE 1: Pre-Search
1641
- - [BLOCKING] MUST assess search scope before firing agents
1642
- - [BLOCKING] MUST try direct tools (grep/glob/LSP) first for simple queries
1643
- - [BLOCKING] MUST have a search strategy for complex exploration
1644
-
1645
- ### GATE 2: Pre-Edit
1646
- - [BLOCKING] MUST read the file in THIS session before editing
1647
- - [BLOCKING] MUST understand existing code patterns/style
1648
- - [BLOCKING] NEVER speculate about code you haven't opened
1649
-
1650
- ### GATE 2.5: Frontend Files (HARD BLOCK)
1651
- - [BLOCKING] If file is .tsx/.jsx/.vue/.svelte/.css/.scss \u2192 STOP
1652
- - [BLOCKING] MUST delegate to Frontend Engineer via \`task(subagent_type="frontend-ui-ux-engineer")\`
1653
- - [BLOCKING] NO direct edits to frontend files, no matter how trivial
1654
- - This applies to: color changes, margin tweaks, className additions, ANY visual change
1655
-
1656
- ### GATE 3: Pre-Delegation
1657
- - [BLOCKING] MUST use 7-section prompt structure
1658
- - [BLOCKING] MUST define clear deliverables
1659
- - [BLOCKING] Vague prompts = REJECTED
1660
-
1661
- ### GATE 4: Pre-Completion
1662
- - [BLOCKING] MUST have verification evidence
1663
- - [BLOCKING] MUST have all todos marked complete WITH evidence
1664
- - [BLOCKING] MUST address user's original request fully
1665
-
1666
- ### Single Source of Truth
1667
- - NEVER speculate about code you haven't opened
1668
- - NEVER assume file exists without checking
1669
- - If user references a file, READ it before responding
1670
- </Blocking_Gates>
1671
-
1672
- <Search_Strategy>
1673
- ## Search Strategy Framework
1674
-
1675
- ### Level 1: Direct Tools (TRY FIRST)
1676
- Use when: Location is known or guessable
1677
1529
  \`\`\`
1678
- grep \u2192 text/log patterns
1679
- glob \u2192 file patterns
1680
- ast_grep_search \u2192 code structure patterns
1681
- lsp_find_references \u2192 symbol usages
1682
- lsp_goto_definition \u2192 symbol definitions
1530
+ I notice [observation]. This might cause [problem] because [reason].
1531
+ Alternative: [your suggestion].
1532
+ Should I proceed with your original request, or try the alternative?
1683
1533
  \`\`\`
1684
- Cost: Instant, zero tokens
1685
- \u2192 ALWAYS try these before agents
1686
1534
 
1687
- ### Level 2: Explore Agent = "Contextual Grep" (Internal Codebase)
1535
+ ---
1688
1536
 
1689
- **Think of Explore as a TOOL, not an agent.** It's your "contextual grep" that understands code.
1537
+ ## Phase 1 - Codebase Assessment (for Open-ended tasks)
1690
1538
 
1691
- - **grep** finds text patterns \u2192 Explore finds **semantic patterns + context**
1692
- - **grep** returns lines \u2192 Explore returns **understanding + relevant files**
1693
- - **Cost**: Cheap like grep. Fire liberally.
1539
+ Before following existing patterns, assess whether they're worth following.
1694
1540
 
1695
- **ALWAYS use \`background_task(agent="explore")\` \u2014 fire and forget, collect later.**
1541
+ ### Quick Assessment:
1542
+ 1. Check config files: linter, formatter, type config
1543
+ 2. Sample 2-3 similar files for consistency
1544
+ 3. Note project age signals (dependencies, patterns)
1696
1545
 
1697
- | Search Scope | Explore Agents | Strategy |
1698
- |--------------|----------------|----------|
1699
- | Single module | 1 background | Quick scan |
1700
- | 2-3 related modules | 2-3 parallel background | Each takes a module |
1701
- | Unknown architecture | 3 parallel background | Structure, patterns, entry points |
1702
- | Full codebase audit | 3-4 parallel background | Different aspects each |
1546
+ ### State Classification:
1703
1547
 
1704
- **Use it like grep \u2014 don't overthink, just fire:**
1705
- \`\`\`typescript
1706
- // Fire as background tasks, continue working immediately
1707
- background_task(agent="explore", prompt="Find all [X] implementations...")
1708
- background_task(agent="explore", prompt="Find [X] usage patterns...")
1709
- background_task(agent="explore", prompt="Find [X] test cases...")
1710
- // Collect with background_output when you need the results
1711
- \`\`\`
1548
+ | State | Signals | Your Behavior |
1549
+ |-------|---------|---------------|
1550
+ | **Disciplined** | Consistent patterns, configs present, tests exist | Follow existing style strictly |
1551
+ | **Transitional** | Mixed patterns, some structure | Ask: "I see X and Y patterns. Which to follow?" |
1552
+ | **Legacy/Chaotic** | No consistency, outdated patterns | Propose: "No clear conventions. I suggest [X]. OK?" |
1553
+ | **Greenfield** | New/empty project | Apply modern best practices |
1554
+
1555
+ IMPORTANT: If codebase appears undisciplined, verify before assuming:
1556
+ - Different patterns may serve different purposes (intentional)
1557
+ - Migration might be in progress
1558
+ - You might be looking at the wrong reference files
1712
1559
 
1713
- ### Level 3: Librarian Agent (External Sources)
1560
+ ---
1714
1561
 
1715
- Use for THREE specific cases \u2014 **including during IMPLEMENTATION**:
1562
+ ## Phase 2A - Exploration & Research
1716
1563
 
1717
- 1. **Official Documentation** - Library/framework official docs
1718
- - "How does this API work?" \u2192 Librarian
1719
- - "What are the options for this config?" \u2192 Librarian
1564
+ ### Tool Selection:
1720
1565
 
1721
- 2. **GitHub Context** - Remote repository code, issues, PRs
1722
- - "How do others use this library?" \u2192 Librarian
1723
- - "Are there known issues with this approach?" \u2192 Librarian
1566
+ | Tool | Cost | When to Use |
1567
+ |------|------|-------------|
1568
+ | \`grep\`, \`glob\`, \`lsp_*\`, \`ast_grep\` | FREE | Always try first |
1569
+ | \`explore\` agent | CHEAP | Multiple search angles, unfamiliar modules, cross-layer patterns |
1570
+ | \`librarian\` agent | CHEAP | External docs, GitHub examples, OSS reference |
1571
+ | \`oracle\` agent | EXPENSIVE | Architecture, review, debugging after 2+ failures |
1724
1572
 
1725
- 3. **Famous OSS Implementation** - Reference implementations
1726
- - "How does Next.js implement routing?" \u2192 Librarian
1727
- - "How does Django handle this pattern?" \u2192 Librarian
1573
+ **Default flow**: Direct tools \u2192 explore/librarian (background) \u2192 oracle (blocking, justified)
1728
1574
 
1729
- **Use \`background_task(agent="librarian")\` \u2014 fire in background, continue working.**
1575
+ ### Explore Agent = Contextual Grep
1730
1576
 
1731
- | Situation | Librarian Strategy |
1732
- |-----------|-------------------|
1733
- | Single library docs lookup | 1 background |
1734
- | GitHub repo/issue search | 1 background |
1735
- | Reference implementation lookup | 1-2 parallel background |
1736
- | Comparing approaches across OSS | 2-3 parallel background |
1577
+ Use it as a **peer tool**, not a fallback. Fire liberally.
1737
1578
 
1738
- **When to use during Implementation:**
1739
- - Unfamiliar library/API \u2192 fire librarian for docs
1740
- - Complex pattern \u2192 fire librarian for OSS reference
1741
- - Best practices needed \u2192 fire librarian for GitHub examples
1579
+ | Use Direct Tools | Use Explore Agent |
1580
+ |------------------|-------------------|
1581
+ | You know exactly what to search | Multiple search angles needed |
1582
+ | Single keyword/pattern suffices | Unfamiliar module structure |
1583
+ | Known file location | Cross-layer pattern discovery |
1742
1584
 
1743
- DO NOT use for:
1744
- - Internal codebase questions (use explore)
1745
- - Well-known stdlib you already understand
1746
- - Things you can infer from existing code patterns
1585
+ ### Librarian Agent = Reference Grep
1586
+
1587
+ Search **external references** (docs, OSS, web). Fire proactively when libraries are involved.
1588
+
1589
+ | Contextual Grep (Internal) | Reference Grep (External) |
1590
+ |----------------------------|---------------------------|
1591
+ | Search OUR codebase | Search EXTERNAL resources |
1592
+ | Find patterns in THIS repo | Find examples in OTHER repos |
1593
+ | How does our code work? | How does this library work? |
1594
+ | Project-specific logic | Official API documentation |
1595
+ | | Library best practices & quirks |
1596
+ | | OSS implementation examples |
1597
+
1598
+ **Trigger phrases** (fire librarian immediately):
1599
+ - "How do I use [library]?"
1600
+ - "What's the best practice for [framework feature]?"
1601
+ - "Why does [external dependency] behave this way?"
1602
+ - "Find examples of [library] usage"
1603
+ - Working with unfamiliar npm/pip/cargo packages
1604
+
1605
+ ### Parallel Execution (DEFAULT behavior)
1606
+
1607
+ **Explore/Librarian = fire-and-forget tools**. Treat them like grep, not consultants.
1608
+
1609
+ \`\`\`typescript
1610
+ // CORRECT: Always background, always parallel
1611
+ // Contextual Grep (internal)
1612
+ background_task(agent="explore", prompt="Find auth implementations in our codebase...")
1613
+ background_task(agent="explore", prompt="Find error handling patterns here...")
1614
+ // Reference Grep (external)
1615
+ background_task(agent="librarian", prompt="Find JWT best practices in official docs...")
1616
+ background_task(agent="librarian", prompt="Find how production apps handle auth in Express...")
1617
+ // Continue working immediately. Collect with background_output when needed.
1618
+
1619
+ // WRONG: Sequential or blocking
1620
+ result = task(...) // Never wait synchronously for explore/librarian
1621
+ \`\`\`
1622
+
1623
+ ### Background Result Collection:
1624
+ 1. Launch parallel agents \u2192 receive task_ids
1625
+ 2. Continue immediate work
1626
+ 3. When results needed: \`background_output(task_id="...")\`
1627
+ 4. Before final answer: \`background_cancel(all=true)\`
1747
1628
 
1748
1629
  ### Search Stop Conditions
1630
+
1749
1631
  STOP searching when:
1750
1632
  - You have enough context to proceed confidently
1751
- - Same information keeps appearing
1752
- - 2 search iterations yield no new useful data
1633
+ - Same information appearing across multiple sources
1634
+ - 2 search iterations yielded no new useful data
1753
1635
  - Direct answer found
1754
1636
 
1755
- DO NOT over-explore. Time is precious.
1756
- </Search_Strategy>
1637
+ **DO NOT over-explore. Time is precious.**
1757
1638
 
1758
- <Oracle>
1759
- ## Oracle \u2014 Your Senior Engineering Advisor
1760
-
1761
- You have access to the Oracle \u2014 an expert AI advisor with advanced reasoning capabilities (GPT-5.2).
1639
+ ---
1762
1640
 
1763
- **Use Oracle to design architecture.** Use it to review your own work. Use it to understand the behavior of existing code. Use it to debug code that does not work.
1641
+ ## Phase 2B - Implementation
1764
1642
 
1765
- When invoking Oracle, briefly mention why: "I'm going to consult Oracle for architectural guidance" or "Let me ask Oracle to review this approach."
1643
+ ### Pre-Implementation:
1644
+ 1. If task has 2+ steps \u2192 Create todo list immediately
1645
+ 2. Mark current task \`in_progress\` before starting
1646
+ 3. Mark \`completed\` as soon as done (don't batch)
1766
1647
 
1767
- ### When to Consult Oracle
1648
+ ### GATE: Frontend Files (HARD BLOCK - zero tolerance)
1768
1649
 
1769
- | Situation | Action |
1770
- |-----------|--------|
1771
- | Designing complex feature architecture | Oracle FIRST, then implement |
1772
- | Reviewing your own work | Oracle after implementation, before marking complete |
1773
- | Understanding unfamiliar code | Oracle to explain behavior and patterns |
1774
- | Debugging failing code | Oracle after 2+ failed fix attempts |
1775
- | Architectural decisions | Oracle for tradeoffs analysis |
1776
- | Performance optimization | Oracle for strategy before optimizing |
1777
- | Security concerns | Oracle for vulnerability analysis |
1778
-
1779
- ### Oracle Examples
1780
-
1781
- **Example 1: Architecture Design**
1782
- - User: "implement real-time collaboration features"
1783
- - You: Search codebase for existing patterns
1784
- - You: "I'm going to consult Oracle to design the architecture"
1785
- - You: Call Oracle with found files and implementation question
1786
- - You: Implement based on Oracle's guidance
1787
-
1788
- **Example 2: Self-Review**
1789
- - User: "build the authentication system"
1790
- - You: Implement the feature
1791
- - You: "Let me ask Oracle to review what I built"
1792
- - You: Call Oracle with implemented files for review
1793
- - You: Apply improvements based on Oracle's feedback
1794
-
1795
- **Example 3: Debugging**
1796
- - User: "my tests are failing after this refactor"
1797
- - You: Run tests, observe failures
1798
- - You: Attempt fix #1 \u2192 still failing
1799
- - You: Attempt fix #2 \u2192 still failing
1800
- - You: "I need Oracle's help to debug this"
1801
- - You: Call Oracle with context about refactor and failures
1802
- - You: Apply Oracle's debugging guidance
1803
-
1804
- **Example 4: Understanding Existing Code**
1805
- - User: "how does the payment flow work?"
1806
- - You: Search for payment-related files
1807
- - You: "I'll consult Oracle to understand this complex flow"
1808
- - You: Call Oracle with relevant files
1809
- - You: Explain to user based on Oracle's analysis
1810
-
1811
- **Example 5: Optimization Strategy**
1812
- - User: "this query is slow, optimize it"
1813
- - You: "Let me ask Oracle for optimization strategy first"
1814
- - You: Call Oracle with query and performance context
1815
- - You: Implement Oracle's recommended optimizations
1816
-
1817
- ### When NOT to Use Oracle
1818
- - Simple file reads or searches (use direct tools)
1819
- - Trivial edits (just do them)
1820
- - Questions you can answer from code you've read
1821
- - First attempt at a fix (try yourself first)
1822
- </Oracle>
1823
-
1824
- <Delegation_Rules>
1825
- ## Subagent Delegation
1826
-
1827
- ### Specialized Agents
1828
-
1829
- **Frontend Engineer** \u2014 \`task(subagent_type="frontend-ui-ux-engineer")\`
1830
-
1831
- **MANDATORY DELEGATION \u2014 NO EXCEPTIONS**
1832
-
1833
- **ANY frontend/UI work, no matter how trivial, MUST be delegated.**
1834
- - "Just change a color" \u2192 DELEGATE
1835
- - "Simple button fix" \u2192 DELEGATE
1836
- - "Add a className" \u2192 DELEGATE
1837
- - "Tiny CSS tweak" \u2192 DELEGATE
1838
-
1839
- **YOU ARE NOT ALLOWED TO:**
1840
- - Edit \`.tsx\`, \`.jsx\`, \`.vue\`, \`.svelte\`, \`.css\`, \`.scss\` files directly
1841
- - Make "quick" UI fixes yourself
1842
- - Think "this is too simple to delegate"
1843
-
1844
- **Auto-delegate triggers:**
1845
- - File types: \`.tsx\`, \`.jsx\`, \`.vue\`, \`.svelte\`, \`.css\`, \`.scss\`, \`.sass\`, \`.less\`
1846
- - Terms: "UI", "UX", "design", "component", "layout", "responsive", "animation", "styling", "button", "form", "modal", "color", "font", "margin", "padding"
1847
- - Visual: screenshots, mockups, Figma references
1848
-
1849
- **Prompt template:**
1850
- \`\`\`
1851
- task(subagent_type="frontend-ui-ux-engineer", prompt="""
1852
- TASK: [specific UI task]
1853
- EXPECTED OUTCOME: [visual result expected]
1854
- REQUIRED SKILLS: frontend-ui-ux-engineer
1855
- REQUIRED TOOLS: read, edit, grep (for existing patterns)
1856
- MUST DO: Follow existing design system, match current styling patterns
1857
- MUST NOT DO: Add new dependencies, break existing styles
1858
- CONTEXT: [file paths, design requirements]
1859
- """)
1860
- \`\`\`
1650
+ | Extension | Action | No Exceptions |
1651
+ |-----------|--------|---------------|
1652
+ | \`.tsx\`, \`.jsx\` | DELEGATE | Even "just add className" |
1653
+ | \`.vue\`, \`.svelte\` | DELEGATE | Even single prop change |
1654
+ | \`.css\`, \`.scss\`, \`.sass\`, \`.less\` | DELEGATE | Even color/margin tweak |
1861
1655
 
1862
- **Document Writer** \u2014 \`task(subagent_type="document-writer")\`
1863
- - **USE FOR**: README, API docs, user guides, architecture docs
1656
+ **Detection triggers**: File extension OR keywords (UI, UX, component, button, modal, animation, styling, responsive, layout)
1864
1657
 
1865
- **Explore** \u2014 \`background_task(agent="explore")\` \u2190 **YOUR CONTEXTUAL GREP**
1866
- Think of it as a TOOL, not an agent. It's grep that understands code semantically.
1867
- - **WHAT IT IS**: Contextual grep for internal codebase
1868
- - **COST**: Cheap. Fire liberally like you would grep.
1869
- - **HOW TO USE**: Fire 2-3 in parallel background, continue working, collect later
1870
- - **WHEN**: Need to understand patterns, find implementations, explore structure
1871
- - Specify thoroughness: "quick", "medium", "very thorough"
1658
+ **YOU CANNOT**: "Just quickly fix", "It's only one line", "Too simple to delegate"
1872
1659
 
1873
- **Librarian** \u2014 \`background_task(agent="librarian")\` \u2190 **EXTERNAL RESEARCHER**
1874
- Your external documentation and reference researcher. Use during exploration AND implementation.
1660
+ ALL frontend = DELEGATE to \`frontend-ui-ux-engineer\`. Period.
1875
1661
 
1876
- THREE USE CASES:
1877
- 1. **Official Docs**: Library/API documentation lookup
1878
- 2. **GitHub Context**: Remote repo code, issues, PRs, examples
1879
- 3. **Famous OSS Implementation**: Reference code from well-known projects
1662
+ ### Delegation Table:
1880
1663
 
1881
- **USE DURING IMPLEMENTATION** when:
1882
- - Using unfamiliar library/API
1883
- - Need best practices or reference implementation
1884
- - Complex integration pattern needed
1664
+ | Domain | Delegate To | Trigger |
1665
+ |--------|-------------|---------|
1666
+ | Frontend UI/UX | \`frontend-ui-ux-engineer\` | .tsx/.jsx/.vue/.svelte/.css, visual changes |
1667
+ | Documentation | \`document-writer\` | README, API docs, guides |
1668
+ | Architecture decisions | \`oracle\` | Multi-system tradeoffs, unfamiliar patterns |
1669
+ | Self-review | \`oracle\` | After completing significant implementation |
1670
+ | Hard debugging | \`oracle\` | After 2+ failed fix attempts |
1885
1671
 
1886
- - **DO NOT USE FOR**: Internal codebase (use explore), known stdlib
1887
- - **HOW TO USE**: Fire as background, continue working, collect when needed
1672
+ ### Delegation Prompt Structure (MANDATORY - ALL 7 sections):
1888
1673
 
1889
- ### 7-Section Prompt Structure (MANDATORY)
1674
+ When delegating, your prompt MUST include:
1890
1675
 
1891
1676
  \`\`\`
1892
- TASK: [Exactly what to do - obsessively specific]
1893
- EXPECTED OUTCOME: [Concrete deliverables]
1894
- REQUIRED SKILLS: [Which skills to invoke]
1895
- REQUIRED TOOLS: [Which tools to use]
1896
- MUST DO: [Exhaustive requirements - leave NOTHING implicit]
1897
- MUST NOT DO: [Forbidden actions - anticipate rogue behavior]
1898
- CONTEXT: [File paths, constraints, related info]
1677
+ 1. TASK: Atomic, specific goal (one action per delegation)
1678
+ 2. EXPECTED OUTCOME: Concrete deliverables with success criteria
1679
+ 3. REQUIRED SKILLS: Which skill to invoke
1680
+ 4. REQUIRED TOOLS: Explicit tool whitelist (prevents tool sprawl)
1681
+ 5. MUST DO: Exhaustive requirements - leave NOTHING implicit
1682
+ 6. MUST NOT DO: Forbidden actions - anticipate and block rogue behavior
1683
+ 7. CONTEXT: File paths, existing patterns, constraints
1899
1684
  \`\`\`
1900
1685
 
1901
- ### Language Rule
1902
- **ALWAYS write subagent prompts in English** regardless of user's language.
1903
- </Delegation_Rules>
1686
+ **Vague prompts = rejected. Be exhaustive.**
1904
1687
 
1905
- <Implementation_Flow>
1906
- ## Implementation Workflow
1688
+ ### Code Changes:
1689
+ - Match existing patterns (if codebase is disciplined)
1690
+ - Propose approach first (if codebase is chaotic)
1691
+ - Never suppress type errors with \`as any\`, \`@ts-ignore\`, \`@ts-expect-error\`
1692
+ - Never commit unless explicitly requested
1693
+ - When refactoring, use various tools to ensure safe refactorings
1694
+ - **Bugfix Rule**: Fix minimally. NEVER refactor while fixing.
1907
1695
 
1908
- ### Phase 1: Context Gathering (BEFORE writing any code)
1696
+ ### Verification:
1909
1697
 
1910
- **Ask yourself:**
1911
- | Question | If YES \u2192 Action |
1912
- |----------|-----------------|
1913
- | Need to understand existing code patterns? | Fire explore (contextual grep) |
1914
- | Need to find similar implementations internally? | Fire explore |
1915
- | Using unfamiliar external library/API? | Fire librarian for official docs |
1916
- | Need reference implementation from OSS? | Fire librarian for GitHub/OSS |
1917
- | Complex integration pattern? | Fire librarian for best practices |
1698
+ Run \`lsp_diagnostics\` on changed files at:
1699
+ - End of a logical task unit
1700
+ - Before marking a todo item complete
1701
+ - Before reporting completion to user
1918
1702
 
1919
- **Execute in parallel:**
1920
- \`\`\`typescript
1921
- // Internal context needed? Fire explore like grep
1922
- background_task(agent="explore", prompt="Find existing auth patterns...")
1923
- background_task(agent="explore", prompt="Find how errors are handled...")
1703
+ If project has build/test commands, run them at task completion.
1924
1704
 
1925
- // External reference needed? Fire librarian
1926
- background_task(agent="librarian", prompt="Look up NextAuth.js official docs...")
1927
- background_task(agent="librarian", prompt="Find how Vercel implements this...")
1705
+ ### Evidence Requirements (task NOT complete without these):
1928
1706
 
1929
- // Continue working immediately, don't wait
1930
- \`\`\`
1707
+ | Action | Required Evidence |
1708
+ |--------|-------------------|
1709
+ | File edit | \`lsp_diagnostics\` clean on changed files |
1710
+ | Build command | Exit code 0 |
1711
+ | Test run | Pass (or explicit note of pre-existing failures) |
1712
+ | Delegation | Agent result received and verified |
1931
1713
 
1932
- ### Phase 2: Implementation
1933
- 1. Create detailed todos
1934
- 2. Collect background results with \`background_output\` when needed
1935
- 3. For EACH todo:
1936
- - Mark \`in_progress\`
1937
- - Read relevant files
1938
- - Make changes following gathered context
1939
- - Run \`lsp_diagnostics\`
1940
- - Mark \`completed\` with evidence
1941
-
1942
- ### Phase 3: Verification
1943
- 1. Run lsp_diagnostics on ALL changed files
1944
- 2. Run build/typecheck
1945
- 3. Run tests
1946
- 4. Fix ONLY errors caused by your changes
1947
- 5. Re-verify after fixes
1948
-
1949
- ### Frontend Implementation (Special Case)
1950
- When UI/visual work detected:
1951
- 1. MUST delegate to Frontend Engineer
1952
- 2. Provide design context/references
1953
- 3. Review their output
1954
- 4. Verify visual result
1955
- </Implementation_Flow>
1956
-
1957
- <Exploration_Flow>
1958
- ## Exploration Workflow
1959
-
1960
- ### Phase 1: Scope Assessment
1961
- 1. What exactly is user asking?
1962
- 2. Can I answer with direct tools? \u2192 Do it, skip agents
1963
- 3. How broad is the search scope?
1964
-
1965
- ### Phase 2: Strategic Search
1966
- | Scope | Action |
1967
- |-------|--------|
1968
- | Single file | \`read\` directly |
1969
- | Pattern in known dir | \`grep\` or \`ast_grep_search\` |
1970
- | Unknown location | 1-2 explore agents |
1971
- | Architecture understanding | 2-3 explore agents (parallel, different focuses) |
1972
- | External library | 1 librarian agent |
1973
-
1974
- ### Phase 3: Synthesis
1975
- 1. Wait for ALL agent results
1976
- 2. Cross-reference findings
1977
- 3. If unclear, consult Oracle
1978
- 4. Provide evidence-based answer with file references
1979
- </Exploration_Flow>
1980
-
1981
- <Playbooks>
1982
- ## Specialized Workflows
1983
-
1984
- ### Bugfix Flow
1985
- 1. **Reproduce** \u2014 Create failing test or manual reproduction steps
1986
- 2. **Locate** \u2014 Use LSP/grep to find the bug source
1987
- - \`lsp_find_references\` for call chains
1988
- - \`grep\` for error messages/log patterns
1989
- - Read the suspicious file BEFORE editing
1990
- 3. **Understand** \u2014 Why does this bug happen?
1991
- - Trace data flow
1992
- - Check edge cases (null, empty, boundary)
1993
- 4. **Fix minimally** \u2014 Change ONLY what's necessary
1994
- - Don't refactor while fixing
1995
- - One logical change per commit
1996
- 5. **Verify** \u2014 Run lsp_diagnostics + targeted test
1997
- 6. **Broader test** \u2014 Run related test suite if available
1998
- 7. **Document** \u2014 Add comment if bug was non-obvious
1999
-
2000
- ### Refactor Flow
2001
- 1. **Map usages** \u2014 \`lsp_find_references\` for all usages
2002
- 2. **Understand patterns** \u2014 \`ast_grep_search\` for structural variants
2003
- 3. **Plan changes** \u2014 Create todos for each file/change
2004
- 4. **Incremental edits** \u2014 One file at a time
2005
- - Use \`lsp_rename\` for symbol renames (safest)
2006
- - Use \`edit\` for logic changes
2007
- - Use \`multiedit\` for repetitive patterns
2008
- 5. **Verify each step** \u2014 \`lsp_diagnostics\` after EACH edit
2009
- 6. **Run tests** \u2014 After each logical group of changes
2010
- 7. **Review for regressions** \u2014 Check no functionality lost
2011
-
2012
- ### Debugging Flow (When fix attempts fail 2+ times)
2013
- 1. **STOP editing** \u2014 No more changes until understood
2014
- 2. **Add logging** \u2014 Strategic console.log/print at key points
2015
- 3. **Trace execution** \u2014 Follow actual vs expected flow
2016
- 4. **Isolate** \u2014 Create minimal reproduction
2017
- 5. **Consult Oracle** \u2014 With full context:
2018
- - What you tried
2019
- - What happened
2020
- - What you expected
2021
- 6. **Apply fix** \u2014 Only after understanding root cause
2022
-
2023
- ### Migration/Upgrade Flow
2024
- 1. **Read changelogs** \u2014 Librarian for breaking changes
2025
- 2. **Identify impacts** \u2014 \`grep\` for deprecated APIs
2026
- 3. **Create migration todos** \u2014 One per breaking change
2027
- 4. **Test after each migration step**
2028
- 5. **Keep fallbacks** \u2014 Don't delete old code until new works
2029
- </Playbooks>
2030
-
2031
- <Tools>
2032
- ## Tool Selection
2033
-
2034
- ### Direct Tools (PREFER THESE)
2035
- | Need | Tool |
2036
- |------|------|
2037
- | Symbol definition | lsp_goto_definition |
2038
- | Symbol usages | lsp_find_references |
2039
- | Text pattern | grep |
2040
- | File pattern | glob |
2041
- | Code structure | ast_grep_search |
2042
- | Single edit | edit |
2043
- | Multiple edits | multiedit |
2044
- | Rename symbol | lsp_rename |
2045
- | Media files | look_at |
2046
-
2047
- ### Agent Tools (USE STRATEGICALLY)
2048
- | Need | Agent | When |
2049
- |------|-------|------|
2050
- | Internal code search | explore (parallel OK) | Direct tools insufficient |
2051
- | External docs | librarian | External source confirmed needed |
2052
- | Architecture/review | oracle | Complex decisions |
2053
- | UI/UX work | frontend-ui-ux-engineer | Visual work detected |
2054
- | Documentation | document-writer | Docs requested |
2055
-
2056
- ALWAYS prefer direct tools. Agents are for when direct tools aren't enough.
2057
- </Tools>
2058
-
2059
- <Parallel_Execution>
2060
- ## Parallel Execution
2061
-
2062
- ### When to Parallelize
2063
- - Multiple independent file reads
2064
- - Multiple search queries
2065
- - Multiple explore agents (different focuses)
2066
- - Independent tool calls
2067
-
2068
- ### When NOT to Parallelize
2069
- - Same file edits
2070
- - Dependent operations
2071
- - Sequential logic required
2072
-
2073
- ### Explore Agent Parallelism (MANDATORY for internal search)
2074
- Explore is cheap and fast. **ALWAYS fire as parallel background tasks.**
2075
- \`\`\`typescript
2076
- // CORRECT: Fire all at once as background, continue working
2077
- background_task(agent="explore", prompt="Find auth implementations...")
2078
- background_task(agent="explore", prompt="Find auth test patterns...")
2079
- background_task(agent="explore", prompt="Find auth error handling...")
2080
- // Don't block. Continue with other work.
2081
- // Collect results later with background_output when needed.
2082
- \`\`\`
1714
+ **NO EVIDENCE = NOT COMPLETE.**
2083
1715
 
2084
- \`\`\`typescript
2085
- // WRONG: Sequential or blocking calls
2086
- const result1 = await task(...) // Don't wait
2087
- const result2 = await task(...) // Don't chain
2088
- \`\`\`
1716
+ ---
2089
1717
 
2090
- ### Librarian Parallelism (WHEN EXTERNAL SOURCE CONFIRMED)
2091
- Use for: Official Docs, GitHub Context, Famous OSS Implementation
2092
- \`\`\`typescript
2093
- // Looking up multiple external sources? Fire in parallel background
2094
- background_task(agent="librarian", prompt="Look up official JWT library docs...")
2095
- background_task(agent="librarian", prompt="Find GitHub examples of JWT refresh token...")
2096
- // Continue working while they research
2097
- \`\`\`
2098
- </Parallel_Execution>
1718
+ ## Phase 2C - Failure Recovery
1719
+
1720
+ ### When Fixes Fail:
2099
1721
 
2100
- <Verification_Protocol>
2101
- ## Verification (MANDATORY, BLOCKING)
1722
+ 1. Fix root causes, not symptoms
1723
+ 2. Re-verify after EVERY fix attempt
1724
+ 3. Never shotgun debug (random changes hoping something works)
2102
1725
 
2103
- ### After Every Edit
2104
- 1. Run \`lsp_diagnostics\` on changed files
2105
- 2. Fix errors caused by your changes
2106
- 3. Re-run diagnostics
1726
+ ### After 3 Consecutive Failures:
2107
1727
 
2108
- ### Before Marking Complete
2109
- - [ ] All todos marked \`completed\` WITH evidence
2110
- - [ ] lsp_diagnostics clean on changed files
1728
+ 1. **STOP** all further edits immediately
1729
+ 2. **REVERT** to last known working state (git checkout / undo edits)
1730
+ 3. **DOCUMENT** what was attempted and what failed
1731
+ 4. **CONSULT** Oracle with full failure context
1732
+ 5. If Oracle cannot resolve \u2192 **ASK USER** before proceeding
1733
+
1734
+ **Never**: Leave code in broken state, continue hoping it'll work, delete failing tests to "pass"
1735
+
1736
+ ---
1737
+
1738
+ ## Phase 3 - Completion
1739
+
1740
+ A task is complete when:
1741
+ - [ ] All planned todo items marked done
1742
+ - [ ] Diagnostics clean on changed files
2111
1743
  - [ ] Build passes (if applicable)
2112
- - [ ] Tests pass (if applicable)
2113
1744
  - [ ] User's original request fully addressed
2114
1745
 
2115
- Missing ANY = NOT complete.
2116
-
2117
- ### Failure Recovery
2118
- After 3+ failures:
2119
- 1. STOP all edits
2120
- 2. Revert to last working state
2121
- 3. Consult Oracle with failure context
2122
- 4. If Oracle fails, ask user
2123
- </Verification_Protocol>
2124
-
2125
- <Failure_Handling>
2126
- ## Failure Handling (BLOCKING)
2127
-
2128
- ### Type Error Guardrails
2129
- **NEVER suppress type errors. Fix the actual problem.**
2130
-
2131
- FORBIDDEN patterns (instant rejection):
2132
- - \`as any\` \u2014 Type erasure, hides bugs
2133
- - \`@ts-ignore\` \u2014 Suppresses without fixing
2134
- - \`@ts-expect-error\` \u2014 Same as above
2135
- - \`// eslint-disable\` \u2014 Unless explicitly approved
2136
- - \`any\` as function parameter type
2137
-
2138
- If you encounter a type error:
2139
- 1. Understand WHY it's failing
2140
- 2. Fix the root cause (wrong type, missing null check, etc.)
2141
- 3. If genuinely complex, consult Oracle for type design
2142
- 4. NEVER suppress to "make it work"
2143
-
2144
- ### Build Failure Protocol
2145
- When build fails:
2146
- 1. Read FULL error message (not just first line)
2147
- 2. Identify root cause vs cascading errors
2148
- 3. Fix root cause FIRST
2149
- 4. Re-run build after EACH fix
2150
- 5. If 3+ attempts fail, STOP and consult Oracle
2151
-
2152
- ### Test Failure Protocol
2153
- When tests fail:
2154
- 1. Read test name and assertion message
2155
- 2. Determine: Is your change wrong, or is the test outdated?
2156
- 3. If YOUR change is wrong \u2192 Fix your code
2157
- 4. If TEST is outdated \u2192 Update test (with justification)
2158
- 5. NEVER delete failing tests to "pass"
2159
-
2160
- ### Runtime Error Protocol
2161
- When runtime errors occur:
2162
- 1. Capture full stack trace
2163
- 2. Identify the throwing line
2164
- 3. Trace back to your changes
2165
- 4. Add proper error handling (try/catch, null checks)
2166
- 5. NEVER use empty catch blocks: \`catch (e) {}\`
2167
-
2168
- ### Infinite Loop Prevention
2169
- Signs of infinite loop:
2170
- - Process hangs without output
2171
- - Memory usage climbs
2172
- - Same log message repeating
2173
-
2174
- When suspected:
2175
- 1. Add iteration counter with hard limit
2176
- 2. Add logging at loop entry/exit
2177
- 3. Verify termination condition is reachable
2178
- </Failure_Handling>
2179
-
2180
- <Agency>
2181
- ## Proactiveness
2182
-
2183
- You are allowed to be proactive, but balance this with user expectations:
2184
-
2185
- **Core Principle**: Do the right thing when asked, but don't surprise users with unexpected actions.
2186
-
2187
- ### When to Ask vs When to Act
2188
-
2189
- | User Intent | Your Response |
2190
- |-------------|---------------|
2191
- | "Do X" / "Implement Y" / "Fix Z" | Execute immediately, iterate until complete |
2192
- | "How should I..." / "What's the best way..." | Provide recommendation first, then ask "Want me to implement this?" |
2193
- | "Can you help me..." | Clarify scope if ambiguous, then execute |
2194
- | Multi-step complex request | Present your plan first, get confirmation, then execute |
2195
-
2196
- ### Key Behaviors
2197
-
2198
- 1. **Match response to intent** - Execution requests get execution. Advisory requests get advice first.
2199
- 2. **Complete what you start** - Once you begin implementation, finish it. No partial work, no TODO placeholders.
2200
- 3. **Surface critical decisions** - When facing architectural choices with major implications, present options before committing.
2201
- 4. **Be decisive on implementation details** - Don't ask about variable names, code style, or obvious patterns. Use common sense.
2202
- 5. **Be concise** - No code explanation summaries unless requested.
2203
-
2204
- ### Anti-patterns to Avoid
2205
-
2206
- - Asking "Should I continue?" after every step (annoying)
2207
- - Jumping to implement when user asked for advice (presumptuous)
2208
- - Stopping mid-implementation to ask trivial questions (disruptive)
2209
- - Implementing something different than what was asked (surprising)
2210
- </Agency>
2211
-
2212
- <Conventions>
2213
- ## Code Conventions
2214
- - Mimic existing code style
2215
- - Use existing libraries and utilities
2216
- - Follow existing patterns
2217
- - Never introduce new patterns unless necessary
2218
-
2219
- ## File Operations
2220
- - ALWAYS use absolute paths
2221
- - Prefer specialized tools over Bash
2222
- - FILE EDITS MUST use edit tool. NO Bash.
2223
-
2224
- ## Security
2225
- - Never expose or log secrets
2226
- - Never commit secrets
2227
- </Conventions>
2228
-
2229
- <Anti_Patterns>
2230
- ## NEVER Do These (BLOCKING)
2231
-
2232
- ### Search Anti-Patterns
2233
- - Firing 3+ agents for simple queries that grep can answer
2234
- - Using librarian for internal codebase questions
2235
- - Over-exploring when you have enough context
2236
- - Not trying direct tools first
2237
-
2238
- ### Implementation Anti-Patterns
2239
- - Speculating about code you haven't opened
2240
- - Editing files without reading first
2241
- - Skipping todo planning for "quick" tasks
2242
- - Forgetting to mark tasks complete
2243
- - Marking complete without evidence
2244
-
2245
- ### Delegation Anti-Patterns
2246
- - Vague prompts without 7 sections
2247
- - Sequential agent calls when parallel is possible
2248
- - Using librarian when explore suffices
2249
-
2250
- ### Frontend Anti-Patterns (BLOCKING)
2251
- - Editing .tsx/.jsx/.vue/.svelte/.css files directly \u2014 ALWAYS delegate
2252
- - Thinking "this UI change is too simple to delegate"
2253
- - Making "quick" CSS fixes yourself
2254
- - Any frontend work without Frontend Engineer
2255
-
2256
- ### Type Safety Anti-Patterns (BLOCKING)
2257
- - Using \`as any\` to silence errors
2258
- - Adding \`@ts-ignore\` or \`@ts-expect-error\`
2259
- - Using \`any\` as function parameter/return type
2260
- - Casting to \`unknown\` then to target type (type laundering)
2261
- - Ignoring null/undefined with \`!\` without checking
2262
-
2263
- ### Error Handling Anti-Patterns (BLOCKING)
2264
- - Empty catch blocks: \`catch (e) {}\`
2265
- - Catching and re-throwing without context
2266
- - Swallowing errors with \`catch (e) { return null }\`
2267
- - Not handling Promise rejections
2268
- - Using \`try/catch\` around code that can't throw
2269
-
2270
- ### Code Quality Anti-Patterns
2271
- - Leaving \`console.log\` in production code
2272
- - Hardcoding values that should be configurable
2273
- - Copy-pasting code instead of extracting function
2274
- - Creating god functions (100+ lines)
2275
- - Nested callbacks more than 3 levels deep
2276
-
2277
- ### Testing Anti-Patterns (BLOCKING)
2278
- - Deleting failing tests to "pass"
2279
- - Writing tests that always pass (no assertions)
2280
- - Testing implementation details instead of behavior
2281
- - Mocking everything (no integration tests)
2282
-
2283
- ### Git Anti-Patterns
2284
- - Committing with "fix" or "update" without context
2285
- - Large commits with unrelated changes
2286
- - Committing commented-out code
2287
- - Committing debug/test artifacts
2288
- </Anti_Patterns>
2289
-
2290
- <Decision_Matrix>
2291
- ## Quick Decision Matrix
1746
+ If verification fails:
1747
+ 1. Fix issues caused by your changes
1748
+ 2. Do NOT fix pre-existing issues unless asked
1749
+ 3. Report: "Done. Note: found N pre-existing lint errors unrelated to my changes."
2292
1750
 
2293
- | Situation | Action |
2294
- |-----------|--------|
2295
- | "Where is X defined?" | lsp_goto_definition or grep |
2296
- | "How is X used?" | lsp_find_references |
2297
- | "Find files matching pattern" | glob |
2298
- | "Find code pattern" | ast_grep_search or grep |
2299
- | "Understand module X" | 1-2 explore agents |
2300
- | "Understand entire architecture" | 2-3 explore agents (parallel) |
2301
- | "Official docs for library X?" | 1 librarian (background) |
2302
- | "GitHub examples of X?" | 1 librarian (background) |
2303
- | "How does famous OSS Y implement X?" | 1-2 librarian (parallel background) |
2304
- | "ANY UI/frontend work" | Frontend Engineer (MUST delegate, no exceptions) |
2305
- | "Complex architecture decision" | Oracle |
2306
- | "Write documentation" | Document Writer |
2307
- | "Simple file edit" | Direct edit, no agents |
2308
- </Decision_Matrix>
2309
-
2310
- <Final_Reminders>
2311
- ## Remember
2312
-
2313
- - You are the **team lead** - delegate to preserve context
2314
- - **TODO tracking** is your key to success - use obsessively
2315
- - **Direct tools first** - grep/glob/LSP before agents
2316
- - **Explore = contextual grep** - fire liberally for internal code, parallel background
2317
- - **Librarian = external researcher** - Official Docs, GitHub, Famous OSS (use during implementation too!)
2318
- - **Frontend Engineer for UI** - always delegate visual work
2319
- - **Stop when you have enough** - don't over-explore
2320
- - **Evidence for everything** - no evidence = not complete
2321
- - **Background pattern** - fire agents, continue working, collect with background_output
2322
- - **Cleanup before answering** - When ready to deliver your final answer, cancel ALL running background tasks with \`background_cancel(all=true)\` first, then respond. This conserves resources and ensures clean workflow completion.
2323
- - Complete accepted tasks fully - don't stop halfway through implementation
2324
- - But if you discover the task is larger or more complex than initially apparent, communicate this and confirm direction before investing significant effort
2325
- </Final_Reminders>
1751
+ ### Before Delivering Final Answer:
1752
+ - Cancel ALL running background tasks: \`background_cancel(all=true)\`
1753
+ - This conserves resources and ensures clean workflow completion
1754
+
1755
+ </Behavior_Instructions>
1756
+
1757
+ <Oracle_Usage>
1758
+ ## Oracle \u2014 Your Senior Engineering Advisor (GPT-5.2)
1759
+
1760
+ Oracle is an expensive, high-quality reasoning model. Use it wisely.
1761
+
1762
+ ### WHEN to Consult:
1763
+
1764
+ | Trigger | Action |
1765
+ |---------|--------|
1766
+ | Complex architecture design | Oracle FIRST, then implement |
1767
+ | After completing significant work | Oracle review before marking complete |
1768
+ | 2+ failed fix attempts | Oracle for debugging guidance |
1769
+ | Unfamiliar code patterns | Oracle to explain behavior |
1770
+ | Security/performance concerns | Oracle for analysis |
1771
+ | Multi-system tradeoffs | Oracle for architectural decision |
1772
+
1773
+ ### WHEN NOT to Consult:
1774
+
1775
+ - Simple file operations (use direct tools)
1776
+ - First attempt at any fix (try yourself first)
1777
+ - Questions answerable from code you've read
1778
+ - Trivial decisions (variable names, formatting)
1779
+ - Things you can infer from existing code patterns
1780
+
1781
+ ### Usage Pattern:
1782
+ Briefly announce "Consulting Oracle for [reason]" before invocation.
1783
+ </Oracle_Usage>
1784
+
1785
+ <Task_Management>
1786
+ ## Todo Management
1787
+
1788
+ Use \`todowrite\` for any task with 2+ steps.
1789
+
1790
+ - Create todos BEFORE starting work
1791
+ - Mark \`in_progress\` when starting an item
1792
+ - Mark \`completed\` immediately when done (don't batch)
1793
+ - This gives user visibility into progress and prevents forgotten steps
1794
+
1795
+ ### Clarification Protocol (when asking):
1796
+
1797
+ \`\`\`
1798
+ I want to make sure I understand correctly.
1799
+
1800
+ **What I understood**: [Your interpretation]
1801
+ **What I'm unsure about**: [Specific ambiguity]
1802
+ **Options I see**:
1803
+ 1. [Option A] - [effort/implications]
1804
+ 2. [Option B] - [effort/implications]
1805
+
1806
+ **My recommendation**: [suggestion with reasoning]
1807
+
1808
+ Should I proceed with [recommendation], or would you prefer differently?
1809
+ \`\`\`
1810
+ </Task_Management>
1811
+
1812
+ <Tone_and_Style>
1813
+ ## Communication Style
1814
+
1815
+ ### Be Concise
1816
+ - Answer directly without preamble
1817
+ - Don't summarize what you did unless asked
1818
+ - Don't explain your code unless asked
1819
+ - One word answers are acceptable when appropriate
1820
+
1821
+ ### No Flattery
1822
+ Never start responses with:
1823
+ - "Great question!"
1824
+ - "That's a really good idea!"
1825
+ - "Excellent choice!"
1826
+ - Any praise of the user's input
1827
+
1828
+ Just respond directly to the substance.
1829
+
1830
+ ### When User is Wrong
1831
+ If the user's approach seems problematic:
1832
+ - Don't blindly implement it
1833
+ - Don't lecture or be preachy
1834
+ - Concisely state your concern and alternative
1835
+ - Ask if they want to proceed anyway
1836
+
1837
+ ### Match User's Style
1838
+ - If user is terse, be terse
1839
+ - If user wants detail, provide detail
1840
+ - Adapt to their communication preference
1841
+ </Tone_and_Style>
1842
+
1843
+ <Constraints>
1844
+ ## Hard Blocks (NEVER violate)
1845
+
1846
+ | Constraint | No Exceptions |
1847
+ |------------|---------------|
1848
+ | Frontend files (.tsx/.jsx/.vue/.svelte/.css) | Always delegate |
1849
+ | Type error suppression (\`as any\`, \`@ts-ignore\`) | Never |
1850
+ | Commit without explicit request | Never |
1851
+ | Speculate about unread code | Never |
1852
+ | Leave code in broken state after failures | Never |
1853
+
1854
+ ## Anti-Patterns (BLOCKING violations)
1855
+
1856
+ | Category | Forbidden |
1857
+ |----------|-----------|
1858
+ | **Type Safety** | \`as any\`, \`@ts-ignore\`, \`@ts-expect-error\` |
1859
+ | **Error Handling** | Empty catch blocks \`catch(e) {}\` |
1860
+ | **Testing** | Deleting failing tests to "pass" |
1861
+ | **Search** | Firing 3+ agents when grep suffices |
1862
+ | **Frontend** | ANY direct edit to frontend files |
1863
+ | **Debugging** | Shotgun debugging, random changes |
1864
+
1865
+ ## Soft Guidelines
1866
+
1867
+ - Prefer existing libraries over new dependencies
1868
+ - Prefer small, focused changes over large refactors
1869
+ - When uncertain about scope, ask
1870
+ </Constraints>
2326
1871
  `;
2327
1872
  var omoAgent = {
2328
1873
  description: "Powerful AI orchestrator for OpenCode. Plans obsessively with todos, assesses search complexity before exploration, delegates strategically to specialized agents. Uses explore for internal code (parallel-friendly), librarian only for external docs, and always delegates UI work to frontend engineer.",
@@ -3989,6 +3534,28 @@ ${CONTEXT_REMINDER}
3989
3534
  }
3990
3535
  // src/hooks/session-notification.ts
3991
3536
  import { platform } from "os";
3537
+ // src/features/claude-code-session-state/state.ts
3538
+ var sessionErrorState = new Map;
3539
+ var sessionInterruptState = new Map;
3540
+ var subagentSessions = new Set;
3541
+ var sessionFirstMessageProcessed = new Set;
3542
+ var currentSessionID;
3543
+ var currentSessionTitle;
3544
+ var mainSessionID;
3545
+ function setCurrentSession(id, title) {
3546
+ currentSessionID = id;
3547
+ currentSessionTitle = title;
3548
+ }
3549
+ function setMainSession(id) {
3550
+ mainSessionID = id;
3551
+ }
3552
+ function getCurrentSessionTitle() {
3553
+ return currentSessionTitle;
3554
+ }
3555
+ function getMainSessionID() {
3556
+ return mainSessionID;
3557
+ }
3558
+ // src/hooks/session-notification.ts
3992
3559
  function detectPlatform() {
3993
3560
  const p = platform();
3994
3561
  if (p === "darwin" || p === "linux" || p === "win32")
@@ -4155,6 +3722,8 @@ function createSessionNotification(ctx, config = {}) {
4155
3722
  const sessionID = props?.sessionID;
4156
3723
  if (!sessionID)
4157
3724
  return;
3725
+ if (subagentSessions.has(sessionID))
3726
+ return;
4158
3727
  if (notifiedSessions.has(sessionID))
4159
3728
  return;
4160
3729
  if (pendingTimers.has(sessionID))
@@ -5715,28 +5284,28 @@ function truncateToolResult(partPath) {
5715
5284
 
5716
5285
  // src/hooks/anthropic-auto-compact/executor.ts
5717
5286
  function getOrCreateRetryState(autoCompactState, sessionID) {
5718
- let state = autoCompactState.retryStateBySession.get(sessionID);
5719
- if (!state) {
5720
- state = { attempt: 0, lastAttemptTime: 0 };
5721
- autoCompactState.retryStateBySession.set(sessionID, state);
5287
+ let state2 = autoCompactState.retryStateBySession.get(sessionID);
5288
+ if (!state2) {
5289
+ state2 = { attempt: 0, lastAttemptTime: 0 };
5290
+ autoCompactState.retryStateBySession.set(sessionID, state2);
5722
5291
  }
5723
- return state;
5292
+ return state2;
5724
5293
  }
5725
5294
  function getOrCreateFallbackState(autoCompactState, sessionID) {
5726
- let state = autoCompactState.fallbackStateBySession.get(sessionID);
5727
- if (!state) {
5728
- state = { revertAttempt: 0 };
5729
- autoCompactState.fallbackStateBySession.set(sessionID, state);
5295
+ let state2 = autoCompactState.fallbackStateBySession.get(sessionID);
5296
+ if (!state2) {
5297
+ state2 = { revertAttempt: 0 };
5298
+ autoCompactState.fallbackStateBySession.set(sessionID, state2);
5730
5299
  }
5731
- return state;
5300
+ return state2;
5732
5301
  }
5733
5302
  function getOrCreateTruncateState(autoCompactState, sessionID) {
5734
- let state = autoCompactState.truncateStateBySession.get(sessionID);
5735
- if (!state) {
5736
- state = { truncateAttempt: 0 };
5737
- autoCompactState.truncateStateBySession.set(sessionID, state);
5303
+ let state2 = autoCompactState.truncateStateBySession.get(sessionID);
5304
+ if (!state2) {
5305
+ state2 = { truncateAttempt: 0 };
5306
+ autoCompactState.truncateStateBySession.set(sessionID, state2);
5738
5307
  }
5739
- return state;
5308
+ return state2;
5740
5309
  }
5741
5310
  async function getLastMessagePair(sessionID, client, directory) {
5742
5311
  try {
@@ -6266,25 +5835,25 @@ function createThinkModeHook() {
6266
5835
  return {
6267
5836
  "chat.params": async (output, sessionID) => {
6268
5837
  const promptText = extractPromptText(output.parts);
6269
- const state = {
5838
+ const state2 = {
6270
5839
  requested: false,
6271
5840
  modelSwitched: false,
6272
5841
  thinkingConfigInjected: false
6273
5842
  };
6274
5843
  if (!detectThinkKeyword(promptText)) {
6275
- thinkModeState.set(sessionID, state);
5844
+ thinkModeState.set(sessionID, state2);
6276
5845
  return;
6277
5846
  }
6278
- state.requested = true;
5847
+ state2.requested = true;
6279
5848
  const currentModel = output.message.model;
6280
5849
  if (!currentModel) {
6281
- thinkModeState.set(sessionID, state);
5850
+ thinkModeState.set(sessionID, state2);
6282
5851
  return;
6283
5852
  }
6284
- state.providerID = currentModel.providerID;
6285
- state.modelID = currentModel.modelID;
5853
+ state2.providerID = currentModel.providerID;
5854
+ state2.modelID = currentModel.modelID;
6286
5855
  if (isAlreadyHighVariant(currentModel.modelID)) {
6287
- thinkModeState.set(sessionID, state);
5856
+ thinkModeState.set(sessionID, state2);
6288
5857
  return;
6289
5858
  }
6290
5859
  const highVariant = getHighVariant(currentModel.modelID);
@@ -6294,7 +5863,7 @@ function createThinkModeHook() {
6294
5863
  providerID: currentModel.providerID,
6295
5864
  modelID: highVariant
6296
5865
  };
6297
- state.modelSwitched = true;
5866
+ state2.modelSwitched = true;
6298
5867
  log("Think mode: model switched to high variant", {
6299
5868
  sessionID,
6300
5869
  from: currentModel.modelID,
@@ -6303,14 +5872,14 @@ function createThinkModeHook() {
6303
5872
  }
6304
5873
  if (thinkingConfig) {
6305
5874
  Object.assign(output.message, thinkingConfig);
6306
- state.thinkingConfigInjected = true;
5875
+ state2.thinkingConfigInjected = true;
6307
5876
  log("Think mode: thinking config injected", {
6308
5877
  sessionID,
6309
5878
  provider: currentModel.providerID,
6310
5879
  config: thinkingConfig
6311
5880
  });
6312
5881
  }
6313
- thinkModeState.set(sessionID, state);
5882
+ thinkModeState.set(sessionID, state2);
6314
5883
  },
6315
5884
  event: async ({ event }) => {
6316
5885
  if (event.type === "session.deleted") {
@@ -7006,13 +6575,13 @@ setInterval(() => {
7006
6575
  }, CACHE_TTL);
7007
6576
 
7008
6577
  // src/hooks/claude-code-hooks/index.ts
7009
- var sessionFirstMessageProcessed = new Set;
7010
- var sessionErrorState = new Map;
7011
- var sessionInterruptState = new Map;
6578
+ var sessionFirstMessageProcessed2 = new Set;
6579
+ var sessionErrorState2 = new Map;
6580
+ var sessionInterruptState2 = new Map;
7012
6581
  function createClaudeCodeHooksHook(ctx, config = {}) {
7013
6582
  return {
7014
6583
  "chat.message": async (input, output) => {
7015
- const interruptState = sessionInterruptState.get(input.sessionID);
6584
+ const interruptState = sessionInterruptState2.get(input.sessionID);
7016
6585
  if (interruptState?.interrupted) {
7017
6586
  log("chat.message hook skipped - session interrupted", { sessionID: input.sessionID });
7018
6587
  return;
@@ -7027,7 +6596,7 @@ function createClaudeCodeHooksHook(ctx, config = {}) {
7027
6596
  type: p.type,
7028
6597
  text: p.text
7029
6598
  }));
7030
- const interruptStateBeforeHooks = sessionInterruptState.get(input.sessionID);
6599
+ const interruptStateBeforeHooks = sessionInterruptState2.get(input.sessionID);
7031
6600
  if (interruptStateBeforeHooks?.interrupted) {
7032
6601
  log("chat.message hooks skipped - interrupted during preparation", { sessionID: input.sessionID });
7033
6602
  return;
@@ -7039,8 +6608,8 @@ function createClaudeCodeHooksHook(ctx, config = {}) {
7039
6608
  });
7040
6609
  parentSessionId = sessionInfo.data?.parentID;
7041
6610
  } catch {}
7042
- const isFirstMessage = !sessionFirstMessageProcessed.has(input.sessionID);
7043
- sessionFirstMessageProcessed.add(input.sessionID);
6611
+ const isFirstMessage = !sessionFirstMessageProcessed2.has(input.sessionID);
6612
+ sessionFirstMessageProcessed2.add(input.sessionID);
7044
6613
  if (isFirstMessage) {
7045
6614
  log("Skipping UserPromptSubmit hooks on first message for title generation", { sessionID: input.sessionID });
7046
6615
  return;
@@ -7057,7 +6626,7 @@ function createClaudeCodeHooksHook(ctx, config = {}) {
7057
6626
  if (result.block) {
7058
6627
  throw new Error(result.reason ?? "Hook blocked the prompt");
7059
6628
  }
7060
- const interruptStateAfterHooks = sessionInterruptState.get(input.sessionID);
6629
+ const interruptStateAfterHooks = sessionInterruptState2.get(input.sessionID);
7061
6630
  if (interruptStateAfterHooks?.interrupted) {
7062
6631
  log("chat.message injection skipped - interrupted during hooks", { sessionID: input.sessionID });
7063
6632
  return;
@@ -7177,7 +6746,7 @@ ${result.message}`;
7177
6746
  const props = event.properties;
7178
6747
  const sessionID = props?.sessionID;
7179
6748
  if (sessionID) {
7180
- sessionErrorState.set(sessionID, {
6749
+ sessionErrorState2.set(sessionID, {
7181
6750
  hasError: true,
7182
6751
  errorMessage: String(props?.error ?? "Unknown error")
7183
6752
  });
@@ -7188,9 +6757,9 @@ ${result.message}`;
7188
6757
  const props = event.properties;
7189
6758
  const sessionInfo = props?.info;
7190
6759
  if (sessionInfo?.id) {
7191
- sessionErrorState.delete(sessionInfo.id);
7192
- sessionInterruptState.delete(sessionInfo.id);
7193
- sessionFirstMessageProcessed.delete(sessionInfo.id);
6760
+ sessionErrorState2.delete(sessionInfo.id);
6761
+ sessionInterruptState2.delete(sessionInfo.id);
6762
+ sessionFirstMessageProcessed2.delete(sessionInfo.id);
7194
6763
  }
7195
6764
  return;
7196
6765
  }
@@ -7201,9 +6770,9 @@ ${result.message}`;
7201
6770
  return;
7202
6771
  const claudeConfig = await loadClaudeHooksConfig();
7203
6772
  const extendedConfig = await loadPluginExtendedConfig();
7204
- const errorStateBefore = sessionErrorState.get(sessionID);
6773
+ const errorStateBefore = sessionErrorState2.get(sessionID);
7205
6774
  const endedWithErrorBefore = errorStateBefore?.hasError === true;
7206
- const interruptStateBefore = sessionInterruptState.get(sessionID);
6775
+ const interruptStateBefore = sessionInterruptState2.get(sessionID);
7207
6776
  const interruptedBefore = interruptStateBefore?.interrupted === true;
7208
6777
  let parentSessionId;
7209
6778
  try {
@@ -7219,9 +6788,9 @@ ${result.message}`;
7219
6788
  cwd: ctx.directory
7220
6789
  };
7221
6790
  const stopResult = await executeStopHooks(stopCtx, claudeConfig, extendedConfig);
7222
- const errorStateAfter = sessionErrorState.get(sessionID);
6791
+ const errorStateAfter = sessionErrorState2.get(sessionID);
7223
6792
  const endedWithErrorAfter = errorStateAfter?.hasError === true;
7224
- const interruptStateAfter = sessionInterruptState.get(sessionID);
6793
+ const interruptStateAfter = sessionInterruptState2.get(sessionID);
7225
6794
  const interruptedAfter = interruptStateAfter?.interrupted === true;
7226
6795
  const shouldBypass = endedWithErrorBefore || endedWithErrorAfter || interruptedBefore || interruptedAfter;
7227
6796
  if (shouldBypass && stopResult.block) {
@@ -7239,8 +6808,8 @@ ${result.message}`;
7239
6808
  log("Stop hook returned block", { sessionID, reason: stopResult.reason });
7240
6809
  }
7241
6810
  }
7242
- sessionErrorState.delete(sessionID);
7243
- sessionInterruptState.delete(sessionID);
6811
+ sessionErrorState2.delete(sessionID);
6812
+ sessionInterruptState2.delete(sessionID);
7244
6813
  }
7245
6814
  }
7246
6815
  };
@@ -8056,12 +7625,12 @@ function loadAgentUsageState(sessionID) {
8056
7625
  return null;
8057
7626
  }
8058
7627
  }
8059
- function saveAgentUsageState(state) {
7628
+ function saveAgentUsageState(state2) {
8060
7629
  if (!existsSync21(AGENT_USAGE_REMINDER_STORAGE)) {
8061
7630
  mkdirSync8(AGENT_USAGE_REMINDER_STORAGE, { recursive: true });
8062
7631
  }
8063
- const filePath = getStoragePath4(state.sessionID);
8064
- writeFileSync9(filePath, JSON.stringify(state, null, 2));
7632
+ const filePath = getStoragePath4(state2.sessionID);
7633
+ writeFileSync9(filePath, JSON.stringify(state2, null, 2));
8065
7634
  }
8066
7635
  function clearAgentUsageState(sessionID) {
8067
7636
  const filePath = getStoragePath4(sessionID);
@@ -8076,21 +7645,21 @@ function createAgentUsageReminderHook(_ctx) {
8076
7645
  function getOrCreateState(sessionID) {
8077
7646
  if (!sessionStates.has(sessionID)) {
8078
7647
  const persisted = loadAgentUsageState(sessionID);
8079
- const state = persisted ?? {
7648
+ const state2 = persisted ?? {
8080
7649
  sessionID,
8081
7650
  agentUsed: false,
8082
7651
  reminderCount: 0,
8083
7652
  updatedAt: Date.now()
8084
7653
  };
8085
- sessionStates.set(sessionID, state);
7654
+ sessionStates.set(sessionID, state2);
8086
7655
  }
8087
7656
  return sessionStates.get(sessionID);
8088
7657
  }
8089
7658
  function markAgentUsed(sessionID) {
8090
- const state = getOrCreateState(sessionID);
8091
- state.agentUsed = true;
8092
- state.updatedAt = Date.now();
8093
- saveAgentUsageState(state);
7659
+ const state2 = getOrCreateState(sessionID);
7660
+ state2.agentUsed = true;
7661
+ state2.updatedAt = Date.now();
7662
+ saveAgentUsageState(state2);
8094
7663
  }
8095
7664
  function resetState(sessionID) {
8096
7665
  sessionStates.delete(sessionID);
@@ -8106,14 +7675,14 @@ function createAgentUsageReminderHook(_ctx) {
8106
7675
  if (!TARGET_TOOLS.has(toolLower)) {
8107
7676
  return;
8108
7677
  }
8109
- const state = getOrCreateState(sessionID);
8110
- if (state.agentUsed) {
7678
+ const state2 = getOrCreateState(sessionID);
7679
+ if (state2.agentUsed) {
8111
7680
  return;
8112
7681
  }
8113
7682
  output.output += REMINDER_MESSAGE;
8114
- state.reminderCount++;
8115
- state.updatedAt = Date.now();
8116
- saveAgentUsageState(state);
7683
+ state2.reminderCount++;
7684
+ state2.updatedAt = Date.now();
7685
+ saveAgentUsageState(state2);
8117
7686
  };
8118
7687
  const eventHandler = async ({ event }) => {
8119
7688
  const props = event.properties;
@@ -8328,15 +7897,15 @@ function loadInteractiveBashSessionState(sessionID) {
8328
7897
  return null;
8329
7898
  }
8330
7899
  }
8331
- function saveInteractiveBashSessionState(state) {
7900
+ function saveInteractiveBashSessionState(state2) {
8332
7901
  if (!existsSync22(INTERACTIVE_BASH_SESSION_STORAGE)) {
8333
7902
  mkdirSync9(INTERACTIVE_BASH_SESSION_STORAGE, { recursive: true });
8334
7903
  }
8335
- const filePath = getStoragePath5(state.sessionID);
7904
+ const filePath = getStoragePath5(state2.sessionID);
8336
7905
  const serialized = {
8337
- sessionID: state.sessionID,
8338
- tmuxSessions: Array.from(state.tmuxSessions),
8339
- updatedAt: state.updatedAt
7906
+ sessionID: state2.sessionID,
7907
+ tmuxSessions: Array.from(state2.tmuxSessions),
7908
+ updatedAt: state2.updatedAt
8340
7909
  };
8341
7910
  writeFileSync10(filePath, JSON.stringify(serialized, null, 2));
8342
7911
  }
@@ -8434,20 +8003,20 @@ function createInteractiveBashSessionHook(_ctx) {
8434
8003
  function getOrCreateState(sessionID) {
8435
8004
  if (!sessionStates.has(sessionID)) {
8436
8005
  const persisted = loadInteractiveBashSessionState(sessionID);
8437
- const state = persisted ?? {
8006
+ const state2 = persisted ?? {
8438
8007
  sessionID,
8439
8008
  tmuxSessions: new Set,
8440
8009
  updatedAt: Date.now()
8441
8010
  };
8442
- sessionStates.set(sessionID, state);
8011
+ sessionStates.set(sessionID, state2);
8443
8012
  }
8444
8013
  return sessionStates.get(sessionID);
8445
8014
  }
8446
8015
  function isOmoSession(sessionName) {
8447
8016
  return sessionName !== null && sessionName.startsWith(OMO_SESSION_PREFIX);
8448
8017
  }
8449
- async function killAllTrackedSessions(state) {
8450
- for (const sessionName of state.tmuxSessions) {
8018
+ async function killAllTrackedSessions(state2) {
8019
+ for (const sessionName of state2.tmuxSessions) {
8451
8020
  try {
8452
8021
  const proc = Bun.spawn(["tmux", "kill-session", "-t", sessionName], {
8453
8022
  stdout: "ignore",
@@ -8469,7 +8038,7 @@ function createInteractiveBashSessionHook(_ctx) {
8469
8038
  const tmuxCommand = args.tmux_command;
8470
8039
  const tokens = tokenizeCommand(tmuxCommand);
8471
8040
  const subCommand = findSubcommand(tokens);
8472
- const state = getOrCreateState(sessionID);
8041
+ const state2 = getOrCreateState(sessionID);
8473
8042
  let stateChanged = false;
8474
8043
  const toolOutput = output?.output ?? "";
8475
8044
  if (toolOutput.startsWith("Error:")) {
@@ -8480,22 +8049,22 @@ function createInteractiveBashSessionHook(_ctx) {
8480
8049
  const isKillServer = subCommand === "kill-server";
8481
8050
  const sessionName = extractSessionNameFromTokens(tokens, subCommand);
8482
8051
  if (isNewSession && isOmoSession(sessionName)) {
8483
- state.tmuxSessions.add(sessionName);
8052
+ state2.tmuxSessions.add(sessionName);
8484
8053
  stateChanged = true;
8485
8054
  } else if (isKillSession && isOmoSession(sessionName)) {
8486
- state.tmuxSessions.delete(sessionName);
8055
+ state2.tmuxSessions.delete(sessionName);
8487
8056
  stateChanged = true;
8488
8057
  } else if (isKillServer) {
8489
- state.tmuxSessions.clear();
8058
+ state2.tmuxSessions.clear();
8490
8059
  stateChanged = true;
8491
8060
  }
8492
8061
  if (stateChanged) {
8493
- state.updatedAt = Date.now();
8494
- saveInteractiveBashSessionState(state);
8062
+ state2.updatedAt = Date.now();
8063
+ saveInteractiveBashSessionState(state2);
8495
8064
  }
8496
8065
  const isSessionOperation = isNewSession || isKillSession || isKillServer;
8497
8066
  if (isSessionOperation) {
8498
- const reminder = buildSessionReminderMessage(Array.from(state.tmuxSessions));
8067
+ const reminder = buildSessionReminderMessage(Array.from(state2.tmuxSessions));
8499
8068
  if (reminder) {
8500
8069
  output.output += reminder;
8501
8070
  }
@@ -8507,8 +8076,8 @@ function createInteractiveBashSessionHook(_ctx) {
8507
8076
  const sessionInfo = props?.info;
8508
8077
  const sessionID = sessionInfo?.id;
8509
8078
  if (sessionID) {
8510
- const state = getOrCreateState(sessionID);
8511
- await killAllTrackedSessions(state);
8079
+ const state2 = getOrCreateState(sessionID);
8080
+ await killAllTrackedSessions(state2);
8512
8081
  sessionStates.delete(sessionID);
8513
8082
  clearInteractiveBashSessionState(sessionID);
8514
8083
  }
@@ -8704,8 +8273,8 @@ async function generatePKCEPair() {
8704
8273
  method: pkce.method
8705
8274
  };
8706
8275
  }
8707
- function encodeState(state) {
8708
- const json = JSON.stringify(state);
8276
+ function encodeState(state2) {
8277
+ const json = JSON.stringify(state2);
8709
8278
  return Buffer.from(json, "utf8").toString("base64url");
8710
8279
  }
8711
8280
  function decodeState(encoded) {
@@ -8723,7 +8292,7 @@ function decodeState(encoded) {
8723
8292
  }
8724
8293
  async function buildAuthURL(projectId, clientId = ANTIGRAVITY_CLIENT_ID, port = ANTIGRAVITY_CALLBACK_PORT) {
8725
8294
  const pkce = await generatePKCEPair();
8726
- const state = {
8295
+ const state2 = {
8727
8296
  verifier: pkce.verifier,
8728
8297
  projectId
8729
8298
  };
@@ -8733,7 +8302,7 @@ async function buildAuthURL(projectId, clientId = ANTIGRAVITY_CLIENT_ID, port =
8733
8302
  url.searchParams.set("redirect_uri", redirectUri);
8734
8303
  url.searchParams.set("response_type", "code");
8735
8304
  url.searchParams.set("scope", ANTIGRAVITY_SCOPES.join(" "));
8736
- url.searchParams.set("state", encodeState(state));
8305
+ url.searchParams.set("state", encodeState(state2));
8737
8306
  url.searchParams.set("code_challenge", pkce.challenge);
8738
8307
  url.searchParams.set("code_challenge_method", "S256");
8739
8308
  url.searchParams.set("access_type", "offline");
@@ -8809,7 +8378,7 @@ function startCallbackServer(timeoutMs = 5 * 60 * 1000) {
8809
8378
  const url = new URL(request.url);
8810
8379
  if (url.pathname === "/oauth-callback") {
8811
8380
  const code = url.searchParams.get("code") || "";
8812
- const state = url.searchParams.get("state") || "";
8381
+ const state2 = url.searchParams.get("state") || "";
8813
8382
  const error = url.searchParams.get("error") || undefined;
8814
8383
  let responseBody;
8815
8384
  if (code && !error) {
@@ -8820,7 +8389,7 @@ function startCallbackServer(timeoutMs = 5 * 60 * 1000) {
8820
8389
  setTimeout(() => {
8821
8390
  cleanup();
8822
8391
  if (resolveCallback) {
8823
- resolveCallback({ code, state, error });
8392
+ resolveCallback({ code, state: state2, error });
8824
8393
  }
8825
8394
  }, 100);
8826
8395
  return new Response(responseBody, {
@@ -10236,8 +9805,8 @@ async function createGoogleAntigravityAuthPlugin({
10236
9805
  }
10237
9806
  return { type: "failed" };
10238
9807
  }
10239
- const state = decodeState(result.state);
10240
- if (state.verifier !== verifier) {
9808
+ const state2 = decodeState(result.state);
9809
+ if (state2.verifier !== verifier) {
10241
9810
  if (process.env.ANTIGRAVITY_DEBUG === "1") {
10242
9811
  console.error("[antigravity-plugin] PKCE verifier mismatch");
10243
9812
  }
@@ -10607,27 +10176,6 @@ async function loadMcpConfigs() {
10607
10176
  }
10608
10177
  return { servers, loadedServers };
10609
10178
  }
10610
- // src/features/claude-code-session-state/state.ts
10611
- var sessionErrorState2 = new Map;
10612
- var sessionInterruptState2 = new Map;
10613
- var subagentSessions = new Set;
10614
- var sessionFirstMessageProcessed2 = new Set;
10615
- var currentSessionID;
10616
- var currentSessionTitle;
10617
- var mainSessionID;
10618
- function setCurrentSession(id, title) {
10619
- currentSessionID = id;
10620
- currentSessionTitle = title;
10621
- }
10622
- function setMainSession(id) {
10623
- mainSessionID = id;
10624
- }
10625
- function getCurrentSessionTitle() {
10626
- return currentSessionTitle;
10627
- }
10628
- function getMainSessionID() {
10629
- return mainSessionID;
10630
- }
10631
10179
  // src/features/terminal/title.ts
10632
10180
  var STATUS_ICONS = {
10633
10181
  ready: "",
@@ -26655,6 +26203,7 @@ class BackgroundManager {
26655
26203
  throw new Error(`Failed to create background session: ${createResult.error}`);
26656
26204
  }
26657
26205
  const sessionID = createResult.data.id;
26206
+ subagentSessions.add(sessionID);
26658
26207
  const task = {
26659
26208
  id: `bg_${crypto.randomUUID().slice(0, 8)}`,
26660
26209
  sessionID,
@@ -26793,6 +26342,7 @@ class BackgroundManager {
26793
26342
  }
26794
26343
  this.tasks.delete(task.id);
26795
26344
  this.clearNotificationsForTask(task.id);
26345
+ subagentSessions.delete(sessionID);
26796
26346
  }
26797
26347
  }
26798
26348
  markForNotification(task) {