oh-my-opencode-gpt-slim 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -277,8 +277,8 @@ var require_utils = __commonJS((exports) => {
277
277
  }
278
278
  return output;
279
279
  };
280
- exports.basename = (path4, { windows } = {}) => {
281
- const segs = path4.split(windows ? /[\\/]/ : "/");
280
+ exports.basename = (path3, { windows } = {}) => {
281
+ const segs = path3.split(windows ? /[\\/]/ : "/");
282
282
  const last = segs[segs.length - 1];
283
283
  if (last === "") {
284
284
  return segs[segs.length - 2];
@@ -4653,8 +4653,8 @@ var require_utils2 = __commonJS((exports, module) => {
4653
4653
  }
4654
4654
  return ind;
4655
4655
  }
4656
- function removeDotSegments(path4) {
4657
- let input = path4;
4656
+ function removeDotSegments(path3) {
4657
+ let input = path3;
4658
4658
  const output = [];
4659
4659
  let nextSlash = -1;
4660
4660
  let len = 0;
@@ -4844,8 +4844,8 @@ var require_schemes = __commonJS((exports, module) => {
4844
4844
  wsComponent.secure = undefined;
4845
4845
  }
4846
4846
  if (wsComponent.resourceName) {
4847
- const [path4, query] = wsComponent.resourceName.split("?");
4848
- wsComponent.path = path4 && path4 !== "/" ? path4 : undefined;
4847
+ const [path3, query] = wsComponent.resourceName.split("?");
4848
+ wsComponent.path = path3 && path3 !== "/" ? path3 : undefined;
4849
4849
  wsComponent.query = query;
4850
4850
  wsComponent.resourceName = undefined;
4851
4851
  }
@@ -8006,7 +8006,7 @@ var require_windows = __commonJS((exports, module) => {
8006
8006
  module.exports = isexe;
8007
8007
  isexe.sync = sync;
8008
8008
  var fs5 = __require("fs");
8009
- function checkPathExt(path4, options) {
8009
+ function checkPathExt(path3, options) {
8010
8010
  var pathext = options.pathExt !== undefined ? options.pathExt : process.env.PATHEXT;
8011
8011
  if (!pathext) {
8012
8012
  return true;
@@ -8017,25 +8017,25 @@ var require_windows = __commonJS((exports, module) => {
8017
8017
  }
8018
8018
  for (var i2 = 0;i2 < pathext.length; i2++) {
8019
8019
  var p = pathext[i2].toLowerCase();
8020
- if (p && path4.substr(-p.length).toLowerCase() === p) {
8020
+ if (p && path3.substr(-p.length).toLowerCase() === p) {
8021
8021
  return true;
8022
8022
  }
8023
8023
  }
8024
8024
  return false;
8025
8025
  }
8026
- function checkStat(stat, path4, options) {
8026
+ function checkStat(stat, path3, options) {
8027
8027
  if (!stat.isSymbolicLink() && !stat.isFile()) {
8028
8028
  return false;
8029
8029
  }
8030
- return checkPathExt(path4, options);
8030
+ return checkPathExt(path3, options);
8031
8031
  }
8032
- function isexe(path4, options, cb) {
8033
- fs5.stat(path4, function(er, stat) {
8034
- cb(er, er ? false : checkStat(stat, path4, options));
8032
+ function isexe(path3, options, cb) {
8033
+ fs5.stat(path3, function(er, stat) {
8034
+ cb(er, er ? false : checkStat(stat, path3, options));
8035
8035
  });
8036
8036
  }
8037
- function sync(path4, options) {
8038
- return checkStat(fs5.statSync(path4), path4, options);
8037
+ function sync(path3, options) {
8038
+ return checkStat(fs5.statSync(path3), path3, options);
8039
8039
  }
8040
8040
  });
8041
8041
 
@@ -8044,13 +8044,13 @@ var require_mode = __commonJS((exports, module) => {
8044
8044
  module.exports = isexe;
8045
8045
  isexe.sync = sync;
8046
8046
  var fs5 = __require("fs");
8047
- function isexe(path4, options, cb) {
8048
- fs5.stat(path4, function(er, stat) {
8047
+ function isexe(path3, options, cb) {
8048
+ fs5.stat(path3, function(er, stat) {
8049
8049
  cb(er, er ? false : checkStat(stat, options));
8050
8050
  });
8051
8051
  }
8052
- function sync(path4, options) {
8053
- return checkStat(fs5.statSync(path4), options);
8052
+ function sync(path3, options) {
8053
+ return checkStat(fs5.statSync(path3), options);
8054
8054
  }
8055
8055
  function checkStat(stat, options) {
8056
8056
  return stat.isFile() && checkMode(stat, options);
@@ -8081,7 +8081,7 @@ var require_isexe = __commonJS((exports, module) => {
8081
8081
  }
8082
8082
  module.exports = isexe;
8083
8083
  isexe.sync = sync;
8084
- function isexe(path4, options, cb) {
8084
+ function isexe(path3, options, cb) {
8085
8085
  if (typeof options === "function") {
8086
8086
  cb = options;
8087
8087
  options = {};
@@ -8091,7 +8091,7 @@ var require_isexe = __commonJS((exports, module) => {
8091
8091
  throw new TypeError("callback not provided");
8092
8092
  }
8093
8093
  return new Promise(function(resolve6, reject) {
8094
- isexe(path4, options || {}, function(er, is) {
8094
+ isexe(path3, options || {}, function(er, is) {
8095
8095
  if (er) {
8096
8096
  reject(er);
8097
8097
  } else {
@@ -8100,7 +8100,7 @@ var require_isexe = __commonJS((exports, module) => {
8100
8100
  });
8101
8101
  });
8102
8102
  }
8103
- core3(path4, options || {}, function(er, is) {
8103
+ core3(path3, options || {}, function(er, is) {
8104
8104
  if (er) {
8105
8105
  if (er.code === "EACCES" || options && options.ignoreErrors) {
8106
8106
  er = null;
@@ -8110,9 +8110,9 @@ var require_isexe = __commonJS((exports, module) => {
8110
8110
  cb(er, is);
8111
8111
  });
8112
8112
  }
8113
- function sync(path4, options) {
8113
+ function sync(path3, options) {
8114
8114
  try {
8115
- return core3.sync(path4, options || {});
8115
+ return core3.sync(path3, options || {});
8116
8116
  } catch (er) {
8117
8117
  if (options && options.ignoreErrors || er.code === "EACCES") {
8118
8118
  return false;
@@ -8126,7 +8126,7 @@ var require_isexe = __commonJS((exports, module) => {
8126
8126
  // node_modules/which/which.js
8127
8127
  var require_which = __commonJS((exports, module) => {
8128
8128
  var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
8129
- var path4 = __require("path");
8129
+ var path3 = __require("path");
8130
8130
  var COLON = isWindows ? ";" : ":";
8131
8131
  var isexe = require_isexe();
8132
8132
  var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
@@ -8162,7 +8162,7 @@ var require_which = __commonJS((exports, module) => {
8162
8162
  return opt.all && found.length ? resolve6(found) : reject(getNotFoundError(cmd));
8163
8163
  const ppRaw = pathEnv[i2];
8164
8164
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
8165
- const pCmd = path4.join(pathPart, cmd);
8165
+ const pCmd = path3.join(pathPart, cmd);
8166
8166
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
8167
8167
  resolve6(subStep(p, i2, 0));
8168
8168
  });
@@ -8189,7 +8189,7 @@ var require_which = __commonJS((exports, module) => {
8189
8189
  for (let i2 = 0;i2 < pathEnv.length; i2++) {
8190
8190
  const ppRaw = pathEnv[i2];
8191
8191
  const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
8192
- const pCmd = path4.join(pathPart, cmd);
8192
+ const pCmd = path3.join(pathPart, cmd);
8193
8193
  const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
8194
8194
  for (let j = 0;j < pathExt.length; j++) {
8195
8195
  const cur = p + pathExt[j];
@@ -8230,7 +8230,7 @@ var require_path_key = __commonJS((exports, module) => {
8230
8230
 
8231
8231
  // node_modules/cross-spawn/lib/util/resolveCommand.js
8232
8232
  var require_resolveCommand = __commonJS((exports, module) => {
8233
- var path4 = __require("path");
8233
+ var path3 = __require("path");
8234
8234
  var which2 = require_which();
8235
8235
  var getPathKey = require_path_key();
8236
8236
  function resolveCommandAttempt(parsed, withoutPathExt) {
@@ -8247,7 +8247,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
8247
8247
  try {
8248
8248
  resolved = which2.sync(parsed.command, {
8249
8249
  path: env[getPathKey({ env })],
8250
- pathExt: withoutPathExt ? path4.delimiter : undefined
8250
+ pathExt: withoutPathExt ? path3.delimiter : undefined
8251
8251
  });
8252
8252
  } catch (e) {} finally {
8253
8253
  if (shouldSwitchCwd) {
@@ -8255,7 +8255,7 @@ var require_resolveCommand = __commonJS((exports, module) => {
8255
8255
  }
8256
8256
  }
8257
8257
  if (resolved) {
8258
- resolved = path4.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
8258
+ resolved = path3.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
8259
8259
  }
8260
8260
  return resolved;
8261
8261
  }
@@ -8300,8 +8300,8 @@ var require_shebang_command = __commonJS((exports, module) => {
8300
8300
  if (!match) {
8301
8301
  return null;
8302
8302
  }
8303
- const [path4, argument] = match[0].replace(/#! ?/, "").split(" ");
8304
- const binary2 = path4.split("/").pop();
8303
+ const [path3, argument] = match[0].replace(/#! ?/, "").split(" ");
8304
+ const binary2 = path3.split("/").pop();
8305
8305
  if (binary2 === "env") {
8306
8306
  return argument;
8307
8307
  }
@@ -8329,7 +8329,7 @@ var require_readShebang = __commonJS((exports, module) => {
8329
8329
 
8330
8330
  // node_modules/cross-spawn/lib/parse.js
8331
8331
  var require_parse2 = __commonJS((exports, module) => {
8332
- var path4 = __require("path");
8332
+ var path3 = __require("path");
8333
8333
  var resolveCommand = require_resolveCommand();
8334
8334
  var escape2 = require_escape();
8335
8335
  var readShebang = require_readShebang();
@@ -8354,7 +8354,7 @@ var require_parse2 = __commonJS((exports, module) => {
8354
8354
  const needsShell = !isExecutableRegExp.test(commandFile);
8355
8355
  if (parsed.options.forceShell || needsShell) {
8356
8356
  const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
8357
- parsed.command = path4.normalize(parsed.command);
8357
+ parsed.command = path3.normalize(parsed.command);
8358
8358
  parsed.command = escape2.command(parsed.command);
8359
8359
  parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
8360
8360
  const shellCommand = [parsed.command].concat(parsed.args).join(" ");
@@ -11981,7 +11981,7 @@ var require_main = __commonJS((exports) => {
11981
11981
  exports.createMessageConnection = exports.createServerSocketTransport = exports.createClientSocketTransport = exports.createServerPipeTransport = exports.createClientPipeTransport = exports.generateRandomPipeName = exports.StreamMessageWriter = exports.StreamMessageReader = exports.SocketMessageWriter = exports.SocketMessageReader = exports.PortMessageWriter = exports.PortMessageReader = exports.IPCMessageWriter = exports.IPCMessageReader = undefined;
11982
11982
  var ril_1 = require_ril();
11983
11983
  ril_1.default.install();
11984
- var path4 = __require("path");
11984
+ var path3 = __require("path");
11985
11985
  var os3 = __require("os");
11986
11986
  var crypto_1 = __require("crypto");
11987
11987
  var net_1 = __require("net");
@@ -12123,9 +12123,9 @@ var require_main = __commonJS((exports) => {
12123
12123
  }
12124
12124
  let result;
12125
12125
  if (XDG_RUNTIME_DIR) {
12126
- result = path4.join(XDG_RUNTIME_DIR, `vscode-ipc-${randomSuffix}.sock`);
12126
+ result = path3.join(XDG_RUNTIME_DIR, `vscode-ipc-${randomSuffix}.sock`);
12127
12127
  } else {
12128
- result = path4.join(os3.tmpdir(), `vscode-${randomSuffix}.sock`);
12128
+ result = path3.join(os3.tmpdir(), `vscode-${randomSuffix}.sock`);
12129
12129
  }
12130
12130
  const limit = safeIpcPathLengths.get(process.platform);
12131
12131
  if (limit !== undefined && result.length > limit) {
@@ -12308,7 +12308,7 @@ function initConfigContext(binary, version) {
12308
12308
  // package.json
12309
12309
  var package_default = {
12310
12310
  name: "oh-my-opencode-gpt-slim",
12311
- version: "0.1.2",
12311
+ version: "0.1.3",
12312
12312
  description: "GPT-optimized lean fork of oh-my-openagent \u2014 33 hooks removed, 5 tools removed, Sisyphus prompt rewritten based on OpenAI Codex prompt.md",
12313
12313
  main: "dist/index.js",
12314
12314
  types: "dist/index.d.ts",
@@ -12386,15 +12386,15 @@ var package_default = {
12386
12386
  typescript: "^5.7.3"
12387
12387
  },
12388
12388
  optionalDependencies: {
12389
- "oh-my-opencode-gpt-slim-darwin-arm64": "0.1.2",
12390
- "oh-my-opencode-gpt-slim-darwin-x64": "0.1.2",
12391
- "oh-my-opencode-gpt-slim-darwin-x64-baseline": "0.1.2",
12392
- "oh-my-opencode-gpt-slim-linux-arm64": "0.1.2",
12393
- "oh-my-opencode-gpt-slim-linux-arm64-musl": "0.1.2",
12394
- "oh-my-opencode-gpt-slim-linux-x64": "0.1.2",
12395
- "oh-my-opencode-gpt-slim-linux-x64-baseline": "0.1.2",
12396
- "oh-my-opencode-gpt-slim-linux-x64-musl": "0.1.2",
12397
- "oh-my-opencode-gpt-slim-linux-x64-musl-baseline": "0.1.2"
12389
+ "oh-my-opencode-gpt-slim-darwin-arm64": "0.1.3",
12390
+ "oh-my-opencode-gpt-slim-darwin-x64": "0.1.3",
12391
+ "oh-my-opencode-gpt-slim-darwin-x64-baseline": "0.1.3",
12392
+ "oh-my-opencode-gpt-slim-linux-arm64": "0.1.3",
12393
+ "oh-my-opencode-gpt-slim-linux-arm64-musl": "0.1.3",
12394
+ "oh-my-opencode-gpt-slim-linux-x64": "0.1.3",
12395
+ "oh-my-opencode-gpt-slim-linux-x64-baseline": "0.1.3",
12396
+ "oh-my-opencode-gpt-slim-linux-x64-musl": "0.1.3",
12397
+ "oh-my-opencode-gpt-slim-linux-x64-musl-baseline": "0.1.3"
12398
12398
  },
12399
12399
  overrides: {
12400
12400
  "@opencode-ai/sdk": "^1.2.17"
@@ -16393,6 +16393,18 @@ function detectConfigFile(basePath) {
16393
16393
  }
16394
16394
  return { format: "none", path: jsonPath };
16395
16395
  }
16396
+ // src/shared/omo-config-file.ts
16397
+ import { join as join6 } from "path";
16398
+ var OMO_CONFIG_FILENAME = "oh-my-opencode-gpt-slim.json";
16399
+ function getOmoConfigFilePath(directory) {
16400
+ return join6(directory, OMO_CONFIG_FILENAME);
16401
+ }
16402
+ function getProjectOmoConfigFilePath(projectRoot) {
16403
+ return getOmoConfigFilePath(join6(projectRoot, ".opencode"));
16404
+ }
16405
+ function parseOmoConfigJson(content) {
16406
+ return JSON.parse(content);
16407
+ }
16396
16408
  // src/shared/migration/agent-names.ts
16397
16409
  var AGENT_NAME_MAP = {
16398
16410
  omo: "sisyphus",
@@ -16723,7 +16735,7 @@ function isOpenCodeVersionAtLeast(version) {
16723
16735
  }
16724
16736
  // src/shared/opencode-storage-detection.ts
16725
16737
  import { existsSync as existsSync4 } from "fs";
16726
- import { join as join6 } from "path";
16738
+ import { join as join7 } from "path";
16727
16739
  var NOT_CACHED2 = Symbol("NOT_CACHED");
16728
16740
  var FALSE_PENDING_RETRY = Symbol("FALSE_PENDING_RETRY");
16729
16741
  var cachedResult = NOT_CACHED2;
@@ -16734,7 +16746,7 @@ function isSqliteBackend() {
16734
16746
  return false;
16735
16747
  const check = () => {
16736
16748
  const versionOk = isOpenCodeVersionAtLeast(OPENCODE_SQLITE_VERSION);
16737
- const dbPath = join6(getDataDir(), "opencode", "opencode.db");
16749
+ const dbPath = join7(getDataDir(), "opencode", "opencode.db");
16738
16750
  return versionOk && existsSync4(dbPath);
16739
16751
  };
16740
16752
  if (cachedResult === FALSE_PENDING_RETRY) {
@@ -17234,11 +17246,11 @@ init_logger();
17234
17246
  // src/shared/connected-providers-cache.ts
17235
17247
  init_logger();
17236
17248
  import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
17237
- import { join as join7 } from "path";
17249
+ import { join as join8 } from "path";
17238
17250
  var CONNECTED_PROVIDERS_CACHE_FILE = "connected-providers.json";
17239
17251
  var PROVIDER_MODELS_CACHE_FILE = "provider-models.json";
17240
17252
  function getCacheFilePath(filename) {
17241
- return join7(getOmoOpenCodeCacheDir(), filename);
17253
+ return join8(getOmoOpenCodeCacheDir(), filename);
17242
17254
  }
17243
17255
  function readConnectedProvidersCache() {
17244
17256
  const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
@@ -17283,7 +17295,7 @@ function readProviderModelsCache() {
17283
17295
  // src/shared/model-availability.ts
17284
17296
  init_logger();
17285
17297
  import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
17286
- import { join as join8 } from "path";
17298
+ import { join as join9 } from "path";
17287
17299
  function normalizeModelName(name) {
17288
17300
  return name.toLowerCase().replace(/claude-(opus|sonnet|haiku)-(\d+)[.-](\d+)/g, "claude-$1-$2.$3");
17289
17301
  }
@@ -17419,7 +17431,7 @@ async function fetchAvailableModels(client, options) {
17419
17431
  }
17420
17432
  }
17421
17433
  log("[fetchAvailableModels] provider-models cache not found, falling back to models.json");
17422
- const cacheFile = join8(getOpenCodeCacheDir(), "models.json");
17434
+ const cacheFile = join9(getOpenCodeCacheDir(), "models.json");
17423
17435
  if (!existsSync7(cacheFile)) {
17424
17436
  log("[fetchAvailableModels] models.json cache file not found, falling back to client");
17425
17437
  } else {
@@ -17710,7 +17722,7 @@ function isAnyFallbackModelAvailable(fallbackChain, availableModels) {
17710
17722
  // src/features/hook-message-injector/injector.ts
17711
17723
  import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync, writeFileSync as writeFileSync3 } from "fs";
17712
17724
  import { randomBytes } from "crypto";
17713
- import { join as join9 } from "path";
17725
+ import { join as join10 } from "path";
17714
17726
  init_logger();
17715
17727
  var processPrefix = randomBytes(4).toString("hex");
17716
17728
  function convertSDKMessageToStoredMessage(msg) {
@@ -17779,7 +17791,7 @@ function findNearestMessageWithFields(messageDir) {
17779
17791
  const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort().reverse();
17780
17792
  for (const file of files) {
17781
17793
  try {
17782
- const content = readFileSync5(join9(messageDir, file), "utf-8");
17794
+ const content = readFileSync5(join10(messageDir, file), "utf-8");
17783
17795
  const msg = JSON.parse(content);
17784
17796
  if (msg.agent && msg.model?.providerID && msg.model?.modelID) {
17785
17797
  return msg;
@@ -17790,7 +17802,7 @@ function findNearestMessageWithFields(messageDir) {
17790
17802
  }
17791
17803
  for (const file of files) {
17792
17804
  try {
17793
- const content = readFileSync5(join9(messageDir, file), "utf-8");
17805
+ const content = readFileSync5(join10(messageDir, file), "utf-8");
17794
17806
  const msg = JSON.parse(content);
17795
17807
  if (msg.agent || msg.model?.providerID && msg.model?.modelID) {
17796
17808
  return msg;
@@ -17812,7 +17824,7 @@ function findFirstMessageWithAgent(messageDir) {
17812
17824
  const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort();
17813
17825
  for (const file of files) {
17814
17826
  try {
17815
- const content = readFileSync5(join9(messageDir, file), "utf-8");
17827
+ const content = readFileSync5(join10(messageDir, file), "utf-8");
17816
17828
  const msg = JSON.parse(content);
17817
17829
  if (msg.agent) {
17818
17830
  return msg.agent;
@@ -17838,14 +17850,14 @@ async function resolveMessageContext(sessionID, client, messageDir) {
17838
17850
  }
17839
17851
  // src/shared/opencode-message-dir.ts
17840
17852
  import { existsSync as existsSync9, readdirSync as readdirSync2 } from "fs";
17841
- import { join as join11 } from "path";
17853
+ import { join as join12 } from "path";
17842
17854
 
17843
17855
  // src/shared/opencode-storage-paths.ts
17844
- import { join as join10 } from "path";
17856
+ import { join as join11 } from "path";
17845
17857
  var OPENCODE_STORAGE = getOpenCodeStorageDir();
17846
- var MESSAGE_STORAGE = join10(OPENCODE_STORAGE, "message");
17847
- var PART_STORAGE = join10(OPENCODE_STORAGE, "part");
17848
- var SESSION_STORAGE = join10(OPENCODE_STORAGE, "session");
17858
+ var MESSAGE_STORAGE = join11(OPENCODE_STORAGE, "message");
17859
+ var PART_STORAGE = join11(OPENCODE_STORAGE, "part");
17860
+ var SESSION_STORAGE = join11(OPENCODE_STORAGE, "session");
17849
17861
 
17850
17862
  // src/shared/opencode-message-dir.ts
17851
17863
  init_logger();
@@ -17858,13 +17870,13 @@ function getMessageDir(sessionID) {
17858
17870
  return null;
17859
17871
  if (!existsSync9(MESSAGE_STORAGE))
17860
17872
  return null;
17861
- const directPath = join11(MESSAGE_STORAGE, sessionID);
17873
+ const directPath = join12(MESSAGE_STORAGE, sessionID);
17862
17874
  if (existsSync9(directPath)) {
17863
17875
  return directPath;
17864
17876
  }
17865
17877
  try {
17866
17878
  for (const dir of readdirSync2(MESSAGE_STORAGE)) {
17867
- const sessionPath = join11(MESSAGE_STORAGE, dir, sessionID);
17879
+ const sessionPath = join12(MESSAGE_STORAGE, dir, sessionID);
17868
17880
  if (existsSync9(sessionPath)) {
17869
17881
  return sessionPath;
17870
17882
  }
@@ -18702,15 +18714,15 @@ init_logger();
18702
18714
  init_logger();
18703
18715
  import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
18704
18716
  import { homedir as homedir4 } from "os";
18705
- import { join as join12 } from "path";
18717
+ import { join as join13 } from "path";
18706
18718
  function getPluginsBaseDir() {
18707
18719
  if (process.env.CLAUDE_PLUGINS_HOME) {
18708
18720
  return process.env.CLAUDE_PLUGINS_HOME;
18709
18721
  }
18710
- return join12(homedir4(), ".claude", "plugins");
18722
+ return join13(homedir4(), ".claude", "plugins");
18711
18723
  }
18712
18724
  function getInstalledPluginsPath() {
18713
- return join12(getPluginsBaseDir(), "installed_plugins.json");
18725
+ return join13(getPluginsBaseDir(), "installed_plugins.json");
18714
18726
  }
18715
18727
  function loadInstalledPlugins() {
18716
18728
  const dbPath = getInstalledPluginsPath();
@@ -18729,7 +18741,7 @@ function getClaudeSettingsPath() {
18729
18741
  if (process.env.CLAUDE_SETTINGS_PATH) {
18730
18742
  return process.env.CLAUDE_SETTINGS_PATH;
18731
18743
  }
18732
- return join12(homedir4(), ".claude", "settings.json");
18744
+ return join13(homedir4(), ".claude", "settings.json");
18733
18745
  }
18734
18746
  function loadClaudeSettings() {
18735
18747
  const settingsPath = getClaudeSettingsPath();
@@ -18745,7 +18757,7 @@ function loadClaudeSettings() {
18745
18757
  }
18746
18758
  }
18747
18759
  function loadPluginManifest(installPath) {
18748
- const manifestPath = join12(installPath, ".claude-plugin", "plugin.json");
18760
+ const manifestPath = join13(installPath, ".claude-plugin", "plugin.json");
18749
18761
  if (!existsSync10(manifestPath)) {
18750
18762
  return null;
18751
18763
  }
@@ -18812,20 +18824,20 @@ function discoverInstalledPlugins(options) {
18812
18824
  pluginKey,
18813
18825
  manifest: manifest ?? undefined
18814
18826
  };
18815
- if (existsSync10(join12(installPath, "commands"))) {
18816
- loadedPlugin.commandsDir = join12(installPath, "commands");
18827
+ if (existsSync10(join13(installPath, "commands"))) {
18828
+ loadedPlugin.commandsDir = join13(installPath, "commands");
18817
18829
  }
18818
- if (existsSync10(join12(installPath, "agents"))) {
18819
- loadedPlugin.agentsDir = join12(installPath, "agents");
18830
+ if (existsSync10(join13(installPath, "agents"))) {
18831
+ loadedPlugin.agentsDir = join13(installPath, "agents");
18820
18832
  }
18821
- if (existsSync10(join12(installPath, "skills"))) {
18822
- loadedPlugin.skillsDir = join12(installPath, "skills");
18833
+ if (existsSync10(join13(installPath, "skills"))) {
18834
+ loadedPlugin.skillsDir = join13(installPath, "skills");
18823
18835
  }
18824
- const hooksPath = join12(installPath, "hooks", "hooks.json");
18836
+ const hooksPath = join13(installPath, "hooks", "hooks.json");
18825
18837
  if (existsSync10(hooksPath)) {
18826
18838
  loadedPlugin.hooksPath = hooksPath;
18827
18839
  }
18828
- const mcpPath = join12(installPath, ".mcp.json");
18840
+ const mcpPath = join13(installPath, ".mcp.json");
18829
18841
  if (existsSync10(mcpPath)) {
18830
18842
  loadedPlugin.mcpPath = mcpPath;
18831
18843
  }
@@ -18840,7 +18852,7 @@ function discoverInstalledPlugins(options) {
18840
18852
 
18841
18853
  // src/features/claude-code-plugin-loader/command-loader.ts
18842
18854
  import { existsSync as existsSync11, readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
18843
- import { basename, join as join13 } from "path";
18855
+ import { basename, join as join14 } from "path";
18844
18856
  init_logger();
18845
18857
  function loadPluginCommands(plugins) {
18846
18858
  const commands = {};
@@ -18851,7 +18863,7 @@ function loadPluginCommands(plugins) {
18851
18863
  for (const entry of entries) {
18852
18864
  if (!isMarkdownFile(entry))
18853
18865
  continue;
18854
- const commandPath = join13(plugin.commandsDir, entry.name);
18866
+ const commandPath = join14(plugin.commandsDir, entry.name);
18855
18867
  const commandName = basename(entry.name, ".md");
18856
18868
  const namespacedName = `${plugin.name}:${commandName}`;
18857
18869
  try {
@@ -18887,13 +18899,13 @@ $ARGUMENTS
18887
18899
 
18888
18900
  // src/features/claude-code-plugin-loader/skill-loader.ts
18889
18901
  import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync8 } from "fs";
18890
- import { join as join15 } from "path";
18902
+ import { join as join16 } from "path";
18891
18903
 
18892
18904
  // src/shared/skill-path-resolver.ts
18893
- import { join as join14 } from "path";
18905
+ import { join as join15 } from "path";
18894
18906
  function resolveSkillPathReferences(content, basePath) {
18895
18907
  const normalizedBase = basePath.endsWith("/") ? basePath.slice(0, -1) : basePath;
18896
- return content.replace(/(?<![a-zA-Z0-9])@([a-zA-Z0-9_-]+\/[a-zA-Z0-9_.\-\/]*)/g, (_, relativePath) => join14(normalizedBase, relativePath));
18908
+ return content.replace(/(?<![a-zA-Z0-9])@([a-zA-Z0-9_-]+\/[a-zA-Z0-9_.\-\/]*)/g, (_, relativePath) => join15(normalizedBase, relativePath));
18897
18909
  }
18898
18910
 
18899
18911
  // src/features/claude-code-plugin-loader/skill-loader.ts
@@ -18907,11 +18919,11 @@ function loadPluginSkillsAsCommands(plugins) {
18907
18919
  for (const entry of entries) {
18908
18920
  if (entry.name.startsWith("."))
18909
18921
  continue;
18910
- const skillPath = join15(plugin.skillsDir, entry.name);
18922
+ const skillPath = join16(plugin.skillsDir, entry.name);
18911
18923
  if (!entry.isDirectory() && !entry.isSymbolicLink())
18912
18924
  continue;
18913
18925
  const resolvedPath = resolveSymlink(skillPath);
18914
- const skillMdPath = join15(resolvedPath, "SKILL.md");
18926
+ const skillMdPath = join16(resolvedPath, "SKILL.md");
18915
18927
  if (!existsSync12(skillMdPath))
18916
18928
  continue;
18917
18929
  try {
@@ -18951,7 +18963,7 @@ $ARGUMENTS
18951
18963
 
18952
18964
  // src/features/claude-code-plugin-loader/agent-loader.ts
18953
18965
  import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
18954
- import { basename as basename2, join as join16 } from "path";
18966
+ import { basename as basename2, join as join17 } from "path";
18955
18967
  init_logger();
18956
18968
  function parseToolsConfig(toolsStr) {
18957
18969
  if (!toolsStr)
@@ -18974,7 +18986,7 @@ function loadPluginAgents(plugins) {
18974
18986
  for (const entry of entries) {
18975
18987
  if (!isMarkdownFile(entry))
18976
18988
  continue;
18977
- const agentPath = join16(plugin.agentsDir, entry.name);
18989
+ const agentPath = join17(plugin.agentsDir, entry.name);
18978
18990
  const agentName = basename2(entry.name, ".md");
18979
18991
  const namespacedName = `${plugin.name}:${agentName}`;
18980
18992
  try {
@@ -19326,16 +19338,16 @@ init_logger();
19326
19338
  // src/hooks/auto-update-checker/cache.ts
19327
19339
  init_logger();
19328
19340
  import { existsSync as existsSync17, rmSync, unlinkSync as unlinkSync2 } from "fs";
19329
- import { join as join18 } from "path";
19341
+ import { join as join19 } from "path";
19330
19342
 
19331
19343
  // src/hooks/auto-update-checker/constants.ts
19332
- import { join as join17 } from "path";
19344
+ import { join as join18 } from "path";
19333
19345
  var PACKAGE_NAME = PLUGIN_PACKAGE_NAME;
19334
19346
  var NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
19335
19347
  var NPM_FETCH_TIMEOUT = 5000;
19336
19348
  var CACHE_DIR = getOpenCodeCacheDir();
19337
19349
  var USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
19338
- var INSTALLED_PACKAGE_JSON = join17(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
19350
+ var INSTALLED_PACKAGE_JSON = join18(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
19339
19351
 
19340
19352
  // src/hooks/auto-update-checker/cache.ts
19341
19353
  function deleteLockfile(lockPath) {
@@ -19352,16 +19364,16 @@ function deleteLockfile(lockPath) {
19352
19364
  function invalidatePackage(packageName = PACKAGE_NAME) {
19353
19365
  let changed = false;
19354
19366
  for (const packageDir of [
19355
- join18(USER_CONFIG_DIR, "node_modules", packageName),
19356
- join18(CACHE_DIR, "node_modules", packageName)
19367
+ join19(USER_CONFIG_DIR, "node_modules", packageName),
19368
+ join19(CACHE_DIR, "node_modules", packageName)
19357
19369
  ]) {
19358
19370
  if (!existsSync17(packageDir))
19359
19371
  continue;
19360
19372
  rmSync(packageDir, { recursive: true, force: true });
19361
19373
  changed = true;
19362
19374
  }
19363
- changed = deleteLockfile(join18(CACHE_DIR, "bun.lock")) || changed;
19364
- changed = deleteLockfile(join18(CACHE_DIR, "bun.lockb")) || changed;
19375
+ changed = deleteLockfile(join19(CACHE_DIR, "bun.lock")) || changed;
19376
+ changed = deleteLockfile(join19(CACHE_DIR, "bun.lockb")) || changed;
19365
19377
  return changed;
19366
19378
  }
19367
19379
 
@@ -19369,12 +19381,12 @@ function invalidatePackage(packageName = PACKAGE_NAME) {
19369
19381
  import { existsSync as existsSync18, readFileSync as readFileSync11 } from "fs";
19370
19382
 
19371
19383
  // src/hooks/auto-update-checker/checker/config-paths.ts
19372
- import { join as join19 } from "path";
19384
+ import { join as join20 } from "path";
19373
19385
  function getConfigPaths(directory) {
19374
19386
  const userPaths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
19375
19387
  return [
19376
- join19(directory, ".opencode", "opencode.jsonc"),
19377
- join19(directory, ".opencode", "opencode.json"),
19388
+ join20(directory, ".opencode", "opencode.jsonc"),
19389
+ join20(directory, ".opencode", "opencode.json"),
19378
19390
  userPaths.configJsonc,
19379
19391
  userPaths.configJson
19380
19392
  ];
@@ -20087,7 +20099,6 @@ init_logger();
20087
20099
 
20088
20100
  // src/plugin-config.ts
20089
20101
  import * as fs4 from "fs";
20090
- import * as path3 from "path";
20091
20102
 
20092
20103
  // node_modules/zod/v4/classic/external.js
20093
20104
  var exports_external = {};
@@ -34046,7 +34057,9 @@ function parseConfigPartially(rawConfig) {
34046
34057
  const partialConfig = {};
34047
34058
  const invalidSections = [];
34048
34059
  for (const key of Object.keys(rawConfig)) {
34049
- const sectionResult = OhMyOpenCodeConfigSchema.safeParse({ [key]: rawConfig[key] });
34060
+ const sectionResult = OhMyOpenCodeConfigSchema.safeParse({
34061
+ [key]: rawConfig[key]
34062
+ });
34050
34063
  if (sectionResult.success) {
34051
34064
  const parsed = sectionResult.data;
34052
34065
  if (parsed[key] !== undefined) {
@@ -34068,7 +34081,7 @@ function loadConfigFromPath(configPath, _ctx) {
34068
34081
  try {
34069
34082
  if (fs4.existsSync(configPath)) {
34070
34083
  const content = fs4.readFileSync(configPath, "utf-8");
34071
- const rawConfig = parseJsonc(content);
34084
+ const rawConfig = parseOmoConfigJson(content);
34072
34085
  migrateConfigFile(configPath, rawConfig);
34073
34086
  const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
34074
34087
  if (result.success) {
@@ -34083,7 +34096,9 @@ function loadConfigFromPath(configPath, _ctx) {
34083
34096
  });
34084
34097
  const partialResult = parseConfigPartially(rawConfig);
34085
34098
  if (partialResult) {
34086
- log(`Partial config loaded from ${configPath}`, { agents: partialResult.agents });
34099
+ log(`Partial config loaded from ${configPath}`, {
34100
+ agents: partialResult.agents
34101
+ });
34087
34102
  return partialResult;
34088
34103
  }
34089
34104
  return null;
@@ -34135,13 +34150,11 @@ function mergeConfigs(base, override) {
34135
34150
  };
34136
34151
  }
34137
34152
  function loadPluginConfig(directory, ctx) {
34138
- const configDir = getOpenCodeConfigDir({ binary: "opencode" });
34139
- const userBasePath = path3.join(configDir, "oh-my-opencode-gpt-slim");
34140
- const userDetected = detectConfigFile(userBasePath);
34141
- const userConfigPath = userDetected.format !== "none" ? userDetected.path : userBasePath + ".json";
34142
- const projectBasePath = path3.join(directory, ".opencode", "oh-my-opencode-gpt-slim");
34143
- const projectDetected = detectConfigFile(projectBasePath);
34144
- const projectConfigPath = projectDetected.format !== "none" ? projectDetected.path : projectBasePath + ".json";
34153
+ const userConfigPath = getOpenCodeConfigPaths({
34154
+ binary: "opencode",
34155
+ version: null
34156
+ }).omoConfig;
34157
+ const projectConfigPath = getProjectOmoConfigFilePath(directory);
34145
34158
  let config2 = loadConfigFromPath(userConfigPath, ctx) ?? {};
34146
34159
  const projectConfig = loadConfigFromPath(projectConfigPath, ctx);
34147
34160
  if (projectConfig) {
@@ -35913,12 +35926,12 @@ var AGENTS_INJECTOR_STORAGE = join25(OPENCODE_STORAGE, "directory-agents");
35913
35926
  var AGENTS_FILENAME = "AGENTS.md";
35914
35927
 
35915
35928
  // src/hooks/directory-agents-injector/finder.ts
35916
- function resolveFilePath2(rootDirectory, path4) {
35917
- if (!path4)
35929
+ function resolveFilePath2(rootDirectory, path3) {
35930
+ if (!path3)
35918
35931
  return null;
35919
- if (isAbsolute2(path4))
35920
- return path4;
35921
- return resolve2(rootDirectory, path4);
35932
+ if (isAbsolute2(path3))
35933
+ return path3;
35934
+ return resolve2(rootDirectory, path3);
35922
35935
  }
35923
35936
  function findAgentsMdUp(input) {
35924
35937
  const found = [];
@@ -36091,12 +36104,12 @@ var README_INJECTOR_STORAGE = join28(OPENCODE_STORAGE, "directory-readme");
36091
36104
  var README_FILENAME = "README.md";
36092
36105
 
36093
36106
  // src/hooks/directory-readme-injector/finder.ts
36094
- function resolveFilePath3(rootDirectory, path4) {
36095
- if (!path4)
36107
+ function resolveFilePath3(rootDirectory, path3) {
36108
+ if (!path3)
36096
36109
  return null;
36097
- if (isAbsolute3(path4))
36098
- return path4;
36099
- return resolve3(rootDirectory, path4);
36110
+ if (isAbsolute3(path3))
36111
+ return path3;
36112
+ return resolve3(rootDirectory, path3);
36100
36113
  }
36101
36114
  function findReadmeMdUp(input) {
36102
36115
  const found = [];
@@ -36641,12 +36654,12 @@ function getCachedParsedRule(filePath, realPath) {
36641
36654
  return parseRuleFrontmatter(rawContent);
36642
36655
  }
36643
36656
  }
36644
- function resolveFilePath4(workspaceDirectory, path4) {
36645
- if (!path4)
36657
+ function resolveFilePath4(workspaceDirectory, path3) {
36658
+ if (!path3)
36646
36659
  return null;
36647
- if (path4.startsWith("/"))
36648
- return path4;
36649
- return resolve4(workspaceDirectory, path4);
36660
+ if (path3.startsWith("/"))
36661
+ return path3;
36662
+ return resolve4(workspaceDirectory, path3);
36650
36663
  }
36651
36664
  function createRuleInjectionProcessor(deps) {
36652
36665
  const { workspaceDirectory, truncator, getSessionCache: getSessionCache3 } = deps;
@@ -37021,16 +37034,16 @@ class Diff {
37021
37034
  }
37022
37035
  }
37023
37036
  }
37024
- addToPath(path4, added, removed, oldPosInc, options) {
37025
- const last = path4.lastComponent;
37037
+ addToPath(path3, added, removed, oldPosInc, options) {
37038
+ const last = path3.lastComponent;
37026
37039
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
37027
37040
  return {
37028
- oldPos: path4.oldPos + oldPosInc,
37041
+ oldPos: path3.oldPos + oldPosInc,
37029
37042
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
37030
37043
  };
37031
37044
  } else {
37032
37045
  return {
37033
- oldPos: path4.oldPos + oldPosInc,
37046
+ oldPos: path3.oldPos + oldPosInc,
37034
37047
  lastComponent: { count: 1, added, removed, previousComponent: last }
37035
37048
  };
37036
37049
  }
@@ -45870,196 +45883,6 @@ function isGeminiModel(model) {
45870
45883
  const modelName = extractModelName(model).toLowerCase();
45871
45884
  return modelName.startsWith("gemini-");
45872
45885
  }
45873
- // src/agents/sisyphus/gemini.ts
45874
- function buildGeminiToolMandate() {
45875
- return `<TOOL_CALL_MANDATE>
45876
- ## YOU MUST USE TOOLS. THIS IS NOT OPTIONAL.
45877
-
45878
- **The user expects you to ACT using tools, not REASON internally.** Every response to a task MUST contain tool_use blocks. A response without tool calls is a FAILED response.
45879
-
45880
- **YOUR FAILURE MODE**: You believe you can reason through problems without calling tools. You CANNOT. Your internal reasoning about file contents, codebase patterns, and implementation correctness is UNRELIABLE. The ONLY reliable information comes from actual tool calls.
45881
-
45882
- **RULES (VIOLATION = BROKEN RESPONSE):**
45883
-
45884
- 1. **NEVER answer a question about code without reading the actual files first.** Your memory of files you "recently read" decays rapidly. Read them AGAIN.
45885
- 2. **NEVER claim a task is done without running \`lsp_diagnostics\`.** Your confidence that "this should work" is WRONG more often than right.
45886
- 3. **NEVER skip delegation because you think you can do it faster yourself.** You CANNOT. Specialists with domain-specific skills produce better results. USE THEM.
45887
- 4. **NEVER reason about what a file "probably contains."** READ IT. Tool calls are cheap. Wrong answers are expensive.
45888
- 5. **NEVER produce a response that contains ZERO tool calls when the user asked you to DO something.** Thinking is not doing.
45889
-
45890
- **THINK ABOUT WHICH TOOLS TO USE:**
45891
- Before responding, enumerate in your head:
45892
- - What tools do I need to call to fulfill this request?
45893
- - What information am I assuming that I should verify with a tool call?
45894
- - Am I about to skip a tool call because I "already know" the answer?
45895
-
45896
- Then ACTUALLY CALL those tools using the JSON tool schema. Produce the tool_use blocks. Execute.
45897
- </TOOL_CALL_MANDATE>`;
45898
- }
45899
- function buildGeminiToolGuide() {
45900
- return `<GEMINI_TOOL_GUIDE>
45901
- ## Tool Usage Guide \u2014 WHEN and HOW to Call Each Tool
45902
-
45903
- You have access to tools via function calling. This guide defines WHEN to call each one.
45904
- **Violating these patterns = failed response.**
45905
-
45906
- ### Reading & Search (parallelize)
45907
- - \`Read\`: before ANY claim about file contents; before editing any file
45908
- - \`Grep\`: find patterns, imports, usages; verify "X is used in Y"
45909
- - \`Glob\`: verify file existence by name/extension pattern
45910
- - \`AstGrepSearch\`: structural code pattern search
45911
-
45912
- ### Code Intelligence (parallelize on different files)
45913
- - \`LspDiagnostics\`: AFTER EVERY edit; BEFORE claiming done; MANDATORY
45914
- - \`LspGotoDefinition\`: find where a symbol is defined
45915
- - \`LspFindReferences\`: find all usages across workspace
45916
- - \`LspSymbols\`: file outline or workspace symbol search
45917
-
45918
- ### Editing (sequential)
45919
- - \`Edit\`: modify existing files; MUST Read first for LINE#ID anchors
45920
- - \`Write\`: create new files or fully overwrite files
45921
-
45922
- ### Execution & Delegation
45923
- - \`Bash\`: tests, builds, git commands; usually sequential
45924
- - \`Task\`: ANY non-trivial implementation; research via explore/librarian; fire in background
45925
-
45926
- ### Correct Sequences (MANDATORY \u2014 follow these exactly):
45927
-
45928
- 1. **Answer about code**: Read \u2192 (analyze) \u2192 Answer
45929
- 2. **Edit code**: Read \u2192 Edit \u2192 LspDiagnostics \u2192 Report
45930
- 3. **Find something**: Grep/Glob (parallel) \u2192 Read results \u2192 Report
45931
- 4. **Implement feature**: Task(delegate) \u2192 Verify results \u2192 Report
45932
- 5. **Debug**: Read error \u2192 Read file \u2192 Grep related \u2192 Fix \u2192 LspDiagnostics
45933
-
45934
- ### PARALLEL RULES:
45935
-
45936
- - **Independent reads/searches**: ALWAYS call simultaneously in ONE response
45937
- - **Dependent operations**: Call sequentially (Edit AFTER Read, LspDiagnostics AFTER Edit)
45938
- - **Background agents**: ALWAYS \`run_in_background=true\`, continue working
45939
- </GEMINI_TOOL_GUIDE>`;
45940
- }
45941
- function buildGeminiToolCallExamples() {
45942
- return `<GEMINI_TOOL_CALL_EXAMPLES>
45943
- ## Correct Tool Calling Patterns \u2014 Follow These Examples
45944
-
45945
- ### Example 1: User asks about code \u2192 Read FIRST, then answer
45946
- **User**: "How does the auth middleware work?"
45947
- **CORRECT**:
45948
- \`\`\`
45949
- \u2192 Call Read(filePath="/src/middleware/auth.ts")
45950
- \u2192 Call Read(filePath="/src/config/auth.ts") // parallel with above
45951
- \u2192 (After reading) Answer based on ACTUAL file contents
45952
- \`\`\`
45953
- **WRONG**:
45954
- \`\`\`
45955
- \u2192 "The auth middleware likely validates JWT tokens by..." \u2190 HALLUCINATION. You didn't read the file.
45956
- \`\`\`
45957
-
45958
- ### Example 2: User asks to edit code \u2192 Read, Edit, Verify
45959
- **User**: "Fix the type error in user.ts"
45960
- **CORRECT**:
45961
- \`\`\`
45962
- \u2192 Call Read(filePath="/src/models/user.ts")
45963
- \u2192 Call LspDiagnostics(filePath="/src/models/user.ts") // parallel with Read
45964
- \u2192 (After reading) Call Edit with LINE#ID anchors
45965
- \u2192 Call LspDiagnostics(filePath="/src/models/user.ts") // verify fix
45966
- \u2192 Report: "Fixed. Diagnostics clean."
45967
- \`\`\`
45968
- **WRONG**:
45969
- \`\`\`
45970
- \u2192 Call Edit without reading first \u2190 No LINE#ID anchors = WILL FAIL
45971
- \u2192 Skip LspDiagnostics after edit \u2190 UNVERIFIED
45972
- \`\`\`
45973
-
45974
- ### Example 3: Investigation \u2260 Implementation
45975
- **User**: "Look into why the tests are failing"
45976
- **CORRECT**:
45977
- \`\`\`
45978
- \u2192 Call Bash(command="npm test") // see actual failures
45979
- \u2192 Call Read on failing test files
45980
- \u2192 Call Read on source files under test
45981
- \u2192 Report: "Tests fail because X. Root cause: Y. Proposed fix: Z."
45982
- \u2192 STOP \u2014 wait for user to say "fix it"
45983
- \`\`\`
45984
- **WRONG**:
45985
- \`\`\`
45986
- \u2192 Start editing source files immediately \u2190 "look into" \u2260 "fix"
45987
- \`\`\`
45988
- </GEMINI_TOOL_CALL_EXAMPLES>`;
45989
- }
45990
- function buildGeminiDelegationOverride() {
45991
- return `<GEMINI_DELEGATION_OVERRIDE>
45992
- ## DELEGATION IS MANDATORY \u2014 YOU ARE NOT AN IMPLEMENTER
45993
-
45994
- **You have a strong tendency to do work yourself. RESIST THIS.**
45995
-
45996
- You are an ORCHESTRATOR. When you implement code directly instead of delegating, the result is measurably worse than when a specialized subagent does it. This is not opinion \u2014 subagents have domain-specific configurations, loaded skills, and tuned prompts that you lack.
45997
-
45998
- **EVERY TIME you are about to write code or make changes directly:**
45999
- \u2192 STOP. Ask: "Is there a category + skills combination for this?"
46000
- \u2192 If YES (almost always): delegate via \`task()\`
46001
- \u2192 If NO (extremely rare): proceed, but this should happen less than 5% of the time
46002
-
46003
- **The user chose an orchestrator model specifically because they want delegation and parallel execution. If you do work yourself, you are failing your purpose.**
46004
- </GEMINI_DELEGATION_OVERRIDE>`;
46005
- }
46006
- function buildGeminiVerificationOverride() {
46007
- return `<GEMINI_VERIFICATION_OVERRIDE>
46008
- ## YOUR SELF-ASSESSMENT IS UNRELIABLE \u2014 VERIFY WITH TOOLS
46009
-
46010
- **When you believe something is "done" or "correct" \u2014 you are probably wrong.**
46011
-
46012
- Your internal confidence estimator is miscalibrated toward optimism. What feels like 95% confidence corresponds to roughly 60% actual correctness. This is a known characteristic, not an insult.
46013
-
46014
- **MANDATORY**: Replace internal confidence with external verification:
46015
-
46016
- | Your Feeling | Reality | Required Action |
46017
- | "This should work" | ~60% chance it works | Run \`lsp_diagnostics\` NOW |
46018
- | "I'm sure this file exists" | ~70% chance | Use \`glob\` to verify NOW |
46019
- | "The subagent did it right" | ~50% chance | Read EVERY changed file NOW |
46020
- | "No need to check this" | You DEFINITELY need to | Check it NOW |
46021
-
46022
- **BEFORE claiming ANY task is complete:**
46023
- 1. Run \`lsp_diagnostics\` on ALL changed files \u2014 ACTUALLY clean, not "probably clean"
46024
- 2. If tests exist, run them \u2014 ACTUALLY pass, not "they should pass"
46025
- 3. Read the output of every command \u2014 ACTUALLY read, not skim
46026
- 4. If you delegated, read EVERY file the subagent touched \u2014 not trust their claims
46027
- </GEMINI_VERIFICATION_OVERRIDE>`;
46028
- }
46029
- function buildGeminiIntentGateEnforcement() {
46030
- return `<GEMINI_INTENT_GATE_ENFORCEMENT>
46031
- ## YOU MUST CLASSIFY INTENT BEFORE ACTING. NO EXCEPTIONS.
46032
-
46033
- **Your failure mode: You skip intent classification and jump straight to implementation.**
46034
-
46035
- You see a user message and your instinct is to immediately start working. WRONG. You MUST first determine WHAT KIND of work the user wants. Getting this wrong wastes everything that follows.
46036
-
46037
- **MANDATORY FIRST OUTPUT \u2014 before ANY tool call or action:**
46038
-
46039
- \`\`\`
46040
- I detect [TYPE] intent \u2014 [REASON].
46041
- My approach: [ROUTING DECISION].
46042
- \`\`\`
46043
-
46044
- Where TYPE is one of: research | implementation | investigation | evaluation | fix | open-ended
46045
-
46046
- **SELF-CHECK (answer honestly before proceeding):**
46047
-
46048
- 1. Did the user EXPLICITLY ask me to implement/build/create something? \u2192 If NO, do NOT implement.
46049
- 2. Did the user say "look into", "check", "investigate", "explain"? \u2192 That means RESEARCH, not implementation.
46050
- 3. Did the user ask "what do you think?" \u2192 That means EVALUATION \u2014 propose and WAIT, do not execute.
46051
- 4. Did the user report an error? \u2192 That means MINIMAL FIX, not refactoring.
46052
-
46053
- **COMMON MISTAKES YOU MAKE (AND MUST NOT):**
46054
- - "explain how X works" \u2192 Research X, explain it, STOP
46055
- - "look into this bug" \u2192 Investigate, report findings, WAIT for go-ahead
46056
- - "what do you think about approach X?" \u2192 Evaluate X, propose alternatives, WAIT
46057
- - "improve the tests" \u2192 Assess current tests FIRST, propose approach, THEN implement
46058
-
46059
- **IF YOU SKIPPED THE INTENT CLASSIFICATION ABOVE:** STOP. Go back. Do it now. Your next tool call is INVALID without it.
46060
- </GEMINI_INTENT_GATE_ENFORCEMENT>`;
46061
- }
46062
-
46063
45886
  // src/agents/dynamic-agent-prompt-builder.ts
46064
45887
  function categorizeTools(toolNames) {
46065
45888
  return toolNames.map((name) => {
@@ -46094,6 +45917,136 @@ function formatToolsForPrompt(tools) {
46094
45917
  }
46095
45918
  return parts.join(", ");
46096
45919
  }
45920
+ function hasAgent(agents, name) {
45921
+ return agents.some((agent) => agent.name === name);
45922
+ }
45923
+ function buildSearchGuidance(tools = []) {
45924
+ const searchTools = tools.filter((tool) => tool.category === "search").map((tool) => `\`${tool.name}\``);
45925
+ const hasLspTools = tools.some((tool) => tool.category === "lsp");
45926
+ const availableSearch = [...searchTools, ...hasLspTools ? ["`lsp_*`"] : []];
45927
+ if (availableSearch.length === 0) {
45928
+ return "Use repo-native search tools first, then read known files directly";
45929
+ }
45930
+ return `Use repo-native search first (${availableSearch.join(", ")}), then read known files directly`;
45931
+ }
45932
+ function buildDefaultResearchFlow(agents) {
45933
+ const hasExplore = hasAgent(agents, "explore");
45934
+ const hasLibrarian = hasAgent(agents, "librarian");
45935
+ if (hasExplore && hasLibrarian) {
45936
+ return "**Default flow**: explore/librarian (background) + tools \u2192 oracle (if required)";
45937
+ }
45938
+ if (hasExplore) {
45939
+ return "**Default flow**: explore (background) + repo-native tools \u2192 oracle (if required)";
45940
+ }
45941
+ if (hasLibrarian) {
45942
+ return "**Default flow**: librarian (background) + repo-native tools \u2192 oracle (if required)";
45943
+ }
45944
+ return "**Default flow**: repo-native tools \u2192 oracle (if required)";
45945
+ }
45946
+ function buildExplorationParallelGuidance(agents) {
45947
+ const hasExplore = hasAgent(agents, "explore");
45948
+ const hasLibrarian = hasAgent(agents, "librarian");
45949
+ if (hasExplore && hasLibrarian) {
45950
+ return "Parallelize EVERYTHING independent. Fire 2-5 explore/librarian agents (always `run_in_background=true`) for any non-trivial codebase question.";
45951
+ }
45952
+ if (hasExplore) {
45953
+ return "Parallelize EVERYTHING independent. Fire 2-5 explore agents (always `run_in_background=true`) for non-trivial repo discovery.";
45954
+ }
45955
+ if (hasLibrarian) {
45956
+ return "Parallelize EVERYTHING independent. Use librarian (always `run_in_background=true`) for external docs/code questions, and use repo-native tools for repo discovery.";
45957
+ }
45958
+ return "Parallelize EVERYTHING independent. Use repo-native tools aggressively for discovery when no research agents are available.";
45959
+ }
45960
+ function buildResearchDelegationThresholds(agents) {
45961
+ const hasExplore = hasAgent(agents, "explore");
45962
+ const hasLibrarian = hasAgent(agents, "librarian");
45963
+ if (hasExplore && hasLibrarian) {
45964
+ return "- need to discover files, symbols, or patterns first \u2192 `explore`\n- unfamiliar or version-sensitive library/API behavior \u2192 `librarian`";
45965
+ }
45966
+ if (hasExplore) {
45967
+ return "- need to discover files, symbols, or patterns first \u2192 `explore`\n- library/API uncertainty without external research support \u2192 use repo-native tools first and avoid guessing";
45968
+ }
45969
+ if (hasLibrarian) {
45970
+ return "- need repo discovery first \u2192 use repo-native tools\n- unfamiliar or version-sensitive library/API behavior \u2192 `librarian`";
45971
+ }
45972
+ return `- need to discover files, symbols, or patterns first \u2192 use repo-native tools
45973
+ - library/API uncertainty without research agents \u2192 rely on available repo context and avoid guessing`;
45974
+ }
45975
+ function buildResearchAnswerRouting(agents) {
45976
+ const hasExplore = hasAgent(agents, "explore");
45977
+ const hasLibrarian = hasAgent(agents, "librarian");
45978
+ if (hasExplore && hasLibrarian) {
45979
+ return "explore/librarian \u2192 synthesize \u2192 answer";
45980
+ }
45981
+ if (hasExplore) {
45982
+ return "explore + repo-native tools \u2192 synthesize \u2192 answer";
45983
+ }
45984
+ if (hasLibrarian) {
45985
+ return "librarian + repo-native tools \u2192 synthesize \u2192 answer";
45986
+ }
45987
+ return "repo-native tools \u2192 synthesize \u2192 answer";
45988
+ }
45989
+ function buildInvestigationRouting(agents) {
45990
+ return hasAgent(agents, "explore") ? "explore \u2192 report findings" : "repo-native tools \u2192 report findings";
45991
+ }
45992
+ function buildResearchToolUsageRules(agents) {
45993
+ const hasExplore = hasAgent(agents, "explore");
45994
+ const hasLibrarian = hasAgent(agents, "librarian");
45995
+ if (hasExplore && hasLibrarian) {
45996
+ return "- Explore/Librarian = background research. ALWAYS `run_in_background=true`, ALWAYS parallel\n- Fire 2-5 explore/librarian agents in parallel for any non-trivial codebase question";
45997
+ }
45998
+ if (hasExplore) {
45999
+ return "- Explore = background repo research. ALWAYS `run_in_background=true`, ALWAYS parallel\n- Fire 2-5 explore agents in parallel for non-trivial repo discovery; use repo-native tools for the rest";
46000
+ }
46001
+ if (hasLibrarian) {
46002
+ return "- Librarian = background external research. ALWAYS `run_in_background=true`; use repo-native tools for repo discovery\n- Fire librarian proactively for library/docs questions, but keep direct repo inspection in tools";
46003
+ }
46004
+ return "- No research agents available. Use repo-native tools in parallel for discovery and avoid guessing from memory";
46005
+ }
46006
+ function buildBackgroundResearchExamples(agents) {
46007
+ const hasExplore = hasAgent(agents, "explore");
46008
+ const hasLibrarian = hasAgent(agents, "librarian");
46009
+ if (hasExplore && hasLibrarian) {
46010
+ return `**Research agents = background grep, not consultants.**
46011
+
46012
+
46013
+ ~~~typescript
46014
+ // CORRECT: Always background, always parallel.
46015
+ task(subagent_type="explore", run_in_background=true, load_skills=[], description="Find auth patterns", prompt="[CONTEXT] Adding JWT auth in src/api/routes/. [GOAL] Match existing middleware and token-flow conventions. [DOWNSTREAM] Use findings to choose middleware structure and validation flow. [REQUEST] Find auth middleware, login/signup handlers, token generation, and credential validation. Focus on src/, skip tests, return file paths with pattern summaries.")
46016
+ task(subagent_type="librarian", run_in_background=true, load_skills=[], description="Find JWT security guidance", prompt="[CONTEXT] Implementing JWT auth and choosing token storage plus expiration policy. [GOAL] Get current production security guidance. [DOWNSTREAM] Use findings to choose storage, lifetime, and refresh strategy. [REQUEST] Find OWASP guidance, token lifetime recommendations, refresh rotation strategies, and common JWT vulnerabilities. Skip tutorials, return concise production-focused recommendations.")
46017
+
46018
+ // WRONG: Never block on explore/librarian.
46019
+ result = task(..., run_in_background=false)
46020
+ ~~~
46021
+ `;
46022
+ }
46023
+ if (hasExplore) {
46024
+ return `**Explore = background repo grep. Use repo-native tools for anything outside the repo.**
46025
+
46026
+
46027
+ ~~~typescript
46028
+ // CORRECT: Use explore in background for repo discovery.
46029
+ task(subagent_type="explore", run_in_background=true, load_skills=[], description="Find auth patterns", prompt="[CONTEXT] Adding JWT auth in src/api/routes/. [GOAL] Match existing middleware and token-flow conventions. [DOWNSTREAM] Use findings to choose middleware structure and validation flow. [REQUEST] Find auth middleware, login/signup handlers, token generation, and credential validation. Focus on src/, skip tests, return file paths with pattern summaries.")
46030
+
46031
+ // WRONG: Never block on explore.
46032
+ result = task(..., run_in_background=false)
46033
+ ~~~
46034
+ `;
46035
+ }
46036
+ if (hasLibrarian) {
46037
+ return `**Librarian = background external research. Use repo-native tools for repo discovery.**
46038
+
46039
+
46040
+ ~~~typescript
46041
+ // CORRECT: Use librarian in background for external docs/code guidance.
46042
+ task(subagent_type="librarian", run_in_background=true, load_skills=[], description="Find JWT security guidance", prompt="[CONTEXT] Implementing JWT auth and choosing token storage plus expiration policy. [GOAL] Get current production security guidance. [DOWNSTREAM] Use findings to choose storage, lifetime, and refresh strategy. [REQUEST] Find OWASP guidance, token lifetime recommendations, refresh rotation strategies, and common JWT vulnerabilities. Skip tutorials, return concise production-focused recommendations.")
46043
+
46044
+ // WRONG: Use repo-native tools, not librarian, for files you can inspect directly.
46045
+ ~~~
46046
+ `;
46047
+ }
46048
+ return "**No research agents are available. Use repo-native tools directly and parallelize reads/searches aggressively.**";
46049
+ }
46097
46050
  function buildKeyTriggersSection(agents, _skills = []) {
46098
46051
  const keyTriggers = agents.filter((a) => a.metadata.keyTrigger).map((a) => `- ${a.metadata.keyTrigger}`);
46099
46052
  if (keyTriggers.length === 0)
@@ -46120,7 +46073,7 @@ function buildToolSelectionTable(agents, tools = [], _skills = []) {
46120
46073
  rows.push(`- \`${agent.name}\` agent \u2014 **${agent.metadata.cost}** \u2014 ${shortDesc}`);
46121
46074
  }
46122
46075
  rows.push("");
46123
- rows.push("**Default flow**: explore/librarian (background) + tools \u2192 oracle (if required)");
46076
+ rows.push(buildDefaultResearchFlow(agents));
46124
46077
  return rows.join(`
46125
46078
  `);
46126
46079
  }
@@ -46309,9 +46262,9 @@ function buildAntiPatternsSection() {
46309
46262
  ${patterns.join(`
46310
46263
  `)}`;
46311
46264
  }
46312
- function buildNonClaudePlannerSection(model) {
46265
+ function buildNonClaudePlannerSection(model, agents = []) {
46313
46266
  const isNonClaude = !model.toLowerCase().includes("claude");
46314
- if (!isNonClaude)
46267
+ if (!isNonClaude || !hasAgent(agents, "plan"))
46315
46268
  return "";
46316
46269
  return `### Plan Agent Dependency (Non-Claude)
46317
46270
 
@@ -46344,9 +46297,309 @@ Each delegation prompt must include GOAL + success criteria, file paths + constr
46344
46297
  **Your value is orchestration, decomposition, and quality control.**`;
46345
46298
  }
46346
46299
 
46300
+ // src/agents/sisyphus/default.ts
46301
+ function buildTaskManagementSection(useTaskSystem) {
46302
+ if (useTaskSystem) {
46303
+ return `<Task_Management>
46304
+ ## Task Management (CRITICAL)
46305
+
46306
+ **DEFAULT BEHAVIOR**: Create tasks BEFORE starting any non-trivial task. This is your PRIMARY coordination mechanism.
46307
+
46308
+ ### When to Create Tasks (MANDATORY)
46309
+
46310
+ - Multi-step task (2+ steps) \u2192 ALWAYS \`task_create\` first
46311
+ - Uncertain scope \u2192 ALWAYS (tasks clarify thinking)
46312
+ - User request with multiple items \u2192 ALWAYS
46313
+ - Complex single task \u2192 \`task_create\` to break down
46314
+
46315
+ ### Workflow (NON-NEGOTIABLE)
46316
+
46317
+ 1. **IMMEDIATELY on receiving request**: \`task_create\` to plan atomic steps.
46318
+ - ONLY ADD TASKS TO IMPLEMENT SOMETHING, ONLY WHEN USER WANTS YOU TO IMPLEMENT SOMETHING.
46319
+ 2. **Before starting each step**: \`task_update(task_id="...", status="in_progress")\` (only ONE at a time)
46320
+ 3. **After completing each step**: \`task_update(task_id="...", status="completed")\` IMMEDIATELY (NEVER batch)
46321
+ 4. **If scope changes**: Update tasks before proceeding
46322
+
46323
+ ### Why This Is Non-Negotiable
46324
+
46325
+ - **User visibility**: User sees real-time progress, not a black box
46326
+ - **Prevents drift**: Tasks anchor you to the actual request
46327
+ - **Recovery**: If interrupted, tasks enable seamless continuation
46328
+ - **Accountability**: Each task = explicit commitment
46329
+
46330
+ ### Anti-Patterns (BLOCKING)
46331
+
46332
+ - Skipping tasks on multi-step tasks \u2014 user has no visibility, steps get forgotten
46333
+ - Batch-completing multiple tasks \u2014 defeats real-time tracking purpose
46334
+ - Proceeding without marking in_progress \u2014 no indication of what you're working on
46335
+ - Finishing without completing tasks \u2014 task appears incomplete to user
46336
+
46337
+ **FAILURE TO USE TASKS ON NON-TRIVIAL TASKS = INCOMPLETE WORK.**
46338
+
46339
+ ### Clarification Protocol (when asking):
46340
+
46341
+ \`\`\`
46342
+ I want to make sure I understand correctly.
46343
+
46344
+ **What I understood**: [Your interpretation]
46345
+ **What I'm unsure about**: [Specific ambiguity]
46346
+ **Options I see**:
46347
+ 1. [Option A] - [effort/implications]
46348
+ 2. [Option B] - [effort/implications]
46349
+
46350
+ **My recommendation**: [suggestion with reasoning]
46351
+
46352
+ Should I proceed with [recommendation], or would you prefer differently?
46353
+ \`\`\`
46354
+ </Task_Management>`;
46355
+ }
46356
+ return `<Task_Management>
46357
+ ## Todo Management (CRITICAL)
46358
+
46359
+ **DEFAULT BEHAVIOR**: Create todos BEFORE starting any non-trivial task. This is your PRIMARY coordination mechanism.
46360
+
46361
+ ### When to Create Todos (MANDATORY)
46362
+
46363
+ - Multi-step task (2+ steps) \u2192 ALWAYS create todos first
46364
+ - Uncertain scope \u2192 ALWAYS (todos clarify thinking)
46365
+ - User request with multiple items \u2192 ALWAYS
46366
+ - Complex single task \u2192 Create todos to break down
46367
+
46368
+ ### Workflow (NON-NEGOTIABLE)
46369
+
46370
+ 1. **IMMEDIATELY on receiving request**: \`todowrite\` to plan atomic steps.
46371
+ - ONLY ADD TODOS TO IMPLEMENT SOMETHING, ONLY WHEN USER WANTS YOU TO IMPLEMENT SOMETHING.
46372
+ 2. **Before starting each step**: Mark \`in_progress\` (only ONE at a time)
46373
+ 3. **After completing each step**: Mark \`completed\` IMMEDIATELY (NEVER batch)
46374
+ 4. **If scope changes**: Update todos before proceeding
46375
+
46376
+ ### Why This Is Non-Negotiable
46377
+
46378
+ - **User visibility**: User sees real-time progress, not a black box
46379
+ - **Prevents drift**: Todos anchor you to the actual request
46380
+ - **Recovery**: If interrupted, todos enable seamless continuation
46381
+ - **Accountability**: Each todo = explicit commitment
46382
+
46383
+ ### Anti-Patterns (BLOCKING)
46384
+
46385
+ - Skipping todos on multi-step tasks \u2014 user has no visibility, steps get forgotten
46386
+ - Batch-completing multiple todos \u2014 defeats real-time tracking purpose
46387
+ - Proceeding without marking in_progress \u2014 no indication of what you're working on
46388
+ - Finishing without completing todos \u2014 task appears incomplete to user
46389
+
46390
+ **FAILURE TO USE TODOS ON NON-TRIVIAL TASKS = INCOMPLETE WORK.**
46391
+
46392
+ ### Clarification Protocol (when asking):
46393
+
46394
+ \`\`\`
46395
+ I want to make sure I understand correctly.
46396
+
46397
+ **What I understood**: [Your interpretation]
46398
+ **What I'm unsure about**: [Specific ambiguity]
46399
+ **Options I see**:
46400
+ 1. [Option A] - [effort/implications]
46401
+ 2. [Option B] - [effort/implications]
46402
+
46403
+ **My recommendation**: [suggestion with reasoning]
46404
+
46405
+ Should I proceed with [recommendation], or would you prefer differently?
46406
+ \`\`\`
46407
+ </Task_Management>`;
46408
+ }
46409
+
46410
+ // src/agents/sisyphus/gemini.ts
46411
+ function buildGeminiToolMandate() {
46412
+ return `<TOOL_CALL_MANDATE>
46413
+ ## YOU MUST USE TOOLS. THIS IS NOT OPTIONAL.
46414
+
46415
+ **The user expects you to ACT using tools, not REASON internally.** Every response to a task MUST contain tool_use blocks. A response without tool calls is a FAILED response.
46416
+
46417
+ **YOUR FAILURE MODE**: You believe you can reason through problems without calling tools. You CANNOT. Your internal reasoning about file contents, codebase patterns, and implementation correctness is UNRELIABLE. The ONLY reliable information comes from actual tool calls.
46418
+
46419
+ **RULES (VIOLATION = BROKEN RESPONSE):**
46420
+
46421
+ 1. **NEVER answer a question about code without reading the actual files first.** Your memory of files you "recently read" decays rapidly. Read them AGAIN.
46422
+ 2. **NEVER claim a task is done without running \`lsp_diagnostics\`.** Your confidence that "this should work" is WRONG more often than right.
46423
+ 3. **NEVER skip delegation because you think you can do it faster yourself.** You CANNOT. Specialists with domain-specific skills produce better results. USE THEM.
46424
+ 4. **NEVER reason about what a file "probably contains."** READ IT. Tool calls are cheap. Wrong answers are expensive.
46425
+ 5. **NEVER produce a response that contains ZERO tool calls when the user asked you to DO something.** Thinking is not doing.
46426
+
46427
+ **THINK ABOUT WHICH TOOLS TO USE:**
46428
+ Before responding, enumerate in your head:
46429
+ - What tools do I need to call to fulfill this request?
46430
+ - What information am I assuming that I should verify with a tool call?
46431
+ - Am I about to skip a tool call because I "already know" the answer?
46432
+
46433
+ Then ACTUALLY CALL those tools using the JSON tool schema. Produce the tool_use blocks. Execute.
46434
+ </TOOL_CALL_MANDATE>`;
46435
+ }
46436
+ function buildGeminiToolGuide() {
46437
+ return `<GEMINI_TOOL_GUIDE>
46438
+ ## Tool Usage Guide \u2014 WHEN and HOW to Call Each Tool
46439
+
46440
+ You have access to tools via function calling. This guide defines WHEN to call each one.
46441
+ **Violating these patterns = failed response.**
46442
+
46443
+ ### Reading & Search (parallelize)
46444
+ - \`Read\`: before ANY claim about file contents; before editing any file
46445
+ - \`Grep\`: find patterns, imports, usages; verify "X is used in Y"
46446
+ - \`Glob\`: verify file existence by name/extension pattern
46447
+ - \`AstGrepSearch\`: structural code pattern search
46448
+
46449
+ ### Code Intelligence (parallelize on different files)
46450
+ - \`LspDiagnostics\`: AFTER EVERY edit; BEFORE claiming done; MANDATORY
46451
+ - \`LspGotoDefinition\`: find where a symbol is defined
46452
+ - \`LspFindReferences\`: find all usages across workspace
46453
+ - \`LspSymbols\`: file outline or workspace symbol search
46454
+
46455
+ ### Editing (sequential)
46456
+ - \`Edit\`: modify existing files; MUST Read first for LINE#ID anchors
46457
+ - \`Write\`: create new files or fully overwrite files
46458
+
46459
+ ### Execution & Delegation
46460
+ - \`Bash\`: tests, builds, git commands; usually sequential
46461
+ - \`Task\`: ANY non-trivial implementation; research via explore/librarian; fire in background
46462
+
46463
+ ### Correct Sequences (MANDATORY \u2014 follow these exactly):
46464
+
46465
+ 1. **Answer about code**: Read \u2192 (analyze) \u2192 Answer
46466
+ 2. **Edit code**: Read \u2192 Edit \u2192 LspDiagnostics \u2192 Report
46467
+ 3. **Find something**: Grep/Glob (parallel) \u2192 Read results \u2192 Report
46468
+ 4. **Implement feature**: Task(delegate) \u2192 Verify results \u2192 Report
46469
+ 5. **Debug**: Read error \u2192 Read file \u2192 Grep related \u2192 Fix \u2192 LspDiagnostics
46470
+
46471
+ ### PARALLEL RULES:
46472
+
46473
+ - **Independent reads/searches**: ALWAYS call simultaneously in ONE response
46474
+ - **Dependent operations**: Call sequentially (Edit AFTER Read, LspDiagnostics AFTER Edit)
46475
+ - **Background agents**: ALWAYS \`run_in_background=true\`, continue working
46476
+ </GEMINI_TOOL_GUIDE>`;
46477
+ }
46478
+ function buildGeminiToolCallExamples() {
46479
+ return `<GEMINI_TOOL_CALL_EXAMPLES>
46480
+ ## Correct Tool Calling Patterns \u2014 Follow These Examples
46481
+
46482
+ ### Example 1: User asks about code \u2192 Read FIRST, then answer
46483
+ **User**: "How does the auth middleware work?"
46484
+ **CORRECT**:
46485
+ \`\`\`
46486
+ \u2192 Call Read(filePath="/src/middleware/auth.ts")
46487
+ \u2192 Call Read(filePath="/src/config/auth.ts") // parallel with above
46488
+ \u2192 (After reading) Answer based on ACTUAL file contents
46489
+ \`\`\`
46490
+ **WRONG**:
46491
+ \`\`\`
46492
+ \u2192 "The auth middleware likely validates JWT tokens by..." \u2190 HALLUCINATION. You didn't read the file.
46493
+ \`\`\`
46494
+
46495
+ ### Example 2: User asks to edit code \u2192 Read, Edit, Verify
46496
+ **User**: "Fix the type error in user.ts"
46497
+ **CORRECT**:
46498
+ \`\`\`
46499
+ \u2192 Call Read(filePath="/src/models/user.ts")
46500
+ \u2192 Call LspDiagnostics(filePath="/src/models/user.ts") // parallel with Read
46501
+ \u2192 (After reading) Call Edit with LINE#ID anchors
46502
+ \u2192 Call LspDiagnostics(filePath="/src/models/user.ts") // verify fix
46503
+ \u2192 Report: "Fixed. Diagnostics clean."
46504
+ \`\`\`
46505
+ **WRONG**:
46506
+ \`\`\`
46507
+ \u2192 Call Edit without reading first \u2190 No LINE#ID anchors = WILL FAIL
46508
+ \u2192 Skip LspDiagnostics after edit \u2190 UNVERIFIED
46509
+ \`\`\`
46510
+
46511
+ ### Example 3: Investigation \u2260 Implementation
46512
+ **User**: "Look into why the tests are failing"
46513
+ **CORRECT**:
46514
+ \`\`\`
46515
+ \u2192 Call Bash(command="npm test") // see actual failures
46516
+ \u2192 Call Read on failing test files
46517
+ \u2192 Call Read on source files under test
46518
+ \u2192 Report: "Tests fail because X. Root cause: Y. Proposed fix: Z."
46519
+ \u2192 STOP \u2014 wait for user to say "fix it"
46520
+ \`\`\`
46521
+ **WRONG**:
46522
+ \`\`\`
46523
+ \u2192 Start editing source files immediately \u2190 "look into" \u2260 "fix"
46524
+ \`\`\`
46525
+ </GEMINI_TOOL_CALL_EXAMPLES>`;
46526
+ }
46527
+ function buildGeminiDelegationOverride() {
46528
+ return `<GEMINI_DELEGATION_OVERRIDE>
46529
+ ## DELEGATION IS MANDATORY \u2014 YOU ARE NOT AN IMPLEMENTER
46530
+
46531
+ **You have a strong tendency to do work yourself. RESIST THIS.**
46532
+
46533
+ You are an ORCHESTRATOR. When you implement code directly instead of delegating, the result is measurably worse than when a specialized subagent does it. This is not opinion \u2014 subagents have domain-specific configurations, loaded skills, and tuned prompts that you lack.
46534
+
46535
+ **EVERY TIME you are about to write code or make changes directly:**
46536
+ \u2192 STOP. Ask: "Is there a category + skills combination for this?"
46537
+ \u2192 If YES (almost always): delegate via \`task()\`
46538
+ \u2192 If NO (extremely rare): proceed, but this should happen less than 5% of the time
46539
+
46540
+ **The user chose an orchestrator model specifically because they want delegation and parallel execution. If you do work yourself, you are failing your purpose.**
46541
+ </GEMINI_DELEGATION_OVERRIDE>`;
46542
+ }
46543
+ function buildGeminiVerificationOverride() {
46544
+ return `<GEMINI_VERIFICATION_OVERRIDE>
46545
+ ## YOUR SELF-ASSESSMENT IS UNRELIABLE \u2014 VERIFY WITH TOOLS
46546
+
46547
+ **When you believe something is "done" or "correct" \u2014 you are probably wrong.**
46548
+
46549
+ Your internal confidence estimator is miscalibrated toward optimism. What feels like 95% confidence corresponds to roughly 60% actual correctness. This is a known characteristic, not an insult.
46550
+
46551
+ **MANDATORY**: Replace internal confidence with external verification:
46552
+
46553
+ | Your Feeling | Reality | Required Action |
46554
+ | "This should work" | ~60% chance it works | Run \`lsp_diagnostics\` NOW |
46555
+ | "I'm sure this file exists" | ~70% chance | Use \`glob\` to verify NOW |
46556
+ | "The subagent did it right" | ~50% chance | Read EVERY changed file NOW |
46557
+ | "No need to check this" | You DEFINITELY need to | Check it NOW |
46558
+
46559
+ **BEFORE claiming ANY task is complete:**
46560
+ 1. Run \`lsp_diagnostics\` on ALL changed files \u2014 ACTUALLY clean, not "probably clean"
46561
+ 2. If tests exist, run them \u2014 ACTUALLY pass, not "they should pass"
46562
+ 3. Read the output of every command \u2014 ACTUALLY read, not skim
46563
+ 4. If you delegated, read EVERY file the subagent touched \u2014 not trust their claims
46564
+ </GEMINI_VERIFICATION_OVERRIDE>`;
46565
+ }
46566
+ function buildGeminiIntentGateEnforcement() {
46567
+ return `<GEMINI_INTENT_GATE_ENFORCEMENT>
46568
+ ## YOU MUST CLASSIFY INTENT BEFORE ACTING. NO EXCEPTIONS.
46569
+
46570
+ **Your failure mode: You skip intent classification and jump straight to implementation.**
46571
+
46572
+ You see a user message and your instinct is to immediately start working. WRONG. You MUST first determine WHAT KIND of work the user wants. Getting this wrong wastes everything that follows.
46573
+
46574
+ **MANDATORY FIRST OUTPUT \u2014 before ANY tool call or action:**
46575
+
46576
+ \`\`\`
46577
+ I detect [TYPE] intent \u2014 [REASON].
46578
+ My approach: [ROUTING DECISION].
46579
+ \`\`\`
46580
+
46581
+ Where TYPE is one of: research | implementation | investigation | evaluation | fix | open-ended
46582
+
46583
+ **SELF-CHECK (answer honestly before proceeding):**
46584
+
46585
+ 1. Did the user EXPLICITLY ask me to implement/build/create something? \u2192 If NO, do NOT implement.
46586
+ 2. Did the user say "look into", "check", "investigate", "explain"? \u2192 That means RESEARCH, not implementation.
46587
+ 3. Did the user ask "what do you think?" \u2192 That means EVALUATION \u2014 propose and WAIT, do not execute.
46588
+ 4. Did the user report an error? \u2192 That means MINIMAL FIX, not refactoring.
46589
+
46590
+ **COMMON MISTAKES YOU MAKE (AND MUST NOT):**
46591
+ - "explain how X works" \u2192 Research X, explain it, STOP
46592
+ - "look into this bug" \u2192 Investigate, report findings, WAIT for go-ahead
46593
+ - "what do you think about approach X?" \u2192 Evaluate X, propose alternatives, WAIT
46594
+ - "improve the tests" \u2192 Assess current tests FIRST, propose approach, THEN implement
46595
+
46596
+ **IF YOU SKIPPED THE INTENT CLASSIFICATION ABOVE:** STOP. Go back. Do it now. Your next tool call is INVALID without it.
46597
+ </GEMINI_INTENT_GATE_ENFORCEMENT>`;
46598
+ }
46599
+
46347
46600
  // src/agents/sisyphus/gpt-5-4.ts
46348
46601
  function buildTasksSection(useTaskSystem) {
46349
- const tool = useTaskSystem ? "TaskCreate / TaskUpdate" : "todowrite";
46602
+ const tool = useTaskSystem ? "task_create / task_update" : "todowrite";
46350
46603
  return `## Tasks
46351
46604
  Create ${useTaskSystem ? "tasks" : "todos"} before starting any non-trivial work (multi-step, uncertain scope, complex breakdown).
46352
46605
  Use \`${tool}\` with atomic steps. Mark each step in_progress \u2192 completed immediately. Never batch.`;
@@ -46356,12 +46609,15 @@ function buildGpt54SisyphusPrompt(model, availableAgents, availableTools = [], a
46356
46609
  const toolSelection = buildToolSelectionTable(availableAgents, availableTools, availableSkills);
46357
46610
  const exploreSection = buildExploreSection(availableAgents);
46358
46611
  const librarianSection = buildLibrarianSection(availableAgents);
46612
+ const explorationParallelGuidance = buildExplorationParallelGuidance(availableAgents);
46613
+ const researchDelegationThresholds = buildResearchDelegationThresholds(availableAgents);
46614
+ const searchGuidance = buildSearchGuidance(availableTools);
46359
46615
  const categorySkillsGuide = buildCategorySkillsDelegationGuide(availableCategories, availableSkills);
46360
46616
  const delegationTable = buildDelegationTable(availableAgents);
46361
46617
  const oracleSection = buildOracleSection(availableAgents);
46362
46618
  const hardBlocks = buildHardBlocksSection();
46363
46619
  const antiPatterns = buildAntiPatternsSection();
46364
- const nonClaudePlannerSection = buildNonClaudePlannerSection(model);
46620
+ const nonClaudePlannerSection = buildNonClaudePlannerSection(model, availableAgents);
46365
46621
  const tasksSection = buildTasksSection(useTaskSystem);
46366
46622
  const identity = `You are Sisyphus, an AI coding orchestrator running in OhMyOpenCode. You are expected to be precise, safe, and helpful.
46367
46623
 
@@ -46404,7 +46660,7 @@ ${exploreSection}
46404
46660
 
46405
46661
  ${librarianSection}
46406
46662
 
46407
- Parallelize EVERYTHING independent. Fire 2-5 explore/librarian agents (always \`run_in_background=true\`) for any non-trivial codebase question.
46663
+ ${explorationParallelGuidance}
46408
46664
 
46409
46665
  Each agent prompt needs: [CONTEXT] [GOAL] [DOWNSTREAM] [REQUEST].
46410
46666
 
@@ -46418,7 +46674,7 @@ Coding guidelines:
46418
46674
  - Avoid unneeded complexity
46419
46675
  - Keep changes minimal and consistent with existing style
46420
46676
  - Do not fix unrelated bugs or broken tests (mention them in final message)
46421
- - Use \`rg\` for searching (faster than grep)
46677
+ - ${searchGuidance}
46422
46678
  - Use \`git log\` / \`git blame\` for history context
46423
46679
  - Do NOT git commit unless explicitly asked
46424
46680
  - Do NOT add copyright/license headers unless asked
@@ -46433,8 +46689,7 @@ Coding guidelines:
46433
46689
  - no user-facing UI/UX, styling, layout, animation, or polish requirement
46434
46690
  - no meaningful parallelization opportunity
46435
46691
  - Delegate when ANY are true:
46436
- - need to discover files, symbols, or patterns first \u2192 \`explore\`
46437
- - unfamiliar or version-sensitive library/API behavior \u2192 \`librarian\`
46692
+ ${researchDelegationThresholds}
46438
46693
  - architecture tradeoff, security/performance risk, or 2+ failed attempts \u2192 \`oracle\`
46439
46694
  - user-facing UI/UX, layout, styling, animation, or polish \u2192 \`visual-engineering\`
46440
46695
  - likely 2+ files, or one file plus tightly coupled tests/config/docs \u2192 delegate via category
@@ -46500,116 +46755,6 @@ ${tasksSection}
46500
46755
  ${style}`;
46501
46756
  }
46502
46757
 
46503
- // src/agents/sisyphus/default.ts
46504
- function buildTaskManagementSection(useTaskSystem) {
46505
- if (useTaskSystem) {
46506
- return `<Task_Management>
46507
- ## Task Management (CRITICAL)
46508
-
46509
- **DEFAULT BEHAVIOR**: Create tasks BEFORE starting any non-trivial task. This is your PRIMARY coordination mechanism.
46510
-
46511
- ### When to Create Tasks (MANDATORY)
46512
-
46513
- - Multi-step task (2+ steps) \u2192 ALWAYS \`TaskCreate\` first
46514
- - Uncertain scope \u2192 ALWAYS (tasks clarify thinking)
46515
- - User request with multiple items \u2192 ALWAYS
46516
- - Complex single task \u2192 \`TaskCreate\` to break down
46517
-
46518
- ### Workflow (NON-NEGOTIABLE)
46519
-
46520
- 1. **IMMEDIATELY on receiving request**: \`TaskCreate\` to plan atomic steps.
46521
- - ONLY ADD TASKS TO IMPLEMENT SOMETHING, ONLY WHEN USER WANTS YOU TO IMPLEMENT SOMETHING.
46522
- 2. **Before starting each step**: \`TaskUpdate(status="in_progress")\` (only ONE at a time)
46523
- 3. **After completing each step**: \`TaskUpdate(status="completed")\` IMMEDIATELY (NEVER batch)
46524
- 4. **If scope changes**: Update tasks before proceeding
46525
-
46526
- ### Why This Is Non-Negotiable
46527
-
46528
- - **User visibility**: User sees real-time progress, not a black box
46529
- - **Prevents drift**: Tasks anchor you to the actual request
46530
- - **Recovery**: If interrupted, tasks enable seamless continuation
46531
- - **Accountability**: Each task = explicit commitment
46532
-
46533
- ### Anti-Patterns (BLOCKING)
46534
-
46535
- - Skipping tasks on multi-step tasks \u2014 user has no visibility, steps get forgotten
46536
- - Batch-completing multiple tasks \u2014 defeats real-time tracking purpose
46537
- - Proceeding without marking in_progress \u2014 no indication of what you're working on
46538
- - Finishing without completing tasks \u2014 task appears incomplete to user
46539
-
46540
- **FAILURE TO USE TASKS ON NON-TRIVIAL TASKS = INCOMPLETE WORK.**
46541
-
46542
- ### Clarification Protocol (when asking):
46543
-
46544
- \`\`\`
46545
- I want to make sure I understand correctly.
46546
-
46547
- **What I understood**: [Your interpretation]
46548
- **What I'm unsure about**: [Specific ambiguity]
46549
- **Options I see**:
46550
- 1. [Option A] - [effort/implications]
46551
- 2. [Option B] - [effort/implications]
46552
-
46553
- **My recommendation**: [suggestion with reasoning]
46554
-
46555
- Should I proceed with [recommendation], or would you prefer differently?
46556
- \`\`\`
46557
- </Task_Management>`;
46558
- }
46559
- return `<Task_Management>
46560
- ## Todo Management (CRITICAL)
46561
-
46562
- **DEFAULT BEHAVIOR**: Create todos BEFORE starting any non-trivial task. This is your PRIMARY coordination mechanism.
46563
-
46564
- ### When to Create Todos (MANDATORY)
46565
-
46566
- - Multi-step task (2+ steps) \u2192 ALWAYS create todos first
46567
- - Uncertain scope \u2192 ALWAYS (todos clarify thinking)
46568
- - User request with multiple items \u2192 ALWAYS
46569
- - Complex single task \u2192 Create todos to break down
46570
-
46571
- ### Workflow (NON-NEGOTIABLE)
46572
-
46573
- 1. **IMMEDIATELY on receiving request**: \`todowrite\` to plan atomic steps.
46574
- - ONLY ADD TODOS TO IMPLEMENT SOMETHING, ONLY WHEN USER WANTS YOU TO IMPLEMENT SOMETHING.
46575
- 2. **Before starting each step**: Mark \`in_progress\` (only ONE at a time)
46576
- 3. **After completing each step**: Mark \`completed\` IMMEDIATELY (NEVER batch)
46577
- 4. **If scope changes**: Update todos before proceeding
46578
-
46579
- ### Why This Is Non-Negotiable
46580
-
46581
- - **User visibility**: User sees real-time progress, not a black box
46582
- - **Prevents drift**: Todos anchor you to the actual request
46583
- - **Recovery**: If interrupted, todos enable seamless continuation
46584
- - **Accountability**: Each todo = explicit commitment
46585
-
46586
- ### Anti-Patterns (BLOCKING)
46587
-
46588
- - Skipping todos on multi-step tasks \u2014 user has no visibility, steps get forgotten
46589
- - Batch-completing multiple todos \u2014 defeats real-time tracking purpose
46590
- - Proceeding without marking in_progress \u2014 no indication of what you're working on
46591
- - Finishing without completing todos \u2014 task appears incomplete to user
46592
-
46593
- **FAILURE TO USE TODOS ON NON-TRIVIAL TASKS = INCOMPLETE WORK.**
46594
-
46595
- ### Clarification Protocol (when asking):
46596
-
46597
- \`\`\`
46598
- I want to make sure I understand correctly.
46599
-
46600
- **What I understood**: [Your interpretation]
46601
- **What I'm unsure about**: [Specific ambiguity]
46602
- **Options I see**:
46603
- 1. [Option A] - [effort/implications]
46604
- 2. [Option B] - [effort/implications]
46605
-
46606
- **My recommendation**: [suggestion with reasoning]
46607
-
46608
- Should I proceed with [recommendation], or would you prefer differently?
46609
- \`\`\`
46610
- </Task_Management>`;
46611
- }
46612
-
46613
46758
  // src/agents/sisyphus.ts
46614
46759
  var MODE = "all";
46615
46760
  function buildDynamicSisyphusPrompt(model, availableAgents, availableTools = [], availableSkills = [], availableCategories = [], useTaskSystem = false) {
@@ -46623,7 +46768,12 @@ function buildDynamicSisyphusPrompt(model, availableAgents, availableTools = [],
46623
46768
  const hardBlocks = buildHardBlocksSection();
46624
46769
  const antiPatterns = buildAntiPatternsSection();
46625
46770
  const parallelDelegationSection = buildParallelDelegationSection(model, availableCategories);
46626
- const nonClaudePlannerSection = buildNonClaudePlannerSection(model);
46771
+ const nonClaudePlannerSection = buildNonClaudePlannerSection(model, availableAgents);
46772
+ const researchAnswerRouting = buildResearchAnswerRouting(availableAgents);
46773
+ const investigationRouting = buildInvestigationRouting(availableAgents);
46774
+ const researchDelegationThresholds = buildResearchDelegationThresholds(availableAgents);
46775
+ const researchToolUsageRules = buildResearchToolUsageRules(availableAgents);
46776
+ const backgroundResearchExamples = buildBackgroundResearchExamples(availableAgents);
46627
46777
  const taskManagementSection = buildTaskManagementSection(useTaskSystem);
46628
46778
  const todoHookNote = useTaskSystem ? "YOUR TASK CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TASK CONTINUATION])" : "YOUR TODO CREATION WOULD BE TRACKED BY HOOK([SYSTEM REMINDER - TODO CONTINUATION])";
46629
46779
  return `<Role>
@@ -46659,9 +46809,9 @@ Before classifying the task, identify what the user actually wants from you as a
46659
46809
 
46660
46810
  | Surface Form | True Intent | Your Routing |
46661
46811
  |---|---|---|
46662
- | "explain X", "how does Y work" | Research/understanding | explore/librarian \u2192 synthesize \u2192 answer |
46812
+ | "explain X", "how does Y work" | Research/understanding | ${researchAnswerRouting} |
46663
46813
  | "implement X", "add Y", "create Z" | Implementation (explicit) | plan \u2192 delegate or execute |
46664
- | "look into X", "check Y", "investigate" | Investigation | explore \u2192 report findings |
46814
+ | "look into X", "check Y", "investigate" | Investigation | ${investigationRouting} |
46665
46815
  | "what do you think about X?" | Evaluation | evaluate \u2192 propose \u2192 **wait for confirmation** |
46666
46816
  | "I'm seeing error X" / "Y is broken" | Fix needed | diagnose \u2192 fix minimally |
46667
46817
  | "refactor", "improve", "clean up" | Open-ended change | assess codebase first \u2192 propose approach |
@@ -46707,8 +46857,7 @@ Work yourself only when ALL are true:
46707
46857
  - no meaningful parallelization opportunity
46708
46858
 
46709
46859
  Delegate when ANY are true:
46710
- - need to discover files, symbols, or patterns first \u2192 \`explore\`
46711
- - unfamiliar or version-sensitive library/API behavior \u2192 \`librarian\`
46860
+ ${researchDelegationThresholds}
46712
46861
  - architecture tradeoff, security/performance risk, or 2+ failed attempts \u2192 \`oracle\`
46713
46862
  - user-facing UI/UX, layout, styling, animation, or polish \u2192 \`visual-engineering\`
46714
46863
  - likely 2+ files, or one file plus tightly coupled tests/config/docs \u2192 delegate via category
@@ -46774,29 +46923,13 @@ ${librarianSection}
46774
46923
 
46775
46924
  <tool_usage_rules>
46776
46925
  - Parallelize independent tool calls: multiple file reads, grep searches, agent fires \u2014 all at once
46777
- - Explore/Librarian = background grep. ALWAYS \`run_in_background=true\`, ALWAYS parallel
46778
- - Fire 2-5 explore/librarian agents in parallel for any non-trivial codebase question
46926
+ ${researchToolUsageRules}
46779
46927
  - Parallelize independent file reads \u2014 don't read files one at a time
46780
46928
  - After any write/edit tool call, briefly restate what changed, where, and what validation follows
46781
46929
  - Prefer tools over internal knowledge whenever you need specific data (files, configs, patterns)
46782
46930
  </tool_usage_rules>
46783
46931
 
46784
- **Explore/Librarian = Grep, not consultants.
46785
-
46786
- \`\`\`typescript
46787
- // CORRECT: Always background, always parallel.
46788
- // Prompt structure:
46789
- // [CONTEXT]: task context, modules/files involved, approach
46790
- // [GOAL]: the outcome needed - what decision/action this unblocks
46791
- // [DOWNSTREAM]: how results will be used after the search
46792
- // [REQUEST]: exactly what to find, what to skip, and what format to return
46793
-
46794
- task(subagent_type="explore", run_in_background=true, load_skills=[], description="Find auth patterns", prompt="[CONTEXT] Adding JWT auth in src/api/routes/. [GOAL] Match existing middleware and token-flow conventions. [DOWNSTREAM] Use findings to choose middleware structure and validation flow. [REQUEST] Find auth middleware, login/signup handlers, token generation, and credential validation. Focus on src/, skip tests, return file paths with pattern summaries.")
46795
- task(subagent_type="librarian", run_in_background=true, load_skills=[], description="Find JWT security guidance", prompt="[CONTEXT] Implementing JWT auth and choosing token storage plus expiration policy. [GOAL] Get current production security guidance. [DOWNSTREAM] Use findings to choose storage, lifetime, and refresh strategy. [REQUEST] Find OWASP guidance, token lifetime recommendations, refresh rotation strategies, and common JWT vulnerabilities. Skip tutorials, return concise production-focused recommendations.")
46796
-
46797
- // WRONG: Never block on explore/librarian.
46798
- result = task(..., run_in_background=false)
46799
- \`\`\`
46932
+ ${backgroundResearchExamples}
46800
46933
 
46801
46934
  ### Background Result Collection:
46802
46935
  1. Launch parallel agents \u2192 receive task_ids
@@ -52991,17 +53124,17 @@ Task NOT complete without:
52991
53124
  </Style>`;
52992
53125
  if (!promptAppend)
52993
53126
  return prompt;
52994
- return prompt + `
53127
+ return `${prompt}
52995
53128
 
52996
- ` + resolvePromptAppend(promptAppend);
53129
+ ${resolvePromptAppend(promptAppend)}`;
52997
53130
  }
52998
53131
  function buildTodoDisciplineSection(useTaskSystem) {
52999
53132
  if (useTaskSystem) {
53000
53133
  return `<Task_Discipline>
53001
53134
  TASK OBSESSION (NON-NEGOTIABLE):
53002
53135
  - 2+ steps \u2192 task_create FIRST, atomic breakdown
53003
- - task_update(status="in_progress") before starting (ONE at a time)
53004
- - task_update(status="completed") IMMEDIATELY after each step
53136
+ - task_update(task_id="...", status="in_progress") before starting (ONE at a time)
53137
+ - task_update(task_id="...", status="completed") IMMEDIATELY after each step
53005
53138
  - NEVER batch completions
53006
53139
 
53007
53140
  No tasks on multi-step work = INCOMPLETE WORK.
@@ -53129,17 +53262,17 @@ Style:
53129
53262
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53130
53263
  if (!promptAppend)
53131
53264
  return prompt;
53132
- return prompt + `
53265
+ return `${prompt}
53133
53266
 
53134
- ` + resolvePromptAppend(promptAppend);
53267
+ ${resolvePromptAppend(promptAppend)}`;
53135
53268
  }
53136
53269
  function buildGptTaskDisciplineSection(useTaskSystem) {
53137
53270
  if (useTaskSystem) {
53138
53271
  return `## Task Discipline (NON-NEGOTIABLE)
53139
53272
 
53140
53273
  - **2+ steps** \u2014 task_create FIRST, atomic breakdown
53141
- - **Starting step** \u2014 task_update(status="in_progress") \u2014 ONE at a time
53142
- - **Completing step** \u2014 task_update(status="completed") IMMEDIATELY
53274
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53275
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY
53143
53276
  - **Batching** \u2014 NEVER batch completions
53144
53277
 
53145
53278
  No tasks on multi-step work = INCOMPLETE WORK.`;
@@ -53268,17 +53401,17 @@ Style:
53268
53401
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53269
53402
  if (!promptAppend)
53270
53403
  return prompt;
53271
- return prompt + `
53404
+ return `${prompt}
53272
53405
 
53273
- ` + resolvePromptAppend(promptAppend);
53406
+ ${resolvePromptAppend(promptAppend)}`;
53274
53407
  }
53275
53408
  function buildGpt54TaskDisciplineSection(useTaskSystem) {
53276
53409
  if (useTaskSystem) {
53277
53410
  return `## Task Discipline (NON-NEGOTIABLE)
53278
53411
 
53279
53412
  - **2+ steps** \u2014 task_create FIRST, atomic breakdown
53280
- - **Starting step** \u2014 task_update(status="in_progress") \u2014 ONE at a time
53281
- - **Completing step** \u2014 task_update(status="completed") IMMEDIATELY
53413
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53414
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY
53282
53415
  - **Batching** \u2014 NEVER batch completions
53283
53416
 
53284
53417
  No tasks on multi-step work = INCOMPLETE WORK.`;
@@ -53404,17 +53537,17 @@ Style:
53404
53537
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53405
53538
  if (!promptAppend)
53406
53539
  return prompt;
53407
- return prompt + `
53540
+ return `${prompt}
53408
53541
 
53409
- ` + resolvePromptAppend(promptAppend);
53542
+ ${resolvePromptAppend(promptAppend)}`;
53410
53543
  }
53411
53544
  function buildGpt53CodexTaskDisciplineSection(useTaskSystem) {
53412
53545
  if (useTaskSystem) {
53413
53546
  return `## Task Discipline (NON-NEGOTIABLE)
53414
53547
 
53415
53548
  - **2+ steps** \u2014 task_create FIRST, atomic breakdown
53416
- - **Starting step** \u2014 task_update(status="in_progress") \u2014 ONE at a time
53417
- - **Completing step** \u2014 task_update(status="completed") IMMEDIATELY
53549
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53550
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY
53418
53551
  - **Batching** \u2014 NEVER batch completions
53419
53552
 
53420
53553
  No tasks on multi-step work = INCOMPLETE WORK.`;
@@ -53574,9 +53707,9 @@ If ANY answer is no \u2192 GO BACK AND DO IT. Do not claim completion.
53574
53707
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53575
53708
  if (!promptAppend)
53576
53709
  return prompt;
53577
- return prompt + `
53710
+ return `${prompt}
53578
53711
 
53579
- ` + resolvePromptAppend(promptAppend);
53712
+ ${resolvePromptAppend(promptAppend)}`;
53580
53713
  }
53581
53714
  function buildGeminiTaskDisciplineSection(useTaskSystem) {
53582
53715
  if (useTaskSystem) {
@@ -53585,8 +53718,8 @@ function buildGeminiTaskDisciplineSection(useTaskSystem) {
53585
53718
  **You WILL forget to track tasks if not forced. This section forces you.**
53586
53719
 
53587
53720
  - **2+ steps** \u2014 task_create FIRST, atomic breakdown. DO THIS BEFORE ANY IMPLEMENTATION.
53588
- - **Starting step** \u2014 task_update(status="in_progress") \u2014 ONE at a time
53589
- - **Completing step** \u2014 task_update(status="completed") IMMEDIATELY after verification passes
53721
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53722
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY after verification passes
53590
53723
  - **Batching** \u2014 NEVER batch completions. Mark EACH task individually.
53591
53724
 
53592
53725
  No tasks on multi-step work = INCOMPLETE WORK. The user tracks your progress through tasks.`;
@@ -53899,20 +54032,20 @@ var import_picomatch2 = __toESM(require_picomatch2(), 1);
53899
54032
  import { promises as fs8 } from "fs";
53900
54033
  import { dirname as dirname10, extname, isAbsolute as isAbsolute7, join as join42, relative as relative4 } from "path";
53901
54034
  var MAX_RECURSIVE_DEPTH = 10;
53902
- function isHttpUrl(path4) {
53903
- return path4.startsWith("http://") || path4.startsWith("https://");
54035
+ function isHttpUrl(path3) {
54036
+ return path3.startsWith("http://") || path3.startsWith("https://");
53904
54037
  }
53905
- function toAbsolutePath(path4, configDir) {
53906
- if (isAbsolute7(path4)) {
53907
- return path4;
54038
+ function toAbsolutePath(path3, configDir) {
54039
+ if (isAbsolute7(path3)) {
54040
+ return path3;
53908
54041
  }
53909
- return join42(configDir, path4);
54042
+ return join42(configDir, path3);
53910
54043
  }
53911
- function isMarkdownPath(path4) {
53912
- return extname(path4).toLowerCase() === ".md";
54044
+ function isMarkdownPath(path3) {
54045
+ return extname(path3).toLowerCase() === ".md";
53913
54046
  }
53914
- function normalizePathForGlob(path4) {
53915
- return path4.split("\\").join("/");
54047
+ function normalizePathForGlob(path3) {
54048
+ return path3.split("\\").join("/");
53916
54049
  }
53917
54050
  function filterByGlob(skills2, sourceBaseDir, globPattern) {
53918
54051
  if (!globPattern)
@@ -58062,11 +58195,11 @@ async function loadMcpConfigFile(filePath) {
58062
58195
  function getSystemMcpServerNames() {
58063
58196
  const names = new Set;
58064
58197
  const paths = getMcpConfigPaths();
58065
- for (const { path: path4 } of paths) {
58066
- if (!existsSync38(path4))
58198
+ for (const { path: path3 } of paths) {
58199
+ if (!existsSync38(path3))
58067
58200
  continue;
58068
58201
  try {
58069
- const content = readFileSync29(path4, "utf-8");
58202
+ const content = readFileSync29(path3, "utf-8");
58070
58203
  const config2 = JSON.parse(content);
58071
58204
  if (!config2?.mcpServers)
58072
58205
  continue;
@@ -58086,22 +58219,22 @@ async function loadMcpConfigs(disabledMcps = []) {
58086
58219
  const loadedServers = [];
58087
58220
  const paths = getMcpConfigPaths();
58088
58221
  const disabledSet = new Set(disabledMcps);
58089
- for (const { path: path4, scope } of paths) {
58090
- const config2 = await loadMcpConfigFile(path4);
58222
+ for (const { path: path3, scope } of paths) {
58223
+ const config2 = await loadMcpConfigFile(path3);
58091
58224
  if (!config2?.mcpServers)
58092
58225
  continue;
58093
58226
  for (const [name, serverConfig] of Object.entries(config2.mcpServers)) {
58094
58227
  if (disabledSet.has(name)) {
58095
- log(`Skipping MCP "${name}" (in disabled_mcps)`, { path: path4 });
58228
+ log(`Skipping MCP "${name}" (in disabled_mcps)`, { path: path3 });
58096
58229
  continue;
58097
58230
  }
58098
58231
  if (serverConfig.disabled) {
58099
- log(`Disabling MCP server "${name}"`, { path: path4 });
58232
+ log(`Disabling MCP server "${name}"`, { path: path3 });
58100
58233
  delete servers[name];
58101
58234
  const existingIndex = loadedServers.findIndex((s) => s.name === name);
58102
58235
  if (existingIndex !== -1) {
58103
58236
  loadedServers.splice(existingIndex, 1);
58104
- log(`Removed previously loaded MCP server "${name}"`, { path: path4 });
58237
+ log(`Removed previously loaded MCP server "${name}"`, { path: path3 });
58105
58238
  }
58106
58239
  continue;
58107
58240
  }
@@ -58113,7 +58246,7 @@ async function loadMcpConfigs(disabledMcps = []) {
58113
58246
  loadedServers.splice(existingIndex, 1);
58114
58247
  }
58115
58248
  loadedServers.push({ name, scope, config: transformed });
58116
- log(`Loaded MCP server "${name}" from ${scope}`, { path: path4 });
58249
+ log(`Loaded MCP server "${name}" from ${scope}`, { path: path3 });
58117
58250
  } catch (error48) {
58118
58251
  log(`Failed to transform MCP server "${name}"`, error48);
58119
58252
  }
@@ -58769,11 +58902,20 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
58769
58902
  // src/tools/lsp/server-config-loader.ts
58770
58903
  import { existsSync as existsSync39, readFileSync as readFileSync30 } from "fs";
58771
58904
  import { join as join46 } from "path";
58772
- function loadJsonFile(path4) {
58773
- if (!existsSync39(path4))
58905
+ function loadJsonFile(path3) {
58906
+ if (!existsSync39(path3))
58907
+ return null;
58908
+ try {
58909
+ return parseOmoConfigJson(readFileSync30(path3, "utf-8"));
58910
+ } catch {
58911
+ return null;
58912
+ }
58913
+ }
58914
+ function loadOpenCodeConfigFile(path3) {
58915
+ if (!existsSync39(path3))
58774
58916
  return null;
58775
58917
  try {
58776
- return parseJsonc(readFileSync30(path4, "utf-8"));
58918
+ return parseJsonc(readFileSync30(path3, "utf-8"));
58777
58919
  } catch {
58778
58920
  return null;
58779
58921
  }
@@ -58782,8 +58924,8 @@ function getConfigPaths2() {
58782
58924
  const cwd = process.cwd();
58783
58925
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
58784
58926
  return {
58785
- project: detectConfigFile(join46(cwd, ".opencode", "oh-my-opencode-gpt-slim")).path,
58786
- user: detectConfigFile(join46(configDir, "oh-my-opencode-gpt-slim")).path,
58927
+ project: getProjectOmoConfigFilePath(cwd),
58928
+ user: getOmoConfigFilePath(configDir),
58787
58929
  opencode: detectConfigFile(join46(configDir, "opencode")).path
58788
58930
  };
58789
58931
  }
@@ -58796,7 +58938,7 @@ function loadAllConfigs() {
58796
58938
  const user = loadJsonFile(paths.user);
58797
58939
  if (user)
58798
58940
  configs.set("user", user);
58799
- const opencode = loadJsonFile(paths.opencode);
58941
+ const opencode = loadOpenCodeConfigFile(paths.opencode);
58800
58942
  if (opencode)
58801
58943
  configs.set("opencode", opencode);
58802
58944
  return configs;
@@ -58845,7 +58987,11 @@ function getMergedServers() {
58845
58987
  }
58846
58988
  return servers.sort((a, b) => {
58847
58989
  if (a.source !== b.source) {
58848
- const order = { project: 0, user: 1, opencode: 2 };
58990
+ const order = {
58991
+ project: 0,
58992
+ user: 1,
58993
+ opencode: 2
58994
+ };
58849
58995
  return order[a.source] - order[b.source];
58850
58996
  }
58851
58997
  return b.priority - a.priority;
@@ -60724,10 +60870,10 @@ function mergeDefs2(...defs) {
60724
60870
  function cloneDef2(schema2) {
60725
60871
  return mergeDefs2(schema2._zod.def);
60726
60872
  }
60727
- function getElementAtPath2(obj, path4) {
60728
- if (!path4)
60873
+ function getElementAtPath2(obj, path3) {
60874
+ if (!path3)
60729
60875
  return obj;
60730
- return path4.reduce((acc, key) => acc?.[key], obj);
60876
+ return path3.reduce((acc, key) => acc?.[key], obj);
60731
60877
  }
60732
60878
  function promiseAllObject2(promisesObj) {
60733
60879
  const keys = Object.keys(promisesObj);
@@ -61086,11 +61232,11 @@ function aborted2(x, startIndex = 0) {
61086
61232
  }
61087
61233
  return false;
61088
61234
  }
61089
- function prefixIssues2(path4, issues) {
61235
+ function prefixIssues2(path3, issues) {
61090
61236
  return issues.map((iss) => {
61091
61237
  var _a2;
61092
61238
  (_a2 = iss).path ?? (_a2.path = []);
61093
- iss.path.unshift(path4);
61239
+ iss.path.unshift(path3);
61094
61240
  return iss;
61095
61241
  });
61096
61242
  }
@@ -61258,7 +61404,7 @@ function treeifyError2(error48, _mapper) {
61258
61404
  return issue3.message;
61259
61405
  };
61260
61406
  const result = { errors: [] };
61261
- const processError = (error49, path4 = []) => {
61407
+ const processError = (error49, path3 = []) => {
61262
61408
  var _a2, _b;
61263
61409
  for (const issue3 of error49.issues) {
61264
61410
  if (issue3.code === "invalid_union" && issue3.errors.length) {
@@ -61268,7 +61414,7 @@ function treeifyError2(error48, _mapper) {
61268
61414
  } else if (issue3.code === "invalid_element") {
61269
61415
  processError({ issues: issue3.issues }, issue3.path);
61270
61416
  } else {
61271
- const fullpath = [...path4, ...issue3.path];
61417
+ const fullpath = [...path3, ...issue3.path];
61272
61418
  if (fullpath.length === 0) {
61273
61419
  result.errors.push(mapper(issue3));
61274
61420
  continue;
@@ -61300,8 +61446,8 @@ function treeifyError2(error48, _mapper) {
61300
61446
  }
61301
61447
  function toDotPath2(_path) {
61302
61448
  const segs = [];
61303
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
61304
- for (const seg of path4) {
61449
+ const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
61450
+ for (const seg of path3) {
61305
61451
  if (typeof seg === "number")
61306
61452
  segs.push(`[${seg}]`);
61307
61453
  else if (typeof seg === "symbol")