sidekick-agent-hub 0.13.1 → 0.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/sidekick-cli.mjs +988 -672
  2. package/package.json +6 -1
@@ -1157,8 +1157,8 @@ var require_command = __commonJS({
1157
1157
  "node_modules/commander/lib/command.js"(exports) {
1158
1158
  var EventEmitter3 = __require("node:events").EventEmitter;
1159
1159
  var childProcess = __require("node:child_process");
1160
- var path8 = __require("node:path");
1161
- var fs10 = __require("node:fs");
1160
+ var path7 = __require("node:path");
1161
+ var fs9 = __require("node:fs");
1162
1162
  var process14 = __require("node:process");
1163
1163
  var { Argument: Argument2, humanReadableArgName } = require_argument();
1164
1164
  var { CommanderError: CommanderError2 } = require_error();
@@ -2139,7 +2139,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2139
2139
  * @param {string} subcommandName
2140
2140
  */
2141
2141
  _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
2142
- if (fs10.existsSync(executableFile)) return;
2142
+ if (fs9.existsSync(executableFile)) return;
2143
2143
  const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
2144
2144
  const executableMissing = `'${executableFile}' does not exist
2145
2145
  - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
@@ -2157,11 +2157,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2157
2157
  let launchWithNode = false;
2158
2158
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
2159
2159
  function findFile(baseDir, baseName) {
2160
- const localBin = path8.resolve(baseDir, baseName);
2161
- if (fs10.existsSync(localBin)) return localBin;
2162
- if (sourceExt.includes(path8.extname(baseName))) return void 0;
2160
+ const localBin = path7.resolve(baseDir, baseName);
2161
+ if (fs9.existsSync(localBin)) return localBin;
2162
+ if (sourceExt.includes(path7.extname(baseName))) return void 0;
2163
2163
  const foundExt = sourceExt.find(
2164
- (ext) => fs10.existsSync(`${localBin}${ext}`)
2164
+ (ext) => fs9.existsSync(`${localBin}${ext}`)
2165
2165
  );
2166
2166
  if (foundExt) return `${localBin}${foundExt}`;
2167
2167
  return void 0;
@@ -2173,21 +2173,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2173
2173
  if (this._scriptPath) {
2174
2174
  let resolvedScriptPath;
2175
2175
  try {
2176
- resolvedScriptPath = fs10.realpathSync(this._scriptPath);
2176
+ resolvedScriptPath = fs9.realpathSync(this._scriptPath);
2177
2177
  } catch {
2178
2178
  resolvedScriptPath = this._scriptPath;
2179
2179
  }
2180
- executableDir = path8.resolve(
2181
- path8.dirname(resolvedScriptPath),
2180
+ executableDir = path7.resolve(
2181
+ path7.dirname(resolvedScriptPath),
2182
2182
  executableDir
2183
2183
  );
2184
2184
  }
2185
2185
  if (executableDir) {
2186
2186
  let localFile = findFile(executableDir, executableFile);
2187
2187
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
2188
- const legacyName = path8.basename(
2188
+ const legacyName = path7.basename(
2189
2189
  this._scriptPath,
2190
- path8.extname(this._scriptPath)
2190
+ path7.extname(this._scriptPath)
2191
2191
  );
2192
2192
  if (legacyName !== this._name) {
2193
2193
  localFile = findFile(
@@ -2198,7 +2198,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2198
2198
  }
2199
2199
  executableFile = localFile || executableFile;
2200
2200
  }
2201
- launchWithNode = sourceExt.includes(path8.extname(executableFile));
2201
+ launchWithNode = sourceExt.includes(path7.extname(executableFile));
2202
2202
  let proc;
2203
2203
  if (process14.platform !== "win32") {
2204
2204
  if (launchWithNode) {
@@ -3045,7 +3045,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3045
3045
  * @return {Command}
3046
3046
  */
3047
3047
  nameFromFilename(filename) {
3048
- this._name = path8.basename(filename, path8.extname(filename));
3048
+ this._name = path7.basename(filename, path7.extname(filename));
3049
3049
  return this;
3050
3050
  }
3051
3051
  /**
@@ -3059,9 +3059,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
3059
3059
  * @param {string} [path]
3060
3060
  * @return {(string|null|Command)}
3061
3061
  */
3062
- executableDir(path9) {
3063
- if (path9 === void 0) return this._executableDir;
3064
- this._executableDir = path9;
3062
+ executableDir(path8) {
3063
+ if (path8 === void 0) return this._executableDir;
3064
+ this._executableDir = path8;
3065
3065
  return this;
3066
3066
  }
3067
3067
  /**
@@ -3483,20 +3483,20 @@ var require_paths = __commonJS({
3483
3483
  exports.encodeWorkspacePath = encodeWorkspacePath;
3484
3484
  exports.getProjectSlug = getProjectSlug7;
3485
3485
  exports.getProjectSlugRaw = getProjectSlugRaw7;
3486
- var fs10 = __importStar(__require("fs"));
3487
- var path8 = __importStar(__require("path"));
3488
- var os6 = __importStar(__require("os"));
3486
+ var fs9 = __importStar(__require("fs"));
3487
+ var path7 = __importStar(__require("path"));
3488
+ var os5 = __importStar(__require("os"));
3489
3489
  function getConfigDir2() {
3490
3490
  if (process.platform === "win32") {
3491
- return path8.join(process.env.APPDATA || os6.homedir(), "sidekick");
3491
+ return path7.join(process.env.APPDATA || os5.homedir(), "sidekick");
3492
3492
  }
3493
- return path8.join(os6.homedir(), ".config", "sidekick");
3493
+ return path7.join(os5.homedir(), ".config", "sidekick");
3494
3494
  }
3495
3495
  function getProjectDataPath(slug, subdomain) {
3496
- return path8.join(getConfigDir2(), subdomain, `${slug}.json`);
3496
+ return path7.join(getConfigDir2(), subdomain, `${slug}.json`);
3497
3497
  }
3498
3498
  function getGlobalDataPath(filename) {
3499
- return path8.join(getConfigDir2(), filename);
3499
+ return path7.join(getConfigDir2(), filename);
3500
3500
  }
3501
3501
  function encodeWorkspacePath(workspacePath) {
3502
3502
  const normalized = workspacePath.replace(/\\/g, "/");
@@ -3506,15 +3506,15 @@ var require_paths = __commonJS({
3506
3506
  const dir = cwd2 || process.cwd();
3507
3507
  let resolved;
3508
3508
  try {
3509
- resolved = fs10.realpathSync(dir);
3509
+ resolved = fs9.realpathSync(dir);
3510
3510
  } catch {
3511
- resolved = path8.resolve(dir);
3511
+ resolved = path7.resolve(dir);
3512
3512
  }
3513
3513
  return encodeWorkspacePath(resolved);
3514
3514
  }
3515
3515
  function getProjectSlugRaw7(cwd2) {
3516
3516
  const dir = cwd2 || process.cwd();
3517
- return encodeWorkspacePath(path8.resolve(dir));
3517
+ return encodeWorkspacePath(path7.resolve(dir));
3518
3518
  }
3519
3519
  }
3520
3520
  });
@@ -3562,10 +3562,10 @@ var require_helpers = __commonJS({
3562
3562
  }();
3563
3563
  Object.defineProperty(exports, "__esModule", { value: true });
3564
3564
  exports.readJsonStore = readJsonStore;
3565
- var fs10 = __importStar(__require("fs"));
3565
+ var fs9 = __importStar(__require("fs"));
3566
3566
  async function readJsonStore(filePath) {
3567
3567
  try {
3568
- const content = await fs10.promises.readFile(filePath, "utf-8");
3568
+ const content = await fs9.promises.readFile(filePath, "utf-8");
3569
3569
  return JSON.parse(content);
3570
3570
  } catch {
3571
3571
  return null;
@@ -3729,12 +3729,12 @@ var require_handoff = __commonJS({
3729
3729
  }();
3730
3730
  Object.defineProperty(exports, "__esModule", { value: true });
3731
3731
  exports.readLatestHandoff = readLatestHandoff2;
3732
- var fs10 = __importStar(__require("fs"));
3732
+ var fs9 = __importStar(__require("fs"));
3733
3733
  var paths_1 = require_paths();
3734
3734
  async function readLatestHandoff2(slug) {
3735
3735
  const filePath = (0, paths_1.getProjectDataPath)(slug, "handoffs").replace(".json", "-latest.md");
3736
3736
  try {
3737
- const content = await fs10.promises.readFile(filePath, "utf-8");
3737
+ const content = await fs9.promises.readFile(filePath, "utf-8");
3738
3738
  return content.trim() || null;
3739
3739
  } catch {
3740
3740
  return null;
@@ -4076,9 +4076,9 @@ var require_plans = __commonJS({
4076
4076
  exports.getPlanAnalytics = getPlanAnalytics;
4077
4077
  exports.writePlans = writePlans;
4078
4078
  exports.readClaudeCodePlanFiles = readClaudeCodePlanFiles2;
4079
- var fs10 = __importStar(__require("fs"));
4080
- var path8 = __importStar(__require("path"));
4081
- var os6 = __importStar(__require("os"));
4079
+ var fs9 = __importStar(__require("fs"));
4080
+ var path7 = __importStar(__require("path"));
4081
+ var os5 = __importStar(__require("os"));
4082
4082
  var plan_1 = require_plan();
4083
4083
  var paths_1 = require_paths();
4084
4084
  var helpers_1 = require_helpers();
@@ -4192,30 +4192,30 @@ var require_plans = __commonJS({
4192
4192
  lastSaved: (/* @__PURE__ */ new Date()).toISOString()
4193
4193
  };
4194
4194
  const dir = filePath.replace(/[/\\][^/\\]+$/, "");
4195
- await fs10.promises.mkdir(dir, { recursive: true });
4196
- await fs10.promises.writeFile(filePath, JSON.stringify(store, null, 2), "utf-8");
4195
+ await fs9.promises.mkdir(dir, { recursive: true });
4196
+ await fs9.promises.writeFile(filePath, JSON.stringify(store, null, 2), "utf-8");
4197
4197
  }
4198
4198
  async function readClaudeCodePlanFiles2(workspacePath) {
4199
- const claudePlansDir = path8.join(os6.homedir(), ".claude", "plans");
4200
- const claudeProjectsDir = path8.join(os6.homedir(), ".claude", "projects");
4199
+ const claudePlansDir = path7.join(os5.homedir(), ".claude", "plans");
4200
+ const claudeProjectsDir = path7.join(os5.homedir(), ".claude", "projects");
4201
4201
  const cwd2 = workspacePath || process.cwd();
4202
- const encoded = (0, paths_1.encodeWorkspacePath)(path8.resolve(cwd2));
4203
- const projectDir = path8.join(claudeProjectsDir, encoded);
4204
- if (!fs10.existsSync(projectDir) || !fs10.existsSync(claudePlansDir)) {
4202
+ const encoded = (0, paths_1.encodeWorkspacePath)(path7.resolve(cwd2));
4203
+ const projectDir = path7.join(claudeProjectsDir, encoded);
4204
+ if (!fs9.existsSync(projectDir) || !fs9.existsSync(claudePlansDir)) {
4205
4205
  return [];
4206
4206
  }
4207
4207
  const slugSet = /* @__PURE__ */ new Set();
4208
4208
  let jsonlFiles;
4209
4209
  try {
4210
- jsonlFiles = (await fs10.promises.readdir(projectDir)).filter((f) => f.endsWith(".jsonl"));
4210
+ jsonlFiles = (await fs9.promises.readdir(projectDir)).filter((f) => f.endsWith(".jsonl"));
4211
4211
  } catch {
4212
4212
  return [];
4213
4213
  }
4214
4214
  const SLUG_RE = /"slug":"([^"]+)"/;
4215
4215
  await Promise.all(jsonlFiles.map(async (f) => {
4216
4216
  try {
4217
- const filePath = path8.join(projectDir, f);
4218
- const handle = await fs10.promises.open(filePath, "r");
4217
+ const filePath = path7.join(projectDir, f);
4218
+ const handle = await fs9.promises.open(filePath, "r");
4219
4219
  try {
4220
4220
  const buf = Buffer.alloc(32768);
4221
4221
  const { bytesRead } = await handle.read(buf, 0, buf.length, 0);
@@ -4237,10 +4237,10 @@ var require_plans = __commonJS({
4237
4237
  return [];
4238
4238
  const plans = [];
4239
4239
  for (const slug of slugSet) {
4240
- const planPath = path8.join(claudePlansDir, `${slug}.md`);
4240
+ const planPath = path7.join(claudePlansDir, `${slug}.md`);
4241
4241
  try {
4242
- const stat = await fs10.promises.stat(planPath);
4243
- const content = await fs10.promises.readFile(planPath, "utf-8");
4242
+ const stat = await fs9.promises.stat(planPath);
4243
+ const content = await fs9.promises.readFile(planPath, "utf-8");
4244
4244
  const parsed = (0, planExtractor_1.parsePlanMarkdown)(content);
4245
4245
  const steps = parsed.steps.map((s) => ({
4246
4246
  id: s.id,
@@ -4316,30 +4316,30 @@ var require_detect = __commonJS({
4316
4316
  Object.defineProperty(exports, "__esModule", { value: true });
4317
4317
  exports.getAllDetectedProviders = getAllDetectedProviders2;
4318
4318
  exports.detectProvider = detectProvider2;
4319
- var fs10 = __importStar(__require("fs"));
4320
- var os6 = __importStar(__require("os"));
4321
- var path8 = __importStar(__require("path"));
4319
+ var fs9 = __importStar(__require("fs"));
4320
+ var os5 = __importStar(__require("os"));
4321
+ var path7 = __importStar(__require("path"));
4322
4322
  function getOpenCodeDataDir() {
4323
4323
  const xdg = process.env.XDG_DATA_HOME;
4324
4324
  if (xdg)
4325
- return path8.join(xdg, "opencode");
4326
- return path8.join(os6.homedir(), ".local", "share", "opencode");
4325
+ return path7.join(xdg, "opencode");
4326
+ return path7.join(os5.homedir(), ".local", "share", "opencode");
4327
4327
  }
4328
4328
  function getCodexHome() {
4329
4329
  const envHome = process.env.CODEX_HOME;
4330
4330
  if (envHome)
4331
4331
  return envHome;
4332
- return path8.join(os6.homedir(), ".codex");
4332
+ return path7.join(os5.homedir(), ".codex");
4333
4333
  }
4334
4334
  function getMostRecentMtime(dir) {
4335
4335
  try {
4336
- if (!fs10.existsSync(dir))
4336
+ if (!fs9.existsSync(dir))
4337
4337
  return 0;
4338
4338
  let latest = 0;
4339
- const entries = fs10.readdirSync(dir);
4339
+ const entries = fs9.readdirSync(dir);
4340
4340
  for (const entry of entries) {
4341
4341
  try {
4342
- const stats = fs10.statSync(path8.join(dir, entry));
4342
+ const stats = fs9.statSync(path7.join(dir, entry));
4343
4343
  if (stats.mtime.getTime() > latest) {
4344
4344
  latest = stats.mtime.getTime();
4345
4345
  }
@@ -4353,46 +4353,46 @@ var require_detect = __commonJS({
4353
4353
  }
4354
4354
  function getOpenCodeActivityMtime() {
4355
4355
  const dataDir = getOpenCodeDataDir();
4356
- const dbPath = path8.join(dataDir, "opencode.db");
4356
+ const dbPath = path7.join(dataDir, "opencode.db");
4357
4357
  try {
4358
- const dbMtime = fs10.statSync(dbPath).mtime.getTime();
4358
+ const dbMtime = fs9.statSync(dbPath).mtime.getTime();
4359
4359
  if (dbMtime > 0)
4360
4360
  return dbMtime;
4361
4361
  } catch {
4362
4362
  }
4363
- const storageDir = path8.join(dataDir, "storage");
4364
- const sessionMtime = getMostRecentMtime(path8.join(storageDir, "session"));
4365
- const messageMtime = getMostRecentMtime(path8.join(storageDir, "message"));
4366
- const partMtime = getMostRecentMtime(path8.join(storageDir, "part"));
4363
+ const storageDir = path7.join(dataDir, "storage");
4364
+ const sessionMtime = getMostRecentMtime(path7.join(storageDir, "session"));
4365
+ const messageMtime = getMostRecentMtime(path7.join(storageDir, "message"));
4366
+ const partMtime = getMostRecentMtime(path7.join(storageDir, "part"));
4367
4367
  return Math.max(sessionMtime, messageMtime, partMtime);
4368
4368
  }
4369
4369
  function getCodexActivityMtime() {
4370
4370
  const codexHome = getCodexHome();
4371
- const dbPath = path8.join(codexHome, "state.sqlite");
4371
+ const dbPath = path7.join(codexHome, "state.sqlite");
4372
4372
  try {
4373
- const dbMtime = fs10.statSync(dbPath).mtime.getTime();
4373
+ const dbMtime = fs9.statSync(dbPath).mtime.getTime();
4374
4374
  if (dbMtime > 0)
4375
4375
  return dbMtime;
4376
4376
  } catch {
4377
4377
  }
4378
- return getMostRecentMtime(path8.join(codexHome, "sessions"));
4378
+ return getMostRecentMtime(path7.join(codexHome, "sessions"));
4379
4379
  }
4380
4380
  function getProviderPaths() {
4381
- const claudeBase = path8.join(os6.homedir(), ".claude", "projects");
4381
+ const claudeBase = path7.join(os5.homedir(), ".claude", "projects");
4382
4382
  const openCodeDataDir = getOpenCodeDataDir();
4383
4383
  return {
4384
4384
  claudeBase,
4385
- openCodeDbPath: path8.join(openCodeDataDir, "opencode.db"),
4386
- openCodeStorageDir: path8.join(openCodeDataDir, "storage"),
4387
- codexSessionsDir: path8.join(getCodexHome(), "sessions"),
4388
- codexDbPath: path8.join(getCodexHome(), "state.sqlite")
4385
+ openCodeDbPath: path7.join(openCodeDataDir, "opencode.db"),
4386
+ openCodeStorageDir: path7.join(openCodeDataDir, "storage"),
4387
+ codexSessionsDir: path7.join(getCodexHome(), "sessions"),
4388
+ codexDbPath: path7.join(getCodexHome(), "state.sqlite")
4389
4389
  };
4390
4390
  }
4391
4391
  function getAllDetectedProviders2() {
4392
4392
  const { claudeBase, openCodeDbPath, openCodeStorageDir, codexSessionsDir, codexDbPath } = getProviderPaths();
4393
- const hasClaude = fs10.existsSync(claudeBase);
4394
- const hasOpenCode = fs10.existsSync(openCodeStorageDir) || fs10.existsSync(openCodeDbPath);
4395
- const hasCodex = fs10.existsSync(codexSessionsDir) || fs10.existsSync(codexDbPath);
4393
+ const hasClaude = fs9.existsSync(claudeBase);
4394
+ const hasOpenCode = fs9.existsSync(openCodeStorageDir) || fs9.existsSync(openCodeDbPath);
4395
+ const hasCodex = fs9.existsSync(codexSessionsDir) || fs9.existsSync(codexDbPath);
4396
4396
  const available = [];
4397
4397
  if (hasClaude)
4398
4398
  available.push({ id: "claude-code", mtime: getMostRecentMtime(claudeBase) });
@@ -4407,9 +4407,9 @@ var require_detect = __commonJS({
4407
4407
  if (override && override !== "auto")
4408
4408
  return override;
4409
4409
  const { claudeBase, openCodeDbPath, openCodeStorageDir, codexSessionsDir, codexDbPath } = getProviderPaths();
4410
- const hasClaude = fs10.existsSync(claudeBase);
4411
- const hasOpenCode = fs10.existsSync(openCodeStorageDir) || fs10.existsSync(openCodeDbPath);
4412
- const hasCodex = fs10.existsSync(codexSessionsDir) || fs10.existsSync(codexDbPath);
4410
+ const hasClaude = fs9.existsSync(claudeBase);
4411
+ const hasOpenCode = fs9.existsSync(openCodeStorageDir) || fs9.existsSync(openCodeDbPath);
4412
+ const hasCodex = fs9.existsSync(codexSessionsDir) || fs9.existsSync(codexDbPath);
4413
4413
  const available = [];
4414
4414
  if (hasClaude) {
4415
4415
  available.push({ id: "claude-code", mtime: getMostRecentMtime(claudeBase) });
@@ -4542,29 +4542,29 @@ var require_sessionPathResolver = __commonJS({
4542
4542
  exports.resolveWorktreeMainRepo = resolveWorktreeMainRepo;
4543
4543
  exports.discoverWorktreeSiblings = discoverWorktreeSiblings;
4544
4544
  exports.findAllSessionsWithWorktrees = findAllSessionsWithWorktrees;
4545
- var fs10 = __importStar(__require("fs"));
4546
- var path8 = __importStar(__require("path"));
4547
- var os6 = __importStar(__require("os"));
4545
+ var fs9 = __importStar(__require("fs"));
4546
+ var path7 = __importStar(__require("path"));
4547
+ var os5 = __importStar(__require("os"));
4548
4548
  function encodeWorkspacePath(workspacePath) {
4549
4549
  const normalized = workspacePath.replace(/\\/g, "/");
4550
4550
  return normalized.replace(/[:/_]/g, "-");
4551
4551
  }
4552
4552
  function getSessionDirectory(workspacePath) {
4553
4553
  const encoded = encodeWorkspacePath(workspacePath);
4554
- return path8.join(os6.homedir(), ".claude", "projects", encoded);
4554
+ return path7.join(os5.homedir(), ".claude", "projects", encoded);
4555
4555
  }
4556
4556
  var ACTIVE_SESSION_THRESHOLD_MS = 5 * 60 * 1e3;
4557
4557
  function findSubdirectorySessionDirs(workspacePath) {
4558
- const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
4558
+ const projectsDir = path7.join(os5.homedir(), ".claude", "projects");
4559
4559
  try {
4560
- if (!fs10.existsSync(projectsDir)) {
4560
+ if (!fs9.existsSync(projectsDir)) {
4561
4561
  return [];
4562
4562
  }
4563
4563
  const encodedPrefix = encodeWorkspacePath(workspacePath).toLowerCase();
4564
- const allDirs = fs10.readdirSync(projectsDir).filter((name) => {
4565
- const fullPath = path8.join(projectsDir, name);
4564
+ const allDirs = fs9.readdirSync(projectsDir).filter((name) => {
4565
+ const fullPath = path7.join(projectsDir, name);
4566
4566
  try {
4567
- return fs10.statSync(fullPath).isDirectory();
4567
+ return fs9.statSync(fullPath).isDirectory();
4568
4568
  } catch {
4569
4569
  return false;
4570
4570
  }
@@ -4573,7 +4573,7 @@ var require_sessionPathResolver = __commonJS({
4573
4573
  for (const dir of allDirs) {
4574
4574
  const dirLower = dir.toLowerCase();
4575
4575
  if (dirLower.startsWith(encodedPrefix + "-")) {
4576
- matches.push(path8.join(projectsDir, dir));
4576
+ matches.push(path7.join(projectsDir, dir));
4577
4577
  }
4578
4578
  }
4579
4579
  return matches;
@@ -4586,11 +4586,11 @@ var require_sessionPathResolver = __commonJS({
4586
4586
  let mostRecentMtime = 0;
4587
4587
  for (const dir of sessionDirs) {
4588
4588
  try {
4589
- const files = fs10.readdirSync(dir).filter((file) => file.endsWith(".jsonl"));
4589
+ const files = fs9.readdirSync(dir).filter((file) => file.endsWith(".jsonl"));
4590
4590
  for (const file of files) {
4591
4591
  try {
4592
- const fullPath = path8.join(dir, file);
4593
- const stats = fs10.statSync(fullPath);
4592
+ const fullPath = path7.join(dir, file);
4593
+ const stats = fs9.statSync(fullPath);
4594
4594
  if (stats.size > 0 && stats.mtime.getTime() > mostRecentMtime) {
4595
4595
  mostRecentMtime = stats.mtime.getTime();
4596
4596
  mostRecentDir = dir;
@@ -4604,9 +4604,9 @@ var require_sessionPathResolver = __commonJS({
4604
4604
  return mostRecentDir;
4605
4605
  }
4606
4606
  function discoverSessionDirectory(workspacePath) {
4607
- const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
4607
+ const projectsDir = path7.join(os5.homedir(), ".claude", "projects");
4608
4608
  const computedDir = getSessionDirectory(workspacePath);
4609
- if (fs10.existsSync(computedDir)) {
4609
+ if (fs9.existsSync(computedDir)) {
4610
4610
  return computedDir;
4611
4611
  }
4612
4612
  const subdirMatches = findSubdirectorySessionDirs(workspacePath);
@@ -4617,11 +4617,11 @@ var require_sessionPathResolver = __commonJS({
4617
4617
  }
4618
4618
  }
4619
4619
  try {
4620
- if (fs10.existsSync(projectsDir)) {
4621
- const existingDirs = fs10.readdirSync(projectsDir).filter((name) => {
4622
- const fullPath = path8.join(projectsDir, name);
4620
+ if (fs9.existsSync(projectsDir)) {
4621
+ const existingDirs = fs9.readdirSync(projectsDir).filter((name) => {
4622
+ const fullPath = path7.join(projectsDir, name);
4623
4623
  try {
4624
- return fs10.statSync(fullPath).isDirectory();
4624
+ return fs9.statSync(fullPath).isDirectory();
4625
4625
  } catch {
4626
4626
  return false;
4627
4627
  }
@@ -4629,36 +4629,36 @@ var require_sessionPathResolver = __commonJS({
4629
4629
  const normalizedWorkspace = workspacePath.replace(/\\/g, "/").replace(/:/g, "-").replace(/_/g, "-").replace(/\//g, "-").toLowerCase();
4630
4630
  for (const dir of existingDirs) {
4631
4631
  if (dir.toLowerCase() === normalizedWorkspace) {
4632
- return path8.join(projectsDir, dir);
4632
+ return path7.join(projectsDir, dir);
4633
4633
  }
4634
4634
  }
4635
- const workspaceBasename = path8.basename(workspacePath).replace(/_/g, "-").toLowerCase();
4635
+ const workspaceBasename = path7.basename(workspacePath).replace(/_/g, "-").toLowerCase();
4636
4636
  for (const dir of existingDirs) {
4637
4637
  const dirLower = dir.toLowerCase();
4638
4638
  if (dirLower.endsWith("-" + workspaceBasename) || dirLower === workspaceBasename) {
4639
- return path8.join(projectsDir, dir);
4639
+ return path7.join(projectsDir, dir);
4640
4640
  }
4641
4641
  }
4642
4642
  }
4643
4643
  } catch {
4644
4644
  }
4645
4645
  try {
4646
- const claudeTempDir = path8.join(os6.tmpdir(), "claude");
4647
- if (fs10.existsSync(claudeTempDir)) {
4648
- const tempDirs = fs10.readdirSync(claudeTempDir).filter((name) => {
4649
- const fullPath = path8.join(claudeTempDir, name);
4646
+ const claudeTempDir = path7.join(os5.tmpdir(), "claude");
4647
+ if (fs9.existsSync(claudeTempDir)) {
4648
+ const tempDirs = fs9.readdirSync(claudeTempDir).filter((name) => {
4649
+ const fullPath = path7.join(claudeTempDir, name);
4650
4650
  try {
4651
- return fs10.statSync(fullPath).isDirectory();
4651
+ return fs9.statSync(fullPath).isDirectory();
4652
4652
  } catch {
4653
4653
  return false;
4654
4654
  }
4655
4655
  });
4656
- const workspaceBasename = path8.basename(workspacePath).replace(/_/g, "-").toLowerCase();
4656
+ const workspaceBasename = path7.basename(workspacePath).replace(/_/g, "-").toLowerCase();
4657
4657
  for (const encodedDir of tempDirs) {
4658
4658
  const encodedLower = encodedDir.toLowerCase();
4659
4659
  if (encodedLower.endsWith("-" + workspaceBasename) || encodedLower === workspaceBasename) {
4660
- const sessionDir = path8.join(projectsDir, encodedDir);
4661
- if (fs10.existsSync(sessionDir)) {
4660
+ const sessionDir = path7.join(projectsDir, encodedDir);
4661
+ if (fs9.existsSync(sessionDir)) {
4662
4662
  return sessionDir;
4663
4663
  }
4664
4664
  }
@@ -4675,9 +4675,9 @@ var require_sessionPathResolver = __commonJS({
4675
4675
  return null;
4676
4676
  }
4677
4677
  const now = Date.now();
4678
- const files = fs10.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
4679
- const fullPath = path8.join(sessionDir, file);
4680
- const stats = fs10.statSync(fullPath);
4678
+ const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
4679
+ const fullPath = path7.join(sessionDir, file);
4680
+ const stats = fs9.statSync(fullPath);
4681
4681
  const mtime = stats.mtime.getTime();
4682
4682
  return {
4683
4683
  path: fullPath,
@@ -4708,9 +4708,9 @@ var require_sessionPathResolver = __commonJS({
4708
4708
  if (!sessionDir) {
4709
4709
  return [];
4710
4710
  }
4711
- const files = fs10.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
4712
- const fullPath = path8.join(sessionDir, file);
4713
- const stats = fs10.statSync(fullPath);
4711
+ const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
4712
+ const fullPath = path7.join(sessionDir, file);
4713
+ const stats = fs9.statSync(fullPath);
4714
4714
  return {
4715
4715
  path: fullPath,
4716
4716
  mtime: stats.mtime.getTime()
@@ -4736,27 +4736,27 @@ var require_sessionPathResolver = __commonJS({
4736
4736
  return encoded.replace(/-/g, "/");
4737
4737
  }
4738
4738
  function getAllProjectFolders(workspacePath) {
4739
- const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
4739
+ const projectsDir = path7.join(os5.homedir(), ".claude", "projects");
4740
4740
  const folders = [];
4741
4741
  try {
4742
- if (!fs10.existsSync(projectsDir)) {
4742
+ if (!fs9.existsSync(projectsDir)) {
4743
4743
  return [];
4744
4744
  }
4745
- const entries = fs10.readdirSync(projectsDir);
4745
+ const entries = fs9.readdirSync(projectsDir);
4746
4746
  for (const entry of entries) {
4747
- const fullPath = path8.join(projectsDir, entry);
4747
+ const fullPath = path7.join(projectsDir, entry);
4748
4748
  try {
4749
- const stats = fs10.statSync(fullPath);
4749
+ const stats = fs9.statSync(fullPath);
4750
4750
  if (!stats.isDirectory()) {
4751
4751
  continue;
4752
4752
  }
4753
- const sessionFiles = fs10.readdirSync(fullPath).filter((f) => f.endsWith(".jsonl"));
4753
+ const sessionFiles = fs9.readdirSync(fullPath).filter((f) => f.endsWith(".jsonl"));
4754
4754
  let lastModified = stats.mtime;
4755
4755
  let sessionCount = 0;
4756
4756
  for (const sessionFile of sessionFiles) {
4757
4757
  try {
4758
- const sessionPath = path8.join(fullPath, sessionFile);
4759
- const sessionStats = fs10.statSync(sessionPath);
4758
+ const sessionPath = path7.join(fullPath, sessionFile);
4759
+ const sessionStats = fs9.statSync(sessionPath);
4760
4760
  if (sessionStats.size > 0) {
4761
4761
  sessionCount++;
4762
4762
  if (sessionStats.mtime > lastModified) {
@@ -4803,13 +4803,13 @@ var require_sessionPathResolver = __commonJS({
4803
4803
  }
4804
4804
  function findSessionsInDirectory(sessionDir) {
4805
4805
  try {
4806
- if (!fs10.existsSync(sessionDir)) {
4806
+ if (!fs9.existsSync(sessionDir)) {
4807
4807
  return [];
4808
4808
  }
4809
- const files = fs10.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
4810
- const fullPath = path8.join(sessionDir, file);
4809
+ const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
4810
+ const fullPath = path7.join(sessionDir, file);
4811
4811
  try {
4812
- const stats = fs10.statSync(fullPath);
4812
+ const stats = fs9.statSync(fullPath);
4813
4813
  return {
4814
4814
  path: fullPath,
4815
4815
  mtime: stats.mtime.getTime(),
@@ -4825,43 +4825,43 @@ var require_sessionPathResolver = __commonJS({
4825
4825
  }
4826
4826
  }
4827
4827
  function resolveWorktreeMainRepo(workspacePath) {
4828
- const gitPath = path8.join(workspacePath, ".git");
4828
+ const gitPath = path7.join(workspacePath, ".git");
4829
4829
  try {
4830
- const stat = fs10.statSync(gitPath);
4830
+ const stat = fs9.statSync(gitPath);
4831
4831
  if (stat.isDirectory()) {
4832
4832
  return null;
4833
4833
  }
4834
- const content = fs10.readFileSync(gitPath, "utf-8").trim();
4834
+ const content = fs9.readFileSync(gitPath, "utf-8").trim();
4835
4835
  const match = content.match(/^gitdir:\s*(.+)$/m);
4836
4836
  if (!match)
4837
4837
  return null;
4838
4838
  const gitdir = match[1].trim();
4839
- const resolvedGitdir = path8.isAbsolute(gitdir) ? gitdir : path8.resolve(workspacePath, gitdir);
4840
- const worktreesDir = path8.dirname(resolvedGitdir);
4841
- if (path8.basename(worktreesDir) !== "worktrees")
4839
+ const resolvedGitdir = path7.isAbsolute(gitdir) ? gitdir : path7.resolve(workspacePath, gitdir);
4840
+ const worktreesDir = path7.dirname(resolvedGitdir);
4841
+ if (path7.basename(worktreesDir) !== "worktrees")
4842
4842
  return null;
4843
- const dotGit = path8.dirname(worktreesDir);
4844
- if (path8.basename(dotGit) !== ".git")
4843
+ const dotGit = path7.dirname(worktreesDir);
4844
+ if (path7.basename(dotGit) !== ".git")
4845
4845
  return null;
4846
- return path8.dirname(dotGit);
4846
+ return path7.dirname(dotGit);
4847
4847
  } catch {
4848
4848
  return null;
4849
4849
  }
4850
4850
  }
4851
4851
  function discoverWorktreeSiblings(mainRepoPath) {
4852
- const worktreesDir = path8.join(mainRepoPath, ".git", "worktrees");
4852
+ const worktreesDir = path7.join(mainRepoPath, ".git", "worktrees");
4853
4853
  const siblings = [];
4854
4854
  try {
4855
- if (!fs10.existsSync(worktreesDir))
4855
+ if (!fs9.existsSync(worktreesDir))
4856
4856
  return siblings;
4857
- const entries = fs10.readdirSync(worktreesDir);
4857
+ const entries = fs9.readdirSync(worktreesDir);
4858
4858
  for (const entry of entries) {
4859
- const gitdirFile = path8.join(worktreesDir, entry, "gitdir");
4859
+ const gitdirFile = path7.join(worktreesDir, entry, "gitdir");
4860
4860
  try {
4861
- const content = fs10.readFileSync(gitdirFile, "utf-8").trim();
4862
- const worktreeGit = path8.isAbsolute(content) ? content : path8.resolve(worktreesDir, entry, content);
4863
- const worktreeDir = path8.dirname(worktreeGit);
4864
- if (fs10.existsSync(worktreeDir)) {
4861
+ const content = fs9.readFileSync(gitdirFile, "utf-8").trim();
4862
+ const worktreeGit = path7.isAbsolute(content) ? content : path7.resolve(worktreesDir, entry, content);
4863
+ const worktreeDir = path7.dirname(worktreeGit);
4864
+ if (fs9.existsSync(worktreeDir)) {
4865
4865
  siblings.push(worktreeDir);
4866
4866
  }
4867
4867
  } catch {
@@ -4898,7 +4898,7 @@ var require_sessionPathResolver = __commonJS({
4898
4898
  }
4899
4899
  return Array.from(allPaths).map((sessionPath) => {
4900
4900
  try {
4901
- const stat = fs10.statSync(sessionPath);
4901
+ const stat = fs9.statSync(sessionPath);
4902
4902
  return { path: sessionPath, mtime: stat.mtime.getTime() };
4903
4903
  } catch {
4904
4904
  return { path: sessionPath, mtime: 0 };
@@ -4953,8 +4953,8 @@ var require_subagentScanner = __commonJS({
4953
4953
  exports.scanSubagentDir = scanSubagentDir;
4954
4954
  exports.handleTaskUpdate = handleTaskUpdate;
4955
4955
  exports.extractTaskInfo = extractTaskInfo;
4956
- var fs10 = __importStar(__require("fs"));
4957
- var path8 = __importStar(__require("path"));
4956
+ var fs9 = __importStar(__require("fs"));
4957
+ var path7 = __importStar(__require("path"));
4958
4958
  var AGENT_FILE_PATTERN = /^agent-(.+)\.jsonl$/;
4959
4959
  var TASK_TOOLS = ["TaskCreate", "TaskUpdate", "TaskGet", "TaskList"];
4960
4960
  function extractTaskIdFromResult(resultContent) {
@@ -4973,10 +4973,10 @@ var require_subagentScanner = __commonJS({
4973
4973
  function scanSubagentDir(sessionDir, sessionId, logger) {
4974
4974
  const log = logger || (() => {
4975
4975
  });
4976
- const subagentsDir = path8.join(sessionDir, sessionId, "subagents");
4976
+ const subagentsDir = path7.join(sessionDir, sessionId, "subagents");
4977
4977
  const results = [];
4978
4978
  try {
4979
- if (!fs10.existsSync(subagentsDir)) {
4979
+ if (!fs9.existsSync(subagentsDir)) {
4980
4980
  if (!reportedMissing.has(subagentsDir)) {
4981
4981
  reportedMissing.add(subagentsDir);
4982
4982
  log(`[SubagentScanner] No subagents directory: ${subagentsDir}`);
@@ -4984,7 +4984,7 @@ var require_subagentScanner = __commonJS({
4984
4984
  return results;
4985
4985
  }
4986
4986
  reportedMissing.delete(subagentsDir);
4987
- const files = fs10.readdirSync(subagentsDir);
4987
+ const files = fs9.readdirSync(subagentsDir);
4988
4988
  log(`[SubagentScanner] Found ${files.length} files: ${files.join(", ")}`);
4989
4989
  for (const file of files) {
4990
4990
  const match = file.match(AGENT_FILE_PATTERN);
@@ -4992,7 +4992,7 @@ var require_subagentScanner = __commonJS({
4992
4992
  continue;
4993
4993
  }
4994
4994
  const agentId = match[1];
4995
- const filePath = path8.join(subagentsDir, file);
4995
+ const filePath = path7.join(subagentsDir, file);
4996
4996
  const agentStats = parseAgentFile(filePath, agentId, log);
4997
4997
  if (agentStats) {
4998
4998
  log(`[SubagentScanner] Agent ${agentId}: ${agentStats.toolCalls.length} tool calls`);
@@ -5009,7 +5009,7 @@ var require_subagentScanner = __commonJS({
5009
5009
  }
5010
5010
  function parseAgentFile(filePath, agentId, log) {
5011
5011
  try {
5012
- const content = fs10.readFileSync(filePath, "utf-8");
5012
+ const content = fs9.readFileSync(filePath, "utf-8");
5013
5013
  const lines = content.split("\n").filter((line) => line.trim());
5014
5014
  const toolCalls = [];
5015
5015
  let agentType;
@@ -5237,9 +5237,9 @@ var require_claudeCode = __commonJS({
5237
5237
  }();
5238
5238
  Object.defineProperty(exports, "__esModule", { value: true });
5239
5239
  exports.ClaudeCodeProvider = void 0;
5240
- var fs10 = __importStar(__require("fs"));
5241
- var os6 = __importStar(__require("os"));
5242
- var path8 = __importStar(__require("path"));
5240
+ var fs9 = __importStar(__require("fs"));
5241
+ var os5 = __importStar(__require("os"));
5242
+ var path7 = __importStar(__require("path"));
5243
5243
  var jsonl_1 = require_jsonl();
5244
5244
  var sessionPathResolver_1 = require_sessionPathResolver();
5245
5245
  var subagentScanner_1 = require_subagentScanner();
@@ -5289,10 +5289,10 @@ var require_claudeCode = __commonJS({
5289
5289
  this.events = [];
5290
5290
  this._wasTruncated = false;
5291
5291
  try {
5292
- if (!fs10.existsSync(this.sessionPath)) {
5292
+ if (!fs9.existsSync(this.sessionPath)) {
5293
5293
  return [];
5294
5294
  }
5295
- const stats = fs10.statSync(this.sessionPath);
5295
+ const stats = fs9.statSync(this.sessionPath);
5296
5296
  const currentSize = stats.size;
5297
5297
  if (currentSize < this.filePosition) {
5298
5298
  this._wasTruncated = true;
@@ -5302,11 +5302,11 @@ var require_claudeCode = __commonJS({
5302
5302
  if (currentSize <= this.filePosition) {
5303
5303
  return [];
5304
5304
  }
5305
- const fd = fs10.openSync(this.sessionPath, "r");
5305
+ const fd = fs9.openSync(this.sessionPath, "r");
5306
5306
  const bufferSize = currentSize - this.filePosition;
5307
5307
  const buffer = Buffer.alloc(bufferSize);
5308
- fs10.readSync(fd, buffer, 0, bufferSize, this.filePosition);
5309
- fs10.closeSync(fd);
5308
+ fs9.readSync(fd, buffer, 0, bufferSize, this.filePosition);
5309
+ fs9.closeSync(fd);
5310
5310
  const chunk = buffer.toString("utf-8");
5311
5311
  this.parser.processChunk(chunk);
5312
5312
  this.filePosition = currentSize;
@@ -5325,7 +5325,7 @@ var require_claudeCode = __commonJS({
5325
5325
  this._wasTruncated = false;
5326
5326
  }
5327
5327
  exists() {
5328
- return fs10.existsSync(this.sessionPath);
5328
+ return fs9.existsSync(this.sessionPath);
5329
5329
  }
5330
5330
  flush() {
5331
5331
  this.parser.flush();
@@ -5373,17 +5373,17 @@ var require_claudeCode = __commonJS({
5373
5373
  return filename.endsWith(".jsonl");
5374
5374
  }
5375
5375
  getSessionId(sessionPath) {
5376
- return path8.basename(sessionPath, ".jsonl");
5376
+ return path7.basename(sessionPath, ".jsonl");
5377
5377
  }
5378
5378
  encodeWorkspacePath(workspacePath) {
5379
5379
  return (0, sessionPathResolver_1.encodeWorkspacePath)(workspacePath);
5380
5380
  }
5381
5381
  extractSessionLabel(sessionPath) {
5382
5382
  try {
5383
- const fd = fs10.openSync(sessionPath, "r");
5383
+ const fd = fs9.openSync(sessionPath, "r");
5384
5384
  const buffer = Buffer.alloc(8192);
5385
- const bytesRead = fs10.readSync(fd, buffer, 0, 8192, 0);
5386
- fs10.closeSync(fd);
5385
+ const bytesRead = fs9.readSync(fd, buffer, 0, 8192, 0);
5386
+ fs9.closeSync(fd);
5387
5387
  if (bytesRead === 0)
5388
5388
  return null;
5389
5389
  const chunk = buffer.toString("utf-8", 0, bytesRead);
@@ -5436,9 +5436,9 @@ var require_claudeCode = __commonJS({
5436
5436
  const results = [];
5437
5437
  const queryLower = query.toLowerCase();
5438
5438
  try {
5439
- const content = fs10.readFileSync(sessionPath, "utf8");
5439
+ const content = fs9.readFileSync(sessionPath, "utf8");
5440
5440
  const lines = content.split("\n");
5441
- const projectDir = path8.basename(path8.dirname(sessionPath));
5441
+ const projectDir = path7.basename(path7.dirname(sessionPath));
5442
5442
  const projectPath = (0, sessionPathResolver_1.decodeEncodedPath)(projectDir);
5443
5443
  for (const line of lines) {
5444
5444
  if (results.length >= maxResults)
@@ -5472,11 +5472,11 @@ var require_claudeCode = __commonJS({
5472
5472
  return results;
5473
5473
  }
5474
5474
  getProjectsBaseDir() {
5475
- return path8.join(os6.homedir(), ".claude", "projects");
5475
+ return path7.join(os5.homedir(), ".claude", "projects");
5476
5476
  }
5477
5477
  // --- Stats ---
5478
5478
  readSessionStats(sessionPath) {
5479
- const sessionId = path8.basename(sessionPath, ".jsonl");
5479
+ const sessionId = path7.basename(sessionPath, ".jsonl");
5480
5480
  let messageCount = 0;
5481
5481
  let startTime = "";
5482
5482
  let endTime = "";
@@ -5487,7 +5487,7 @@ var require_claudeCode = __commonJS({
5487
5487
  let truncationCount = 0;
5488
5488
  let reportedCost = 0;
5489
5489
  try {
5490
- const content = fs10.readFileSync(sessionPath, "utf8");
5490
+ const content = fs9.readFileSync(sessionPath, "utf8");
5491
5491
  const lines = content.split("\n");
5492
5492
  for (const line of lines) {
5493
5493
  const trimmed = line.trim();
@@ -5570,14 +5570,14 @@ var require_claudeCode = __commonJS({
5570
5570
  */
5571
5571
  getCurrentUsageSnapshot(sessionPath) {
5572
5572
  try {
5573
- if (!fs10.existsSync(sessionPath))
5573
+ if (!fs9.existsSync(sessionPath))
5574
5574
  return null;
5575
- const stats = fs10.statSync(sessionPath);
5575
+ const stats = fs9.statSync(sessionPath);
5576
5576
  const readSize = Math.min(stats.size, 64 * 1024);
5577
- const fd = fs10.openSync(sessionPath, "r");
5577
+ const fd = fs9.openSync(sessionPath, "r");
5578
5578
  const buffer = Buffer.alloc(readSize);
5579
- fs10.readSync(fd, buffer, 0, readSize, stats.size - readSize);
5580
- fs10.closeSync(fd);
5579
+ fs9.readSync(fd, buffer, 0, readSize, stats.size - readSize);
5580
+ fs9.closeSync(fd);
5581
5581
  const chunk = buffer.toString("utf-8");
5582
5582
  const lines = chunk.split("\n").reverse();
5583
5583
  for (const line of lines) {
@@ -6120,17 +6120,17 @@ var require_openCodeDatabase = __commonJS({
6120
6120
  }();
6121
6121
  Object.defineProperty(exports, "__esModule", { value: true });
6122
6122
  exports.OpenCodeDatabase = void 0;
6123
- var fs10 = __importStar(__require("fs"));
6124
- var path8 = __importStar(__require("path"));
6123
+ var fs9 = __importStar(__require("fs"));
6124
+ var path7 = __importStar(__require("path"));
6125
6125
  var child_process_1 = __require("child_process");
6126
6126
  var OpenCodeDatabase = class {
6127
6127
  dbPath;
6128
6128
  sqlite3Available = null;
6129
6129
  constructor(dataDir) {
6130
- this.dbPath = path8.join(dataDir, "opencode.db");
6130
+ this.dbPath = path7.join(dataDir, "opencode.db");
6131
6131
  }
6132
6132
  isAvailable() {
6133
- return fs10.existsSync(this.dbPath);
6133
+ return fs9.existsSync(this.dbPath);
6134
6134
  }
6135
6135
  open() {
6136
6136
  if (this.sqlite3Available !== null)
@@ -6188,7 +6188,7 @@ var require_openCodeDatabase = __commonJS({
6188
6188
  const projPath = normalizePath(proj.worktree);
6189
6189
  if (projPath === normalized)
6190
6190
  return proj;
6191
- if (normalized.startsWith(projPath + path8.sep) || projPath.startsWith(normalized + path8.sep)) {
6191
+ if (normalized.startsWith(projPath + path7.sep) || projPath.startsWith(normalized + path7.sep)) {
6192
6192
  matches.push({ ...proj, pathLen: projPath.length });
6193
6193
  }
6194
6194
  }
@@ -6298,7 +6298,7 @@ var require_openCodeDatabase = __commonJS({
6298
6298
  /** Get the database file's mtime (ms epoch). Returns 0 if unavailable. */
6299
6299
  getDbMtime() {
6300
6300
  try {
6301
- return fs10.statSync(this.dbPath).mtime.getTime();
6301
+ return fs9.statSync(this.dbPath).mtime.getTime();
6302
6302
  } catch {
6303
6303
  return 0;
6304
6304
  }
@@ -6307,9 +6307,9 @@ var require_openCodeDatabase = __commonJS({
6307
6307
  exports.OpenCodeDatabase = OpenCodeDatabase;
6308
6308
  function normalizePath(input) {
6309
6309
  try {
6310
- return fs10.realpathSync(input);
6310
+ return fs9.realpathSync(input);
6311
6311
  } catch {
6312
- return path8.resolve(input);
6312
+ return path7.resolve(input);
6313
6313
  }
6314
6314
  }
6315
6315
  }
@@ -6358,21 +6358,21 @@ var require_openCode = __commonJS({
6358
6358
  }();
6359
6359
  Object.defineProperty(exports, "__esModule", { value: true });
6360
6360
  exports.OpenCodeProvider = void 0;
6361
- var fs10 = __importStar(__require("fs"));
6362
- var os6 = __importStar(__require("os"));
6363
- var path8 = __importStar(__require("path"));
6361
+ var fs9 = __importStar(__require("fs"));
6362
+ var os5 = __importStar(__require("os"));
6363
+ var path7 = __importStar(__require("path"));
6364
6364
  var child_process_1 = __require("child_process");
6365
6365
  var openCodeParser_1 = require_openCodeParser();
6366
6366
  var openCodeDatabase_1 = require_openCodeDatabase();
6367
6367
  function getOpenCodeDataDir() {
6368
6368
  const xdg = process.env.XDG_DATA_HOME;
6369
6369
  if (xdg) {
6370
- return path8.join(xdg, "opencode");
6370
+ return path7.join(xdg, "opencode");
6371
6371
  }
6372
- return path8.join(os6.homedir(), ".local", "share", "opencode");
6372
+ return path7.join(os5.homedir(), ".local", "share", "opencode");
6373
6373
  }
6374
6374
  function getStorageDir() {
6375
- return path8.join(getOpenCodeDataDir(), "storage");
6375
+ return path7.join(getOpenCodeDataDir(), "storage");
6376
6376
  }
6377
6377
  var GENERIC_AGENT_RE = /^(gpt-|claude-|o[1-9]|gemini|default|agent|worker)/i;
6378
6378
  function isGenericAgentType(type) {
@@ -6403,18 +6403,18 @@ var require_openCode = __commonJS({
6403
6403
  }
6404
6404
  var DB_SESSION_PREFIX = "db-sessions";
6405
6405
  function makeDbSessionPath(dataDir, projectId, sessionId) {
6406
- return path8.join(dataDir, DB_SESSION_PREFIX, projectId, `${sessionId}.json`);
6406
+ return path7.join(dataDir, DB_SESSION_PREFIX, projectId, `${sessionId}.json`);
6407
6407
  }
6408
6408
  function isDbSessionPath(sessionPath) {
6409
- return sessionPath.includes(path8.sep + DB_SESSION_PREFIX + path8.sep);
6409
+ return sessionPath.includes(path7.sep + DB_SESSION_PREFIX + path7.sep);
6410
6410
  }
6411
6411
  function extractProjectIdFromDbPath(sessionPath) {
6412
- const prefix = path8.sep + DB_SESSION_PREFIX + path8.sep;
6412
+ const prefix = path7.sep + DB_SESSION_PREFIX + path7.sep;
6413
6413
  const idx = sessionPath.indexOf(prefix);
6414
6414
  if (idx < 0)
6415
6415
  return null;
6416
6416
  const rest = sessionPath.substring(idx + prefix.length);
6417
- const slashIdx = rest.indexOf(path8.sep);
6417
+ const slashIdx = rest.indexOf(path7.sep);
6418
6418
  return slashIdx > 0 ? rest.substring(0, slashIdx) : null;
6419
6419
  }
6420
6420
  function extractRoleFromDbMessage(row) {
@@ -6446,25 +6446,25 @@ var require_openCode = __commonJS({
6446
6446
  function resolveProjectIdFromFiles(workspacePath) {
6447
6447
  const workspaceResolved = normalizePath(workspacePath);
6448
6448
  try {
6449
- const projectDir = path8.join(getStorageDir(), "project");
6450
- if (!fs10.existsSync(projectDir))
6449
+ const projectDir = path7.join(getStorageDir(), "project");
6450
+ if (!fs9.existsSync(projectDir))
6451
6451
  return resolveProjectIdFromGit(workspacePath);
6452
- const files = fs10.readdirSync(projectDir).filter((f) => f.endsWith(".json"));
6452
+ const files = fs9.readdirSync(projectDir).filter((f) => f.endsWith(".json"));
6453
6453
  const matches = [];
6454
6454
  for (const file of files) {
6455
6455
  try {
6456
- const project = JSON.parse(fs10.readFileSync(path8.join(projectDir, file), "utf-8"));
6456
+ const project = JSON.parse(fs9.readFileSync(path7.join(projectDir, file), "utf-8"));
6457
6457
  if (project.path) {
6458
6458
  const projectPath = normalizePath(project.path);
6459
6459
  if (projectPath === workspaceResolved) {
6460
6460
  matches.push({ id: project.id, path: projectPath });
6461
6461
  continue;
6462
6462
  }
6463
- if (workspaceResolved.startsWith(projectPath + path8.sep)) {
6463
+ if (workspaceResolved.startsWith(projectPath + path7.sep)) {
6464
6464
  matches.push({ id: project.id, path: projectPath });
6465
6465
  continue;
6466
6466
  }
6467
- if (projectPath.startsWith(workspaceResolved + path8.sep)) {
6467
+ if (projectPath.startsWith(workspaceResolved + path7.sep)) {
6468
6468
  matches.push({ id: project.id, path: projectPath });
6469
6469
  }
6470
6470
  }
@@ -6496,7 +6496,7 @@ var require_openCode = __commonJS({
6496
6496
  }
6497
6497
  function readJsonSafe(filePath) {
6498
6498
  try {
6499
- return JSON.parse(fs10.readFileSync(filePath, "utf-8"));
6499
+ return JSON.parse(fs9.readFileSync(filePath, "utf-8"));
6500
6500
  } catch {
6501
6501
  return null;
6502
6502
  }
@@ -6510,9 +6510,9 @@ var require_openCode = __commonJS({
6510
6510
  }
6511
6511
  function normalizePath(input) {
6512
6512
  try {
6513
- return fs10.realpathSync(input);
6513
+ return fs9.realpathSync(input);
6514
6514
  } catch {
6515
- return path8.resolve(input);
6515
+ return path7.resolve(input);
6516
6516
  }
6517
6517
  }
6518
6518
  var OpenCodeFileReader = class {
@@ -6524,33 +6524,33 @@ var require_openCode = __commonJS({
6524
6524
  this.storageBase = getStorageDir();
6525
6525
  }
6526
6526
  readNew() {
6527
- const messageDir = path8.join(this.storageBase, "message", this.sessionId);
6528
- if (!fs10.existsSync(messageDir))
6527
+ const messageDir = path7.join(this.storageBase, "message", this.sessionId);
6528
+ if (!fs9.existsSync(messageDir))
6529
6529
  return [];
6530
6530
  let messageFiles;
6531
6531
  try {
6532
- messageFiles = fs10.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
6532
+ messageFiles = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
6533
6533
  } catch {
6534
6534
  return [];
6535
6535
  }
6536
6536
  const newEvents = [];
6537
6537
  for (const file of messageFiles) {
6538
- const msgId = path8.basename(file, ".json");
6539
- const messagePath = path8.join(messageDir, file);
6538
+ const msgId = path7.basename(file, ".json");
6539
+ const messagePath = path7.join(messageDir, file);
6540
6540
  const message = readJsonSafe(messagePath);
6541
6541
  if (!message)
6542
6542
  continue;
6543
6543
  let messageMtimeMs = 0;
6544
6544
  try {
6545
- messageMtimeMs = fs10.statSync(messagePath).mtimeMs;
6545
+ messageMtimeMs = fs9.statSync(messagePath).mtimeMs;
6546
6546
  } catch {
6547
6547
  messageMtimeMs = 0;
6548
6548
  }
6549
- const partDir = path8.join(this.storageBase, "part", msgId);
6549
+ const partDir = path7.join(this.storageBase, "part", msgId);
6550
6550
  let parts = [];
6551
- if (fs10.existsSync(partDir)) {
6551
+ if (fs9.existsSync(partDir)) {
6552
6552
  try {
6553
- parts = fs10.readdirSync(partDir).filter((f) => f.endsWith(".json")).map((f) => readJsonSafe(path8.join(partDir, f))).filter((p) => p !== null);
6553
+ parts = fs9.readdirSync(partDir).filter((f) => f.endsWith(".json")).map((f) => readJsonSafe(path7.join(partDir, f))).filter((p) => p !== null);
6554
6554
  } catch {
6555
6555
  }
6556
6556
  }
@@ -6587,7 +6587,7 @@ var require_openCode = __commonJS({
6587
6587
  this.seenMessages.clear();
6588
6588
  }
6589
6589
  exists() {
6590
- return fs10.existsSync(path8.join(this.storageBase, "message", this.sessionId));
6590
+ return fs9.existsSync(path7.join(this.storageBase, "message", this.sessionId));
6591
6591
  }
6592
6592
  flush() {
6593
6593
  }
@@ -6794,11 +6794,11 @@ var require_openCode = __commonJS({
6794
6794
  const projectId = resolveProjectId(workspacePath, db);
6795
6795
  if (projectId) {
6796
6796
  if (db) {
6797
- return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
6797
+ return path7.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
6798
6798
  }
6799
- return path8.join(getStorageDir(), "session", projectId);
6799
+ return path7.join(getStorageDir(), "session", projectId);
6800
6800
  }
6801
- return path8.join(getStorageDir(), "session");
6801
+ return path7.join(getStorageDir(), "session");
6802
6802
  }
6803
6803
  discoverSessionDirectory(workspacePath) {
6804
6804
  const db = this.ensureDb();
@@ -6808,11 +6808,11 @@ var require_openCode = __commonJS({
6808
6808
  if (db) {
6809
6809
  const sessions = db.getSessionsForProject(projectId);
6810
6810
  if (sessions.length > 0) {
6811
- return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
6811
+ return path7.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
6812
6812
  }
6813
6813
  }
6814
- const dir = path8.join(getStorageDir(), "session", projectId);
6815
- return fs10.existsSync(dir) ? dir : null;
6814
+ const dir = path7.join(getStorageDir(), "session", projectId);
6815
+ return fs9.existsSync(dir) ? dir : null;
6816
6816
  }
6817
6817
  // --- Session discovery ---
6818
6818
  findActiveSession(workspacePath) {
@@ -6834,17 +6834,17 @@ var require_openCode = __commonJS({
6834
6834
  return this.findActiveSessionFromFiles(projectId);
6835
6835
  }
6836
6836
  findActiveSessionFromFiles(projectId) {
6837
- const sessionDir = path8.join(getStorageDir(), "session", projectId);
6838
- if (!fs10.existsSync(sessionDir))
6837
+ const sessionDir = path7.join(getStorageDir(), "session", projectId);
6838
+ if (!fs9.existsSync(sessionDir))
6839
6839
  return null;
6840
6840
  let bestPath = null;
6841
6841
  let bestMtime = 0;
6842
6842
  try {
6843
- const files = fs10.readdirSync(sessionDir).filter((f) => f.endsWith(".json"));
6843
+ const files = fs9.readdirSync(sessionDir).filter((f) => f.endsWith(".json"));
6844
6844
  for (const file of files) {
6845
- const fullPath = path8.join(sessionDir, file);
6845
+ const fullPath = path7.join(sessionDir, file);
6846
6846
  try {
6847
- const stats = fs10.statSync(fullPath);
6847
+ const stats = fs9.statSync(fullPath);
6848
6848
  if (stats.size > 0 && stats.mtime.getTime() > bestMtime) {
6849
6849
  bestMtime = stats.mtime.getTime();
6850
6850
  bestPath = fullPath;
@@ -6856,14 +6856,14 @@ var require_openCode = __commonJS({
6856
6856
  return null;
6857
6857
  }
6858
6858
  if (bestPath) {
6859
- const sessionId = path8.basename(bestPath, ".json");
6860
- const messageDir = path8.join(getStorageDir(), "message", sessionId);
6861
- if (fs10.existsSync(messageDir)) {
6859
+ const sessionId = path7.basename(bestPath, ".json");
6860
+ const messageDir = path7.join(getStorageDir(), "message", sessionId);
6861
+ if (fs9.existsSync(messageDir)) {
6862
6862
  try {
6863
- const messageFiles = fs10.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
6863
+ const messageFiles = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
6864
6864
  for (const mf of messageFiles) {
6865
6865
  try {
6866
- const mstat = fs10.statSync(path8.join(messageDir, mf));
6866
+ const mstat = fs9.statSync(path7.join(messageDir, mf));
6867
6867
  if (mstat.mtime.getTime() > bestMtime) {
6868
6868
  bestMtime = mstat.mtime.getTime();
6869
6869
  }
@@ -6900,13 +6900,13 @@ var require_openCode = __commonJS({
6900
6900
  });
6901
6901
  }
6902
6902
  }
6903
- const sessionDir = path8.join(getStorageDir(), "session", projectId);
6903
+ const sessionDir = path7.join(getStorageDir(), "session", projectId);
6904
6904
  return this.findSessionsInDirectoryFromFiles(sessionDir);
6905
6905
  }
6906
6906
  findSessionsInDirectory(dir) {
6907
6907
  const db = this.ensureDb();
6908
- if (db && dir.includes(path8.sep + DB_SESSION_PREFIX + path8.sep)) {
6909
- const projectId = extractProjectIdFromDbPath(dir + path8.sep + "dummy.json");
6908
+ if (db && dir.includes(path7.sep + DB_SESSION_PREFIX + path7.sep)) {
6909
+ const projectId = extractProjectIdFromDbPath(dir + path7.sep + "dummy.json");
6910
6910
  if (projectId) {
6911
6911
  const sessions = db.getSessionsForProject(projectId);
6912
6912
  const dataDir = getOpenCodeDataDir();
@@ -6921,7 +6921,7 @@ var require_openCode = __commonJS({
6921
6921
  }
6922
6922
  }
6923
6923
  if (db) {
6924
- const dirName = path8.basename(dir);
6924
+ const dirName = path7.basename(dir);
6925
6925
  const sessions = db.getSessionsForProject(dirName);
6926
6926
  if (sessions.length > 0) {
6927
6927
  const dataDir = getOpenCodeDataDir();
@@ -6939,12 +6939,12 @@ var require_openCode = __commonJS({
6939
6939
  }
6940
6940
  findSessionsInDirectoryFromFiles(dir) {
6941
6941
  try {
6942
- if (!fs10.existsSync(dir))
6942
+ if (!fs9.existsSync(dir))
6943
6943
  return [];
6944
- return fs10.readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => {
6945
- const fullPath = path8.join(dir, f);
6944
+ return fs9.readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => {
6945
+ const fullPath = path7.join(dir, f);
6946
6946
  try {
6947
- const stats = fs10.statSync(fullPath);
6947
+ const stats = fs9.statSync(fullPath);
6948
6948
  return { path: fullPath, mtime: stats.mtime.getTime(), size: stats.size };
6949
6949
  } catch {
6950
6950
  return null;
@@ -6971,7 +6971,7 @@ var require_openCode = __commonJS({
6971
6971
  if (!projStats || projStats.sessionCount === 0)
6972
6972
  continue;
6973
6973
  folders.push({
6974
- dir: path8.join(dataDir, DB_SESSION_PREFIX, project.id),
6974
+ dir: path7.join(dataDir, DB_SESSION_PREFIX, project.id),
6975
6975
  name: project.worktree || project.name || project.id,
6976
6976
  encodedName: project.id,
6977
6977
  sessionCount: projStats.sessionCount,
@@ -6996,23 +6996,23 @@ var require_openCode = __commonJS({
6996
6996
  }
6997
6997
  getAllProjectFoldersFromFiles(workspacePath) {
6998
6998
  const folders = [];
6999
- const sessionBase = path8.join(getStorageDir(), "session");
6999
+ const sessionBase = path7.join(getStorageDir(), "session");
7000
7000
  try {
7001
- if (!fs10.existsSync(sessionBase))
7001
+ if (!fs9.existsSync(sessionBase))
7002
7002
  return [];
7003
- const projectIds = fs10.readdirSync(sessionBase).filter((name) => {
7003
+ const projectIds = fs9.readdirSync(sessionBase).filter((name) => {
7004
7004
  try {
7005
- return fs10.statSync(path8.join(sessionBase, name)).isDirectory();
7005
+ return fs9.statSync(path7.join(sessionBase, name)).isDirectory();
7006
7006
  } catch {
7007
7007
  return false;
7008
7008
  }
7009
7009
  });
7010
- const projectDir = path8.join(getStorageDir(), "project");
7010
+ const projectDir = path7.join(getStorageDir(), "project");
7011
7011
  const projectNames = /* @__PURE__ */ new Map();
7012
- if (fs10.existsSync(projectDir)) {
7012
+ if (fs9.existsSync(projectDir)) {
7013
7013
  try {
7014
- for (const file of fs10.readdirSync(projectDir).filter((f) => f.endsWith(".json"))) {
7015
- const proj = readJsonSafe(path8.join(projectDir, file));
7014
+ for (const file of fs9.readdirSync(projectDir).filter((f) => f.endsWith(".json"))) {
7015
+ const proj = readJsonSafe(path7.join(projectDir, file));
7016
7016
  if (proj) {
7017
7017
  projectNames.set(proj.id, proj.path || proj.name || proj.id);
7018
7018
  }
@@ -7025,14 +7025,14 @@ var require_openCode = __commonJS({
7025
7025
  currentProjectId = resolveProjectIdFromFiles(workspacePath);
7026
7026
  }
7027
7027
  for (const projectId of projectIds) {
7028
- const projSessionDir = path8.join(sessionBase, projectId);
7028
+ const projSessionDir = path7.join(sessionBase, projectId);
7029
7029
  let sessionCount = 0;
7030
7030
  let lastModified = /* @__PURE__ */ new Date(0);
7031
7031
  try {
7032
- const sessions = fs10.readdirSync(projSessionDir).filter((f) => f.endsWith(".json"));
7032
+ const sessions = fs9.readdirSync(projSessionDir).filter((f) => f.endsWith(".json"));
7033
7033
  for (const session of sessions) {
7034
7034
  try {
7035
- const fstats = fs10.statSync(path8.join(projSessionDir, session));
7035
+ const fstats = fs9.statSync(path7.join(projSessionDir, session));
7036
7036
  if (fstats.size > 0) {
7037
7037
  sessionCount++;
7038
7038
  if (fstats.mtime > lastModified) {
@@ -7073,7 +7073,7 @@ var require_openCode = __commonJS({
7073
7073
  return filename.endsWith(".json");
7074
7074
  }
7075
7075
  getSessionId(sessionPath) {
7076
- return path8.basename(sessionPath, ".json");
7076
+ return path7.basename(sessionPath, ".json");
7077
7077
  }
7078
7078
  encodeWorkspacePath(workspacePath) {
7079
7079
  const db = this.ensureDb();
@@ -7101,19 +7101,19 @@ var require_openCode = __commonJS({
7101
7101
  if (session?.title) {
7102
7102
  return truncateTitle(session.title);
7103
7103
  }
7104
- const messageDir = path8.join(getStorageDir(), "message", sessionId);
7105
- if (!fs10.existsSync(messageDir))
7104
+ const messageDir = path7.join(getStorageDir(), "message", sessionId);
7105
+ if (!fs9.existsSync(messageDir))
7106
7106
  return null;
7107
7107
  try {
7108
- const files = fs10.readdirSync(messageDir).filter((f) => f.endsWith(".json")).slice(0, 5);
7108
+ const files = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json")).slice(0, 5);
7109
7109
  for (const file of files) {
7110
- const msg = readJsonSafe(path8.join(messageDir, file));
7110
+ const msg = readJsonSafe(path7.join(messageDir, file));
7111
7111
  if (msg?.role === "user") {
7112
- const partDir = path8.join(getStorageDir(), "part", msg.id);
7113
- if (fs10.existsSync(partDir)) {
7114
- const partFiles = fs10.readdirSync(partDir).filter((f) => f.endsWith(".json"));
7112
+ const partDir = path7.join(getStorageDir(), "part", msg.id);
7113
+ if (fs9.existsSync(partDir)) {
7114
+ const partFiles = fs9.readdirSync(partDir).filter((f) => f.endsWith(".json"));
7115
7115
  for (const pf of partFiles) {
7116
- const part = readJsonSafe(path8.join(partDir, pf));
7116
+ const part = readJsonSafe(path7.join(partDir, pf));
7117
7117
  if (part?.type === "text" && part.text.trim().length > 0) {
7118
7118
  let text = part.text.trim().replace(/\s+/g, " ");
7119
7119
  if (text.length > 60) {
@@ -7297,28 +7297,28 @@ var require_openCode = __commonJS({
7297
7297
  }
7298
7298
  searchInSessionFromFiles(sessionPath, sessionId, queryLower, query, maxResults) {
7299
7299
  const results = [];
7300
- const messageDir = path8.join(getStorageDir(), "message", sessionId);
7301
- if (!fs10.existsSync(messageDir))
7300
+ const messageDir = path7.join(getStorageDir(), "message", sessionId);
7301
+ if (!fs9.existsSync(messageDir))
7302
7302
  return results;
7303
7303
  try {
7304
7304
  const session = readJsonSafe(sessionPath);
7305
7305
  const projectPath = session?.projectID || sessionId;
7306
- const messageFiles = fs10.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
7306
+ const messageFiles = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
7307
7307
  for (const file of messageFiles) {
7308
7308
  if (results.length >= maxResults)
7309
7309
  break;
7310
- const msg = readJsonSafe(path8.join(messageDir, file));
7310
+ const msg = readJsonSafe(path7.join(messageDir, file));
7311
7311
  if (!msg)
7312
7312
  continue;
7313
- const partDir = path8.join(getStorageDir(), "part", msg.id);
7314
- if (!fs10.existsSync(partDir))
7313
+ const partDir = path7.join(getStorageDir(), "part", msg.id);
7314
+ if (!fs9.existsSync(partDir))
7315
7315
  continue;
7316
7316
  try {
7317
- const partFiles = fs10.readdirSync(partDir).filter((f) => f.endsWith(".json"));
7317
+ const partFiles = fs9.readdirSync(partDir).filter((f) => f.endsWith(".json"));
7318
7318
  for (const pf of partFiles) {
7319
7319
  if (results.length >= maxResults)
7320
7320
  break;
7321
- const part = readJsonSafe(path8.join(partDir, pf));
7321
+ const part = readJsonSafe(path7.join(partDir, pf));
7322
7322
  if (!part)
7323
7323
  continue;
7324
7324
  let text = "";
@@ -7355,11 +7355,11 @@ var require_openCode = __commonJS({
7355
7355
  return results;
7356
7356
  }
7357
7357
  getProjectsBaseDir() {
7358
- return path8.join(getStorageDir(), "session");
7358
+ return path7.join(getStorageDir(), "session");
7359
7359
  }
7360
7360
  // --- Stats ---
7361
7361
  readSessionStats(sessionPath) {
7362
- const sessionId = path8.basename(sessionPath, ".json");
7362
+ const sessionId = path7.basename(sessionPath, ".json");
7363
7363
  const db = this.ensureDb();
7364
7364
  let messageCount = 0;
7365
7365
  let startTime = "";
@@ -7447,7 +7447,7 @@ var require_openCode = __commonJS({
7447
7447
  }
7448
7448
  if (!isDbSessionPath(sessionPath)) {
7449
7449
  try {
7450
- const stats = fs10.statSync(sessionPath);
7450
+ const stats = fs9.statSync(sessionPath);
7451
7451
  return { mtime: stats.mtime };
7452
7452
  } catch {
7453
7453
  }
@@ -8240,18 +8240,18 @@ var require_codexDatabase = __commonJS({
8240
8240
  }();
8241
8241
  Object.defineProperty(exports, "__esModule", { value: true });
8242
8242
  exports.CodexDatabase = void 0;
8243
- var fs10 = __importStar(__require("fs"));
8244
- var path8 = __importStar(__require("path"));
8243
+ var fs9 = __importStar(__require("fs"));
8244
+ var path7 = __importStar(__require("path"));
8245
8245
  var child_process_1 = __require("child_process");
8246
8246
  var CodexDatabase = class {
8247
8247
  dbPath;
8248
8248
  sqlite3Available = null;
8249
8249
  constructor(codexHome) {
8250
- this.dbPath = path8.join(codexHome, "state.sqlite");
8250
+ this.dbPath = path7.join(codexHome, "state.sqlite");
8251
8251
  }
8252
8252
  isAvailable() {
8253
8253
  try {
8254
- return fs10.statSync(this.dbPath).size > 0;
8254
+ return fs9.statSync(this.dbPath).size > 0;
8255
8255
  } catch {
8256
8256
  return false;
8257
8257
  }
@@ -8312,7 +8312,7 @@ var require_codexDatabase = __commonJS({
8312
8312
  const all = this.query("SELECT * FROM threads ORDER BY updated_at DESC");
8313
8313
  return all.filter((t) => {
8314
8314
  const threadCwd = normalizePath(t.cwd);
8315
- return threadCwd === normalized || normalized.startsWith(threadCwd + path8.sep) || threadCwd.startsWith(normalized + path8.sep);
8315
+ return threadCwd === normalized || normalized.startsWith(threadCwd + path7.sep) || threadCwd.startsWith(normalized + path7.sep);
8316
8316
  });
8317
8317
  }
8318
8318
  getMostRecentThread(cwd2) {
@@ -8331,7 +8331,7 @@ var require_codexDatabase = __commonJS({
8331
8331
  /** Get the database file's mtime (ms epoch). Returns 0 if unavailable. */
8332
8332
  getDbMtime() {
8333
8333
  try {
8334
- return fs10.statSync(this.dbPath).mtime.getTime();
8334
+ return fs9.statSync(this.dbPath).mtime.getTime();
8335
8335
  } catch {
8336
8336
  return 0;
8337
8337
  }
@@ -8340,9 +8340,9 @@ var require_codexDatabase = __commonJS({
8340
8340
  exports.CodexDatabase = CodexDatabase;
8341
8341
  function normalizePath(input) {
8342
8342
  try {
8343
- return fs10.realpathSync(input);
8343
+ return fs9.realpathSync(input);
8344
8344
  } catch {
8345
- return path8.resolve(input);
8345
+ return path7.resolve(input);
8346
8346
  }
8347
8347
  }
8348
8348
  }
@@ -8391,25 +8391,25 @@ var require_codex = __commonJS({
8391
8391
  }();
8392
8392
  Object.defineProperty(exports, "__esModule", { value: true });
8393
8393
  exports.CodexProvider = void 0;
8394
- var fs10 = __importStar(__require("fs"));
8395
- var os6 = __importStar(__require("os"));
8396
- var path8 = __importStar(__require("path"));
8394
+ var fs9 = __importStar(__require("fs"));
8395
+ var os5 = __importStar(__require("os"));
8396
+ var path7 = __importStar(__require("path"));
8397
8397
  var codexParser_1 = require_codexParser();
8398
8398
  var codexDatabase_1 = require_codexDatabase();
8399
8399
  function getCodexHome() {
8400
8400
  const envHome = process.env.CODEX_HOME;
8401
8401
  if (envHome)
8402
8402
  return envHome;
8403
- return path8.join(os6.homedir(), ".codex");
8403
+ return path7.join(os5.homedir(), ".codex");
8404
8404
  }
8405
8405
  function getSessionsDir() {
8406
- return path8.join(getCodexHome(), "sessions");
8406
+ return path7.join(getCodexHome(), "sessions");
8407
8407
  }
8408
8408
  function isRolloutFile(filename) {
8409
8409
  return filename.startsWith("rollout-") && filename.endsWith(".jsonl");
8410
8410
  }
8411
8411
  function extractSessionId(filename) {
8412
- const base = path8.basename(filename, ".jsonl");
8412
+ const base = path7.basename(filename, ".jsonl");
8413
8413
  const parts = base.split("-");
8414
8414
  if (parts.length >= 6) {
8415
8415
  const possibleUuid = parts.slice(-5).join("-");
@@ -8429,16 +8429,16 @@ var require_codex = __commonJS({
8429
8429
  function findRolloutFiles(dir) {
8430
8430
  const results = [];
8431
8431
  try {
8432
- if (!fs10.existsSync(dir))
8432
+ if (!fs9.existsSync(dir))
8433
8433
  return results;
8434
- const entries = fs10.readdirSync(dir, { withFileTypes: true });
8434
+ const entries = fs9.readdirSync(dir, { withFileTypes: true });
8435
8435
  for (const entry of entries) {
8436
- const fullPath = path8.join(dir, entry.name);
8436
+ const fullPath = path7.join(dir, entry.name);
8437
8437
  if (entry.isDirectory()) {
8438
8438
  results.push(...findRolloutFiles(fullPath));
8439
8439
  } else if (entry.isFile() && isRolloutFile(entry.name)) {
8440
8440
  try {
8441
- const stats = fs10.statSync(fullPath);
8441
+ const stats = fs9.statSync(fullPath);
8442
8442
  if (stats.size > 0) {
8443
8443
  results.push({ path: fullPath, mtime: stats.mtime });
8444
8444
  }
@@ -8458,7 +8458,7 @@ var require_codex = __commonJS({
8458
8458
  const lines = [];
8459
8459
  let fd;
8460
8460
  try {
8461
- fd = fs10.openSync(filePath, "r");
8461
+ fd = fs9.openSync(filePath, "r");
8462
8462
  } catch {
8463
8463
  return [];
8464
8464
  }
@@ -8468,7 +8468,7 @@ var require_codex = __commonJS({
8468
8468
  try {
8469
8469
  while (totalRead < maxBytes && lines.length < maxLines) {
8470
8470
  const buf = Buffer.alloc(Math.min(chunkSize, maxBytes - totalRead));
8471
- const bytesRead = fs10.readSync(fd, buf, 0, buf.length, totalRead);
8471
+ const bytesRead = fs9.readSync(fd, buf, 0, buf.length, totalRead);
8472
8472
  if (bytesRead === 0)
8473
8473
  break;
8474
8474
  totalRead += bytesRead;
@@ -8483,7 +8483,7 @@ var require_codex = __commonJS({
8483
8483
  lines.push(pending);
8484
8484
  }
8485
8485
  } finally {
8486
- fs10.closeSync(fd);
8486
+ fs9.closeSync(fd);
8487
8487
  }
8488
8488
  return lines;
8489
8489
  }
@@ -8514,13 +8514,13 @@ var require_codex = __commonJS({
8514
8514
  function cwdMatches(sessionCwd, workspacePath) {
8515
8515
  const normalizedSession = normalizePath(sessionCwd);
8516
8516
  const normalizedWorkspace = normalizePath(workspacePath);
8517
- return normalizedSession === normalizedWorkspace || normalizedWorkspace.startsWith(normalizedSession + path8.sep) || normalizedSession.startsWith(normalizedWorkspace + path8.sep);
8517
+ return normalizedSession === normalizedWorkspace || normalizedWorkspace.startsWith(normalizedSession + path7.sep) || normalizedSession.startsWith(normalizedWorkspace + path7.sep);
8518
8518
  }
8519
8519
  function normalizePath(input) {
8520
8520
  try {
8521
- return fs10.realpathSync(input);
8521
+ return fs9.realpathSync(input);
8522
8522
  } catch {
8523
- return path8.resolve(input);
8523
+ return path7.resolve(input);
8524
8524
  }
8525
8525
  }
8526
8526
  function extractFirstUserMessage(rolloutPath) {
@@ -8626,9 +8626,9 @@ var require_codex = __commonJS({
8626
8626
  this._wasTruncated = false;
8627
8627
  const events = [];
8628
8628
  try {
8629
- if (!fs10.existsSync(this.rolloutPath))
8629
+ if (!fs9.existsSync(this.rolloutPath))
8630
8630
  return [];
8631
- const stats = fs10.statSync(this.rolloutPath);
8631
+ const stats = fs9.statSync(this.rolloutPath);
8632
8632
  const currentSize = stats.size;
8633
8633
  if (currentSize < this.filePosition) {
8634
8634
  this._wasTruncated = true;
@@ -8638,11 +8638,11 @@ var require_codex = __commonJS({
8638
8638
  }
8639
8639
  if (currentSize <= this.filePosition)
8640
8640
  return [];
8641
- const fd = fs10.openSync(this.rolloutPath, "r");
8641
+ const fd = fs9.openSync(this.rolloutPath, "r");
8642
8642
  const bufferSize = currentSize - this.filePosition;
8643
8643
  const buffer = Buffer.alloc(bufferSize);
8644
- fs10.readSync(fd, buffer, 0, bufferSize, this.filePosition);
8645
- fs10.closeSync(fd);
8644
+ fs9.readSync(fd, buffer, 0, bufferSize, this.filePosition);
8645
+ fs9.closeSync(fd);
8646
8646
  const chunk = buffer.toString("utf-8");
8647
8647
  this.filePosition = currentSize;
8648
8648
  const text = this.lineBuffer + chunk;
@@ -8693,7 +8693,7 @@ var require_codex = __commonJS({
8693
8693
  this._wasTruncated = false;
8694
8694
  }
8695
8695
  exists() {
8696
- return fs10.existsSync(this.rolloutPath);
8696
+ return fs9.existsSync(this.rolloutPath);
8697
8697
  }
8698
8698
  flush() {
8699
8699
  if (this.lineBuffer.trim()) {
@@ -8742,7 +8742,7 @@ var require_codex = __commonJS({
8742
8742
  if (db) {
8743
8743
  const thread = db.getMostRecentThread(workspacePath);
8744
8744
  if (thread?.rollout_path) {
8745
- return path8.dirname(thread.rollout_path);
8745
+ return path7.dirname(thread.rollout_path);
8746
8746
  }
8747
8747
  }
8748
8748
  return getSessionsDir();
@@ -8751,12 +8751,12 @@ var require_codex = __commonJS({
8751
8751
  const db = this.ensureDb();
8752
8752
  if (db) {
8753
8753
  const thread = db.getMostRecentThread(workspacePath);
8754
- if (thread?.rollout_path && fs10.existsSync(thread.rollout_path)) {
8755
- return path8.dirname(thread.rollout_path);
8754
+ if (thread?.rollout_path && fs9.existsSync(thread.rollout_path)) {
8755
+ return path7.dirname(thread.rollout_path);
8756
8756
  }
8757
8757
  }
8758
8758
  const sessionsDir = getSessionsDir();
8759
- if (!fs10.existsSync(sessionsDir))
8759
+ if (!fs9.existsSync(sessionsDir))
8760
8760
  return null;
8761
8761
  const files = findRolloutFiles(sessionsDir);
8762
8762
  if (files.length === 0)
@@ -8765,22 +8765,22 @@ var require_codex = __commonJS({
8765
8765
  for (const file of files) {
8766
8766
  const meta = readSessionMeta(file.path);
8767
8767
  if (meta && cwdMatches(meta.cwd, workspacePath)) {
8768
- return path8.dirname(file.path);
8768
+ return path7.dirname(file.path);
8769
8769
  }
8770
8770
  }
8771
- return fs10.existsSync(sessionsDir) ? sessionsDir : null;
8771
+ return fs9.existsSync(sessionsDir) ? sessionsDir : null;
8772
8772
  }
8773
8773
  // --- Session discovery ---
8774
8774
  findActiveSession(workspacePath) {
8775
8775
  const db = this.ensureDb();
8776
8776
  if (db) {
8777
8777
  const thread = db.getMostRecentThread(workspacePath);
8778
- if (thread?.rollout_path && fs10.existsSync(thread.rollout_path)) {
8778
+ if (thread?.rollout_path && fs9.existsSync(thread.rollout_path)) {
8779
8779
  return thread.rollout_path;
8780
8780
  }
8781
8781
  }
8782
8782
  const sessionsDir = getSessionsDir();
8783
- if (!fs10.existsSync(sessionsDir))
8783
+ if (!fs9.existsSync(sessionsDir))
8784
8784
  return null;
8785
8785
  const files = findRolloutFiles(sessionsDir);
8786
8786
  files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
@@ -8796,12 +8796,12 @@ var require_codex = __commonJS({
8796
8796
  const db = this.ensureDb();
8797
8797
  if (db) {
8798
8798
  const threads = db.getThreadsByCwd(workspacePath);
8799
- const dbPaths = threads.filter((t) => t.rollout_path && fs10.existsSync(t.rollout_path)).map((t) => t.rollout_path);
8799
+ const dbPaths = threads.filter((t) => t.rollout_path && fs9.existsSync(t.rollout_path)).map((t) => t.rollout_path);
8800
8800
  if (dbPaths.length > 0)
8801
8801
  return dbPaths;
8802
8802
  }
8803
8803
  const sessionsDir = getSessionsDir();
8804
- if (!fs10.existsSync(sessionsDir))
8804
+ if (!fs9.existsSync(sessionsDir))
8805
8805
  return [];
8806
8806
  const files = findRolloutFiles(sessionsDir);
8807
8807
  files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
@@ -8836,7 +8836,7 @@ var require_codex = __commonJS({
8836
8836
  }
8837
8837
  }
8838
8838
  const sessionsDir = getSessionsDir();
8839
- if (fs10.existsSync(sessionsDir)) {
8839
+ if (fs9.existsSync(sessionsDir)) {
8840
8840
  const files = findRolloutFiles(sessionsDir);
8841
8841
  for (const file of files) {
8842
8842
  const meta = readSessionMeta(file.path);
@@ -8849,7 +8849,7 @@ var require_codex = __commonJS({
8849
8849
  }
8850
8850
  } else {
8851
8851
  seenCwds.set(meta.cwd, {
8852
- dir: path8.dirname(file.path),
8852
+ dir: path7.dirname(file.path),
8853
8853
  name: meta.cwd,
8854
8854
  encodedName: meta.cwd,
8855
8855
  sessionCount: 1,
@@ -8878,7 +8878,7 @@ var require_codex = __commonJS({
8878
8878
  return isRolloutFile(filename);
8879
8879
  }
8880
8880
  getSessionId(sessionPath) {
8881
- return extractSessionId(path8.basename(sessionPath));
8881
+ return extractSessionId(path7.basename(sessionPath));
8882
8882
  }
8883
8883
  encodeWorkspacePath(workspacePath) {
8884
8884
  return workspacePath;
@@ -8920,7 +8920,7 @@ var require_codex = __commonJS({
8920
8920
  return subagents;
8921
8921
  }
8922
8922
  const sessionsDir = getSessionsDir();
8923
- if (!fs10.existsSync(sessionsDir))
8923
+ if (!fs9.existsSync(sessionsDir))
8924
8924
  return subagents;
8925
8925
  const files = findRolloutFiles(sessionsDir);
8926
8926
  files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
@@ -8928,7 +8928,7 @@ var require_codex = __commonJS({
8928
8928
  for (const file of filesToCheck) {
8929
8929
  const meta = readSessionMeta(file.path);
8930
8930
  if (meta?.forked_from_id === sessionId) {
8931
- const childId = extractSessionId(path8.basename(file.path));
8931
+ const childId = extractSessionId(path7.basename(file.path));
8932
8932
  const stats = this.buildSubagentStats(childId, file.path, meta.source);
8933
8933
  if (stats)
8934
8934
  subagents.push(stats);
@@ -8940,7 +8940,7 @@ var require_codex = __commonJS({
8940
8940
  * Builds SubagentStats for a forked session by reading its rollout file.
8941
8941
  */
8942
8942
  buildSubagentStats(agentId, rolloutPath, description) {
8943
- if (!rolloutPath || !fs10.existsSync(rolloutPath))
8943
+ if (!rolloutPath || !fs9.existsSync(rolloutPath))
8944
8944
  return null;
8945
8945
  const stats = {
8946
8946
  agentId,
@@ -8951,7 +8951,7 @@ var require_codex = __commonJS({
8951
8951
  };
8952
8952
  try {
8953
8953
  const parser = new codexParser_1.CodexRolloutParser();
8954
- const content = fs10.readFileSync(rolloutPath, "utf8");
8954
+ const content = fs9.readFileSync(rolloutPath, "utf8");
8955
8955
  const lines = content.split("\n");
8956
8956
  for (const line of lines) {
8957
8957
  const trimmed = line.trim();
@@ -8999,7 +8999,7 @@ var require_codex = __commonJS({
8999
8999
  const results = [];
9000
9000
  const queryLower = query.toLowerCase();
9001
9001
  try {
9002
- const content = fs10.readFileSync(sessionPath, "utf8");
9002
+ const content = fs9.readFileSync(sessionPath, "utf8");
9003
9003
  const lines = content.split("\n");
9004
9004
  for (const line of lines) {
9005
9005
  if (results.length >= maxResults)
@@ -9040,7 +9040,7 @@ var require_codex = __commonJS({
9040
9040
  }
9041
9041
  // --- Stats ---
9042
9042
  readSessionStats(sessionPath) {
9043
- const sessionId = extractSessionId(path8.basename(sessionPath));
9043
+ const sessionId = extractSessionId(path7.basename(sessionPath));
9044
9044
  let messageCount = 0;
9045
9045
  let startTime = "";
9046
9046
  let endTime = "";
@@ -9050,7 +9050,7 @@ var require_codex = __commonJS({
9050
9050
  let compactionEstimate = 0;
9051
9051
  let currentModel = "unknown";
9052
9052
  try {
9053
- const content = fs10.readFileSync(sessionPath, "utf8");
9053
+ const content = fs9.readFileSync(sessionPath, "utf8");
9054
9054
  const lines = content.split("\n");
9055
9055
  for (const line of lines) {
9056
9056
  const trimmed = line.trim();
@@ -9202,7 +9202,7 @@ var require_sessionActivityDetector = __commonJS({
9202
9202
  }();
9203
9203
  Object.defineProperty(exports, "__esModule", { value: true });
9204
9204
  exports.detectSessionActivity = detectSessionActivity;
9205
- var fs10 = __importStar(__require("fs"));
9205
+ var fs9 = __importStar(__require("fs"));
9206
9206
  var TAIL_BYTES = 32 * 1024;
9207
9207
  var GRACE_PERIOD_MS = 5e3;
9208
9208
  var STALENESS_THRESHOLD_MS = 5 * 60 * 1e3;
@@ -9224,7 +9224,7 @@ var require_sessionActivityDetector = __commonJS({
9224
9224
  function detectSessionActivity(sessionPath) {
9225
9225
  let stat;
9226
9226
  try {
9227
- stat = fs10.statSync(sessionPath);
9227
+ stat = fs9.statSync(sessionPath);
9228
9228
  } catch {
9229
9229
  return { state: "ended", lastActivityTime: null, reason: "file-not-found" };
9230
9230
  }
@@ -9291,17 +9291,17 @@ var require_sessionActivityDetector = __commonJS({
9291
9291
  return null;
9292
9292
  let fd = null;
9293
9293
  try {
9294
- fd = fs10.openSync(filePath, "r");
9294
+ fd = fs9.openSync(filePath, "r");
9295
9295
  const buffer = Buffer.alloc(bytesToRead);
9296
9296
  const offset = Math.max(0, fileSize - bytesToRead);
9297
- const bytesRead = fs10.readSync(fd, buffer, 0, bytesToRead, offset);
9298
- fs10.closeSync(fd);
9297
+ const bytesRead = fs9.readSync(fd, buffer, 0, bytesToRead, offset);
9298
+ fs9.closeSync(fd);
9299
9299
  fd = null;
9300
9300
  return buffer.toString("utf-8", 0, bytesRead);
9301
9301
  } catch {
9302
9302
  if (fd !== null) {
9303
9303
  try {
9304
- fs10.closeSync(fd);
9304
+ fs9.closeSync(fd);
9305
9305
  } catch {
9306
9306
  }
9307
9307
  }
@@ -9393,24 +9393,24 @@ var require_toolSummary = __commonJS({
9393
9393
  if (!pattern)
9394
9394
  return "";
9395
9395
  const glob = input.glob;
9396
- const path8 = input.path;
9396
+ const path7 = input.path;
9397
9397
  const type = input.type;
9398
9398
  const parts = [truncate2(pattern, 40)];
9399
9399
  if (glob)
9400
9400
  parts.push(`in ${glob}`);
9401
9401
  else if (type)
9402
9402
  parts.push(`in *.${type}`);
9403
- else if (path8)
9404
- parts.push(`in ${basename5(path8)}`);
9403
+ else if (path7)
9404
+ parts.push(`in ${basename5(path7)}`);
9405
9405
  return parts.join(" ");
9406
9406
  };
9407
9407
  var formatGlob = (input) => {
9408
9408
  const pattern = input.pattern;
9409
9409
  if (!pattern)
9410
9410
  return "";
9411
- const path8 = input.path;
9412
- if (path8)
9413
- return `${pattern} in ${basename5(path8)}`;
9411
+ const path7 = input.path;
9412
+ if (path7)
9413
+ return `${pattern} in ${basename5(path7)}`;
9414
9414
  return pattern;
9415
9415
  };
9416
9416
  var formatTask = (input) => {
@@ -9718,24 +9718,24 @@ var require_subagentTraceParser = __commonJS({
9718
9718
  }();
9719
9719
  Object.defineProperty(exports, "__esModule", { value: true });
9720
9720
  exports.scanSubagentTraces = scanSubagentTraces;
9721
- var fs10 = __importStar(__require("fs"));
9722
- var path8 = __importStar(__require("path"));
9721
+ var fs9 = __importStar(__require("fs"));
9722
+ var path7 = __importStar(__require("path"));
9723
9723
  var toolSummary_1 = require_toolSummary();
9724
9724
  var noiseClassifier_1 = require_noiseClassifier();
9725
9725
  var AGENT_FILE_PATTERN = /^agent-(.+)\.jsonl$/;
9726
9726
  function scanSubagentTraces(sessionDir, sessionId) {
9727
- const subagentsDir = path8.join(sessionDir, sessionId, "subagents");
9727
+ const subagentsDir = path7.join(sessionDir, sessionId, "subagents");
9728
9728
  try {
9729
- if (!fs10.existsSync(subagentsDir))
9729
+ if (!fs9.existsSync(subagentsDir))
9730
9730
  return [];
9731
- const files = fs10.readdirSync(subagentsDir);
9731
+ const files = fs9.readdirSync(subagentsDir);
9732
9732
  const traces = [];
9733
9733
  for (const file of files) {
9734
9734
  const match = file.match(AGENT_FILE_PATTERN);
9735
9735
  if (!match)
9736
9736
  continue;
9737
9737
  const agentId = match[1];
9738
- const filePath = path8.join(subagentsDir, file);
9738
+ const filePath = path7.join(subagentsDir, file);
9739
9739
  const trace = parseAgentTrace(filePath, agentId);
9740
9740
  if (trace)
9741
9741
  traces.push(trace);
@@ -9748,7 +9748,7 @@ var require_subagentTraceParser = __commonJS({
9748
9748
  }
9749
9749
  function parseAgentTrace(filePath, agentId) {
9750
9750
  try {
9751
- const content = fs10.readFileSync(filePath, "utf-8");
9751
+ const content = fs9.readFileSync(filePath, "utf-8");
9752
9752
  const lines = content.split("\n").filter((l) => l.trim());
9753
9753
  const events = [];
9754
9754
  const toolCalls = [];
@@ -10018,9 +10018,9 @@ var require_debugLogParser = __commonJS({
10018
10018
  exports.filterByLevel = filterByLevel;
10019
10019
  exports.collapseDuplicates = collapseDuplicates;
10020
10020
  exports.discoverDebugLogs = discoverDebugLogs;
10021
- var fs10 = __importStar(__require("fs"));
10022
- var path8 = __importStar(__require("path"));
10023
- var os6 = __importStar(__require("os"));
10021
+ var fs9 = __importStar(__require("fs"));
10022
+ var path7 = __importStar(__require("path"));
10023
+ var os5 = __importStar(__require("os"));
10024
10024
  var LOG_LINE_PATTERN = /^(\d{4}-\d{2}-\d{2}[T ]\d{2}:\d{2}:\d{2}[.\d]*Z?)\s+(DEBUG|INFO|WARN|ERROR)\s+(.*)$/;
10025
10025
  var LEVEL_ORDER = {
10026
10026
  DEBUG: 0,
@@ -10074,14 +10074,14 @@ var require_debugLogParser = __commonJS({
10074
10074
  return result;
10075
10075
  }
10076
10076
  function discoverDebugLogs() {
10077
- const debugDir = path8.join(os6.homedir(), ".claude", "debug");
10077
+ const debugDir = path7.join(os5.homedir(), ".claude", "debug");
10078
10078
  try {
10079
- if (!fs10.existsSync(debugDir))
10079
+ if (!fs9.existsSync(debugDir))
10080
10080
  return [];
10081
- return fs10.readdirSync(debugDir).filter((f) => f.endsWith(".log") || f.endsWith(".txt")).map((name) => {
10082
- const fullPath = path8.join(debugDir, name);
10081
+ return fs9.readdirSync(debugDir).filter((f) => f.endsWith(".log") || f.endsWith(".txt")).map((name) => {
10082
+ const fullPath = path7.join(debugDir, name);
10083
10083
  try {
10084
- const stat = fs10.statSync(fullPath);
10084
+ const stat = fs9.statSync(fullPath);
10085
10085
  return {
10086
10086
  path: fullPath,
10087
10087
  name,
@@ -10142,14 +10142,14 @@ var require_sessionSearch = __commonJS({
10142
10142
  }();
10143
10143
  Object.defineProperty(exports, "__esModule", { value: true });
10144
10144
  exports.searchSessions = searchSessions2;
10145
- var fs10 = __importStar(__require("fs"));
10146
- var path8 = __importStar(__require("path"));
10145
+ var fs9 = __importStar(__require("fs"));
10146
+ var path7 = __importStar(__require("path"));
10147
10147
  async function searchSessions2(provider, query, opts) {
10148
10148
  const maxResults = opts?.maxResults ?? 50;
10149
10149
  const results = [];
10150
10150
  const baseDir = provider.getProjectsBaseDir();
10151
10151
  try {
10152
- if (!fs10.existsSync(baseDir))
10152
+ if (!fs9.existsSync(baseDir))
10153
10153
  return results;
10154
10154
  const folders = provider.getAllProjectFolders();
10155
10155
  for (const folder of folders) {
@@ -10160,9 +10160,9 @@ var require_sessionSearch = __commonJS({
10160
10160
  let sessionFiles = [];
10161
10161
  try {
10162
10162
  const dir = folder.dir;
10163
- if (fs10.existsSync(dir)) {
10164
- const entries = fs10.readdirSync(dir).filter((f) => f.endsWith(".jsonl") || f.endsWith(".json"));
10165
- sessionFiles = entries.map((f) => path8.join(dir, f));
10163
+ if (fs9.existsSync(dir)) {
10164
+ const entries = fs9.readdirSync(dir).filter((f) => f.endsWith(".jsonl") || f.endsWith(".json"));
10165
+ sessionFiles = entries.map((f) => path7.join(dir, f));
10166
10166
  }
10167
10167
  } catch {
10168
10168
  }
@@ -10407,7 +10407,7 @@ var require_composer = __commonJS({
10407
10407
  (0, handoff_1.readLatestHandoff)(slug)
10408
10408
  ]);
10409
10409
  const sessionFiles = workspacePath ? provider.findAllSessions(workspacePath) : [];
10410
- let sessionSummaries = [];
10410
+ const sessionSummaries = [];
10411
10411
  const FIDELITY_SESSION_LIMIT = { full: 5, compact: 2, brief: 1 };
10412
10412
  const sessionLimit = FIDELITY_SESSION_LIMIT[fidelity];
10413
10413
  const sessionPaths = sessionFiles.slice(0, sessionLimit);
@@ -10563,7 +10563,7 @@ var require_jsonlWatcher = __commonJS({
10563
10563
  }();
10564
10564
  Object.defineProperty(exports, "__esModule", { value: true });
10565
10565
  exports.JsonlSessionWatcher = void 0;
10566
- var fs10 = __importStar(__require("fs"));
10566
+ var fs9 = __importStar(__require("fs"));
10567
10567
  var jsonl_1 = require_jsonl();
10568
10568
  var codexParser_1 = require_codexParser();
10569
10569
  var toolSummary_1 = require_toolSummary();
@@ -10760,14 +10760,14 @@ var require_jsonlWatcher = __commonJS({
10760
10760
  this.readNewBytes();
10761
10761
  } else {
10762
10762
  try {
10763
- const stat = fs10.statSync(this.sessionPath);
10763
+ const stat = fs9.statSync(this.sessionPath);
10764
10764
  this.filePosition = stat.size;
10765
10765
  } catch {
10766
10766
  this.filePosition = 0;
10767
10767
  }
10768
10768
  }
10769
10769
  try {
10770
- this.fsWatcher = fs10.watch(this.sessionPath, { persistent: false }, () => {
10770
+ this.fsWatcher = fs9.watch(this.sessionPath, { persistent: false }, () => {
10771
10771
  this.debouncedRead();
10772
10772
  });
10773
10773
  this.fsWatcher.on("error", () => {
@@ -10811,18 +10811,18 @@ var require_jsonlWatcher = __commonJS({
10811
10811
  return;
10812
10812
  let fd = null;
10813
10813
  try {
10814
- const stat = fs10.statSync(this.sessionPath);
10814
+ const stat = fs9.statSync(this.sessionPath);
10815
10815
  if (stat.size < this.filePosition) {
10816
10816
  this.filePosition = 0;
10817
10817
  this.parser.reset();
10818
10818
  }
10819
10819
  if (stat.size <= this.filePosition)
10820
10820
  return;
10821
- fd = fs10.openSync(this.sessionPath, "r");
10821
+ fd = fs9.openSync(this.sessionPath, "r");
10822
10822
  const bytesToRead = stat.size - this.filePosition;
10823
10823
  const buffer = Buffer.alloc(bytesToRead);
10824
- const bytesRead = fs10.readSync(fd, buffer, 0, bytesToRead, this.filePosition);
10825
- fs10.closeSync(fd);
10824
+ const bytesRead = fs9.readSync(fd, buffer, 0, bytesToRead, this.filePosition);
10825
+ fs9.closeSync(fd);
10826
10826
  fd = null;
10827
10827
  if (bytesRead > 0) {
10828
10828
  this.filePosition += bytesRead;
@@ -10832,7 +10832,7 @@ var require_jsonlWatcher = __commonJS({
10832
10832
  } catch (err) {
10833
10833
  if (fd !== null) {
10834
10834
  try {
10835
- fs10.closeSync(fd);
10835
+ fs9.closeSync(fd);
10836
10836
  } catch {
10837
10837
  }
10838
10838
  }
@@ -11033,8 +11033,8 @@ var require_sqliteWatcher = __commonJS({
11033
11033
  }();
11034
11034
  Object.defineProperty(exports, "__esModule", { value: true });
11035
11035
  exports.SqliteSessionWatcher = void 0;
11036
- var fs10 = __importStar(__require("fs"));
11037
- var path8 = __importStar(__require("path"));
11036
+ var fs9 = __importStar(__require("fs"));
11037
+ var path7 = __importStar(__require("path"));
11038
11038
  var openCodeDatabase_1 = require_openCodeDatabase();
11039
11039
  var openCodeParser_1 = require_openCodeParser();
11040
11040
  var DEBOUNCE_MS = 200;
@@ -11159,7 +11159,7 @@ var require_sqliteWatcher = __commonJS({
11159
11159
  this.dbPath = dbPath;
11160
11160
  this.sessionId = sessionId;
11161
11161
  this.callbacks = callbacks;
11162
- this.db = new openCodeDatabase_1.OpenCodeDatabase(path8.dirname(dbPath));
11162
+ this.db = new openCodeDatabase_1.OpenCodeDatabase(path7.dirname(dbPath));
11163
11163
  }
11164
11164
  get isActive() {
11165
11165
  return this._isActive;
@@ -11222,9 +11222,9 @@ var require_sqliteWatcher = __commonJS({
11222
11222
  }
11223
11223
  watchFile(filePath, setter) {
11224
11224
  try {
11225
- if (!fs10.existsSync(filePath))
11225
+ if (!fs9.existsSync(filePath))
11226
11226
  return;
11227
- const watcher = fs10.watch(filePath, { persistent: false }, () => {
11227
+ const watcher = fs9.watch(filePath, { persistent: false }, () => {
11228
11228
  this.debouncedPoll();
11229
11229
  });
11230
11230
  watcher.on("error", () => {
@@ -11324,15 +11324,15 @@ var require_factory = __commonJS({
11324
11324
  }();
11325
11325
  Object.defineProperty(exports, "__esModule", { value: true });
11326
11326
  exports.createWatcher = createWatcher4;
11327
- var os6 = __importStar(__require("os"));
11328
- var path8 = __importStar(__require("path"));
11327
+ var os5 = __importStar(__require("os"));
11328
+ var path7 = __importStar(__require("path"));
11329
11329
  var jsonlWatcher_1 = require_jsonlWatcher();
11330
11330
  var sqliteWatcher_1 = require_sqliteWatcher();
11331
11331
  function getOpenCodeDataDir() {
11332
11332
  const xdg = process.env.XDG_DATA_HOME;
11333
11333
  if (xdg)
11334
- return path8.join(xdg, "opencode");
11335
- return path8.join(os6.homedir(), ".local", "share", "opencode");
11334
+ return path7.join(xdg, "opencode");
11335
+ return path7.join(os5.homedir(), ".local", "share", "opencode");
11336
11336
  }
11337
11337
  function createWatcher4(options) {
11338
11338
  const { provider, workspacePath, sessionId, callbacks } = options;
@@ -11344,7 +11344,7 @@ var require_factory = __commonJS({
11344
11344
  if (sessionId) {
11345
11345
  const match = sessions.find((s) => s.includes(sessionId));
11346
11346
  if (!match) {
11347
- throw new Error(`Session ${sessionId} not found. Available: ${sessions.slice(0, 5).map((s) => path8.basename(s)).join(", ")}`);
11347
+ throw new Error(`Session ${sessionId} not found. Available: ${sessions.slice(0, 5).map((s) => path7.basename(s)).join(", ")}`);
11348
11348
  }
11349
11349
  sessionPath = match;
11350
11350
  } else {
@@ -11360,8 +11360,8 @@ var require_factory = __commonJS({
11360
11360
  return new jsonlWatcher_1.JsonlSessionWatcher(providerId, sessionPath, callbacks);
11361
11361
  case "opencode": {
11362
11362
  const dataDir = getOpenCodeDataDir();
11363
- const dbPath = path8.join(dataDir, "opencode.db");
11364
- const sid = path8.basename(sessionPath, ".json");
11363
+ const dbPath = path7.join(dataDir, "opencode.db");
11364
+ const sid = path7.basename(sessionPath, ".json");
11365
11365
  return new sqliteWatcher_1.SqliteSessionWatcher(dbPath, sid, callbacks);
11366
11366
  }
11367
11367
  default:
@@ -12051,7 +12051,7 @@ var require_eventHighlighter = __commonJS({
12051
12051
  }
12052
12052
  function classifyWord(word) {
12053
12053
  const lower = word.toLowerCase();
12054
- const stripped = lower.replace(/[.,;:!?()\[\]{}'"]+$/g, "").replace(/^['"([\]{}]+/, "");
12054
+ const stripped = lower.replace(/[.,;:!?()[\]{}'"]+$/g, "").replace(/^['"([\]{}]+/, "");
12055
12055
  if (ERROR_KEYWORDS.has(stripped))
12056
12056
  return "red";
12057
12057
  if (WARNING_KEYWORDS.has(stripped))
@@ -13762,6 +13762,7 @@ var require_EventAggregator = __commonJS({
13762
13762
  "use strict";
13763
13763
  Object.defineProperty(exports, "__esModule", { value: true });
13764
13764
  exports.EventAggregator = void 0;
13765
+ exports.parseTodoDependencies = parseTodoDependencies;
13765
13766
  var jsonl_1 = require_jsonl();
13766
13767
  var planExtractor_1 = require_planExtractor();
13767
13768
  var eventBridge_1 = require_eventBridge();
@@ -13776,6 +13777,26 @@ var require_EventAggregator = __commonJS({
13776
13777
  var DEFAULT_BURN_SAMPLE_MS = 1e4;
13777
13778
  var COMPACTION_DROP_THRESHOLD = 0.8;
13778
13779
  var SNAPSHOT_SCHEMA_VERSION = 1;
13780
+ var GOAL_GATE_REGEX = /\b(CRITICAL|MUST|blocker|required|must.?complete|goal.?gate|essential|do.?not.?skip|blocking)\b/i;
13781
+ function parseTodoDependencies(content, allTodos) {
13782
+ const depPattern = /(?:blocked by|depends on|waiting on|requires)\s+(.+?)(?:\)|$)/i;
13783
+ const match = content.match(depPattern);
13784
+ if (!match)
13785
+ return [];
13786
+ const refs = match[1].split(/\s+and\s+|,\s*|&\s*/).map((r) => r.trim()).filter(Boolean);
13787
+ const result = [];
13788
+ for (const ref of refs) {
13789
+ const refLower = ref.toLowerCase();
13790
+ for (let j = 0; j < allTodos.length; j++) {
13791
+ const otherContent = String(allTodos[j].content || allTodos[j].subject || "").toLowerCase();
13792
+ if (otherContent.includes(refLower) || refLower.includes(otherContent.split(":")[0].trim())) {
13793
+ result.push(`todo-${j}`);
13794
+ break;
13795
+ }
13796
+ }
13797
+ }
13798
+ return result;
13799
+ }
13779
13800
  var EventAggregator5 = class {
13780
13801
  // Options
13781
13802
  timelineCap;
@@ -14550,16 +14571,25 @@ var require_EventAggregator = __commonJS({
14550
14571
  description: input.description,
14551
14572
  activeForm: input.activeForm,
14552
14573
  subagentType: input.subagentType,
14553
- isGoalGate: input.isGoalGate
14574
+ isGoalGate: input.isGoalGate,
14575
+ timestamp: new Date(event.timestamp)
14554
14576
  });
14555
14577
  } else if (name === "TaskUpdate") {
14556
14578
  this.applyTaskUpdate(input);
14579
+ } else if (name === "TodoWrite") {
14580
+ this.handleTodoWrite(input, new Date(event.timestamp));
14581
+ } else if (name === "UpdatePlan") {
14582
+ this.handleUpdatePlan(input, new Date(event.timestamp));
14583
+ } else if ((name === "Agent" || name === "Task") && toolUseId) {
14584
+ this.handleAgentSpawn(toolUseId, input, new Date(event.timestamp));
14557
14585
  }
14558
14586
  } else if (block.type === "tool_result") {
14559
14587
  const toolUseId = block.tool_use_id;
14560
14588
  if (!toolUseId)
14561
14589
  continue;
14562
- this.resolveTaskCreate(toolUseId, block.content ?? block.output, event.timestamp);
14590
+ const isError = block.is_error ?? false;
14591
+ this.resolveTaskCreate(toolUseId, block.content ?? block.output, event.timestamp, isError);
14592
+ this.resolveAgentResult(toolUseId, isError, event.timestamp);
14563
14593
  }
14564
14594
  }
14565
14595
  }
@@ -14579,10 +14609,17 @@ var require_EventAggregator = __commonJS({
14579
14609
  description: input.description,
14580
14610
  activeForm: input.activeForm,
14581
14611
  subagentType: input.subagentType,
14582
- isGoalGate: input.isGoalGate
14612
+ isGoalGate: input.isGoalGate,
14613
+ timestamp: new Date(event.timestamp)
14583
14614
  });
14584
14615
  } else if (event.toolName === "TaskUpdate") {
14585
14616
  this.applyTaskUpdate(input);
14617
+ } else if (event.toolName === "TodoWrite") {
14618
+ this.handleTodoWrite(input, new Date(event.timestamp));
14619
+ } else if (event.toolName === "UpdatePlan") {
14620
+ this.handleUpdatePlan(input, new Date(event.timestamp));
14621
+ } else if ((event.toolName === "Agent" || event.toolName === "Task") && toolUseId) {
14622
+ this.handleAgentSpawn(toolUseId, input, new Date(event.timestamp));
14586
14623
  }
14587
14624
  } else if (event.type === "tool_result") {
14588
14625
  if (!raw)
@@ -14590,7 +14627,9 @@ var require_EventAggregator = __commonJS({
14590
14627
  const toolUseId = raw.tool_use_id;
14591
14628
  if (!toolUseId)
14592
14629
  return;
14593
- this.resolveTaskCreate(toolUseId, raw.content, event.timestamp);
14630
+ const isError = raw.is_error ?? false;
14631
+ this.resolveTaskCreate(toolUseId, raw.content, event.timestamp, isError);
14632
+ this.resolveAgentResult(toolUseId, isError, event.timestamp);
14594
14633
  }
14595
14634
  }
14596
14635
  applyTaskUpdate(input) {
@@ -14607,10 +14646,14 @@ var require_EventAggregator = __commonJS({
14607
14646
  this.activeTaskId = null;
14608
14647
  return;
14609
14648
  }
14649
+ const oldStatus = existing.status;
14610
14650
  existing.status = newStatus;
14611
14651
  existing.updatedAt = /* @__PURE__ */ new Date();
14612
- if (newStatus === "in_progress") {
14652
+ if (newStatus === "in_progress" && oldStatus !== "in_progress") {
14613
14653
  this.activeTaskId = taskId;
14654
+ } else if (oldStatus === "in_progress" && newStatus !== "in_progress") {
14655
+ if (this.activeTaskId === taskId)
14656
+ this.activeTaskId = null;
14614
14657
  }
14615
14658
  }
14616
14659
  if (input.subject)
@@ -14620,19 +14663,31 @@ var require_EventAggregator = __commonJS({
14620
14663
  if (input.activeForm)
14621
14664
  existing.activeForm = input.activeForm;
14622
14665
  if (input.addBlockedBy && Array.isArray(input.addBlockedBy)) {
14623
- existing.blockedBy.push(...input.addBlockedBy);
14666
+ for (const id of input.addBlockedBy) {
14667
+ const idStr = String(id);
14668
+ if (!existing.blockedBy.includes(idStr)) {
14669
+ existing.blockedBy.push(idStr);
14670
+ }
14671
+ }
14624
14672
  }
14625
14673
  if (input.addBlocks && Array.isArray(input.addBlocks)) {
14626
- existing.blocks.push(...input.addBlocks);
14674
+ for (const id of input.addBlocks) {
14675
+ const idStr = String(id);
14676
+ if (!existing.blocks.includes(idStr)) {
14677
+ existing.blocks.push(idStr);
14678
+ }
14679
+ }
14627
14680
  }
14681
+ existing.isGoalGate = this.isGoalGateTask(existing);
14628
14682
  } else {
14629
14683
  const status = input.status || "pending";
14630
14684
  if (status === "deleted")
14631
14685
  return;
14632
14686
  const now = /* @__PURE__ */ new Date();
14633
- this.tasks.set(taskId, {
14687
+ const task = {
14634
14688
  taskId,
14635
14689
  subject: input.subject || `Task ${taskId}`,
14690
+ description: input.description,
14636
14691
  status,
14637
14692
  createdAt: now,
14638
14693
  updatedAt: now,
@@ -14640,27 +14695,31 @@ var require_EventAggregator = __commonJS({
14640
14695
  blocks: [],
14641
14696
  associatedToolCalls: [],
14642
14697
  activeForm: input.activeForm
14643
- });
14698
+ };
14699
+ task.isGoalGate = this.isGoalGateTask(task);
14700
+ this.tasks.set(taskId, task);
14644
14701
  if (status === "in_progress") {
14645
14702
  this.activeTaskId = taskId;
14646
14703
  }
14647
14704
  }
14648
14705
  }
14649
- resolveTaskCreate(toolUseId, content, timestamp) {
14706
+ resolveTaskCreate(toolUseId, content, timestamp, isError) {
14650
14707
  const pending = this.pendingTaskCreates.get(toolUseId);
14651
14708
  if (!pending)
14652
14709
  return;
14653
14710
  this.pendingTaskCreates.delete(toolUseId);
14711
+ if (isError)
14712
+ return;
14654
14713
  const taskId = this.extractTaskIdFromResult(content);
14655
14714
  if (!taskId)
14656
14715
  return;
14657
14716
  const now = new Date(timestamp);
14658
- this.tasks.set(taskId, {
14717
+ const task = {
14659
14718
  taskId,
14660
14719
  subject: pending.subject,
14661
14720
  description: pending.description,
14662
14721
  status: "pending",
14663
- createdAt: now,
14722
+ createdAt: pending.timestamp ?? now,
14664
14723
  updatedAt: now,
14665
14724
  blockedBy: [],
14666
14725
  blocks: [],
@@ -14668,7 +14727,185 @@ var require_EventAggregator = __commonJS({
14668
14727
  activeForm: pending.activeForm,
14669
14728
  subagentType: pending.subagentType,
14670
14729
  isGoalGate: pending.isGoalGate
14671
- });
14730
+ };
14731
+ task.isGoalGate = task.isGoalGate || this.isGoalGateTask(task);
14732
+ this.tasks.set(taskId, task);
14733
+ }
14734
+ // ═══════════════════════════════════════════════════════════════════════
14735
+ // Private: TodoWrite handling (OpenCode)
14736
+ // ═══════════════════════════════════════════════════════════════════════
14737
+ handleTodoWrite(input, now) {
14738
+ const todos = input.todos;
14739
+ if (!Array.isArray(todos))
14740
+ return;
14741
+ for (const [taskId, task] of this.tasks) {
14742
+ if (!task.isSubagent) {
14743
+ this.tasks.delete(taskId);
14744
+ }
14745
+ }
14746
+ if (this.activeTaskId && !this.tasks.has(this.activeTaskId)) {
14747
+ this.activeTaskId = null;
14748
+ }
14749
+ for (let i = 0; i < todos.length; i++) {
14750
+ const todo = todos[i];
14751
+ const taskId = `todo-${i}`;
14752
+ const content = String(todo.content || todo.subject || `Todo ${i + 1}`);
14753
+ const rawStatus = String(todo.status || "pending").toLowerCase();
14754
+ const priority = todo.priority ? String(todo.priority) : void 0;
14755
+ let status;
14756
+ if (rawStatus === "completed" || rawStatus === "done") {
14757
+ status = "completed";
14758
+ } else if (rawStatus === "in_progress" || rawStatus === "in-progress") {
14759
+ status = "in_progress";
14760
+ } else {
14761
+ status = "pending";
14762
+ }
14763
+ const task = {
14764
+ taskId,
14765
+ subject: content,
14766
+ description: priority ? `Priority: ${priority}` : void 0,
14767
+ status,
14768
+ createdAt: now,
14769
+ updatedAt: now,
14770
+ blockedBy: [],
14771
+ blocks: [],
14772
+ associatedToolCalls: []
14773
+ };
14774
+ this.tasks.set(taskId, task);
14775
+ if (status === "in_progress") {
14776
+ this.activeTaskId = taskId;
14777
+ }
14778
+ }
14779
+ for (let i = 0; i < todos.length; i++) {
14780
+ const task = this.tasks.get(`todo-${i}`);
14781
+ if (!task)
14782
+ continue;
14783
+ if (Array.isArray(todos[i].blockedBy)) {
14784
+ for (const ref of todos[i].blockedBy) {
14785
+ const refStr = String(ref);
14786
+ if (!task.blockedBy.includes(refStr)) {
14787
+ task.blockedBy.push(refStr);
14788
+ }
14789
+ }
14790
+ }
14791
+ const deps = parseTodoDependencies(String(todos[i].content || ""), todos);
14792
+ for (const depId of deps) {
14793
+ if (depId !== `todo-${i}` && !task.blockedBy.includes(depId)) {
14794
+ task.blockedBy.push(depId);
14795
+ const depTask = this.tasks.get(depId);
14796
+ if (depTask && !depTask.blocks.includes(`todo-${i}`)) {
14797
+ depTask.blocks.push(`todo-${i}`);
14798
+ }
14799
+ }
14800
+ }
14801
+ }
14802
+ }
14803
+ // ═══════════════════════════════════════════════════════════════════════
14804
+ // Private: UpdatePlan handling (Codex)
14805
+ // ═══════════════════════════════════════════════════════════════════════
14806
+ handleUpdatePlan(input, now) {
14807
+ const plan = input.plan;
14808
+ if (!Array.isArray(plan))
14809
+ return;
14810
+ const seenPlanTaskIds = /* @__PURE__ */ new Set();
14811
+ let activePlanTaskId = null;
14812
+ for (let i = 0; i < plan.length; i++) {
14813
+ const entry = plan[i];
14814
+ const step = String(entry.step || "").trim();
14815
+ if (!step)
14816
+ continue;
14817
+ const rawStatus = String(entry.status || "pending").toLowerCase();
14818
+ let status;
14819
+ if (rawStatus === "completed")
14820
+ status = "completed";
14821
+ else if (rawStatus === "in_progress" || rawStatus === "in-progress")
14822
+ status = "in_progress";
14823
+ else
14824
+ status = "pending";
14825
+ const taskId = `plan-${i}`;
14826
+ seenPlanTaskIds.add(taskId);
14827
+ const existing = this.tasks.get(taskId);
14828
+ if (existing) {
14829
+ existing.subject = step;
14830
+ existing.status = status;
14831
+ existing.updatedAt = now;
14832
+ if (!existing.activeForm) {
14833
+ existing.activeForm = `Working on ${step}`;
14834
+ }
14835
+ } else {
14836
+ const task = {
14837
+ taskId,
14838
+ subject: step,
14839
+ status,
14840
+ createdAt: now,
14841
+ updatedAt: now,
14842
+ activeForm: `Working on ${step}`,
14843
+ blockedBy: [],
14844
+ blocks: [],
14845
+ associatedToolCalls: []
14846
+ };
14847
+ this.tasks.set(taskId, task);
14848
+ }
14849
+ if (status === "in_progress") {
14850
+ activePlanTaskId = taskId;
14851
+ }
14852
+ }
14853
+ for (const [taskId, task] of this.tasks) {
14854
+ if (!taskId.startsWith("plan-"))
14855
+ continue;
14856
+ if (!seenPlanTaskIds.has(taskId) && task.status !== "deleted") {
14857
+ task.status = "deleted";
14858
+ task.updatedAt = now;
14859
+ }
14860
+ }
14861
+ if (activePlanTaskId) {
14862
+ this.activeTaskId = activePlanTaskId;
14863
+ } else if (this.activeTaskId?.startsWith("plan-")) {
14864
+ this.activeTaskId = null;
14865
+ }
14866
+ }
14867
+ // ═══════════════════════════════════════════════════════════════════════
14868
+ // Private: Agent/Task (subagent) as tracked task
14869
+ // ═══════════════════════════════════════════════════════════════════════
14870
+ handleAgentSpawn(toolUseId, input, now) {
14871
+ const agentTaskId = `agent-${toolUseId}`;
14872
+ const description = input.description ? String(input.description) : "Subagent";
14873
+ const subagentType = input.subagent_type || input.subagentType || void 0;
14874
+ const task = {
14875
+ taskId: agentTaskId,
14876
+ subject: description,
14877
+ status: "in_progress",
14878
+ createdAt: now,
14879
+ updatedAt: now,
14880
+ activeForm: subagentType ? `Running ${subagentType} agent` : "Running subagent",
14881
+ blockedBy: [],
14882
+ blocks: [],
14883
+ associatedToolCalls: [],
14884
+ isSubagent: true,
14885
+ subagentType,
14886
+ toolUseId
14887
+ };
14888
+ this.tasks.set(agentTaskId, task);
14889
+ }
14890
+ resolveAgentResult(toolUseId, isError, timestamp) {
14891
+ const agentTaskId = `agent-${toolUseId}`;
14892
+ const agentTask = this.tasks.get(agentTaskId);
14893
+ if (!agentTask)
14894
+ return;
14895
+ agentTask.status = isError ? "deleted" : "completed";
14896
+ agentTask.updatedAt = new Date(timestamp);
14897
+ }
14898
+ // ═══════════════════════════════════════════════════════════════════════
14899
+ // Private: Goal gate detection
14900
+ // ═══════════════════════════════════════════════════════════════════════
14901
+ isGoalGateTask(task) {
14902
+ if (GOAL_GATE_REGEX.test(task.subject))
14903
+ return true;
14904
+ if (task.description && GOAL_GATE_REGEX.test(task.description))
14905
+ return true;
14906
+ if (task.blocks.length >= 3)
14907
+ return true;
14908
+ return false;
14672
14909
  }
14673
14910
  // ═══════════════════════════════════════════════════════════════════════
14674
14911
  // Private: Subagent Tracking from SessionEvent
@@ -15144,37 +15381,37 @@ var require_snapshot = __commonJS({
15144
15381
  exports.loadSnapshot = loadSnapshot2;
15145
15382
  exports.deleteSnapshot = deleteSnapshot2;
15146
15383
  exports.isSnapshotValid = isSnapshotValid2;
15147
- var fs10 = __importStar(__require("fs"));
15148
- var path8 = __importStar(__require("path"));
15384
+ var fs9 = __importStar(__require("fs"));
15385
+ var path7 = __importStar(__require("path"));
15149
15386
  var paths_1 = require_paths();
15150
15387
  var SNAPSHOT_VERSION = 1;
15151
15388
  function getSnapshotsDir() {
15152
- return path8.join((0, paths_1.getConfigDir)(), "snapshots");
15389
+ return path7.join((0, paths_1.getConfigDir)(), "snapshots");
15153
15390
  }
15154
15391
  function getSnapshotPath(sessionId) {
15155
15392
  const safe = sessionId.replace(/[/\\:]/g, "_");
15156
- return path8.join(getSnapshotsDir(), `${safe}.json`);
15393
+ return path7.join(getSnapshotsDir(), `${safe}.json`);
15157
15394
  }
15158
15395
  function saveSnapshot2(snapshot) {
15159
15396
  try {
15160
15397
  const dir = getSnapshotsDir();
15161
- if (!fs10.existsSync(dir)) {
15162
- fs10.mkdirSync(dir, { recursive: true });
15398
+ if (!fs9.existsSync(dir)) {
15399
+ fs9.mkdirSync(dir, { recursive: true });
15163
15400
  }
15164
15401
  const filePath = getSnapshotPath(snapshot.sessionId);
15165
15402
  const tmpPath = filePath + ".tmp";
15166
- fs10.writeFileSync(tmpPath, JSON.stringify(snapshot), "utf-8");
15167
- fs10.renameSync(tmpPath, filePath);
15403
+ fs9.writeFileSync(tmpPath, JSON.stringify(snapshot), "utf-8");
15404
+ fs9.renameSync(tmpPath, filePath);
15168
15405
  } catch {
15169
15406
  }
15170
15407
  }
15171
15408
  function loadSnapshot2(sessionId) {
15172
15409
  try {
15173
15410
  const filePath = getSnapshotPath(sessionId);
15174
- if (!fs10.existsSync(filePath)) {
15411
+ if (!fs9.existsSync(filePath)) {
15175
15412
  return null;
15176
15413
  }
15177
- const raw = fs10.readFileSync(filePath, "utf-8");
15414
+ const raw = fs9.readFileSync(filePath, "utf-8");
15178
15415
  const snapshot = JSON.parse(raw);
15179
15416
  if (snapshot.version !== SNAPSHOT_VERSION) {
15180
15417
  deleteSnapshot2(sessionId);
@@ -15189,8 +15426,8 @@ var require_snapshot = __commonJS({
15189
15426
  function deleteSnapshot2(sessionId) {
15190
15427
  try {
15191
15428
  const filePath = getSnapshotPath(sessionId);
15192
- if (fs10.existsSync(filePath)) {
15193
- fs10.unlinkSync(filePath);
15429
+ if (fs9.existsSync(filePath)) {
15430
+ fs9.unlinkSync(filePath);
15194
15431
  }
15195
15432
  } catch {
15196
15433
  }
@@ -15250,12 +15487,12 @@ var require_transcriptParser = __commonJS({
15250
15487
  }();
15251
15488
  Object.defineProperty(exports, "__esModule", { value: true });
15252
15489
  exports.parseTranscript = parseTranscript3;
15253
- var fs10 = __importStar(__require("fs"));
15490
+ var fs9 = __importStar(__require("fs"));
15254
15491
  var jsonl_1 = require_jsonl();
15255
15492
  function parseTranscript3(sessionPath) {
15256
15493
  let data;
15257
15494
  try {
15258
- data = fs10.readFileSync(sessionPath, "utf-8");
15495
+ data = fs9.readFileSync(sessionPath, "utf-8");
15259
15496
  } catch {
15260
15497
  return [];
15261
15498
  }
@@ -16327,14 +16564,166 @@ var require_report = __commonJS({
16327
16564
  }
16328
16565
  });
16329
16566
 
16567
+ // ../sidekick-shared/dist/credentials.js
16568
+ var require_credentials = __commonJS({
16569
+ "../sidekick-shared/dist/credentials.js"(exports) {
16570
+ "use strict";
16571
+ var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
16572
+ if (k2 === void 0) k2 = k;
16573
+ var desc = Object.getOwnPropertyDescriptor(m, k);
16574
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16575
+ desc = { enumerable: true, get: function() {
16576
+ return m[k];
16577
+ } };
16578
+ }
16579
+ Object.defineProperty(o, k2, desc);
16580
+ } : function(o, m, k, k2) {
16581
+ if (k2 === void 0) k2 = k;
16582
+ o[k2] = m[k];
16583
+ });
16584
+ var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
16585
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
16586
+ } : function(o, v) {
16587
+ o["default"] = v;
16588
+ });
16589
+ var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
16590
+ var ownKeys = function(o) {
16591
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
16592
+ var ar = [];
16593
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
16594
+ return ar;
16595
+ };
16596
+ return ownKeys(o);
16597
+ };
16598
+ return function(mod) {
16599
+ if (mod && mod.__esModule) return mod;
16600
+ var result = {};
16601
+ if (mod != null) {
16602
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
16603
+ }
16604
+ __setModuleDefault(result, mod);
16605
+ return result;
16606
+ };
16607
+ }();
16608
+ Object.defineProperty(exports, "__esModule", { value: true });
16609
+ exports.readClaudeMaxCredentials = readClaudeMaxCredentials2;
16610
+ exports.readClaudeMaxAccessTokenSync = readClaudeMaxAccessTokenSync;
16611
+ var fs9 = __importStar(__require("fs"));
16612
+ var path7 = __importStar(__require("path"));
16613
+ var os5 = __importStar(__require("os"));
16614
+ async function readClaudeMaxCredentials2() {
16615
+ const credPath = path7.join(os5.homedir(), ".claude", ".credentials.json");
16616
+ try {
16617
+ if (!fs9.existsSync(credPath))
16618
+ return null;
16619
+ const content = await fs9.promises.readFile(credPath, "utf8");
16620
+ const parsed = JSON.parse(content);
16621
+ const oauth = parsed?.claudeAiOauth;
16622
+ if (!oauth?.accessToken)
16623
+ return null;
16624
+ if (oauth.expiresAt && Date.now() > oauth.expiresAt)
16625
+ return null;
16626
+ return {
16627
+ accessToken: oauth.accessToken,
16628
+ refreshToken: oauth.refreshToken,
16629
+ expiresAt: oauth.expiresAt,
16630
+ scopes: oauth.scopes,
16631
+ subscriptionType: oauth.subscriptionType
16632
+ };
16633
+ } catch {
16634
+ return null;
16635
+ }
16636
+ }
16637
+ function readClaudeMaxAccessTokenSync() {
16638
+ const credPath = path7.join(os5.homedir(), ".claude", ".credentials.json");
16639
+ try {
16640
+ if (!fs9.existsSync(credPath))
16641
+ return null;
16642
+ const content = fs9.readFileSync(credPath, "utf8");
16643
+ const parsed = JSON.parse(content);
16644
+ const oauth = parsed?.claudeAiOauth;
16645
+ if (!oauth?.accessToken)
16646
+ return null;
16647
+ if (oauth.expiresAt && Date.now() > oauth.expiresAt)
16648
+ return null;
16649
+ return oauth.accessToken;
16650
+ } catch {
16651
+ return null;
16652
+ }
16653
+ }
16654
+ }
16655
+ });
16656
+
16657
+ // ../sidekick-shared/dist/quota.js
16658
+ var require_quota = __commonJS({
16659
+ "../sidekick-shared/dist/quota.js"(exports) {
16660
+ "use strict";
16661
+ Object.defineProperty(exports, "__esModule", { value: true });
16662
+ exports.fetchQuota = fetchQuota2;
16663
+ var USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
16664
+ var BETA_HEADER = "oauth-2025-04-20";
16665
+ var FIVE_HOUR_MS = 5 * 36e5;
16666
+ var SEVEN_DAY_MS = 7 * 864e5;
16667
+ function projectFromElapsed(utilization, resetsAt, windowMs) {
16668
+ if (!resetsAt || utilization <= 0)
16669
+ return void 0;
16670
+ const resetTime = new Date(resetsAt).getTime();
16671
+ const now = Date.now();
16672
+ const elapsed = windowMs - (resetTime - now);
16673
+ if (elapsed <= 0)
16674
+ return void 0;
16675
+ return Math.min(Math.round(utilization * (windowMs / elapsed)), 200);
16676
+ }
16677
+ function unavailableState(error) {
16678
+ return {
16679
+ fiveHour: { utilization: 0, resetsAt: "" },
16680
+ sevenDay: { utilization: 0, resetsAt: "" },
16681
+ available: false,
16682
+ error
16683
+ };
16684
+ }
16685
+ async function fetchQuota2(accessToken) {
16686
+ try {
16687
+ const res = await fetch(USAGE_URL, {
16688
+ method: "GET",
16689
+ headers: {
16690
+ "Authorization": `Bearer ${accessToken}`,
16691
+ "anthropic-beta": BETA_HEADER,
16692
+ "Content-Type": "application/json"
16693
+ }
16694
+ });
16695
+ if (!res.ok) {
16696
+ if (res.status === 401)
16697
+ return unavailableState("Sign in to Claude Code to view quota");
16698
+ return unavailableState(`API error: ${res.status}`);
16699
+ }
16700
+ const data = await res.json();
16701
+ const fiveUtil = data.five_hour?.utilization ?? 0;
16702
+ const sevenUtil = data.seven_day?.utilization ?? 0;
16703
+ const fiveResetsAt = data.five_hour?.resets_at ?? "";
16704
+ const sevenResetsAt = data.seven_day?.resets_at ?? "";
16705
+ return {
16706
+ fiveHour: { utilization: fiveUtil, resetsAt: fiveResetsAt },
16707
+ sevenDay: { utilization: sevenUtil, resetsAt: sevenResetsAt },
16708
+ available: true,
16709
+ projectedFiveHour: projectFromElapsed(fiveUtil, fiveResetsAt, FIVE_HOUR_MS),
16710
+ projectedSevenDay: projectFromElapsed(sevenUtil, sevenResetsAt, SEVEN_DAY_MS)
16711
+ };
16712
+ } catch {
16713
+ return unavailableState("Network error");
16714
+ }
16715
+ }
16716
+ }
16717
+ });
16718
+
16330
16719
  // ../sidekick-shared/dist/index.js
16331
16720
  var require_dist = __commonJS({
16332
16721
  "../sidekick-shared/dist/index.js"(exports) {
16333
16722
  "use strict";
16334
16723
  Object.defineProperty(exports, "__esModule", { value: true });
16335
16724
  exports.findActiveClaudeSession = exports.discoverSessionDirectory = exports.getClaudeSessionDirectory = exports.encodeClaudeWorkspacePath = exports.detectSessionActivity = exports.extractTaskInfo = exports.scanSubagentDir = exports.normalizeCodexToolInput = exports.normalizeCodexToolName = exports.extractPatchFilePaths = exports.CodexRolloutParser = exports.parseDbPartData = exports.parseDbMessageData = exports.convertOpenCodeMessage = exports.detectPlanModeFromText = exports.normalizeToolInput = exports.normalizeToolName = exports.TRUNCATION_PATTERNS = exports.JsonlParser = exports.CodexProvider = exports.OpenCodeProvider = exports.ClaudeCodeProvider = exports.getAllDetectedProviders = exports.detectProvider = exports.readClaudeCodePlanFiles = exports.getPlanAnalytics = exports.writePlans = exports.getLatestPlan = exports.readPlans = exports.readLatestHandoff = exports.readHistory = exports.readNotes = exports.readDecisions = exports.readTasks = exports.getProjectSlugRaw = exports.getProjectSlug = exports.encodeWorkspacePath = exports.getGlobalDataPath = exports.getProjectDataPath = exports.getConfigDir = exports.MAX_PLANS_PER_PROJECT = exports.PLAN_SCHEMA_VERSION = exports.createEmptyTokenTotals = exports.HISTORICAL_DATA_SCHEMA_VERSION = exports.STALENESS_THRESHOLDS = exports.IMPORTANCE_DECAY_FACTORS = exports.KNOWLEDGE_NOTE_SCHEMA_VERSION = exports.DECISION_LOG_SCHEMA_VERSION = exports.normalizeTaskStatus = exports.TASK_PERSISTENCE_SCHEMA_VERSION = void 0;
16336
- exports.PatternExtractor = exports.HeatmapTracker = exports.FrequencyTracker = exports.getSnapshotPath = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.EventAggregator = exports.getRandomPhrase = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.toFollowEvents = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionsInDirectory = exports.findAllClaudeSessions = void 0;
16337
- exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = void 0;
16725
+ exports.HeatmapTracker = exports.FrequencyTracker = exports.getSnapshotPath = exports.isSnapshotValid = exports.deleteSnapshot = exports.loadSnapshot = exports.saveSnapshot = exports.parseTodoDependencies = exports.EventAggregator = exports.getRandomPhrase = exports.ALL_PHRASES = exports.HIGHLIGHT_CSS = exports.clearHighlightCache = exports.highlightEvent = exports.formatSessionJson = exports.formatSessionMarkdown = exports.formatSessionText = exports.classifyNoise = exports.shouldMergeWithPrevious = exports.classifyFollowEvent = exports.classifyMessage = exports.getSoftNoiseReason = exports.isHardNoiseFollowEvent = exports.isHardNoise = exports.formatToolSummary = exports.toFollowEvents = exports.createWatcher = exports.parseChangelog = exports.extractProposedPlanShared = exports.parsePlanMarkdownShared = exports.PlanExtractor = exports.composeContext = exports.FilterEngine = exports.searchSessions = exports.CodexDatabase = exports.OpenCodeDatabase = exports.discoverDebugLogs = exports.collapseDuplicates = exports.filterByLevel = exports.parseDebugLog = exports.scanSubagentTraces = exports.findAllSessionsWithWorktrees = exports.discoverWorktreeSiblings = exports.resolveWorktreeMainRepo = exports.getAllClaudeProjectFolders = exports.decodeEncodedPath = exports.getMostRecentlyActiveSessionDir = exports.findSubdirectorySessionDirs = exports.findSessionsInDirectory = exports.findAllClaudeSessions = void 0;
16726
+ exports.fetchQuota = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = void 0;
16338
16727
  var taskPersistence_1 = require_taskPersistence();
16339
16728
  Object.defineProperty(exports, "TASK_PERSISTENCE_SCHEMA_VERSION", { enumerable: true, get: function() {
16340
16729
  return taskPersistence_1.TASK_PERSISTENCE_SCHEMA_VERSION;
@@ -16650,6 +17039,9 @@ var require_dist = __commonJS({
16650
17039
  Object.defineProperty(exports, "EventAggregator", { enumerable: true, get: function() {
16651
17040
  return EventAggregator_1.EventAggregator;
16652
17041
  } });
17042
+ Object.defineProperty(exports, "parseTodoDependencies", { enumerable: true, get: function() {
17043
+ return EventAggregator_1.parseTodoDependencies;
17044
+ } });
16653
17045
  var snapshot_1 = require_snapshot();
16654
17046
  Object.defineProperty(exports, "saveSnapshot", { enumerable: true, get: function() {
16655
17047
  return snapshot_1.saveSnapshot;
@@ -16688,6 +17080,17 @@ var require_dist = __commonJS({
16688
17080
  Object.defineProperty(exports, "openInBrowser", { enumerable: true, get: function() {
16689
17081
  return report_1.openInBrowser;
16690
17082
  } });
17083
+ var credentials_1 = require_credentials();
17084
+ Object.defineProperty(exports, "readClaudeMaxCredentials", { enumerable: true, get: function() {
17085
+ return credentials_1.readClaudeMaxCredentials;
17086
+ } });
17087
+ Object.defineProperty(exports, "readClaudeMaxAccessTokenSync", { enumerable: true, get: function() {
17088
+ return credentials_1.readClaudeMaxAccessTokenSync;
17089
+ } });
17090
+ var quota_1 = require_quota();
17091
+ Object.defineProperty(exports, "fetchQuota", { enumerable: true, get: function() {
17092
+ return quota_1.fetchQuota;
17093
+ } });
16691
17094
  }
16692
17095
  });
16693
17096
 
@@ -18745,18 +19148,12 @@ var init_StaticDataLoader = __esm({
18745
19148
  });
18746
19149
 
18747
19150
  // src/dashboard/QuotaService.ts
18748
- import * as fs2 from "fs";
18749
- import * as path from "path";
18750
- import * as os from "os";
18751
- var REFRESH_MS, USAGE_URL, BETA_HEADER, FIVE_HOUR_MS, SEVEN_DAY_MS, QuotaService;
19151
+ var import_sidekick_shared4, REFRESH_MS, QuotaService;
18752
19152
  var init_QuotaService = __esm({
18753
19153
  "src/dashboard/QuotaService.ts"() {
18754
19154
  "use strict";
19155
+ import_sidekick_shared4 = __toESM(require_dist(), 1);
18755
19156
  REFRESH_MS = 3e4;
18756
- USAGE_URL = "https://api.anthropic.com/api/oauth/usage";
18757
- BETA_HEADER = "oauth-2025-04-20";
18758
- FIVE_HOUR_MS = 5 * 36e5;
18759
- SEVEN_DAY_MS = 7 * 864e5;
18760
19157
  QuotaService = class {
18761
19158
  _interval = null;
18762
19159
  _cached = null;
@@ -18784,114 +19181,33 @@ var init_QuotaService = __esm({
18784
19181
  }
18785
19182
  /** Single fetch — no polling, includes elapsed-time projections. */
18786
19183
  async fetchOnce() {
18787
- const token = await this.readToken();
18788
- if (!token) {
19184
+ const creds = await (0, import_sidekick_shared4.readClaudeMaxCredentials)();
19185
+ if (!creds) {
18789
19186
  return { fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error: "no-credentials" };
18790
19187
  }
18791
- try {
18792
- const res = await fetch(USAGE_URL, {
18793
- method: "GET",
18794
- headers: {
18795
- "Authorization": `Bearer ${token}`,
18796
- "anthropic-beta": BETA_HEADER,
18797
- "Content-Type": "application/json"
18798
- }
18799
- });
18800
- if (!res.ok) {
18801
- const error = res.status === 401 ? "auth-failed" : `API error: ${res.status}`;
18802
- return { fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error };
18803
- }
18804
- const data = await res.json();
18805
- const fiveUtil = data.five_hour?.utilization ?? 0;
18806
- const sevenUtil = data.seven_day?.utilization ?? 0;
18807
- const fiveResetsAt = data.five_hour?.resets_at ?? "";
18808
- const sevenResetsAt = data.seven_day?.resets_at ?? "";
18809
- return {
18810
- fiveHour: { utilization: fiveUtil, resetsAt: fiveResetsAt },
18811
- sevenDay: { utilization: sevenUtil, resetsAt: sevenResetsAt },
18812
- available: true,
18813
- projectedFiveHour: this.projectFromElapsed(fiveUtil, fiveResetsAt, FIVE_HOUR_MS),
18814
- projectedSevenDay: this.projectFromElapsed(sevenUtil, sevenResetsAt, SEVEN_DAY_MS)
18815
- };
18816
- } catch {
18817
- return { fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error: "network-error" };
18818
- }
19188
+ return (0, import_sidekick_shared4.fetchQuota)(creds.accessToken);
18819
19189
  }
18820
19190
  async fetchQuota() {
18821
- const token = await this.readToken();
18822
- if (!token) {
19191
+ const creds = await (0, import_sidekick_shared4.readClaudeMaxCredentials)();
19192
+ if (!creds) {
18823
19193
  this.emit({ fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false });
18824
19194
  return;
18825
19195
  }
18826
- try {
18827
- const res = await fetch(USAGE_URL, {
18828
- method: "GET",
18829
- headers: {
18830
- "Authorization": `Bearer ${token}`,
18831
- "anthropic-beta": BETA_HEADER,
18832
- "Content-Type": "application/json"
18833
- }
18834
- });
18835
- if (!res.ok) {
18836
- if (res.status === 429 && this._cached?.available) return;
18837
- this.emit({
18838
- fiveHour: { utilization: 0, resetsAt: "" },
18839
- sevenDay: { utilization: 0, resetsAt: "" },
18840
- available: false,
18841
- error: res.status === 401 ? "Sign in to Claude Code to view quota" : `API error: ${res.status}`
18842
- });
18843
- return;
18844
- }
18845
- const data = await res.json();
18846
- const fiveUtil = data.five_hour?.utilization ?? 0;
18847
- const sevenUtil = data.seven_day?.utilization ?? 0;
18848
- const fiveResetsAt = data.five_hour?.resets_at ?? "";
18849
- const sevenResetsAt = data.seven_day?.resets_at ?? "";
18850
- this.emit({
18851
- fiveHour: { utilization: fiveUtil, resetsAt: fiveResetsAt },
18852
- sevenDay: { utilization: sevenUtil, resetsAt: sevenResetsAt },
18853
- available: true,
18854
- projectedFiveHour: this.projectFromElapsed(fiveUtil, fiveResetsAt, FIVE_HOUR_MS),
18855
- projectedSevenDay: this.projectFromElapsed(sevenUtil, sevenResetsAt, SEVEN_DAY_MS)
18856
- });
18857
- } catch {
18858
- if (this._cached?.available) return;
18859
- this.emit({ fiveHour: { utilization: 0, resetsAt: "" }, sevenDay: { utilization: 0, resetsAt: "" }, available: false, error: "Network error" });
18860
- }
19196
+ const state = await (0, import_sidekick_shared4.fetchQuota)(creds.accessToken);
19197
+ if (!state.available && this._cached?.available) return;
19198
+ this.emit(state);
18861
19199
  }
18862
19200
  emit(state) {
18863
19201
  this._cached = state;
18864
19202
  this._callback?.(state);
18865
19203
  }
18866
- async readToken() {
18867
- const credPath = path.join(os.homedir(), ".claude", ".credentials.json");
18868
- try {
18869
- if (!fs2.existsSync(credPath)) return null;
18870
- const content = await fs2.promises.readFile(credPath, "utf8");
18871
- const creds = JSON.parse(content);
18872
- const oauth = creds?.claudeAiOauth;
18873
- if (!oauth?.accessToken) return null;
18874
- if (oauth.expiresAt && Date.now() > oauth.expiresAt) return null;
18875
- return oauth.accessToken;
18876
- } catch {
18877
- return null;
18878
- }
18879
- }
18880
- projectFromElapsed(utilization, resetsAt, windowMs) {
18881
- if (!resetsAt || utilization <= 0) return void 0;
18882
- const resetTime = new Date(resetsAt).getTime();
18883
- const now = Date.now();
18884
- const elapsed = windowMs - (resetTime - now);
18885
- if (elapsed <= 0) return void 0;
18886
- return Math.min(Math.round(utilization * (windowMs / elapsed)), 200);
18887
- }
18888
19204
  };
18889
19205
  }
18890
19206
  });
18891
19207
 
18892
19208
  // src/dashboard/UpdateCheckService.ts
18893
- import * as fs3 from "fs";
18894
- import * as path2 from "path";
19209
+ import * as fs2 from "fs";
19210
+ import * as path from "path";
18895
19211
  function isNewer(a, b) {
18896
19212
  const pa = a.split(".").map(Number);
18897
19213
  const pb = b.split(".").map(Number);
@@ -18903,11 +19219,11 @@ function isNewer(a, b) {
18903
19219
  }
18904
19220
  return false;
18905
19221
  }
18906
- var import_sidekick_shared4, REGISTRY_URL, CACHE_FILE, CACHE_TTL_MS, UpdateCheckService;
19222
+ var import_sidekick_shared5, REGISTRY_URL, CACHE_FILE, CACHE_TTL_MS, UpdateCheckService;
18907
19223
  var init_UpdateCheckService = __esm({
18908
19224
  "src/dashboard/UpdateCheckService.ts"() {
18909
19225
  "use strict";
18910
- import_sidekick_shared4 = __toESM(require_dist(), 1);
19226
+ import_sidekick_shared5 = __toESM(require_dist(), 1);
18911
19227
  REGISTRY_URL = "https://registry.npmjs.org/sidekick-agent-hub/latest";
18912
19228
  CACHE_FILE = "update-check.json";
18913
19229
  CACHE_TTL_MS = 4 * 60 * 60 * 1e3;
@@ -18920,7 +19236,7 @@ var init_UpdateCheckService = __esm({
18920
19236
  /** Run the update check (one-shot). */
18921
19237
  async check() {
18922
19238
  try {
18923
- const current = "0.13.1";
19239
+ const current = "0.13.3";
18924
19240
  const cached = this.readCache();
18925
19241
  let latest;
18926
19242
  if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
@@ -18949,9 +19265,9 @@ var init_UpdateCheckService = __esm({
18949
19265
  }
18950
19266
  readCache() {
18951
19267
  try {
18952
- const cachePath = path2.join((0, import_sidekick_shared4.getConfigDir)(), CACHE_FILE);
18953
- if (!fs3.existsSync(cachePath)) return null;
18954
- const content = fs3.readFileSync(cachePath, "utf8");
19268
+ const cachePath = path.join((0, import_sidekick_shared5.getConfigDir)(), CACHE_FILE);
19269
+ if (!fs2.existsSync(cachePath)) return null;
19270
+ const content = fs2.readFileSync(cachePath, "utf8");
18955
19271
  const parsed = JSON.parse(content);
18956
19272
  if (parsed.latest && typeof parsed.checkedAt === "number") {
18957
19273
  return parsed;
@@ -18962,12 +19278,12 @@ var init_UpdateCheckService = __esm({
18962
19278
  }
18963
19279
  writeCache(cache3) {
18964
19280
  try {
18965
- const configDir = (0, import_sidekick_shared4.getConfigDir)();
18966
- if (!fs3.existsSync(configDir)) {
18967
- fs3.mkdirSync(configDir, { recursive: true });
19281
+ const configDir = (0, import_sidekick_shared5.getConfigDir)();
19282
+ if (!fs2.existsSync(configDir)) {
19283
+ fs2.mkdirSync(configDir, { recursive: true });
18968
19284
  }
18969
- fs3.writeFileSync(
18970
- path2.join(configDir, CACHE_FILE),
19285
+ fs2.writeFileSync(
19286
+ path.join(configDir, CACHE_FILE),
18971
19287
  JSON.stringify(cache3),
18972
19288
  "utf8"
18973
19289
  );
@@ -19830,7 +20146,7 @@ var init_MindMapBuilder = __esm({
19830
20146
 
19831
20147
  // src/dashboard/GitDiffCache.ts
19832
20148
  import { execSync } from "child_process";
19833
- import * as path3 from "path";
20149
+ import * as path2 from "path";
19834
20150
  var CACHE_TTL_MS2, GitDiffCache;
19835
20151
  var init_GitDiffCache = __esm({
19836
20152
  "src/dashboard/GitDiffCache.ts"() {
@@ -19898,8 +20214,8 @@ var init_GitDiffCache = __esm({
19898
20214
  toRelative(absolutePath) {
19899
20215
  const root = this.getRepoRoot();
19900
20216
  if (!root) return absolutePath;
19901
- if (!path3.isAbsolute(absolutePath)) return absolutePath;
19902
- const rel = path3.relative(root, absolutePath);
20217
+ if (!path2.isAbsolute(absolutePath)) return absolutePath;
20218
+ const rel = path2.relative(root, absolutePath);
19903
20219
  if (rel.startsWith("..")) return absolutePath;
19904
20220
  return rel;
19905
20221
  }
@@ -20203,7 +20519,7 @@ function renderContextAttribution(attr) {
20203
20519
  }
20204
20520
  return lines;
20205
20521
  }
20206
- var import_sidekick_shared5, MINDMAP_FILTERS, SessionsPanel, EVENT_COLORS;
20522
+ var import_sidekick_shared6, MINDMAP_FILTERS, SessionsPanel, EVENT_COLORS;
20207
20523
  var init_SessionsPanel = __esm({
20208
20524
  "src/dashboard/panels/SessionsPanel.ts"() {
20209
20525
  "use strict";
@@ -20212,7 +20528,7 @@ var init_SessionsPanel = __esm({
20212
20528
  init_GitDiffCache();
20213
20529
  init_CliInferenceClient();
20214
20530
  init_narrativePrompt();
20215
- import_sidekick_shared5 = __toESM(require_dist(), 1);
20531
+ import_sidekick_shared6 = __toESM(require_dist(), 1);
20216
20532
  MINDMAP_FILTERS = ["all", "file", "tool", "task", "subagent", "command", "plan", "knowledge-note"];
20217
20533
  SessionsPanel = class {
20218
20534
  id = "sessions";
@@ -20546,7 +20862,7 @@ ${hint}{/grey-fg}`;
20546
20862
  const prefixLen = 1 + time.length + 2 + 12;
20547
20863
  const summaryMax = Math.max(10, w - prefixLen - suffix.length);
20548
20864
  const rawSummary = truncate(ev.summary || "", summaryMax);
20549
- const summary = (0, import_sidekick_shared5.highlightEvent)(rawSummary, "blessed");
20865
+ const summary = (0, import_sidekick_shared6.highlightEvent)(rawSummary, "blessed");
20550
20866
  let line = `{${color}-fg}[${time}] ${label}{/${color}-fg} ${summary}`;
20551
20867
  if (suffix) {
20552
20868
  line += ` {grey-fg}${suffix.trimStart()}{/grey-fg}`;
@@ -20712,7 +21028,7 @@ function mergeTasks(live, persisted) {
20712
21028
  map.set(p.taskId, {
20713
21029
  taskId: p.taskId,
20714
21030
  subject: p.subject,
20715
- status: (0, import_sidekick_shared6.normalizeTaskStatus)(p.status),
21031
+ status: (0, import_sidekick_shared7.normalizeTaskStatus)(p.status),
20716
21032
  blockedBy: p.blockedBy || [],
20717
21033
  blocks: p.blocks || [],
20718
21034
  subagentType: p.subagentType,
@@ -20728,11 +21044,11 @@ function mergeTasks(live, persisted) {
20728
21044
  }
20729
21045
  return Array.from(map.values());
20730
21046
  }
20731
- var import_sidekick_shared6;
21047
+ var import_sidekick_shared7;
20732
21048
  var init_taskMerger = __esm({
20733
21049
  "src/dashboard/utils/taskMerger.ts"() {
20734
21050
  "use strict";
20735
- import_sidekick_shared6 = __toESM(require_dist(), 1);
21051
+ import_sidekick_shared7 = __toESM(require_dist(), 1);
20736
21052
  }
20737
21053
  });
20738
21054
 
@@ -21335,12 +21651,12 @@ var init_PlansPanel = __esm({
21335
21651
  });
21336
21652
 
21337
21653
  // src/dashboard/panels/EventStreamPanel.ts
21338
- var import_sidekick_shared7, EVENT_TYPE_BADGES, EventStreamPanel;
21654
+ var import_sidekick_shared8, EVENT_TYPE_BADGES, EventStreamPanel;
21339
21655
  var init_EventStreamPanel = __esm({
21340
21656
  "src/dashboard/panels/EventStreamPanel.ts"() {
21341
21657
  "use strict";
21342
21658
  init_formatters();
21343
- import_sidekick_shared7 = __toESM(require_dist(), 1);
21659
+ import_sidekick_shared8 = __toESM(require_dist(), 1);
21344
21660
  EVENT_TYPE_BADGES = {
21345
21661
  user: "{green-fg}[USR]{/green-fg}",
21346
21662
  assistant: "{blue-fg}[AST]{/blue-fg}",
@@ -21364,7 +21680,7 @@ var init_EventStreamPanel = __esm({
21364
21680
  return events.map((ev, i) => {
21365
21681
  const time = formatTime(ev.timestamp);
21366
21682
  const badge = EVENT_TYPE_BADGES[ev.type] || "{grey-fg}[???]{/grey-fg}";
21367
- const summary = (0, import_sidekick_shared7.highlightEvent)(ev.summary || "", "blessed");
21683
+ const summary = (0, import_sidekick_shared8.highlightEvent)(ev.summary || "", "blessed");
21368
21684
  const label = `{grey-fg}${time}{/grey-fg} ${badge} ${summary}`;
21369
21685
  return {
21370
21686
  id: `ev-${i}`,
@@ -21405,7 +21721,7 @@ var init_EventStreamPanel = __esm({
21405
21721
  lines.push(sectionHeader("Summary", w));
21406
21722
  lines.push("");
21407
21723
  const summary = String(ev.summary || "(no summary)");
21408
- lines.push(wordWrap((0, import_sidekick_shared7.highlightEvent)(summary, "blessed"), w));
21724
+ lines.push(wordWrap((0, import_sidekick_shared8.highlightEvent)(summary, "blessed"), w));
21409
21725
  lines.push("");
21410
21726
  lines.push(sectionHeader("Raw JSON", w));
21411
21727
  lines.push("");
@@ -21434,7 +21750,7 @@ var init_EventStreamPanel = __esm({
21434
21750
  const ev = events[i];
21435
21751
  const time = formatTime(ev.timestamp);
21436
21752
  const badge = EVENT_TYPE_BADGES[ev.type] || "{grey-fg}[???]{/grey-fg}";
21437
- const summary = (0, import_sidekick_shared7.highlightEvent)(ev.summary || "", "blessed");
21753
+ const summary = (0, import_sidekick_shared8.highlightEvent)(ev.summary || "", "blessed");
21438
21754
  if (i === idx) {
21439
21755
  lines.push(`{bold}{magenta-fg}\u25B8 ${time} ${badge} ${summary}{/magenta-fg}{/bold}`);
21440
21756
  } else {
@@ -21803,7 +22119,7 @@ __export(base_exports, {
21803
22119
  synchronizedOutput: () => synchronizedOutput
21804
22120
  });
21805
22121
  import process2 from "node:process";
21806
- import os2 from "node:os";
22122
+ import os from "node:os";
21807
22123
  var ESC, OSC, BEL, SEP, isTerminalApp, isWindows2, isTmux, cwdFunction, wrapOsc, cursorTo, cursorMove, cursorUp, cursorDown, cursorForward, cursorBackward, cursorLeft, cursorSavePosition, cursorRestorePosition, cursorGetPosition, cursorNextLine, cursorPrevLine, cursorHide, cursorShow, eraseLines, eraseEndLine, eraseStartLine, eraseLine, eraseDown, eraseUp, eraseScreen, scrollUp, scrollDown, clearScreen, clearViewport, isOldWindows, clearTerminal, enterAlternativeScreen, exitAlternativeScreen, beginSynchronizedOutput, endSynchronizedOutput, synchronizedOutput, beep, link, image, iTerm, ConEmu, setCwd;
21808
22124
  var init_base = __esm({
21809
22125
  "node_modules/ink/node_modules/ansi-escapes/base.js"() {
@@ -21886,7 +22202,7 @@ var init_base = __esm({
21886
22202
  if (isBrowser || !isWindows2) {
21887
22203
  return false;
21888
22204
  }
21889
- const parts = os2.release().split(".");
22205
+ const parts = os.release().split(".");
21890
22206
  const major = Number(parts[0]);
21891
22207
  const build = Number(parts[2] ?? 0);
21892
22208
  if (major < 10) {
@@ -24413,7 +24729,7 @@ var init_wrap_ansi = __esm({
24413
24729
  // node_modules/terminal-size/index.js
24414
24730
  import process3 from "node:process";
24415
24731
  import { execFileSync } from "node:child_process";
24416
- import fs4 from "node:fs";
24732
+ import fs3 from "node:fs";
24417
24733
  import tty from "node:tty";
24418
24734
  function terminalSize() {
24419
24735
  const { env: env3, stdout, stderr } = process3;
@@ -24469,7 +24785,7 @@ var init_terminal_size = __esm({
24469
24785
  return true;
24470
24786
  }
24471
24787
  try {
24472
- const statContents = fs4.readFileSync("/proc/self/stat", "utf8");
24788
+ const statContents = fs3.readFileSync("/proc/self/stat", "utf8");
24473
24789
  const closingParenthesisIndex = statContents.lastIndexOf(") ");
24474
24790
  if (closingParenthesisIndex === -1) {
24475
24791
  return false;
@@ -24490,8 +24806,8 @@ var init_terminal_size = __esm({
24490
24806
  };
24491
24807
  devTty = () => {
24492
24808
  try {
24493
- const flags = process3.platform === "darwin" ? fs4.constants.O_EVTONLY | fs4.constants.O_NONBLOCK : fs4.constants.O_NONBLOCK;
24494
- const { columns, rows } = tty.WriteStream(fs4.openSync("/dev/tty", flags));
24809
+ const flags = process3.platform === "darwin" ? fs3.constants.O_EVTONLY | fs3.constants.O_NONBLOCK : fs3.constants.O_NONBLOCK;
24810
+ const { columns, rows } = tty.WriteStream(fs3.openSync("/dev/tty", flags));
24495
24811
  return { columns, rows };
24496
24812
  } catch {
24497
24813
  }
@@ -33263,10 +33579,10 @@ var require_react_reconciler_development = __commonJS({
33263
33579
  fiber = fiber.next, id--;
33264
33580
  return fiber;
33265
33581
  }
33266
- function copyWithSetImpl(obj, path8, index, value) {
33267
- if (index >= path8.length) return value;
33268
- var key = path8[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
33269
- updated[key] = copyWithSetImpl(obj[key], path8, index + 1, value);
33582
+ function copyWithSetImpl(obj, path7, index, value) {
33583
+ if (index >= path7.length) return value;
33584
+ var key = path7[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
33585
+ updated[key] = copyWithSetImpl(obj[key], path7, index + 1, value);
33270
33586
  return updated;
33271
33587
  }
33272
33588
  function copyWithRename(obj, oldPath, newPath) {
@@ -33293,11 +33609,11 @@ var require_react_reconciler_development = __commonJS({
33293
33609
  );
33294
33610
  return updated;
33295
33611
  }
33296
- function copyWithDeleteImpl(obj, path8, index) {
33297
- var key = path8[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
33298
- if (index + 1 === path8.length)
33612
+ function copyWithDeleteImpl(obj, path7, index) {
33613
+ var key = path7[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
33614
+ if (index + 1 === path7.length)
33299
33615
  return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
33300
- updated[key] = copyWithDeleteImpl(obj[key], path8, index + 1);
33616
+ updated[key] = copyWithDeleteImpl(obj[key], path7, index + 1);
33301
33617
  return updated;
33302
33618
  }
33303
33619
  function shouldSuspendImpl() {
@@ -46574,29 +46890,29 @@ var require_react_reconciler_development = __commonJS({
46574
46890
  var didWarnAboutNestedUpdates = false;
46575
46891
  var didWarnAboutFindNodeInStrictMode = {};
46576
46892
  var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
46577
- overrideHookState = function(fiber, id, path8, value) {
46893
+ overrideHookState = function(fiber, id, path7, value) {
46578
46894
  id = findHook(fiber, id);
46579
- null !== id && (path8 = copyWithSetImpl(id.memoizedState, path8, 0, value), id.memoizedState = path8, id.baseState = path8, fiber.memoizedProps = assign({}, fiber.memoizedProps), path8 = enqueueConcurrentRenderForLane(fiber, 2), null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2));
46895
+ null !== id && (path7 = copyWithSetImpl(id.memoizedState, path7, 0, value), id.memoizedState = path7, id.baseState = path7, fiber.memoizedProps = assign({}, fiber.memoizedProps), path7 = enqueueConcurrentRenderForLane(fiber, 2), null !== path7 && scheduleUpdateOnFiber(path7, fiber, 2));
46580
46896
  };
46581
- overrideHookStateDeletePath = function(fiber, id, path8) {
46897
+ overrideHookStateDeletePath = function(fiber, id, path7) {
46582
46898
  id = findHook(fiber, id);
46583
- null !== id && (path8 = copyWithDeleteImpl(id.memoizedState, path8, 0), id.memoizedState = path8, id.baseState = path8, fiber.memoizedProps = assign({}, fiber.memoizedProps), path8 = enqueueConcurrentRenderForLane(fiber, 2), null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2));
46899
+ null !== id && (path7 = copyWithDeleteImpl(id.memoizedState, path7, 0), id.memoizedState = path7, id.baseState = path7, fiber.memoizedProps = assign({}, fiber.memoizedProps), path7 = enqueueConcurrentRenderForLane(fiber, 2), null !== path7 && scheduleUpdateOnFiber(path7, fiber, 2));
46584
46900
  };
46585
46901
  overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
46586
46902
  id = findHook(fiber, id);
46587
46903
  null !== id && (oldPath = copyWithRename(id.memoizedState, oldPath, newPath), id.memoizedState = oldPath, id.baseState = oldPath, fiber.memoizedProps = assign({}, fiber.memoizedProps), oldPath = enqueueConcurrentRenderForLane(fiber, 2), null !== oldPath && scheduleUpdateOnFiber(oldPath, fiber, 2));
46588
46904
  };
46589
- overrideProps = function(fiber, path8, value) {
46590
- fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path8, 0, value);
46905
+ overrideProps = function(fiber, path7, value) {
46906
+ fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path7, 0, value);
46591
46907
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
46592
- path8 = enqueueConcurrentRenderForLane(fiber, 2);
46593
- null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2);
46908
+ path7 = enqueueConcurrentRenderForLane(fiber, 2);
46909
+ null !== path7 && scheduleUpdateOnFiber(path7, fiber, 2);
46594
46910
  };
46595
- overridePropsDeletePath = function(fiber, path8) {
46596
- fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path8, 0);
46911
+ overridePropsDeletePath = function(fiber, path7) {
46912
+ fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path7, 0);
46597
46913
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
46598
- path8 = enqueueConcurrentRenderForLane(fiber, 2);
46599
- null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2);
46914
+ path7 = enqueueConcurrentRenderForLane(fiber, 2);
46915
+ null !== path7 && scheduleUpdateOnFiber(path7, fiber, 2);
46600
46916
  };
46601
46917
  overridePropsRenamePath = function(fiber, oldPath, newPath) {
46602
46918
  fiber.pendingProps = copyWithRename(
@@ -52238,8 +52554,8 @@ var init_devtools = __esm({
52238
52554
 
52239
52555
  // node_modules/ink/build/reconciler.js
52240
52556
  async function loadPackageJson() {
52241
- const fs10 = await import("node:fs");
52242
- const content = fs10.readFileSync(new URL("../package.json", import.meta.url), "utf8");
52557
+ const fs9 = await import("node:fs");
52558
+ const content = fs9.readFileSync(new URL("../package.json", import.meta.url), "utf8");
52243
52559
  return JSON.parse(content);
52244
52560
  }
52245
52561
  var import_react_reconciler, import_constants, Scheduler, import_react, diff, cleanupYogaNode, currentUpdatePriority, currentRootNode, packageJson, reconciler_default;
@@ -52849,7 +53165,7 @@ var init_ansi_styles3 = __esm({
52849
53165
 
52850
53166
  // node_modules/chalk/source/vendor/supports-color/index.js
52851
53167
  import process5 from "node:process";
52852
- import os3 from "node:os";
53168
+ import os2 from "node:os";
52853
53169
  import tty2 from "node:tty";
52854
53170
  function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : process5.argv) {
52855
53171
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
@@ -52907,7 +53223,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
52907
53223
  return min;
52908
53224
  }
52909
53225
  if (process5.platform === "win32") {
52910
- const osRelease = os3.release().split(".");
53226
+ const osRelease = os2.release().split(".");
52911
53227
  if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
52912
53228
  return Number(osRelease[2]) >= 14931 ? 3 : 2;
52913
53229
  }
@@ -56403,7 +56719,7 @@ var init_Text = __esm({
56403
56719
  });
56404
56720
 
56405
56721
  // node_modules/ink/build/components/ErrorOverview.js
56406
- import * as fs5 from "node:fs";
56722
+ import * as fs4 from "node:fs";
56407
56723
  import { cwd } from "node:process";
56408
56724
  function ErrorOverview({ error }) {
56409
56725
  const stack = error.stack ? error.stack.split("\n").slice(1) : void 0;
@@ -56411,8 +56727,8 @@ function ErrorOverview({ error }) {
56411
56727
  const filePath = cleanupPath(origin?.file);
56412
56728
  let excerpt;
56413
56729
  let lineWidth = 0;
56414
- if (filePath && origin?.line && fs5.existsSync(filePath)) {
56415
- const sourceCode = fs5.readFileSync(filePath, "utf8");
56730
+ if (filePath && origin?.line && fs4.existsSync(filePath)) {
56731
+ const sourceCode = fs4.readFileSync(filePath, "utf8");
56416
56732
  excerpt = dist_default3(sourceCode, origin.line);
56417
56733
  if (excerpt) {
56418
56734
  for (const { line } of excerpt) {
@@ -56513,8 +56829,8 @@ var init_ErrorOverview = __esm({
56513
56829
  init_dist3();
56514
56830
  init_Box();
56515
56831
  init_Text();
56516
- cleanupPath = (path8) => {
56517
- return path8?.replace(`file://${cwd()}/`, "");
56832
+ cleanupPath = (path7) => {
56833
+ return path7?.replace(`file://${cwd()}/`, "");
56518
56834
  };
56519
56835
  stackUtils = new import_stack_utils.default({
56520
56836
  cwd: cwd(),
@@ -58418,8 +58734,8 @@ var init_build2 = __esm({
58418
58734
  });
58419
58735
 
58420
58736
  // src/dashboard/SessionPickerHelpers.ts
58421
- import * as fs6 from "fs";
58422
- import * as path4 from "path";
58737
+ import * as fs5 from "fs";
58738
+ import * as path3 from "path";
58423
58739
  function formatRelativeTime(mtime, now = /* @__PURE__ */ new Date()) {
58424
58740
  const diffMs = now.getTime() - mtime.getTime();
58425
58741
  if (diffMs < 0) return "just now";
@@ -58438,13 +58754,13 @@ function collectSessionItems(sessionPaths, provider, now = /* @__PURE__ */ new D
58438
58754
  for (const sp of paths) {
58439
58755
  let mtime;
58440
58756
  try {
58441
- mtime = fs6.statSync(sp).mtime;
58757
+ mtime = fs5.statSync(sp).mtime;
58442
58758
  } catch {
58443
58759
  continue;
58444
58760
  }
58445
58761
  const rawLabel = provider.extractSessionLabel(sp);
58446
58762
  const label = rawLabel || "Untitled session";
58447
- const basename5 = path4.basename(sp, path4.extname(sp));
58763
+ const basename5 = path3.basename(sp, path3.extname(sp));
58448
58764
  const sessionId = basename5.length > 8 ? basename5.substring(0, 8) : basename5;
58449
58765
  const age = formatRelativeTime(mtime, now);
58450
58766
  const isActive = now.getTime() - mtime.getTime() < ACTIVE_THRESHOLD_MS;
@@ -58459,13 +58775,13 @@ function collectMultiProviderItems(providers, now = /* @__PURE__ */ new Date())
58459
58775
  for (const sp of paths) {
58460
58776
  let mtime;
58461
58777
  try {
58462
- mtime = fs6.statSync(sp).mtime;
58778
+ mtime = fs5.statSync(sp).mtime;
58463
58779
  } catch {
58464
58780
  continue;
58465
58781
  }
58466
58782
  const rawLabel = provider.extractSessionLabel(sp);
58467
58783
  const label = rawLabel || "Untitled session";
58468
- const basename5 = path4.basename(sp, path4.extname(sp));
58784
+ const basename5 = path3.basename(sp, path3.extname(sp));
58469
58785
  const sessionId = basename5.length > 8 ? basename5.substring(0, 8) : basename5;
58470
58786
  const age = formatRelativeTime(mtime, now);
58471
58787
  const isActive = now.getTime() - mtime.getTime() < ACTIVE_THRESHOLD_MS;
@@ -59010,13 +59326,13 @@ var init_SessionPickerInk = __esm({
59010
59326
 
59011
59327
  // src/phraseFormatters.ts
59012
59328
  function getRandomPhraseBlessedTag() {
59013
- return `{grey-fg}${(0, import_sidekick_shared8.getRandomPhrase)()}{/grey-fg}`;
59329
+ return `{grey-fg}${(0, import_sidekick_shared9.getRandomPhrase)()}{/grey-fg}`;
59014
59330
  }
59015
- var import_sidekick_shared8;
59331
+ var import_sidekick_shared9;
59016
59332
  var init_phraseFormatters = __esm({
59017
59333
  "src/phraseFormatters.ts"() {
59018
59334
  "use strict";
59019
- import_sidekick_shared8 = __toESM(require_dist(), 1);
59335
+ import_sidekick_shared9 = __toESM(require_dist(), 1);
59020
59336
  }
59021
59337
  });
59022
59338
 
@@ -59476,7 +59792,7 @@ function StatusBar({
59476
59792
  ] }),
59477
59793
  /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
59478
59794
  " v",
59479
- "0.13.1"
59795
+ "0.13.3"
59480
59796
  ] }),
59481
59797
  updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
59482
59798
  " (v",
@@ -59622,7 +59938,7 @@ function SplashOverlay() {
59622
59938
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
59623
59939
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { color: "gray", children: [
59624
59940
  " ",
59625
- (0, import_sidekick_shared9.getRandomPhrase)()
59941
+ (0, import_sidekick_shared10.getRandomPhrase)()
59626
59942
  ] }),
59627
59943
  /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Text, { children: " " }),
59628
59944
  /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(Text, { children: [
@@ -59657,13 +59973,13 @@ function SplashOverlay() {
59657
59973
  }
59658
59974
  );
59659
59975
  }
59660
- var import_sidekick_shared9, import_jsx_runtime8;
59976
+ var import_sidekick_shared10, import_jsx_runtime8;
59661
59977
  var init_SplashOverlay = __esm({
59662
59978
  async "src/dashboard/ink/SplashOverlay.tsx"() {
59663
59979
  "use strict";
59664
59980
  await init_build2();
59665
59981
  init_useSpinner();
59666
- import_sidekick_shared9 = __toESM(require_dist(), 1);
59982
+ import_sidekick_shared10 = __toESM(require_dist(), 1);
59667
59983
  init_branding();
59668
59984
  await init_parseBlessedTags();
59669
59985
  import_jsx_runtime8 = __toESM(require_jsx_runtime(), 1);
@@ -59859,7 +60175,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
59859
60175
  " ",
59860
60176
  /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
59861
60177
  "Terminal Dashboard v",
59862
- "0.13.1"
60178
+ "0.13.3"
59863
60179
  ] }),
59864
60180
  latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
59865
60181
  " \u2014 ",
@@ -60214,7 +60530,7 @@ var init_mouse = __esm({
60214
60530
  var CHANGELOG_default;
60215
60531
  var init_CHANGELOG = __esm({
60216
60532
  "CHANGELOG.md"() {
60217
- CHANGELOG_default = '# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.13.1] - 2026-03-04\n\n### Added\n\n- **`sidekick quota` Command**: One-shot subscription quota check showing 5-hour and 7-day utilization with color-coded progress bars and reset countdowns \u2014 supports `--json` for machine-readable output\n- **Quota Projections**: Elapsed-time projections shown in `sidekick quota` output and TUI dashboard quota section \u2014 displays projected end-of-window utilization next to current value (e.g., `40% \u2192 100%`), included in `--json` output as `projectedFiveHour` / `projectedSevenDay`\n\n## [0.13.0] - 2026-03-03\n\n_No CLI-specific changes in this release._\n\n## [0.12.10] - 2026-03-01\n\n### Added\n\n- **Events Panel** (key 7): Scrollable live event stream with colored type badges (`[USR]`, `[AST]`, `[TOOL]`, `[RES]`), timestamps, and keyword-highlighted summaries; detail tabs for full event JSON and surrounding context\n- **Charts Panel** (key 8): Tool frequency horizontal bars, event type distribution, 60-minute activity heatmap using `\u2591\u2592\u2593\u2588` intensity characters, and pattern analysis with frequency bars and template text\n- **Multi-Mode Filter**: `/` filter overlay now supports four modes \u2014 substring, fuzzy, regex, and date range \u2014 Tab cycles modes, regex mode shows red validation errors\n- **Search Term Highlighting**: Active filter terms highlighted in blue within side list items\n- **Timeline Keyword Coloring**: Event summaries in the Sessions panel Timeline tab now use semantic keyword coloring \u2014 errors red, success green, tool names cyan, file paths magenta\n\n### Removed\n\n- **Search Panel**: Removed redundant Search panel (previously key 7) \u2014 the `/` filter with multi-mode support serves the same purpose\n\n## [0.12.9] - 2026-02-28\n\n### Added\n\n- **Standalone Data Commands**: `sidekick tasks`, `sidekick decisions`, `sidekick notes`, `sidekick stats`, `sidekick handoff` for accessing project data without launching the TUI\n- **`sidekick search <query>`**: Cross-session full-text search from the terminal\n- **`sidekick context`**: Composite output of tasks, decisions, notes, and handoff for piping into other tools\n- **`--list` flag on `sidekick dump`**: Discover available session IDs before requiring `--session <id>`\n- **Search Panel**: Search panel (panel 7) wired into the TUI dashboard\n\n### Changed\n\n- **`taskMerger` utility**: Duplicate `mergeTasks` logic extracted into shared `taskMerger` utility\n- **Model constants**: Hardcoded model IDs extracted to named constants\n\n### Fixed\n\n- **`convention` icon**: Notes panel icon replaced with valid `tip` type\n- **Linux clipboard**: Now supports Wayland (`wl-copy`) and `xsel` fallbacks, with error messages instead of silent failure\n- **`provider.dispose()`**: Added to `dump` and `report` commands (prevents SQLite connection leaks)\n\n## [0.12.8] - 2026-02-28\n\n### Changed\n\n- **Dashboard UI/UX Polish**: Visual overhaul for better hierarchy, consistency, and readability\n - Splash screen and help overlay now display the robot ASCII logo\n - Toast notifications show severity icons (\u2718 error, \u26A0 warning, \u25CF info) with inner padding\n - Focused pane uses double-border for clear focus indication\n - Section dividers (`\u2500\u2500 Title \u2500\u2500\u2500\u2500`) replace bare bold headers in summary, agents, and context attribution\n - Tab bar: active tab underlined in magenta, inactive tabs dimmed, bracket syntax removed\n - Status bar: segmented layout with `\u2502` separators; keys bold, labels dim\n - Summary metrics condensed: elapsed/events/compactions on one line, tokens on one line with cache rate and cost\n - Sparklines display peak metadata annotations\n - Progress bars use blessed color tags for consistent coloring\n - Help overlay uses dot-leader alignment for all keybinding rows\n - Empty state hints per panel (e.g. "Tasks appear as your agent works.")\n - Session picker groups sessions by provider with section headers when multiple providers are present\n\n## [0.12.7] - 2026-02-27\n\n### Added\n\n- **HTML Session Report**: `sidekick report` command generates a self-contained HTML report and opens it in the default browser\n - Options: `--session`, `--output`, `--theme` (dark/light), `--no-open`, `--no-thinking`\n - TUI Dashboard: press `r` to generate and open an HTML report for the current session\n\n## [0.12.6] - 2026-02-26\n\n### Added\n\n- **Session Dump Command**: `sidekick dump` exports session data in text, markdown, or JSON format with `--format`, `--width`, and `--expand` options\n- **Plans Panel Re-enabled**: Plans panel restored in CLI dashboard with plan file discovery from `~/.claude/plans/`\n- **Enhanced Status Bar**: Session info display improved with richer metadata\n\n### Fixed\n\n- **Old snapshot format migration**: Restoring pre-0.12.3 session snapshots no longer shows empty timeline entries\n\n### Changed\n\n- **Phrase library moved to shared**: CLI-specific phrase formatting kept local, all phrase content now from `sidekick-shared`\n\n## [0.12.5] - 2026-02-24\n\n### Fixed\n\n- **Update check too slow to notice new versions**: Reduced npm registry cache TTL from 24 hours to 4 hours so upgrade notices appear sooner after a new release\n\n## [0.12.4] - 2026-02-24\n\n### Fixed\n\n- **Session crash on upgrade**: Fixed `d.timestamp.getTime is not a function` error when restoring tool call data from session snapshots \u2014 `Date` objects were serialized to strings by JSON but not rehydrated on restore, causing the session monitor to crash on first run after upgrading from 0.12.2 to 0.12.3\n\n## [0.12.3] - 2026-02-24\n\n### Added\n\n- **Latest-node indicator**: The most recently added node in tree and boxed mind map views is now marked with a yellow indicator\n- **Plan analytics in mind map**: Tree and boxed views now display plan progress and per-step metrics\n - Tree view: plan header shows completion stats; steps show complexity, duration, tokens, tool calls, and errors in metadata brackets\n - Box view: progress bar with completion percentage; steps show right-aligned metrics; subtitle shows step count and total duration\n- **Cross-provider plan extraction**: Shared `PlanExtractor` now handles Claude Code (EnterPlanMode/ExitPlanMode) and OpenCode (`<proposed_plan>` XML) plans \u2014 previously only Codex plans were shown\n- **Enriched plan data model**: Plan steps include duration, token count, tool call count, and error messages\n- **Phase-grouped plan display**: When a plan has phase structure, tree and boxed views group steps under phase headers with context lines from the original plan markdown\n- **Node type filter**: Press `f` on the Mind Map tab to cycle through node type filters (file, tool, task, subagent, command, plan, knowledge-note) \u2014 non-matching sections render dimmed in grey\n\n### Fixed\n\n- **Kanban board regression**: Subagent and plan-step tasks now correctly appear in the kanban board\n\n### Changed\n\n- **Plans panel temporarily disabled**: The Plans panel in the CLI dashboard is disabled until plan-mode event capture is reliably working end-to-end. Plan nodes in the mind map remain active.\n- `DashboardState` now delegates to shared `EventAggregator` instead of maintaining its own aggregation logic\n\n## [0.12.2] - 2026-02-23\n\n### Added\n\n- **Update notifications**: The dashboard now checks the npm registry for newer versions on startup and shows a yellow banner in the status bar when an update is available (e.g., `v0.13.0 available \u2014 npm i -g sidekick-agent-hub`). Results are cached for 24 hours to avoid repeated network requests.\n\n## [0.12.1] - 2026-02-23\n\n### Fixed\n\n- **VS Code integration**: Fixed exit code 127 when the extension launches the CLI dashboard on systems using nvm or volta (node binary not found when shell init is bypassed)\n\n## [0.12.0] - 2026-02-22\n\n### Added\n\n- **"Open CLI Dashboard" VS Code Integration**: New VS Code command `Sidekick: Open CLI Dashboard` launches the TUI dashboard in an integrated terminal\n - Install the CLI with `npm install -g sidekick-agent-hub`\n\n## [0.11.0] - 2026-02-19\n\n### Added\n\n- **Initial Release**: Full-screen TUI dashboard for monitoring agent sessions from the terminal\n - Ink-based terminal UI with panels for sessions, tasks, kanban, mind map, notes, decisions, search, files, and git diff\n - Multi-provider support: auto-detects Claude Code, OpenCode, and Codex sessions\n - Reads from `~/.config/sidekick/` \u2014 the same data files the VS Code extension writes\n - Usage: `sidekick dashboard [--project <path>] [--provider <id>]`\n';
60533
+ CHANGELOG_default = '# Changelog\n\nAll notable changes to the Sidekick Agent Hub CLI will be documented in this file.\n\nThe format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),\nand this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n\n## [0.13.3] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.2] - 2026-03-04\n\n_No CLI-specific changes in this release._\n\n## [0.13.1] - 2026-03-04\n\n### Added\n\n- **`sidekick quota` Command**: One-shot subscription quota check showing 5-hour and 7-day utilization with color-coded progress bars and reset countdowns \u2014 supports `--json` for machine-readable output\n- **Quota Projections**: Elapsed-time projections shown in `sidekick quota` output and TUI dashboard quota section \u2014 displays projected end-of-window utilization next to current value (e.g., `40% \u2192 100%`), included in `--json` output as `projectedFiveHour` / `projectedSevenDay`\n\n## [0.13.0] - 2026-03-03\n\n_No CLI-specific changes in this release._\n\n## [0.12.10] - 2026-03-01\n\n### Added\n\n- **Events Panel** (key 7): Scrollable live event stream with colored type badges (`[USR]`, `[AST]`, `[TOOL]`, `[RES]`), timestamps, and keyword-highlighted summaries; detail tabs for full event JSON and surrounding context\n- **Charts Panel** (key 8): Tool frequency horizontal bars, event type distribution, 60-minute activity heatmap using `\u2591\u2592\u2593\u2588` intensity characters, and pattern analysis with frequency bars and template text\n- **Multi-Mode Filter**: `/` filter overlay now supports four modes \u2014 substring, fuzzy, regex, and date range \u2014 Tab cycles modes, regex mode shows red validation errors\n- **Search Term Highlighting**: Active filter terms highlighted in blue within side list items\n- **Timeline Keyword Coloring**: Event summaries in the Sessions panel Timeline tab now use semantic keyword coloring \u2014 errors red, success green, tool names cyan, file paths magenta\n\n### Removed\n\n- **Search Panel**: Removed redundant Search panel (previously key 7) \u2014 the `/` filter with multi-mode support serves the same purpose\n\n## [0.12.9] - 2026-02-28\n\n### Added\n\n- **Standalone Data Commands**: `sidekick tasks`, `sidekick decisions`, `sidekick notes`, `sidekick stats`, `sidekick handoff` for accessing project data without launching the TUI\n- **`sidekick search <query>`**: Cross-session full-text search from the terminal\n- **`sidekick context`**: Composite output of tasks, decisions, notes, and handoff for piping into other tools\n- **`--list` flag on `sidekick dump`**: Discover available session IDs before requiring `--session <id>`\n- **Search Panel**: Search panel (panel 7) wired into the TUI dashboard\n\n### Changed\n\n- **`taskMerger` utility**: Duplicate `mergeTasks` logic extracted into shared `taskMerger` utility\n- **Model constants**: Hardcoded model IDs extracted to named constants\n\n### Fixed\n\n- **`convention` icon**: Notes panel icon replaced with valid `tip` type\n- **Linux clipboard**: Now supports Wayland (`wl-copy`) and `xsel` fallbacks, with error messages instead of silent failure\n- **`provider.dispose()`**: Added to `dump` and `report` commands (prevents SQLite connection leaks)\n\n## [0.12.8] - 2026-02-28\n\n### Changed\n\n- **Dashboard UI/UX Polish**: Visual overhaul for better hierarchy, consistency, and readability\n - Splash screen and help overlay now display the robot ASCII logo\n - Toast notifications show severity icons (\u2718 error, \u26A0 warning, \u25CF info) with inner padding\n - Focused pane uses double-border for clear focus indication\n - Section dividers (`\u2500\u2500 Title \u2500\u2500\u2500\u2500`) replace bare bold headers in summary, agents, and context attribution\n - Tab bar: active tab underlined in magenta, inactive tabs dimmed, bracket syntax removed\n - Status bar: segmented layout with `\u2502` separators; keys bold, labels dim\n - Summary metrics condensed: elapsed/events/compactions on one line, tokens on one line with cache rate and cost\n - Sparklines display peak metadata annotations\n - Progress bars use blessed color tags for consistent coloring\n - Help overlay uses dot-leader alignment for all keybinding rows\n - Empty state hints per panel (e.g. "Tasks appear as your agent works.")\n - Session picker groups sessions by provider with section headers when multiple providers are present\n\n## [0.12.7] - 2026-02-27\n\n### Added\n\n- **HTML Session Report**: `sidekick report` command generates a self-contained HTML report and opens it in the default browser\n - Options: `--session`, `--output`, `--theme` (dark/light), `--no-open`, `--no-thinking`\n - TUI Dashboard: press `r` to generate and open an HTML report for the current session\n\n## [0.12.6] - 2026-02-26\n\n### Added\n\n- **Session Dump Command**: `sidekick dump` exports session data in text, markdown, or JSON format with `--format`, `--width`, and `--expand` options\n- **Plans Panel Re-enabled**: Plans panel restored in CLI dashboard with plan file discovery from `~/.claude/plans/`\n- **Enhanced Status Bar**: Session info display improved with richer metadata\n\n### Fixed\n\n- **Old snapshot format migration**: Restoring pre-0.12.3 session snapshots no longer shows empty timeline entries\n\n### Changed\n\n- **Phrase library moved to shared**: CLI-specific phrase formatting kept local, all phrase content now from `sidekick-shared`\n\n## [0.12.5] - 2026-02-24\n\n### Fixed\n\n- **Update check too slow to notice new versions**: Reduced npm registry cache TTL from 24 hours to 4 hours so upgrade notices appear sooner after a new release\n\n## [0.12.4] - 2026-02-24\n\n### Fixed\n\n- **Session crash on upgrade**: Fixed `d.timestamp.getTime is not a function` error when restoring tool call data from session snapshots \u2014 `Date` objects were serialized to strings by JSON but not rehydrated on restore, causing the session monitor to crash on first run after upgrading from 0.12.2 to 0.12.3\n\n## [0.12.3] - 2026-02-24\n\n### Added\n\n- **Latest-node indicator**: The most recently added node in tree and boxed mind map views is now marked with a yellow indicator\n- **Plan analytics in mind map**: Tree and boxed views now display plan progress and per-step metrics\n - Tree view: plan header shows completion stats; steps show complexity, duration, tokens, tool calls, and errors in metadata brackets\n - Box view: progress bar with completion percentage; steps show right-aligned metrics; subtitle shows step count and total duration\n- **Cross-provider plan extraction**: Shared `PlanExtractor` now handles Claude Code (EnterPlanMode/ExitPlanMode) and OpenCode (`<proposed_plan>` XML) plans \u2014 previously only Codex plans were shown\n- **Enriched plan data model**: Plan steps include duration, token count, tool call count, and error messages\n- **Phase-grouped plan display**: When a plan has phase structure, tree and boxed views group steps under phase headers with context lines from the original plan markdown\n- **Node type filter**: Press `f` on the Mind Map tab to cycle through node type filters (file, tool, task, subagent, command, plan, knowledge-note) \u2014 non-matching sections render dimmed in grey\n\n### Fixed\n\n- **Kanban board regression**: Subagent and plan-step tasks now correctly appear in the kanban board\n\n### Changed\n\n- **Plans panel temporarily disabled**: The Plans panel in the CLI dashboard is disabled until plan-mode event capture is reliably working end-to-end. Plan nodes in the mind map remain active.\n- `DashboardState` now delegates to shared `EventAggregator` instead of maintaining its own aggregation logic\n\n## [0.12.2] - 2026-02-23\n\n### Added\n\n- **Update notifications**: The dashboard now checks the npm registry for newer versions on startup and shows a yellow banner in the status bar when an update is available (e.g., `v0.13.0 available \u2014 npm i -g sidekick-agent-hub`). Results are cached for 24 hours to avoid repeated network requests.\n\n## [0.12.1] - 2026-02-23\n\n### Fixed\n\n- **VS Code integration**: Fixed exit code 127 when the extension launches the CLI dashboard on systems using nvm or volta (node binary not found when shell init is bypassed)\n\n## [0.12.0] - 2026-02-22\n\n### Added\n\n- **"Open CLI Dashboard" VS Code Integration**: New VS Code command `Sidekick: Open CLI Dashboard` launches the TUI dashboard in an integrated terminal\n - Install the CLI with `npm install -g sidekick-agent-hub`\n\n## [0.11.0] - 2026-02-19\n\n### Added\n\n- **Initial Release**: Full-screen TUI dashboard for monitoring agent sessions from the terminal\n - Ink-based terminal UI with panels for sessions, tasks, kanban, mind map, notes, decisions, search, files, and git diff\n - Multi-provider support: auto-detects Claude Code, OpenCode, and Codex sessions\n - Reads from `~/.config/sidekick/` \u2014 the same data files the VS Code extension writes\n - Usage: `sidekick dashboard [--project <path>] [--provider <id>]`\n';
60218
60534
  }
60219
60535
  });
60220
60536
 
@@ -60941,7 +61257,7 @@ function filterKanbanColumn(item, filter) {
60941
61257
  data: { status: colData.status, tasks: filtered }
60942
61258
  };
60943
61259
  }
60944
- var import_react35, import_sidekick_shared10, import_jsx_runtime16, changelogEntries, SIDE_PANEL_WIDTH, NARROW_SIDE_WIDTH, MIN_SCREEN_WIDTH, MIN_SCREEN_HEIGHT, WIDE_SIDE_WIDTH, initialState;
61260
+ var import_react35, import_sidekick_shared11, import_jsx_runtime16, changelogEntries, SIDE_PANEL_WIDTH, NARROW_SIDE_WIDTH, MIN_SCREEN_WIDTH, MIN_SCREEN_HEIGHT, WIDE_SIDE_WIDTH, initialState;
60945
61261
  var init_Dashboard = __esm({
60946
61262
  async "src/dashboard/ink/Dashboard.tsx"() {
60947
61263
  "use strict";
@@ -60964,9 +61280,9 @@ var init_Dashboard = __esm({
60964
61280
  await init_ToastNotification();
60965
61281
  await init_mouse();
60966
61282
  init_CHANGELOG();
60967
- import_sidekick_shared10 = __toESM(require_dist(), 1);
61283
+ import_sidekick_shared11 = __toESM(require_dist(), 1);
60968
61284
  import_jsx_runtime16 = __toESM(require_jsx_runtime(), 1);
60969
- changelogEntries = (0, import_sidekick_shared10.parseChangelog)(CHANGELOG_default, 5);
61285
+ changelogEntries = (0, import_sidekick_shared11.parseChangelog)(CHANGELOG_default, 5);
60970
61286
  SIDE_PANEL_WIDTH = 26;
60971
61287
  NARROW_SIDE_WIDTH = 22;
60972
61288
  MIN_SCREEN_WIDTH = 60;
@@ -60998,18 +61314,18 @@ var dashboard_exports = {};
60998
61314
  __export(dashboard_exports, {
60999
61315
  dashboardAction: () => dashboardAction
61000
61316
  });
61001
- import * as path5 from "path";
61002
- import * as os4 from "os";
61003
- import * as fs7 from "fs";
61317
+ import * as path4 from "path";
61318
+ import * as os3 from "os";
61319
+ import * as fs6 from "fs";
61004
61320
  function createProviderById(id) {
61005
61321
  switch (id) {
61006
61322
  case "opencode":
61007
- return new import_sidekick_shared12.OpenCodeProvider();
61323
+ return new import_sidekick_shared13.OpenCodeProvider();
61008
61324
  case "codex":
61009
- return new import_sidekick_shared12.CodexProvider();
61325
+ return new import_sidekick_shared13.CodexProvider();
61010
61326
  case "claude-code":
61011
61327
  default:
61012
- return new import_sidekick_shared12.ClaudeCodeProvider();
61328
+ return new import_sidekick_shared13.ClaudeCodeProvider();
61013
61329
  }
61014
61330
  }
61015
61331
  async function dashboardAction(_opts, cmd) {
@@ -61020,7 +61336,7 @@ async function dashboardAction(_opts, cmd) {
61020
61336
  let sessionId = opts.session;
61021
61337
  let replay = !!opts.replay;
61022
61338
  let activeProvider = provider;
61023
- const detectedIds = (0, import_sidekick_shared11.getAllDetectedProviders)();
61339
+ const detectedIds = (0, import_sidekick_shared12.getAllDetectedProviders)();
61024
61340
  const additionalProviders = detectedIds.filter((id) => id !== provider.id).map((id) => createProviderById(id));
61025
61341
  if (!sessionId) {
61026
61342
  const sessions = provider.findAllSessions(workspacePath);
@@ -61029,7 +61345,7 @@ async function dashboardAction(_opts, cmd) {
61029
61345
  try {
61030
61346
  const result = await showSessionPicker(provider, workspacePath, additionalProviders);
61031
61347
  if (result.sessionPath) {
61032
- sessionId = path5.basename(result.sessionPath, path5.extname(result.sessionPath));
61348
+ sessionId = path4.basename(result.sessionPath, path4.extname(result.sessionPath));
61033
61349
  replay = true;
61034
61350
  if (result.providerId && result.providerId !== provider.id) {
61035
61351
  activeProvider = createProviderById(result.providerId);
@@ -61089,7 +61405,7 @@ async function dashboardAction(_opts, cmd) {
61089
61405
  if (watcher?.getPosition && sessionPath) {
61090
61406
  let sourceSize = 0;
61091
61407
  try {
61092
- sourceSize = fs7.statSync(sessionPath).size;
61408
+ sourceSize = fs6.statSync(sessionPath).size;
61093
61409
  } catch {
61094
61410
  }
61095
61411
  state.persistSnapshot(watcher.getPosition(), sourceSize);
@@ -61100,10 +61416,10 @@ async function dashboardAction(_opts, cmd) {
61100
61416
  }
61101
61417
  state.reset();
61102
61418
  pendingSessionPath = null;
61103
- const newSessionId = path5.basename(newSessionPath, path5.extname(newSessionPath));
61419
+ const newSessionId = path4.basename(newSessionPath, path4.extname(newSessionPath));
61104
61420
  state.setSessionId(newSessionId);
61105
61421
  try {
61106
- const result = (0, import_sidekick_shared11.createWatcher)({
61422
+ const result = (0, import_sidekick_shared12.createWatcher)({
61107
61423
  provider: activeProvider,
61108
61424
  workspacePath,
61109
61425
  sessionId: newSessionId,
@@ -61116,7 +61432,7 @@ async function dashboardAction(_opts, cmd) {
61116
61432
  lastSnapshotTime = now;
61117
61433
  let ss = 0;
61118
61434
  try {
61119
- if (sessionPath) ss = fs7.statSync(sessionPath).size;
61435
+ if (sessionPath) ss = fs6.statSync(sessionPath).size;
61120
61436
  } catch {
61121
61437
  }
61122
61438
  state.persistSnapshot(watcher.getPosition(), ss);
@@ -61133,7 +61449,7 @@ async function dashboardAction(_opts, cmd) {
61133
61449
  if (watcher.seekTo) {
61134
61450
  let sourceSize = 0;
61135
61451
  try {
61136
- sourceSize = fs7.statSync(sessionPath).size;
61452
+ sourceSize = fs6.statSync(sessionPath).size;
61137
61453
  } catch {
61138
61454
  }
61139
61455
  const seekPos = state.tryRestoreFromSnapshot(newSessionId, activeProvider.id, sourceSize);
@@ -61146,7 +61462,7 @@ async function dashboardAction(_opts, cmd) {
61146
61462
  if (!switchRestored && watcher.getPosition) {
61147
61463
  let sourceSize = 0;
61148
61464
  try {
61149
- sourceSize = fs7.statSync(sessionPath).size;
61465
+ sourceSize = fs6.statSync(sessionPath).size;
61150
61466
  } catch {
61151
61467
  }
61152
61468
  state.persistSnapshot(watcher.getPosition(), sourceSize);
@@ -61178,28 +61494,28 @@ async function dashboardAction(_opts, cmd) {
61178
61494
  const generateReport = () => {
61179
61495
  if (!sessionPath) return;
61180
61496
  const events = [];
61181
- const replayResult = (0, import_sidekick_shared11.createWatcher)({
61497
+ const replayResult = (0, import_sidekick_shared12.createWatcher)({
61182
61498
  provider: activeProvider,
61183
61499
  workspacePath,
61184
- sessionId: path5.basename(sessionPath, path5.extname(sessionPath)),
61500
+ sessionId: path4.basename(sessionPath, path4.extname(sessionPath)),
61185
61501
  callbacks: { onEvent: (e) => events.push(e), onError: () => {
61186
61502
  } }
61187
61503
  });
61188
61504
  replayResult.watcher.start(true);
61189
61505
  replayResult.watcher.stop();
61190
- const aggregator = new import_sidekick_shared11.EventAggregator({ providerId: activeProvider.id });
61506
+ const aggregator = new import_sidekick_shared12.EventAggregator({ providerId: activeProvider.id });
61191
61507
  for (const e of events) aggregator.processFollowEvent(e);
61192
61508
  const metrics = aggregator.getMetrics();
61193
- const transcript = (0, import_sidekick_shared11.parseTranscript)(sessionPath);
61194
- const html = (0, import_sidekick_shared11.generateHtmlReport)(metrics, transcript, {
61195
- sessionFileName: path5.basename(sessionPath),
61509
+ const transcript = (0, import_sidekick_shared12.parseTranscript)(sessionPath);
61510
+ const html = (0, import_sidekick_shared12.generateHtmlReport)(metrics, transcript, {
61511
+ sessionFileName: path4.basename(sessionPath),
61196
61512
  includeThinking: true,
61197
61513
  includeToolDetail: true,
61198
61514
  theme: "dark"
61199
61515
  });
61200
- const outFile = path5.join(os4.tmpdir(), `sidekick-report-${Date.now()}.html`);
61201
- fs7.writeFileSync(outFile, html, "utf-8");
61202
- (0, import_sidekick_shared11.openInBrowser)(outFile);
61516
+ const outFile = path4.join(os3.tmpdir(), `sidekick-report-${Date.now()}.html`);
61517
+ fs6.writeFileSync(outFile, html, "utf-8");
61518
+ (0, import_sidekick_shared12.openInBrowser)(outFile);
61203
61519
  };
61204
61520
  const instance = render2(
61205
61521
  import_react36.default.createElement(Dashboard, {
@@ -61278,7 +61594,7 @@ async function dashboardAction(_opts, cmd) {
61278
61594
  let lastSnapshotTime = 0;
61279
61595
  const SNAPSHOT_INTERVAL_MS = 3e4;
61280
61596
  try {
61281
- const result = (0, import_sidekick_shared11.createWatcher)({
61597
+ const result = (0, import_sidekick_shared12.createWatcher)({
61282
61598
  provider: activeProvider,
61283
61599
  workspacePath,
61284
61600
  sessionId,
@@ -61291,7 +61607,7 @@ async function dashboardAction(_opts, cmd) {
61291
61607
  lastSnapshotTime = now;
61292
61608
  let sourceSize = 0;
61293
61609
  try {
61294
- if (sessionPath) sourceSize = fs7.statSync(sessionPath).size;
61610
+ if (sessionPath) sourceSize = fs6.statSync(sessionPath).size;
61295
61611
  } catch {
61296
61612
  }
61297
61613
  state.persistSnapshot(watcher.getPosition(), sourceSize);
@@ -61307,7 +61623,7 @@ async function dashboardAction(_opts, cmd) {
61307
61623
  if (sessionId && replay && watcher.seekTo) {
61308
61624
  let sourceSize = 0;
61309
61625
  try {
61310
- sourceSize = fs7.statSync(sessionPath).size;
61626
+ sourceSize = fs6.statSync(sessionPath).size;
61311
61627
  } catch {
61312
61628
  }
61313
61629
  const seekPosition = state.tryRestoreFromSnapshot(sessionId, activeProvider.id, sourceSize);
@@ -61327,7 +61643,7 @@ async function dashboardAction(_opts, cmd) {
61327
61643
  if (watcher.getPosition && sessionPath) {
61328
61644
  let sourceSize = 0;
61329
61645
  try {
61330
- sourceSize = fs7.statSync(sessionPath).size;
61646
+ sourceSize = fs6.statSync(sessionPath).size;
61331
61647
  } catch {
61332
61648
  }
61333
61649
  state.persistSnapshot(watcher.getPosition(), sourceSize);
@@ -61338,7 +61654,7 @@ async function dashboardAction(_opts, cmd) {
61338
61654
  if (replay && watcher.getPosition && sessionPath) {
61339
61655
  let sourceSize = 0;
61340
61656
  try {
61341
- sourceSize = fs7.statSync(sessionPath).size;
61657
+ sourceSize = fs6.statSync(sessionPath).size;
61342
61658
  } catch {
61343
61659
  }
61344
61660
  state.persistSnapshot(watcher.getPosition(), sourceSize);
@@ -61350,13 +61666,13 @@ async function dashboardAction(_opts, cmd) {
61350
61666
  cleanup();
61351
61667
  process.exit(0);
61352
61668
  }
61353
- var import_react36, import_sidekick_shared11, import_sidekick_shared12;
61669
+ var import_react36, import_sidekick_shared12, import_sidekick_shared13;
61354
61670
  var init_dashboard = __esm({
61355
61671
  async "src/commands/dashboard.ts"() {
61356
61672
  "use strict";
61357
61673
  import_react36 = __toESM(require_react(), 1);
61358
- import_sidekick_shared11 = __toESM(require_dist(), 1);
61359
61674
  import_sidekick_shared12 = __toESM(require_dist(), 1);
61675
+ import_sidekick_shared13 = __toESM(require_dist(), 1);
61360
61676
  init_cli();
61361
61677
  init_DashboardState();
61362
61678
  init_StaticDataLoader();
@@ -61381,8 +61697,8 @@ var dump_exports = {};
61381
61697
  __export(dump_exports, {
61382
61698
  dumpAction: () => dumpAction
61383
61699
  });
61384
- import * as fs8 from "fs";
61385
- import * as path6 from "path";
61700
+ import * as fs7 from "fs";
61701
+ import * as path5 from "path";
61386
61702
  function formatTimestamp(d) {
61387
61703
  const pad = (n) => String(n).padStart(2, "0");
61388
61704
  return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
@@ -61414,14 +61730,14 @@ function listSessions(provider, workspacePath, asJson) {
61414
61730
  let mtime;
61415
61731
  let size;
61416
61732
  try {
61417
- const stat = fs8.statSync(sp);
61733
+ const stat = fs7.statSync(sp);
61418
61734
  mtime = stat.mtime;
61419
61735
  size = stat.size;
61420
61736
  } catch {
61421
61737
  continue;
61422
61738
  }
61423
- const ext = path6.extname(sp);
61424
- const id = path6.basename(sp, ext);
61739
+ const ext = path5.extname(sp);
61740
+ const id = path5.basename(sp, ext);
61425
61741
  const label = provider.extractSessionLabel(sp) || "";
61426
61742
  sessions.push({
61427
61743
  id,
@@ -61485,7 +61801,7 @@ async function dumpAction(_opts, cmd) {
61485
61801
  let sessionPath;
61486
61802
  try {
61487
61803
  try {
61488
- const result = (0, import_sidekick_shared13.createWatcher)({
61804
+ const result = (0, import_sidekick_shared14.createWatcher)({
61489
61805
  provider,
61490
61806
  workspacePath,
61491
61807
  sessionId,
@@ -61506,22 +61822,22 @@ async function dumpAction(_opts, cmd) {
61506
61822
  `);
61507
61823
  process.exit(1);
61508
61824
  }
61509
- const aggregator = new import_sidekick_shared13.EventAggregator({ providerId: provider.id });
61825
+ const aggregator = new import_sidekick_shared14.EventAggregator({ providerId: provider.id });
61510
61826
  for (const event of events) {
61511
61827
  aggregator.processFollowEvent(event);
61512
61828
  }
61513
61829
  const metrics = aggregator.getMetrics();
61514
- const sessionFileName = path6.basename(sessionPath);
61830
+ const sessionFileName = path5.basename(sessionPath);
61515
61831
  switch (format) {
61516
61832
  case "json":
61517
- process.stdout.write((0, import_sidekick_shared13.formatSessionJson)(metrics));
61833
+ process.stdout.write((0, import_sidekick_shared14.formatSessionJson)(metrics));
61518
61834
  break;
61519
61835
  case "markdown":
61520
- process.stdout.write((0, import_sidekick_shared13.formatSessionMarkdown)(metrics, { expand, sessionFileName }));
61836
+ process.stdout.write((0, import_sidekick_shared14.formatSessionMarkdown)(metrics, { expand, sessionFileName }));
61521
61837
  break;
61522
61838
  case "text":
61523
61839
  default:
61524
- process.stdout.write((0, import_sidekick_shared13.formatSessionText)(metrics, { width: termWidth, expand }));
61840
+ process.stdout.write((0, import_sidekick_shared14.formatSessionText)(metrics, { width: termWidth, expand }));
61525
61841
  break;
61526
61842
  }
61527
61843
  } finally {
@@ -61531,11 +61847,11 @@ async function dumpAction(_opts, cmd) {
61531
61847
  }
61532
61848
  }
61533
61849
  }
61534
- var import_sidekick_shared13;
61850
+ var import_sidekick_shared14;
61535
61851
  var init_dump = __esm({
61536
61852
  "src/commands/dump.ts"() {
61537
61853
  "use strict";
61538
- import_sidekick_shared13 = __toESM(require_dist(), 1);
61854
+ import_sidekick_shared14 = __toESM(require_dist(), 1);
61539
61855
  init_cli();
61540
61856
  }
61541
61857
  });
@@ -61625,11 +61941,11 @@ async function contextAction(_opts, cmd) {
61625
61941
  const workspacePath = globalOpts.project || process.cwd();
61626
61942
  const jsonOutput = !!globalOpts.json || !!opts.json;
61627
61943
  const fidelity = opts.fidelity || "full";
61628
- const slug = (0, import_sidekick_shared14.getProjectSlug)(workspacePath);
61629
- const slugRaw = (0, import_sidekick_shared14.getProjectSlugRaw)(workspacePath);
61944
+ const slug = (0, import_sidekick_shared15.getProjectSlug)(workspacePath);
61945
+ const slugRaw = (0, import_sidekick_shared15.getProjectSlugRaw)(workspacePath);
61630
61946
  const effectiveSlug = slug !== slugRaw ? slugRaw : slug;
61631
61947
  try {
61632
- const ctx = await (0, import_sidekick_shared14.composeContext)(effectiveSlug, fidelity, provider, workspacePath);
61948
+ const ctx = await (0, import_sidekick_shared15.composeContext)(effectiveSlug, fidelity, provider, workspacePath);
61633
61949
  if (jsonOutput) {
61634
61950
  process.stdout.write(JSON.stringify(ctx, null, 2) + "\n");
61635
61951
  } else {
@@ -61647,11 +61963,11 @@ async function contextAction(_opts, cmd) {
61647
61963
  }
61648
61964
  }
61649
61965
  }
61650
- var import_sidekick_shared14;
61966
+ var import_sidekick_shared15;
61651
61967
  var init_context = __esm({
61652
61968
  "src/commands/context.ts"() {
61653
61969
  "use strict";
61654
- import_sidekick_shared14 = __toESM(require_dist(), 1);
61970
+ import_sidekick_shared15 = __toESM(require_dist(), 1);
61655
61971
  init_cli();
61656
61972
  }
61657
61973
  });
@@ -61661,9 +61977,9 @@ var report_exports = {};
61661
61977
  __export(report_exports, {
61662
61978
  reportAction: () => reportAction
61663
61979
  });
61664
- import * as os5 from "os";
61665
- import * as path7 from "path";
61666
- import * as fs9 from "fs";
61980
+ import * as os4 from "os";
61981
+ import * as path6 from "path";
61982
+ import * as fs8 from "fs";
61667
61983
  async function reportAction(_opts, cmd) {
61668
61984
  const globalOpts = cmd.parent.opts();
61669
61985
  const opts = cmd.opts();
@@ -61678,7 +61994,7 @@ async function reportAction(_opts, cmd) {
61678
61994
  let sessionPath;
61679
61995
  try {
61680
61996
  try {
61681
- const result = (0, import_sidekick_shared15.createWatcher)({
61997
+ const result = (0, import_sidekick_shared16.createWatcher)({
61682
61998
  provider,
61683
61999
  workspacePath,
61684
62000
  sessionId,
@@ -61699,26 +62015,26 @@ async function reportAction(_opts, cmd) {
61699
62015
  `);
61700
62016
  process.exit(1);
61701
62017
  }
61702
- const aggregator = new import_sidekick_shared15.EventAggregator({ providerId: provider.id });
62018
+ const aggregator = new import_sidekick_shared16.EventAggregator({ providerId: provider.id });
61703
62019
  for (const event of events) {
61704
62020
  aggregator.processFollowEvent(event);
61705
62021
  }
61706
62022
  const metrics = aggregator.getMetrics();
61707
- const transcript = (0, import_sidekick_shared15.parseTranscript)(sessionPath);
61708
- const sessionFileName = path7.basename(sessionPath);
62023
+ const transcript = (0, import_sidekick_shared16.parseTranscript)(sessionPath);
62024
+ const sessionFileName = path6.basename(sessionPath);
61709
62025
  const reportOptions = {
61710
62026
  sessionFileName,
61711
62027
  includeThinking: !noThinking,
61712
62028
  includeToolDetail: true,
61713
62029
  theme
61714
62030
  };
61715
- const html = (0, import_sidekick_shared15.generateHtmlReport)(metrics, transcript, reportOptions);
61716
- const outFile = outputPath || path7.join(os5.tmpdir(), `sidekick-report-${Date.now()}.html`);
61717
- fs9.writeFileSync(outFile, html, "utf-8");
62031
+ const html = (0, import_sidekick_shared16.generateHtmlReport)(metrics, transcript, reportOptions);
62032
+ const outFile = outputPath || path6.join(os4.tmpdir(), `sidekick-report-${Date.now()}.html`);
62033
+ fs8.writeFileSync(outFile, html, "utf-8");
61718
62034
  process.stderr.write(`Report written to: ${outFile}
61719
62035
  `);
61720
62036
  if (!noOpen) {
61721
- (0, import_sidekick_shared15.openInBrowser)(outFile);
62037
+ (0, import_sidekick_shared16.openInBrowser)(outFile);
61722
62038
  }
61723
62039
  } finally {
61724
62040
  try {
@@ -61727,11 +62043,11 @@ async function reportAction(_opts, cmd) {
61727
62043
  }
61728
62044
  }
61729
62045
  }
61730
- var import_sidekick_shared15;
62046
+ var import_sidekick_shared16;
61731
62047
  var init_report = __esm({
61732
62048
  "src/commands/report.ts"() {
61733
62049
  "use strict";
61734
- import_sidekick_shared15 = __toESM(require_dist(), 1);
62050
+ import_sidekick_shared16 = __toESM(require_dist(), 1);
61735
62051
  init_cli();
61736
62052
  }
61737
62053
  });
@@ -61776,12 +62092,12 @@ async function searchAction(_opts, cmd) {
61776
62092
  const projectPath = globalOpts.project || void 0;
61777
62093
  let projectSlug;
61778
62094
  if (projectPath) {
61779
- const path8 = await import("path");
61780
- const resolved = path8.resolve(projectPath);
62095
+ const path7 = await import("path");
62096
+ const resolved = path7.resolve(projectPath);
61781
62097
  const { encodeWorkspacePath } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
61782
62098
  projectSlug = encodeWorkspacePath(resolved);
61783
62099
  }
61784
- const results = await (0, import_sidekick_shared16.searchSessions)(provider, query.trim(), {
62100
+ const results = await (0, import_sidekick_shared17.searchSessions)(provider, query.trim(), {
61785
62101
  projectSlug,
61786
62102
  maxResults: limit
61787
62103
  });
@@ -61817,12 +62133,12 @@ async function searchAction(_opts, cmd) {
61817
62133
  }
61818
62134
  }
61819
62135
  }
61820
- var import_sidekick_shared16;
62136
+ var import_sidekick_shared17;
61821
62137
  var init_search = __esm({
61822
62138
  "src/commands/search.ts"() {
61823
62139
  "use strict";
61824
62140
  init_source();
61825
- import_sidekick_shared16 = __toESM(require_dist(), 1);
62141
+ import_sidekick_shared17 = __toESM(require_dist(), 1);
61826
62142
  init_cli();
61827
62143
  }
61828
62144
  });
@@ -61881,12 +62197,12 @@ async function tasksAction(_opts, cmd) {
61881
62197
  const jsonOutput = !!globalOpts.json;
61882
62198
  const statusFilter = opts.status || "all";
61883
62199
  try {
61884
- const rawSlug = (0, import_sidekick_shared17.getProjectSlugRaw)(workspacePath);
61885
- const resolvedSlug = (0, import_sidekick_shared17.getProjectSlug)(workspacePath);
62200
+ const rawSlug = (0, import_sidekick_shared18.getProjectSlugRaw)(workspacePath);
62201
+ const resolvedSlug = (0, import_sidekick_shared18.getProjectSlug)(workspacePath);
61886
62202
  const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
61887
62203
  let tasks = [];
61888
62204
  for (const slug of slugs) {
61889
- tasks = await (0, import_sidekick_shared17.readTasks)(slug, { status: statusFilter });
62205
+ tasks = await (0, import_sidekick_shared18.readTasks)(slug, { status: statusFilter });
61890
62206
  if (tasks.length > 0) break;
61891
62207
  }
61892
62208
  if (jsonOutput) {
@@ -61901,12 +62217,12 @@ async function tasksAction(_opts, cmd) {
61901
62217
  process.exit(1);
61902
62218
  }
61903
62219
  }
61904
- var import_sidekick_shared17, STATUS_COLORS, STATUS_ICONS2;
62220
+ var import_sidekick_shared18, STATUS_COLORS, STATUS_ICONS2;
61905
62221
  var init_tasks = __esm({
61906
62222
  "src/commands/tasks.ts"() {
61907
62223
  "use strict";
61908
62224
  init_source();
61909
- import_sidekick_shared17 = __toESM(require_dist(), 1);
62225
+ import_sidekick_shared18 = __toESM(require_dist(), 1);
61910
62226
  STATUS_COLORS = {
61911
62227
  pending: source_default.yellow,
61912
62228
  in_progress: source_default.blue,
@@ -61972,12 +62288,12 @@ async function decisionsAction(_opts, cmd) {
61972
62288
  const search = opts.search;
61973
62289
  const limit = opts.limit ? parseInt(opts.limit, 10) : void 0;
61974
62290
  try {
61975
- const rawSlug = (0, import_sidekick_shared18.getProjectSlugRaw)(workspacePath);
61976
- const resolvedSlug = (0, import_sidekick_shared18.getProjectSlug)(workspacePath);
62291
+ const rawSlug = (0, import_sidekick_shared19.getProjectSlugRaw)(workspacePath);
62292
+ const resolvedSlug = (0, import_sidekick_shared19.getProjectSlug)(workspacePath);
61977
62293
  const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
61978
62294
  let decisions = [];
61979
62295
  for (const slug of slugs) {
61980
- decisions = await (0, import_sidekick_shared18.readDecisions)(slug, { search, limit });
62296
+ decisions = await (0, import_sidekick_shared19.readDecisions)(slug, { search, limit });
61981
62297
  if (decisions.length > 0) break;
61982
62298
  }
61983
62299
  if (jsonOutput) {
@@ -61992,12 +62308,12 @@ async function decisionsAction(_opts, cmd) {
61992
62308
  process.exit(1);
61993
62309
  }
61994
62310
  }
61995
- var import_sidekick_shared18, SOURCE_LABELS;
62311
+ var import_sidekick_shared19, SOURCE_LABELS;
61996
62312
  var init_decisions = __esm({
61997
62313
  "src/commands/decisions.ts"() {
61998
62314
  "use strict";
61999
62315
  init_source();
62000
- import_sidekick_shared18 = __toESM(require_dist(), 1);
62316
+ import_sidekick_shared19 = __toESM(require_dist(), 1);
62001
62317
  SOURCE_LABELS = {
62002
62318
  recovery_pattern: "recovery",
62003
62319
  plan_mode: "plan",
@@ -62059,12 +62375,12 @@ async function notesAction(_opts, cmd) {
62059
62375
  const type = opts.type;
62060
62376
  const status = opts.status;
62061
62377
  try {
62062
- const rawSlug = (0, import_sidekick_shared19.getProjectSlugRaw)(workspacePath);
62063
- const resolvedSlug = (0, import_sidekick_shared19.getProjectSlug)(workspacePath);
62378
+ const rawSlug = (0, import_sidekick_shared20.getProjectSlugRaw)(workspacePath);
62379
+ const resolvedSlug = (0, import_sidekick_shared20.getProjectSlug)(workspacePath);
62064
62380
  const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
62065
62381
  let notes = [];
62066
62382
  for (const slug of slugs) {
62067
- notes = await (0, import_sidekick_shared19.readNotes)(slug, { file, type, status });
62383
+ notes = await (0, import_sidekick_shared20.readNotes)(slug, { file, type, status });
62068
62384
  if (notes.length > 0) break;
62069
62385
  }
62070
62386
  if (jsonOutput) {
@@ -62079,12 +62395,12 @@ async function notesAction(_opts, cmd) {
62079
62395
  process.exit(1);
62080
62396
  }
62081
62397
  }
62082
- var import_sidekick_shared19, TYPE_COLORS, IMPORTANCE_COLORS;
62398
+ var import_sidekick_shared20, TYPE_COLORS, IMPORTANCE_COLORS;
62083
62399
  var init_notes = __esm({
62084
62400
  "src/commands/notes.ts"() {
62085
62401
  "use strict";
62086
62402
  init_source();
62087
- import_sidekick_shared19 = __toESM(require_dist(), 1);
62403
+ import_sidekick_shared20 = __toESM(require_dist(), 1);
62088
62404
  TYPE_COLORS = {
62089
62405
  gotcha: source_default.red,
62090
62406
  pattern: source_default.blue,
@@ -62182,7 +62498,7 @@ async function statsAction(_opts, cmd) {
62182
62498
  const globalOpts = cmd.parent.opts();
62183
62499
  const jsonOutput = !!globalOpts.json;
62184
62500
  try {
62185
- const history = await (0, import_sidekick_shared20.readHistory)();
62501
+ const history = await (0, import_sidekick_shared21.readHistory)();
62186
62502
  if (!history) {
62187
62503
  if (jsonOutput) {
62188
62504
  process.stdout.write(JSON.stringify(null) + "\n");
@@ -62204,12 +62520,12 @@ async function statsAction(_opts, cmd) {
62204
62520
  process.exit(1);
62205
62521
  }
62206
62522
  }
62207
- var import_sidekick_shared20;
62523
+ var import_sidekick_shared21;
62208
62524
  var init_stats = __esm({
62209
62525
  "src/commands/stats.ts"() {
62210
62526
  "use strict";
62211
62527
  init_source();
62212
- import_sidekick_shared20 = __toESM(require_dist(), 1);
62528
+ import_sidekick_shared21 = __toESM(require_dist(), 1);
62213
62529
  }
62214
62530
  });
62215
62531
 
@@ -62309,12 +62625,12 @@ async function handoffAction(_opts, cmd) {
62309
62625
  const workspacePath = globalOpts.project || process.cwd();
62310
62626
  const jsonOutput = !!globalOpts.json;
62311
62627
  try {
62312
- const rawSlug = (0, import_sidekick_shared21.getProjectSlugRaw)(workspacePath);
62313
- const resolvedSlug = (0, import_sidekick_shared21.getProjectSlug)(workspacePath);
62628
+ const rawSlug = (0, import_sidekick_shared22.getProjectSlugRaw)(workspacePath);
62629
+ const resolvedSlug = (0, import_sidekick_shared22.getProjectSlug)(workspacePath);
62314
62630
  const slugs = rawSlug !== resolvedSlug ? [rawSlug, resolvedSlug] : [rawSlug];
62315
62631
  let content = null;
62316
62632
  for (const slug of slugs) {
62317
- content = await (0, import_sidekick_shared21.readLatestHandoff)(slug);
62633
+ content = await (0, import_sidekick_shared22.readLatestHandoff)(slug);
62318
62634
  if (content) break;
62319
62635
  }
62320
62636
  if (!content) {
@@ -62339,37 +62655,37 @@ async function handoffAction(_opts, cmd) {
62339
62655
  process.exit(1);
62340
62656
  }
62341
62657
  }
62342
- var import_sidekick_shared21;
62658
+ var import_sidekick_shared22;
62343
62659
  var init_handoff = __esm({
62344
62660
  "src/commands/handoff.ts"() {
62345
62661
  "use strict";
62346
62662
  init_source();
62347
- import_sidekick_shared21 = __toESM(require_dist(), 1);
62663
+ import_sidekick_shared22 = __toESM(require_dist(), 1);
62348
62664
  }
62349
62665
  });
62350
62666
 
62351
62667
  // src/cli.ts
62352
62668
  function resolveProvider(opts) {
62353
62669
  const override = opts.provider && opts.provider !== "auto" ? opts.provider : void 0;
62354
- const id = override || (0, import_sidekick_shared22.detectProvider)(override);
62670
+ const id = override || (0, import_sidekick_shared23.detectProvider)(override);
62355
62671
  switch (id) {
62356
62672
  case "opencode":
62357
- return new import_sidekick_shared23.OpenCodeProvider();
62673
+ return new import_sidekick_shared24.OpenCodeProvider();
62358
62674
  case "codex":
62359
- return new import_sidekick_shared23.CodexProvider();
62675
+ return new import_sidekick_shared24.CodexProvider();
62360
62676
  case "claude-code":
62361
62677
  default:
62362
- return new import_sidekick_shared23.ClaudeCodeProvider();
62678
+ return new import_sidekick_shared24.ClaudeCodeProvider();
62363
62679
  }
62364
62680
  }
62365
- var import_sidekick_shared22, import_sidekick_shared23, program2, dashCmd, dumpCmd, ctxCmd, reportCmd, searchCmd, tasksCmd, decisionsCmd, notesCmd, statsCmd, quotaCmd, handoffCmd;
62681
+ var import_sidekick_shared23, import_sidekick_shared24, program2, dashCmd, dumpCmd, ctxCmd, reportCmd, searchCmd, tasksCmd, decisionsCmd, notesCmd, statsCmd, quotaCmd, handoffCmd;
62366
62682
  var init_cli = __esm({
62367
62683
  "src/cli.ts"() {
62368
62684
  init_esm();
62369
- import_sidekick_shared22 = __toESM(require_dist(), 1);
62370
62685
  import_sidekick_shared23 = __toESM(require_dist(), 1);
62686
+ import_sidekick_shared24 = __toESM(require_dist(), 1);
62371
62687
  program2 = new Command();
62372
- program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.13.1").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
62688
+ program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.13.3").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
62373
62689
  dashCmd = new Command("dashboard").description("Full-screen TUI dashboard with live session metrics").option("--session <id>", "Follow a specific session (default: most recent)").option("--replay", "Replay existing events before streaming new ones").action(async (_opts, cmd) => {
62374
62690
  const { dashboardAction: dashboardAction2 } = await init_dashboard().then(() => dashboard_exports);
62375
62691
  return dashboardAction2(_opts, cmd);