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

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.4",
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.4",
12390
+ "oh-my-opencode-gpt-slim-darwin-x64": "0.1.4",
12391
+ "oh-my-opencode-gpt-slim-darwin-x64-baseline": "0.1.4",
12392
+ "oh-my-opencode-gpt-slim-linux-arm64": "0.1.4",
12393
+ "oh-my-opencode-gpt-slim-linux-arm64-musl": "0.1.4",
12394
+ "oh-my-opencode-gpt-slim-linux-x64": "0.1.4",
12395
+ "oh-my-opencode-gpt-slim-linux-x64-baseline": "0.1.4",
12396
+ "oh-my-opencode-gpt-slim-linux-x64-musl": "0.1.4",
12397
+ "oh-my-opencode-gpt-slim-linux-x64-musl-baseline": "0.1.4"
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) {
@@ -17132,6 +17144,32 @@ var CATEGORY_MODEL_REQUIREMENTS = {
17132
17144
  ]
17133
17145
  }
17134
17146
  };
17147
+
17148
+ // src/shared/agent-variant.ts
17149
+ function resolveAgentReasoningEffort(config, agentName) {
17150
+ if (!agentName) {
17151
+ return;
17152
+ }
17153
+ const agentOverrides = config.agents;
17154
+ const agentOverride = agentOverrides ? agentOverrides[agentName] ?? Object.entries(agentOverrides).find(([key]) => key.toLowerCase() === agentName.toLowerCase())?.[1] : undefined;
17155
+ if (!agentOverride) {
17156
+ return;
17157
+ }
17158
+ if (agentOverride.reasoningEffort) {
17159
+ return agentOverride.reasoningEffort;
17160
+ }
17161
+ const categoryName = agentOverride.category;
17162
+ if (!categoryName) {
17163
+ return;
17164
+ }
17165
+ return config.categories?.[categoryName]?.reasoningEffort;
17166
+ }
17167
+ function applyAgentReasoningEffort(config, agentName, message) {
17168
+ const reasoningEffort = resolveAgentReasoningEffort(config, agentName);
17169
+ if (reasoningEffort !== undefined && message.reasoningEffort === undefined) {
17170
+ message.reasoningEffort = reasoningEffort;
17171
+ }
17172
+ }
17135
17173
  // src/shared/session-cursor.ts
17136
17174
  var sessionCursors = new Map;
