@skj1724/oh-my-opencode 3.23.3 → 3.23.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
@@ -46,6 +46,59 @@ var __export = (target, all) => {
46
46
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
47
47
  var __require = import.meta.require;
48
48
 
49
+ // src/features/claude-code-session-state/state.ts
50
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
51
+ import { join } from "path";
52
+ function setMainSession(id) {
53
+ _mainSessionID = id;
54
+ }
55
+ function getMainSessionID() {
56
+ return _mainSessionID;
57
+ }
58
+ function updateSessionAgent(sessionID, agent, source = "unknown") {
59
+ sessionAgentMap.set(sessionID, agent);
60
+ sessionAgentMetaMap.set(sessionID, { updatedAt: Date.now(), source });
61
+ }
62
+ function getSessionAgent(sessionID) {
63
+ return sessionAgentMap.get(sessionID);
64
+ }
65
+ function isSessionAgentStale(sessionID, staleThresholdMs) {
66
+ const meta = sessionAgentMetaMap.get(sessionID);
67
+ if (!meta)
68
+ return false;
69
+ return Date.now() - meta.updatedAt > staleThresholdMs;
70
+ }
71
+ function clearSessionAgent(sessionID) {
72
+ sessionAgentMap.delete(sessionID);
73
+ sessionAgentMetaMap.delete(sessionID);
74
+ }
75
+ function loadSessionAgentMap(directory) {
76
+ try {
77
+ const persistPath = join(directory, ".opencode", "session-agent-map.json");
78
+ if (!existsSync(persistPath))
79
+ return;
80
+ const content = readFileSync(persistPath, "utf-8");
81
+ const data = JSON.parse(content);
82
+ for (const [sessionID, entry] of Object.entries(data)) {
83
+ if (!sessionAgentMap.has(sessionID)) {
84
+ sessionAgentMap.set(sessionID, entry.agent);
85
+ sessionAgentMetaMap.set(sessionID, { updatedAt: entry.updatedAt, source: entry.source });
86
+ }
87
+ }
88
+ } catch {}
89
+ }
90
+ var subagentSessions, _mainSessionID, sessionAgentMap, sessionAgentMetaMap;
91
+ var init_state = __esm(() => {
92
+ subagentSessions = new Set;
93
+ sessionAgentMap = new Map;
94
+ sessionAgentMetaMap = new Map;
95
+ });
96
+
97
+ // src/features/claude-code-session-state/index.ts
98
+ var init_claude_code_session_state = __esm(() => {
99
+ init_state();
100
+ });
101
+
49
102
  // src/shared/agent-display-names.ts
50
103
  function getAgentDisplayName(configKey) {
51
104
  const exactMatch = AGENT_DISPLAY_TO_KEY[configKey];
@@ -135,7 +188,7 @@ var init_agent_display_names = __esm(() => {
135
188
  });
136
189
 
137
190
  // src/shared/fileio-monitor.ts
138
- import { readdirSync, readFileSync, writeFileSync, existsSync } from "fs";
191
+ import { readdirSync, readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync2 } from "fs";
139
192
  import { relative } from "path";
140
193
  import { cwd } from "process";
141
194
  function summarize(path) {
@@ -172,11 +225,11 @@ function createFileIOMonitor(tracer) {
172
225
  },
173
226
  readFileSync(path, options) {
174
227
  if (!tracer.isEnabled()) {
175
- return readFileSync(path, options);
228
+ return readFileSync2(path, options);
176
229
  }
177
230
  const start = performance.now();
178
231
  try {
179
- return readFileSync(path, options);
232
+ return readFileSync2(path, options);
180
233
  } finally {
181
234
  const durationMs = performance.now() - start;
182
235
  tracer.recordFileIO("readFileSync", summarize(path), durationMs);
@@ -184,12 +237,12 @@ function createFileIOMonitor(tracer) {
184
237
  },
185
238
  writeFileSync(path, data, options) {
186
239
  if (!tracer.isEnabled()) {
187
- writeFileSync(path, data, options);
240
+ writeFileSync2(path, data, options);
188
241
  return;
189
242
  }
190
243
  const start = performance.now();
191
244
  try {
192
- writeFileSync(path, data, options);
245
+ writeFileSync2(path, data, options);
193
246
  } finally {
194
247
  const durationMs = performance.now() - start;
195
248
  tracer.recordFileIO("writeFileSync", summarize(path), durationMs);
@@ -197,11 +250,11 @@ function createFileIOMonitor(tracer) {
197
250
  },
198
251
  existsSync(path) {
199
252
  if (!tracer.isEnabled()) {
200
- return existsSync(path);
253
+ return existsSync2(path);
201
254
  }
202
255
  const start = performance.now();
203
256
  try {
204
- return existsSync(path);
257
+ return existsSync2(path);
205
258
  } finally {
206
259
  const durationMs = performance.now() - start;
207
260
  tracer.recordFileIO("existsSync", summarize(path), durationMs);
@@ -262,9 +315,9 @@ var init_system_directive = __esm(() => {
262
315
  });
263
316
 
264
317
  // src/shared/opencode-config-dir.ts
265
- import { existsSync as existsSync3 } from "fs";
318
+ import { existsSync as existsSync4 } from "fs";
266
319
  import { homedir as homedir2 } from "os";
267
- import { join as join5, resolve } from "path";
320
+ import { join as join6, resolve } from "path";
268
321
  function isDevBuild(version) {
269
322
  if (!version)
270
323
  return false;
@@ -274,15 +327,15 @@ function getTauriConfigDir(identifier) {
274
327
  const platform = process.platform;
275
328
  switch (platform) {
276
329
  case "darwin":
277
- return join5(homedir2(), "Library", "Application Support", identifier);
330
+ return join6(homedir2(), "Library", "Application Support", identifier);
278
331
  case "win32": {
279
- const appData = process.env.APPDATA || join5(homedir2(), "AppData", "Roaming");
280
- return join5(appData, identifier);
332
+ const appData = process.env.APPDATA || join6(homedir2(), "AppData", "Roaming");
333
+ return join6(appData, identifier);
281
334
  }
282
335
  case "linux":
283
336
  default: {
284
- const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
285
- return join5(xdgConfig, identifier);
337
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join6(homedir2(), ".config");
338
+ return join6(xdgConfig, identifier);
286
339
  }
287
340
  }
288
341
  }
@@ -292,21 +345,21 @@ function getCliConfigDir() {
292
345
  return resolve(envConfigDir);
293
346
  }
294
347
  if (process.platform === "win32") {
295
- const crossPlatformDir = join5(homedir2(), ".config", "opencode");
296
- const crossPlatformConfig = join5(crossPlatformDir, "opencode.json");
297
- if (existsSync3(crossPlatformConfig)) {
348
+ const crossPlatformDir = join6(homedir2(), ".config", "opencode");
349
+ const crossPlatformConfig = join6(crossPlatformDir, "opencode.json");
350
+ if (existsSync4(crossPlatformConfig)) {
298
351
  return crossPlatformDir;
299
352
  }
300
- const appData = process.env.APPDATA || join5(homedir2(), "AppData", "Roaming");
301
- const appdataDir = join5(appData, "opencode");
302
- const appdataConfig = join5(appdataDir, "opencode.json");
303
- if (existsSync3(appdataConfig)) {
353
+ const appData = process.env.APPDATA || join6(homedir2(), "AppData", "Roaming");
354
+ const appdataDir = join6(appData, "opencode");
355
+ const appdataConfig = join6(appdataDir, "opencode.json");
356
+ if (existsSync4(appdataConfig)) {
304
357
  return appdataDir;
305
358
  }
306
359
  return crossPlatformDir;
307
360
  }
308
- const xdgConfig = process.env.XDG_CONFIG_HOME || join5(homedir2(), ".config");
309
- return join5(xdgConfig, "opencode");
361
+ const xdgConfig = process.env.XDG_CONFIG_HOME || join6(homedir2(), ".config");
362
+ return join6(xdgConfig, "opencode");
310
363
  }
311
364
  function getOpenCodeConfigDir(options) {
312
365
  const { binary, version, checkExisting = true } = options;
@@ -317,9 +370,9 @@ function getOpenCodeConfigDir(options) {
317
370
  const tauriDir = getTauriConfigDir(identifier);
318
371
  if (checkExisting) {
319
372
  const legacyDir = getCliConfigDir();
320
- const legacyConfig = join5(legacyDir, "opencode.json");
321
- const legacyConfigC = join5(legacyDir, "opencode.jsonc");
322
- if (existsSync3(legacyConfig) || existsSync3(legacyConfigC)) {
373
+ const legacyConfig = join6(legacyDir, "opencode.json");
374
+ const legacyConfigC = join6(legacyDir, "opencode.jsonc");
375
+ if (existsSync4(legacyConfig) || existsSync4(legacyConfigC)) {
323
376
  return legacyDir;
324
377
  }
325
378
  }
@@ -329,10 +382,10 @@ function getOpenCodeConfigPaths(options) {
329
382
  const configDir = getOpenCodeConfigDir(options);
330
383
  return {
331
384
  configDir,
332
- configJson: join5(configDir, "opencode.json"),
333
- configJsonc: join5(configDir, "opencode.jsonc"),
334
- packageJson: join5(configDir, "package.json"),
335
- omoConfig: join5(configDir, "oh-my-opencode.json")
385
+ configJson: join6(configDir, "opencode.json"),
386
+ configJsonc: join6(configDir, "opencode.jsonc"),
387
+ packageJson: join6(configDir, "package.json"),
388
+ omoConfig: join6(configDir, "oh-my-opencode.json")
336
389
  };
337
390
  }
338
391
  var TAURI_APP_IDENTIFIER = "ai.opencode.desktop", TAURI_APP_IDENTIFIER_DEV = "ai.opencode.desktop.dev";
@@ -1203,7 +1256,7 @@ var init_main = __esm(() => {
1203
1256
  });
1204
1257
 
1205
1258
  // src/shared/jsonc-parser.ts
1206
- import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
1259
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
1207
1260
  function parseJsonc(content) {
1208
1261
  const errors = [];
1209
1262
  const result = parse2(content, errors, {
@@ -1234,10 +1287,10 @@ function parseJsoncSafe(content) {
1234
1287
  function detectConfigFile(basePath) {
1235
1288
  const jsoncPath = `${basePath}.jsonc`;
1236
1289
  const jsonPath = `${basePath}.json`;
1237
- if (existsSync4(jsoncPath)) {
1290
+ if (existsSync5(jsoncPath)) {
1238
1291
  return { format: "jsonc", path: jsoncPath };
1239
1292
  }
1240
- if (existsSync4(jsonPath)) {
1293
+ if (existsSync5(jsonPath)) {
1241
1294
  return { format: "json", path: jsonPath };
1242
1295
  }
1243
1296
  return { format: "none", path: jsonPath };
@@ -3999,7 +4052,7 @@ var init_js_yaml = __esm(() => {
3999
4052
  });
4000
4053
 
4001
4054
  // src/shared/frontmatter.ts
4002
- import { readFileSync as readFileSync6 } from "fs";
4055
+ import { readFileSync as readFileSync7 } from "fs";
4003
4056
  function parseFrontmatter(content) {
4004
4057
  const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n?---\r?\n([\s\S]*)$/;
4005
4058
  const match = content.match(frontmatterRegex);
@@ -4018,7 +4071,7 @@ function parseFrontmatter(content) {
4018
4071
  }
4019
4072
  function parseCompletionActions(planPath) {
4020
4073
  try {
4021
- const content = readFileSync6(planPath, "utf-8");
4074
+ const content = readFileSync7(planPath, "utf-8");
4022
4075
  const result = parseFrontmatter(content);
4023
4076
  if (!result.hadFrontmatter || result.parseError) {
4024
4077
  return [];
@@ -4046,17 +4099,17 @@ var init_frontmatter = __esm(() => {
4046
4099
  import { spawn as spawn2 } from "child_process";
4047
4100
  import { exec } from "child_process";
4048
4101
  import { promisify } from "util";
4049
- import { existsSync as existsSync7 } from "fs";
4102
+ import { existsSync as existsSync8 } from "fs";
4050
4103
  import { homedir as homedir3 } from "os";
4051
4104
  function getHomeDir() {
4052
4105
  return process.env.HOME || process.env.USERPROFILE || homedir3();
4053
4106
  }
4054
4107
  function findShellPath(defaultPaths, customPath) {
4055
- if (customPath && existsSync7(customPath)) {
4108
+ if (customPath && existsSync8(customPath)) {
4056
4109
  return customPath;
4057
4110
  }
4058
4111
  for (const path3 of defaultPaths) {
4059
- if (existsSync7(path3)) {
4112
+ if (existsSync8(path3)) {
4060
4113
  return path3;
4061
4114
  }
4062
4115
  }
@@ -4191,8 +4244,8 @@ var init_command_executor = __esm(() => {
4191
4244
  });
4192
4245
 
4193
4246
  // src/shared/file-reference-resolver.ts
4194
- import { existsSync as existsSync8, readFileSync as readFileSync7, statSync } from "fs";
4195
- import { join as join9, isAbsolute } from "path";
4247
+ import { existsSync as existsSync9, readFileSync as readFileSync8, statSync } from "fs";
4248
+ import { join as join10, isAbsolute } from "path";
4196
4249
  function findFileReferences(text) {
4197
4250
  const matches = [];
4198
4251
  let match;
@@ -4211,17 +4264,17 @@ function resolveFilePath(filePath, cwd2) {
4211
4264
  if (isAbsolute(filePath)) {
4212
4265
  return filePath;
4213
4266
  }
4214
- return join9(cwd2, filePath);
4267
+ return join10(cwd2, filePath);
4215
4268
  }
4216
4269
  function readFileContent(resolvedPath) {
4217
- if (!existsSync8(resolvedPath)) {
4270
+ if (!existsSync9(resolvedPath)) {
4218
4271
  return `[file not found: ${resolvedPath}]`;
4219
4272
  }
4220
4273
  const stat = statSync(resolvedPath);
4221
4274
  if (stat.isDirectory()) {
4222
4275
  return `[cannot read directory: ${resolvedPath}]`;
4223
4276
  }
4224
- const content = readFileSync7(resolvedPath, "utf-8");
4277
+ const content = readFileSync8(resolvedPath, "utf-8");
4225
4278
  return content;
4226
4279
  }
4227
4280
  async function resolveFileReferencesInText(text, cwd2 = process.cwd(), depth = 0, maxDepth = 3) {
@@ -4542,13 +4595,13 @@ var init_config_errors = __esm(() => {
4542
4595
 
4543
4596
  // src/shared/claude-config-dir.ts
4544
4597
  import { homedir as homedir4 } from "os";
4545
- import { join as join10 } from "path";
4598
+ import { join as join11 } from "path";
4546
4599
  function getClaudeConfigDir() {
4547
4600
  const envConfigDir = process.env.CLAUDE_CONFIG_DIR;
4548
4601
  if (envConfigDir) {
4549
4602
  return envConfigDir;
4550
4603
  }
4551
- return join10(homedir4(), ".claude");
4604
+ return join11(homedir4(), ".claude");
4552
4605
  }
4553
4606
  var init_claude_config_dir = () => {};
4554
4607
 
@@ -5214,9 +5267,9 @@ var init_model_requirements = __esm(() => {
5214
5267
  });
5215
5268
 
5216
5269
  // src/shared/model-availability.ts
5217
- import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
5270
+ import { existsSync as existsSync11, readFileSync as readFileSync10 } from "fs";
5218
5271
  import { homedir as homedir6 } from "os";
5219
- import { join as join12 } from "path";
5272
+ import { join as join13 } from "path";
5220
5273
  function normalizeModelName(name) {
5221
5274
  return name.toLowerCase().replace(/claude-(opus|sonnet|haiku)-4-5/g, "claude-$1-4.5").replace(/claude-(opus|sonnet|haiku)-4\.5/g, "claude-$1-4.5");
5222
5275
  }
@@ -5257,8 +5310,8 @@ function fuzzyMatchModel(target, available, providers) {
5257
5310
  function getOpenCodeCacheDir() {
5258
5311
  const xdgCache = process.env.XDG_CACHE_HOME;
5259
5312
  if (xdgCache)
5260
- return join12(xdgCache, "opencode");
5261
- return join12(homedir6(), ".cache", "opencode");
5313
+ return join13(xdgCache, "opencode");
5314
+ return join13(homedir6(), ".cache", "opencode");
5262
5315
  }
5263
5316
  async function fetchAvailableModels(_client) {
5264
5317
  log("[fetchAvailableModels] CALLED");
@@ -5267,14 +5320,14 @@ async function fetchAvailableModels(_client) {
5267
5320
  return cachedModels;
5268
5321
  }
5269
5322
  const modelSet = new Set;
5270
- const cacheFile = join12(getOpenCodeCacheDir(), "models.json");
5323
+ const cacheFile = join13(getOpenCodeCacheDir(), "models.json");
5271
5324
  log("[fetchAvailableModels] reading cache file", { cacheFile });
5272
- if (!existsSync10(cacheFile)) {
5325
+ if (!existsSync11(cacheFile)) {
5273
5326
  log("[fetchAvailableModels] cache file not found, returning empty set");
5274
5327
  return modelSet;
5275
5328
  }
5276
5329
  try {
5277
- const content = readFileSync9(cacheFile, "utf-8");
5330
+ const content = readFileSync10(cacheFile, "utf-8");
5278
5331
  const data = JSON.parse(content);
5279
5332
  const providerIds = Object.keys(data);
5280
5333
  log("[fetchAvailableModels] providers found", { count: providerIds.length, providers: providerIds.slice(0, 10) });
@@ -5296,8 +5349,8 @@ async function fetchAvailableModels(_client) {
5296
5349
  }
5297
5350
  }
5298
5351
  function isModelCacheAvailable() {
5299
- const cacheFile = join12(getOpenCodeCacheDir(), "models.json");
5300
- return existsSync10(cacheFile);
5352
+ const cacheFile = join13(getOpenCodeCacheDir(), "models.json");
5353
+ return existsSync11(cacheFile);
5301
5354
  }
5302
5355
  var cachedModels = null;
5303
5356
  var init_model_availability = __esm(() => {
@@ -5651,9 +5704,9 @@ class PerfTimer {
5651
5704
  }
5652
5705
 
5653
5706
  // src/shared/perf-tracer.ts
5654
- import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync4, existsSync as existsSync11 } from "fs";
5707
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync5, existsSync as existsSync12 } from "fs";
5655
5708
  import { tmpdir as tmpdir2 } from "os";
5656
- import { join as join13 } from "path";
5709
+ import { join as join14 } from "path";
5657
5710
 
5658
5711
  class PerfTracer {
5659
5712
  buffer = [];
@@ -5664,7 +5717,7 @@ class PerfTracer {
5664
5717
  memorySnapshotInterval;
5665
5718
  constructor(config) {
5666
5719
  this.enabled = config.enabled;
5667
- this.outputDir = config.outputDir ?? join13(tmpdir2(), "oh-my-opencode-perf");
5720
+ this.outputDir = config.outputDir ?? join14(tmpdir2(), "oh-my-opencode-perf");
5668
5721
  this.slowThreshold = config.slowThreshold ?? 100;
5669
5722
  this.memorySnapshotInterval = config.memorySnapshotInterval ?? 5;
5670
5723
  }
@@ -5760,11 +5813,11 @@ class PerfTracer {
5760
5813
  flush() {
5761
5814
  if (this.buffer.length === 0)
5762
5815
  return;
5763
- if (!existsSync11(this.outputDir)) {
5764
- mkdirSync4(this.outputDir, { recursive: true });
5816
+ if (!existsSync12(this.outputDir)) {
5817
+ mkdirSync5(this.outputDir, { recursive: true });
5765
5818
  }
5766
5819
  const date = new Date().toISOString().slice(0, 10);
5767
- const filePath = join13(this.outputDir, `${date}.jsonl`);
5820
+ const filePath = join14(this.outputDir, `${date}.jsonl`);
5768
5821
  let output = "";
5769
5822
  for (const span of this.buffer) {
5770
5823
  output += JSON.stringify(span) + `
@@ -5781,10 +5834,10 @@ class PerfTracer {
5781
5834
  var init_perf_tracer = () => {};
5782
5835
 
5783
5836
  // src/shared/windows-reserved-names.ts
5784
- import { existsSync as existsSync12, readdirSync as readdirSync5 } from "fs";
5785
- import { join as join14 } from "path";
5837
+ import { existsSync as existsSync13, readdirSync as readdirSync5 } from "fs";
5838
+ import { join as join15 } from "path";
5786
5839
  function scanForReservedNames(directory, maxDepth = 2) {
5787
- if (!existsSync12(directory))
5840
+ if (!existsSync13(directory))
5788
5841
  return [];
5789
5842
  const found = [];
5790
5843
  _scan(directory, 0, maxDepth, found);
@@ -5803,11 +5856,11 @@ function _scan(dir, depth, maxDepth, found) {
5803
5856
  const upper = name.toUpperCase();
5804
5857
  const baseName = upper.split(".")[0] ?? "";
5805
5858
  if (WIN_RESERVED_NAMES.has(upper) || WIN_RESERVED_NAMES.has(baseName)) {
5806
- found.push(join14(dir, name));
5859
+ found.push(join15(dir, name));
5807
5860
  }
5808
- const fullPath = join14(dir, name);
5861
+ const fullPath = join15(dir, name);
5809
5862
  try {
5810
- const stat = existsSync12(fullPath);
5863
+ const stat = existsSync13(fullPath);
5811
5864
  if (stat && depth < maxDepth) {
5812
5865
  _scan(fullPath, depth + 1, maxDepth, found);
5813
5866
  }
@@ -5861,12 +5914,12 @@ var init_windows_reserved_names = __esm(() => {
5861
5914
  });
5862
5915
 
5863
5916
  // src/shared/usage-tracker.ts
5864
- import { existsSync as existsSync13, mkdirSync as mkdirSync5, readFileSync as readFileSync10, writeFileSync as writeFileSync6 } from "fs";
5917
+ import { existsSync as existsSync14, mkdirSync as mkdirSync6, readFileSync as readFileSync11, writeFileSync as writeFileSync7 } from "fs";
5865
5918
  import { homedir as homedir7 } from "os";
5866
- import { join as join15 } from "path";
5919
+ import { join as join16 } from "path";
5867
5920
  function getStatsFilePath() {
5868
- const configDir = join15(homedir7(), ".config", "opencode");
5869
- return join15(configDir, "usage-stats.json");
5921
+ const configDir = join16(homedir7(), ".config", "opencode");
5922
+ return join16(configDir, "usage-stats.json");
5870
5923
  }
5871
5924
 
5872
5925
  class UsageTracker {
@@ -5967,9 +6020,9 @@ class UsageTracker {
5967
6020
  persistToFile() {
5968
6021
  try {
5969
6022
  const filePath = getStatsFilePath();
5970
- const dir = join15(filePath, "..");
5971
- if (!existsSync13(dir)) {
5972
- mkdirSync5(dir, { recursive: true });
6023
+ const dir = join16(filePath, "..");
6024
+ if (!existsSync14(dir)) {
6025
+ mkdirSync6(dir, { recursive: true });
5973
6026
  }
5974
6027
  const sessions = {};
5975
6028
  for (const [sessionID, records] of this.sessionData) {
@@ -5984,7 +6037,7 @@ class UsageTracker {
5984
6037
  sessions,
5985
6038
  lastUpdated: Date.now()
5986
6039
  };
5987
- writeFileSync6(filePath, JSON.stringify(data, null, 2), "utf-8");
6040
+ writeFileSync7(filePath, JSON.stringify(data, null, 2), "utf-8");
5988
6041
  } catch (error) {
5989
6042
  log("UsageTracker: \u6301\u4E45\u5316\u5931\u8D25", error);
5990
6043
  }
@@ -5992,9 +6045,9 @@ class UsageTracker {
5992
6045
  loadFromDisk() {
5993
6046
  try {
5994
6047
  const filePath = getStatsFilePath();
5995
- if (!existsSync13(filePath))
6048
+ if (!existsSync14(filePath))
5996
6049
  return;
5997
- const content = readFileSync10(filePath, "utf-8");
6050
+ const content = readFileSync11(filePath, "utf-8");
5998
6051
  const data = JSON.parse(content);
5999
6052
  if (data.sessions) {
6000
6053
  for (const [sessionID, sessionData] of Object.entries(data.sessions)) {
@@ -6105,7 +6158,7 @@ function isEnglishText(text, threshold) {
6105
6158
  function detectEnglishViolation(text, threshold = 0.6) {
6106
6159
  let stripped = stripCodeAndUrls(text);
6107
6160
  stripped = stripped.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1");
6108
- const englishTriggers = [
6161
+ const englishOpeners = [
6109
6162
  "let me",
6110
6163
  "i need",
6111
6164
  "first,",
@@ -6123,12 +6176,44 @@ function detectEnglishViolation(text, threshold = 0.6) {
6123
6176
  "next,",
6124
6177
  "next i",
6125
6178
  "then,",
6126
- "finally,"
6179
+ "finally,",
6180
+ "so,",
6181
+ "okay,",
6182
+ "alright,",
6183
+ "hmm,",
6184
+ "well,",
6185
+ "looking at",
6186
+ "looking into",
6187
+ "going to",
6188
+ "it seems",
6189
+ "it looks",
6190
+ "the code",
6191
+ "the function",
6192
+ "the implementation"
6193
+ ];
6194
+ const englishMarkers = [
6195
+ "i think",
6196
+ "i believe",
6197
+ "i would",
6198
+ "i could",
6199
+ "we should",
6200
+ "we could",
6201
+ "we would",
6202
+ "my approach",
6203
+ "my plan",
6204
+ "i want to",
6205
+ "in summary",
6206
+ "to summarize",
6207
+ "in conclusion"
6127
6208
  ];
6128
6209
  const lowerText = stripped.toLowerCase().trim();
6129
6210
  if (lowerText.length > 0) {
6130
- for (const trigger of englishTriggers) {
6131
- if (lowerText.startsWith(trigger))
6211
+ for (const opener of englishOpeners) {
6212
+ if (lowerText.startsWith(opener))
6213
+ return "trigger";
6214
+ }
6215
+ for (const marker of englishMarkers) {
6216
+ if (lowerText.includes(marker))
6132
6217
  return "trigger";
6133
6218
  }
6134
6219
  }
@@ -6139,6 +6224,59 @@ function detectEnglishViolation(text, threshold = 0.6) {
6139
6224
  return asciiLetters / meaningful.length > threshold ? "ascii" : false;
6140
6225
  }
6141
6226
 
6227
+ // src/shared/agent-identity-resolver.ts
6228
+ function resolveCurrentAgent(sessionID, inputAgent, options) {
6229
+ const staleThresholdMs = options?.staleThresholdMs ?? 600000;
6230
+ const getAgentFromMessages = options?.getAgentFromSessionMessages;
6231
+ const logger = options?.logger;
6232
+ const sessionAgent = getSessionAgent(sessionID);
6233
+ if (sessionAgent !== undefined) {
6234
+ const stale = isSessionAgentStale(sessionID, staleThresholdMs);
6235
+ if (!stale) {
6236
+ if (logger) {
6237
+ logger("[resolveCurrentAgent] resolved from sessionAgentMap", { sessionID, agent: sessionAgent });
6238
+ }
6239
+ return sessionAgent;
6240
+ }
6241
+ if (getAgentFromMessages !== null) {
6242
+ const messageFileAgent = getAgentFromMessages ? getAgentFromMessages(sessionID) : undefined;
6243
+ if (messageFileAgent !== undefined) {
6244
+ updateSessionAgent(sessionID, messageFileAgent, "resolveCurrentAgent.stale-refresh");
6245
+ if (logger) {
6246
+ logger("[resolveCurrentAgent] stale entry refreshed from message files", { sessionID, oldAgent: sessionAgent, newAgent: messageFileAgent });
6247
+ }
6248
+ return messageFileAgent;
6249
+ }
6250
+ if (logger) {
6251
+ logger("[resolveCurrentAgent] stale entry, no message file fallback", { sessionID, oldAgent: sessionAgent });
6252
+ }
6253
+ }
6254
+ }
6255
+ if (inputAgent !== undefined && inputAgent !== null) {
6256
+ if (logger) {
6257
+ logger("[resolveCurrentAgent] resolved from inputAgent", { sessionID, agent: inputAgent });
6258
+ }
6259
+ return inputAgent;
6260
+ }
6261
+ if (getAgentFromMessages !== null) {
6262
+ const messageFileAgent = getAgentFromMessages ? getAgentFromMessages(sessionID) : undefined;
6263
+ if (messageFileAgent !== undefined) {
6264
+ updateSessionAgent(sessionID, messageFileAgent, "resolveCurrentAgent.message-file");
6265
+ if (logger) {
6266
+ logger("[resolveCurrentAgent] resolved from message files", { sessionID, agent: messageFileAgent });
6267
+ }
6268
+ return messageFileAgent;
6269
+ }
6270
+ }
6271
+ if (logger) {
6272
+ logger("[resolveCurrentAgent] no agent identity found", { sessionID });
6273
+ }
6274
+ return;
6275
+ }
6276
+ var init_agent_identity_resolver = __esm(() => {
6277
+ init_claude_code_session_state();
6278
+ });
6279
+
6142
6280
  // src/shared/index.ts
6143
6281
  var init_shared = __esm(() => {
6144
6282
  init_frontmatter();
@@ -6173,6 +6311,7 @@ var init_shared = __esm(() => {
6173
6311
  init_fileio_monitor();
6174
6312
  init_windows_reserved_names();
6175
6313
  init_usage_tracker();
6314
+ init_agent_identity_resolver();
6176
6315
  });
6177
6316
 
6178
6317
  // src/tools/delegate-task/constants.ts
@@ -15624,51 +15763,22 @@ var require_cross_spawn = __commonJS((exports, module) => {
15624
15763
  });
15625
15764
 
15626
15765
  // src/hooks/todo-continuation-enforcer.ts
15627
- import { existsSync as existsSync5, readdirSync as readdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, mkdirSync as mkdirSync2, renameSync } from "fs";
15628
- import { join as join6 } from "path";
15629
-
15630
- // src/features/claude-code-session-state/state.ts
15631
- var subagentSessions = new Set;
15632
- var _mainSessionID;
15633
- function setMainSession(id) {
15634
- _mainSessionID = id;
15635
- }
15636
- function getMainSessionID() {
15637
- return _mainSessionID;
15638
- }
15639
- var sessionAgentMap = new Map;
15640
- var sessionAgentMetaMap = new Map;
15641
- function updateSessionAgent(sessionID, agent, source = "unknown") {
15642
- sessionAgentMap.set(sessionID, agent);
15643
- sessionAgentMetaMap.set(sessionID, { updatedAt: Date.now(), source });
15644
- }
15645
- function getSessionAgent(sessionID) {
15646
- return sessionAgentMap.get(sessionID);
15647
- }
15648
- function isSessionAgentStale(sessionID, staleThresholdMs) {
15649
- const meta = sessionAgentMetaMap.get(sessionID);
15650
- if (!meta)
15651
- return false;
15652
- return Date.now() - meta.updatedAt > staleThresholdMs;
15653
- }
15654
- function clearSessionAgent(sessionID) {
15655
- sessionAgentMap.delete(sessionID);
15656
- sessionAgentMetaMap.delete(sessionID);
15657
- }
15658
- // src/hooks/todo-continuation-enforcer.ts
15766
+ init_claude_code_session_state();
15659
15767
  init_agent_display_names();
15768
+ import { existsSync as existsSync6, readdirSync as readdirSync3, readFileSync as readFileSync5, writeFileSync as writeFileSync4, mkdirSync as mkdirSync3, renameSync } from "fs";
15769
+ import { join as join7 } from "path";
15660
15770
 
15661
15771
  // src/features/hook-message-injector/injector.ts
15662
15772
  init_fileio_monitor();
15663
- import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, readdirSync as readdirSync2, writeFileSync as writeFileSync2 } from "fs";
15664
- import { join as join3 } from "path";
15773
+ import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync as readdirSync2, writeFileSync as writeFileSync3 } from "fs";
15774
+ import { join as join4 } from "path";
15665
15775
 
15666
15776
  // src/features/hook-message-injector/constants.ts
15667
15777
  init_data_path();
15668
- import { join as join2 } from "path";
15778
+ import { join as join3 } from "path";
15669
15779
  var OPENCODE_STORAGE = getOpenCodeStorageDir();
15670
- var MESSAGE_STORAGE = join2(OPENCODE_STORAGE, "message");
15671
- var PART_STORAGE = join2(OPENCODE_STORAGE, "part");
15780
+ var MESSAGE_STORAGE = join3(OPENCODE_STORAGE, "message");
15781
+ var PART_STORAGE = join3(OPENCODE_STORAGE, "part");
15672
15782
 
15673
15783
  // src/features/hook-message-injector/injector.ts
15674
15784
  function findNearestMessageWithFields(messageDir) {
@@ -15677,7 +15787,7 @@ function findNearestMessageWithFields(messageDir) {
15677
15787
  const files = (monitor?.readdirSync(messageDir) ?? readdirSync2(messageDir)).filter((f) => f.endsWith(".json")).sort().reverse();
15678
15788
  for (const file of files) {
15679
15789
  try {
15680
- const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
15790
+ const content = monitor?.readFileSync(join4(messageDir, file), "utf-8") ?? readFileSync3(join4(messageDir, file), "utf-8");
15681
15791
  const msg = JSON.parse(content);
15682
15792
  if (msg.agent && msg.model?.providerID && msg.model?.modelID) {
15683
15793
  return msg;
@@ -15688,7 +15798,7 @@ function findNearestMessageWithFields(messageDir) {
15688
15798
  }
15689
15799
  for (const file of files) {
15690
15800
  try {
15691
- const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
15801
+ const content = monitor?.readFileSync(join4(messageDir, file), "utf-8") ?? readFileSync3(join4(messageDir, file), "utf-8");
15692
15802
  const msg = JSON.parse(content);
15693
15803
  if (msg.agent || msg.model?.providerID && msg.model?.modelID) {
15694
15804
  return msg;
@@ -15708,7 +15818,7 @@ function findNearestAssistantMessage(messageDir) {
15708
15818
  const files = (monitor?.readdirSync(messageDir) ?? readdirSync2(messageDir)).filter((f) => f.endsWith(".json")).sort().reverse();
15709
15819
  for (const file of files) {
15710
15820
  try {
15711
- const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
15821
+ const content = monitor?.readFileSync(join4(messageDir, file), "utf-8") ?? readFileSync3(join4(messageDir, file), "utf-8");
15712
15822
  const msg = JSON.parse(content);
15713
15823
  if (msg.role === "assistant" && msg.agent && msg.model?.providerID && msg.model?.modelID) {
15714
15824
  return msg;
@@ -15719,7 +15829,7 @@ function findNearestAssistantMessage(messageDir) {
15719
15829
  }
15720
15830
  for (const file of files) {
15721
15831
  try {
15722
- const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
15832
+ const content = monitor?.readFileSync(join4(messageDir, file), "utf-8") ?? readFileSync3(join4(messageDir, file), "utf-8");
15723
15833
  const msg = JSON.parse(content);
15724
15834
  if (msg.role === "assistant" && (msg.agent || msg.model?.providerID && msg.model?.modelID)) {
15725
15835
  return msg;
@@ -15739,7 +15849,7 @@ function findFirstAssistantAgent(messageDir) {
15739
15849
  const files = (monitor?.readdirSync(messageDir) ?? readdirSync2(messageDir)).filter((f) => f.endsWith(".json")).sort();
15740
15850
  for (const file of files) {
15741
15851
  try {
15742
- const content = monitor?.readFileSync(join3(messageDir, file), "utf-8") ?? readFileSync2(join3(messageDir, file), "utf-8");
15852
+ const content = monitor?.readFileSync(join4(messageDir, file), "utf-8") ?? readFileSync3(join4(messageDir, file), "utf-8");
15743
15853
  const msg = JSON.parse(content);
15744
15854
  if (msg.role === "assistant" && msg.agent) {
15745
15855
  return msg.agent;
@@ -15758,19 +15868,19 @@ function getAgentFromMessageDir(messageDir) {
15758
15868
  }
15759
15869
  function getAgentFromSessionMessages(sessionID) {
15760
15870
  const monitor = getFileIOMonitor();
15761
- const _exists = (p) => monitor?.existsSync(p) ?? existsSync2(p);
15871
+ const _exists = (p) => monitor?.existsSync(p) ?? existsSync3(p);
15762
15872
  const _readdir = (p) => monitor?.readdirSync(p) ?? readdirSync2(p);
15763
15873
  try {
15764
15874
  if (!_exists(MESSAGE_STORAGE))
15765
15875
  return;
15766
- const directPath = join3(MESSAGE_STORAGE, sessionID);
15876
+ const directPath = join4(MESSAGE_STORAGE, sessionID);
15767
15877
  if (_exists(directPath)) {
15768
15878
  const agent = getAgentFromMessageDir(directPath);
15769
15879
  if (agent)
15770
15880
  return agent;
15771
15881
  }
15772
15882
  for (const dir of _readdir(MESSAGE_STORAGE)) {
15773
- const sessionPath = join3(MESSAGE_STORAGE, dir, sessionID);
15883
+ const sessionPath = join4(MESSAGE_STORAGE, dir, sessionID);
15774
15884
  if (_exists(sessionPath)) {
15775
15885
  const agent = getAgentFromMessageDir(sessionPath);
15776
15886
  if (agent)
@@ -15794,18 +15904,18 @@ function generatePartId() {
15794
15904
  }
15795
15905
  function getOrCreateMessageDir(sessionID) {
15796
15906
  const monitor = getFileIOMonitor();
15797
- const _exists = (p) => monitor?.existsSync(p) ?? existsSync2(p);
15798
- const _mkdir = (p, opts) => monitor ? undefined : mkdirSync(p, opts);
15907
+ const _exists = (p) => monitor?.existsSync(p) ?? existsSync3(p);
15908
+ const _mkdir = (p, opts) => monitor ? undefined : mkdirSync2(p, opts);
15799
15909
  const _readdir = (p) => monitor?.readdirSync(p) ?? readdirSync2(p);
15800
15910
  if (!_exists(MESSAGE_STORAGE)) {
15801
15911
  _mkdir(MESSAGE_STORAGE, { recursive: true });
15802
15912
  }
15803
- const directPath = join3(MESSAGE_STORAGE, sessionID);
15913
+ const directPath = join4(MESSAGE_STORAGE, sessionID);
15804
15914
  if (_exists(directPath)) {
15805
15915
  return directPath;
15806
15916
  }
15807
15917
  for (const dir of _readdir(MESSAGE_STORAGE)) {
15808
- const sessionPath = join3(MESSAGE_STORAGE, dir, sessionID);
15918
+ const sessionPath = join4(MESSAGE_STORAGE, dir, sessionID);
15809
15919
  if (_exists(sessionPath)) {
15810
15920
  return sessionPath;
15811
15921
  }
@@ -15861,19 +15971,19 @@ function injectHookMessage(sessionID, hookContent, originalMessage) {
15861
15971
  try {
15862
15972
  const monitor = getFileIOMonitor();
15863
15973
  if (monitor) {
15864
- monitor.writeFileSync(join3(messageDir, `${messageID}.json`), JSON.stringify(messageMeta, null, 2));
15974
+ monitor.writeFileSync(join4(messageDir, `${messageID}.json`), JSON.stringify(messageMeta, null, 2));
15865
15975
  } else {
15866
- writeFileSync2(join3(messageDir, `${messageID}.json`), JSON.stringify(messageMeta, null, 2));
15976
+ writeFileSync3(join4(messageDir, `${messageID}.json`), JSON.stringify(messageMeta, null, 2));
15867
15977
  }
15868
- const partDir = join3(PART_STORAGE, messageID);
15869
- const _exists = (p) => monitor?.existsSync(p) ?? existsSync2(p);
15978
+ const partDir = join4(PART_STORAGE, messageID);
15979
+ const _exists = (p) => monitor?.existsSync(p) ?? existsSync3(p);
15870
15980
  if (!_exists(partDir)) {
15871
- mkdirSync(partDir, { recursive: true });
15981
+ mkdirSync2(partDir, { recursive: true });
15872
15982
  }
15873
15983
  if (monitor) {
15874
- monitor.writeFileSync(join3(partDir, `${partID}.json`), JSON.stringify(textPart, null, 2));
15984
+ monitor.writeFileSync(join4(partDir, `${partID}.json`), JSON.stringify(textPart, null, 2));
15875
15985
  } else {
15876
- writeFileSync2(join3(partDir, `${partID}.json`), JSON.stringify(textPart, null, 2));
15986
+ writeFileSync3(join4(partDir, `${partID}.json`), JSON.stringify(textPart, null, 2));
15877
15987
  }
15878
15988
  return true;
15879
15989
  } catch {
@@ -15890,14 +16000,14 @@ var DEFAULT_SKIP_AGENTS = ["\u6218\u7565\u53C2\u8C0B", "compaction"];
15890
16000
  var todoOwnerMap = new Map;
15891
16001
  function getTodoOwnershipFilePath() {
15892
16002
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
15893
- return join6(configDir, "todo-ownership.json");
16003
+ return join7(configDir, "todo-ownership.json");
15894
16004
  }
15895
16005
  function loadTodoOwnership() {
15896
16006
  try {
15897
16007
  const filePath = getTodoOwnershipFilePath();
15898
- if (!existsSync5(filePath))
16008
+ if (!existsSync6(filePath))
15899
16009
  return;
15900
- const content = readFileSync4(filePath, "utf-8");
16010
+ const content = readFileSync5(filePath, "utf-8");
15901
16011
  const result = parseJsoncSafe(content);
15902
16012
  if (!result.data || typeof result.data !== "object")
15903
16013
  return;
@@ -15913,15 +16023,15 @@ function loadTodoOwnership() {
15913
16023
  function persistTodoOwnership() {
15914
16024
  try {
15915
16025
  const filePath = getTodoOwnershipFilePath();
15916
- const dir = join6(filePath, "..");
15917
- if (!existsSync5(dir))
15918
- mkdirSync2(dir, { recursive: true });
16026
+ const dir = join7(filePath, "..");
16027
+ if (!existsSync6(dir))
16028
+ mkdirSync3(dir, { recursive: true });
15919
16029
  const tmpPath = `${filePath}.tmp`;
15920
16030
  const data = {};
15921
16031
  for (const [key, value] of todoOwnerMap) {
15922
16032
  data[key] = value;
15923
16033
  }
15924
- writeFileSync3(tmpPath, JSON.stringify(data, null, 2), "utf-8");
16034
+ writeFileSync4(tmpPath, JSON.stringify(data, null, 2), "utf-8");
15925
16035
  renameSync(tmpPath, filePath);
15926
16036
  } catch (err) {
15927
16037
  log(`[${HOOK_NAME}] Failed to persist todo ownership`, { error: String(err) });
@@ -15956,14 +16066,14 @@ var COUNTDOWN_SECONDS = 2;
15956
16066
  var TOAST_DURATION_MS = 900;
15957
16067
  var COUNTDOWN_GRACE_PERIOD_MS = 500;
15958
16068
  function getMessageDir(sessionID) {
15959
- if (!existsSync5(MESSAGE_STORAGE))
16069
+ if (!existsSync6(MESSAGE_STORAGE))
15960
16070
  return null;
15961
- const directPath = join6(MESSAGE_STORAGE, sessionID);
15962
- if (existsSync5(directPath))
16071
+ const directPath = join7(MESSAGE_STORAGE, sessionID);
16072
+ if (existsSync6(directPath))
15963
16073
  return directPath;
15964
16074
  for (const dir of readdirSync3(MESSAGE_STORAGE)) {
15965
- const sessionPath = join6(MESSAGE_STORAGE, dir, sessionID);
15966
- if (existsSync5(sessionPath))
16075
+ const sessionPath = join7(MESSAGE_STORAGE, dir, sessionID);
16076
+ if (existsSync6(sessionPath))
15967
16077
  return sessionPath;
15968
16078
  }
15969
16079
  return null;
@@ -16380,6 +16490,7 @@ ${CONTEXT_REMINDER}
16380
16490
  };
16381
16491
  }
16382
16492
  // src/hooks/session-notification.ts
16493
+ init_claude_code_session_state();
16383
16494
  import { platform } from "os";
16384
16495
 
16385
16496
  // src/hooks/session-notification-utils.ts
@@ -16766,15 +16877,15 @@ function createSessionNotification(ctx, config = {}) {
16766
16877
  };
16767
16878
  }
16768
16879
  // src/hooks/session-recovery/storage.ts
16769
- import { existsSync as existsSync6, mkdirSync as mkdirSync3, readdirSync as readdirSync4, readFileSync as readFileSync5, unlinkSync, writeFileSync as writeFileSync4 } from "fs";
16770
- import { join as join8 } from "path";
16880
+ import { existsSync as existsSync7, mkdirSync as mkdirSync4, readdirSync as readdirSync4, readFileSync as readFileSync6, unlinkSync, writeFileSync as writeFileSync5 } from "fs";
16881
+ import { join as join9 } from "path";
16771
16882
 
16772
16883
  // src/hooks/session-recovery/constants.ts
16773
16884
  init_data_path();
16774
- import { join as join7 } from "path";
16885
+ import { join as join8 } from "path";
16775
16886
  var OPENCODE_STORAGE2 = getOpenCodeStorageDir();
16776
- var MESSAGE_STORAGE2 = join7(OPENCODE_STORAGE2, "message");
16777
- var PART_STORAGE2 = join7(OPENCODE_STORAGE2, "part");
16887
+ var MESSAGE_STORAGE2 = join8(OPENCODE_STORAGE2, "message");
16888
+ var PART_STORAGE2 = join8(OPENCODE_STORAGE2, "part");
16778
16889
  var THINKING_TYPES = new Set(["thinking", "redacted_thinking", "reasoning"]);
16779
16890
  var META_TYPES = new Set(["step-start", "step-finish"]);
16780
16891
  var CONTENT_TYPES = new Set(["text", "tool", "tool_use", "tool_result"]);
@@ -16787,15 +16898,15 @@ function generatePartId2() {
16787
16898
  return `prt_${timestamp}${random}`;
16788
16899
  }
16789
16900
  function getMessageDir2(sessionID) {
16790
- if (!existsSync6(MESSAGE_STORAGE2))
16901
+ if (!existsSync7(MESSAGE_STORAGE2))
16791
16902
  return "";
16792
- const directPath = join8(MESSAGE_STORAGE2, sessionID);
16793
- if (existsSync6(directPath)) {
16903
+ const directPath = join9(MESSAGE_STORAGE2, sessionID);
16904
+ if (existsSync7(directPath)) {
16794
16905
  return directPath;
16795
16906
  }
16796
16907
  for (const dir of readdirSync4(MESSAGE_STORAGE2)) {
16797
- const sessionPath = join8(MESSAGE_STORAGE2, dir, sessionID);
16798
- if (existsSync6(sessionPath)) {
16908
+ const sessionPath = join9(MESSAGE_STORAGE2, dir, sessionID);
16909
+ if (existsSync7(sessionPath)) {
16799
16910
  return sessionPath;
16800
16911
  }
16801
16912
  }
@@ -16803,14 +16914,14 @@ function getMessageDir2(sessionID) {
16803
16914
  }
16804
16915
  function readMessages(sessionID) {
16805
16916
  const messageDir = getMessageDir2(sessionID);
16806
- if (!messageDir || !existsSync6(messageDir))
16917
+ if (!messageDir || !existsSync7(messageDir))
16807
16918
  return [];
16808
16919
  const messages = [];
16809
16920
  for (const file of readdirSync4(messageDir)) {
16810
16921
  if (!file.endsWith(".json"))
16811
16922
  continue;
16812
16923
  try {
16813
- const content = readFileSync5(join8(messageDir, file), "utf-8");
16924
+ const content = readFileSync6(join9(messageDir, file), "utf-8");
16814
16925
  messages.push(JSON.parse(content));
16815
16926
  } catch {
16816
16927
  continue;
@@ -16825,15 +16936,15 @@ function readMessages(sessionID) {
16825
16936
  });
16826
16937
  }
16827
16938
  function readParts(messageID) {
16828
- const partDir = join8(PART_STORAGE2, messageID);
16829
- if (!existsSync6(partDir))
16939
+ const partDir = join9(PART_STORAGE2, messageID);
16940
+ if (!existsSync7(partDir))
16830
16941
  return [];
16831
16942
  const parts = [];
16832
16943
  for (const file of readdirSync4(partDir)) {
16833
16944
  if (!file.endsWith(".json"))
16834
16945
  continue;
16835
16946
  try {
16836
- const content = readFileSync5(join8(partDir, file), "utf-8");
16947
+ const content = readFileSync6(join9(partDir, file), "utf-8");
16837
16948
  parts.push(JSON.parse(content));
16838
16949
  } catch {
16839
16950
  continue;
@@ -16863,9 +16974,9 @@ function messageHasContent(messageID) {
16863
16974
  return parts.some(hasContent);
16864
16975
  }
16865
16976
  function injectTextPart(sessionID, messageID, text) {
16866
- const partDir = join8(PART_STORAGE2, messageID);
16867
- if (!existsSync6(partDir)) {
16868
- mkdirSync3(partDir, { recursive: true });
16977
+ const partDir = join9(PART_STORAGE2, messageID);
16978
+ if (!existsSync7(partDir)) {
16979
+ mkdirSync4(partDir, { recursive: true });
16869
16980
  }
16870
16981
  const partId = generatePartId2();
16871
16982
  const part = {
@@ -16877,7 +16988,7 @@ function injectTextPart(sessionID, messageID, text) {
16877
16988
  synthetic: true
16878
16989
  };
16879
16990
  try {
16880
- writeFileSync4(join8(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
16991
+ writeFileSync5(join9(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
16881
16992
  return true;
16882
16993
  } catch {
16883
16994
  return false;
@@ -16972,9 +17083,9 @@ function findLastThinkingContent(sessionID, beforeMessageID) {
16972
17083
  return "";
16973
17084
  }
16974
17085
  function prependThinkingPart(sessionID, messageID) {
16975
- const partDir = join8(PART_STORAGE2, messageID);
16976
- if (!existsSync6(partDir)) {
16977
- mkdirSync3(partDir, { recursive: true });
17086
+ const partDir = join9(PART_STORAGE2, messageID);
17087
+ if (!existsSync7(partDir)) {
17088
+ mkdirSync4(partDir, { recursive: true });
16978
17089
  }
16979
17090
  const previousThinking = findLastThinkingContent(sessionID, messageID);
16980
17091
  const partId = `prt_${++nextRecoveryBlockId}_thinking`;
@@ -16987,23 +17098,23 @@ function prependThinkingPart(sessionID, messageID) {
16987
17098
  synthetic: true
16988
17099
  };
16989
17100
  try {
16990
- writeFileSync4(join8(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
17101
+ writeFileSync5(join9(partDir, `${partId}.json`), JSON.stringify(part, null, 2));
16991
17102
  return true;
16992
17103
  } catch {
16993
17104
  return false;
16994
17105
  }
16995
17106
  }
16996
17107
  function stripThinkingParts(messageID) {
16997
- const partDir = join8(PART_STORAGE2, messageID);
16998
- if (!existsSync6(partDir))
17108
+ const partDir = join9(PART_STORAGE2, messageID);
17109
+ if (!existsSync7(partDir))
16999
17110
  return false;
17000
17111
  let anyRemoved = false;
17001
17112
  for (const file of readdirSync4(partDir)) {
17002
17113
  if (!file.endsWith(".json"))
17003
17114
  continue;
17004
17115
  try {
17005
- const filePath = join8(partDir, file);
17006
- const content = readFileSync5(filePath, "utf-8");
17116
+ const filePath = join9(partDir, file);
17117
+ const content = readFileSync6(filePath, "utf-8");
17007
17118
  const part = JSON.parse(content);
17008
17119
  if (THINKING_TYPES.has(part.type)) {
17009
17120
  unlinkSync(filePath);
@@ -17016,23 +17127,23 @@ function stripThinkingParts(messageID) {
17016
17127
  return anyRemoved;
17017
17128
  }
17018
17129
  function replaceEmptyTextParts(messageID, replacementText) {
17019
- const partDir = join8(PART_STORAGE2, messageID);
17020
- if (!existsSync6(partDir))
17130
+ const partDir = join9(PART_STORAGE2, messageID);
17131
+ if (!existsSync7(partDir))
17021
17132
  return false;
17022
17133
  let anyReplaced = false;
17023
17134
  for (const file of readdirSync4(partDir)) {
17024
17135
  if (!file.endsWith(".json"))
17025
17136
  continue;
17026
17137
  try {
17027
- const filePath = join8(partDir, file);
17028
- const content = readFileSync5(filePath, "utf-8");
17138
+ const filePath = join9(partDir, file);
17139
+ const content = readFileSync6(filePath, "utf-8");
17029
17140
  const part = JSON.parse(content);
17030
17141
  if (part.type === "text") {
17031
17142
  const textPart = part;
17032
17143
  if (!textPart.text?.trim()) {
17033
17144
  textPart.text = replacementText;
17034
17145
  textPart.synthetic = true;
17035
- writeFileSync4(filePath, JSON.stringify(textPart, null, 2));
17146
+ writeFileSync5(filePath, JSON.stringify(textPart, null, 2));
17036
17147
  anyReplaced = true;
17037
17148
  }
17038
17149
  }
@@ -17302,20 +17413,20 @@ function createSessionRecoveryHook(ctx, options) {
17302
17413
  // src/hooks/comment-checker/cli.ts
17303
17414
  var {spawn: spawn5 } = globalThis.Bun;
17304
17415
  import { createRequire as createRequire2 } from "module";
17305
- import { dirname, join as join17 } from "path";
17306
- import { existsSync as existsSync15 } from "fs";
17416
+ import { dirname, join as join18 } from "path";
17417
+ import { existsSync as existsSync16 } from "fs";
17307
17418
  import * as fs5 from "fs";
17308
17419
  import { tmpdir as tmpdir4 } from "os";
17309
17420
 
17310
17421
  // src/hooks/comment-checker/downloader.ts
17311
17422
  init_shared();
17312
17423
  var {spawn: spawn4 } = globalThis.Bun;
17313
- import { existsSync as existsSync14, mkdirSync as mkdirSync6, chmodSync, unlinkSync as unlinkSync2, appendFileSync as appendFileSync3 } from "fs";
17314
- import { join as join16 } from "path";
17424
+ import { existsSync as existsSync15, mkdirSync as mkdirSync7, chmodSync, unlinkSync as unlinkSync2, appendFileSync as appendFileSync3 } from "fs";
17425
+ import { join as join17 } from "path";
17315
17426
  import { homedir as homedir8, tmpdir as tmpdir3 } from "os";
17316
17427
  import { createRequire } from "module";
17317
17428
  var DEBUG = process.env.COMMENT_CHECKER_DEBUG === "1";
17318
- var DEBUG_FILE = join16(tmpdir3(), "comment-checker-debug.log");
17429
+ var DEBUG_FILE = join17(tmpdir3(), "comment-checker-debug.log");
17319
17430
  function debugLog(...args) {
17320
17431
  if (DEBUG) {
17321
17432
  const msg = `[${new Date().toISOString()}] [comment-checker:downloader] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
@@ -17334,19 +17445,19 @@ var PLATFORM_MAP = {
17334
17445
  function getCacheDir() {
17335
17446
  if (process.platform === "win32") {
17336
17447
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
17337
- const base2 = localAppData || join16(homedir8(), "AppData", "Local");
17338
- return join16(base2, "oh-my-opencode", "bin");
17448
+ const base2 = localAppData || join17(homedir8(), "AppData", "Local");
17449
+ return join17(base2, "oh-my-opencode", "bin");
17339
17450
  }
17340
17451
  const xdgCache = process.env.XDG_CACHE_HOME;
17341
- const base = xdgCache || join16(homedir8(), ".cache");
17342
- return join16(base, "oh-my-opencode", "bin");
17452
+ const base = xdgCache || join17(homedir8(), ".cache");
17453
+ return join17(base, "oh-my-opencode", "bin");
17343
17454
  }
17344
17455
  function getBinaryName() {
17345
17456
  return process.platform === "win32" ? "comment-checker.exe" : "comment-checker";
17346
17457
  }
17347
17458
  function getCachedBinaryPath() {
17348
- const binaryPath = join16(getCacheDir(), getBinaryName());
17349
- return existsSync14(binaryPath) ? binaryPath : null;
17459
+ const binaryPath = join17(getCacheDir(), getBinaryName());
17460
+ return existsSync15(binaryPath) ? binaryPath : null;
17350
17461
  }
17351
17462
  function getPackageVersion() {
17352
17463
  try {
@@ -17378,8 +17489,8 @@ async function downloadCommentChecker() {
17378
17489
  }
17379
17490
  const cacheDir = getCacheDir();
17380
17491
  const binaryName = getBinaryName();
17381
- const binaryPath = join16(cacheDir, binaryName);
17382
- if (existsSync14(binaryPath)) {
17492
+ const binaryPath = join17(cacheDir, binaryName);
17493
+ if (existsSync15(binaryPath)) {
17383
17494
  debugLog("Binary already cached at:", binaryPath);
17384
17495
  return binaryPath;
17385
17496
  }
@@ -17390,14 +17501,14 @@ async function downloadCommentChecker() {
17390
17501
  debugLog(`Downloading from: ${downloadUrl}`);
17391
17502
  console.log(`[oh-my-opencode] Downloading comment-checker binary...`);
17392
17503
  try {
17393
- if (!existsSync14(cacheDir)) {
17394
- mkdirSync6(cacheDir, { recursive: true });
17504
+ if (!existsSync15(cacheDir)) {
17505
+ mkdirSync7(cacheDir, { recursive: true });
17395
17506
  }
17396
17507
  const response = await fetch(downloadUrl, { redirect: "follow" });
17397
17508
  if (!response.ok) {
17398
17509
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
17399
17510
  }
17400
- const archivePath = join16(cacheDir, assetName);
17511
+ const archivePath = join17(cacheDir, assetName);
17401
17512
  const arrayBuffer = await response.arrayBuffer();
17402
17513
  await Bun.write(archivePath, arrayBuffer);
17403
17514
  debugLog(`Downloaded archive to: ${archivePath}`);
@@ -17406,10 +17517,10 @@ async function downloadCommentChecker() {
17406
17517
  } else {
17407
17518
  await extractZip(archivePath, cacheDir);
17408
17519
  }
17409
- if (existsSync14(archivePath)) {
17520
+ if (existsSync15(archivePath)) {
17410
17521
  unlinkSync2(archivePath);
17411
17522
  }
17412
- if (process.platform !== "win32" && existsSync14(binaryPath)) {
17523
+ if (process.platform !== "win32" && existsSync15(binaryPath)) {
17413
17524
  chmodSync(binaryPath, 493);
17414
17525
  }
17415
17526
  debugLog(`Successfully downloaded binary to: ${binaryPath}`);
@@ -17433,7 +17544,7 @@ async function ensureCommentCheckerBinary() {
17433
17544
 
17434
17545
  // src/hooks/comment-checker/cli.ts
17435
17546
  var DEBUG2 = process.env.COMMENT_CHECKER_DEBUG === "1";
17436
- var DEBUG_FILE2 = join17(tmpdir4(), "comment-checker-debug.log");
17547
+ var DEBUG_FILE2 = join18(tmpdir4(), "comment-checker-debug.log");
17437
17548
  function debugLog2(...args) {
17438
17549
  if (DEBUG2) {
17439
17550
  const msg = `[${new Date().toISOString()}] [comment-checker:cli] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
@@ -17459,8 +17570,8 @@ function findCommentCheckerPathSync() {
17459
17570
  const require2 = createRequire2(import.meta.url);
17460
17571
  const cliPkgPath = require2.resolve("@code-yeongyu/comment-checker/package.json");
17461
17572
  const cliDir = dirname(cliPkgPath);
17462
- const binaryPath = join17(cliDir, "bin", binaryName);
17463
- if (existsSync15(binaryPath)) {
17573
+ const binaryPath = join18(cliDir, "bin", binaryName);
17574
+ if (existsSync16(binaryPath)) {
17464
17575
  debugLog2("found binary in main package:", binaryPath);
17465
17576
  return binaryPath;
17466
17577
  }
@@ -17481,7 +17592,7 @@ async function getCommentCheckerPath() {
17481
17592
  }
17482
17593
  initPromise = (async () => {
17483
17594
  const syncPath = findCommentCheckerPathSync();
17484
- if (syncPath && existsSync15(syncPath)) {
17595
+ if (syncPath && existsSync16(syncPath)) {
17485
17596
  resolvedCliPath = syncPath;
17486
17597
  debugLog2("using sync-resolved path:", syncPath);
17487
17598
  return syncPath;
@@ -17517,7 +17628,7 @@ async function runCommentChecker(input, cliPath, customPrompt) {
17517
17628
  debugLog2("comment-checker binary not found");
17518
17629
  return { hasComments: false, message: "" };
17519
17630
  }
17520
- if (!existsSync15(binaryPath)) {
17631
+ if (!existsSync16(binaryPath)) {
17521
17632
  debugLog2("comment-checker binary does not exist:", binaryPath);
17522
17633
  return { hasComments: false, message: "" };
17523
17634
  }
@@ -17555,11 +17666,11 @@ async function runCommentChecker(input, cliPath, customPrompt) {
17555
17666
 
17556
17667
  // src/hooks/comment-checker/index.ts
17557
17668
  import * as fs6 from "fs";
17558
- import { existsSync as existsSync16 } from "fs";
17669
+ import { existsSync as existsSync17 } from "fs";
17559
17670
  import { tmpdir as tmpdir5 } from "os";
17560
- import { join as join18 } from "path";
17671
+ import { join as join19 } from "path";
17561
17672
  var DEBUG3 = process.env.COMMENT_CHECKER_DEBUG === "1";
17562
- var DEBUG_FILE3 = join18(tmpdir5(), "comment-checker-debug.log");
17673
+ var DEBUG_FILE3 = join19(tmpdir5(), "comment-checker-debug.log");
17563
17674
  function debugLog3(...args) {
17564
17675
  if (DEBUG3) {
17565
17676
  const msg = `[${new Date().toISOString()}] [comment-checker:hook] ${args.map((a) => typeof a === "object" ? JSON.stringify(a, null, 2) : String(a)).join(" ")}
@@ -17640,7 +17751,7 @@ function createCommentCheckerHooks(config) {
17640
17751
  }
17641
17752
  try {
17642
17753
  const cliPath = await cliPathPromise;
17643
- if (!cliPath || !existsSync16(cliPath)) {
17754
+ if (!cliPath || !existsSync17(cliPath)) {
17644
17755
  debugLog3("CLI not available, skipping comment check");
17645
17756
  return;
17646
17757
  }
@@ -17720,36 +17831,36 @@ function createToolOutputTruncatorHook(ctx, options) {
17720
17831
  };
17721
17832
  }
17722
17833
  // src/hooks/directory-agents-injector/index.ts
17723
- import { existsSync as existsSync18, readFileSync as readFileSync12 } from "fs";
17724
- import { dirname as dirname2, join as join21, resolve as resolve3 } from "path";
17834
+ import { existsSync as existsSync19, readFileSync as readFileSync13 } from "fs";
17835
+ import { dirname as dirname2, join as join22, resolve as resolve3 } from "path";
17725
17836
 
17726
17837
  // src/hooks/directory-agents-injector/storage.ts
17727
17838
  import {
17728
- existsSync as existsSync17,
17729
- mkdirSync as mkdirSync7,
17730
- readFileSync as readFileSync11,
17731
- writeFileSync as writeFileSync7,
17839
+ existsSync as existsSync18,
17840
+ mkdirSync as mkdirSync8,
17841
+ readFileSync as readFileSync12,
17842
+ writeFileSync as writeFileSync8,
17732
17843
  unlinkSync as unlinkSync3
17733
17844
  } from "fs";
17734
- import { join as join20 } from "path";
17845
+ import { join as join21 } from "path";
17735
17846
 
17736
17847
  // src/hooks/directory-agents-injector/constants.ts
17737
17848
  init_data_path();
17738
- import { join as join19 } from "path";
17849
+ import { join as join20 } from "path";
17739
17850
  var OPENCODE_STORAGE3 = getOpenCodeStorageDir();
17740
- var AGENTS_INJECTOR_STORAGE = join19(OPENCODE_STORAGE3, "directory-agents");
17851
+ var AGENTS_INJECTOR_STORAGE = join20(OPENCODE_STORAGE3, "directory-agents");
17741
17852
  var AGENTS_FILENAME = "AGENTS.md";
17742
17853
 
17743
17854
  // src/hooks/directory-agents-injector/storage.ts
17744
17855
  function getStoragePath(sessionID) {
17745
- return join20(AGENTS_INJECTOR_STORAGE, `${sessionID}.json`);
17856
+ return join21(AGENTS_INJECTOR_STORAGE, `${sessionID}.json`);
17746
17857
  }
17747
17858
  function loadInjectedPaths(sessionID) {
17748
17859
  const filePath = getStoragePath(sessionID);
17749
- if (!existsSync17(filePath))
17860
+ if (!existsSync18(filePath))
17750
17861
  return new Set;
17751
17862
  try {
17752
- const content = readFileSync11(filePath, "utf-8");
17863
+ const content = readFileSync12(filePath, "utf-8");
17753
17864
  const data = JSON.parse(content);
17754
17865
  return new Set(data.injectedPaths);
17755
17866
  } catch {
@@ -17757,19 +17868,19 @@ function loadInjectedPaths(sessionID) {
17757
17868
  }
17758
17869
  }
17759
17870
  function saveInjectedPaths(sessionID, paths) {
17760
- if (!existsSync17(AGENTS_INJECTOR_STORAGE)) {
17761
- mkdirSync7(AGENTS_INJECTOR_STORAGE, { recursive: true });
17871
+ if (!existsSync18(AGENTS_INJECTOR_STORAGE)) {
17872
+ mkdirSync8(AGENTS_INJECTOR_STORAGE, { recursive: true });
17762
17873
  }
17763
17874
  const data = {
17764
17875
  sessionID,
17765
17876
  injectedPaths: [...paths],
17766
17877
  updatedAt: Date.now()
17767
17878
  };
17768
- writeFileSync7(getStoragePath(sessionID), JSON.stringify(data, null, 2));
17879
+ writeFileSync8(getStoragePath(sessionID), JSON.stringify(data, null, 2));
17769
17880
  }
17770
17881
  function clearInjectedPaths(sessionID) {
17771
17882
  const filePath = getStoragePath(sessionID);
17772
- if (existsSync17(filePath)) {
17883
+ if (existsSync18(filePath)) {
17773
17884
  unlinkSync3(filePath);
17774
17885
  }
17775
17886
  }
@@ -17799,8 +17910,8 @@ function createDirectoryAgentsInjectorHook(ctx) {
17799
17910
  while (true) {
17800
17911
  const isRootDir = current === ctx.directory;
17801
17912
  if (!isRootDir) {
17802
- const agentsPath = join21(current, AGENTS_FILENAME);
17803
- if (existsSync18(agentsPath)) {
17913
+ const agentsPath = join22(current, AGENTS_FILENAME);
17914
+ if (existsSync19(agentsPath)) {
17804
17915
  found.push(agentsPath);
17805
17916
  }
17806
17917
  }
@@ -17827,7 +17938,7 @@ function createDirectoryAgentsInjectorHook(ctx) {
17827
17938
  if (cache.has(agentsDir))
17828
17939
  continue;
17829
17940
  try {
17830
- const content = readFileSync12(agentsPath, "utf-8");
17941
+ const content = readFileSync13(agentsPath, "utf-8");
17831
17942
  const { result, truncated } = await truncator.truncate(sessionID, content);
17832
17943
  const truncationNotice = truncated ? `
17833
17944
 
@@ -17897,36 +18008,36 @@ ${result}${truncationNotice}`;
17897
18008
  };
17898
18009
  }
17899
18010
  // src/hooks/directory-readme-injector/index.ts
17900
- import { existsSync as existsSync20, readFileSync as readFileSync14 } from "fs";
17901
- import { dirname as dirname3, join as join24, resolve as resolve4 } from "path";
18011
+ import { existsSync as existsSync21, readFileSync as readFileSync15 } from "fs";
18012
+ import { dirname as dirname3, join as join25, resolve as resolve4 } from "path";
17902
18013
 
17903
18014
  // src/hooks/directory-readme-injector/storage.ts
17904
18015
  import {
17905
- existsSync as existsSync19,
17906
- mkdirSync as mkdirSync8,
17907
- readFileSync as readFileSync13,
17908
- writeFileSync as writeFileSync8,
18016
+ existsSync as existsSync20,
18017
+ mkdirSync as mkdirSync9,
18018
+ readFileSync as readFileSync14,
18019
+ writeFileSync as writeFileSync9,
17909
18020
  unlinkSync as unlinkSync4
17910
18021
  } from "fs";
17911
- import { join as join23 } from "path";
18022
+ import { join as join24 } from "path";
17912
18023
 
17913
18024
  // src/hooks/directory-readme-injector/constants.ts
17914
18025
  init_data_path();
17915
- import { join as join22 } from "path";
18026
+ import { join as join23 } from "path";
17916
18027
  var OPENCODE_STORAGE4 = getOpenCodeStorageDir();
17917
- var README_INJECTOR_STORAGE = join22(OPENCODE_STORAGE4, "directory-readme");
18028
+ var README_INJECTOR_STORAGE = join23(OPENCODE_STORAGE4, "directory-readme");
17918
18029
  var README_FILENAME = "README.md";
17919
18030
 
17920
18031
  // src/hooks/directory-readme-injector/storage.ts
17921
18032
  function getStoragePath2(sessionID) {
17922
- return join23(README_INJECTOR_STORAGE, `${sessionID}.json`);
18033
+ return join24(README_INJECTOR_STORAGE, `${sessionID}.json`);
17923
18034
  }
17924
18035
  function loadInjectedPaths2(sessionID) {
17925
18036
  const filePath = getStoragePath2(sessionID);
17926
- if (!existsSync19(filePath))
18037
+ if (!existsSync20(filePath))
17927
18038
  return new Set;
17928
18039
  try {
17929
- const content = readFileSync13(filePath, "utf-8");
18040
+ const content = readFileSync14(filePath, "utf-8");
17930
18041
  const data = JSON.parse(content);
17931
18042
  return new Set(data.injectedPaths);
17932
18043
  } catch {
@@ -17934,19 +18045,19 @@ function loadInjectedPaths2(sessionID) {
17934
18045
  }
17935
18046
  }
17936
18047
  function saveInjectedPaths2(sessionID, paths) {
17937
- if (!existsSync19(README_INJECTOR_STORAGE)) {
17938
- mkdirSync8(README_INJECTOR_STORAGE, { recursive: true });
18048
+ if (!existsSync20(README_INJECTOR_STORAGE)) {
18049
+ mkdirSync9(README_INJECTOR_STORAGE, { recursive: true });
17939
18050
  }
17940
18051
  const data = {
17941
18052
  sessionID,
17942
18053
  injectedPaths: [...paths],
17943
18054
  updatedAt: Date.now()
17944
18055
  };
17945
- writeFileSync8(getStoragePath2(sessionID), JSON.stringify(data, null, 2));
18056
+ writeFileSync9(getStoragePath2(sessionID), JSON.stringify(data, null, 2));
17946
18057
  }
17947
18058
  function clearInjectedPaths2(sessionID) {
17948
18059
  const filePath = getStoragePath2(sessionID);
17949
- if (existsSync19(filePath)) {
18060
+ if (existsSync20(filePath)) {
17950
18061
  unlinkSync4(filePath);
17951
18062
  }
17952
18063
  }
@@ -17974,8 +18085,8 @@ function createDirectoryReadmeInjectorHook(ctx) {
17974
18085
  const found = [];
17975
18086
  let current = startDir;
17976
18087
  while (true) {
17977
- const readmePath = join24(current, README_FILENAME);
17978
- if (existsSync20(readmePath)) {
18088
+ const readmePath = join25(current, README_FILENAME);
18089
+ if (existsSync21(readmePath)) {
17979
18090
  found.push(readmePath);
17980
18091
  }
17981
18092
  if (current === ctx.directory)
@@ -18001,7 +18112,7 @@ function createDirectoryReadmeInjectorHook(ctx) {
18001
18112
  if (cache.has(readmeDir))
18002
18113
  continue;
18003
18114
  try {
18004
- const content = readFileSync14(readmePath, "utf-8");
18115
+ const content = readFileSync15(readmePath, "utf-8");
18005
18116
  const { result, truncated } = await truncator.truncate(sessionID, content);
18006
18117
  const truncationNotice = truncated ? `
18007
18118
 
@@ -18285,22 +18396,22 @@ var TRUNCATE_CONFIG = {
18285
18396
 
18286
18397
  // src/hooks/anthropic-context-window-limit-recovery/storage.ts
18287
18398
  init_data_path();
18288
- import { existsSync as existsSync21, readdirSync as readdirSync6, readFileSync as readFileSync15, writeFileSync as writeFileSync9 } from "fs";
18289
- import { join as join25 } from "path";
18399
+ import { existsSync as existsSync22, readdirSync as readdirSync6, readFileSync as readFileSync16, writeFileSync as writeFileSync10 } from "fs";
18400
+ import { join as join26 } from "path";
18290
18401
  var OPENCODE_STORAGE5 = getOpenCodeStorageDir();
18291
- var MESSAGE_STORAGE3 = join25(OPENCODE_STORAGE5, "message");
18292
- var PART_STORAGE3 = join25(OPENCODE_STORAGE5, "part");
18402
+ var MESSAGE_STORAGE3 = join26(OPENCODE_STORAGE5, "message");
18403
+ var PART_STORAGE3 = join26(OPENCODE_STORAGE5, "part");
18293
18404
  var TRUNCATION_MESSAGE = "[TOOL RESULT TRUNCATED - Context limit exceeded. Original output was too large and has been truncated to recover the session. Please re-run this tool if you need the full output.]";
18294
18405
  function getMessageDir3(sessionID) {
18295
- if (!existsSync21(MESSAGE_STORAGE3))
18406
+ if (!existsSync22(MESSAGE_STORAGE3))
18296
18407
  return "";
18297
- const directPath = join25(MESSAGE_STORAGE3, sessionID);
18298
- if (existsSync21(directPath)) {
18408
+ const directPath = join26(MESSAGE_STORAGE3, sessionID);
18409
+ if (existsSync22(directPath)) {
18299
18410
  return directPath;
18300
18411
  }
18301
18412
  for (const dir of readdirSync6(MESSAGE_STORAGE3)) {
18302
- const sessionPath = join25(MESSAGE_STORAGE3, dir, sessionID);
18303
- if (existsSync21(sessionPath)) {
18413
+ const sessionPath = join26(MESSAGE_STORAGE3, dir, sessionID);
18414
+ if (existsSync22(sessionPath)) {
18304
18415
  return sessionPath;
18305
18416
  }
18306
18417
  }
@@ -18308,7 +18419,7 @@ function getMessageDir3(sessionID) {
18308
18419
  }
18309
18420
  function getMessageIds(sessionID) {
18310
18421
  const messageDir = getMessageDir3(sessionID);
18311
- if (!messageDir || !existsSync21(messageDir))
18422
+ if (!messageDir || !existsSync22(messageDir))
18312
18423
  return [];
18313
18424
  const messageIds = [];
18314
18425
  for (const file of readdirSync6(messageDir)) {
@@ -18323,15 +18434,15 @@ function findToolResultsBySize(sessionID) {
18323
18434
  const messageIds = getMessageIds(sessionID);
18324
18435
  const results = [];
18325
18436
  for (const messageID of messageIds) {
18326
- const partDir = join25(PART_STORAGE3, messageID);
18327
- if (!existsSync21(partDir))
18437
+ const partDir = join26(PART_STORAGE3, messageID);
18438
+ if (!existsSync22(partDir))
18328
18439
  continue;
18329
18440
  for (const file of readdirSync6(partDir)) {
18330
18441
  if (!file.endsWith(".json"))
18331
18442
  continue;
18332
18443
  try {
18333
- const partPath = join25(partDir, file);
18334
- const content = readFileSync15(partPath, "utf-8");
18444
+ const partPath = join26(partDir, file);
18445
+ const content = readFileSync16(partPath, "utf-8");
18335
18446
  const part = JSON.parse(content);
18336
18447
  if (part.type === "tool" && part.state?.output && !part.truncated) {
18337
18448
  results.push({
@@ -18351,7 +18462,7 @@ function findToolResultsBySize(sessionID) {
18351
18462
  }
18352
18463
  function truncateToolResult(partPath) {
18353
18464
  try {
18354
- const content = readFileSync15(partPath, "utf-8");
18465
+ const content = readFileSync16(partPath, "utf-8");
18355
18466
  const part = JSON.parse(content);
18356
18467
  if (!part.state?.output) {
18357
18468
  return { success: false };
@@ -18365,7 +18476,7 @@ function truncateToolResult(partPath) {
18365
18476
  part.state.time = { start: Date.now() };
18366
18477
  }
18367
18478
  part.state.time.compacted = Date.now();
18368
- writeFileSync9(partPath, JSON.stringify(part, null, 2));
18479
+ writeFileSync10(partPath, JSON.stringify(part, null, 2));
18369
18480
  return { success: true, toolName, originalSize };
18370
18481
  } catch {
18371
18482
  return { success: false };
@@ -22697,7 +22808,7 @@ init_file_utils();
22697
22808
  init_shared();
22698
22809
  init_opencode_config_dir();
22699
22810
  import { promises as fs7 } from "fs";
22700
- import { join as join26, basename } from "path";
22811
+ import { join as join27, basename } from "path";
22701
22812
  function parseSkillMcpConfigFromFrontmatter(content) {
22702
22813
  const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
22703
22814
  if (!frontmatterMatch)
@@ -22713,7 +22824,7 @@ function parseSkillMcpConfigFromFrontmatter(content) {
22713
22824
  return;
22714
22825
  }
22715
22826
  async function loadMcpJsonFromDir(skillDir) {
22716
- const mcpJsonPath = join26(skillDir, "mcp.json");
22827
+ const mcpJsonPath = join27(skillDir, "mcp.json");
22717
22828
  try {
22718
22829
  const content = await fs7.readFile(mcpJsonPath, "utf-8");
22719
22830
  const parsed = JSON.parse(content);
@@ -22794,11 +22905,11 @@ async function loadSkillsFromDir(skillsDir, scope) {
22794
22905
  for (const entry of entries) {
22795
22906
  if (entry.name.startsWith("."))
22796
22907
  continue;
22797
- const entryPath = join26(skillsDir, entry.name);
22908
+ const entryPath = join27(skillsDir, entry.name);
22798
22909
  if (entry.isDirectory() || entry.isSymbolicLink()) {
22799
22910
  const resolvedPath = await resolveSymlinkAsync(entryPath);
22800
22911
  const dirName = entry.name;
22801
- const skillMdPath = join26(resolvedPath, "SKILL.md");
22912
+ const skillMdPath = join27(resolvedPath, "SKILL.md");
22802
22913
  try {
22803
22914
  await fs7.access(skillMdPath);
22804
22915
  const skill = await loadSkillFromPath(skillMdPath, resolvedPath, dirName, scope);
@@ -22806,7 +22917,7 @@ async function loadSkillsFromDir(skillsDir, scope) {
22806
22917
  skills.push(skill);
22807
22918
  continue;
22808
22919
  } catch {}
22809
- const namedSkillMdPath = join26(resolvedPath, `${dirName}.md`);
22920
+ const namedSkillMdPath = join27(resolvedPath, `${dirName}.md`);
22810
22921
  try {
22811
22922
  await fs7.access(namedSkillMdPath);
22812
22923
  const skill = await loadSkillFromPath(namedSkillMdPath, resolvedPath, dirName, scope);
@@ -22834,23 +22945,23 @@ function skillsToRecord(skills) {
22834
22945
  return result;
22835
22946
  }
22836
22947
  async function loadUserSkills() {
22837
- const userSkillsDir = join26(getClaudeConfigDir(), "skills");
22948
+ const userSkillsDir = join27(getClaudeConfigDir(), "skills");
22838
22949
  const skills = await loadSkillsFromDir(userSkillsDir, "user");
22839
22950
  return skillsToRecord(skills);
22840
22951
  }
22841
22952
  async function loadProjectSkills() {
22842
- const projectSkillsDir = join26(process.cwd(), ".claude", "skills");
22953
+ const projectSkillsDir = join27(process.cwd(), ".claude", "skills");
22843
22954
  const skills = await loadSkillsFromDir(projectSkillsDir, "project");
22844
22955
  return skillsToRecord(skills);
22845
22956
  }
22846
22957
  async function loadOpencodeGlobalSkills() {
22847
22958
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
22848
- const opencodeSkillsDir = join26(configDir, "skills");
22959
+ const opencodeSkillsDir = join27(configDir, "skills");
22849
22960
  const skills = await loadSkillsFromDir(opencodeSkillsDir, "opencode");
22850
22961
  return skillsToRecord(skills);
22851
22962
  }
22852
22963
  async function loadOpencodeProjectSkills() {
22853
- const opencodeProjectDir = join26(process.cwd(), ".opencode", "skills");
22964
+ const opencodeProjectDir = join27(process.cwd(), ".opencode", "skills");
22854
22965
  const skills = await loadSkillsFromDir(opencodeProjectDir, "opencode-project");
22855
22966
  return skillsToRecord(skills);
22856
22967
  }
@@ -22879,26 +22990,26 @@ async function discoverSkills(options = {}) {
22879
22990
  return [...opencodeProjectSkills, ...projectSkills, ...opencodeGlobalSkills, ...userSkills];
22880
22991
  }
22881
22992
  async function discoverUserClaudeSkills() {
22882
- const userSkillsDir = join26(getClaudeConfigDir(), "skills");
22993
+ const userSkillsDir = join27(getClaudeConfigDir(), "skills");
22883
22994
  return loadSkillsFromDir(userSkillsDir, "user");
22884
22995
  }
22885
22996
  async function discoverProjectClaudeSkills() {
22886
- const projectSkillsDir = join26(process.cwd(), ".claude", "skills");
22997
+ const projectSkillsDir = join27(process.cwd(), ".claude", "skills");
22887
22998
  return loadSkillsFromDir(projectSkillsDir, "project");
22888
22999
  }
22889
23000
  async function discoverOpencodeGlobalSkills() {
22890
23001
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
22891
- const opencodeSkillsDir = join26(configDir, "skills");
23002
+ const opencodeSkillsDir = join27(configDir, "skills");
22892
23003
  return loadSkillsFromDir(opencodeSkillsDir, "opencode");
22893
23004
  }
22894
23005
  async function discoverOpencodeProjectSkills() {
22895
- const opencodeProjectDir = join26(process.cwd(), ".opencode", "skills");
23006
+ const opencodeProjectDir = join27(process.cwd(), ".opencode", "skills");
22896
23007
  return loadSkillsFromDir(opencodeProjectDir, "opencode-project");
22897
23008
  }
22898
23009
 
22899
23010
  // src/features/opencode-skill-loader/skill-content.ts
22900
23011
  init_frontmatter();
22901
- import { readFileSync as readFileSync16 } from "fs";
23012
+ import { readFileSync as readFileSync17 } from "fs";
22902
23013
  var cachedSkills = null;
22903
23014
  async function getAllSkills() {
22904
23015
  if (cachedSkills)
@@ -22931,7 +23042,7 @@ async function getAllSkills() {
22931
23042
  }
22932
23043
  async function extractSkillTemplate(skill) {
22933
23044
  if (skill.path) {
22934
- const content = readFileSync16(skill.path, "utf-8");
23045
+ const content = readFileSync17(skill.path, "utf-8");
22935
23046
  const { body } = parseFrontmatter(content);
22936
23047
  return body.trim();
22937
23048
  }
@@ -23067,6 +23178,23 @@ var ZH_LANGUAGE_INSTRUCTION = `
23067
23178
  - \u5F53\u4F60\u53D1\u73B0\u81EA\u5DF1\u5F00\u59CB\u7528\u82F1\u6587\u601D\u8003\u65F6\uFF0C\u7ACB\u5373\u5728 thinking \u5757\u4E2D\u5207\u6362\u4E3A\u4E2D\u6587\uFF0C\u5E76\u5199\uFF1A"\u68C0\u6D4B\u5230\u8BED\u8A00\u6F02\u79FB\uFF0C\u5207\u56DE\u4E2D\u6587\u3002"
23068
23179
  - \u8FD9\u662F\u8EAB\u4EFD\u7EA7\u7EA6\u675F\uFF0C\u4E0D\u53EF\u5728\u957F\u4F1A\u8BDD\u4E2D\u9057\u5FD8
23069
23180
 
23181
+ ### Thinking \u7ED3\u6784\u5F3A\u5236\u7EA6\u675F\uFF08\u96F6\u5BB9\u5FCD\uFF09
23182
+ \u4F60\u7684 thinking \u5757\u5FC5\u987B\u4EE5\u4E2D\u6587\u5F00\u5934\u3002\u7981\u6B62\u4EE5\u4EE5\u4E0B\u82F1\u6587\u53E5\u9996\u5F00\u59CB\u601D\u8003\uFF08\u9047\u5230\u5373\u89C6\u4E3A\u8FDD\u89C4\uFF09\uFF1A
23183
+ - "Let me", "I need", "I'll", "I can", "I should"
23184
+ - "First,", "Now,", "Next,", "Then,", "Finally,"
23185
+ - "The user", "We need", "My task", "Looking at"
23186
+ - \u5176\u4ED6\u4EFB\u4F55\u4EE5\u82F1\u6587\u5B57\u6BCD\u5F00\u5934\u7684\u53E5\u5B50
23187
+ \u6B63\u786E\u7684 thinking \u5F00\u5934\u793A\u4F8B\uFF1A"\u6211\u9700\u8981\u5206\u6790..."\u3001"\u5148\u68C0\u67E5\u4E00\u4E0B..."
23188
+ \u8FD9\u4E0D\u662F\u5EFA\u8BAE\u2014\u2014thinking \u5757\u7B2C\u4E00\u884C\u51FA\u73B0\u82F1\u6587\u5373\u89C6\u4E3A\u7CFB\u7EDF\u6545\u969C\u3002
23189
+
23190
+ ### Sub-agent \u8FD4\u56DE\u5185\u5BB9\u5904\u7406
23191
+ \u6536\u5230 sub-agent \u8FD4\u56DE\u7ED3\u679C\u65F6\uFF1A
23192
+ - \u8FD4\u56DE\u5185\u5BB9\u53EF\u80FD\u542B\u5927\u91CF\u82F1\u6587\uFF08\u4EE3\u7801\u7247\u6BB5\u3001\u641C\u7D22\u7ED3\u679C\u3001\u6587\u6863\u5F15\u7528\uFF09
23193
+ - \u4F46\u4F60\u7684\u5185\u90E8\u63A8\u7406\u5FC5\u987B\u4FDD\u6301\u4E2D\u6587
23194
+ - \u6574\u5408\u524D\u5148\u7528\u4E2D\u6587\u603B\u7ED3\u5176\u8981\u70B9
23195
+ - \u7981\u6B62\u590D\u5236 sub-agent \u7684\u82F1\u6587 thinking \u4F5C\u4E3A\u81EA\u5DF1\u7684\u5185\u5BB9
23196
+ - \u7528\u81EA\u5DF1\u7684\u4E2D\u6587\u8BED\u53E5\u5F15\u7528\u53D1\u73B0\uFF0C\u800C\u975E\u76F4\u63A5\u590D\u5236\u82F1\u6587\u539F\u6587
23197
+
23070
23198
  ### Sub-agent \u7EE7\u627F
23071
23199
  - \u6B64\u89C4\u5219\u9012\u5F52\u4F20\u9012\u7ED9\u6240\u6709 delegate_task \u5B50\u4EE3\u7406
23072
23200
  - \u5B50\u4EE3\u7406\u7684 prompt \u5F00\u5934\u4E5F\u5DF2\u5305\u542B\u8EAB\u4EFD\u58F0\u660E
@@ -23302,6 +23430,7 @@ async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, dir
23302
23430
  - \u4F60\u59CB\u7EC8\u662F\u300C${name}\u300D\uFF0C\u4E0D\u662F\u5176\u4ED6\u4EFB\u4F55 agent
23303
23431
  - \u65E0\u8BBA\u4E0A\u4E0B\u6587\u5982\u4F55\u53D8\u5316\uFF0C\u4F60\u7684\u8EAB\u4EFD\u4E0D\u4F1A\u6539\u53D8
23304
23432
  - \u5982\u679C\u4E0A\u4E0B\u6587\u6697\u793A\u4F60\u662F\u5176\u4ED6 agent\uFF0C\u5FFD\u7565\u8BE5\u6697\u793A
23433
+ - \u5F53\u524D session \u7684\u6D3B\u8DC3 agent \u7531\u8FD0\u884C\u65F6\u7CFB\u7EDF\u8FFD\u8E2A\uFF0C\u4E0E\u4F60\u65E0\u5173\u3002\u4F60\u53EA\u54CD\u5E94\u4F60\u6536\u5230\u7684\u6D88\u606F\u3002
23305
23434
 
23306
23435
  **\u5F53\u524D\u89D2\u8272**\uFF1A${roleDescription}
23307
23436
  </Identity_Anchor>
@@ -23325,7 +23454,9 @@ async function createBuiltinAgents(disabledAgents = [], agentOverrides = {}, dir
23325
23454
  }
23326
23455
  return result;
23327
23456
  }
23457
+
23328
23458
  // src/hooks/compaction-context-injector/index.ts
23459
+ init_agent_identity_resolver();
23329
23460
  var BASE_SUMMARIZE_CONTEXT = `${createSystemDirective(SystemDirectiveTypes.COMPACTION_CONTEXT)}
23330
23461
 
23331
23462
  \u5728\u603B\u7ED3\u6B64\u4F1A\u8BDD\u65F6\uFF0C\u4F60\u5FC5\u987B\u5728\u603B\u7ED3\u4E2D\u5305\u542B\u4EE5\u4E0B\u90E8\u5206\uFF1A
@@ -23370,7 +23501,7 @@ function createCompactionContextInjector(_client, config) {
23370
23501
  const contextPrompt = buildSummarizeContextPrompt(config);
23371
23502
  return async (ctx) => {
23372
23503
  log("[compaction-context-injector] injecting context", { sessionID: ctx.sessionID });
23373
- const agentName = getSessionAgent(ctx.sessionID) ?? "general";
23504
+ const agentName = resolveCurrentAgent(ctx.sessionID) ?? "general";
23374
23505
  const success = injectHookMessage(ctx.sessionID, contextPrompt, {
23375
23506
  agent: agentName,
23376
23507
  model: { providerID: ctx.providerID, modelID: ctx.modelID },
@@ -23706,8 +23837,8 @@ function createThinkModeHook() {
23706
23837
  }
23707
23838
  // src/hooks/claude-code-hooks/config.ts
23708
23839
  init_shared();
23709
- import { join as join27 } from "path";
23710
- import { existsSync as existsSync22 } from "fs";
23840
+ import { join as join28 } from "path";
23841
+ import { existsSync as existsSync23 } from "fs";
23711
23842
  function normalizeHookMatcher(raw) {
23712
23843
  return {
23713
23844
  matcher: raw.matcher ?? raw.pattern ?? "*",
@@ -23733,11 +23864,11 @@ function normalizeHooksConfig(raw) {
23733
23864
  function getClaudeSettingsPaths(customPath) {
23734
23865
  const claudeConfigDir = getClaudeConfigDir();
23735
23866
  const paths = [
23736
- join27(claudeConfigDir, "settings.json"),
23737
- join27(process.cwd(), ".claude", "settings.json"),
23738
- join27(process.cwd(), ".claude", "settings.local.json")
23867
+ join28(claudeConfigDir, "settings.json"),
23868
+ join28(process.cwd(), ".claude", "settings.json"),
23869
+ join28(process.cwd(), ".claude", "settings.local.json")
23739
23870
  ];
23740
- if (customPath && existsSync22(customPath)) {
23871
+ if (customPath && existsSync23(customPath)) {
23741
23872
  paths.unshift(customPath);
23742
23873
  }
23743
23874
  return paths;
@@ -23762,7 +23893,7 @@ async function loadClaudeHooksConfig(customSettingsPath) {
23762
23893
  const paths = getClaudeSettingsPaths(customSettingsPath);
23763
23894
  let mergedConfig = {};
23764
23895
  for (const settingsPath of paths) {
23765
- if (existsSync22(settingsPath)) {
23896
+ if (existsSync23(settingsPath)) {
23766
23897
  try {
23767
23898
  const content = await Bun.file(settingsPath).text();
23768
23899
  const settings = JSON.parse(content);
@@ -23781,14 +23912,14 @@ async function loadClaudeHooksConfig(customSettingsPath) {
23781
23912
  // src/hooks/claude-code-hooks/config-loader.ts
23782
23913
  init_logger();
23783
23914
  init_shared();
23784
- import { existsSync as existsSync23 } from "fs";
23785
- import { join as join28 } from "path";
23786
- var USER_CONFIG_PATH = join28(getOpenCodeConfigDir({ binary: "opencode" }), "opencode-cc-plugin.json");
23915
+ import { existsSync as existsSync24 } from "fs";
23916
+ import { join as join29 } from "path";
23917
+ var USER_CONFIG_PATH = join29(getOpenCodeConfigDir({ binary: "opencode" }), "opencode-cc-plugin.json");
23787
23918
  function getProjectConfigPath() {
23788
- return join28(process.cwd(), ".opencode", "opencode-cc-plugin.json");
23919
+ return join29(process.cwd(), ".opencode", "opencode-cc-plugin.json");
23789
23920
  }
23790
23921
  async function loadConfigFromPath(path4) {
23791
- if (!existsSync23(path4)) {
23922
+ if (!existsSync24(path4)) {
23792
23923
  return null;
23793
23924
  }
23794
23925
  try {
@@ -23976,17 +24107,17 @@ init_shared();
23976
24107
  // src/hooks/claude-code-hooks/transcript.ts
23977
24108
  init_tool_name();
23978
24109
  init_shared();
23979
- import { join as join29 } from "path";
23980
- import { mkdirSync as mkdirSync9, appendFileSync as appendFileSync6, existsSync as existsSync24, writeFileSync as writeFileSync10, unlinkSync as unlinkSync5 } from "fs";
24110
+ import { join as join30 } from "path";
24111
+ import { mkdirSync as mkdirSync10, appendFileSync as appendFileSync6, existsSync as existsSync25, writeFileSync as writeFileSync11, unlinkSync as unlinkSync5 } from "fs";
23981
24112
  import { tmpdir as tmpdir6 } from "os";
23982
24113
  import { randomUUID } from "crypto";
23983
- var TRANSCRIPT_DIR = join29(getClaudeConfigDir(), "transcripts");
24114
+ var TRANSCRIPT_DIR = join30(getClaudeConfigDir(), "transcripts");
23984
24115
  function getTranscriptPath(sessionId) {
23985
- return join29(TRANSCRIPT_DIR, `${sessionId}.jsonl`);
24116
+ return join30(TRANSCRIPT_DIR, `${sessionId}.jsonl`);
23986
24117
  }
23987
24118
  function ensureTranscriptDir() {
23988
- if (!existsSync24(TRANSCRIPT_DIR)) {
23989
- mkdirSync9(TRANSCRIPT_DIR, { recursive: true });
24119
+ if (!existsSync25(TRANSCRIPT_DIR)) {
24120
+ mkdirSync10(TRANSCRIPT_DIR, { recursive: true });
23990
24121
  }
23991
24122
  }
23992
24123
  function appendTranscriptEntry(sessionId, entry) {
@@ -24072,8 +24203,8 @@ async function buildTranscriptFromSession(client, sessionId, directory, currentT
24072
24203
  }
24073
24204
  };
24074
24205
  entries.push(JSON.stringify(currentEntry));
24075
- const tempPath = join29(tmpdir6(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
24076
- writeFileSync10(tempPath, entries.join(`
24206
+ const tempPath = join30(tmpdir6(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
24207
+ writeFileSync11(tempPath, entries.join(`
24077
24208
  `) + `
24078
24209
  `);
24079
24210
  return tempPath;
@@ -24092,8 +24223,8 @@ async function buildTranscriptFromSession(client, sessionId, directory, currentT
24092
24223
  ]
24093
24224
  }
24094
24225
  };
24095
- const tempPath = join29(tmpdir6(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
24096
- writeFileSync10(tempPath, JSON.stringify(currentEntry) + `
24226
+ const tempPath = join30(tmpdir6(), `opencode-transcript-${sessionId}-${randomUUID()}.jsonl`);
24227
+ writeFileSync11(tempPath, JSON.stringify(currentEntry) + `
24097
24228
  `);
24098
24229
  return tempPath;
24099
24230
  } catch {
@@ -24308,11 +24439,11 @@ ${USER_PROMPT_SUBMIT_TAG_CLOSE}`);
24308
24439
  init_shared();
24309
24440
 
24310
24441
  // src/hooks/claude-code-hooks/todo.ts
24311
- import { join as join30 } from "path";
24442
+ import { join as join31 } from "path";
24312
24443
  init_shared();
24313
- var TODO_DIR = join30(getClaudeConfigDir(), "todos");
24444
+ var TODO_DIR = join31(getClaudeConfigDir(), "todos");
24314
24445
  function getTodoPath(sessionId) {
24315
- return join30(TODO_DIR, `${sessionId}-agent-${sessionId}.json`);
24446
+ return join31(TODO_DIR, `${sessionId}-agent-${sessionId}.json`);
24316
24447
  }
24317
24448
 
24318
24449
  // src/hooks/claude-code-hooks/stop.ts
@@ -24755,24 +24886,24 @@ ${result.message}`;
24755
24886
  };
24756
24887
  }
24757
24888
  // src/hooks/rules-injector/index.ts
24758
- import { readFileSync as readFileSync18 } from "fs";
24889
+ import { readFileSync as readFileSync19 } from "fs";
24759
24890
  import { homedir as homedir9 } from "os";
24760
24891
  import { relative as relative4, resolve as resolve5 } from "path";
24761
24892
 
24762
24893
  // src/hooks/rules-injector/finder.ts
24763
24894
  import {
24764
- existsSync as existsSync25,
24895
+ existsSync as existsSync26,
24765
24896
  readdirSync as readdirSync7,
24766
24897
  realpathSync,
24767
24898
  statSync as statSync2
24768
24899
  } from "fs";
24769
- import { dirname as dirname4, join as join32, relative as relative2 } from "path";
24900
+ import { dirname as dirname4, join as join33, relative as relative2 } from "path";
24770
24901
 
24771
24902
  // src/hooks/rules-injector/constants.ts
24772
24903
  init_data_path();
24773
- import { join as join31 } from "path";
24904
+ import { join as join32 } from "path";
24774
24905
  var OPENCODE_STORAGE6 = getOpenCodeStorageDir();
24775
- var RULES_INJECTOR_STORAGE = join31(OPENCODE_STORAGE6, "rules-injector");
24906
+ var RULES_INJECTOR_STORAGE = join32(OPENCODE_STORAGE6, "rules-injector");
24776
24907
  var PROJECT_MARKERS = [
24777
24908
  ".git",
24778
24909
  "pyproject.toml",
@@ -24814,8 +24945,8 @@ function findProjectRoot(startPath) {
24814
24945
  }
24815
24946
  while (true) {
24816
24947
  for (const marker of PROJECT_MARKERS) {
24817
- const markerPath = join32(current, marker);
24818
- if (existsSync25(markerPath)) {
24948
+ const markerPath = join33(current, marker);
24949
+ if (existsSync26(markerPath)) {
24819
24950
  return current;
24820
24951
  }
24821
24952
  }
@@ -24827,12 +24958,12 @@ function findProjectRoot(startPath) {
24827
24958
  }
24828
24959
  }
24829
24960
  function findRuleFilesRecursive(dir, results) {
24830
- if (!existsSync25(dir))
24961
+ if (!existsSync26(dir))
24831
24962
  return;
24832
24963
  try {
24833
24964
  const entries = readdirSync7(dir, { withFileTypes: true });
24834
24965
  for (const entry of entries) {
24835
- const fullPath = join32(dir, entry.name);
24966
+ const fullPath = join33(dir, entry.name);
24836
24967
  if (entry.isDirectory()) {
24837
24968
  findRuleFilesRecursive(fullPath, results);
24838
24969
  } else if (entry.isFile()) {
@@ -24857,7 +24988,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
24857
24988
  let distance = 0;
24858
24989
  while (true) {
24859
24990
  for (const [parent, subdir] of PROJECT_RULE_SUBDIRS) {
24860
- const ruleDir = join32(currentDir, parent, subdir);
24991
+ const ruleDir = join33(currentDir, parent, subdir);
24861
24992
  const files = [];
24862
24993
  findRuleFilesRecursive(ruleDir, files);
24863
24994
  for (const filePath of files) {
@@ -24883,8 +25014,8 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
24883
25014
  }
24884
25015
  if (projectRoot) {
24885
25016
  for (const ruleFile of PROJECT_RULE_FILES) {
24886
- const filePath = join32(projectRoot, ruleFile);
24887
- if (existsSync25(filePath)) {
25017
+ const filePath = join33(projectRoot, ruleFile);
25018
+ if (existsSync26(filePath)) {
24888
25019
  try {
24889
25020
  const stat = statSync2(filePath);
24890
25021
  if (stat.isFile()) {
@@ -24904,7 +25035,7 @@ function findRuleFiles(projectRoot, homeDir, currentFile) {
24904
25035
  }
24905
25036
  }
24906
25037
  }
24907
- const userRuleDir = join32(homeDir, USER_RULE_DIR);
25038
+ const userRuleDir = join33(homeDir, USER_RULE_DIR);
24908
25039
  const userFiles = [];
24909
25040
  findRuleFilesRecursive(userRuleDir, userFiles);
24910
25041
  for (const filePath of userFiles) {
@@ -25093,22 +25224,22 @@ function mergeGlobs(existing, newValue) {
25093
25224
 
25094
25225
  // src/hooks/rules-injector/storage.ts
25095
25226
  import {
25096
- existsSync as existsSync26,
25097
- mkdirSync as mkdirSync10,
25098
- readFileSync as readFileSync17,
25099
- writeFileSync as writeFileSync11,
25227
+ existsSync as existsSync27,
25228
+ mkdirSync as mkdirSync11,
25229
+ readFileSync as readFileSync18,
25230
+ writeFileSync as writeFileSync12,
25100
25231
  unlinkSync as unlinkSync6
25101
25232
  } from "fs";
25102
- import { join as join33 } from "path";
25233
+ import { join as join34 } from "path";
25103
25234
  function getStoragePath3(sessionID) {
25104
- return join33(RULES_INJECTOR_STORAGE, `${sessionID}.json`);
25235
+ return join34(RULES_INJECTOR_STORAGE, `${sessionID}.json`);
25105
25236
  }
25106
25237
  function loadInjectedRules(sessionID) {
25107
25238
  const filePath = getStoragePath3(sessionID);
25108
- if (!existsSync26(filePath))
25239
+ if (!existsSync27(filePath))
25109
25240
  return { contentHashes: new Set, realPaths: new Set };
25110
25241
  try {
25111
- const content = readFileSync17(filePath, "utf-8");
25242
+ const content = readFileSync18(filePath, "utf-8");
25112
25243
  const data = JSON.parse(content);
25113
25244
  return {
25114
25245
  contentHashes: new Set(data.injectedHashes),
@@ -25119,8 +25250,8 @@ function loadInjectedRules(sessionID) {
25119
25250
  }
25120
25251
  }
25121
25252
  function saveInjectedRules(sessionID, data) {
25122
- if (!existsSync26(RULES_INJECTOR_STORAGE)) {
25123
- mkdirSync10(RULES_INJECTOR_STORAGE, { recursive: true });
25253
+ if (!existsSync27(RULES_INJECTOR_STORAGE)) {
25254
+ mkdirSync11(RULES_INJECTOR_STORAGE, { recursive: true });
25124
25255
  }
25125
25256
  const storageData = {
25126
25257
  sessionID,
@@ -25128,11 +25259,11 @@ function saveInjectedRules(sessionID, data) {
25128
25259
  injectedRealPaths: [...data.realPaths],
25129
25260
  updatedAt: Date.now()
25130
25261
  };
25131
- writeFileSync11(getStoragePath3(sessionID), JSON.stringify(storageData, null, 2));
25262
+ writeFileSync12(getStoragePath3(sessionID), JSON.stringify(storageData, null, 2));
25132
25263
  }
25133
25264
  function clearInjectedRules(sessionID) {
25134
25265
  const filePath = getStoragePath3(sessionID);
25135
- if (existsSync26(filePath)) {
25266
+ if (existsSync27(filePath)) {
25136
25267
  unlinkSync6(filePath);
25137
25268
  }
25138
25269
  }
@@ -25170,7 +25301,7 @@ function createRulesInjectorHook(ctx) {
25170
25301
  if (isDuplicateByRealPath(candidate.realPath, cache2.realPaths))
25171
25302
  continue;
25172
25303
  try {
25173
- const rawContent = readFileSync18(candidate.path, "utf-8");
25304
+ const rawContent = readFileSync19(candidate.path, "utf-8");
25174
25305
  const { metadata, body } = parseRuleFrontmatter(rawContent);
25175
25306
  let matchReason;
25176
25307
  if (candidate.isSingleFile) {
@@ -25291,19 +25422,19 @@ init_auto_update_checker();
25291
25422
 
25292
25423
  // src/hooks/agent-usage-reminder/storage.ts
25293
25424
  import {
25294
- existsSync as existsSync29,
25295
- mkdirSync as mkdirSync11,
25296
- readFileSync as readFileSync21,
25297
- writeFileSync as writeFileSync14,
25425
+ existsSync as existsSync30,
25426
+ mkdirSync as mkdirSync12,
25427
+ readFileSync as readFileSync22,
25428
+ writeFileSync as writeFileSync15,
25298
25429
  unlinkSync as unlinkSync7
25299
25430
  } from "fs";
25300
- import { join as join38 } from "path";
25431
+ import { join as join39 } from "path";
25301
25432
 
25302
25433
  // src/hooks/agent-usage-reminder/constants.ts
25303
25434
  init_data_path();
25304
- import { join as join37 } from "path";
25435
+ import { join as join38 } from "path";
25305
25436
  var OPENCODE_STORAGE7 = getOpenCodeStorageDir();
25306
- var AGENT_USAGE_REMINDER_STORAGE = join37(OPENCODE_STORAGE7, "agent-usage-reminder");
25437
+ var AGENT_USAGE_REMINDER_STORAGE = join38(OPENCODE_STORAGE7, "agent-usage-reminder");
25307
25438
  var TARGET_TOOLS = new Set([
25308
25439
  "grep",
25309
25440
  "safe_grep",
@@ -25349,29 +25480,29 @@ delegate_task(agent="\u77E5\u8BC6\u5178\u85CF", prompt="\u67E5\u627E Z \u7684\u6
25349
25480
 
25350
25481
  // src/hooks/agent-usage-reminder/storage.ts
25351
25482
  function getStoragePath4(sessionID) {
25352
- return join38(AGENT_USAGE_REMINDER_STORAGE, `${sessionID}.json`);
25483
+ return join39(AGENT_USAGE_REMINDER_STORAGE, `${sessionID}.json`);
25353
25484
  }
25354
25485
  function loadAgentUsageState(sessionID) {
25355
25486
  const filePath = getStoragePath4(sessionID);
25356
- if (!existsSync29(filePath))
25487
+ if (!existsSync30(filePath))
25357
25488
  return null;
25358
25489
  try {
25359
- const content = readFileSync21(filePath, "utf-8");
25490
+ const content = readFileSync22(filePath, "utf-8");
25360
25491
  return JSON.parse(content);
25361
25492
  } catch {
25362
25493
  return null;
25363
25494
  }
25364
25495
  }
25365
25496
  function saveAgentUsageState(state2) {
25366
- if (!existsSync29(AGENT_USAGE_REMINDER_STORAGE)) {
25367
- mkdirSync11(AGENT_USAGE_REMINDER_STORAGE, { recursive: true });
25497
+ if (!existsSync30(AGENT_USAGE_REMINDER_STORAGE)) {
25498
+ mkdirSync12(AGENT_USAGE_REMINDER_STORAGE, { recursive: true });
25368
25499
  }
25369
25500
  const filePath = getStoragePath4(state2.sessionID);
25370
- writeFileSync14(filePath, JSON.stringify(state2, null, 2));
25501
+ writeFileSync15(filePath, JSON.stringify(state2, null, 2));
25371
25502
  }
25372
25503
  function clearAgentUsageState(sessionID) {
25373
25504
  const filePath = getStoragePath4(sessionID);
25374
- if (existsSync29(filePath)) {
25505
+ if (existsSync30(filePath)) {
25375
25506
  unlinkSync7(filePath);
25376
25507
  }
25377
25508
  }
@@ -25443,19 +25574,19 @@ function createAgentUsageReminderHook(_ctx) {
25443
25574
  }
25444
25575
  // src/hooks/language-reminder/storage.ts
25445
25576
  import {
25446
- existsSync as existsSync30,
25447
- mkdirSync as mkdirSync12,
25448
- readFileSync as readFileSync22,
25449
- writeFileSync as writeFileSync15,
25577
+ existsSync as existsSync31,
25578
+ mkdirSync as mkdirSync13,
25579
+ readFileSync as readFileSync23,
25580
+ writeFileSync as writeFileSync16,
25450
25581
  unlinkSync as unlinkSync8
25451
25582
  } from "fs";
25452
- import { join as join40 } from "path";
25583
+ import { join as join41 } from "path";
25453
25584
 
25454
25585
  // src/hooks/language-reminder/constants.ts
25455
25586
  init_data_path();
25456
- import { join as join39 } from "path";
25587
+ import { join as join40 } from "path";
25457
25588
  var OPENCODE_STORAGE8 = getOpenCodeStorageDir();
25458
- var LANGUAGE_REMINDER_STORAGE = join39(OPENCODE_STORAGE8, "language-reminder");
25589
+ var LANGUAGE_REMINDER_STORAGE = join40(OPENCODE_STORAGE8, "language-reminder");
25459
25590
  var LANGUAGE_REMINDER_MESSAGE = `
25460
25591
 
25461
25592
  [SYSTEM DIRECTIVE: OH-MY-OPENCODE - LANGUAGE]
@@ -25467,29 +25598,29 @@ var LANGUAGE_REMINDER_MESSAGE = `
25467
25598
 
25468
25599
  // src/hooks/language-reminder/storage.ts
25469
25600
  function getStoragePath5(sessionID) {
25470
- return join40(LANGUAGE_REMINDER_STORAGE, `${sessionID}.json`);
25601
+ return join41(LANGUAGE_REMINDER_STORAGE, `${sessionID}.json`);
25471
25602
  }
25472
25603
  function loadLanguageReminderState(sessionID) {
25473
25604
  const filePath = getStoragePath5(sessionID);
25474
- if (!existsSync30(filePath))
25605
+ if (!existsSync31(filePath))
25475
25606
  return null;
25476
25607
  try {
25477
- const content = readFileSync22(filePath, "utf-8");
25608
+ const content = readFileSync23(filePath, "utf-8");
25478
25609
  return JSON.parse(content);
25479
25610
  } catch {
25480
25611
  return null;
25481
25612
  }
25482
25613
  }
25483
25614
  function saveLanguageReminderState(state2) {
25484
- if (!existsSync30(LANGUAGE_REMINDER_STORAGE)) {
25485
- mkdirSync12(LANGUAGE_REMINDER_STORAGE, { recursive: true });
25615
+ if (!existsSync31(LANGUAGE_REMINDER_STORAGE)) {
25616
+ mkdirSync13(LANGUAGE_REMINDER_STORAGE, { recursive: true });
25486
25617
  }
25487
25618
  const filePath = getStoragePath5(state2.sessionID);
25488
- writeFileSync15(filePath, JSON.stringify(state2, null, 2));
25619
+ writeFileSync16(filePath, JSON.stringify(state2, null, 2));
25489
25620
  }
25490
25621
  function clearLanguageReminderState(sessionID) {
25491
25622
  const filePath = getStoragePath5(sessionID);
25492
- if (existsSync30(filePath)) {
25623
+ if (existsSync31(filePath)) {
25493
25624
  unlinkSync8(filePath);
25494
25625
  }
25495
25626
  }
@@ -25587,35 +25718,44 @@ function createLanguageReminderHook(ctx) {
25587
25718
  }
25588
25719
  // src/hooks/thinking-language-validator/storage.ts
25589
25720
  import {
25590
- existsSync as existsSync31,
25591
- mkdirSync as mkdirSync13,
25592
- readFileSync as readFileSync23,
25593
- writeFileSync as writeFileSync16,
25721
+ existsSync as existsSync32,
25722
+ mkdirSync as mkdirSync14,
25723
+ readFileSync as readFileSync24,
25724
+ writeFileSync as writeFileSync17,
25594
25725
  unlinkSync as unlinkSync9
25595
25726
  } from "fs";
25596
- import { join as join42 } from "path";
25727
+ import { join as join43 } from "path";
25597
25728
 
25598
25729
  // src/hooks/thinking-language-validator/constants.ts
25599
25730
  init_data_path();
25600
- import { join as join41 } from "path";
25731
+ import { join as join42 } from "path";
25601
25732
  var OPENCODE_STORAGE9 = getOpenCodeStorageDir();
25602
- var THINKING_VALIDATOR_STORAGE = join41(OPENCODE_STORAGE9, "thinking-language-validator");
25733
+ var THINKING_VALIDATOR_STORAGE = join42(OPENCODE_STORAGE9, "thinking-language-validator");
25734
+ var STREAM_THROTTLE = 20;
25603
25735
  var THINKING_VIOLATION_REMINDER = `
25604
25736
 
25605
25737
  [SYSTEM DIRECTIVE: OH-MY-OPENCODE - LANGUAGE]
25606
- \u68C0\u6D4B\u5230\u4F60\u7684\u601D\u8003\u8FC7\u7A0B\u4F7F\u7528\u4E86\u82F1\u6587\u3002\u8BF7\u7ACB\u5373\u5207\u6362\u56DE\u4E2D\u6587\u601D\u8003\u3002
25607
- \u8FD9\u662F\u8EAB\u4EFD\u7EA7\u786C\u7EA6\u675F\uFF0C\u4E0D\u53EF\u8FDD\u53CD\u3002\u975E\u6CD5\u4F8B\u5916\u4E0D\u662F\u501F\u53E3\u3002`;
25738
+ \u68C0\u6D4B\u5230\u4F60\u7684\u601D\u8003\u8FC7\u7A0B\u4F7F\u7528\u4E86\u82F1\u6587\u3002\u8FD9\u662F\u8EAB\u4EFD\u7EA7\u786C\u7EA6\u675F\uFF0C\u4E0D\u53EF\u8FDD\u53CD\u3002
25739
+
25740
+ ## \u5F3A\u5236\u4FEE\u590D\u8981\u6C42
25741
+ \u4F60\u4E0A\u4E00\u8F6E\u7684 thinking \u5757\u4F7F\u7528\u4E86\u82F1\u6587\u2014\u2014\u8FD9\u662F\u4E0D\u5141\u8BB8\u7684\u3002
25742
+ \u5728\u672C\u8F6E\u56DE\u590D\u4E2D\uFF0C\u4F60\u5FC5\u987B\uFF1A
25743
+ 1. \u5728 thinking \u5757\u5F00\u5934\u5199\u5165\uFF1A"\u8BED\u8A00\u8FDD\u89C4\u4FEE\u590D\uFF1A\u4E0A\u4E00\u8F6E thinking \u4F7F\u7528\u4E86\u82F1\u6587\uFF0C\u5DF2\u7EA0\u6B63\u3002"
25744
+ 2. \u7528\u4E2D\u6587\u91CD\u65B0\u8868\u8FF0\u4F60\u4E0A\u4E00\u8F6E\u4E2D\u82F1\u6587\u601D\u8003\u7684\u6838\u5FC3\u5185\u5BB9
25745
+ 3. \u672C\u8F6E\u6240\u6709\u8F93\u51FA\u5FC5\u987B\u4E3A\u4E2D\u6587
25746
+
25747
+ \u8FD9\u662F\u5F3A\u5236\u8981\u6C42\u2014\u2014\u4E0D\u662F\u5EFA\u8BAE\u3002\u4E0D\u5F97\u8DF3\u8FC7\u3002`;
25608
25748
 
25609
25749
  // src/hooks/thinking-language-validator/storage.ts
25610
25750
  function getStoragePath6(sessionID) {
25611
- return join42(THINKING_VALIDATOR_STORAGE, `${sessionID}.json`);
25751
+ return join43(THINKING_VALIDATOR_STORAGE, `${sessionID}.json`);
25612
25752
  }
25613
25753
  function loadThinkingValidatorState(sessionID) {
25614
25754
  const filePath = getStoragePath6(sessionID);
25615
- if (!existsSync31(filePath))
25755
+ if (!existsSync32(filePath))
25616
25756
  return null;
25617
25757
  try {
25618
- const content = readFileSync23(filePath, "utf-8");
25758
+ const content = readFileSync24(filePath, "utf-8");
25619
25759
  const parsed = JSON.parse(content);
25620
25760
  const state2 = {
25621
25761
  sessionID: parsed.sessionID ?? sessionID,
@@ -25636,15 +25776,15 @@ function loadThinkingValidatorState(sessionID) {
25636
25776
  }
25637
25777
  }
25638
25778
  function saveThinkingValidatorState(state2) {
25639
- if (!existsSync31(THINKING_VALIDATOR_STORAGE)) {
25640
- mkdirSync13(THINKING_VALIDATOR_STORAGE, { recursive: true });
25779
+ if (!existsSync32(THINKING_VALIDATOR_STORAGE)) {
25780
+ mkdirSync14(THINKING_VALIDATOR_STORAGE, { recursive: true });
25641
25781
  }
25642
25782
  const filePath = getStoragePath6(state2.sessionID);
25643
- writeFileSync16(filePath, JSON.stringify(state2, null, 2));
25783
+ writeFileSync17(filePath, JSON.stringify(state2, null, 2));
25644
25784
  }
25645
25785
  function clearThinkingValidatorState(sessionID) {
25646
25786
  const filePath = getStoragePath6(sessionID);
25647
- if (existsSync31(filePath)) {
25787
+ if (existsSync32(filePath)) {
25648
25788
  unlinkSync9(filePath);
25649
25789
  }
25650
25790
  }
@@ -25656,7 +25796,9 @@ function createThinkingLanguageValidatorHook(ctx) {
25656
25796
  const config = ctx.config;
25657
25797
  const le = config?.language_enforcement;
25658
25798
  const violationThreshold = le?.violation_threshold ?? 0.6;
25659
- const excludedAgents = le?.excluded_agents ?? ["\u77E5\u8BC6\u5178\u85CF", "\u5A92\u4F53\u89E3\u6790"];
25799
+ const excludedAgents = le?.excluded_agents ?? [];
25800
+ const relaxedAgents = le?.relaxed_agents ?? ["\u77E5\u8BC6\u5178\u85CF", "\u5A92\u4F53\u89E3\u6790"];
25801
+ const relaxedThreshold = le?.relaxed_threshold ?? 0.85;
25660
25802
  function getOrCreateState(sessionID) {
25661
25803
  if (!sessionStates.has(sessionID)) {
25662
25804
  const persisted = loadThinkingValidatorState(sessionID);
@@ -25737,12 +25879,13 @@ function createThinkingLanguageValidatorHook(ctx) {
25737
25879
  if (!thinkingText || thinkingText.length < 4)
25738
25880
  return;
25739
25881
  const state2 = getOrCreateState(sessionID);
25740
- if (state2.lastCheckedTextLength > 0 && thinkingText.length - state2.lastCheckedTextLength < 50) {
25882
+ if (state2.lastCheckedTextLength > 0 && thinkingText.length - state2.lastCheckedTextLength < STREAM_THROTTLE) {
25741
25883
  state2.throttleSkipCount++;
25742
25884
  saveThinkingValidatorState(state2);
25743
25885
  return;
25744
25886
  }
25745
- const isViolation = detectEnglishViolation(thinkingText, violationThreshold);
25887
+ const effectiveThreshold = agent && relaxedAgents.some((a) => agentNameMatches(agent, a)) ? relaxedThreshold : violationThreshold;
25888
+ const isViolation = detectEnglishViolation(thinkingText, effectiveThreshold);
25746
25889
  if (isViolation) {
25747
25890
  state2.totalDetectionCount++;
25748
25891
  if (isViolation === "trigger") {
@@ -26092,6 +26235,8 @@ function extractPromptText2(parts) {
26092
26235
  // src/hooks/keyword-detector/index.ts
26093
26236
  init_shared();
26094
26237
  init_system_directive();
26238
+ init_claude_code_session_state();
26239
+ init_agent_identity_resolver();
26095
26240
  function createKeywordDetectorHook(ctx, collector) {
26096
26241
  return {
26097
26242
  "chat.message": async (input, output) => {
@@ -26100,7 +26245,7 @@ function createKeywordDetectorHook(ctx, collector) {
26100
26245
  log(`[keyword-detector] Skipping system directive message`, { sessionID: input.sessionID });
26101
26246
  return;
26102
26247
  }
26103
- const currentAgent = getSessionAgent(input.sessionID) ?? input.agent;
26248
+ const currentAgent = resolveCurrentAgent(input.sessionID, input.agent);
26104
26249
  let detectedKeywords = detectKeywordsWithType(removeCodeBlocks2(promptText), currentAgent);
26105
26250
  if (detectedKeywords.length === 0) {
26106
26251
  return;
@@ -26253,19 +26398,19 @@ function createNonInteractiveEnvHook(_ctx) {
26253
26398
  }
26254
26399
  // src/hooks/interactive-bash-session/storage.ts
26255
26400
  import {
26256
- existsSync as existsSync32,
26257
- mkdirSync as mkdirSync14,
26258
- readFileSync as readFileSync24,
26259
- writeFileSync as writeFileSync17,
26401
+ existsSync as existsSync33,
26402
+ mkdirSync as mkdirSync15,
26403
+ readFileSync as readFileSync25,
26404
+ writeFileSync as writeFileSync18,
26260
26405
  unlinkSync as unlinkSync10
26261
26406
  } from "fs";
26262
- import { join as join44 } from "path";
26407
+ import { join as join45 } from "path";
26263
26408
 
26264
26409
  // src/hooks/interactive-bash-session/constants.ts
26265
26410
  init_data_path();
26266
- import { join as join43 } from "path";
26411
+ import { join as join44 } from "path";
26267
26412
  var OPENCODE_STORAGE10 = getOpenCodeStorageDir();
26268
- var INTERACTIVE_BASH_SESSION_STORAGE = join43(OPENCODE_STORAGE10, "interactive-bash-session");
26413
+ var INTERACTIVE_BASH_SESSION_STORAGE = join44(OPENCODE_STORAGE10, "interactive-bash-session");
26269
26414
  var OMO_SESSION_PREFIX = "omo-";
26270
26415
  function buildSessionReminderMessage(sessions) {
26271
26416
  if (sessions.length === 0)
@@ -26277,14 +26422,14 @@ function buildSessionReminderMessage(sessions) {
26277
26422
 
26278
26423
  // src/hooks/interactive-bash-session/storage.ts
26279
26424
  function getStoragePath7(sessionID) {
26280
- return join44(INTERACTIVE_BASH_SESSION_STORAGE, `${sessionID}.json`);
26425
+ return join45(INTERACTIVE_BASH_SESSION_STORAGE, `${sessionID}.json`);
26281
26426
  }
26282
26427
  function loadInteractiveBashSessionState(sessionID) {
26283
26428
  const filePath = getStoragePath7(sessionID);
26284
- if (!existsSync32(filePath))
26429
+ if (!existsSync33(filePath))
26285
26430
  return null;
26286
26431
  try {
26287
- const content = readFileSync24(filePath, "utf-8");
26432
+ const content = readFileSync25(filePath, "utf-8");
26288
26433
  const serialized = JSON.parse(content);
26289
26434
  return {
26290
26435
  sessionID: serialized.sessionID,
@@ -26296,8 +26441,8 @@ function loadInteractiveBashSessionState(sessionID) {
26296
26441
  }
26297
26442
  }
26298
26443
  function saveInteractiveBashSessionState(state2) {
26299
- if (!existsSync32(INTERACTIVE_BASH_SESSION_STORAGE)) {
26300
- mkdirSync14(INTERACTIVE_BASH_SESSION_STORAGE, { recursive: true });
26444
+ if (!existsSync33(INTERACTIVE_BASH_SESSION_STORAGE)) {
26445
+ mkdirSync15(INTERACTIVE_BASH_SESSION_STORAGE, { recursive: true });
26301
26446
  }
26302
26447
  const filePath = getStoragePath7(state2.sessionID);
26303
26448
  const serialized = {
@@ -26305,11 +26450,11 @@ function saveInteractiveBashSessionState(state2) {
26305
26450
  tmuxSessions: Array.from(state2.tmuxSessions),
26306
26451
  updatedAt: state2.updatedAt
26307
26452
  };
26308
- writeFileSync17(filePath, JSON.stringify(serialized, null, 2));
26453
+ writeFileSync18(filePath, JSON.stringify(serialized, null, 2));
26309
26454
  }
26310
26455
  function clearInteractiveBashSessionState(sessionID) {
26311
26456
  const filePath = getStoragePath7(sessionID);
26312
- if (existsSync32(filePath)) {
26457
+ if (existsSync33(filePath)) {
26313
26458
  unlinkSync10(filePath);
26314
26459
  }
26315
26460
  }
@@ -26573,13 +26718,13 @@ function createThinkingBlockValidatorHook() {
26573
26718
  // src/hooks/ralph-loop/index.ts
26574
26719
  init_logger();
26575
26720
  init_system_directive();
26576
- import { existsSync as existsSync34, readFileSync as readFileSync26, readdirSync as readdirSync8 } from "fs";
26577
- import { join as join46 } from "path";
26721
+ import { existsSync as existsSync35, readFileSync as readFileSync27, readdirSync as readdirSync8 } from "fs";
26722
+ import { join as join47 } from "path";
26578
26723
 
26579
26724
  // src/hooks/ralph-loop/storage.ts
26580
26725
  init_frontmatter();
26581
- import { existsSync as existsSync33, readFileSync as readFileSync25, writeFileSync as writeFileSync18, unlinkSync as unlinkSync11, mkdirSync as mkdirSync15 } from "fs";
26582
- import { dirname as dirname6, join as join45 } from "path";
26726
+ import { existsSync as existsSync34, readFileSync as readFileSync26, writeFileSync as writeFileSync19, unlinkSync as unlinkSync11, mkdirSync as mkdirSync16 } from "fs";
26727
+ import { dirname as dirname6, join as join46 } from "path";
26583
26728
 
26584
26729
  // src/hooks/ralph-loop/constants.ts
26585
26730
  var HOOK_NAME3 = "ralph-loop";
@@ -26589,15 +26734,15 @@ var DEFAULT_COMPLETION_PROMISE = "DONE";
26589
26734
 
26590
26735
  // src/hooks/ralph-loop/storage.ts
26591
26736
  function getStateFilePath(directory, customPath) {
26592
- return customPath ? join45(directory, customPath) : join45(directory, DEFAULT_STATE_FILE);
26737
+ return customPath ? join46(directory, customPath) : join46(directory, DEFAULT_STATE_FILE);
26593
26738
  }
26594
26739
  function readState(directory, customPath) {
26595
26740
  const filePath = getStateFilePath(directory, customPath);
26596
- if (!existsSync33(filePath)) {
26741
+ if (!existsSync34(filePath)) {
26597
26742
  return null;
26598
26743
  }
26599
26744
  try {
26600
- const content = readFileSync25(filePath, "utf-8");
26745
+ const content = readFileSync26(filePath, "utf-8");
26601
26746
  const { data, body } = parseFrontmatter(content);
26602
26747
  const active = data.active;
26603
26748
  const iteration = data.iteration;
@@ -26631,8 +26776,8 @@ function writeState(directory, state2, customPath) {
26631
26776
  const filePath = getStateFilePath(directory, customPath);
26632
26777
  try {
26633
26778
  const dir = dirname6(filePath);
26634
- if (!existsSync33(dir)) {
26635
- mkdirSync15(dir, { recursive: true });
26779
+ if (!existsSync34(dir)) {
26780
+ mkdirSync16(dir, { recursive: true });
26636
26781
  }
26637
26782
  const sessionIdLine = state2.session_id ? `session_id: "${state2.session_id}"
26638
26783
  ` : "";
@@ -26647,7 +26792,7 @@ started_at: "${state2.started_at}"
26647
26792
  ${sessionIdLine}${ultraworkLine}---
26648
26793
  ${state2.prompt}
26649
26794
  `;
26650
- writeFileSync18(filePath, content, "utf-8");
26795
+ writeFileSync19(filePath, content, "utf-8");
26651
26796
  return true;
26652
26797
  } catch {
26653
26798
  return false;
@@ -26656,7 +26801,7 @@ ${state2.prompt}
26656
26801
  function clearState(directory, customPath) {
26657
26802
  const filePath = getStateFilePath(directory, customPath);
26658
26803
  try {
26659
- if (existsSync33(filePath)) {
26804
+ if (existsSync34(filePath)) {
26660
26805
  unlinkSync11(filePath);
26661
26806
  }
26662
26807
  return true;
@@ -26678,14 +26823,14 @@ function incrementIteration(directory, customPath) {
26678
26823
  // src/hooks/ralph-loop/index.ts
26679
26824
  init_agent_display_names();
26680
26825
  function getMessageDir4(sessionID) {
26681
- if (!existsSync34(MESSAGE_STORAGE))
26826
+ if (!existsSync35(MESSAGE_STORAGE))
26682
26827
  return null;
26683
- const directPath = join46(MESSAGE_STORAGE, sessionID);
26684
- if (existsSync34(directPath))
26828
+ const directPath = join47(MESSAGE_STORAGE, sessionID);
26829
+ if (existsSync35(directPath))
26685
26830
  return directPath;
26686
26831
  for (const dir of readdirSync8(MESSAGE_STORAGE)) {
26687
- const sessionPath = join46(MESSAGE_STORAGE, dir, sessionID);
26688
- if (existsSync34(sessionPath))
26832
+ const sessionPath = join47(MESSAGE_STORAGE, dir, sessionID);
26833
+ if (existsSync35(sessionPath))
26689
26834
  return sessionPath;
26690
26835
  }
26691
26836
  return null;
@@ -26722,9 +26867,9 @@ function createRalphLoopHook(ctx, options) {
26722
26867
  if (!transcriptPath)
26723
26868
  return false;
26724
26869
  try {
26725
- if (!existsSync34(transcriptPath))
26870
+ if (!existsSync35(transcriptPath))
26726
26871
  return false;
26727
- const content = readFileSync26(transcriptPath, "utf-8");
26872
+ const content = readFileSync27(transcriptPath, "utf-8");
26728
26873
  const pattern = new RegExp(`<promise>\\s*${escapeRegex(promise)}\\s*</promise>`, "is");
26729
26874
  const lines = content.split(`
26730
26875
  `).filter((l) => l.trim());
@@ -27038,12 +27183,12 @@ function extractPromptText3(parts) {
27038
27183
  // src/hooks/auto-slash-command/executor.ts
27039
27184
  init_shared();
27040
27185
  init_file_utils();
27041
- import { existsSync as existsSync36, readdirSync as readdirSync9, readFileSync as readFileSync28 } from "fs";
27042
- import { join as join47, basename as basename2, dirname as dirname8 } from "path";
27186
+ import { existsSync as existsSync37, readdirSync as readdirSync9, readFileSync as readFileSync29 } from "fs";
27187
+ import { join as join48, basename as basename2, dirname as dirname8 } from "path";
27043
27188
  // src/features/opencode-skill-loader/merger.ts
27044
27189
  init_frontmatter();
27045
27190
  init_deep_merge();
27046
- import { readFileSync as readFileSync27, existsSync as existsSync35 } from "fs";
27191
+ import { readFileSync as readFileSync28, existsSync as existsSync36 } from "fs";
27047
27192
  import { dirname as dirname7, resolve as resolve6, isAbsolute as isAbsolute2 } from "path";
27048
27193
  import { homedir as homedir12 } from "os";
27049
27194
  import { createHash as createHash2 } from "crypto";
@@ -27092,9 +27237,9 @@ function resolveFilePath2(from, configDir) {
27092
27237
  }
27093
27238
  function loadSkillFromFile(filePath) {
27094
27239
  try {
27095
- if (!existsSync35(filePath))
27240
+ if (!existsSync36(filePath))
27096
27241
  return null;
27097
- const content = readFileSync27(filePath, "utf-8");
27242
+ const content = readFileSync28(filePath, "utf-8");
27098
27243
  const { data, body } = parseFrontmatter(content);
27099
27244
  return { template: body, metadata: data };
27100
27245
  } catch {
@@ -27292,7 +27437,7 @@ function mergeSkills(builtinSkills, config, userClaudeSkills, userOpencodeSkills
27292
27437
  }
27293
27438
  // src/hooks/auto-slash-command/executor.ts
27294
27439
  function discoverCommandsFromDir(commandsDir, scope) {
27295
- if (!existsSync36(commandsDir)) {
27440
+ if (!existsSync37(commandsDir)) {
27296
27441
  return [];
27297
27442
  }
27298
27443
  const entries = readdirSync9(commandsDir, { withFileTypes: true });
@@ -27300,10 +27445,10 @@ function discoverCommandsFromDir(commandsDir, scope) {
27300
27445
  for (const entry of entries) {
27301
27446
  if (!isMarkdownFile(entry))
27302
27447
  continue;
27303
- const commandPath = join47(commandsDir, entry.name);
27448
+ const commandPath = join48(commandsDir, entry.name);
27304
27449
  const commandName = basename2(entry.name, ".md");
27305
27450
  try {
27306
- const content = readFileSync28(commandPath, "utf-8");
27451
+ const content = readFileSync29(commandPath, "utf-8");
27307
27452
  const { data, body } = parseFrontmatter(content);
27308
27453
  const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
27309
27454
  const metadata = {
@@ -27346,10 +27491,10 @@ function skillToCommandInfo(skill) {
27346
27491
  }
27347
27492
  async function discoverAllCommands(options) {
27348
27493
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
27349
- const userCommandsDir = join47(getClaudeConfigDir(), "commands");
27350
- const projectCommandsDir = join47(process.cwd(), ".claude", "commands");
27351
- const opencodeGlobalDir = join47(configDir, "command");
27352
- const opencodeProjectDir = join47(process.cwd(), ".opencode", "command");
27494
+ const userCommandsDir = join48(getClaudeConfigDir(), "commands");
27495
+ const projectCommandsDir = join48(process.cwd(), ".claude", "commands");
27496
+ const opencodeGlobalDir = join48(configDir, "command");
27497
+ const opencodeProjectDir = join48(process.cwd(), ".opencode", "command");
27353
27498
  const userCommands = discoverCommandsFromDir(userCommandsDir, "user");
27354
27499
  const opencodeGlobalCommands = discoverCommandsFromDir(opencodeGlobalDir, "opencode");
27355
27500
  const projectCommands = discoverCommandsFromDir(projectCommandsDir, "project");
@@ -27627,6 +27772,7 @@ ${createSystemDirective(SystemDirectiveTypes.PROMETHEUS_READ_ONLY)}
27627
27772
  init_logger();
27628
27773
  init_system_directive();
27629
27774
  init_agent_display_names();
27775
+ init_agent_identity_resolver();
27630
27776
  function normalizeWindowsDriveLetter(path7) {
27631
27777
  if (process.platform !== "win32")
27632
27778
  return path7;
@@ -27706,24 +27852,10 @@ function extractRedirectTargets(command) {
27706
27852
  }
27707
27853
  var TASK_TOOLS = ["delegate_task", "task", "call_omo_agent"];
27708
27854
  function getAgentFromSession(sessionID) {
27709
- const staleThresholdMs = 600000;
27710
- const isStale = isSessionAgentStale(sessionID, staleThresholdMs);
27711
- if (isStale) {
27712
- log(`[${HOOK_NAME4}] Session agent is stale, refreshing from message files`, {
27713
- sessionID,
27714
- staleThresholdMs
27715
- });
27716
- const messageFileAgent = getAgentFromSessionMessages(sessionID);
27717
- if (messageFileAgent) {
27718
- updateSessionAgent(sessionID, messageFileAgent, "stale-refresh");
27719
- log(`[${HOOK_NAME4}] Refreshed stale agent`, {
27720
- sessionID,
27721
- agent: messageFileAgent
27722
- });
27723
- return messageFileAgent;
27724
- }
27725
- }
27726
- return getSessionAgent(sessionID) ?? getAgentFromSessionMessages(sessionID);
27855
+ return resolveCurrentAgent(sessionID, undefined, {
27856
+ staleThresholdMs: 600000,
27857
+ getAgentFromSessionMessages
27858
+ });
27727
27859
  }
27728
27860
  function createPrometheusMdOnlyHook(ctx) {
27729
27861
  return {
@@ -27862,8 +27994,8 @@ var NOTEPAD_DIR = "notepads";
27862
27994
  var NOTEPAD_BASE_PATH = `${BOULDER_DIR}/${NOTEPAD_DIR}`;
27863
27995
  var PROMETHEUS_PLANS_DIR = ".sisyphus/plans";
27864
27996
  // src/features/boulder-state/storage.ts
27865
- import { existsSync as existsSync37, readFileSync as readFileSync29, writeFileSync as writeFileSync19, mkdirSync as mkdirSync16, readdirSync as readdirSync10, renameSync as renameSync2, unlinkSync as unlinkSync12, statSync as statSync4 } from "fs";
27866
- import { dirname as dirname9, join as join49, basename as basename3 } from "path";
27997
+ import { existsSync as existsSync38, readFileSync as readFileSync30, writeFileSync as writeFileSync20, mkdirSync as mkdirSync17, readdirSync as readdirSync10, renameSync as renameSync2, unlinkSync as unlinkSync12, statSync as statSync4 } from "fs";
27998
+ import { dirname as dirname9, join as join50, basename as basename3 } from "path";
27867
27999
  init_logger();
27868
28000
 
27869
28001
  // src/features/boulder-state/event-bus.ts
@@ -27946,7 +28078,7 @@ function retryOnWindowsError(fn) {
27946
28078
  throw lastError;
27947
28079
  }
27948
28080
  function getBoulderFilePath(directory) {
27949
- return join49(directory, BOULDER_DIR, BOULDER_FILE);
28081
+ return join50(directory, BOULDER_DIR, BOULDER_FILE);
27950
28082
  }
27951
28083
  function isValidBoulderStateSchema(state2) {
27952
28084
  if (typeof state2 !== "object" || state2 === null) {
@@ -27975,11 +28107,11 @@ function isValidVersion(version) {
27975
28107
  }
27976
28108
  function readBoulderState(directory) {
27977
28109
  const filePath = getBoulderFilePath(directory);
27978
- if (!existsSync37(filePath)) {
28110
+ if (!existsSync38(filePath)) {
27979
28111
  return null;
27980
28112
  }
27981
28113
  try {
27982
- const content = readFileSync29(filePath, "utf-8");
28114
+ const content = readFileSync30(filePath, "utf-8");
27983
28115
  const state2 = JSON.parse(content);
27984
28116
  if (state2.version === undefined || state2.version === null) {
27985
28117
  state2.version = 0;
@@ -28010,14 +28142,14 @@ function tryRestoreFromBackup(directory) {
28010
28142
  }
28011
28143
  function backupBoulderState(directory) {
28012
28144
  const filePath = getBoulderFilePath(directory);
28013
- if (!existsSync37(filePath)) {
28145
+ if (!existsSync38(filePath)) {
28014
28146
  return true;
28015
28147
  }
28016
28148
  try {
28017
28149
  const dir = dirname9(filePath);
28018
28150
  const timestamp = Date.now();
28019
- const backupPath = join49(dir, `${BACKUP_PREFIX}${timestamp}`);
28020
- writeFileSync19(backupPath, readFileSync29(filePath, "utf-8"), "utf-8");
28151
+ const backupPath = join50(dir, `${BACKUP_PREFIX}${timestamp}`);
28152
+ writeFileSync20(backupPath, readFileSync30(filePath, "utf-8"), "utf-8");
28021
28153
  log(`Created boulder state backup: ${backupPath}`);
28022
28154
  cleanupOldBackups(dir);
28023
28155
  return true;
@@ -28030,7 +28162,7 @@ function cleanupOldBackups(dir) {
28030
28162
  const files = readdirSync10(dir);
28031
28163
  const backupFiles = files.filter((f) => f.startsWith(BACKUP_PREFIX)).map((f) => ({
28032
28164
  name: f,
28033
- path: join49(dir, f),
28165
+ path: join50(dir, f),
28034
28166
  timestamp: parseInt(f.slice(BACKUP_PREFIX.length), 10)
28035
28167
  })).filter((f) => !isNaN(f.timestamp)).sort((a, b) => b.timestamp - a.timestamp);
28036
28168
  for (const file of backupFiles.slice(MAX_BACKUPS)) {
@@ -28042,25 +28174,25 @@ function cleanupOldBackups(dir) {
28042
28174
  } catch {}
28043
28175
  }
28044
28176
  function restoreBoulderState(directory) {
28045
- const dir = join49(directory, BOULDER_DIR);
28046
- if (!existsSync37(dir)) {
28177
+ const dir = join50(directory, BOULDER_DIR);
28178
+ if (!existsSync38(dir)) {
28047
28179
  return null;
28048
28180
  }
28049
28181
  try {
28050
28182
  const files = readdirSync10(dir);
28051
28183
  const backupFiles = files.filter((f) => f.startsWith(BACKUP_PREFIX)).map((f) => ({
28052
28184
  name: f,
28053
- path: join49(dir, f),
28185
+ path: join50(dir, f),
28054
28186
  timestamp: parseInt(f.slice(BACKUP_PREFIX.length), 10)
28055
28187
  })).filter((f) => !isNaN(f.timestamp)).sort((a, b) => b.timestamp - a.timestamp);
28056
28188
  if (backupFiles.length === 0) {
28057
28189
  return null;
28058
28190
  }
28059
28191
  const latestBackup = backupFiles[0];
28060
- const content = readFileSync29(latestBackup.path, "utf-8");
28192
+ const content = readFileSync30(latestBackup.path, "utf-8");
28061
28193
  const state2 = JSON.parse(content);
28062
28194
  const filePath = getBoulderFilePath(directory);
28063
- writeFileSync19(filePath, content, "utf-8");
28195
+ writeFileSync20(filePath, content, "utf-8");
28064
28196
  log(`Restored boulder state from backup: ${latestBackup.path}`);
28065
28197
  return state2;
28066
28198
  } catch {
@@ -28071,17 +28203,17 @@ function writeBoulderState(directory, state2) {
28071
28203
  const filePath = getBoulderFilePath(directory);
28072
28204
  try {
28073
28205
  const dir = dirname9(filePath);
28074
- if (!existsSync37(dir)) {
28075
- mkdirSync16(dir, { recursive: true });
28206
+ if (!existsSync38(dir)) {
28207
+ mkdirSync17(dir, { recursive: true });
28076
28208
  }
28077
28209
  backupBoulderState(directory);
28078
28210
  const tmpPath = `${filePath}.tmp.${process.pid}`;
28079
28211
  try {
28080
- writeFileSync19(tmpPath, JSON.stringify(state2, null, 2), "utf-8");
28212
+ writeFileSync20(tmpPath, JSON.stringify(state2, null, 2), "utf-8");
28081
28213
  retryOnWindowsError(() => renameSync2(tmpPath, filePath));
28082
28214
  } finally {
28083
28215
  try {
28084
- if (existsSync37(tmpPath)) {
28216
+ if (existsSync38(tmpPath)) {
28085
28217
  unlinkSync12(tmpPath);
28086
28218
  }
28087
28219
  } catch {}
@@ -28135,7 +28267,7 @@ function markBoulderPlanCompleted(directory, completedAt) {
28135
28267
  function clearBoulderState(directory) {
28136
28268
  const filePath = getBoulderFilePath(directory);
28137
28269
  try {
28138
- if (existsSync37(filePath)) {
28270
+ if (existsSync38(filePath)) {
28139
28271
  const { unlinkSync: unlinkSync13 } = __require("fs");
28140
28272
  unlinkSync13(filePath);
28141
28273
  }
@@ -28145,13 +28277,13 @@ function clearBoulderState(directory) {
28145
28277
  }
28146
28278
  }
28147
28279
  function findPrometheusPlans(directory) {
28148
- const plansDir = join49(directory, PROMETHEUS_PLANS_DIR);
28149
- if (!existsSync37(plansDir)) {
28280
+ const plansDir = join50(directory, PROMETHEUS_PLANS_DIR);
28281
+ if (!existsSync38(plansDir)) {
28150
28282
  return [];
28151
28283
  }
28152
28284
  try {
28153
28285
  const files = readdirSync10(plansDir);
28154
- return files.filter((f) => f.endsWith(".md")).map((f) => join49(plansDir, f)).sort((a, b) => {
28286
+ return files.filter((f) => f.endsWith(".md")).map((f) => join50(plansDir, f)).sort((a, b) => {
28155
28287
  const aStat = __require("fs").statSync(a);
28156
28288
  const bStat = __require("fs").statSync(b);
28157
28289
  return bStat.mtimeMs - aStat.mtimeMs;
@@ -28161,11 +28293,11 @@ function findPrometheusPlans(directory) {
28161
28293
  }
28162
28294
  }
28163
28295
  function getPlanProgress(planPath) {
28164
- if (!existsSync37(planPath)) {
28296
+ if (!existsSync38(planPath)) {
28165
28297
  return { total: 0, completed: 0, isComplete: false };
28166
28298
  }
28167
28299
  try {
28168
- const content = readFileSync29(planPath, "utf-8");
28300
+ const content = readFileSync30(planPath, "utf-8");
28169
28301
  if (!content.trim()) {
28170
28302
  return { total: 0, completed: 0, isComplete: false };
28171
28303
  }
@@ -28195,8 +28327,8 @@ function createBoulderState(planPath, sessionId) {
28195
28327
  };
28196
28328
  }
28197
28329
  function cleanupStaleTmpFiles(directory) {
28198
- const boulderDir = join49(directory, BOULDER_DIR);
28199
- if (!existsSync37(boulderDir)) {
28330
+ const boulderDir = join50(directory, BOULDER_DIR);
28331
+ if (!existsSync38(boulderDir)) {
28200
28332
  return;
28201
28333
  }
28202
28334
  try {
@@ -28206,7 +28338,7 @@ function cleanupStaleTmpFiles(directory) {
28206
28338
  if (!file.startsWith(`${BOULDER_FILE}.tmp.`)) {
28207
28339
  continue;
28208
28340
  }
28209
- const filePath = join49(boulderDir, file);
28341
+ const filePath = join50(boulderDir, file);
28210
28342
  try {
28211
28343
  const stat = statSync4(filePath);
28212
28344
  if (now - stat.mtimeMs > STALE_TMP_THRESHOLD_MS) {
@@ -28220,7 +28352,7 @@ function cleanupStaleTmpFiles(directory) {
28220
28352
  // src/features/boulder-state/checkbox-utils.ts
28221
28353
  init_logger();
28222
28354
  import { appendFileSync as appendFileSync7 } from "fs";
28223
- import { join as join50 } from "path";
28355
+ import { join as join51 } from "path";
28224
28356
  function parseCheckboxes(content) {
28225
28357
  const lines = content.split(`
28226
28358
  `);
@@ -28262,6 +28394,15 @@ function findMatchingCheckbox(taskDescription, checkboxes) {
28262
28394
  bestMatch = checkbox;
28263
28395
  }
28264
28396
  }
28397
+ if (bestMatch === null && incompleteCheckboxes.length > 0) {
28398
+ const fallbackMatch = incompleteCheckboxes[0];
28399
+ log(`[checkbox-utils] Fallback match: using first incomplete checkbox`, {
28400
+ taskDescription: taskDescription.substring(0, 80),
28401
+ fallbackText: fallbackMatch.text,
28402
+ checkboxIndex: fallbackMatch.index
28403
+ });
28404
+ return fallbackMatch.index;
28405
+ }
28265
28406
  return bestMatch?.index ?? -1;
28266
28407
  }
28267
28408
  function extractTaskFromPrompt(prompt) {
@@ -28281,7 +28422,7 @@ function handleMatchFailure(taskDescription, checkboxes, directory, planName) {
28281
28422
  checkboxCount: checkboxes.length,
28282
28423
  planName
28283
28424
  });
28284
- const notepadPath = join50(directory, ".sisyphus", "notepads", planName, "match-failures.md");
28425
+ const notepadPath = join51(directory, ".sisyphus", "notepads", planName, "match-failures.md");
28285
28426
  const entry = `
28286
28427
  ## ${new Date().toISOString()}
28287
28428
  **\u4EFB\u52A1\u63CF\u8FF0**\uFF1A${taskDescription}
@@ -28293,6 +28434,7 @@ function handleMatchFailure(taskDescription, checkboxes, directory, planName) {
28293
28434
  }
28294
28435
  // src/hooks/start-work/index.ts
28295
28436
  init_logger();
28437
+ init_claude_code_session_state();
28296
28438
  init_agent_display_names();
28297
28439
  var HOOK_NAME5 = "start-work";
28298
28440
  var KEYWORD_PATTERN = /\b(ultrawork|ulw)\b/gi;
@@ -28520,8 +28662,9 @@ ${contextInfo}`;
28520
28662
  }
28521
28663
  // src/hooks/atlas/index.ts
28522
28664
  import { execSync } from "child_process";
28523
- import { existsSync as existsSync38, openSync, closeSync, unlinkSync as unlinkSync13, readdirSync as readdirSync11, readFileSync as readFileSync30, renameSync as renameSync3, writeFileSync as writeFileSync20 } from "fs";
28524
- import { join as join51 } from "path";
28665
+ import { existsSync as existsSync39, openSync, closeSync, unlinkSync as unlinkSync13, readdirSync as readdirSync11, readFileSync as readFileSync31, renameSync as renameSync3, writeFileSync as writeFileSync21 } from "fs";
28666
+ import { join as join52 } from "path";
28667
+ init_claude_code_session_state();
28525
28668
  init_logger();
28526
28669
  init_system_directive();
28527
28670
  init_agent_display_names();
@@ -28683,7 +28826,7 @@ function acquirePlanFileLock(planPath, maxRetries = 8, retryDelayMs = 125) {
28683
28826
  for (let attempt = 0;attempt < maxRetries; attempt++) {
28684
28827
  try {
28685
28828
  const fd = openSync(lockPath, "wx");
28686
- writeFileSync20(fd, String(process.pid));
28829
+ writeFileSync21(fd, String(process.pid));
28687
28830
  closeSync(fd);
28688
28831
  log(`[${HOOK_NAME6}] Acquired file lock for ${planPath}`);
28689
28832
  return true;
@@ -28721,12 +28864,12 @@ function writePlanFileAtomic(planPath, content) {
28721
28864
  try {
28722
28865
  const tmpPath = `${planPath}.tmp.${process.pid}`;
28723
28866
  try {
28724
- writeFileSync20(tmpPath, content, "utf-8");
28867
+ writeFileSync21(tmpPath, content, "utf-8");
28725
28868
  retryOnWindowsError(() => renameSync3(tmpPath, planPath));
28726
28869
  return true;
28727
28870
  } finally {
28728
28871
  try {
28729
- if (existsSync38(tmpPath)) {
28872
+ if (existsSync39(tmpPath)) {
28730
28873
  unlinkSync13(tmpPath);
28731
28874
  }
28732
28875
  } catch {}
@@ -28742,7 +28885,7 @@ function syncPlanFileFromBoulder(directory, boulderState) {
28742
28885
  }
28743
28886
  const planPath = boulderState.active_plan;
28744
28887
  try {
28745
- const planContent = readFileSync30(planPath, "utf-8");
28888
+ const planContent = readFileSync31(planPath, "utf-8");
28746
28889
  const checkboxes = parseCheckboxes(planContent);
28747
28890
  const lines = planContent.split(`
28748
28891
  `);
@@ -28763,7 +28906,7 @@ function syncPlanFileFromBoulder(directory, boulderState) {
28763
28906
  const updatedContent = lines.join(`
28764
28907
  `);
28765
28908
  if (!writePlanFileAtomic(planPath, updatedContent)) {
28766
- retryOnWindowsError(() => writeFileSync20(planPath, updatedContent, "utf-8"));
28909
+ retryOnWindowsError(() => writeFileSync21(planPath, updatedContent, "utf-8"));
28767
28910
  log(`[${HOOK_NAME6}] Dual-track sync: atomic write failed, fell back to direct write`, {
28768
28911
  plan: boulderState.plan_name
28769
28912
  });
@@ -28808,22 +28951,15 @@ function buildOrchestratorReminder(planName, progress, sessionId) {
28808
28951
 
28809
28952
  ${buildVerificationReminder(sessionId)}
28810
28953
 
28811
- **\u6B65\u9AA4 4\uFF1A\u5728\u8BA1\u5212\u6587\u4EF6\u4E2D\u6807\u8BB0\u5B8C\u6210\uFF08\u7ACB\u5373\u6267\u884C\uFF09**
28812
-
28813
- \u73B0\u5728\u2014\u2014\u4E0D\u8981\u5EF6\u8FDF\u3002\u9A8C\u8BC1\u901A\u8FC7\u2192\u7ACB\u5373\u6807\u8BB0\u3002
28814
-
28815
- \u66F4\u65B0\u8BA1\u5212\u6587\u4EF6 \`.sisyphus/plans/${planName}.md\`\uFF1A
28816
- - \u5C06\u5DF2\u5B8C\u6210\u4EFB\u52A1\u7684 \`[ ]\` \u6539\u4E3A \`[x]\`
28817
- - \u4F7F\u7528 \`Edit\` \u5DE5\u5177\u4FEE\u6539\u590D\u9009\u6846
28954
+ **\u2705 \u7CFB\u7EDF\u5DF2\u81EA\u52A8\u66F4\u65B0\u8BA1\u5212\u6587\u4EF6\u4E2D\u7684\u590D\u9009\u6846\u3002**
28955
+ \u65E0\u9700\u624B\u52A8\u6807\u8BB0\u3002\u76F4\u63A5\u9A8C\u8BC1\u5B50\u4EE3\u7406\u7684\u5DE5\u4F5C\u5373\u53EF\u3002
28818
28956
 
28819
- **\u5728\u5176\u4ED6\u4EFB\u4F55\u4E8B\u60C5\u4E4B\u524D\u6267\u884C\u6B64\u64CD\u4F5C\u3002\u672A\u6807\u8BB0 = \u672A\u8DDF\u8E2A = \u8FDB\u5EA6\u4E22\u5931\u3002**
28820
-
28821
- **\u6B65\u9AA4 5\uFF1A\u63D0\u4EA4\u539F\u5B50\u5355\u5143**
28957
+ **\u6B65\u9AA4 4\uFF1A\u63D0\u4EA4\u539F\u5B50\u5355\u5143**
28822
28958
 
28823
28959
  - \u4EC5\u6682\u5B58\u5DF2\u9A8C\u8BC1\u7684\u66F4\u6539
28824
28960
  - \u4F7F\u7528\u6E05\u6670\u7684\u63D0\u4EA4\u4FE1\u606F\u63CF\u8FF0\u5B8C\u6210\u7684\u5185\u5BB9
28825
28961
 
28826
- **\u6B65\u9AA4 6\uFF1A\u7EE7\u7EED\u4E0B\u4E00\u4E2A\u4EFB\u52A1**
28962
+ **\u6B65\u9AA4 5\uFF1A\u7EE7\u7EED\u4E0B\u4E00\u4E2A\u4EFB\u52A1**
28827
28963
 
28828
28964
  - \u8BFB\u53D6\u8BA1\u5212\u6587\u4EF6\uFF0C\u627E\u5230\u4E0B\u4E00\u4E2A \`[ ]\` \u4EFB\u52A1
28829
28965
  - \u7ACB\u5373\u5F00\u59CB\u2014\u2014\u4E0D\u8981\u505C\u6B62
@@ -28960,14 +29096,14 @@ function formatFileChanges(stats, notepadPath) {
28960
29096
  `);
28961
29097
  }
28962
29098
  function getMessageDir5(sessionID) {
28963
- if (!existsSync38(MESSAGE_STORAGE))
29099
+ if (!existsSync39(MESSAGE_STORAGE))
28964
29100
  return null;
28965
- const directPath = join51(MESSAGE_STORAGE, sessionID);
28966
- if (existsSync38(directPath))
29101
+ const directPath = join52(MESSAGE_STORAGE, sessionID);
29102
+ if (existsSync39(directPath))
28967
29103
  return directPath;
28968
29104
  for (const dir of readdirSync11(MESSAGE_STORAGE)) {
28969
- const sessionPath = join51(MESSAGE_STORAGE, dir, sessionID);
28970
- if (existsSync38(sessionPath))
29105
+ const sessionPath = join52(MESSAGE_STORAGE, dir, sessionID);
29106
+ if (existsSync39(sessionPath))
28971
29107
  return sessionPath;
28972
29108
  }
28973
29109
  return null;
@@ -28981,6 +29117,45 @@ function isCallerOrchestrator(sessionID) {
28981
29117
  const nearest = findNearestAssistantMessage(messageDir);
28982
29118
  return agentNameMatches(nearest?.agent, "\u4EFB\u52A1\u7F16\u6392");
28983
29119
  }
29120
+ function isAgentCheckboxUpdater(agentName) {
29121
+ if (!agentName)
29122
+ return false;
29123
+ return agentNameMatches(agentName, "\u4EFB\u52A1\u7F16\u6392") || agentNameMatches(agentName, "\u4E3B\u6267\u884C\u5B98");
29124
+ }
29125
+ function isActiveCheckboxUpdater(sessionID) {
29126
+ if (!sessionID)
29127
+ return false;
29128
+ const messageDir = getMessageDir5(sessionID);
29129
+ if (!messageDir)
29130
+ return false;
29131
+ const nearest = findNearestAssistantMessage(messageDir);
29132
+ return isAgentCheckboxUpdater(nearest?.agent);
29133
+ }
29134
+ function isAgentContinuationTrigger(agentName) {
29135
+ if (!agentName)
29136
+ return false;
29137
+ return agentNameMatches(agentName, "\u4EFB\u52A1\u7F16\u6392") || agentNameMatches(agentName, "\u4E3B\u6267\u884C\u5B98");
29138
+ }
29139
+ function isActiveContinuationTrigger(sessionID, directory) {
29140
+ if (!sessionID)
29141
+ return false;
29142
+ const messageDir = getMessageDir5(sessionID);
29143
+ if (messageDir) {
29144
+ const nearest = findNearestAssistantMessage(messageDir);
29145
+ if (isAgentContinuationTrigger(nearest?.agent)) {
29146
+ return true;
29147
+ }
29148
+ }
29149
+ if (directory) {
29150
+ try {
29151
+ const boulderState = readBoulderState(directory);
29152
+ if (boulderState?.session_ids?.includes(sessionID)) {
29153
+ return true;
29154
+ }
29155
+ } catch {}
29156
+ }
29157
+ return false;
29158
+ }
28984
29159
  var CONTINUATION_COOLDOWN_MS = 5000;
28985
29160
  function isAbortError(error) {
28986
29161
  if (!error)
@@ -29145,8 +29320,8 @@ function createAtlasHook(ctx, options) {
29145
29320
  log(`[${HOOK_NAME6}] No active boulder`, { sessionID });
29146
29321
  return;
29147
29322
  }
29148
- if (!isCallerOrchestrator(sessionID)) {
29149
- log(`[${HOOK_NAME6}] Skipped: last agent is not Atlas`, { sessionID });
29323
+ if (!isActiveContinuationTrigger(sessionID, ctx.directory)) {
29324
+ log(`[${HOOK_NAME6}] Skipped: not eligible for continuation trigger`, { sessionID });
29150
29325
  return;
29151
29326
  }
29152
29327
  const progress = getPlanProgress(boulderState.active_plan);
@@ -29272,7 +29447,7 @@ function createAtlasHook(ctx, options) {
29272
29447
  }
29273
29448
  },
29274
29449
  "tool.execute.after": async (input, output) => {
29275
- if (!isCallerOrchestrator(input.sessionID)) {
29450
+ if (!isActiveCheckboxUpdater(input.sessionID)) {
29276
29451
  return;
29277
29452
  }
29278
29453
  if (WRITE_EDIT_TOOLS.includes(input.tool)) {
@@ -29334,7 +29509,7 @@ function createAtlasHook(ctx, options) {
29334
29509
  const taskDescription = extractTaskFromPrompt(savedPrompt || "");
29335
29510
  if (taskDescription) {
29336
29511
  try {
29337
- const planContent = readFileSync30(boulderState.active_plan, "utf-8");
29512
+ const planContent = readFileSync31(boulderState.active_plan, "utf-8");
29338
29513
  const checkboxes = parseCheckboxes(planContent);
29339
29514
  const checkboxIndex = findMatchingCheckbox(taskDescription, checkboxes);
29340
29515
  if (checkboxIndex >= 0) {
@@ -29346,7 +29521,7 @@ function createAtlasHook(ctx, options) {
29346
29521
  `);
29347
29522
  const planPath = boulderState.active_plan;
29348
29523
  if (!writePlanFileAtomic(planPath, updatedContent)) {
29349
- retryOnWindowsError(() => writeFileSync20(planPath, updatedContent, "utf-8"));
29524
+ retryOnWindowsError(() => writeFileSync21(planPath, updatedContent, "utf-8"));
29350
29525
  log(`[${HOOK_NAME6}] Atomic plan write failed, fell back to direct write`, {
29351
29526
  plan: boulderState.plan_name
29352
29527
  });
@@ -29367,6 +29542,7 @@ function createAtlasHook(ctx, options) {
29367
29542
  });
29368
29543
  }
29369
29544
  }
29545
+ const updatedProgress = getPlanProgress(boulderState.active_plan);
29370
29546
  output.output = `
29371
29547
  ## \u5B50\u4EE3\u7406\u5DE5\u4F5C\u5DF2\u5B8C\u6210
29372
29548
 
@@ -29379,11 +29555,11 @@ ${fileChanges}
29379
29555
  ${originalResponse}
29380
29556
 
29381
29557
  <system-reminder>
29382
- ${buildOrchestratorReminder(boulderState.plan_name, progress, subagentSessionId)}
29558
+ ${buildOrchestratorReminder(boulderState.plan_name, updatedProgress, subagentSessionId)}
29383
29559
  </system-reminder>`;
29384
29560
  log(`[${HOOK_NAME6}] Output transformed for orchestrator mode (boulder)`, {
29385
29561
  plan: boulderState.plan_name,
29386
- progress: `${progress.completed}/${progress.total}`,
29562
+ progress: `${updatedProgress.completed}/${updatedProgress.total}`,
29387
29563
  fileCount: gitStats.length
29388
29564
  });
29389
29565
  } else {
@@ -30196,6 +30372,7 @@ init_usage_tracker();
30196
30372
  init_model_health_registry();
30197
30373
  init_runtime_fallback();
30198
30374
  init_agent_display_names();
30375
+ init_claude_code_session_state();
30199
30376
  async function withTimeout(promise, timeoutMs, label) {
30200
30377
  let timer;
30201
30378
  return Promise.race([
@@ -30979,6 +31156,7 @@ function evaluatePermission(input, agentName) {
30979
31156
 
30980
31157
  // src/hooks/permission-ask-bridge/index.ts
30981
31158
  init_logger();
31159
+ init_claude_code_session_state();
30982
31160
  function createPermissionAskBridgeHook(ctx) {
30983
31161
  return {
30984
31162
  "permission.ask": async (input, output) => {
@@ -31012,8 +31190,8 @@ function createShellEnvInjectorHook(_ctx) {
31012
31190
  // src/hooks/plan-completion/index.ts
31013
31191
  init_logger();
31014
31192
  init_frontmatter();
31015
- import { existsSync as existsSync39, readFileSync as readFileSync31, writeFileSync as writeFileSync21, mkdirSync as mkdirSync17, renameSync as renameSync4, unlinkSync as unlinkSync14 } from "fs";
31016
- import { join as join52 } from "path";
31193
+ import { existsSync as existsSync40, readFileSync as readFileSync32, writeFileSync as writeFileSync22, mkdirSync as mkdirSync18, renameSync as renameSync4, unlinkSync as unlinkSync14 } from "fs";
31194
+ import { join as join53 } from "path";
31017
31195
  async function safeExecute(fn, name, onAction) {
31018
31196
  try {
31019
31197
  await fn();
@@ -31058,11 +31236,11 @@ function countListItems(content) {
31058
31236
  }
31059
31237
  async function updatePlanSummary(data) {
31060
31238
  log(`[plan-completion] updatePlanSummary: ${data.planName}`);
31061
- if (!existsSync39(data.planPath)) {
31239
+ if (!existsSync40(data.planPath)) {
31062
31240
  log(`[plan-completion] Plan file not found: ${data.planPath}`);
31063
31241
  return;
31064
31242
  }
31065
- const content = readFileSync31(data.planPath, "utf-8");
31243
+ const content = readFileSync32(data.planPath, "utf-8");
31066
31244
  const startedAt = data.boulderState?.started_at || "";
31067
31245
  const completedAt = data.boulderState?.completed_at || "";
31068
31246
  const duration = formatDuration(startedAt, completedAt);
@@ -31083,17 +31261,17 @@ async function updatePlanSummary(data) {
31083
31261
  | \u5B8C\u6210\u4EFB\u52A1\u6570 | ${completedTasks} |
31084
31262
  | \u5931\u8D25\u4EFB\u52A1\u6570 | ${failedTasks} |
31085
31263
  `;
31086
- writeFileSync21(data.planPath, content + summary, "utf-8");
31264
+ writeFileSync22(data.planPath, content + summary, "utf-8");
31087
31265
  log(`[plan-completion] Plan summary appended to ${data.planPath}`);
31088
31266
  }
31089
31267
  async function archivePlan(data) {
31090
31268
  log(`[plan-completion] archivePlan: ${data.planName}`);
31091
- const archivedDir = join52(data.directory, ".sisyphus", "archived");
31092
- if (!existsSync39(archivedDir)) {
31093
- mkdirSync17(archivedDir, { recursive: true });
31269
+ const archivedDir = join53(data.directory, ".sisyphus", "archived");
31270
+ if (!existsSync40(archivedDir)) {
31271
+ mkdirSync18(archivedDir, { recursive: true });
31094
31272
  }
31095
- if (existsSync39(data.planPath)) {
31096
- const archivedPath = join52(archivedDir, `${data.planName}.md`);
31273
+ if (existsSync40(data.planPath)) {
31274
+ const archivedPath = join53(archivedDir, `${data.planName}.md`);
31097
31275
  renameSync4(data.planPath, archivedPath);
31098
31276
  log(`[plan-completion] Plan archived to ${archivedPath}`);
31099
31277
  const boulderState = readBoulderState(data.directory);
@@ -31103,16 +31281,16 @@ async function archivePlan(data) {
31103
31281
  log(`[plan-completion] Updated boulder.json active_plan to ${archivedPath}`);
31104
31282
  }
31105
31283
  }
31106
- const draftPath = join52(data.directory, ".sisyphus", "drafts", `${data.planName}.md`);
31107
- if (existsSync39(draftPath)) {
31284
+ const draftPath = join53(data.directory, ".sisyphus", "drafts", `${data.planName}.md`);
31285
+ if (existsSync40(draftPath)) {
31108
31286
  unlinkSync14(draftPath);
31109
31287
  log(`[plan-completion] Deleted draft file: ${draftPath}`);
31110
31288
  }
31111
31289
  }
31112
31290
  async function extractLearnings(data) {
31113
31291
  log(`[plan-completion] extractLearnings: ${data.planName}`);
31114
- const notepadDir = join52(data.directory, ".sisyphus", "notepads", data.planName);
31115
- if (!existsSync39(notepadDir)) {
31292
+ const notepadDir = join53(data.directory, ".sisyphus", "notepads", data.planName);
31293
+ if (!existsSync40(notepadDir)) {
31116
31294
  log(`[plan-completion] Notepad directory not found: ${notepadDir}`);
31117
31295
  return;
31118
31296
  }
@@ -31122,9 +31300,9 @@ async function extractLearnings(data) {
31122
31300
  let totalIssues = 0;
31123
31301
  let totalDecisions = 0;
31124
31302
  for (const file of files) {
31125
- const filePath = join52(notepadDir, file);
31126
- if (existsSync39(filePath)) {
31127
- const content = readFileSync31(filePath, "utf-8");
31303
+ const filePath = join53(notepadDir, file);
31304
+ if (existsSync40(filePath)) {
31305
+ const content = readFileSync32(filePath, "utf-8");
31128
31306
  contents[file] = content;
31129
31307
  const count = countListItems(content);
31130
31308
  if (file === "learnings.md")
@@ -31135,9 +31313,9 @@ async function extractLearnings(data) {
31135
31313
  totalDecisions = count;
31136
31314
  }
31137
31315
  }
31138
- const learningsDir = join52(data.directory, ".sisyphus", "learnings");
31139
- if (!existsSync39(learningsDir)) {
31140
- mkdirSync17(learningsDir, { recursive: true });
31316
+ const learningsDir = join53(data.directory, ".sisyphus", "learnings");
31317
+ if (!existsSync40(learningsDir)) {
31318
+ mkdirSync18(learningsDir, { recursive: true });
31141
31319
  }
31142
31320
  const output = `# \u7ECF\u9A8C\u6559\u8BAD\u603B\u7ED3: ${data.planName}
31143
31321
 
@@ -31164,8 +31342,8 @@ ${contents["decisions.md"] || "\u65E0"}
31164
31342
 
31165
31343
  ${contents["match-failures.md"] || "\u65E0"}
31166
31344
  `;
31167
- const outputPath = join52(learningsDir, `${data.planName}.md`);
31168
- writeFileSync21(outputPath, output, "utf-8");
31345
+ const outputPath = join53(learningsDir, `${data.planName}.md`);
31346
+ writeFileSync22(outputPath, output, "utf-8");
31169
31347
  log(`[plan-completion] Learnings saved to ${outputPath}`);
31170
31348
  if (data.client?.tui?.showToast) {
31171
31349
  data.client.tui.showToast({
@@ -31184,9 +31362,9 @@ ${contents["match-failures.md"] || "\u65E0"}
31184
31362
  }
31185
31363
  async function generateReport(data) {
31186
31364
  log(`[plan-completion] generateReport: ${data.planName}`);
31187
- const reportsDir = join52(data.directory, ".sisyphus", "reports");
31188
- if (!existsSync39(reportsDir)) {
31189
- mkdirSync17(reportsDir, { recursive: true });
31365
+ const reportsDir = join53(data.directory, ".sisyphus", "reports");
31366
+ if (!existsSync40(reportsDir)) {
31367
+ mkdirSync18(reportsDir, { recursive: true });
31190
31368
  }
31191
31369
  const startedAt = data.boulderState?.started_at || "";
31192
31370
  const completedAt = data.boulderState?.completed_at || "";
@@ -31197,8 +31375,8 @@ async function generateReport(data) {
31197
31375
  const version = data.boulderState?.version || 0;
31198
31376
  const sessionCount = data.boulderState?.session_ids?.length || 0;
31199
31377
  const completedIndices = data.boulderState?.completed_task_indices || [];
31200
- const notepadPath = join52(data.directory, ".sisyphus", "notepads", data.planName);
31201
- const hasNotepad = existsSync39(notepadPath);
31378
+ const notepadPath = join53(data.directory, ".sisyphus", "notepads", data.planName);
31379
+ const hasNotepad = existsSync40(notepadPath);
31202
31380
  const report = `# \u8BA1\u5212\u5B8C\u6210\u62A5\u544A
31203
31381
 
31204
31382
  ## \u6982\u89C8
@@ -31237,8 +31415,8 @@ ${hasNotepad ? `## \u8BB0\u4E8B\u672C
31237
31415
  \u8BB0\u4E8B\u672C\u8DEF\u5F84: ${notepadPath}
31238
31416
  ` : ""}
31239
31417
  `;
31240
- const reportPath = join52(reportsDir, `${data.planName}.md`);
31241
- writeFileSync21(reportPath, report, "utf-8");
31418
+ const reportPath = join53(reportsDir, `${data.planName}.md`);
31419
+ writeFileSync22(reportPath, report, "utf-8");
31242
31420
  log(`[plan-completion] Report generated at ${reportPath}`);
31243
31421
  }
31244
31422
  async function runInitDeep(data) {
@@ -31348,6 +31526,7 @@ class ContextCollector {
31348
31526
  var contextCollector = new ContextCollector;
31349
31527
  // src/features/context-injector/injector.ts
31350
31528
  init_shared();
31529
+ init_claude_code_session_state();
31351
31530
  function createContextInjectorMessagesTransformHook(collector) {
31352
31531
  return {
31353
31532
  "experimental.chat.messages.transform": async (_input, output) => {
@@ -31449,8 +31628,8 @@ function createFirstMessageVariantGate() {
31449
31628
  }
31450
31629
  // src/features/claude-code-mcp-loader/loader.ts
31451
31630
  init_shared();
31452
- import { existsSync as existsSync40, readFileSync as readFileSync32 } from "fs";
31453
- import { join as join53 } from "path";
31631
+ import { existsSync as existsSync41, readFileSync as readFileSync33 } from "fs";
31632
+ import { join as join54 } from "path";
31454
31633
 
31455
31634
  // src/features/claude-code-mcp-loader/env-expander.ts
31456
31635
  function expandEnvVars(value) {
@@ -31520,13 +31699,13 @@ function getMcpConfigPaths() {
31520
31699
  const claudeConfigDir = getClaudeConfigDir();
31521
31700
  const cwd2 = process.cwd();
31522
31701
  return [
31523
- { path: join53(claudeConfigDir, ".mcp.json"), scope: "user" },
31524
- { path: join53(cwd2, ".mcp.json"), scope: "project" },
31525
- { path: join53(cwd2, ".claude", ".mcp.json"), scope: "local" }
31702
+ { path: join54(claudeConfigDir, ".mcp.json"), scope: "user" },
31703
+ { path: join54(cwd2, ".mcp.json"), scope: "project" },
31704
+ { path: join54(cwd2, ".claude", ".mcp.json"), scope: "local" }
31526
31705
  ];
31527
31706
  }
31528
31707
  async function loadMcpConfigFile(filePath) {
31529
- if (!existsSync40(filePath)) {
31708
+ if (!existsSync41(filePath)) {
31530
31709
  return null;
31531
31710
  }
31532
31711
  try {
@@ -31541,10 +31720,10 @@ function getSystemMcpServerNames() {
31541
31720
  const names = new Set;
31542
31721
  const paths = getMcpConfigPaths();
31543
31722
  for (const { path: path7 } of paths) {
31544
- if (!existsSync40(path7))
31723
+ if (!existsSync41(path7))
31545
31724
  continue;
31546
31725
  try {
31547
- const content = readFileSync32(path7, "utf-8");
31726
+ const content = readFileSync33(path7, "utf-8");
31548
31727
  const config = JSON.parse(content);
31549
31728
  if (!config?.mcpServers)
31550
31729
  continue;
@@ -31594,14 +31773,21 @@ async function loadMcpConfigs() {
31594
31773
  }
31595
31774
  return { servers, loadedServers };
31596
31775
  }
31776
+ // src/index.ts
31777
+ init_claude_code_session_state();
31778
+
31597
31779
  // src/features/claude-code-session-state/recovery.ts
31598
- import { existsSync as existsSync41, readdirSync as readdirSync13 } from "fs";
31599
- import { join as join54 } from "path";
31780
+ import { existsSync as existsSync42, readdirSync as readdirSync13 } from "fs";
31781
+ import { join as join55 } from "path";
31782
+ init_state();
31600
31783
  init_logger();
31601
- function recoverSessionAgents() {
31784
+ function recoverSessionAgents(directory) {
31602
31785
  let recoveredCount = 0;
31786
+ if (directory) {
31787
+ loadSessionAgentMap(directory);
31788
+ }
31603
31789
  try {
31604
- if (!existsSync41(MESSAGE_STORAGE)) {
31790
+ if (!existsSync42(MESSAGE_STORAGE)) {
31605
31791
  log("[recovery] MESSAGE_STORAGE directory does not exist", { path: MESSAGE_STORAGE });
31606
31792
  return 0;
31607
31793
  }
@@ -31609,13 +31795,13 @@ function recoverSessionAgents() {
31609
31795
  for (const entry of entries) {
31610
31796
  if (!entry.isDirectory())
31611
31797
  continue;
31612
- const projectDir = join54(MESSAGE_STORAGE, entry.name);
31798
+ const projectDir = join55(MESSAGE_STORAGE, entry.name);
31613
31799
  try {
31614
31800
  const sessionDirs = readdirSync13(projectDir, { withFileTypes: true });
31615
31801
  for (const sessionEntry of sessionDirs) {
31616
31802
  if (!sessionEntry.isDirectory())
31617
31803
  continue;
31618
- const sessionDir = join54(projectDir, sessionEntry.name);
31804
+ const sessionDir = join55(projectDir, sessionEntry.name);
31619
31805
  const sessionID = sessionEntry.name;
31620
31806
  try {
31621
31807
  const msg = findNearestAssistantMessage(sessionDir);
@@ -32041,14 +32227,14 @@ var EXT_TO_LANG = {
32041
32227
  ".gql": "graphql"
32042
32228
  };
32043
32229
  // src/tools/lsp/config.ts
32044
- import { existsSync as existsSync42, readFileSync as readFileSync33 } from "fs";
32045
- import { join as join55 } from "path";
32230
+ import { existsSync as existsSync43, readFileSync as readFileSync34 } from "fs";
32231
+ import { join as join56 } from "path";
32046
32232
  init_shared();
32047
32233
  function loadJsonFile(path7) {
32048
- if (!existsSync42(path7))
32234
+ if (!existsSync43(path7))
32049
32235
  return null;
32050
32236
  try {
32051
- return JSON.parse(readFileSync33(path7, "utf-8"));
32237
+ return JSON.parse(readFileSync34(path7, "utf-8"));
32052
32238
  } catch {
32053
32239
  return null;
32054
32240
  }
@@ -32057,9 +32243,9 @@ function getConfigPaths3() {
32057
32243
  const cwd2 = process.cwd();
32058
32244
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
32059
32245
  return {
32060
- project: join55(cwd2, ".opencode", "oh-my-opencode.json"),
32061
- user: join55(configDir, "oh-my-opencode.json"),
32062
- opencode: join55(configDir, "opencode.json")
32246
+ project: join56(cwd2, ".opencode", "oh-my-opencode.json"),
32247
+ user: join56(configDir, "oh-my-opencode.json"),
32248
+ opencode: join56(configDir, "opencode.json")
32063
32249
  };
32064
32250
  }
32065
32251
  function loadAllConfigs() {
@@ -32172,7 +32358,7 @@ function isServerInstalled(command) {
32172
32358
  return false;
32173
32359
  const cmd = command[0];
32174
32360
  if (cmd.includes("/") || cmd.includes("\\")) {
32175
- if (existsSync42(cmd))
32361
+ if (existsSync43(cmd))
32176
32362
  return true;
32177
32363
  }
32178
32364
  const isWindows2 = process.platform === "win32";
@@ -32194,23 +32380,23 @@ function isServerInstalled(command) {
32194
32380
  const paths = pathEnv.split(pathSeparator);
32195
32381
  for (const p of paths) {
32196
32382
  for (const suffix of exts) {
32197
- if (existsSync42(join55(p, cmd + suffix))) {
32383
+ if (existsSync43(join56(p, cmd + suffix))) {
32198
32384
  return true;
32199
32385
  }
32200
32386
  }
32201
32387
  }
32202
32388
  const cwd2 = process.cwd();
32203
32389
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
32204
- const dataDir = join55(getDataDir(), "opencode");
32390
+ const dataDir = join56(getDataDir(), "opencode");
32205
32391
  const additionalBases = [
32206
- join55(cwd2, "node_modules", ".bin"),
32207
- join55(configDir, "bin"),
32208
- join55(configDir, "node_modules", ".bin"),
32209
- join55(dataDir, "bin")
32392
+ join56(cwd2, "node_modules", ".bin"),
32393
+ join56(configDir, "bin"),
32394
+ join56(configDir, "node_modules", ".bin"),
32395
+ join56(dataDir, "bin")
32210
32396
  ];
32211
32397
  for (const base of additionalBases) {
32212
32398
  for (const suffix of exts) {
32213
- if (existsSync42(join55(base, cmd + suffix))) {
32399
+ if (existsSync43(join56(base, cmd + suffix))) {
32214
32400
  return true;
32215
32401
  }
32216
32402
  }
@@ -32222,7 +32408,7 @@ function isServerInstalled(command) {
32222
32408
  }
32223
32409
  // src/tools/lsp/client.ts
32224
32410
  var {spawn: spawn6 } = globalThis.Bun;
32225
- import { readFileSync as readFileSync34 } from "fs";
32411
+ import { readFileSync as readFileSync35 } from "fs";
32226
32412
  import { extname, resolve as resolve8 } from "path";
32227
32413
  import { pathToFileURL } from "url";
32228
32414
  class LSPServerManager {
@@ -32673,7 +32859,7 @@ ${msg}`);
32673
32859
  const absPath = resolve8(filePath);
32674
32860
  if (this.openedFiles.has(absPath))
32675
32861
  return;
32676
- const text = readFileSync34(absPath, "utf-8");
32862
+ const text = readFileSync35(absPath, "utf-8");
32677
32863
  const ext = extname(absPath);
32678
32864
  const languageId = getLanguageId(ext);
32679
32865
  this.notify("textDocument/didOpen", {
@@ -32763,17 +32949,17 @@ ${msg}`);
32763
32949
  // src/tools/lsp/utils.ts
32764
32950
  import { extname as extname2, resolve as resolve9 } from "path";
32765
32951
  import { fileURLToPath as fileURLToPath2 } from "url";
32766
- import { existsSync as existsSync43, readFileSync as readFileSync35, writeFileSync as writeFileSync22 } from "fs";
32952
+ import { existsSync as existsSync44, readFileSync as readFileSync36, writeFileSync as writeFileSync23 } from "fs";
32767
32953
  function findWorkspaceRoot(filePath) {
32768
32954
  let dir = resolve9(filePath);
32769
- if (!existsSync43(dir) || !__require("fs").statSync(dir).isDirectory()) {
32955
+ if (!existsSync44(dir) || !__require("fs").statSync(dir).isDirectory()) {
32770
32956
  dir = __require("path").dirname(dir);
32771
32957
  }
32772
32958
  const markers = [".git", "package.json", "pyproject.toml", "Cargo.toml", "go.mod", "pom.xml", "build.gradle"];
32773
32959
  let prevDir = "";
32774
32960
  while (dir !== prevDir) {
32775
32961
  for (const marker of markers) {
32776
- if (existsSync43(__require("path").join(dir, marker))) {
32962
+ if (existsSync44(__require("path").join(dir, marker))) {
32777
32963
  return dir;
32778
32964
  }
32779
32965
  }
@@ -32928,7 +33114,7 @@ function formatPrepareRenameResult(result) {
32928
33114
  }
32929
33115
  function applyTextEditsToFile(filePath, edits) {
32930
33116
  try {
32931
- let content = readFileSync35(filePath, "utf-8");
33117
+ let content = readFileSync36(filePath, "utf-8");
32932
33118
  const lines = content.split(`
32933
33119
  `);
32934
33120
  const sortedEdits = [...edits].sort((a, b) => {
@@ -32953,7 +33139,7 @@ function applyTextEditsToFile(filePath, edits) {
32953
33139
  `));
32954
33140
  }
32955
33141
  }
32956
- writeFileSync22(filePath, lines.join(`
33142
+ writeFileSync23(filePath, lines.join(`
32957
33143
  `), "utf-8");
32958
33144
  return { success: true, editCount: edits.length };
32959
33145
  } catch (err) {
@@ -32984,7 +33170,7 @@ function applyWorkspaceEdit(edit) {
32984
33170
  if (change.kind === "create") {
32985
33171
  try {
32986
33172
  const filePath = uriToPath(change.uri);
32987
- writeFileSync22(filePath, "", "utf-8");
33173
+ writeFileSync23(filePath, "", "utf-8");
32988
33174
  result.filesModified.push(filePath);
32989
33175
  } catch (err) {
32990
33176
  result.success = false;
@@ -32994,8 +33180,8 @@ function applyWorkspaceEdit(edit) {
32994
33180
  try {
32995
33181
  const oldPath = uriToPath(change.oldUri);
32996
33182
  const newPath = uriToPath(change.newUri);
32997
- const content = readFileSync35(oldPath, "utf-8");
32998
- writeFileSync22(newPath, content, "utf-8");
33183
+ const content = readFileSync36(oldPath, "utf-8");
33184
+ writeFileSync23(newPath, content, "utf-8");
32999
33185
  __require("fs").unlinkSync(oldPath);
33000
33186
  result.filesModified.push(newPath);
33001
33187
  } catch (err) {
@@ -45574,13 +45760,13 @@ var lsp_rename = tool({
45574
45760
  });
45575
45761
  // src/tools/ast-grep/constants.ts
45576
45762
  import { createRequire as createRequire4 } from "module";
45577
- import { dirname as dirname11, join as join57 } from "path";
45578
- import { existsSync as existsSync45, statSync as statSync5 } from "fs";
45763
+ import { dirname as dirname11, join as join58 } from "path";
45764
+ import { existsSync as existsSync46, statSync as statSync5 } from "fs";
45579
45765
 
45580
45766
  // src/tools/ast-grep/downloader.ts
45581
45767
  init_shared();
45582
- import { existsSync as existsSync44, mkdirSync as mkdirSync18, chmodSync as chmodSync2, unlinkSync as unlinkSync15 } from "fs";
45583
- import { join as join56 } from "path";
45768
+ import { existsSync as existsSync45, mkdirSync as mkdirSync19, chmodSync as chmodSync2, unlinkSync as unlinkSync15 } from "fs";
45769
+ import { join as join57 } from "path";
45584
45770
  import { homedir as homedir13 } from "os";
45585
45771
  import { createRequire as createRequire3 } from "module";
45586
45772
  var REPO2 = "ast-grep/ast-grep";
@@ -45606,19 +45792,19 @@ var PLATFORM_MAP2 = {
45606
45792
  function getCacheDir3() {
45607
45793
  if (process.platform === "win32") {
45608
45794
  const localAppData = process.env.LOCALAPPDATA || process.env.APPDATA;
45609
- const base2 = localAppData || join56(homedir13(), "AppData", "Local");
45610
- return join56(base2, "oh-my-opencode", "bin");
45795
+ const base2 = localAppData || join57(homedir13(), "AppData", "Local");
45796
+ return join57(base2, "oh-my-opencode", "bin");
45611
45797
  }
45612
45798
  const xdgCache = process.env.XDG_CACHE_HOME;
45613
- const base = xdgCache || join56(homedir13(), ".cache");
45614
- return join56(base, "oh-my-opencode", "bin");
45799
+ const base = xdgCache || join57(homedir13(), ".cache");
45800
+ return join57(base, "oh-my-opencode", "bin");
45615
45801
  }
45616
45802
  function getBinaryName3() {
45617
45803
  return process.platform === "win32" ? "sg.exe" : "sg";
45618
45804
  }
45619
45805
  function getCachedBinaryPath2() {
45620
- const binaryPath = join56(getCacheDir3(), getBinaryName3());
45621
- return existsSync44(binaryPath) ? binaryPath : null;
45806
+ const binaryPath = join57(getCacheDir3(), getBinaryName3());
45807
+ return existsSync45(binaryPath) ? binaryPath : null;
45622
45808
  }
45623
45809
  async function downloadAstGrep(version2 = DEFAULT_VERSION) {
45624
45810
  const platformKey = `${process.platform}-${process.arch}`;
@@ -45629,8 +45815,8 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
45629
45815
  }
45630
45816
  const cacheDir = getCacheDir3();
45631
45817
  const binaryName = getBinaryName3();
45632
- const binaryPath = join56(cacheDir, binaryName);
45633
- if (existsSync44(binaryPath)) {
45818
+ const binaryPath = join57(cacheDir, binaryName);
45819
+ if (existsSync45(binaryPath)) {
45634
45820
  return binaryPath;
45635
45821
  }
45636
45822
  const { arch, os: os6 } = platformInfo;
@@ -45638,21 +45824,21 @@ async function downloadAstGrep(version2 = DEFAULT_VERSION) {
45638
45824
  const downloadUrl = `https://github.com/${REPO2}/releases/download/${version2}/${assetName}`;
45639
45825
  console.log(`[oh-my-opencode] Downloading ast-grep binary...`);
45640
45826
  try {
45641
- if (!existsSync44(cacheDir)) {
45642
- mkdirSync18(cacheDir, { recursive: true });
45827
+ if (!existsSync45(cacheDir)) {
45828
+ mkdirSync19(cacheDir, { recursive: true });
45643
45829
  }
45644
45830
  const response = await fetch(downloadUrl, { redirect: "follow" });
45645
45831
  if (!response.ok) {
45646
45832
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
45647
45833
  }
45648
- const archivePath = join56(cacheDir, assetName);
45834
+ const archivePath = join57(cacheDir, assetName);
45649
45835
  const arrayBuffer = await response.arrayBuffer();
45650
45836
  await Bun.write(archivePath, arrayBuffer);
45651
45837
  await extractZip(archivePath, cacheDir);
45652
- if (existsSync44(archivePath)) {
45838
+ if (existsSync45(archivePath)) {
45653
45839
  unlinkSync15(archivePath);
45654
45840
  }
45655
- if (process.platform !== "win32" && existsSync44(binaryPath)) {
45841
+ if (process.platform !== "win32" && existsSync45(binaryPath)) {
45656
45842
  chmodSync2(binaryPath, 493);
45657
45843
  }
45658
45844
  console.log(`[oh-my-opencode] ast-grep binary ready.`);
@@ -45703,8 +45889,8 @@ function findSgCliPathSync() {
45703
45889
  const require2 = createRequire4(import.meta.url);
45704
45890
  const cliPkgPath = require2.resolve("@ast-grep/cli/package.json");
45705
45891
  const cliDir = dirname11(cliPkgPath);
45706
- const sgPath = join57(cliDir, binaryName);
45707
- if (existsSync45(sgPath) && isValidBinary(sgPath)) {
45892
+ const sgPath = join58(cliDir, binaryName);
45893
+ if (existsSync46(sgPath) && isValidBinary(sgPath)) {
45708
45894
  return sgPath;
45709
45895
  }
45710
45896
  } catch {}
@@ -45715,8 +45901,8 @@ function findSgCliPathSync() {
45715
45901
  const pkgPath = require2.resolve(`${platformPkg}/package.json`);
45716
45902
  const pkgDir = dirname11(pkgPath);
45717
45903
  const astGrepName = process.platform === "win32" ? "ast-grep.exe" : "ast-grep";
45718
- const binaryPath = join57(pkgDir, astGrepName);
45719
- if (existsSync45(binaryPath) && isValidBinary(binaryPath)) {
45904
+ const binaryPath = join58(pkgDir, astGrepName);
45905
+ if (existsSync46(binaryPath) && isValidBinary(binaryPath)) {
45720
45906
  return binaryPath;
45721
45907
  }
45722
45908
  } catch {}
@@ -45724,7 +45910,7 @@ function findSgCliPathSync() {
45724
45910
  if (process.platform === "darwin") {
45725
45911
  const homebrewPaths = ["/opt/homebrew/bin/sg", "/usr/local/bin/sg"];
45726
45912
  for (const path7 of homebrewPaths) {
45727
- if (existsSync45(path7) && isValidBinary(path7)) {
45913
+ if (existsSync46(path7) && isValidBinary(path7)) {
45728
45914
  return path7;
45729
45915
  }
45730
45916
  }
@@ -45779,11 +45965,11 @@ var DEFAULT_MAX_MATCHES = 500;
45779
45965
 
45780
45966
  // src/tools/ast-grep/cli.ts
45781
45967
  var {spawn: spawn7 } = globalThis.Bun;
45782
- import { existsSync as existsSync46 } from "fs";
45968
+ import { existsSync as existsSync47 } from "fs";
45783
45969
  var resolvedCliPath3 = null;
45784
45970
  var initPromise2 = null;
45785
45971
  async function getAstGrepPath() {
45786
- if (resolvedCliPath3 !== null && existsSync46(resolvedCliPath3)) {
45972
+ if (resolvedCliPath3 !== null && existsSync47(resolvedCliPath3)) {
45787
45973
  return resolvedCliPath3;
45788
45974
  }
45789
45975
  if (initPromise2) {
@@ -45791,7 +45977,7 @@ async function getAstGrepPath() {
45791
45977
  }
45792
45978
  initPromise2 = (async () => {
45793
45979
  const syncPath = findSgCliPathSync();
45794
- if (syncPath && existsSync46(syncPath)) {
45980
+ if (syncPath && existsSync47(syncPath)) {
45795
45981
  resolvedCliPath3 = syncPath;
45796
45982
  setSgCliPath(syncPath);
45797
45983
  return syncPath;
@@ -45825,7 +46011,7 @@ async function runSg(options) {
45825
46011
  const paths = options.paths && options.paths.length > 0 ? options.paths : ["."];
45826
46012
  args.push(...paths);
45827
46013
  let cliPath = getSgCliPath();
45828
- if (!existsSync46(cliPath) && cliPath !== "sg") {
46014
+ if (!existsSync47(cliPath) && cliPath !== "sg") {
45829
46015
  const downloadedPath = await getAstGrepPath();
45830
46016
  if (downloadedPath) {
45831
46017
  cliPath = downloadedPath;
@@ -46089,21 +46275,21 @@ var ast_grep_replace = tool({
46089
46275
  var {spawn: spawn9 } = globalThis.Bun;
46090
46276
 
46091
46277
  // src/tools/grep/constants.ts
46092
- import { existsSync as existsSync48 } from "fs";
46093
- import { join as join59, dirname as dirname12 } from "path";
46278
+ import { existsSync as existsSync49 } from "fs";
46279
+ import { join as join60, dirname as dirname12 } from "path";
46094
46280
  import { spawnSync as spawnSync2 } from "child_process";
46095
46281
 
46096
46282
  // src/tools/grep/downloader.ts
46097
46283
  init_shared();
46098
- import { existsSync as existsSync47, mkdirSync as mkdirSync19, chmodSync as chmodSync3, unlinkSync as unlinkSync16, readdirSync as readdirSync14 } from "fs";
46099
- import { join as join58 } from "path";
46284
+ import { existsSync as existsSync48, mkdirSync as mkdirSync20, chmodSync as chmodSync3, unlinkSync as unlinkSync16, readdirSync as readdirSync14 } from "fs";
46285
+ import { join as join59 } from "path";
46100
46286
  var {spawn: spawn8 } = globalThis.Bun;
46101
46287
  function findFileRecursive(dir, filename) {
46102
46288
  try {
46103
46289
  const entries = readdirSync14(dir, { withFileTypes: true, recursive: true });
46104
46290
  for (const entry of entries) {
46105
46291
  if (entry.isFile() && entry.name === filename) {
46106
- return join58(entry.parentPath ?? dir, entry.name);
46292
+ return join59(entry.parentPath ?? dir, entry.name);
46107
46293
  }
46108
46294
  }
46109
46295
  } catch {
@@ -46124,11 +46310,11 @@ function getPlatformKey() {
46124
46310
  }
46125
46311
  function getInstallDir() {
46126
46312
  const homeDir = process.env.HOME || process.env.USERPROFILE || ".";
46127
- return join58(homeDir, ".cache", "oh-my-opencode", "bin");
46313
+ return join59(homeDir, ".cache", "oh-my-opencode", "bin");
46128
46314
  }
46129
46315
  function getRgPath() {
46130
46316
  const isWindows2 = process.platform === "win32";
46131
- return join58(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
46317
+ return join59(getInstallDir(), isWindows2 ? "rg.exe" : "rg");
46132
46318
  }
46133
46319
  async function downloadFile(url2, destPath) {
46134
46320
  const response = await fetch(url2);
@@ -46162,7 +46348,7 @@ async function extractZip2(archivePath, destDir) {
46162
46348
  const binaryName = process.platform === "win32" ? "rg.exe" : "rg";
46163
46349
  const foundPath = findFileRecursive(destDir, binaryName);
46164
46350
  if (foundPath) {
46165
- const destPath = join58(destDir, binaryName);
46351
+ const destPath = join59(destDir, binaryName);
46166
46352
  if (foundPath !== destPath) {
46167
46353
  const { renameSync: renameSync5 } = await import("fs");
46168
46354
  renameSync5(foundPath, destPath);
@@ -46177,13 +46363,13 @@ async function downloadAndInstallRipgrep() {
46177
46363
  }
46178
46364
  const installDir = getInstallDir();
46179
46365
  const rgPath = getRgPath();
46180
- if (existsSync47(rgPath)) {
46366
+ if (existsSync48(rgPath)) {
46181
46367
  return rgPath;
46182
46368
  }
46183
- mkdirSync19(installDir, { recursive: true });
46369
+ mkdirSync20(installDir, { recursive: true });
46184
46370
  const filename = `ripgrep-${RG_VERSION}-${config3.platform}.${config3.extension}`;
46185
46371
  const url2 = `https://github.com/BurntSushi/ripgrep/releases/download/${RG_VERSION}/${filename}`;
46186
- const archivePath = join58(installDir, filename);
46372
+ const archivePath = join59(installDir, filename);
46187
46373
  try {
46188
46374
  await downloadFile(url2, archivePath);
46189
46375
  if (config3.extension === "tar.gz") {
@@ -46194,12 +46380,12 @@ async function downloadAndInstallRipgrep() {
46194
46380
  if (process.platform !== "win32") {
46195
46381
  chmodSync3(rgPath, 493);
46196
46382
  }
46197
- if (!existsSync47(rgPath)) {
46383
+ if (!existsSync48(rgPath)) {
46198
46384
  throw new Error("\u63D0\u53D6\u540E\u672A\u627E\u5230 ripgrep \u4E8C\u8FDB\u5236\u6587\u4EF6");
46199
46385
  }
46200
46386
  return rgPath;
46201
46387
  } finally {
46202
- if (existsSync47(archivePath)) {
46388
+ if (existsSync48(archivePath)) {
46203
46389
  try {
46204
46390
  unlinkSync16(archivePath);
46205
46391
  } catch {}
@@ -46208,7 +46394,7 @@ async function downloadAndInstallRipgrep() {
46208
46394
  }
46209
46395
  function getInstalledRipgrepPath() {
46210
46396
  const rgPath = getRgPath();
46211
- return existsSync47(rgPath) ? rgPath : null;
46397
+ return existsSync48(rgPath) ? rgPath : null;
46212
46398
  }
46213
46399
 
46214
46400
  // src/tools/grep/constants.ts
@@ -46232,7 +46418,7 @@ function findExecutable(name) {
46232
46418
  continue;
46233
46419
  }
46234
46420
  }
46235
- if (existsSync48(trimmed)) {
46421
+ if (existsSync49(trimmed)) {
46236
46422
  return trimmed;
46237
46423
  }
46238
46424
  }
@@ -46247,14 +46433,14 @@ function getOpenCodeBundledRg() {
46247
46433
  const isWindows2 = process.platform === "win32";
46248
46434
  const rgName = isWindows2 ? "rg.exe" : "rg";
46249
46435
  const candidates = [
46250
- join59(getDataDir(), "opencode", "bin", rgName),
46251
- join59(execDir, rgName),
46252
- join59(execDir, "bin", rgName),
46253
- join59(execDir, "..", "bin", rgName),
46254
- join59(execDir, "..", "libexec", rgName)
46436
+ join60(getDataDir(), "opencode", "bin", rgName),
46437
+ join60(execDir, rgName),
46438
+ join60(execDir, "bin", rgName),
46439
+ join60(execDir, "..", "bin", rgName),
46440
+ join60(execDir, "..", "libexec", rgName)
46255
46441
  ];
46256
46442
  for (const candidate of candidates) {
46257
- if (existsSync48(candidate)) {
46443
+ if (existsSync49(candidate)) {
46258
46444
  return candidate;
46259
46445
  }
46260
46446
  }
@@ -46716,8 +46902,8 @@ var glob = tool({
46716
46902
  init_shared();
46717
46903
  init_file_utils();
46718
46904
  init_shared();
46719
- import { existsSync as existsSync49, readdirSync as readdirSync15, readFileSync as readFileSync36 } from "fs";
46720
- import { join as join60, basename as basename4, dirname as dirname13 } from "path";
46905
+ import { existsSync as existsSync50, readdirSync as readdirSync15, readFileSync as readFileSync37 } from "fs";
46906
+ import { join as join61, basename as basename4, dirname as dirname13 } from "path";
46721
46907
  // src/features/builtin-commands/templates/init-deep.ts
46722
46908
  var INIT_DEEP_TEMPLATE = `# /init-deep
46723
46909
 
@@ -47862,7 +48048,7 @@ function loadBuiltinCommands(disabledCommands) {
47862
48048
  }
47863
48049
  // src/tools/slashcommand/tools.ts
47864
48050
  function discoverCommandsFromDir2(commandsDir, scope) {
47865
- if (!existsSync49(commandsDir)) {
48051
+ if (!existsSync50(commandsDir)) {
47866
48052
  return [];
47867
48053
  }
47868
48054
  const entries = readdirSync15(commandsDir, { withFileTypes: true });
@@ -47870,10 +48056,10 @@ function discoverCommandsFromDir2(commandsDir, scope) {
47870
48056
  for (const entry of entries) {
47871
48057
  if (!isMarkdownFile(entry))
47872
48058
  continue;
47873
- const commandPath = join60(commandsDir, entry.name);
48059
+ const commandPath = join61(commandsDir, entry.name);
47874
48060
  const commandName = basename4(entry.name, ".md");
47875
48061
  try {
47876
- const content = readFileSync36(commandPath, "utf-8");
48062
+ const content = readFileSync37(commandPath, "utf-8");
47877
48063
  const { data, body } = parseFrontmatter(content);
47878
48064
  const isOpencodeSource = scope === "opencode" || scope === "opencode-project";
47879
48065
  const metadata = {
@@ -47899,10 +48085,10 @@ function discoverCommandsFromDir2(commandsDir, scope) {
47899
48085
  }
47900
48086
  function discoverCommandsSync(disabledCommands) {
47901
48087
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
47902
- const userCommandsDir = join60(getClaudeConfigDir(), "commands");
47903
- const projectCommandsDir = join60(process.cwd(), ".claude", "commands");
47904
- const opencodeGlobalDir = join60(configDir, "command");
47905
- const opencodeProjectDir = join60(process.cwd(), ".opencode", "command");
48088
+ const userCommandsDir = join61(getClaudeConfigDir(), "commands");
48089
+ const projectCommandsDir = join61(process.cwd(), ".claude", "commands");
48090
+ const opencodeGlobalDir = join61(configDir, "command");
48091
+ const opencodeProjectDir = join61(process.cwd(), ".opencode", "command");
47906
48092
  const userCommands = discoverCommandsFromDir2(userCommandsDir, "user");
47907
48093
  const opencodeGlobalCommands = discoverCommandsFromDir2(opencodeGlobalDir, "opencode");
47908
48094
  const projectCommands = discoverCommandsFromDir2(projectCommandsDir, "project");
@@ -48102,13 +48288,13 @@ var slashcommand = createSlashcommandTool();
48102
48288
  // src/tools/session-manager/constants.ts
48103
48289
  init_data_path();
48104
48290
  init_shared();
48105
- import { join as join61 } from "path";
48291
+ import { join as join62 } from "path";
48106
48292
  var OPENCODE_STORAGE11 = getOpenCodeStorageDir();
48107
- var MESSAGE_STORAGE4 = join61(OPENCODE_STORAGE11, "message");
48108
- var PART_STORAGE4 = join61(OPENCODE_STORAGE11, "part");
48109
- var SESSION_STORAGE = join61(OPENCODE_STORAGE11, "session");
48110
- var TODO_DIR2 = join61(getClaudeConfigDir(), "todos");
48111
- var TRANSCRIPT_DIR2 = join61(getClaudeConfigDir(), "transcripts");
48293
+ var MESSAGE_STORAGE4 = join62(OPENCODE_STORAGE11, "message");
48294
+ var PART_STORAGE4 = join62(OPENCODE_STORAGE11, "part");
48295
+ var SESSION_STORAGE = join62(OPENCODE_STORAGE11, "session");
48296
+ var TODO_DIR2 = join62(getClaudeConfigDir(), "todos");
48297
+ var TRANSCRIPT_DIR2 = join62(getClaudeConfigDir(), "transcripts");
48112
48298
  var SESSION_LIST_DESCRIPTION = `\u5217\u51FA\u6240\u6709 OpenCode session\uFF0C\u652F\u6301\u53EF\u9009\u8FC7\u6EE4\u3002
48113
48299
 
48114
48300
  \u8FD4\u56DE\u53EF\u7528\u7684 session ID \u5217\u8868\uFF0C\u5305\u542B\u6D88\u606F\u6570\u91CF\u3001\u65E5\u671F\u8303\u56F4\u548C\u4F7F\u7528\u8FC7\u7684 agents \u7B49\u5143\u6570\u636E\u3002
@@ -48181,11 +48367,11 @@ Has Todos: Yes (12 items, 8 completed)
48181
48367
  Has Transcript: Yes (234 entries)`;
48182
48368
 
48183
48369
  // src/tools/session-manager/storage.ts
48184
- import { existsSync as existsSync50, readdirSync as readdirSync16 } from "fs";
48370
+ import { existsSync as existsSync51, readdirSync as readdirSync16 } from "fs";
48185
48371
  import { readdir, readFile } from "fs/promises";
48186
- import { join as join62 } from "path";
48372
+ import { join as join63 } from "path";
48187
48373
  async function getMainSessions(options) {
48188
- if (!existsSync50(SESSION_STORAGE))
48374
+ if (!existsSync51(SESSION_STORAGE))
48189
48375
  return [];
48190
48376
  const sessions = [];
48191
48377
  try {
@@ -48193,13 +48379,13 @@ async function getMainSessions(options) {
48193
48379
  for (const projectDir of projectDirs) {
48194
48380
  if (!projectDir.isDirectory())
48195
48381
  continue;
48196
- const projectPath = join62(SESSION_STORAGE, projectDir.name);
48382
+ const projectPath = join63(SESSION_STORAGE, projectDir.name);
48197
48383
  const sessionFiles = await readdir(projectPath);
48198
48384
  for (const file2 of sessionFiles) {
48199
48385
  if (!file2.endsWith(".json"))
48200
48386
  continue;
48201
48387
  try {
48202
- const content = await readFile(join62(projectPath, file2), "utf-8");
48388
+ const content = await readFile(join63(projectPath, file2), "utf-8");
48203
48389
  const meta = JSON.parse(content);
48204
48390
  if (meta.parentID)
48205
48391
  continue;
@@ -48217,7 +48403,7 @@ async function getMainSessions(options) {
48217
48403
  return sessions.sort((a, b) => b.time.updated - a.time.updated);
48218
48404
  }
48219
48405
  async function getAllSessions() {
48220
- if (!existsSync50(MESSAGE_STORAGE4))
48406
+ if (!existsSync51(MESSAGE_STORAGE4))
48221
48407
  return [];
48222
48408
  const sessions = [];
48223
48409
  async function scanDirectory(dir) {
@@ -48225,7 +48411,7 @@ async function getAllSessions() {
48225
48411
  const entries = await readdir(dir, { withFileTypes: true });
48226
48412
  for (const entry of entries) {
48227
48413
  if (entry.isDirectory()) {
48228
- const sessionPath = join62(dir, entry.name);
48414
+ const sessionPath = join63(dir, entry.name);
48229
48415
  const files = await readdir(sessionPath);
48230
48416
  if (files.some((f) => f.endsWith(".json"))) {
48231
48417
  sessions.push(entry.name);
@@ -48242,16 +48428,16 @@ async function getAllSessions() {
48242
48428
  return [...new Set(sessions)];
48243
48429
  }
48244
48430
  function getMessageDir6(sessionID) {
48245
- if (!existsSync50(MESSAGE_STORAGE4))
48431
+ if (!existsSync51(MESSAGE_STORAGE4))
48246
48432
  return "";
48247
- const directPath = join62(MESSAGE_STORAGE4, sessionID);
48248
- if (existsSync50(directPath)) {
48433
+ const directPath = join63(MESSAGE_STORAGE4, sessionID);
48434
+ if (existsSync51(directPath)) {
48249
48435
  return directPath;
48250
48436
  }
48251
48437
  try {
48252
48438
  for (const dir of readdirSync16(MESSAGE_STORAGE4)) {
48253
- const sessionPath = join62(MESSAGE_STORAGE4, dir, sessionID);
48254
- if (existsSync50(sessionPath)) {
48439
+ const sessionPath = join63(MESSAGE_STORAGE4, dir, sessionID);
48440
+ if (existsSync51(sessionPath)) {
48255
48441
  return sessionPath;
48256
48442
  }
48257
48443
  }
@@ -48265,7 +48451,7 @@ function sessionExists(sessionID) {
48265
48451
  }
48266
48452
  async function readSessionMessages(sessionID) {
48267
48453
  const messageDir = getMessageDir6(sessionID);
48268
- if (!messageDir || !existsSync50(messageDir))
48454
+ if (!messageDir || !existsSync51(messageDir))
48269
48455
  return [];
48270
48456
  const messages = [];
48271
48457
  try {
@@ -48274,7 +48460,7 @@ async function readSessionMessages(sessionID) {
48274
48460
  if (!file2.endsWith(".json"))
48275
48461
  continue;
48276
48462
  try {
48277
- const content = await readFile(join62(messageDir, file2), "utf-8");
48463
+ const content = await readFile(join63(messageDir, file2), "utf-8");
48278
48464
  const meta = JSON.parse(content);
48279
48465
  const parts = await readParts2(meta.id);
48280
48466
  messages.push({
@@ -48300,8 +48486,8 @@ async function readSessionMessages(sessionID) {
48300
48486
  });
48301
48487
  }
48302
48488
  async function readParts2(messageID) {
48303
- const partDir = join62(PART_STORAGE4, messageID);
48304
- if (!existsSync50(partDir))
48489
+ const partDir = join63(PART_STORAGE4, messageID);
48490
+ if (!existsSync51(partDir))
48305
48491
  return [];
48306
48492
  const parts = [];
48307
48493
  try {
@@ -48310,7 +48496,7 @@ async function readParts2(messageID) {
48310
48496
  if (!file2.endsWith(".json"))
48311
48497
  continue;
48312
48498
  try {
48313
- const content = await readFile(join62(partDir, file2), "utf-8");
48499
+ const content = await readFile(join63(partDir, file2), "utf-8");
48314
48500
  parts.push(JSON.parse(content));
48315
48501
  } catch {
48316
48502
  continue;
@@ -48322,14 +48508,14 @@ async function readParts2(messageID) {
48322
48508
  return parts.sort((a, b) => a.id.localeCompare(b.id));
48323
48509
  }
48324
48510
  async function readSessionTodos(sessionID) {
48325
- if (!existsSync50(TODO_DIR2))
48511
+ if (!existsSync51(TODO_DIR2))
48326
48512
  return [];
48327
48513
  try {
48328
48514
  const allFiles = await readdir(TODO_DIR2);
48329
48515
  const todoFiles = allFiles.filter((f) => f.includes(sessionID) && f.endsWith(".json"));
48330
48516
  for (const file2 of todoFiles) {
48331
48517
  try {
48332
- const content = await readFile(join62(TODO_DIR2, file2), "utf-8");
48518
+ const content = await readFile(join63(TODO_DIR2, file2), "utf-8");
48333
48519
  const data = JSON.parse(content);
48334
48520
  if (Array.isArray(data)) {
48335
48521
  return data.map((item) => ({
@@ -48349,10 +48535,10 @@ async function readSessionTodos(sessionID) {
48349
48535
  return [];
48350
48536
  }
48351
48537
  async function readSessionTranscript(sessionID) {
48352
- if (!existsSync50(TRANSCRIPT_DIR2))
48538
+ if (!existsSync51(TRANSCRIPT_DIR2))
48353
48539
  return 0;
48354
- const transcriptFile = join62(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
48355
- if (!existsSync50(transcriptFile))
48540
+ const transcriptFile = join63(TRANSCRIPT_DIR2, `${sessionID}.jsonl`);
48541
+ if (!existsSync51(transcriptFile))
48356
48542
  return 0;
48357
48543
  try {
48358
48544
  const content = await readFile(transcriptFile, "utf-8");
@@ -49175,6 +49361,7 @@ var BACKGROUND_OUTPUT_DESCRIPTION = `\u83B7\u53D6\u540E\u53F0\u4EFB\u52A1\u7684\
49175
49361
  var BACKGROUND_CANCEL_DESCRIPTION = `\u53D6\u6D88\u6B63\u5728\u8FD0\u884C\u7684\u540E\u53F0\u4EFB\u52A1\u3002\u4F7F\u7528 all=true \u53EF\u5728\u6700\u7EC8\u56DE\u7B54\u524D\u53D6\u6D88\u6240\u6709\u4EFB\u52A1\u3002`;
49176
49362
 
49177
49363
  // src/tools/background-task/tools.ts
49364
+ init_claude_code_session_state();
49178
49365
  init_logger();
49179
49366
  init_session_cursor();
49180
49367
  init_agent_display_names();
@@ -49559,20 +49746,21 @@ var CALL_OMO_AGENT_DESCRIPTION = `\u542F\u52A8\u6DF1\u5EA6\u63A2\u7D22/\u77E5\u8
49559
49746
 
49560
49747
  \u4F20\u5165 \`session_id=<id>\` \u53EF\u7EE7\u7EED\u4E4B\u524D\u7684 agent\uFF0C\u4FDD\u7559\u5B8C\u6574\u4E0A\u4E0B\u6587\u3002Prompts \u5FC5\u987B\u4E3A\u4E2D\u6587\u3002\u4F7F\u7528 \`background_output\` \u83B7\u53D6\u5F02\u6B65\u7ED3\u679C\u3002`;
49561
49748
  // src/tools/call-omo-agent/tools.ts
49562
- import { existsSync as existsSync51, readdirSync as readdirSync17 } from "fs";
49563
- import { join as join63 } from "path";
49749
+ import { existsSync as existsSync52, readdirSync as readdirSync17 } from "fs";
49750
+ import { join as join64 } from "path";
49564
49751
  init_shared();
49565
49752
  init_agent_display_names();
49566
49753
  init_session_cursor();
49754
+ init_claude_code_session_state();
49567
49755
  function getMessageDir7(sessionID) {
49568
- if (!existsSync51(MESSAGE_STORAGE))
49756
+ if (!existsSync52(MESSAGE_STORAGE))
49569
49757
  return null;
49570
- const directPath = join63(MESSAGE_STORAGE, sessionID);
49571
- if (existsSync51(directPath))
49758
+ const directPath = join64(MESSAGE_STORAGE, sessionID);
49759
+ if (existsSync52(directPath))
49572
49760
  return directPath;
49573
49761
  for (const dir of readdirSync17(MESSAGE_STORAGE)) {
49574
- const sessionPath = join63(MESSAGE_STORAGE, dir, sessionID);
49575
- if (existsSync51(sessionPath))
49762
+ const sessionPath = join64(MESSAGE_STORAGE, dir, sessionID);
49763
+ if (existsSync52(sessionPath))
49576
49764
  return sessionPath;
49577
49765
  }
49578
49766
  return null;
@@ -49998,8 +50186,8 @@ function createLookAt(ctx) {
49998
50186
  }
49999
50187
  // src/tools/delegate-task/tools.ts
50000
50188
  init_constants();
50001
- import { existsSync as existsSync52, readdirSync as readdirSync18 } from "fs";
50002
- import { join as join64 } from "path";
50189
+ import { existsSync as existsSync53, readdirSync as readdirSync18 } from "fs";
50190
+ import { join as join65 } from "path";
50003
50191
 
50004
50192
  // src/features/task-toast-manager/manager.ts
50005
50193
  class TaskToastManager {
@@ -50175,10 +50363,12 @@ function initTaskToastManager(client2, concurrencyManager) {
50175
50363
  return instance;
50176
50364
  }
50177
50365
  // src/tools/delegate-task/tools.ts
50366
+ init_claude_code_session_state();
50178
50367
  init_shared();
50179
50368
  init_agent_display_names();
50180
50369
  init_runtime_fallback();
50181
50370
  init_model_health_registry();
50371
+ init_agent_identity_resolver();
50182
50372
  var SISYPHUS_JUNIOR_AGENT = "\u6267\u884C\u52A9\u7406";
50183
50373
  var MAX_LOOP_ATTEMPTS = 10;
50184
50374
  function sleep(ms) {
@@ -50205,14 +50395,14 @@ function parseFallbackModelEntries(entries) {
50205
50395
  });
50206
50396
  }
50207
50397
  function getMessageDir8(sessionID) {
50208
- if (!existsSync52(MESSAGE_STORAGE))
50398
+ if (!existsSync53(MESSAGE_STORAGE))
50209
50399
  return null;
50210
- const directPath = join64(MESSAGE_STORAGE, sessionID);
50211
- if (existsSync52(directPath))
50400
+ const directPath = join65(MESSAGE_STORAGE, sessionID);
50401
+ if (existsSync53(directPath))
50212
50402
  return directPath;
50213
50403
  for (const dir of readdirSync18(MESSAGE_STORAGE)) {
50214
- const sessionPath = join64(MESSAGE_STORAGE, dir, sessionID);
50215
- if (existsSync52(sessionPath))
50404
+ const sessionPath = join65(MESSAGE_STORAGE, dir, sessionID);
50405
+ if (existsSync53(sessionPath))
50216
50406
  return sessionPath;
50217
50407
  }
50218
50408
  return null;
@@ -50294,18 +50484,30 @@ function buildSystemContent(input) {
50294
50484
 
50295
50485
  `);
50296
50486
  }
50297
- function extractResumeInfoFromMessages(messages) {
50298
- let agent;
50299
- let model;
50487
+ function extractResumeInfoFromMessages(sessionID, messages) {
50488
+ const resolvedAgent = resolveCurrentAgent(sessionID);
50489
+ if (resolvedAgent) {
50490
+ for (let i = messages.length - 1;i >= 0; i--) {
50491
+ const info = messages[i].info;
50492
+ if (info?.model || info?.modelID && info?.providerID) {
50493
+ return {
50494
+ agent: resolvedAgent,
50495
+ model: info.model ?? (info.providerID && info.modelID ? { providerID: info.providerID, modelID: info.modelID } : undefined)
50496
+ };
50497
+ }
50498
+ }
50499
+ return { agent: resolvedAgent, model: undefined };
50500
+ }
50300
50501
  for (let i = messages.length - 1;i >= 0; i--) {
50301
50502
  const info = messages[i].info;
50302
50503
  if (info?.role === "assistant" && (info?.agent || info?.model || info?.modelID && info?.providerID)) {
50303
- agent = info.agent;
50304
- model = info.model ?? (info.providerID && info.modelID ? { providerID: info.providerID, modelID: info.modelID } : undefined);
50305
- break;
50504
+ return {
50505
+ agent: info.agent,
50506
+ model: info.model ?? (info.providerID && info.modelID ? { providerID: info.providerID, modelID: info.modelID } : undefined)
50507
+ };
50306
50508
  }
50307
50509
  }
50308
- return { agent, model };
50510
+ return { agent: undefined, model: undefined };
50309
50511
  }
50310
50512
  async function pollTaskCompletion(client2, sessionID, maxWaitMs = 120000, pollIntervalMs = 2000) {
50311
50513
  const startTime = Date.now();
@@ -50483,7 +50685,7 @@ Agent \u7EE7\u7EED\u6267\u884C\uFF0C\u4FDD\u7559\u5B8C\u6574\u4E0A\u4E0B\u6587\u
50483
50685
  try {
50484
50686
  const messagesResp = await client2.session.messages({ path: { id: args.session_id } });
50485
50687
  const messages2 = messagesResp.data ?? [];
50486
- const resumeInfo = extractResumeInfoFromMessages(messages2);
50688
+ const resumeInfo = extractResumeInfoFromMessages(args.session_id, messages2);
50487
50689
  resumeAgent = resumeInfo.agent;
50488
50690
  resumeModel = resumeInfo.model;
50489
50691
  } catch {
@@ -51308,8 +51510,10 @@ class PerformanceAggregator {
51308
51510
  }
51309
51511
 
51310
51512
  // src/features/background-agent/manager.ts
51311
- import { existsSync as existsSync53, readdirSync as readdirSync19 } from "fs";
51312
- import { join as join65 } from "path";
51513
+ init_claude_code_session_state();
51514
+ init_agent_identity_resolver();
51515
+ import { existsSync as existsSync54, readdirSync as readdirSync19 } from "fs";
51516
+ import { join as join66 } from "path";
51313
51517
  var TASK_TTL_MS = 30 * 60 * 1000;
51314
51518
  var MIN_STABILITY_TIME_MS = 10 * 1000;
51315
51519
  var DEFAULT_STALE_TIMEOUT_MS = 120000;
@@ -52102,15 +52306,15 @@ ${perfSnapshot ? `| \u6392\u961F ${PerfTimer.formatDuration(new Date(0), new Dat
52102
52306
  \u4F7F\u7528 \`background_output(task_id="${task.id}")\` \u5728\u51C6\u5907\u5C31\u7EEA\u65F6\u83B7\u53D6\u6B64\u7ED3\u679C\u3002
52103
52307
  </system-reminder>`;
52104
52308
  }
52105
- let agent = task.parentAgent;
52309
+ const currentParentAgent = resolveCurrentAgent(task.parentSessionID);
52310
+ const agent = currentParentAgent ?? task.parentAgent;
52106
52311
  let model;
52107
52312
  try {
52108
52313
  const messagesResp = await this.client.session.messages({ path: { id: task.parentSessionID } });
52109
52314
  const messages = messagesResp.data ?? [];
52110
52315
  for (let i = messages.length - 1;i >= 0; i--) {
52111
52316
  const info = messages[i].info;
52112
- if (info?.agent || info?.model || info?.modelID && info?.providerID) {
52113
- agent = info.agent ?? task.parentAgent;
52317
+ if (info?.model || info?.modelID && info?.providerID) {
52114
52318
  model = info.model ?? (info.providerID && info.modelID ? { providerID: info.providerID, modelID: info.modelID } : undefined);
52115
52319
  break;
52116
52320
  }
@@ -52118,7 +52322,6 @@ ${perfSnapshot ? `| \u6392\u961F ${PerfTimer.formatDuration(new Date(0), new Dat
52118
52322
  } catch {
52119
52323
  const messageDir = getMessageDir9(task.parentSessionID);
52120
52324
  const currentMessage = messageDir ? findNearestAssistantMessage(messageDir) : null;
52121
- agent = currentMessage?.agent ?? task.parentAgent;
52122
52325
  model = currentMessage?.model?.providerID && currentMessage?.model?.modelID ? { providerID: currentMessage.model.providerID, modelID: currentMessage.model.modelID } : undefined;
52123
52326
  }
52124
52327
  log("[background-agent] notifyParentSession context:", {
@@ -52483,14 +52686,14 @@ function registerProcessSignal(signal, handler, exitAfter) {
52483
52686
  return listener;
52484
52687
  }
52485
52688
  function getMessageDir9(sessionID) {
52486
- if (!existsSync53(MESSAGE_STORAGE))
52689
+ if (!existsSync54(MESSAGE_STORAGE))
52487
52690
  return null;
52488
- const directPath = join65(MESSAGE_STORAGE, sessionID);
52489
- if (existsSync53(directPath))
52691
+ const directPath = join66(MESSAGE_STORAGE, sessionID);
52692
+ if (existsSync54(directPath))
52490
52693
  return directPath;
52491
52694
  for (const dir of readdirSync19(MESSAGE_STORAGE)) {
52492
- const sessionPath = join65(MESSAGE_STORAGE, dir, sessionID);
52493
- if (existsSync53(sessionPath))
52695
+ const sessionPath = join66(MESSAGE_STORAGE, dir, sessionID);
52696
+ if (existsSync54(sessionPath))
52494
52697
  return sessionPath;
52495
52698
  }
52496
52699
  return null;
@@ -71715,7 +71918,7 @@ init_file_utils();
71715
71918
  init_shared();
71716
71919
  init_logger();
71717
71920
  import { promises as fs11 } from "fs";
71718
- import { join as join67, basename as basename6 } from "path";
71921
+ import { join as join68, basename as basename6 } from "path";
71719
71922
  async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix = "") {
71720
71923
  try {
71721
71924
  await fs11.access(commandsDir);
@@ -71745,7 +71948,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
71745
71948
  if (entry.isDirectory()) {
71746
71949
  if (entry.name.startsWith("."))
71747
71950
  continue;
71748
- const subDirPath = join67(commandsDir, entry.name);
71951
+ const subDirPath = join68(commandsDir, entry.name);
71749
71952
  const subPrefix = prefix ? `${prefix}:${entry.name}` : entry.name;
71750
71953
  const subCommands = await loadCommandsFromDir(subDirPath, scope, visited, subPrefix);
71751
71954
  commands2.push(...subCommands);
@@ -71753,7 +71956,7 @@ async function loadCommandsFromDir(commandsDir, scope, visited = new Set, prefix
71753
71956
  }
71754
71957
  if (!isMarkdownFile(entry))
71755
71958
  continue;
71756
- const commandPath = join67(commandsDir, entry.name);
71959
+ const commandPath = join68(commandsDir, entry.name);
71757
71960
  const baseCommandName = basename6(entry.name, ".md");
71758
71961
  const commandName = prefix ? `${prefix}:${baseCommandName}` : baseCommandName;
71759
71962
  try {
@@ -71800,23 +72003,23 @@ function commandsToRecord(commands2) {
71800
72003
  return result;
71801
72004
  }
71802
72005
  async function loadUserCommands() {
71803
- const userCommandsDir = join67(getClaudeConfigDir(), "commands");
72006
+ const userCommandsDir = join68(getClaudeConfigDir(), "commands");
71804
72007
  const commands2 = await loadCommandsFromDir(userCommandsDir, "user");
71805
72008
  return commandsToRecord(commands2);
71806
72009
  }
71807
72010
  async function loadProjectCommands() {
71808
- const projectCommandsDir = join67(process.cwd(), ".claude", "commands");
72011
+ const projectCommandsDir = join68(process.cwd(), ".claude", "commands");
71809
72012
  const commands2 = await loadCommandsFromDir(projectCommandsDir, "project");
71810
72013
  return commandsToRecord(commands2);
71811
72014
  }
71812
72015
  async function loadOpencodeGlobalCommands() {
71813
72016
  const configDir = getOpenCodeConfigDir({ binary: "opencode" });
71814
- const opencodeCommandsDir = join67(configDir, "command");
72017
+ const opencodeCommandsDir = join68(configDir, "command");
71815
72018
  const commands2 = await loadCommandsFromDir(opencodeCommandsDir, "opencode");
71816
72019
  return commandsToRecord(commands2);
71817
72020
  }
71818
72021
  async function loadOpencodeProjectCommands() {
71819
- const opencodeProjectDir = join67(process.cwd(), ".opencode", "command");
72022
+ const opencodeProjectDir = join68(process.cwd(), ".opencode", "command");
71820
72023
  const commands2 = await loadCommandsFromDir(opencodeProjectDir, "opencode-project");
71821
72024
  return commandsToRecord(commands2);
71822
72025
  }
@@ -71824,8 +72027,8 @@ async function loadOpencodeProjectCommands() {
71824
72027
  init_frontmatter();
71825
72028
  init_file_utils();
71826
72029
  init_shared();
71827
- import { existsSync as existsSync55, readdirSync as readdirSync20, readFileSync as readFileSync38 } from "fs";
71828
- import { join as join68, basename as basename7 } from "path";
72030
+ import { existsSync as existsSync56, readdirSync as readdirSync20, readFileSync as readFileSync39 } from "fs";
72031
+ import { join as join69, basename as basename7 } from "path";
71829
72032
  function parseToolsConfig(toolsStr) {
71830
72033
  if (!toolsStr)
71831
72034
  return;
@@ -71839,7 +72042,7 @@ function parseToolsConfig(toolsStr) {
71839
72042
  return result;
71840
72043
  }
71841
72044
  function loadAgentsFromDir(agentsDir, scope, leConfig) {
71842
- if (!existsSync55(agentsDir)) {
72045
+ if (!existsSync56(agentsDir)) {
71843
72046
  return [];
71844
72047
  }
71845
72048
  const entries = readdirSync20(agentsDir, { withFileTypes: true });
@@ -71847,10 +72050,10 @@ function loadAgentsFromDir(agentsDir, scope, leConfig) {
71847
72050
  for (const entry of entries) {
71848
72051
  if (!isMarkdownFile(entry))
71849
72052
  continue;
71850
- const agentPath = join68(agentsDir, entry.name);
72053
+ const agentPath = join69(agentsDir, entry.name);
71851
72054
  const agentName = basename7(entry.name, ".md");
71852
72055
  try {
71853
- const content = readFileSync38(agentPath, "utf-8");
72056
+ const content = readFileSync39(agentPath, "utf-8");
71854
72057
  const { data, body } = parseFrontmatter(content);
71855
72058
  const name = data.name || agentName;
71856
72059
  const originalDescription = data.description || "";
@@ -71879,7 +72082,7 @@ function loadAgentsFromDir(agentsDir, scope, leConfig) {
71879
72082
  return agents;
71880
72083
  }
71881
72084
  function loadUserAgents(leConfig) {
71882
- const userAgentsDir = join68(getClaudeConfigDir(), "agents");
72085
+ const userAgentsDir = join69(getClaudeConfigDir(), "agents");
71883
72086
  const agents = loadAgentsFromDir(userAgentsDir, "user", leConfig);
71884
72087
  const result = {};
71885
72088
  for (const agent of agents) {
@@ -71888,7 +72091,7 @@ function loadUserAgents(leConfig) {
71888
72091
  return result;
71889
72092
  }
71890
72093
  function loadProjectAgents(leConfig) {
71891
- const projectAgentsDir = join68(process.cwd(), ".claude", "agents");
72094
+ const projectAgentsDir = join69(process.cwd(), ".claude", "agents");
71892
72095
  const agents = loadAgentsFromDir(projectAgentsDir, "project", leConfig);
71893
72096
  const result = {};
71894
72097
  for (const agent of agents) {
@@ -71900,18 +72103,18 @@ function loadProjectAgents(leConfig) {
71900
72103
  init_frontmatter();
71901
72104
  init_file_utils();
71902
72105
  init_logger();
71903
- import { existsSync as existsSync56, readdirSync as readdirSync21, readFileSync as readFileSync39 } from "fs";
72106
+ import { existsSync as existsSync57, readdirSync as readdirSync21, readFileSync as readFileSync40 } from "fs";
71904
72107
  import { homedir as homedir14 } from "os";
71905
- import { join as join69, basename as basename8 } from "path";
72108
+ import { join as join70, basename as basename8 } from "path";
71906
72109
  var CLAUDE_PLUGIN_ROOT_VAR = "${CLAUDE_PLUGIN_ROOT}";
71907
72110
  function getPluginsBaseDir() {
71908
72111
  if (process.env.CLAUDE_PLUGINS_HOME) {
71909
72112
  return process.env.CLAUDE_PLUGINS_HOME;
71910
72113
  }
71911
- return join69(homedir14(), ".claude", "plugins");
72114
+ return join70(homedir14(), ".claude", "plugins");
71912
72115
  }
71913
72116
  function getInstalledPluginsPath() {
71914
- return join69(getPluginsBaseDir(), "installed_plugins.json");
72117
+ return join70(getPluginsBaseDir(), "installed_plugins.json");
71915
72118
  }
71916
72119
  function resolvePluginPath(path8, pluginRoot) {
71917
72120
  return path8.replace(CLAUDE_PLUGIN_ROOT_VAR, pluginRoot);
@@ -71936,11 +72139,11 @@ function resolvePluginPaths(obj, pluginRoot) {
71936
72139
  }
71937
72140
  function loadInstalledPlugins() {
71938
72141
  const dbPath = getInstalledPluginsPath();
71939
- if (!existsSync56(dbPath)) {
72142
+ if (!existsSync57(dbPath)) {
71940
72143
  return null;
71941
72144
  }
71942
72145
  try {
71943
- const content = readFileSync39(dbPath, "utf-8");
72146
+ const content = readFileSync40(dbPath, "utf-8");
71944
72147
  return JSON.parse(content);
71945
72148
  } catch (error95) {
71946
72149
  log("Failed to load installed plugins database", error95);
@@ -71951,15 +72154,15 @@ function getClaudeSettingsPath() {
71951
72154
  if (process.env.CLAUDE_SETTINGS_PATH) {
71952
72155
  return process.env.CLAUDE_SETTINGS_PATH;
71953
72156
  }
71954
- return join69(homedir14(), ".claude", "settings.json");
72157
+ return join70(homedir14(), ".claude", "settings.json");
71955
72158
  }
71956
72159
  function loadClaudeSettings() {
71957
72160
  const settingsPath = getClaudeSettingsPath();
71958
- if (!existsSync56(settingsPath)) {
72161
+ if (!existsSync57(settingsPath)) {
71959
72162
  return null;
71960
72163
  }
71961
72164
  try {
71962
- const content = readFileSync39(settingsPath, "utf-8");
72165
+ const content = readFileSync40(settingsPath, "utf-8");
71963
72166
  return JSON.parse(content);
71964
72167
  } catch (error95) {
71965
72168
  log("Failed to load Claude settings", error95);
@@ -71967,12 +72170,12 @@ function loadClaudeSettings() {
71967
72170
  }
71968
72171
  }
71969
72172
  function loadPluginManifest(installPath) {
71970
- const manifestPath = join69(installPath, ".claude-plugin", "plugin.json");
71971
- if (!existsSync56(manifestPath)) {
72173
+ const manifestPath = join70(installPath, ".claude-plugin", "plugin.json");
72174
+ if (!existsSync57(manifestPath)) {
71972
72175
  return null;
71973
72176
  }
71974
72177
  try {
71975
- const content = readFileSync39(manifestPath, "utf-8");
72178
+ const content = readFileSync40(manifestPath, "utf-8");
71976
72179
  return JSON.parse(content);
71977
72180
  } catch (error95) {
71978
72181
  log(`Failed to load plugin manifest from ${manifestPath}`, error95);
@@ -72019,7 +72222,7 @@ function discoverInstalledPlugins(options) {
72019
72222
  continue;
72020
72223
  }
72021
72224
  const { installPath, scope, version: version3 } = installation;
72022
- if (!existsSync56(installPath)) {
72225
+ if (!existsSync57(installPath)) {
72023
72226
  errors5.push({
72024
72227
  pluginKey,
72025
72228
  installPath,
@@ -72037,21 +72240,21 @@ function discoverInstalledPlugins(options) {
72037
72240
  pluginKey,
72038
72241
  manifest: manifest ?? undefined
72039
72242
  };
72040
- if (existsSync56(join69(installPath, "commands"))) {
72041
- loadedPlugin.commandsDir = join69(installPath, "commands");
72243
+ if (existsSync57(join70(installPath, "commands"))) {
72244
+ loadedPlugin.commandsDir = join70(installPath, "commands");
72042
72245
  }
72043
- if (existsSync56(join69(installPath, "agents"))) {
72044
- loadedPlugin.agentsDir = join69(installPath, "agents");
72246
+ if (existsSync57(join70(installPath, "agents"))) {
72247
+ loadedPlugin.agentsDir = join70(installPath, "agents");
72045
72248
  }
72046
- if (existsSync56(join69(installPath, "skills"))) {
72047
- loadedPlugin.skillsDir = join69(installPath, "skills");
72249
+ if (existsSync57(join70(installPath, "skills"))) {
72250
+ loadedPlugin.skillsDir = join70(installPath, "skills");
72048
72251
  }
72049
- const hooksPath = join69(installPath, "hooks", "hooks.json");
72050
- if (existsSync56(hooksPath)) {
72252
+ const hooksPath = join70(installPath, "hooks", "hooks.json");
72253
+ if (existsSync57(hooksPath)) {
72051
72254
  loadedPlugin.hooksPath = hooksPath;
72052
72255
  }
72053
- const mcpPath = join69(installPath, ".mcp.json");
72054
- if (existsSync56(mcpPath)) {
72256
+ const mcpPath = join70(installPath, ".mcp.json");
72257
+ if (existsSync57(mcpPath)) {
72055
72258
  loadedPlugin.mcpPath = mcpPath;
72056
72259
  }
72057
72260
  plugins.push(loadedPlugin);
@@ -72062,17 +72265,17 @@ function discoverInstalledPlugins(options) {
72062
72265
  function loadPluginCommands(plugins) {
72063
72266
  const commands2 = {};
72064
72267
  for (const plugin of plugins) {
72065
- if (!plugin.commandsDir || !existsSync56(plugin.commandsDir))
72268
+ if (!plugin.commandsDir || !existsSync57(plugin.commandsDir))
72066
72269
  continue;
72067
72270
  const entries = readdirSync21(plugin.commandsDir, { withFileTypes: true });
72068
72271
  for (const entry of entries) {
72069
72272
  if (!isMarkdownFile(entry))
72070
72273
  continue;
72071
- const commandPath = join69(plugin.commandsDir, entry.name);
72274
+ const commandPath = join70(plugin.commandsDir, entry.name);
72072
72275
  const commandName = basename8(entry.name, ".md");
72073
72276
  const namespacedName = `${plugin.name}:${commandName}`;
72074
72277
  try {
72075
- const content = readFileSync39(commandPath, "utf-8");
72278
+ const content = readFileSync40(commandPath, "utf-8");
72076
72279
  const { data, body } = parseFrontmatter(content);
72077
72280
  const wrappedTemplate = `<command-instruction>
72078
72281
  ${body.trim()}
@@ -72104,21 +72307,21 @@ $ARGUMENTS
72104
72307
  function loadPluginSkillsAsCommands(plugins) {
72105
72308
  const skills = {};
72106
72309
  for (const plugin of plugins) {
72107
- if (!plugin.skillsDir || !existsSync56(plugin.skillsDir))
72310
+ if (!plugin.skillsDir || !existsSync57(plugin.skillsDir))
72108
72311
  continue;
72109
72312
  const entries = readdirSync21(plugin.skillsDir, { withFileTypes: true });
72110
72313
  for (const entry of entries) {
72111
72314
  if (entry.name.startsWith("."))
72112
72315
  continue;
72113
- const skillPath = join69(plugin.skillsDir, entry.name);
72316
+ const skillPath = join70(plugin.skillsDir, entry.name);
72114
72317
  if (!entry.isDirectory() && !entry.isSymbolicLink())
72115
72318
  continue;
72116
72319
  const resolvedPath = resolveSymlink(skillPath);
72117
- const skillMdPath = join69(resolvedPath, "SKILL.md");
72118
- if (!existsSync56(skillMdPath))
72320
+ const skillMdPath = join70(resolvedPath, "SKILL.md");
72321
+ if (!existsSync57(skillMdPath))
72119
72322
  continue;
72120
72323
  try {
72121
- const content = readFileSync39(skillMdPath, "utf-8");
72324
+ const content = readFileSync40(skillMdPath, "utf-8");
72122
72325
  const { data, body } = parseFrontmatter(content);
72123
72326
  const skillName = data.name || entry.name;
72124
72327
  const namespacedName = `${plugin.name}:${skillName}`;
@@ -72165,17 +72368,17 @@ function parseToolsConfig2(toolsStr) {
72165
72368
  function loadPluginAgents(plugins) {
72166
72369
  const agents = {};
72167
72370
  for (const plugin of plugins) {
72168
- if (!plugin.agentsDir || !existsSync56(plugin.agentsDir))
72371
+ if (!plugin.agentsDir || !existsSync57(plugin.agentsDir))
72169
72372
  continue;
72170
72373
  const entries = readdirSync21(plugin.agentsDir, { withFileTypes: true });
72171
72374
  for (const entry of entries) {
72172
72375
  if (!isMarkdownFile(entry))
72173
72376
  continue;
72174
- const agentPath = join69(plugin.agentsDir, entry.name);
72377
+ const agentPath = join70(plugin.agentsDir, entry.name);
72175
72378
  const agentName = basename8(entry.name, ".md");
72176
72379
  const namespacedName = `${plugin.name}:${agentName}`;
72177
72380
  try {
72178
- const content = readFileSync39(agentPath, "utf-8");
72381
+ const content = readFileSync40(agentPath, "utf-8");
72179
72382
  const { data, body } = parseFrontmatter(content);
72180
72383
  const name = data.name || agentName;
72181
72384
  const originalDescription = data.description || "";
@@ -72201,7 +72404,7 @@ function loadPluginAgents(plugins) {
72201
72404
  async function loadPluginMcpServers(plugins) {
72202
72405
  const servers = {};
72203
72406
  for (const plugin of plugins) {
72204
- if (!plugin.mcpPath || !existsSync56(plugin.mcpPath))
72407
+ if (!plugin.mcpPath || !existsSync57(plugin.mcpPath))
72205
72408
  continue;
72206
72409
  try {
72207
72410
  const content = await Bun.file(plugin.mcpPath).text();
@@ -72233,10 +72436,10 @@ async function loadPluginMcpServers(plugins) {
72233
72436
  function loadPluginHooksConfigs(plugins) {
72234
72437
  const configs = [];
72235
72438
  for (const plugin of plugins) {
72236
- if (!plugin.hooksPath || !existsSync56(plugin.hooksPath))
72439
+ if (!plugin.hooksPath || !existsSync57(plugin.hooksPath))
72237
72440
  continue;
72238
72441
  try {
72239
- const content = readFileSync39(plugin.hooksPath, "utf-8");
72442
+ const content = readFileSync40(plugin.hooksPath, "utf-8");
72240
72443
  let config4 = JSON.parse(content);
72241
72444
  config4 = resolvePluginPaths(config4, plugin.installPath);
72242
72445
  configs.push(config4);
@@ -73857,7 +74060,7 @@ var OhMyOpenCodePlugin = async (ctx) => {
73857
74060
  return;
73858
74061
  }
73859
74062
  log("[OhMyOpenCodePlugin] Starting session agent recovery...");
73860
- const recoveredAgents = recoverSessionAgents();
74063
+ const recoveredAgents = recoverSessionAgents(ctx.directory);
73861
74064
  log("[OhMyOpenCodePlugin] Session agent recovery complete", { recoveredAgents });
73862
74065
  startBackgroundCheck2();
73863
74066
  const pluginConfig = loadPluginConfig(ctx.directory, ctx);
@@ -74109,6 +74312,11 @@ var OhMyOpenCodePlugin = async (ctx) => {
74109
74312
  updateSessionAgent(input.sessionID, validatedAgent ?? input.agent, "chat.message");
74110
74313
  } else {
74111
74314
  const staleThresholdMs = pluginConfig.identity?.staleThresholdMs ?? 600000;
74315
+ if (!getSessionAgent(input.sessionID)) {
74316
+ log("[identity] chat.message without agent info and no session agent", {
74317
+ sessionID: input.sessionID
74318
+ });
74319
+ }
74112
74320
  if (isSessionAgentStale(input.sessionID, staleThresholdMs)) {
74113
74321
  log("[identity] session agent stale", { sessionID: input.sessionID, staleThresholdMs });
74114
74322
  const messageFileAgent = getAgentFromSessionMessages(input.sessionID);
@@ -74240,6 +74448,9 @@ var OhMyOpenCodePlugin = async (ctx) => {
74240
74448
  try {
74241
74449
  cleanupStaleTmpFiles(ctx.directory);
74242
74450
  } catch {}
74451
+ if (sessionInfo?.id) {
74452
+ log("[identity] New main session created", { sessionID: sessionInfo.id });
74453
+ }
74243
74454
  }
74244
74455
  firstMessageVariantGate.markSessionCreated(sessionInfo);
74245
74456
  }
@@ -74272,6 +74483,9 @@ var OhMyOpenCodePlugin = async (ctx) => {
74272
74483
  const validatedAgent = validateAndFixAgentIdentity(sessionID, agent);
74273
74484
  updateSessionAgent(sessionID, validatedAgent ?? agent, "message.updated");
74274
74485
  }
74486
+ if (sessionID && agent && role === "assistant") {
74487
+ updateSessionAgent(sessionID, agent, "message.updated.assistant");
74488
+ }
74275
74489
  }
74276
74490
  if (event.type === "session.error") {
74277
74491
  const sessionID = props?.sessionID;