17137
17175
  function buildMessageKey(message, index) {
@@ -17234,11 +17272,11 @@ init_logger();
17234
17272
  // src/shared/connected-providers-cache.ts
17235
17273
  init_logger();
17236
17274
  import { existsSync as existsSync6, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
17237
- import { join as join7 } from "path";
17275
+ import { join as join8 } from "path";
17238
17276
  var CONNECTED_PROVIDERS_CACHE_FILE = "connected-providers.json";
17239
17277
  var PROVIDER_MODELS_CACHE_FILE = "provider-models.json";
17240
17278
  function getCacheFilePath(filename) {
17241
- return join7(getOmoOpenCodeCacheDir(), filename);
17279
+ return join8(getOmoOpenCodeCacheDir(), filename);
17242
17280
  }
17243
17281
  function readConnectedProvidersCache() {
17244
17282
  const cacheFile = getCacheFilePath(CONNECTED_PROVIDERS_CACHE_FILE);
@@ -17283,7 +17321,7 @@ function readProviderModelsCache() {
17283
17321
  // src/shared/model-availability.ts
17284
17322
  init_logger();
17285
17323
  import { existsSync as existsSync7, readFileSync as readFileSync4 } from "fs";
17286
- import { join as join8 } from "path";
17324
+ import { join as join9 } from "path";
17287
17325
  function normalizeModelName(name) {
17288
17326
  return name.toLowerCase().replace(/claude-(opus|sonnet|haiku)-(\d+)[.-](\d+)/g, "claude-$1-$2.$3");
17289
17327
  }
@@ -17419,7 +17457,7 @@ async function fetchAvailableModels(client, options) {
17419
17457
  }
17420
17458
  }
17421
17459
  log("[fetchAvailableModels] provider-models cache not found, falling back to models.json");
17422
- const cacheFile = join8(getOpenCodeCacheDir(), "models.json");
17460
+ const cacheFile = join9(getOpenCodeCacheDir(), "models.json");
17423
17461
  if (!existsSync7(cacheFile)) {
17424
17462
  log("[fetchAvailableModels] models.json cache file not found, falling back to client");
17425
17463
  } else {
@@ -17710,7 +17748,7 @@ function isAnyFallbackModelAvailable(fallbackChain, availableModels) {
17710
17748
  // src/features/hook-message-injector/injector.ts
17711
17749
  import { existsSync as existsSync8, mkdirSync as mkdirSync3, readFileSync as readFileSync5, readdirSync, writeFileSync as writeFileSync3 } from "fs";
17712
17750
  import { randomBytes } from "crypto";
17713
- import { join as join9 } from "path";
17751
+ import { join as join10 } from "path";
17714
17752
  init_logger();
17715
17753
  var processPrefix = randomBytes(4).toString("hex");
17716
17754
  function convertSDKMessageToStoredMessage(msg) {
@@ -17779,7 +17817,7 @@ function findNearestMessageWithFields(messageDir) {
17779
17817
  const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort().reverse();
17780
17818
  for (const file of files) {
17781
17819
  try {
17782
- const content = readFileSync5(join9(messageDir, file), "utf-8");
17820
+ const content = readFileSync5(join10(messageDir, file), "utf-8");
17783
17821
  const msg = JSON.parse(content);
17784
17822
  if (msg.agent && msg.model?.providerID && msg.model?.modelID) {
17785
17823
  return msg;
@@ -17790,7 +17828,7 @@ function findNearestMessageWithFields(messageDir) {
17790
17828
  }
17791
17829
  for (const file of files) {
17792
17830
  try {
17793
- const content = readFileSync5(join9(messageDir, file), "utf-8");
17831
+ const content = readFileSync5(join10(messageDir, file), "utf-8");
17794
17832
  const msg = JSON.parse(content);
17795
17833
  if (msg.agent || msg.model?.providerID && msg.model?.modelID) {
17796
17834
  return msg;
@@ -17812,7 +17850,7 @@ function findFirstMessageWithAgent(messageDir) {
17812
17850
  const files = readdirSync(messageDir).filter((f) => f.endsWith(".json")).sort();
17813
17851
  for (const file of files) {
17814
17852
  try {
17815
- const content = readFileSync5(join9(messageDir, file), "utf-8");
17853
+ const content = readFileSync5(join10(messageDir, file), "utf-8");
17816
17854
  const msg = JSON.parse(content);
17817
17855
  if (msg.agent) {
17818
17856
  return msg.agent;
@@ -17838,14 +17876,14 @@ async function resolveMessageContext(sessionID, client, messageDir) {
17838
17876
  }
17839
17877
  // src/shared/opencode-message-dir.ts
17840
17878
  import { existsSync as existsSync9, readdirSync as readdirSync2 } from "fs";
17841
- import { join as join11 } from "path";
17879
+ import { join as join12 } from "path";
17842
17880
 
17843
17881
  // src/shared/opencode-storage-paths.ts
17844
- import { join as join10 } from "path";
17882
+ import { join as join11 } from "path";
17845
17883
  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");
17884
+ var MESSAGE_STORAGE = join11(OPENCODE_STORAGE, "message");
17885
+ var PART_STORAGE = join11(OPENCODE_STORAGE, "part");
17886
+ var SESSION_STORAGE = join11(OPENCODE_STORAGE, "session");
17849
17887
 
17850
17888
  // src/shared/opencode-message-dir.ts
17851
17889
  init_logger();
@@ -17858,13 +17896,13 @@ function getMessageDir(sessionID) {
17858
17896
  return null;
17859
17897
  if (!existsSync9(MESSAGE_STORAGE))
17860
17898
  return null;
17861
- const directPath = join11(MESSAGE_STORAGE, sessionID);
17899
+ const directPath = join12(MESSAGE_STORAGE, sessionID);
17862
17900
  if (existsSync9(directPath)) {
17863
17901
  return directPath;
17864
17902
  }
17865
17903
  try {
17866
17904
  for (const dir of readdirSync2(MESSAGE_STORAGE)) {
17867
- const sessionPath = join11(MESSAGE_STORAGE, dir, sessionID);
17905
+ const sessionPath = join12(MESSAGE_STORAGE, dir, sessionID);
17868
17906
  if (existsSync9(sessionPath)) {
17869
17907
  return sessionPath;
17870
17908
  }
@@ -18702,15 +18740,15 @@ init_logger();
18702
18740
  init_logger();
18703
18741
  import { existsSync as existsSync10, readFileSync as readFileSync6 } from "fs";
18704
18742
  import { homedir as homedir4 } from "os";
18705
- import { join as join12 } from "path";
18743
+ import { join as join13 } from "path";
18706
18744
  function getPluginsBaseDir() {
18707
18745
  if (process.env.CLAUDE_PLUGINS_HOME) {
18708
18746
  return process.env.CLAUDE_PLUGINS_HOME;
18709
18747
  }
18710
- return join12(homedir4(), ".claude", "plugins");
18748
+ return join13(homedir4(), ".claude", "plugins");
18711
18749
  }
18712
18750
  function getInstalledPluginsPath() {
18713
- return join12(getPluginsBaseDir(), "installed_plugins.json");
18751
+ return join13(getPluginsBaseDir(), "installed_plugins.json");
18714
18752
  }
18715
18753
  function loadInstalledPlugins() {
18716
18754
  const dbPath = getInstalledPluginsPath();
@@ -18729,7 +18767,7 @@ function getClaudeSettingsPath() {
18729
18767
  if (process.env.CLAUDE_SETTINGS_PATH) {
18730
18768
  return process.env.CLAUDE_SETTINGS_PATH;
18731
18769
  }
18732
- return join12(homedir4(), ".claude", "settings.json");
18770
+ return join13(homedir4(), ".claude", "settings.json");
18733
18771
  }
18734
18772
  function loadClaudeSettings() {
18735
18773
  const settingsPath = getClaudeSettingsPath();
@@ -18745,7 +18783,7 @@ function loadClaudeSettings() {
18745
18783
  }
18746
18784
  }
18747
18785
  function loadPluginManifest(installPath) {
18748
- const manifestPath = join12(installPath, ".claude-plugin", "plugin.json");
18786
+ const manifestPath = join13(installPath, ".claude-plugin", "plugin.json");
18749
18787
  if (!existsSync10(manifestPath)) {
18750
18788
  return null;
18751
18789
  }
@@ -18812,20 +18850,20 @@ function discoverInstalledPlugins(options) {
18812
18850
  pluginKey,
18813
18851
  manifest: manifest ?? undefined
18814
18852
  };
18815
- if (existsSync10(join12(installPath, "commands"))) {
18816
- loadedPlugin.commandsDir = join12(installPath, "commands");
18853
+ if (existsSync10(join13(installPath, "commands"))) {
18854
+ loadedPlugin.commandsDir = join13(installPath, "commands");
18817
18855
  }
18818
- if (existsSync10(join12(installPath, "agents"))) {
18819
- loadedPlugin.agentsDir = join12(installPath, "agents");
18856
+ if (existsSync10(join13(installPath, "agents"))) {
18857
+ loadedPlugin.agentsDir = join13(installPath, "agents");
18820
18858
  }
18821
- if (existsSync10(join12(installPath, "skills"))) {
18822
- loadedPlugin.skillsDir = join12(installPath, "skills");
18859
+ if (existsSync10(join13(installPath, "skills"))) {
18860
+ loadedPlugin.skillsDir = join13(installPath, "skills");
18823
18861
  }
18824
- const hooksPath = join12(installPath, "hooks", "hooks.json");
18862
+ const hooksPath = join13(installPath, "hooks", "hooks.json");
18825
18863
  if (existsSync10(hooksPath)) {
18826
18864
  loadedPlugin.hooksPath = hooksPath;
18827
18865
  }
18828
- const mcpPath = join12(installPath, ".mcp.json");
18866
+ const mcpPath = join13(installPath, ".mcp.json");
18829
18867
  if (existsSync10(mcpPath)) {
18830
18868
  loadedPlugin.mcpPath = mcpPath;
18831
18869
  }
@@ -18840,7 +18878,7 @@ function discoverInstalledPlugins(options) {
18840
18878
 
18841
18879
  // src/features/claude-code-plugin-loader/command-loader.ts
18842
18880
  import { existsSync as existsSync11, readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
18843
- import { basename, join as join13 } from "path";
18881
+ import { basename, join as join14 } from "path";
18844
18882
  init_logger();
18845
18883
  function loadPluginCommands(plugins) {
18846
18884
  const commands = {};
@@ -18851,7 +18889,7 @@ function loadPluginCommands(plugins) {
18851
18889
  for (const entry of entries) {
18852
18890
  if (!isMarkdownFile(entry))
18853
18891
  continue;
18854
- const commandPath = join13(plugin.commandsDir, entry.name);
18892
+ const commandPath = join14(plugin.commandsDir, entry.name);
18855
18893
  const commandName = basename(entry.name, ".md");
18856
18894
  const namespacedName = `${plugin.name}:${commandName}`;
18857
18895
  try {
@@ -18887,13 +18925,13 @@ $ARGUMENTS
18887
18925
 
18888
18926
  // src/features/claude-code-plugin-loader/skill-loader.ts
18889
18927
  import { existsSync as existsSync12, readdirSync as readdirSync4, readFileSync as readFileSync8 } from "fs";
18890
- import { join as join15 } from "path";
18928
+ import { join as join16 } from "path";
18891
18929
 
18892
18930
  // src/shared/skill-path-resolver.ts
18893
- import { join as join14 } from "path";
18931
+ import { join as join15 } from "path";
18894
18932
  function resolveSkillPathReferences(content, basePath) {
18895
18933
  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));
18934
+ return content.replace(/(?<![a-zA-Z0-9])@([a-zA-Z0-9_-]+\/[a-zA-Z0-9_.\-\/]*)/g, (_, relativePath) => join15(normalizedBase, relativePath));
18897
18935
  }
18898
18936
 
18899
18937
  // src/features/claude-code-plugin-loader/skill-loader.ts
@@ -18907,11 +18945,11 @@ function loadPluginSkillsAsCommands(plugins) {
18907
18945
  for (const entry of entries) {
18908
18946
  if (entry.name.startsWith("."))
18909
18947
  continue;
18910
- const skillPath = join15(plugin.skillsDir, entry.name);
18948
+ const skillPath = join16(plugin.skillsDir, entry.name);
18911
18949
  if (!entry.isDirectory() && !entry.isSymbolicLink())
18912
18950
  continue;
18913
18951
  const resolvedPath = resolveSymlink(skillPath);
18914
- const skillMdPath = join15(resolvedPath, "SKILL.md");
18952
+ const skillMdPath = join16(resolvedPath, "SKILL.md");
18915
18953
  if (!existsSync12(skillMdPath))
18916
18954
  continue;
18917
18955
  try {
@@ -18951,7 +18989,7 @@ $ARGUMENTS
18951
18989
 
18952
18990
  // src/features/claude-code-plugin-loader/agent-loader.ts
18953
18991
  import { existsSync as existsSync13, readdirSync as readdirSync5, readFileSync as readFileSync9 } from "fs";
18954
- import { basename as basename2, join as join16 } from "path";
18992
+ import { basename as basename2, join as join17 } from "path";
18955
18993
  init_logger();
18956
18994
  function parseToolsConfig(toolsStr) {
18957
18995
  if (!toolsStr)
@@ -18974,7 +19012,7 @@ function loadPluginAgents(plugins) {
18974
19012
  for (const entry of entries) {
18975
19013
  if (!isMarkdownFile(entry))
18976
19014
  continue;
18977
- const agentPath = join16(plugin.agentsDir, entry.name);
19015
+ const agentPath = join17(plugin.agentsDir, entry.name);
18978
19016
  const agentName = basename2(entry.name, ".md");
18979
19017
  const namespacedName = `${plugin.name}:${agentName}`;
18980
19018
  try {
@@ -19326,16 +19364,16 @@ init_logger();
19326
19364
  // src/hooks/auto-update-checker/cache.ts
19327
19365
  init_logger();
19328
19366
  import { existsSync as existsSync17, rmSync, unlinkSync as unlinkSync2 } from "fs";
19329
- import { join as join18 } from "path";
19367
+ import { join as join19 } from "path";
19330
19368
 
19331
19369
  // src/hooks/auto-update-checker/constants.ts
19332
- import { join as join17 } from "path";
19370
+ import { join as join18 } from "path";
19333
19371
  var PACKAGE_NAME = PLUGIN_PACKAGE_NAME;
19334
19372
  var NPM_REGISTRY_URL = `https://registry.npmjs.org/-/package/${PACKAGE_NAME}/dist-tags`;
19335
19373
  var NPM_FETCH_TIMEOUT = 5000;
19336
19374
  var CACHE_DIR = getOpenCodeCacheDir();
19337
19375
  var USER_CONFIG_DIR = getOpenCodeConfigDir({ binary: "opencode" });
19338
- var INSTALLED_PACKAGE_JSON = join17(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
19376
+ var INSTALLED_PACKAGE_JSON = join18(CACHE_DIR, "node_modules", PACKAGE_NAME, "package.json");
19339
19377
 
19340
19378
  // src/hooks/auto-update-checker/cache.ts
19341
19379
  function deleteLockfile(lockPath) {
@@ -19352,16 +19390,16 @@ function deleteLockfile(lockPath) {
19352
19390
  function invalidatePackage(packageName = PACKAGE_NAME) {
19353
19391
  let changed = false;
19354
19392
  for (const packageDir of [
19355
- join18(USER_CONFIG_DIR, "node_modules", packageName),
19356
- join18(CACHE_DIR, "node_modules", packageName)
19393
+ join19(USER_CONFIG_DIR, "node_modules", packageName),
19394
+ join19(CACHE_DIR, "node_modules", packageName)
19357
19395
  ]) {
19358
19396
  if (!existsSync17(packageDir))
19359
19397
  continue;
19360
19398
  rmSync(packageDir, { recursive: true, force: true });
19361
19399
  changed = true;
19362
19400
  }
19363
- changed = deleteLockfile(join18(CACHE_DIR, "bun.lock")) || changed;
19364
- changed = deleteLockfile(join18(CACHE_DIR, "bun.lockb")) || changed;
19401
+ changed = deleteLockfile(join19(CACHE_DIR, "bun.lock")) || changed;
19402
+ changed = deleteLockfile(join19(CACHE_DIR, "bun.lockb")) || changed;
19365
19403
  return changed;
19366
19404
  }
19367
19405
 
@@ -19369,12 +19407,12 @@ function invalidatePackage(packageName = PACKAGE_NAME) {
19369
19407
  import { existsSync as existsSync18, readFileSync as readFileSync11 } from "fs";
19370
19408
 
19371
19409
  // src/hooks/auto-update-checker/checker/config-paths.ts
19372
- import { join as join19 } from "path";
19410
+ import { join as join20 } from "path";
19373
19411
  function getConfigPaths(directory) {
19374
19412
  const userPaths = getOpenCodeConfigPaths({ binary: "opencode", version: null });
19375
19413
  return [
19376
- join19(directory, ".opencode", "opencode.jsonc"),
19377
- join19(directory, ".opencode", "opencode.json"),
19414
+ join20(directory, ".opencode", "opencode.jsonc"),
19415
+ join20(directory, ".opencode", "opencode.json"),
19378
19416
  userPaths.configJsonc,
19379
19417
  userPaths.configJson
19380
19418
  ];
@@ -20087,7 +20125,6 @@ init_logger();
20087
20125
 
20088
20126
  // src/plugin-config.ts
20089
20127
  import * as fs4 from "fs";
20090
- import * as path3 from "path";
20091
20128
 
20092
20129
  // node_modules/zod/v4/classic/external.js
20093
20130
  var exports_external = {};
@@ -34046,7 +34083,9 @@ function parseConfigPartially(rawConfig) {
34046
34083
  const partialConfig = {};
34047
34084
  const invalidSections = [];
34048
34085
  for (const key of Object.keys(rawConfig)) {
34049
- const sectionResult = OhMyOpenCodeConfigSchema.safeParse({ [key]: rawConfig[key] });
34086
+ const sectionResult = OhMyOpenCodeConfigSchema.safeParse({
34087
+ [key]: rawConfig[key]
34088
+ });
34050
34089
  if (sectionResult.success) {
34051
34090
  const parsed = sectionResult.data;
34052
34091
  if (parsed[key] !== undefined) {
@@ -34068,7 +34107,7 @@ function loadConfigFromPath(configPath, _ctx) {
34068
34107
  try {
34069
34108
  if (fs4.existsSync(configPath)) {
34070
34109
  const content = fs4.readFileSync(configPath, "utf-8");
34071
- const rawConfig = parseJsonc(content);
34110
+ const rawConfig = parseOmoConfigJson(content);
34072
34111
  migrateConfigFile(configPath, rawConfig);
34073
34112
  const result = OhMyOpenCodeConfigSchema.safeParse(rawConfig);
34074
34113
  if (result.success) {
@@ -34083,7 +34122,9 @@ function loadConfigFromPath(configPath, _ctx) {
34083
34122
  });
34084
34123
  const partialResult = parseConfigPartially(rawConfig);
34085
34124
  if (partialResult) {
34086
- log(`Partial config loaded from ${configPath}`, { agents: partialResult.agents });
34125
+ log(`Partial config loaded from ${configPath}`, {
34126
+ agents: partialResult.agents
34127
+ });
34087
34128
  return partialResult;
34088
34129
  }
34089
34130
  return null;
@@ -34135,13 +34176,11 @@ function mergeConfigs(base, override) {
34135
34176
  };
34136
34177
  }
34137
34178
  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";
34179
+ const userConfigPath = getOpenCodeConfigPaths({
34180
+ binary: "opencode",
34181
+ version: null
34182
+ }).omoConfig;
34183
+ const projectConfigPath = getProjectOmoConfigFilePath(directory);
34145
34184
  let config2 = loadConfigFromPath(userConfigPath, ctx) ?? {};
34146
34185
  const projectConfig = loadConfigFromPath(projectConfigPath, ctx);
34147
34186
  if (projectConfig) {
@@ -35913,12 +35952,12 @@ var AGENTS_INJECTOR_STORAGE = join25(OPENCODE_STORAGE, "directory-agents");
35913
35952
  var AGENTS_FILENAME = "AGENTS.md";
35914
35953
 
35915
35954
  // src/hooks/directory-agents-injector/finder.ts
35916
- function resolveFilePath2(rootDirectory, path4) {
35917
- if (!path4)
35955
+ function resolveFilePath2(rootDirectory, path3) {
35956
+ if (!path3)
35918
35957
  return null;
35919
- if (isAbsolute2(path4))
35920
- return path4;
35921
- return resolve2(rootDirectory, path4);
35958
+ if (isAbsolute2(path3))
35959
+ return path3;
35960
+ return resolve2(rootDirectory, path3);
35922
35961
  }
35923
35962
  function findAgentsMdUp(input) {
35924
35963
  const found = [];
@@ -36091,12 +36130,12 @@ var README_INJECTOR_STORAGE = join28(OPENCODE_STORAGE, "directory-readme");
36091
36130
  var README_FILENAME = "README.md";
36092
36131
 
36093
36132
  // src/hooks/directory-readme-injector/finder.ts
36094
- function resolveFilePath3(rootDirectory, path4) {
36095
- if (!path4)
36133
+ function resolveFilePath3(rootDirectory, path3) {
36134
+ if (!path3)
36096
36135
  return null;
36097
- if (isAbsolute3(path4))
36098
- return path4;
36099
- return resolve3(rootDirectory, path4);
36136
+ if (isAbsolute3(path3))
36137
+ return path3;
36138
+ return resolve3(rootDirectory, path3);
36100
36139
  }
36101
36140
  function findReadmeMdUp(input) {
36102
36141
  const found = [];
@@ -36641,12 +36680,12 @@ function getCachedParsedRule(filePath, realPath) {
36641
36680
  return parseRuleFrontmatter(rawContent);
36642
36681
  }
36643
36682
  }
36644
- function resolveFilePath4(workspaceDirectory, path4) {
36645
- if (!path4)
36683
+ function resolveFilePath4(workspaceDirectory, path3) {
36684
+ if (!path3)
36646
36685
  return null;
36647
- if (path4.startsWith("/"))
36648
- return path4;
36649
- return resolve4(workspaceDirectory, path4);
36686
+ if (path3.startsWith("/"))
36687
+ return path3;
36688
+ return resolve4(workspaceDirectory, path3);
36650
36689
  }
36651
36690
  function createRuleInjectionProcessor(deps) {
36652
36691
  const { workspaceDirectory, truncator, getSessionCache: getSessionCache3 } = deps;
@@ -37021,16 +37060,16 @@ class Diff {
37021
37060
  }
37022
37061
  }
37023
37062
  }
37024
- addToPath(path4, added, removed, oldPosInc, options) {
37025
- const last = path4.lastComponent;
37063
+ addToPath(path3, added, removed, oldPosInc, options) {
37064
+ const last = path3.lastComponent;
37026
37065
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
37027
37066
  return {
37028
- oldPos: path4.oldPos + oldPosInc,
37067
+ oldPos: path3.oldPos + oldPosInc,
37029
37068
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
37030
37069
  };
37031
37070
  } else {
37032
37071
  return {
37033
- oldPos: path4.oldPos + oldPosInc,
37072
+ oldPos: path3.oldPos + oldPosInc,
37034
37073
  lastComponent: { count: 1, added, removed, previousComponent: last }
37035
37074
  };
37036
37075
  }
@@ -45870,196 +45909,6 @@ function isGeminiModel(model) {
45870
45909
  const modelName = extractModelName(model).toLowerCase();
45871
45910
  return modelName.startsWith("gemini-");
45872
45911
  }
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
45912
  // src/agents/dynamic-agent-prompt-builder.ts
46064
45913
  function categorizeTools(toolNames) {
46065
45914
  return toolNames.map((name) => {
@@ -46094,6 +45943,136 @@ function formatToolsForPrompt(tools) {
46094
45943
  }
46095
45944
  return parts.join(", ");
46096
45945
  }
45946
+ function hasAgent(agents, name) {
45947
+ return agents.some((agent) => agent.name === name);
45948
+ }
45949
+ function buildSearchGuidance(tools = []) {
45950
+ const searchTools = tools.filter((tool) => tool.category === "search").map((tool) => `\`${tool.name}\``);
45951
+ const hasLspTools = tools.some((tool) => tool.category === "lsp");
45952
+ const availableSearch = [...searchTools, ...hasLspTools ? ["`lsp_*`"] : []];
45953
+ if (availableSearch.length === 0) {
45954
+ return "Use repo-native search tools first, then read known files directly";
45955
+ }
45956
+ return `Use repo-native search first (${availableSearch.join(", ")}), then read known files directly`;
45957
+ }
45958
+ function buildDefaultResearchFlow(agents) {
45959
+ const hasExplore = hasAgent(agents, "explore");
45960
+ const hasLibrarian = hasAgent(agents, "librarian");
45961
+ if (hasExplore && hasLibrarian) {
45962
+ return "**Default flow**: explore/librarian (background) + tools \u2192 oracle (if required)";
45963
+ }
45964
+ if (hasExplore) {
45965
+ return "**Default flow**: explore (background) + repo-native tools \u2192 oracle (if required)";
45966
+ }
45967
+ if (hasLibrarian) {
45968
+ return "**Default flow**: librarian (background) + repo-native tools \u2192 oracle (if required)";
45969
+ }
45970
+ return "**Default flow**: repo-native tools \u2192 oracle (if required)";
45971
+ }
45972
+ function buildExplorationParallelGuidance(agents) {
45973
+ const hasExplore = hasAgent(agents, "explore");
45974
+ const hasLibrarian = hasAgent(agents, "librarian");
45975
+ if (hasExplore && hasLibrarian) {
45976
+ return "Parallelize EVERYTHING independent. Fire 2-5 explore/librarian agents (always `run_in_background=true`) for any non-trivial codebase question.";
45977
+ }
45978
+ if (hasExplore) {
45979
+ return "Parallelize EVERYTHING independent. Fire 2-5 explore agents (always `run_in_background=true`) for non-trivial repo discovery.";
45980
+ }
45981
+ if (hasLibrarian) {
45982
+ return "Parallelize EVERYTHING independent. Use librarian (always `run_in_background=true`) for external docs/code questions, and use repo-native tools for repo discovery.";
45983
+ }
45984
+ return "Parallelize EVERYTHING independent. Use repo-native tools aggressively for discovery when no research agents are available.";
45985
+ }
45986
+ function buildResearchDelegationThresholds(agents) {
45987
+ const hasExplore = hasAgent(agents, "explore");
45988
+ const hasLibrarian = hasAgent(agents, "librarian");
45989
+ if (hasExplore && hasLibrarian) {
45990
+ return "- need to discover files, symbols, or patterns first \u2192 `explore`\n- unfamiliar or version-sensitive library/API behavior \u2192 `librarian`";
45991
+ }
45992
+ if (hasExplore) {
45993
+ 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";
45994
+ }
45995
+ if (hasLibrarian) {
45996
+ return "- need repo discovery first \u2192 use repo-native tools\n- unfamiliar or version-sensitive library/API behavior \u2192 `librarian`";
45997
+ }
45998
+ return `- need to discover files, symbols, or patterns first \u2192 use repo-native tools
45999
+ - library/API uncertainty without research agents \u2192 rely on available repo context and avoid guessing`;
46000
+ }
46001
+ function buildResearchAnswerRouting(agents) {
46002
+ const hasExplore = hasAgent(agents, "explore");
46003
+ const hasLibrarian = hasAgent(agents, "librarian");
46004
+ if (hasExplore && hasLibrarian) {
46005
+ return "explore/librarian \u2192 synthesize \u2192 answer";
46006
+ }
46007
+ if (hasExplore) {
46008
+ return "explore + repo-native tools \u2192 synthesize \u2192 answer";
46009
+ }
46010
+ if (hasLibrarian) {
46011
+ return "librarian + repo-native tools \u2192 synthesize \u2192 answer";
46012
+ }
46013
+ return "repo-native tools \u2192 synthesize \u2192 answer";
46014
+ }
46015
+ function buildInvestigationRouting(agents) {
46016
+ return hasAgent(agents, "explore") ? "explore \u2192 report findings" : "repo-native tools \u2192 report findings";
46017
+ }
46018
+ function buildResearchToolUsageRules(agents) {
46019
+ const hasExplore = hasAgent(agents, "explore");
46020
+ const hasLibrarian = hasAgent(agents, "librarian");
46021
+ if (hasExplore && hasLibrarian) {
46022
+ 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";
46023
+ }
46024
+ if (hasExplore) {
46025
+ 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";
46026
+ }
46027
+ if (hasLibrarian) {
46028
+ 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";
46029
+ }
46030
+ return "- No research agents available. Use repo-native tools in parallel for discovery and avoid guessing from memory";
46031
+ }
46032
+ function buildBackgroundResearchExamples(agents) {
46033
+ const hasExplore = hasAgent(agents, "explore");
46034
+ const hasLibrarian = hasAgent(agents, "librarian");
46035
+ if (hasExplore && hasLibrarian) {
46036
+ return `**Research agents = background grep, not consultants.**
46037
+
46038
+
46039
+ ~~~typescript
46040
+ // CORRECT: Always background, always parallel.
46041
+ 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.")
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: Never block on explore/librarian.
46045
+ result = task(..., run_in_background=false)
46046
+ ~~~
46047
+ `;
46048
+ }
46049
+ if (hasExplore) {
46050
+ return `**Explore = background repo grep. Use repo-native tools for anything outside the repo.**
46051
+
46052
+
46053
+ ~~~typescript
46054
+ // CORRECT: Use explore in background for repo discovery.
46055
+ 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.")
46056
+
46057
+ // WRONG: Never block on explore.
46058
+ result = task(..., run_in_background=false)
46059
+ ~~~
46060
+ `;
46061
+ }
46062
+ if (hasLibrarian) {
46063
+ return `**Librarian = background external research. Use repo-native tools for repo discovery.**
46064
+
46065
+
46066
+ ~~~typescript
46067
+ // CORRECT: Use librarian in background for external docs/code guidance.
46068
+ 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.")
46069
+
46070
+ // WRONG: Use repo-native tools, not librarian, for files you can inspect directly.
46071
+ ~~~
46072
+ `;
46073
+ }
46074
+ return "**No research agents are available. Use repo-native tools directly and parallelize reads/searches aggressively.**";
46075
+ }
46097
46076
  function buildKeyTriggersSection(agents, _skills = []) {
46098
46077
  const keyTriggers = agents.filter((a) => a.metadata.keyTrigger).map((a) => `- ${a.metadata.keyTrigger}`);
46099
46078
  if (keyTriggers.length === 0)
@@ -46120,7 +46099,7 @@ function buildToolSelectionTable(agents, tools = [], _skills = []) {
46120
46099
  rows.push(`- \`${agent.name}\` agent \u2014 **${agent.metadata.cost}** \u2014 ${shortDesc}`);
46121
46100
  }
46122
46101
  rows.push("");
46123
- rows.push("**Default flow**: explore/librarian (background) + tools \u2192 oracle (if required)");
46102
+ rows.push(buildDefaultResearchFlow(agents));
46124
46103
  return rows.join(`
46125
46104
  `);
46126
46105
  }
@@ -46309,9 +46288,9 @@ function buildAntiPatternsSection() {
46309
46288
  ${patterns.join(`
46310
46289
  `)}`;
46311
46290
  }
46312
- function buildNonClaudePlannerSection(model) {
46291
+ function buildNonClaudePlannerSection(model, agents = []) {
46313
46292
  const isNonClaude = !model.toLowerCase().includes("claude");
46314
- if (!isNonClaude)
46293
+ if (!isNonClaude || !hasAgent(agents, "plan"))
46315
46294
  return "";
46316
46295
  return `### Plan Agent Dependency (Non-Claude)
46317
46296
 
@@ -46344,9 +46323,309 @@ Each delegation prompt must include GOAL + success criteria, file paths + constr
46344
46323
  **Your value is orchestration, decomposition, and quality control.**`;
46345
46324
  }
46346
46325
 
46326
+ // src/agents/sisyphus/default.ts
46327
+ function buildTaskManagementSection(useTaskSystem) {
46328
+ if (useTaskSystem) {
46329
+ return `<Task_Management>
46330
+ ## Task Management (CRITICAL)
46331
+
46332
+ **DEFAULT BEHAVIOR**: Create tasks BEFORE starting any non-trivial task. This is your PRIMARY coordination mechanism.
46333
+
46334
+ ### When to Create Tasks (MANDATORY)
46335
+
46336
+ - Multi-step task (2+ steps) \u2192 ALWAYS \`task_create\` first
46337
+ - Uncertain scope \u2192 ALWAYS (tasks clarify thinking)
46338
+ - User request with multiple items \u2192 ALWAYS
46339
+ - Complex single task \u2192 \`task_create\` to break down
46340
+
46341
+ ### Workflow (NON-NEGOTIABLE)
46342
+
46343
+ 1. **IMMEDIATELY on receiving request**: \`task_create\` to plan atomic steps.
46344
+ - ONLY ADD TASKS TO IMPLEMENT SOMETHING, ONLY WHEN USER WANTS YOU TO IMPLEMENT SOMETHING.
46345
+ 2. **Before starting each step**: \`task_update(task_id="...", status="in_progress")\` (only ONE at a time)
46346
+ 3. **After completing each step**: \`task_update(task_id="...", status="completed")\` IMMEDIATELY (NEVER batch)
46347
+ 4. **If scope changes**: Update tasks before proceeding
46348
+
46349
+ ### Why This Is Non-Negotiable
46350
+
46351
+ - **User visibility**: User sees real-time progress, not a black box
46352
+ - **Prevents drift**: Tasks anchor you to the actual request
46353
+ - **Recovery**: If interrupted, tasks enable seamless continuation
46354
+ - **Accountability**: Each task = explicit commitment
46355
+
46356
+ ### Anti-Patterns (BLOCKING)
46357
+
46358
+ - Skipping tasks on multi-step tasks \u2014 user has no visibility, steps get forgotten
46359
+ - Batch-completing multiple tasks \u2014 defeats real-time tracking purpose
46360
+ - Proceeding without marking in_progress \u2014 no indication of what you're working on
46361
+ - Finishing without completing tasks \u2014 task appears incomplete to user
46362
+
46363
+ **FAILURE TO USE TASKS ON NON-TRIVIAL TASKS = INCOMPLETE WORK.**
46364
+
46365
+ ### Clarification Protocol (when asking):
46366
+
46367
+ \`\`\`
46368
+ I want to make sure I understand correctly.
46369
+
46370
+ **What I understood**: [Your interpretation]
46371
+ **What I'm unsure about**: [Specific ambiguity]
46372
+ **Options I see**:
46373
+ 1. [Option A] - [effort/implications]
46374
+ 2. [Option B] - [effort/implications]
46375
+
46376
+ **My recommendation**: [suggestion with reasoning]
46377
+
46378
+ Should I proceed with [recommendation], or would you prefer differently?
46379
+ \`\`\`
46380
+ </Task_Management>`;
46381
+ }
46382
+ return `<Task_Management>
46383
+ ## Todo Management (CRITICAL)
46384
+
46385
+ **DEFAULT BEHAVIOR**: Create todos BEFORE starting any non-trivial task. This is your PRIMARY coordination mechanism.
46386
+
46387
+ ### When to Create Todos (MANDATORY)
46388
+
46389
+ - Multi-step task (2+ steps) \u2192 ALWAYS create todos first
46390
+ - Uncertain scope \u2192 ALWAYS (todos clarify thinking)
46391
+ - User request with multiple items \u2192 ALWAYS
46392
+ - Complex single task \u2192 Create todos to break down
46393
+
46394
+ ### Workflow (NON-NEGOTIABLE)
46395
+
46396
+ 1. **IMMEDIATELY on receiving request**: \`todowrite\` to plan atomic steps.
46397
+ - ONLY ADD TODOS TO IMPLEMENT SOMETHING, ONLY WHEN USER WANTS YOU TO IMPLEMENT SOMETHING.
46398
+ 2. **Before starting each step**: Mark \`in_progress\` (only ONE at a time)
46399
+ 3. **After completing each step**: Mark \`completed\` IMMEDIATELY (NEVER batch)
46400
+ 4. **If scope changes**: Update todos before proceeding
46401
+
46402
+ ### Why This Is Non-Negotiable
46403
+
46404
+ - **User visibility**: User sees real-time progress, not a black box
46405
+ - **Prevents drift**: Todos anchor you to the actual request
46406
+ - **Recovery**: If interrupted, todos enable seamless continuation
46407
+ - **Accountability**: Each todo = explicit commitment
46408
+
46409
+ ### Anti-Patterns (BLOCKING)
46410
+
46411
+ - Skipping todos on multi-step tasks \u2014 user has no visibility, steps get forgotten
46412
+ - Batch-completing multiple todos \u2014 defeats real-time tracking purpose
46413
+ - Proceeding without marking in_progress \u2014 no indication of what you're working on
46414
+ - Finishing without completing todos \u2014 task appears incomplete to user
46415
+
46416
+ **FAILURE TO USE TODOS ON NON-TRIVIAL TASKS = INCOMPLETE WORK.**
46417
+
46418
+ ### Clarification Protocol (when asking):
46419
+
46420
+ \`\`\`
46421
+ I want to make sure I understand correctly.
46422
+
46423
+ **What I understood**: [Your interpretation]
46424
+ **What I'm unsure about**: [Specific ambiguity]
46425
+ **Options I see**:
46426
+ 1. [Option A] - [effort/implications]
46427
+ 2. [Option B] - [effort/implications]
46428
+
46429
+ **My recommendation**: [suggestion with reasoning]
46430
+
46431
+ Should I proceed with [recommendation], or would you prefer differently?
46432
+ \`\`\`
46433
+ </Task_Management>`;
46434
+ }
46435
+
46436
+ // src/agents/sisyphus/gemini.ts
46437
+ function buildGeminiToolMandate() {
46438
+ return `<TOOL_CALL_MANDATE>
46439
+ ## YOU MUST USE TOOLS. THIS IS NOT OPTIONAL.
46440
+
46441
+ **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.
46442
+
46443
+ **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.
46444
+
46445
+ **RULES (VIOLATION = BROKEN RESPONSE):**
46446
+
46447
+ 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.
46448
+ 2. **NEVER claim a task is done without running \`lsp_diagnostics\`.** Your confidence that "this should work" is WRONG more often than right.
46449
+ 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.
46450
+ 4. **NEVER reason about what a file "probably contains."** READ IT. Tool calls are cheap. Wrong answers are expensive.
46451
+ 5. **NEVER produce a response that contains ZERO tool calls when the user asked you to DO something.** Thinking is not doing.
46452
+
46453
+ **THINK ABOUT WHICH TOOLS TO USE:**
46454
+ Before responding, enumerate in your head:
46455
+ - What tools do I need to call to fulfill this request?
46456
+ - What information am I assuming that I should verify with a tool call?
46457
+ - Am I about to skip a tool call because I "already know" the answer?
46458
+
46459
+ Then ACTUALLY CALL those tools using the JSON tool schema. Produce the tool_use blocks. Execute.
46460
+ </TOOL_CALL_MANDATE>`;
46461
+ }
46462
+ function buildGeminiToolGuide() {
46463
+ return `<GEMINI_TOOL_GUIDE>
46464
+ ## Tool Usage Guide \u2014 WHEN and HOW to Call Each Tool
46465
+
46466
+ You have access to tools via function calling. This guide defines WHEN to call each one.
46467
+ **Violating these patterns = failed response.**
46468
+
46469
+ ### Reading & Search (parallelize)
46470
+ - \`Read\`: before ANY claim about file contents; before editing any file
46471
+ - \`Grep\`: find patterns, imports, usages; verify "X is used in Y"
46472
+ - \`Glob\`: verify file existence by name/extension pattern
46473
+ - \`AstGrepSearch\`: structural code pattern search
46474
+
46475
+ ### Code Intelligence (parallelize on different files)
46476
+ - \`LspDiagnostics\`: AFTER EVERY edit; BEFORE claiming done; MANDATORY
46477
+ - \`LspGotoDefinition\`: find where a symbol is defined
46478
+ - \`LspFindReferences\`: find all usages across workspace
46479
+ - \`LspSymbols\`: file outline or workspace symbol search
46480
+
46481
+ ### Editing (sequential)
46482
+ - \`Edit\`: modify existing files; MUST Read first for LINE#ID anchors
46483
+ - \`Write\`: create new files or fully overwrite files
46484
+
46485
+ ### Execution & Delegation
46486
+ - \`Bash\`: tests, builds, git commands; usually sequential
46487
+ - \`Task\`: ANY non-trivial implementation; research via explore/librarian; fire in background
46488
+
46489
+ ### Correct Sequences (MANDATORY \u2014 follow these exactly):
46490
+
46491
+ 1. **Answer about code**: Read \u2192 (analyze) \u2192 Answer
46492
+ 2. **Edit code**: Read \u2192 Edit \u2192 LspDiagnostics \u2192 Report
46493
+ 3. **Find something**: Grep/Glob (parallel) \u2192 Read results \u2192 Report
46494
+ 4. **Implement feature**: Task(delegate) \u2192 Verify results \u2192 Report
46495
+ 5. **Debug**: Read error \u2192 Read file \u2192 Grep related \u2192 Fix \u2192 LspDiagnostics
46496
+
46497
+ ### PARALLEL RULES:
46498
+
46499
+ - **Independent reads/searches**: ALWAYS call simultaneously in ONE response
46500
+ - **Dependent operations**: Call sequentially (Edit AFTER Read, LspDiagnostics AFTER Edit)
46501
+ - **Background agents**: ALWAYS \`run_in_background=true\`, continue working
46502
+ </GEMINI_TOOL_GUIDE>`;
46503
+ }
46504
+ function buildGeminiToolCallExamples() {
46505
+ return `<GEMINI_TOOL_CALL_EXAMPLES>
46506
+ ## Correct Tool Calling Patterns \u2014 Follow These Examples
46507
+
46508
+ ### Example 1: User asks about code \u2192 Read FIRST, then answer
46509
+ **User**: "How does the auth middleware work?"
46510
+ **CORRECT**:
46511
+ \`\`\`
46512
+ \u2192 Call Read(filePath="/src/middleware/auth.ts")
46513
+ \u2192 Call Read(filePath="/src/config/auth.ts") // parallel with above
46514
+ \u2192 (After reading) Answer based on ACTUAL file contents
46515
+ \`\`\`
46516
+ **WRONG**:
46517
+ \`\`\`
46518
+ \u2192 "The auth middleware likely validates JWT tokens by..." \u2190 HALLUCINATION. You didn't read the file.
46519
+ \`\`\`
46520
+
46521
+ ### Example 2: User asks to edit code \u2192 Read, Edit, Verify
46522
+ **User**: "Fix the type error in user.ts"
46523
+ **CORRECT**:
46524
+ \`\`\`
46525
+ \u2192 Call Read(filePath="/src/models/user.ts")
46526
+ \u2192 Call LspDiagnostics(filePath="/src/models/user.ts") // parallel with Read
46527
+ \u2192 (After reading) Call Edit with LINE#ID anchors
46528
+ \u2192 Call LspDiagnostics(filePath="/src/models/user.ts") // verify fix
46529
+ \u2192 Report: "Fixed. Diagnostics clean."
46530
+ \`\`\`
46531
+ **WRONG**:
46532
+ \`\`\`
46533
+ \u2192 Call Edit without reading first \u2190 No LINE#ID anchors = WILL FAIL
46534
+ \u2192 Skip LspDiagnostics after edit \u2190 UNVERIFIED
46535
+ \`\`\`
46536
+
46537
+ ### Example 3: Investigation \u2260 Implementation
46538
+ **User**: "Look into why the tests are failing"
46539
+ **CORRECT**:
46540
+ \`\`\`
46541
+ \u2192 Call Bash(command="npm test") // see actual failures
46542
+ \u2192 Call Read on failing test files
46543
+ \u2192 Call Read on source files under test
46544
+ \u2192 Report: "Tests fail because X. Root cause: Y. Proposed fix: Z."
46545
+ \u2192 STOP \u2014 wait for user to say "fix it"
46546
+ \`\`\`
46547
+ **WRONG**:
46548
+ \`\`\`
46549
+ \u2192 Start editing source files immediately \u2190 "look into" \u2260 "fix"
46550
+ \`\`\`
46551
+ </GEMINI_TOOL_CALL_EXAMPLES>`;
46552
+ }
46553
+ function buildGeminiDelegationOverride() {
46554
+ return `<GEMINI_DELEGATION_OVERRIDE>
46555
+ ## DELEGATION IS MANDATORY \u2014 YOU ARE NOT AN IMPLEMENTER
46556
+
46557
+ **You have a strong tendency to do work yourself. RESIST THIS.**
46558
+
46559
+ 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.
46560
+
46561
+ **EVERY TIME you are about to write code or make changes directly:**
46562
+ \u2192 STOP. Ask: "Is there a category + skills combination for this?"
46563
+ \u2192 If YES (almost always): delegate via \`task()\`
46564
+ \u2192 If NO (extremely rare): proceed, but this should happen less than 5% of the time
46565
+
46566
+ **The user chose an orchestrator model specifically because they want delegation and parallel execution. If you do work yourself, you are failing your purpose.**
46567
+ </GEMINI_DELEGATION_OVERRIDE>`;
46568
+ }
46569
+ function buildGeminiVerificationOverride() {
46570
+ return `<GEMINI_VERIFICATION_OVERRIDE>
46571
+ ## YOUR SELF-ASSESSMENT IS UNRELIABLE \u2014 VERIFY WITH TOOLS
46572
+
46573
+ **When you believe something is "done" or "correct" \u2014 you are probably wrong.**
46574
+
46575
+ 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.
46576
+
46577
+ **MANDATORY**: Replace internal confidence with external verification:
46578
+
46579
+ | Your Feeling | Reality | Required Action |
46580
+ | "This should work" | ~60% chance it works | Run \`lsp_diagnostics\` NOW |
46581
+ | "I'm sure this file exists" | ~70% chance | Use \`glob\` to verify NOW |
46582
+ | "The subagent did it right" | ~50% chance | Read EVERY changed file NOW |
46583
+ | "No need to check this" | You DEFINITELY need to | Check it NOW |
46584
+
46585
+ **BEFORE claiming ANY task is complete:**
46586
+ 1. Run \`lsp_diagnostics\` on ALL changed files \u2014 ACTUALLY clean, not "probably clean"
46587
+ 2. If tests exist, run them \u2014 ACTUALLY pass, not "they should pass"
46588
+ 3. Read the output of every command \u2014 ACTUALLY read, not skim
46589
+ 4. If you delegated, read EVERY file the subagent touched \u2014 not trust their claims
46590
+ </GEMINI_VERIFICATION_OVERRIDE>`;
46591
+ }
46592
+ function buildGeminiIntentGateEnforcement() {
46593
+ return `<GEMINI_INTENT_GATE_ENFORCEMENT>
46594
+ ## YOU MUST CLASSIFY INTENT BEFORE ACTING. NO EXCEPTIONS.
46595
+
46596
+ **Your failure mode: You skip intent classification and jump straight to implementation.**
46597
+
46598
+ 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.
46599
+
46600
+ **MANDATORY FIRST OUTPUT \u2014 before ANY tool call or action:**
46601
+
46602
+ \`\`\`
46603
+ I detect [TYPE] intent \u2014 [REASON].
46604
+ My approach: [ROUTING DECISION].
46605
+ \`\`\`
46606
+
46607
+ Where TYPE is one of: research | implementation | investigation | evaluation | fix | open-ended
46608
+
46609
+ **SELF-CHECK (answer honestly before proceeding):**
46610
+
46611
+ 1. Did the user EXPLICITLY ask me to implement/build/create something? \u2192 If NO, do NOT implement.
46612
+ 2. Did the user say "look into", "check", "investigate", "explain"? \u2192 That means RESEARCH, not implementation.
46613
+ 3. Did the user ask "what do you think?" \u2192 That means EVALUATION \u2014 propose and WAIT, do not execute.
46614
+ 4. Did the user report an error? \u2192 That means MINIMAL FIX, not refactoring.
46615
+
46616
+ **COMMON MISTAKES YOU MAKE (AND MUST NOT):**
46617
+ - "explain how X works" \u2192 Research X, explain it, STOP
46618
+ - "look into this bug" \u2192 Investigate, report findings, WAIT for go-ahead
46619
+ - "what do you think about approach X?" \u2192 Evaluate X, propose alternatives, WAIT
46620
+ - "improve the tests" \u2192 Assess current tests FIRST, propose approach, THEN implement
46621
+
46622
+ **IF YOU SKIPPED THE INTENT CLASSIFICATION ABOVE:** STOP. Go back. Do it now. Your next tool call is INVALID without it.
46623
+ </GEMINI_INTENT_GATE_ENFORCEMENT>`;
46624
+ }
46625
+
46347
46626
  // src/agents/sisyphus/gpt-5-4.ts
46348
46627
  function buildTasksSection(useTaskSystem) {
46349
- const tool = useTaskSystem ? "TaskCreate / TaskUpdate" : "todowrite";
46628
+ const tool = useTaskSystem ? "task_create / task_update" : "todowrite";
46350
46629
  return `## Tasks
46351
46630
  Create ${useTaskSystem ? "tasks" : "todos"} before starting any non-trivial work (multi-step, uncertain scope, complex breakdown).
46352
46631
  Use \`${tool}\` with atomic steps. Mark each step in_progress \u2192 completed immediately. Never batch.`;
@@ -46356,12 +46635,15 @@ function buildGpt54SisyphusPrompt(model, availableAgents, availableTools = [], a
46356
46635
  const toolSelection = buildToolSelectionTable(availableAgents, availableTools, availableSkills);
46357
46636
  const exploreSection = buildExploreSection(availableAgents);
46358
46637
  const librarianSection = buildLibrarianSection(availableAgents);
46638
+ const explorationParallelGuidance = buildExplorationParallelGuidance(availableAgents);
46639
+ const researchDelegationThresholds = buildResearchDelegationThresholds(availableAgents);
46640
+ const searchGuidance = buildSearchGuidance(availableTools);
46359
46641
  const categorySkillsGuide = buildCategorySkillsDelegationGuide(availableCategories, availableSkills);
46360
46642
  const delegationTable = buildDelegationTable(availableAgents);
46361
46643
  const oracleSection = buildOracleSection(availableAgents);
46362
46644
  const hardBlocks = buildHardBlocksSection();
46363
46645
  const antiPatterns = buildAntiPatternsSection();
46364
- const nonClaudePlannerSection = buildNonClaudePlannerSection(model);
46646
+ const nonClaudePlannerSection = buildNonClaudePlannerSection(model, availableAgents);
46365
46647
  const tasksSection = buildTasksSection(useTaskSystem);
46366
46648
  const identity = `You are Sisyphus, an AI coding orchestrator running in OhMyOpenCode. You are expected to be precise, safe, and helpful.
46367
46649
 
@@ -46404,7 +46686,7 @@ ${exploreSection}
46404
46686
 
46405
46687
  ${librarianSection}
46406
46688
 
46407
- Parallelize EVERYTHING independent. Fire 2-5 explore/librarian agents (always \`run_in_background=true\`) for any non-trivial codebase question.
46689
+ ${explorationParallelGuidance}
46408
46690
 
46409
46691
  Each agent prompt needs: [CONTEXT] [GOAL] [DOWNSTREAM] [REQUEST].
46410
46692
 
@@ -46418,7 +46700,7 @@ Coding guidelines:
46418
46700
  - Avoid unneeded complexity
46419
46701
  - Keep changes minimal and consistent with existing style
46420
46702
  - Do not fix unrelated bugs or broken tests (mention them in final message)
46421
- - Use \`rg\` for searching (faster than grep)
46703
+ - ${searchGuidance}
46422
46704
  - Use \`git log\` / \`git blame\` for history context
46423
46705
  - Do NOT git commit unless explicitly asked
46424
46706
  - Do NOT add copyright/license headers unless asked
@@ -46433,8 +46715,7 @@ Coding guidelines:
46433
46715
  - no user-facing UI/UX, styling, layout, animation, or polish requirement
46434
46716
  - no meaningful parallelization opportunity
46435
46717
  - 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\`
46718
+ ${researchDelegationThresholds}
46438
46719
  - architecture tradeoff, security/performance risk, or 2+ failed attempts \u2192 \`oracle\`
46439
46720
  - user-facing UI/UX, layout, styling, animation, or polish \u2192 \`visual-engineering\`
46440
46721
  - likely 2+ files, or one file plus tightly coupled tests/config/docs \u2192 delegate via category
@@ -46500,116 +46781,6 @@ ${tasksSection}
46500
46781
  ${style}`;
46501
46782
  }
46502
46783
 
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
46784
  // src/agents/sisyphus.ts
46614
46785
  var MODE = "all";
46615
46786
  function buildDynamicSisyphusPrompt(model, availableAgents, availableTools = [], availableSkills = [], availableCategories = [], useTaskSystem = false) {
@@ -46623,7 +46794,12 @@ function buildDynamicSisyphusPrompt(model, availableAgents, availableTools = [],
46623
46794
  const hardBlocks = buildHardBlocksSection();
46624
46795
  const antiPatterns = buildAntiPatternsSection();
46625
46796
  const parallelDelegationSection = buildParallelDelegationSection(model, availableCategories);
46626
- const nonClaudePlannerSection = buildNonClaudePlannerSection(model);
46797
+ const nonClaudePlannerSection = buildNonClaudePlannerSection(model, availableAgents);
46798
+ const researchAnswerRouting = buildResearchAnswerRouting(availableAgents);
46799
+ const investigationRouting = buildInvestigationRouting(availableAgents);
46800
+ const researchDelegationThresholds = buildResearchDelegationThresholds(availableAgents);
46801
+ const researchToolUsageRules = buildResearchToolUsageRules(availableAgents);
46802
+ const backgroundResearchExamples = buildBackgroundResearchExamples(availableAgents);
46627
46803
  const taskManagementSection = buildTaskManagementSection(useTaskSystem);
46628
46804
  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
46805
  return `<Role>
@@ -46659,9 +46835,9 @@ Before classifying the task, identify what the user actually wants from you as a
46659
46835
 
46660
46836
  | Surface Form | True Intent | Your Routing |
46661
46837
  |---|---|---|
46662
- | "explain X", "how does Y work" | Research/understanding | explore/librarian \u2192 synthesize \u2192 answer |
46838
+ | "explain X", "how does Y work" | Research/understanding | ${researchAnswerRouting} |
46663
46839
  | "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 |
46840
+ | "look into X", "check Y", "investigate" | Investigation | ${investigationRouting} |
46665
46841
  | "what do you think about X?" | Evaluation | evaluate \u2192 propose \u2192 **wait for confirmation** |
46666
46842
  | "I'm seeing error X" / "Y is broken" | Fix needed | diagnose \u2192 fix minimally |
46667
46843
  | "refactor", "improve", "clean up" | Open-ended change | assess codebase first \u2192 propose approach |
@@ -46707,8 +46883,7 @@ Work yourself only when ALL are true:
46707
46883
  - no meaningful parallelization opportunity
46708
46884
 
46709
46885
  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\`
46886
+ ${researchDelegationThresholds}
46712
46887
  - architecture tradeoff, security/performance risk, or 2+ failed attempts \u2192 \`oracle\`
46713
46888
  - user-facing UI/UX, layout, styling, animation, or polish \u2192 \`visual-engineering\`
46714
46889
  - likely 2+ files, or one file plus tightly coupled tests/config/docs \u2192 delegate via category
@@ -46774,29 +46949,13 @@ ${librarianSection}
46774
46949
 
46775
46950
  <tool_usage_rules>
46776
46951
  - 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
46952
+ ${researchToolUsageRules}
46779
46953
  - Parallelize independent file reads \u2014 don't read files one at a time
46780
46954
  - After any write/edit tool call, briefly restate what changed, where, and what validation follows
46781
46955
  - Prefer tools over internal knowledge whenever you need specific data (files, configs, patterns)
46782
46956
  </tool_usage_rules>
46783
46957
 
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
- \`\`\`
46958
+ ${backgroundResearchExamples}
46800
46959
 
46801
46960
  ### Background Result Collection:
46802
46961
  1. Launch parallel agents \u2192 receive task_ids
@@ -52991,17 +53150,17 @@ Task NOT complete without:
52991
53150
  </Style>`;
52992
53151
  if (!promptAppend)
52993
53152
  return prompt;
52994
- return prompt + `
53153
+ return `${prompt}
52995
53154
 
52996
- ` + resolvePromptAppend(promptAppend);
53155
+ ${resolvePromptAppend(promptAppend)}`;
52997
53156
  }
52998
53157
  function buildTodoDisciplineSection(useTaskSystem) {
52999
53158
  if (useTaskSystem) {
53000
53159
  return `<Task_Discipline>
53001
53160
  TASK OBSESSION (NON-NEGOTIABLE):
53002
53161
  - 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
53162
+ - task_update(task_id="...", status="in_progress") before starting (ONE at a time)
53163
+ - task_update(task_id="...", status="completed") IMMEDIATELY after each step
53005
53164
  - NEVER batch completions
53006
53165
 
53007
53166
  No tasks on multi-step work = INCOMPLETE WORK.
@@ -53129,17 +53288,17 @@ Style:
53129
53288
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53130
53289
  if (!promptAppend)
53131
53290
  return prompt;
53132
- return prompt + `
53291
+ return `${prompt}
53133
53292
 
53134
- ` + resolvePromptAppend(promptAppend);
53293
+ ${resolvePromptAppend(promptAppend)}`;
53135
53294
  }
53136
53295
  function buildGptTaskDisciplineSection(useTaskSystem) {
53137
53296
  if (useTaskSystem) {
53138
53297
  return `## Task Discipline (NON-NEGOTIABLE)
53139
53298
 
53140
53299
  - **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
53300
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53301
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY
53143
53302
  - **Batching** \u2014 NEVER batch completions
53144
53303
 
53145
53304
  No tasks on multi-step work = INCOMPLETE WORK.`;
@@ -53268,17 +53427,17 @@ Style:
53268
53427
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53269
53428
  if (!promptAppend)
53270
53429
  return prompt;
53271
- return prompt + `
53430
+ return `${prompt}
53272
53431
 
53273
- ` + resolvePromptAppend(promptAppend);
53432
+ ${resolvePromptAppend(promptAppend)}`;
53274
53433
  }
53275
53434
  function buildGpt54TaskDisciplineSection(useTaskSystem) {
53276
53435
  if (useTaskSystem) {
53277
53436
  return `## Task Discipline (NON-NEGOTIABLE)
53278
53437
 
53279
53438
  - **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
53439
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53440
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY
53282
53441
  - **Batching** \u2014 NEVER batch completions
53283
53442
 
53284
53443
  No tasks on multi-step work = INCOMPLETE WORK.`;
@@ -53404,17 +53563,17 @@ Style:
53404
53563
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53405
53564
  if (!promptAppend)
53406
53565
  return prompt;
53407
- return prompt + `
53566
+ return `${prompt}
53408
53567
 
53409
- ` + resolvePromptAppend(promptAppend);
53568
+ ${resolvePromptAppend(promptAppend)}`;
53410
53569
  }
53411
53570
  function buildGpt53CodexTaskDisciplineSection(useTaskSystem) {
53412
53571
  if (useTaskSystem) {
53413
53572
  return `## Task Discipline (NON-NEGOTIABLE)
53414
53573
 
53415
53574
  - **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
53575
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53576
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY
53418
53577
  - **Batching** \u2014 NEVER batch completions
53419
53578
 
53420
53579
  No tasks on multi-step work = INCOMPLETE WORK.`;
@@ -53574,9 +53733,9 @@ If ANY answer is no \u2192 GO BACK AND DO IT. Do not claim completion.
53574
53733
  3. After 3 DIFFERENT approaches fail \u2192 STOP and report what you tried clearly`;
53575
53734
  if (!promptAppend)
53576
53735
  return prompt;
53577
- return prompt + `
53736
+ return `${prompt}
53578
53737
 
53579
- ` + resolvePromptAppend(promptAppend);
53738
+ ${resolvePromptAppend(promptAppend)}`;
53580
53739
  }
53581
53740
  function buildGeminiTaskDisciplineSection(useTaskSystem) {
53582
53741
  if (useTaskSystem) {
@@ -53585,8 +53744,8 @@ function buildGeminiTaskDisciplineSection(useTaskSystem) {
53585
53744
  **You WILL forget to track tasks if not forced. This section forces you.**
53586
53745
 
53587
53746
  - **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
53747
+ - **Starting step** \u2014 task_update(task_id="...", status="in_progress") \u2014 ONE at a time
53748
+ - **Completing step** \u2014 task_update(task_id="...", status="completed") IMMEDIATELY after verification passes
53590
53749
  - **Batching** \u2014 NEVER batch completions. Mark EACH task individually.
53591
53750
 
53592
53751
  No tasks on multi-step work = INCOMPLETE WORK. The user tracks your progress through tasks.`;
@@ -53899,20 +54058,20 @@ var import_picomatch2 = __toESM(require_picomatch2(), 1);
53899
54058
  import { promises as fs8 } from "fs";
53900
54059
  import { dirname as dirname10, extname, isAbsolute as isAbsolute7, join as join42, relative as relative4 } from "path";
53901
54060
  var MAX_RECURSIVE_DEPTH = 10;
53902
- function isHttpUrl(path4) {
53903
- return path4.startsWith("http://") || path4.startsWith("https://");
54061
+ function isHttpUrl(path3) {
54062
+ return path3.startsWith("http://") || path3.startsWith("https://");
53904
54063
  }
53905
- function toAbsolutePath(path4, configDir) {
53906
- if (isAbsolute7(path4)) {
53907
- return path4;
54064
+ function toAbsolutePath(path3, configDir) {
54065
+ if (isAbsolute7(path3)) {
54066
+ return path3;
53908
54067
  }
53909
- return join42(configDir, path4);
54068
+ return join42(configDir, path3);
53910
54069
  }
53911
- function isMarkdownPath(path4) {
53912
- return extname(path4).toLowerCase() === ".md";
54070
+ function isMarkdownPath(path3) {
54071
+ return extname(path3).toLowerCase() === ".md";
53913
54072
  }
53914
- function normalizePathForGlob(path4) {
53915
- return path4.split("\\").join("/");
54073
+ function normalizePathForGlob(path3) {
54074
+ return path3.split("\\").join("/");
53916
54075
  }
53917
54076
  function filterByGlob(skills2, sourceBaseDir, globPattern) {
53918
54077
  if (!globPattern)
@@ -58062,11 +58221,11 @@ async function loadMcpConfigFile(filePath) {
58062
58221
  function getSystemMcpServerNames() {
58063
58222
  const names = new Set;
58064
58223
  const paths = getMcpConfigPaths();
58065
- for (const { path: path4 } of paths) {
58066
- if (!existsSync38(path4))
58224
+ for (const { path: path3 } of paths) {
58225
+ if (!existsSync38(path3))
58067
58226
  continue;
58068
58227
  try {
58069
- const content = readFileSync29(path4, "utf-8");
58228
+ const content = readFileSync29(path3, "utf-8");
58070
58229
  const config2 = JSON.parse(content);
58071
58230
  if (!config2?.mcpServers)
58072
58231
  continue;
@@ -58086,22 +58245,22 @@ async function loadMcpConfigs(disabledMcps = []) {
58086
58245
  const loadedServers = [];
58087
58246
  const paths = getMcpConfigPaths();
58088
58247
  const disabledSet = new Set(disabledMcps);
58089
- for (const { path: path4, scope } of paths) {
58090
- const config2 = await loadMcpConfigFile(path4);
58248
+ for (const { path: path3, scope } of paths) {
58249
+ const config2 = await loadMcpConfigFile(path3);
58091
58250
  if (!config2?.mcpServers)
58092
58251
  continue;
58093
58252
  for (const [name, serverConfig] of Object.entries(config2.mcpServers)) {
58094
58253
  if (disabledSet.has(name)) {
58095
- log(`Skipping MCP "${name}" (in disabled_mcps)`, { path: path4 });
58254
+ log(`Skipping MCP "${name}" (in disabled_mcps)`, { path: path3 });
58096
58255
  continue;
58097
58256
  }
58098
58257
  if (serverConfig.disabled) {
58099
- log(`Disabling MCP server "${name}"`, { path: path4 });
58258
+ log(`Disabling MCP server "${name}"`, { path: path3 });
58100
58259
  delete servers[name];
58101
58260
  const existingIndex = loadedServers.findIndex((s) => s.name === name);
58102
58261
  if (existingIndex !== -1) {
58103
58262
  loadedServers.splice(existingIndex, 1);
58104
- log(`Removed previously loaded MCP server "${name}"`, { path: path4 });
58263
+ log(`Removed previously loaded MCP server "${name}"`, { path: path3 });
58105
58264
  }
58106
58265
  continue;
58107
58266
  }
@@ -58113,7 +58272,7 @@ async function loadMcpConfigs(disabledMcps = []) {
58113
58272
  loadedServers.splice(existingIndex, 1);
58114
58273
  }
58115
58274
  loadedServers.push({ name, scope, config: transformed });
58116
- log(`Loaded MCP server "${name}" from ${scope}`, { path: path4 });
58275
+ log(`Loaded MCP server "${name}" from ${scope}`, { path: path3 });
58117
58276
  } catch (error48) {
58118
58277
  log(`Failed to transform MCP server "${name}"`, error48);
58119
58278
  }
@@ -58769,11 +58928,20 @@ var DEFAULT_MAX_DIRECTORY_FILES = 50;
58769
58928
  // src/tools/lsp/server-config-loader.ts
58770
58929
  import { existsSync as existsSync39, readFileSync as readFileSync30 } from "fs";
58771
58930
  import { join as join46 } from "path";
58772
- function loadJsonFile(path4) {
58773
- if (!existsSync39(path4))
58931
+ function loadJsonFile(path3) {
58932
+ if (!existsSync39(path3))
58933
+ return null;
58934
+ try {
58935
+ return parseOmoConfigJson(readFileSync30(path3, "utf-8"));
58936
+ } catch {
58937
+ return null;
58938
+ }
58939
+ }
58940
+ function loadOpenCodeConfigFile(path3) {
58941
+ if (!existsSync39(path3))
58774
58942
  return null;
58775
58943
  try {
58776
- return parseJsonc(readFileSync30(path4, "utf-8"));
58944
+ return parseJsonc(readFileSync30(path3, "utf-8"));
58777
58945
  } catch {
58778
58946
  return null;
58779
58947
  }
@@ -58782,8 +58950,8 @@ function getConfigPaths2() {
58782
58950
  const cwd = process.cwd();
58783
58951
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
58784
58952
  return {
58785
- project: detectConfigFile(join46(cwd, ".opencode", "oh-my-opencode-gpt-slim")).path,
58786
- user: detectConfigFile(join46(configDir, "oh-my-opencode-gpt-slim")).path,
58953
+ project: getProjectOmoConfigFilePath(cwd),
58954
+ user: getOmoConfigFilePath(configDir),
58787
58955
  opencode: detectConfigFile(join46(configDir, "opencode")).path
58788
58956
  };
58789
58957
  }
@@ -58796,7 +58964,7 @@ function loadAllConfigs() {
58796
58964
  const user = loadJsonFile(paths.user);
58797
58965
  if (user)
58798
58966
  configs.set("user", user);
58799
- const opencode = loadJsonFile(paths.opencode);
58967
+ const opencode = loadOpenCodeConfigFile(paths.opencode);
58800
58968
  if (opencode)
58801
58969
  configs.set("opencode", opencode);
58802
58970
  return configs;
@@ -58845,7 +59013,11 @@ function getMergedServers() {
58845
59013
  }
58846
59014
  return servers.sort((a, b) => {
58847
59015
  if (a.source !== b.source) {
58848
- const order = { project: 0, user: 1, opencode: 2 };
59016
+ const order = {
59017
+ project: 0,
59018
+ user: 1,
59019
+ opencode: 2
59020
+ };
58849
59021
  return order[a.source] - order[b.source];
58850
59022
  }
58851
59023
  return b.priority - a.priority;
@@ -60724,10 +60896,10 @@ function mergeDefs2(...defs) {
60724
60896
  function cloneDef2(schema2) {
60725
60897
  return mergeDefs2(schema2._zod.def);
60726
60898
  }
60727
- function getElementAtPath2(obj, path4) {
60728
- if (!path4)
60899
+ function getElementAtPath2(obj, path3) {
60900
+ if (!path3)
60729
60901
  return obj;
60730
- return path4.reduce((acc, key) => acc?.[key], obj);
60902
+ return path3.reduce((acc, key) => acc?.[key], obj);
60731
60903
  }
60732
60904
  function promiseAllObject2(promisesObj) {
60733
60905
  const keys = Object.keys(promisesObj);
@@ -61086,11 +61258,11 @@ function aborted2(x, startIndex = 0) {
61086
61258
  }
61087
61259
  return false;
61088
61260
  }
61089
- function prefixIssues2(path4, issues) {
61261
+ function prefixIssues2(path3, issues) {
61090
61262
  return issues.map((iss) => {
61091
61263
  var _a2;
61092
61264
  (_a2 = iss).path ?? (_a2.path = []);
61093
- iss.path.unshift(path4);
61265
+ iss.path.unshift(path3);
61094
61266
  return iss;
61095
61267
  });
61096
61268
  }
@@ -61258,7 +61430,7 @@ function treeifyError2(error48, _mapper) {
61258
61430
  return issue3.message;
61259
61431
  };
61260
61432
  const result = { errors: [] };
61261
- const processError = (error49, path4 = []) => {
61433
+ const processError = (error49, path3 = []) => {
61262
61434
  var _a2, _b;
61263
61435
  for (const issue3 of error49.issues) {
61264
61436
  if (issue3.code === "invalid_union" && issue3.errors.length) {
@@ -61268,7 +61440,7 @@ function treeifyError2(error48, _mapper) {
61268
61440
  } else if (issue3.code === "invalid_element") {
61269
61441
  processError({ issues: issue3.issues }, issue3.path);
61270
61442
  } else {
61271
- const fullpath = [...path4, ...issue3.path];
61443
+ const fullpath = [...path3, ...issue3.path];
61272
61444
  if (fullpath.length === 0) {
61273
61445
  result.errors.push(mapper(issue3));
61274
61446
  continue;
@@ -61300,8 +61472,8 @@ function treeifyError2(error48, _mapper) {
61300
61472
  }
61301
61473
  function toDotPath2(_path) {
61302
61474
  const segs = [];
61303
- const path4 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
61304
- for (const seg of path4) {
61475
+ const path3 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
61476
+ for (const seg of path3) {
61305
61477
  if (typeof seg === "number")
61306
61478
  segs.push(`[${seg}]`);
61307
61479
  else if (typeof seg === "symbol")
@@ -78957,6 +79129,7 @@ function createChatMessageHandler2(args) {
78957
79129
  if (firstMessageVariantGate.shouldOverride(input.sessionID)) {
78958
79130
  firstMessageVariantGate.markApplied(input.sessionID);
78959
79131
  }
79132
+ applyAgentReasoningEffort(pluginConfig, input.agent, output.message);
78960
79133
  if (!isRuntimeFallbackEnabled) {
78961
79134
  await hooks2.modelFallback?.["chat.message"]?.(input, output);
78962
79135
  }