sidekick-agent-hub 0.17.0 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sidekick-cli.mjs +869 -439
- package/package.json +1 -1
package/dist/sidekick-cli.mjs
CHANGED
|
@@ -1157,7 +1157,7 @@ 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
|
|
1160
|
+
var path8 = __require("node:path");
|
|
1161
1161
|
var fs9 = __require("node:fs");
|
|
1162
1162
|
var process14 = __require("node:process");
|
|
1163
1163
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
@@ -2157,9 +2157,9 @@ 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 =
|
|
2160
|
+
const localBin = path8.resolve(baseDir, baseName);
|
|
2161
2161
|
if (fs9.existsSync(localBin)) return localBin;
|
|
2162
|
-
if (sourceExt.includes(
|
|
2162
|
+
if (sourceExt.includes(path8.extname(baseName))) return void 0;
|
|
2163
2163
|
const foundExt = sourceExt.find(
|
|
2164
2164
|
(ext) => fs9.existsSync(`${localBin}${ext}`)
|
|
2165
2165
|
);
|
|
@@ -2177,17 +2177,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2177
2177
|
} catch {
|
|
2178
2178
|
resolvedScriptPath = this._scriptPath;
|
|
2179
2179
|
}
|
|
2180
|
-
executableDir =
|
|
2181
|
-
|
|
2180
|
+
executableDir = path8.resolve(
|
|
2181
|
+
path8.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 =
|
|
2188
|
+
const legacyName = path8.basename(
|
|
2189
2189
|
this._scriptPath,
|
|
2190
|
-
|
|
2190
|
+
path8.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(
|
|
2201
|
+
launchWithNode = sourceExt.includes(path8.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 =
|
|
3048
|
+
this._name = path8.basename(filename, path8.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(
|
|
3063
|
-
if (
|
|
3064
|
-
this._executableDir =
|
|
3062
|
+
executableDir(path9) {
|
|
3063
|
+
if (path9 === void 0) return this._executableDir;
|
|
3064
|
+
this._executableDir = path9;
|
|
3065
3065
|
return this;
|
|
3066
3066
|
}
|
|
3067
3067
|
/**
|
|
@@ -3412,7 +3412,7 @@ var require_historicalData = __commonJS({
|
|
|
3412
3412
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3413
3413
|
exports.HISTORICAL_DATA_SCHEMA_VERSION = void 0;
|
|
3414
3414
|
exports.createEmptyTokenTotals = createEmptyTokenTotals;
|
|
3415
|
-
exports.HISTORICAL_DATA_SCHEMA_VERSION =
|
|
3415
|
+
exports.HISTORICAL_DATA_SCHEMA_VERSION = 2;
|
|
3416
3416
|
function createEmptyTokenTotals() {
|
|
3417
3417
|
return {
|
|
3418
3418
|
inputTokens: 0,
|
|
@@ -3484,19 +3484,19 @@ var require_paths = __commonJS({
|
|
|
3484
3484
|
exports.getProjectSlug = getProjectSlug7;
|
|
3485
3485
|
exports.getProjectSlugRaw = getProjectSlugRaw7;
|
|
3486
3486
|
var fs9 = __importStar(__require("fs"));
|
|
3487
|
-
var
|
|
3488
|
-
var
|
|
3487
|
+
var path8 = __importStar(__require("path"));
|
|
3488
|
+
var os6 = __importStar(__require("os"));
|
|
3489
3489
|
function getConfigDir2() {
|
|
3490
3490
|
if (process.platform === "win32") {
|
|
3491
|
-
return
|
|
3491
|
+
return path8.join(process.env.APPDATA || os6.homedir(), "sidekick");
|
|
3492
3492
|
}
|
|
3493
|
-
return
|
|
3493
|
+
return path8.join(os6.homedir(), ".config", "sidekick");
|
|
3494
3494
|
}
|
|
3495
3495
|
function getProjectDataPath(slug, subdomain) {
|
|
3496
|
-
return
|
|
3496
|
+
return path8.join(getConfigDir2(), subdomain, `${slug}.json`);
|
|
3497
3497
|
}
|
|
3498
3498
|
function getGlobalDataPath(filename) {
|
|
3499
|
-
return
|
|
3499
|
+
return path8.join(getConfigDir2(), filename);
|
|
3500
3500
|
}
|
|
3501
3501
|
function encodeWorkspacePath(workspacePath) {
|
|
3502
3502
|
const normalized = workspacePath.replace(/\\/g, "/");
|
|
@@ -3508,13 +3508,13 @@ var require_paths = __commonJS({
|
|
|
3508
3508
|
try {
|
|
3509
3509
|
resolved = fs9.realpathSync(dir);
|
|
3510
3510
|
} catch {
|
|
3511
|
-
resolved =
|
|
3511
|
+
resolved = path8.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(
|
|
3517
|
+
return encodeWorkspacePath(path8.resolve(dir));
|
|
3518
3518
|
}
|
|
3519
3519
|
}
|
|
3520
3520
|
});
|
|
@@ -4077,8 +4077,8 @@ var require_plans = __commonJS({
|
|
|
4077
4077
|
exports.writePlans = writePlans;
|
|
4078
4078
|
exports.readClaudeCodePlanFiles = readClaudeCodePlanFiles2;
|
|
4079
4079
|
var fs9 = __importStar(__require("fs"));
|
|
4080
|
-
var
|
|
4081
|
-
var
|
|
4080
|
+
var path8 = __importStar(__require("path"));
|
|
4081
|
+
var os6 = __importStar(__require("os"));
|
|
4082
4082
|
var plan_1 = require_plan();
|
|
4083
4083
|
var paths_1 = require_paths();
|
|
4084
4084
|
var helpers_1 = require_helpers();
|
|
@@ -4196,11 +4196,11 @@ var require_plans = __commonJS({
|
|
|
4196
4196
|
await fs9.promises.writeFile(filePath, JSON.stringify(store, null, 2), "utf-8");
|
|
4197
4197
|
}
|
|
4198
4198
|
async function readClaudeCodePlanFiles2(workspacePath) {
|
|
4199
|
-
const claudePlansDir =
|
|
4200
|
-
const claudeProjectsDir =
|
|
4199
|
+
const claudePlansDir = path8.join(os6.homedir(), ".claude", "plans");
|
|
4200
|
+
const claudeProjectsDir = path8.join(os6.homedir(), ".claude", "projects");
|
|
4201
4201
|
const cwd2 = workspacePath || process.cwd();
|
|
4202
|
-
const encoded = (0, paths_1.encodeWorkspacePath)(
|
|
4203
|
-
const projectDir =
|
|
4202
|
+
const encoded = (0, paths_1.encodeWorkspacePath)(path8.resolve(cwd2));
|
|
4203
|
+
const projectDir = path8.join(claudeProjectsDir, encoded);
|
|
4204
4204
|
if (!fs9.existsSync(projectDir) || !fs9.existsSync(claudePlansDir)) {
|
|
4205
4205
|
return [];
|
|
4206
4206
|
}
|
|
@@ -4214,7 +4214,7 @@ var require_plans = __commonJS({
|
|
|
4214
4214
|
const SLUG_RE = /"slug":"([^"]+)"/;
|
|
4215
4215
|
await Promise.all(jsonlFiles.map(async (f) => {
|
|
4216
4216
|
try {
|
|
4217
|
-
const filePath =
|
|
4217
|
+
const filePath = path8.join(projectDir, f);
|
|
4218
4218
|
const handle = await fs9.promises.open(filePath, "r");
|
|
4219
4219
|
try {
|
|
4220
4220
|
const buf = Buffer.alloc(32768);
|
|
@@ -4237,7 +4237,7 @@ var require_plans = __commonJS({
|
|
|
4237
4237
|
return [];
|
|
4238
4238
|
const plans = [];
|
|
4239
4239
|
for (const slug of slugSet) {
|
|
4240
|
-
const planPath =
|
|
4240
|
+
const planPath = path8.join(claudePlansDir, `${slug}.md`);
|
|
4241
4241
|
try {
|
|
4242
4242
|
const stat = await fs9.promises.stat(planPath);
|
|
4243
4243
|
const content = await fs9.promises.readFile(planPath, "utf-8");
|
|
@@ -4324,13 +4324,13 @@ var require_accountRegistry = __commonJS({
|
|
|
4324
4324
|
exports.replaceSavedAccountProfiles = replaceSavedAccountProfiles;
|
|
4325
4325
|
exports.removeSavedAccountProfile = removeSavedAccountProfile;
|
|
4326
4326
|
var fs9 = __importStar(__require("fs"));
|
|
4327
|
-
var
|
|
4327
|
+
var path8 = __importStar(__require("path"));
|
|
4328
4328
|
var paths_1 = require_paths();
|
|
4329
4329
|
function getAccountsDir() {
|
|
4330
|
-
return
|
|
4330
|
+
return path8.join((0, paths_1.getConfigDir)(), "accounts");
|
|
4331
4331
|
}
|
|
4332
4332
|
function getRegistryPath() {
|
|
4333
|
-
return
|
|
4333
|
+
return path8.join(getAccountsDir(), "accounts.json");
|
|
4334
4334
|
}
|
|
4335
4335
|
function ensureAccountsDir() {
|
|
4336
4336
|
fs9.mkdirSync(getAccountsDir(), { recursive: true, mode: 448 });
|
|
@@ -4507,6 +4507,8 @@ var require_codexProfiles = __commonJS({
|
|
|
4507
4507
|
};
|
|
4508
4508
|
}();
|
|
4509
4509
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4510
|
+
exports.getSystemCodexHome = getSystemCodexHome;
|
|
4511
|
+
exports.getCodexMonitoringHomes = getCodexMonitoringHomes;
|
|
4510
4512
|
exports.getCodexProfilesDir = getCodexProfilesDir;
|
|
4511
4513
|
exports.getCodexProfileHome = getCodexProfileHome;
|
|
4512
4514
|
exports.listCodexAccounts = listCodexAccounts2;
|
|
@@ -4518,25 +4520,56 @@ var require_codexProfiles = __commonJS({
|
|
|
4518
4520
|
exports.switchToCodexAccount = switchToCodexAccount2;
|
|
4519
4521
|
exports.removeCodexAccount = removeCodexAccount2;
|
|
4520
4522
|
var fs9 = __importStar(__require("fs"));
|
|
4521
|
-
var
|
|
4522
|
-
var
|
|
4523
|
+
var os6 = __importStar(__require("os"));
|
|
4524
|
+
var path8 = __importStar(__require("path"));
|
|
4523
4525
|
var child_process_1 = __require("child_process");
|
|
4524
4526
|
var crypto_1 = __require("crypto");
|
|
4525
4527
|
var accountRegistry_1 = require_accountRegistry();
|
|
4528
|
+
function getDefaultSystemCodexHome() {
|
|
4529
|
+
return path8.join(os6.homedir(), ".codex");
|
|
4530
|
+
}
|
|
4531
|
+
function getExplicitCodexHome() {
|
|
4532
|
+
const explicitHome = process.env.CODEX_HOME?.trim();
|
|
4533
|
+
return explicitHome ? explicitHome : null;
|
|
4534
|
+
}
|
|
4535
|
+
function dedupePaths(paths) {
|
|
4536
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4537
|
+
const unique = [];
|
|
4538
|
+
for (const candidate of paths) {
|
|
4539
|
+
const normalized = path8.resolve(candidate);
|
|
4540
|
+
if (seen.has(normalized))
|
|
4541
|
+
continue;
|
|
4542
|
+
seen.add(normalized);
|
|
4543
|
+
unique.push(candidate);
|
|
4544
|
+
}
|
|
4545
|
+
return unique;
|
|
4546
|
+
}
|
|
4526
4547
|
function getSystemCodexHome() {
|
|
4527
|
-
return
|
|
4548
|
+
return getExplicitCodexHome() ?? getDefaultSystemCodexHome();
|
|
4549
|
+
}
|
|
4550
|
+
function getCodexMonitoringHomes() {
|
|
4551
|
+
const explicitHome = getExplicitCodexHome();
|
|
4552
|
+
if (explicitHome)
|
|
4553
|
+
return [explicitHome];
|
|
4554
|
+
const homes = [];
|
|
4555
|
+
const active = getActiveCodexAccount3();
|
|
4556
|
+
if (active) {
|
|
4557
|
+
homes.push(getCodexProfileHome(active.id));
|
|
4558
|
+
}
|
|
4559
|
+
homes.push(getDefaultSystemCodexHome());
|
|
4560
|
+
return dedupePaths(homes);
|
|
4528
4561
|
}
|
|
4529
4562
|
function getCodexProfilesDir() {
|
|
4530
|
-
return
|
|
4563
|
+
return path8.join((0, accountRegistry_1.getAccountsDir)(), "codex", "profiles");
|
|
4531
4564
|
}
|
|
4532
4565
|
function getCodexProfileDir(profileId) {
|
|
4533
|
-
return
|
|
4566
|
+
return path8.join(getCodexProfilesDir(), profileId);
|
|
4534
4567
|
}
|
|
4535
4568
|
function getCodexProfileHome(profileId) {
|
|
4536
|
-
return
|
|
4569
|
+
return path8.join(getCodexProfileDir(profileId), "codex-home");
|
|
4537
4570
|
}
|
|
4538
4571
|
function getCodexProfileStatePath(profileId) {
|
|
4539
|
-
return
|
|
4572
|
+
return path8.join(getCodexProfileDir(profileId), "profile.json");
|
|
4540
4573
|
}
|
|
4541
4574
|
function ensureCodexProfileDirs(profileId) {
|
|
4542
4575
|
fs9.mkdirSync(getCodexProfileHome(profileId), { recursive: true, mode: 448 });
|
|
@@ -4562,16 +4595,16 @@ var require_codexProfiles = __commonJS({
|
|
|
4562
4595
|
function copyIfExists(source, destination) {
|
|
4563
4596
|
if (!fs9.existsSync(source))
|
|
4564
4597
|
return false;
|
|
4565
|
-
fs9.mkdirSync(
|
|
4598
|
+
fs9.mkdirSync(path8.dirname(destination), { recursive: true, mode: 448 });
|
|
4566
4599
|
fs9.copyFileSync(source, destination);
|
|
4567
4600
|
return true;
|
|
4568
4601
|
}
|
|
4569
4602
|
function copySourceCodexConfig(sourceHome, targetHome) {
|
|
4570
|
-
copyIfExists(
|
|
4603
|
+
copyIfExists(path8.join(sourceHome, "config.toml"), path8.join(targetHome, "config.toml"));
|
|
4571
4604
|
}
|
|
4572
4605
|
function importCurrentCodexAuth(sourceHome, targetHome) {
|
|
4573
|
-
const authCopied = copyIfExists(
|
|
4574
|
-
const legacyCredsCopied = copyIfExists(
|
|
4606
|
+
const authCopied = copyIfExists(path8.join(sourceHome, "auth.json"), path8.join(targetHome, "auth.json"));
|
|
4607
|
+
const legacyCredsCopied = copyIfExists(path8.join(sourceHome, ".credentials.json"), path8.join(targetHome, ".credentials.json"));
|
|
4575
4608
|
return authCopied || legacyCredsCopied;
|
|
4576
4609
|
}
|
|
4577
4610
|
function parseJwtPayload(jwt) {
|
|
@@ -4586,7 +4619,7 @@ var require_codexProfiles = __commonJS({
|
|
|
4586
4619
|
}
|
|
4587
4620
|
}
|
|
4588
4621
|
function readMetadataFromAuthJson(codexHome) {
|
|
4589
|
-
const authPath =
|
|
4622
|
+
const authPath = path8.join(codexHome, "auth.json");
|
|
4590
4623
|
if (!fs9.existsSync(authPath))
|
|
4591
4624
|
return {};
|
|
4592
4625
|
try {
|
|
@@ -4610,7 +4643,7 @@ var require_codexProfiles = __commonJS({
|
|
|
4610
4643
|
}
|
|
4611
4644
|
}
|
|
4612
4645
|
function readMetadataFromLegacyCredentials(codexHome) {
|
|
4613
|
-
const legacyPath =
|
|
4646
|
+
const legacyPath = path8.join(codexHome, ".credentials.json");
|
|
4614
4647
|
if (!fs9.existsSync(legacyPath))
|
|
4615
4648
|
return {};
|
|
4616
4649
|
try {
|
|
@@ -4661,7 +4694,7 @@ var require_codexProfiles = __commonJS({
|
|
|
4661
4694
|
return {};
|
|
4662
4695
|
}
|
|
4663
4696
|
function isCodexProfileAuthenticated(codexHome) {
|
|
4664
|
-
if (fs9.existsSync(
|
|
4697
|
+
if (fs9.existsSync(path8.join(codexHome, "auth.json")) || fs9.existsSync(path8.join(codexHome, ".credentials.json"))) {
|
|
4665
4698
|
return true;
|
|
4666
4699
|
}
|
|
4667
4700
|
return getCodexLoginStatus(codexHome).loggedIn;
|
|
@@ -4815,22 +4848,22 @@ var require_detect = __commonJS({
|
|
|
4815
4848
|
exports.getAllDetectedProviders = getAllDetectedProviders2;
|
|
4816
4849
|
exports.detectProvider = detectProvider2;
|
|
4817
4850
|
var fs9 = __importStar(__require("fs"));
|
|
4818
|
-
var
|
|
4819
|
-
var
|
|
4851
|
+
var os6 = __importStar(__require("os"));
|
|
4852
|
+
var path8 = __importStar(__require("path"));
|
|
4820
4853
|
var codexProfiles_1 = require_codexProfiles();
|
|
4821
4854
|
function getOpenCodeDataDir() {
|
|
4822
4855
|
const xdg = process.env.XDG_DATA_HOME;
|
|
4823
4856
|
if (xdg)
|
|
4824
|
-
return
|
|
4857
|
+
return path8.join(xdg, "opencode");
|
|
4825
4858
|
if (process.platform === "darwin")
|
|
4826
|
-
return
|
|
4859
|
+
return path8.join(os6.homedir(), "Library", "Application Support", "opencode");
|
|
4827
4860
|
if (process.platform === "win32") {
|
|
4828
|
-
return
|
|
4861
|
+
return path8.join(process.env.LOCALAPPDATA || process.env.APPDATA || path8.join(os6.homedir(), "AppData", "Local"), "opencode");
|
|
4829
4862
|
}
|
|
4830
|
-
return
|
|
4863
|
+
return path8.join(os6.homedir(), ".local", "share", "opencode");
|
|
4831
4864
|
}
|
|
4832
|
-
function
|
|
4833
|
-
return (0, codexProfiles_1.
|
|
4865
|
+
function getCodexHomes() {
|
|
4866
|
+
return (0, codexProfiles_1.getCodexMonitoringHomes)();
|
|
4834
4867
|
}
|
|
4835
4868
|
function getMostRecentMtime(dir) {
|
|
4836
4869
|
try {
|
|
@@ -4840,7 +4873,7 @@ var require_detect = __commonJS({
|
|
|
4840
4873
|
const entries = fs9.readdirSync(dir);
|
|
4841
4874
|
for (const entry of entries) {
|
|
4842
4875
|
try {
|
|
4843
|
-
const stats = fs9.statSync(
|
|
4876
|
+
const stats = fs9.statSync(path8.join(dir, entry));
|
|
4844
4877
|
if (stats.mtime.getTime() > latest) {
|
|
4845
4878
|
latest = stats.mtime.getTime();
|
|
4846
4879
|
}
|
|
@@ -4854,46 +4887,51 @@ var require_detect = __commonJS({
|
|
|
4854
4887
|
}
|
|
4855
4888
|
function getOpenCodeActivityMtime() {
|
|
4856
4889
|
const dataDir = getOpenCodeDataDir();
|
|
4857
|
-
const dbPath =
|
|
4890
|
+
const dbPath = path8.join(dataDir, "opencode.db");
|
|
4858
4891
|
try {
|
|
4859
4892
|
const dbMtime = fs9.statSync(dbPath).mtime.getTime();
|
|
4860
4893
|
if (dbMtime > 0)
|
|
4861
4894
|
return dbMtime;
|
|
4862
4895
|
} catch {
|
|
4863
4896
|
}
|
|
4864
|
-
const storageDir =
|
|
4865
|
-
const sessionMtime = getMostRecentMtime(
|
|
4866
|
-
const messageMtime = getMostRecentMtime(
|
|
4867
|
-
const partMtime = getMostRecentMtime(
|
|
4897
|
+
const storageDir = path8.join(dataDir, "storage");
|
|
4898
|
+
const sessionMtime = getMostRecentMtime(path8.join(storageDir, "session"));
|
|
4899
|
+
const messageMtime = getMostRecentMtime(path8.join(storageDir, "message"));
|
|
4900
|
+
const partMtime = getMostRecentMtime(path8.join(storageDir, "part"));
|
|
4868
4901
|
return Math.max(sessionMtime, messageMtime, partMtime);
|
|
4869
4902
|
}
|
|
4870
4903
|
function getCodexActivityMtime() {
|
|
4871
|
-
|
|
4872
|
-
const
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4904
|
+
let latest = 0;
|
|
4905
|
+
for (const codexHome of getCodexHomes()) {
|
|
4906
|
+
const dbPath = path8.join(codexHome, "state.sqlite");
|
|
4907
|
+
try {
|
|
4908
|
+
const dbMtime = fs9.statSync(dbPath).mtime.getTime();
|
|
4909
|
+
if (dbMtime > latest)
|
|
4910
|
+
latest = dbMtime;
|
|
4911
|
+
} catch {
|
|
4912
|
+
}
|
|
4913
|
+
const sessionsMtime = getMostRecentMtime(path8.join(codexHome, "sessions"));
|
|
4914
|
+
if (sessionsMtime > latest)
|
|
4915
|
+
latest = sessionsMtime;
|
|
4878
4916
|
}
|
|
4879
|
-
return
|
|
4917
|
+
return latest;
|
|
4880
4918
|
}
|
|
4881
4919
|
function getProviderPaths() {
|
|
4882
|
-
const claudeBase =
|
|
4920
|
+
const claudeBase = path8.join(os6.homedir(), ".claude", "projects");
|
|
4883
4921
|
const openCodeDataDir = getOpenCodeDataDir();
|
|
4922
|
+
const codexHomes = getCodexHomes();
|
|
4884
4923
|
return {
|
|
4885
4924
|
claudeBase,
|
|
4886
|
-
openCodeDbPath:
|
|
4887
|
-
openCodeStorageDir:
|
|
4888
|
-
|
|
4889
|
-
codexDbPath: path7.join(getCodexHome(), "state.sqlite")
|
|
4925
|
+
openCodeDbPath: path8.join(openCodeDataDir, "opencode.db"),
|
|
4926
|
+
openCodeStorageDir: path8.join(openCodeDataDir, "storage"),
|
|
4927
|
+
codexHomes
|
|
4890
4928
|
};
|
|
4891
4929
|
}
|
|
4892
4930
|
function getAllDetectedProviders2() {
|
|
4893
|
-
const { claudeBase, openCodeDbPath, openCodeStorageDir,
|
|
4931
|
+
const { claudeBase, openCodeDbPath, openCodeStorageDir, codexHomes } = getProviderPaths();
|
|
4894
4932
|
const hasClaude = fs9.existsSync(claudeBase);
|
|
4895
4933
|
const hasOpenCode = fs9.existsSync(openCodeStorageDir) || fs9.existsSync(openCodeDbPath);
|
|
4896
|
-
const hasCodex = fs9.existsSync(
|
|
4934
|
+
const hasCodex = codexHomes.some((codexHome) => fs9.existsSync(path8.join(codexHome, "sessions")) || fs9.existsSync(path8.join(codexHome, "state.sqlite")));
|
|
4897
4935
|
const available = [];
|
|
4898
4936
|
if (hasClaude)
|
|
4899
4937
|
available.push({ id: "claude-code", mtime: getMostRecentMtime(claudeBase) });
|
|
@@ -4907,10 +4945,10 @@ var require_detect = __commonJS({
|
|
|
4907
4945
|
function detectProvider2(override) {
|
|
4908
4946
|
if (override && override !== "auto")
|
|
4909
4947
|
return override;
|
|
4910
|
-
const { claudeBase, openCodeDbPath, openCodeStorageDir,
|
|
4948
|
+
const { claudeBase, openCodeDbPath, openCodeStorageDir, codexHomes } = getProviderPaths();
|
|
4911
4949
|
const hasClaude = fs9.existsSync(claudeBase);
|
|
4912
4950
|
const hasOpenCode = fs9.existsSync(openCodeStorageDir) || fs9.existsSync(openCodeDbPath);
|
|
4913
|
-
const hasCodex = fs9.existsSync(
|
|
4951
|
+
const hasCodex = codexHomes.some((codexHome) => fs9.existsSync(path8.join(codexHome, "sessions")) || fs9.existsSync(path8.join(codexHome, "state.sqlite")));
|
|
4914
4952
|
const available = [];
|
|
4915
4953
|
if (hasClaude) {
|
|
4916
4954
|
available.push({ id: "claude-code", mtime: getMostRecentMtime(claudeBase) });
|
|
@@ -5055,26 +5093,26 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5055
5093
|
exports.discoverWorktreeSiblings = discoverWorktreeSiblings;
|
|
5056
5094
|
exports.findAllSessionsWithWorktrees = findAllSessionsWithWorktrees;
|
|
5057
5095
|
var fs9 = __importStar(__require("fs"));
|
|
5058
|
-
var
|
|
5059
|
-
var
|
|
5096
|
+
var path8 = __importStar(__require("path"));
|
|
5097
|
+
var os6 = __importStar(__require("os"));
|
|
5060
5098
|
function encodeWorkspacePath(workspacePath) {
|
|
5061
5099
|
const normalized = workspacePath.replace(/\\/g, "/");
|
|
5062
5100
|
return normalized.replace(/[:/_]/g, "-");
|
|
5063
5101
|
}
|
|
5064
5102
|
function getSessionDirectory(workspacePath) {
|
|
5065
5103
|
const encoded = encodeWorkspacePath(workspacePath);
|
|
5066
|
-
return
|
|
5104
|
+
return path8.join(os6.homedir(), ".claude", "projects", encoded);
|
|
5067
5105
|
}
|
|
5068
5106
|
var ACTIVE_SESSION_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
5069
5107
|
function findSubdirectorySessionDirs(workspacePath) {
|
|
5070
|
-
const projectsDir =
|
|
5108
|
+
const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
|
|
5071
5109
|
try {
|
|
5072
5110
|
if (!fs9.existsSync(projectsDir)) {
|
|
5073
5111
|
return [];
|
|
5074
5112
|
}
|
|
5075
5113
|
const encodedPrefix = encodeWorkspacePath(workspacePath).toLowerCase();
|
|
5076
5114
|
const allDirs = fs9.readdirSync(projectsDir).filter((name) => {
|
|
5077
|
-
const fullPath =
|
|
5115
|
+
const fullPath = path8.join(projectsDir, name);
|
|
5078
5116
|
try {
|
|
5079
5117
|
return fs9.statSync(fullPath).isDirectory();
|
|
5080
5118
|
} catch {
|
|
@@ -5085,7 +5123,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5085
5123
|
for (const dir of allDirs) {
|
|
5086
5124
|
const dirLower = dir.toLowerCase();
|
|
5087
5125
|
if (dirLower.startsWith(encodedPrefix + "-")) {
|
|
5088
|
-
matches.push(
|
|
5126
|
+
matches.push(path8.join(projectsDir, dir));
|
|
5089
5127
|
}
|
|
5090
5128
|
}
|
|
5091
5129
|
return matches;
|
|
@@ -5101,7 +5139,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5101
5139
|
const files = fs9.readdirSync(dir).filter((file) => file.endsWith(".jsonl"));
|
|
5102
5140
|
for (const file of files) {
|
|
5103
5141
|
try {
|
|
5104
|
-
const fullPath =
|
|
5142
|
+
const fullPath = path8.join(dir, file);
|
|
5105
5143
|
const stats = fs9.statSync(fullPath);
|
|
5106
5144
|
if (stats.size > 0 && stats.mtime.getTime() > mostRecentMtime) {
|
|
5107
5145
|
mostRecentMtime = stats.mtime.getTime();
|
|
@@ -5116,7 +5154,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5116
5154
|
return mostRecentDir;
|
|
5117
5155
|
}
|
|
5118
5156
|
function discoverSessionDirectory(workspacePath) {
|
|
5119
|
-
const projectsDir =
|
|
5157
|
+
const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
|
|
5120
5158
|
const computedDir = getSessionDirectory(workspacePath);
|
|
5121
5159
|
if (fs9.existsSync(computedDir)) {
|
|
5122
5160
|
return computedDir;
|
|
@@ -5131,7 +5169,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5131
5169
|
try {
|
|
5132
5170
|
if (fs9.existsSync(projectsDir)) {
|
|
5133
5171
|
const existingDirs = fs9.readdirSync(projectsDir).filter((name) => {
|
|
5134
|
-
const fullPath =
|
|
5172
|
+
const fullPath = path8.join(projectsDir, name);
|
|
5135
5173
|
try {
|
|
5136
5174
|
return fs9.statSync(fullPath).isDirectory();
|
|
5137
5175
|
} catch {
|
|
@@ -5141,35 +5179,35 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5141
5179
|
const normalizedWorkspace = workspacePath.replace(/\\/g, "/").replace(/:/g, "-").replace(/_/g, "-").replace(/\//g, "-").toLowerCase();
|
|
5142
5180
|
for (const dir of existingDirs) {
|
|
5143
5181
|
if (dir.toLowerCase() === normalizedWorkspace) {
|
|
5144
|
-
return
|
|
5182
|
+
return path8.join(projectsDir, dir);
|
|
5145
5183
|
}
|
|
5146
5184
|
}
|
|
5147
|
-
const workspaceBasename =
|
|
5185
|
+
const workspaceBasename = path8.basename(workspacePath).replace(/_/g, "-").toLowerCase();
|
|
5148
5186
|
for (const dir of existingDirs) {
|
|
5149
5187
|
const dirLower = dir.toLowerCase();
|
|
5150
5188
|
if (dirLower.endsWith("-" + workspaceBasename) || dirLower === workspaceBasename) {
|
|
5151
|
-
return
|
|
5189
|
+
return path8.join(projectsDir, dir);
|
|
5152
5190
|
}
|
|
5153
5191
|
}
|
|
5154
5192
|
}
|
|
5155
5193
|
} catch {
|
|
5156
5194
|
}
|
|
5157
5195
|
try {
|
|
5158
|
-
const claudeTempDir =
|
|
5196
|
+
const claudeTempDir = path8.join(os6.tmpdir(), "claude");
|
|
5159
5197
|
if (fs9.existsSync(claudeTempDir)) {
|
|
5160
5198
|
const tempDirs = fs9.readdirSync(claudeTempDir).filter((name) => {
|
|
5161
|
-
const fullPath =
|
|
5199
|
+
const fullPath = path8.join(claudeTempDir, name);
|
|
5162
5200
|
try {
|
|
5163
5201
|
return fs9.statSync(fullPath).isDirectory();
|
|
5164
5202
|
} catch {
|
|
5165
5203
|
return false;
|
|
5166
5204
|
}
|
|
5167
5205
|
});
|
|
5168
|
-
const workspaceBasename =
|
|
5206
|
+
const workspaceBasename = path8.basename(workspacePath).replace(/_/g, "-").toLowerCase();
|
|
5169
5207
|
for (const encodedDir of tempDirs) {
|
|
5170
5208
|
const encodedLower = encodedDir.toLowerCase();
|
|
5171
5209
|
if (encodedLower.endsWith("-" + workspaceBasename) || encodedLower === workspaceBasename) {
|
|
5172
|
-
const sessionDir =
|
|
5210
|
+
const sessionDir = path8.join(projectsDir, encodedDir);
|
|
5173
5211
|
if (fs9.existsSync(sessionDir)) {
|
|
5174
5212
|
return sessionDir;
|
|
5175
5213
|
}
|
|
@@ -5188,7 +5226,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5188
5226
|
}
|
|
5189
5227
|
const now = Date.now();
|
|
5190
5228
|
const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
|
|
5191
|
-
const fullPath =
|
|
5229
|
+
const fullPath = path8.join(sessionDir, file);
|
|
5192
5230
|
const stats = fs9.statSync(fullPath);
|
|
5193
5231
|
const mtime = stats.mtime.getTime();
|
|
5194
5232
|
return {
|
|
@@ -5221,7 +5259,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5221
5259
|
return [];
|
|
5222
5260
|
}
|
|
5223
5261
|
const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
|
|
5224
|
-
const fullPath =
|
|
5262
|
+
const fullPath = path8.join(sessionDir, file);
|
|
5225
5263
|
const stats = fs9.statSync(fullPath);
|
|
5226
5264
|
return {
|
|
5227
5265
|
path: fullPath,
|
|
@@ -5248,7 +5286,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5248
5286
|
return encoded.replace(/-/g, "/");
|
|
5249
5287
|
}
|
|
5250
5288
|
function getAllProjectFolders(workspacePath) {
|
|
5251
|
-
const projectsDir =
|
|
5289
|
+
const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
|
|
5252
5290
|
const folders = [];
|
|
5253
5291
|
try {
|
|
5254
5292
|
if (!fs9.existsSync(projectsDir)) {
|
|
@@ -5256,7 +5294,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5256
5294
|
}
|
|
5257
5295
|
const entries = fs9.readdirSync(projectsDir);
|
|
5258
5296
|
for (const entry of entries) {
|
|
5259
|
-
const fullPath =
|
|
5297
|
+
const fullPath = path8.join(projectsDir, entry);
|
|
5260
5298
|
try {
|
|
5261
5299
|
const stats = fs9.statSync(fullPath);
|
|
5262
5300
|
if (!stats.isDirectory()) {
|
|
@@ -5267,7 +5305,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5267
5305
|
let sessionCount = 0;
|
|
5268
5306
|
for (const sessionFile of sessionFiles) {
|
|
5269
5307
|
try {
|
|
5270
|
-
const sessionPath =
|
|
5308
|
+
const sessionPath = path8.join(fullPath, sessionFile);
|
|
5271
5309
|
const sessionStats = fs9.statSync(sessionPath);
|
|
5272
5310
|
if (sessionStats.size > 0) {
|
|
5273
5311
|
sessionCount++;
|
|
@@ -5319,7 +5357,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5319
5357
|
return [];
|
|
5320
5358
|
}
|
|
5321
5359
|
const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
|
|
5322
|
-
const fullPath =
|
|
5360
|
+
const fullPath = path8.join(sessionDir, file);
|
|
5323
5361
|
try {
|
|
5324
5362
|
const stats = fs9.statSync(fullPath);
|
|
5325
5363
|
return {
|
|
@@ -5337,7 +5375,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5337
5375
|
}
|
|
5338
5376
|
}
|
|
5339
5377
|
function resolveWorktreeMainRepo(workspacePath) {
|
|
5340
|
-
const gitPath =
|
|
5378
|
+
const gitPath = path8.join(workspacePath, ".git");
|
|
5341
5379
|
try {
|
|
5342
5380
|
const stat = fs9.statSync(gitPath);
|
|
5343
5381
|
if (stat.isDirectory()) {
|
|
@@ -5348,31 +5386,31 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5348
5386
|
if (!match)
|
|
5349
5387
|
return null;
|
|
5350
5388
|
const gitdir = match[1].trim();
|
|
5351
|
-
const resolvedGitdir =
|
|
5352
|
-
const worktreesDir =
|
|
5353
|
-
if (
|
|
5389
|
+
const resolvedGitdir = path8.isAbsolute(gitdir) ? gitdir : path8.resolve(workspacePath, gitdir);
|
|
5390
|
+
const worktreesDir = path8.dirname(resolvedGitdir);
|
|
5391
|
+
if (path8.basename(worktreesDir) !== "worktrees")
|
|
5354
5392
|
return null;
|
|
5355
|
-
const dotGit =
|
|
5356
|
-
if (
|
|
5393
|
+
const dotGit = path8.dirname(worktreesDir);
|
|
5394
|
+
if (path8.basename(dotGit) !== ".git")
|
|
5357
5395
|
return null;
|
|
5358
|
-
return
|
|
5396
|
+
return path8.dirname(dotGit);
|
|
5359
5397
|
} catch {
|
|
5360
5398
|
return null;
|
|
5361
5399
|
}
|
|
5362
5400
|
}
|
|
5363
5401
|
function discoverWorktreeSiblings(mainRepoPath) {
|
|
5364
|
-
const worktreesDir =
|
|
5402
|
+
const worktreesDir = path8.join(mainRepoPath, ".git", "worktrees");
|
|
5365
5403
|
const siblings = [];
|
|
5366
5404
|
try {
|
|
5367
5405
|
if (!fs9.existsSync(worktreesDir))
|
|
5368
5406
|
return siblings;
|
|
5369
5407
|
const entries = fs9.readdirSync(worktreesDir);
|
|
5370
5408
|
for (const entry of entries) {
|
|
5371
|
-
const gitdirFile =
|
|
5409
|
+
const gitdirFile = path8.join(worktreesDir, entry, "gitdir");
|
|
5372
5410
|
try {
|
|
5373
5411
|
const content = fs9.readFileSync(gitdirFile, "utf-8").trim();
|
|
5374
|
-
const worktreeGit =
|
|
5375
|
-
const worktreeDir =
|
|
5412
|
+
const worktreeGit = path8.isAbsolute(content) ? content : path8.resolve(worktreesDir, entry, content);
|
|
5413
|
+
const worktreeDir = path8.dirname(worktreeGit);
|
|
5376
5414
|
if (fs9.existsSync(worktreeDir)) {
|
|
5377
5415
|
siblings.push(worktreeDir);
|
|
5378
5416
|
}
|
|
@@ -5466,7 +5504,7 @@ var require_subagentScanner = __commonJS({
|
|
|
5466
5504
|
exports.handleTaskUpdate = handleTaskUpdate;
|
|
5467
5505
|
exports.extractTaskInfo = extractTaskInfo;
|
|
5468
5506
|
var fs9 = __importStar(__require("fs"));
|
|
5469
|
-
var
|
|
5507
|
+
var path8 = __importStar(__require("path"));
|
|
5470
5508
|
var AGENT_FILE_PATTERN = /^agent-(.+)\.jsonl$/;
|
|
5471
5509
|
var TASK_TOOLS = ["TaskCreate", "TaskUpdate", "TaskGet", "TaskList"];
|
|
5472
5510
|
function extractTaskIdFromResult(resultContent) {
|
|
@@ -5485,7 +5523,7 @@ var require_subagentScanner = __commonJS({
|
|
|
5485
5523
|
function scanSubagentDir(sessionDir, sessionId, logger) {
|
|
5486
5524
|
const log = logger || (() => {
|
|
5487
5525
|
});
|
|
5488
|
-
const subagentsDir =
|
|
5526
|
+
const subagentsDir = path8.join(sessionDir, sessionId, "subagents");
|
|
5489
5527
|
const results = [];
|
|
5490
5528
|
try {
|
|
5491
5529
|
if (!fs9.existsSync(subagentsDir)) {
|
|
@@ -5504,7 +5542,7 @@ var require_subagentScanner = __commonJS({
|
|
|
5504
5542
|
continue;
|
|
5505
5543
|
}
|
|
5506
5544
|
const agentId = match[1];
|
|
5507
|
-
const filePath =
|
|
5545
|
+
const filePath = path8.join(subagentsDir, file);
|
|
5508
5546
|
const agentStats = parseAgentFile(filePath, agentId, log);
|
|
5509
5547
|
if (agentStats) {
|
|
5510
5548
|
log(`[SubagentScanner] Agent ${agentId}: ${agentStats.toolCalls.length} tool calls`);
|
|
@@ -5714,8 +5752,10 @@ var require_modelContext = __commonJS({
|
|
|
5714
5752
|
exports.DEFAULT_CONTEXT_WINDOW = void 0;
|
|
5715
5753
|
exports.getModelContextWindowSize = getModelContextWindowSize2;
|
|
5716
5754
|
var MODEL_CONTEXT_SIZES = {
|
|
5717
|
-
// Claude 4.6
|
|
5755
|
+
// Claude — native 1M context (Opus 4.6+, Sonnet 4.6+)
|
|
5756
|
+
"claude-opus-4-7": 1e6,
|
|
5718
5757
|
"claude-opus-4-6": 1e6,
|
|
5758
|
+
"claude-sonnet-4-7": 1e6,
|
|
5719
5759
|
"claude-sonnet-4-6": 1e6,
|
|
5720
5760
|
// Claude 4 family
|
|
5721
5761
|
"claude-opus-4": 2e5,
|
|
@@ -5731,7 +5771,11 @@ var require_modelContext = __commonJS({
|
|
|
5731
5771
|
"claude-3-haiku": 2e5,
|
|
5732
5772
|
// OpenAI GPT-4.1 series (1M context)
|
|
5733
5773
|
"gpt-4.1": 1048576,
|
|
5734
|
-
// OpenAI GPT-5 series
|
|
5774
|
+
// OpenAI GPT-5 series (keys sorted longest-first below; explicit entries
|
|
5775
|
+
// for every variant so prefix matching can't misclassify a new one)
|
|
5776
|
+
"gpt-5.4": 105e4,
|
|
5777
|
+
"gpt-5.3-codex-spark": 128e3,
|
|
5778
|
+
"gpt-5.3-codex": 4e5,
|
|
5735
5779
|
"gpt-5": 4e5,
|
|
5736
5780
|
// OpenAI reasoning
|
|
5737
5781
|
"o1": 2e5,
|
|
@@ -5751,11 +5795,14 @@ var require_modelContext = __commonJS({
|
|
|
5751
5795
|
function getModelContextWindowSize2(modelId) {
|
|
5752
5796
|
if (!modelId)
|
|
5753
5797
|
return exports.DEFAULT_CONTEXT_WINDOW;
|
|
5754
|
-
if (
|
|
5755
|
-
return
|
|
5798
|
+
if (/\[1m\]/i.test(modelId))
|
|
5799
|
+
return 1e6;
|
|
5800
|
+
const normalized = modelId.replace(/\[1m\]/gi, "");
|
|
5801
|
+
if (MODEL_CONTEXT_SIZES[normalized] !== void 0) {
|
|
5802
|
+
return MODEL_CONTEXT_SIZES[normalized];
|
|
5756
5803
|
}
|
|
5757
5804
|
for (const key of SORTED_KEYS) {
|
|
5758
|
-
if (
|
|
5805
|
+
if (normalized.startsWith(key)) {
|
|
5759
5806
|
return MODEL_CONTEXT_SIZES[key];
|
|
5760
5807
|
}
|
|
5761
5808
|
}
|
|
@@ -5808,8 +5855,8 @@ var require_claudeCode = __commonJS({
|
|
|
5808
5855
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5809
5856
|
exports.ClaudeCodeProvider = void 0;
|
|
5810
5857
|
var fs9 = __importStar(__require("fs"));
|
|
5811
|
-
var
|
|
5812
|
-
var
|
|
5858
|
+
var os6 = __importStar(__require("os"));
|
|
5859
|
+
var path8 = __importStar(__require("path"));
|
|
5813
5860
|
var jsonl_1 = require_jsonl();
|
|
5814
5861
|
var sessionPathResolver_1 = require_sessionPathResolver();
|
|
5815
5862
|
var subagentScanner_1 = require_subagentScanner();
|
|
@@ -5946,7 +5993,7 @@ var require_claudeCode = __commonJS({
|
|
|
5946
5993
|
return filename.endsWith(".jsonl");
|
|
5947
5994
|
}
|
|
5948
5995
|
getSessionId(sessionPath) {
|
|
5949
|
-
return
|
|
5996
|
+
return path8.basename(sessionPath, ".jsonl");
|
|
5950
5997
|
}
|
|
5951
5998
|
encodeWorkspacePath(workspacePath) {
|
|
5952
5999
|
return (0, sessionPathResolver_1.encodeWorkspacePath)(workspacePath);
|
|
@@ -6011,7 +6058,7 @@ var require_claudeCode = __commonJS({
|
|
|
6011
6058
|
try {
|
|
6012
6059
|
const content = fs9.readFileSync(sessionPath, "utf8");
|
|
6013
6060
|
const lines = content.split("\n");
|
|
6014
|
-
const projectDir =
|
|
6061
|
+
const projectDir = path8.basename(path8.dirname(sessionPath));
|
|
6015
6062
|
const projectPath = (0, sessionPathResolver_1.decodeEncodedPath)(projectDir);
|
|
6016
6063
|
for (const line of lines) {
|
|
6017
6064
|
if (results.length >= maxResults)
|
|
@@ -6045,11 +6092,11 @@ var require_claudeCode = __commonJS({
|
|
|
6045
6092
|
return results;
|
|
6046
6093
|
}
|
|
6047
6094
|
getProjectsBaseDir() {
|
|
6048
|
-
return
|
|
6095
|
+
return path8.join(os6.homedir(), ".claude", "projects");
|
|
6049
6096
|
}
|
|
6050
6097
|
// --- Stats ---
|
|
6051
6098
|
readSessionStats(sessionPath) {
|
|
6052
|
-
const sessionId =
|
|
6099
|
+
const sessionId = path8.basename(sessionPath, ".jsonl");
|
|
6053
6100
|
let messageCount = 0;
|
|
6054
6101
|
let startTime = "";
|
|
6055
6102
|
let endTime = "";
|
|
@@ -6701,13 +6748,13 @@ var require_openCodeDatabase = __commonJS({
|
|
|
6701
6748
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6702
6749
|
exports.OpenCodeDatabase = void 0;
|
|
6703
6750
|
var fs9 = __importStar(__require("fs"));
|
|
6704
|
-
var
|
|
6751
|
+
var path8 = __importStar(__require("path"));
|
|
6705
6752
|
var child_process_1 = __require("child_process");
|
|
6706
6753
|
var OpenCodeDatabase = class {
|
|
6707
6754
|
dbPath;
|
|
6708
6755
|
runtimeStatus = null;
|
|
6709
6756
|
constructor(dataDir) {
|
|
6710
|
-
this.dbPath =
|
|
6757
|
+
this.dbPath = path8.join(dataDir, "opencode.db");
|
|
6711
6758
|
}
|
|
6712
6759
|
isAvailable() {
|
|
6713
6760
|
return fs9.existsSync(this.dbPath);
|
|
@@ -6926,7 +6973,7 @@ var require_openCodeDatabase = __commonJS({
|
|
|
6926
6973
|
try {
|
|
6927
6974
|
return fs9.realpathSync(input);
|
|
6928
6975
|
} catch {
|
|
6929
|
-
return
|
|
6976
|
+
return path8.resolve(input);
|
|
6930
6977
|
}
|
|
6931
6978
|
}
|
|
6932
6979
|
function parseStringArray(value) {
|
|
@@ -6950,8 +6997,8 @@ var require_openCodeDatabase = __commonJS({
|
|
|
6950
6997
|
const normalizedWorkspace = normalizeForCompare(workspacePath);
|
|
6951
6998
|
if (normalizedCandidate === normalizedWorkspace)
|
|
6952
6999
|
return 1e4 + normalizedCandidate.length;
|
|
6953
|
-
const candidatePrefix = normalizedCandidate.endsWith(
|
|
6954
|
-
const workspacePrefix = normalizedWorkspace.endsWith(
|
|
7000
|
+
const candidatePrefix = normalizedCandidate.endsWith(path8.sep) ? normalizedCandidate : normalizedCandidate + path8.sep;
|
|
7001
|
+
const workspacePrefix = normalizedWorkspace.endsWith(path8.sep) ? normalizedWorkspace : normalizedWorkspace + path8.sep;
|
|
6955
7002
|
if (normalizedWorkspace.startsWith(candidatePrefix))
|
|
6956
7003
|
return 5e3 + normalizedCandidate.length;
|
|
6957
7004
|
if (normalizedCandidate.startsWith(workspacePrefix))
|
|
@@ -7018,8 +7065,8 @@ var require_openCode = __commonJS({
|
|
|
7018
7065
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7019
7066
|
exports.OpenCodeProvider = void 0;
|
|
7020
7067
|
var fs9 = __importStar(__require("fs"));
|
|
7021
|
-
var
|
|
7022
|
-
var
|
|
7068
|
+
var os6 = __importStar(__require("os"));
|
|
7069
|
+
var path8 = __importStar(__require("path"));
|
|
7023
7070
|
var child_process_1 = __require("child_process");
|
|
7024
7071
|
var openCodeParser_1 = require_openCodeParser();
|
|
7025
7072
|
var openCodeDatabase_1 = require_openCodeDatabase();
|
|
@@ -7027,18 +7074,18 @@ var require_openCode = __commonJS({
|
|
|
7027
7074
|
function getOpenCodeDataDir() {
|
|
7028
7075
|
const xdg = process.env.XDG_DATA_HOME;
|
|
7029
7076
|
if (xdg) {
|
|
7030
|
-
return
|
|
7077
|
+
return path8.join(xdg, "opencode");
|
|
7031
7078
|
}
|
|
7032
7079
|
if (process.platform === "darwin") {
|
|
7033
|
-
return
|
|
7080
|
+
return path8.join(os6.homedir(), "Library", "Application Support", "opencode");
|
|
7034
7081
|
}
|
|
7035
7082
|
if (process.platform === "win32") {
|
|
7036
|
-
return
|
|
7083
|
+
return path8.join(process.env.LOCALAPPDATA || process.env.APPDATA || path8.join(os6.homedir(), "AppData", "Local"), "opencode");
|
|
7037
7084
|
}
|
|
7038
|
-
return
|
|
7085
|
+
return path8.join(os6.homedir(), ".local", "share", "opencode");
|
|
7039
7086
|
}
|
|
7040
7087
|
function getStorageDir() {
|
|
7041
|
-
return
|
|
7088
|
+
return path8.join(getOpenCodeDataDir(), "storage");
|
|
7042
7089
|
}
|
|
7043
7090
|
var GENERIC_AGENT_RE = /^(gpt-|claude-|o[1-9]|gemini|default|agent|worker)/i;
|
|
7044
7091
|
function isGenericAgentType(type) {
|
|
@@ -7069,18 +7116,18 @@ var require_openCode = __commonJS({
|
|
|
7069
7116
|
}
|
|
7070
7117
|
var DB_SESSION_PREFIX = "db-sessions";
|
|
7071
7118
|
function makeDbSessionPath(dataDir, projectId, sessionId) {
|
|
7072
|
-
return
|
|
7119
|
+
return path8.join(dataDir, DB_SESSION_PREFIX, projectId, `${sessionId}.json`);
|
|
7073
7120
|
}
|
|
7074
7121
|
function isDbSessionPath(sessionPath) {
|
|
7075
|
-
return sessionPath.includes(
|
|
7122
|
+
return sessionPath.includes(path8.sep + DB_SESSION_PREFIX + path8.sep);
|
|
7076
7123
|
}
|
|
7077
7124
|
function extractProjectIdFromDbPath(sessionPath) {
|
|
7078
|
-
const prefix =
|
|
7125
|
+
const prefix = path8.sep + DB_SESSION_PREFIX + path8.sep;
|
|
7079
7126
|
const idx = sessionPath.indexOf(prefix);
|
|
7080
7127
|
if (idx < 0)
|
|
7081
7128
|
return null;
|
|
7082
7129
|
const rest = sessionPath.substring(idx + prefix.length);
|
|
7083
|
-
const slashIdx = rest.indexOf(
|
|
7130
|
+
const slashIdx = rest.indexOf(path8.sep);
|
|
7084
7131
|
return slashIdx > 0 ? rest.substring(0, slashIdx) : null;
|
|
7085
7132
|
}
|
|
7086
7133
|
function extractRoleFromDbMessage(row) {
|
|
@@ -7118,25 +7165,25 @@ var require_openCode = __commonJS({
|
|
|
7118
7165
|
function resolveProjectIdFromFiles(workspacePath) {
|
|
7119
7166
|
const workspaceResolved = normalizePath(workspacePath);
|
|
7120
7167
|
try {
|
|
7121
|
-
const projectDir =
|
|
7168
|
+
const projectDir = path8.join(getStorageDir(), "project");
|
|
7122
7169
|
if (!fs9.existsSync(projectDir))
|
|
7123
7170
|
return resolveProjectIdFromGit(workspacePath);
|
|
7124
7171
|
const files = fs9.readdirSync(projectDir).filter((f) => f.endsWith(".json"));
|
|
7125
7172
|
const matches = [];
|
|
7126
7173
|
for (const file of files) {
|
|
7127
7174
|
try {
|
|
7128
|
-
const project = JSON.parse(fs9.readFileSync(
|
|
7175
|
+
const project = JSON.parse(fs9.readFileSync(path8.join(projectDir, file), "utf-8"));
|
|
7129
7176
|
if (project.path) {
|
|
7130
7177
|
const projectPath = normalizePath(project.path);
|
|
7131
7178
|
if (projectPath === workspaceResolved) {
|
|
7132
7179
|
matches.push({ id: project.id, path: projectPath });
|
|
7133
7180
|
continue;
|
|
7134
7181
|
}
|
|
7135
|
-
if (workspaceResolved.startsWith(projectPath +
|
|
7182
|
+
if (workspaceResolved.startsWith(projectPath + path8.sep)) {
|
|
7136
7183
|
matches.push({ id: project.id, path: projectPath });
|
|
7137
7184
|
continue;
|
|
7138
7185
|
}
|
|
7139
|
-
if (projectPath.startsWith(workspaceResolved +
|
|
7186
|
+
if (projectPath.startsWith(workspaceResolved + path8.sep)) {
|
|
7140
7187
|
matches.push({ id: project.id, path: projectPath });
|
|
7141
7188
|
}
|
|
7142
7189
|
}
|
|
@@ -7184,7 +7231,7 @@ var require_openCode = __commonJS({
|
|
|
7184
7231
|
try {
|
|
7185
7232
|
return fs9.realpathSync(input);
|
|
7186
7233
|
} catch {
|
|
7187
|
-
return
|
|
7234
|
+
return path8.resolve(input);
|
|
7188
7235
|
}
|
|
7189
7236
|
}
|
|
7190
7237
|
var OpenCodeFileReader = class {
|
|
@@ -7196,7 +7243,7 @@ var require_openCode = __commonJS({
|
|
|
7196
7243
|
this.storageBase = getStorageDir();
|
|
7197
7244
|
}
|
|
7198
7245
|
readNew() {
|
|
7199
|
-
const messageDir =
|
|
7246
|
+
const messageDir = path8.join(this.storageBase, "message", this.sessionId);
|
|
7200
7247
|
if (!fs9.existsSync(messageDir))
|
|
7201
7248
|
return [];
|
|
7202
7249
|
let messageFiles;
|
|
@@ -7207,8 +7254,8 @@ var require_openCode = __commonJS({
|
|
|
7207
7254
|
}
|
|
7208
7255
|
const newEvents = [];
|
|
7209
7256
|
for (const file of messageFiles) {
|
|
7210
|
-
const msgId =
|
|
7211
|
-
const messagePath =
|
|
7257
|
+
const msgId = path8.basename(file, ".json");
|
|
7258
|
+
const messagePath = path8.join(messageDir, file);
|
|
7212
7259
|
const message = readJsonSafe(messagePath);
|
|
7213
7260
|
if (!message)
|
|
7214
7261
|
continue;
|
|
@@ -7218,11 +7265,11 @@ var require_openCode = __commonJS({
|
|
|
7218
7265
|
} catch {
|
|
7219
7266
|
messageMtimeMs = 0;
|
|
7220
7267
|
}
|
|
7221
|
-
const partDir =
|
|
7268
|
+
const partDir = path8.join(this.storageBase, "part", msgId);
|
|
7222
7269
|
let parts = [];
|
|
7223
7270
|
if (fs9.existsSync(partDir)) {
|
|
7224
7271
|
try {
|
|
7225
|
-
parts = fs9.readdirSync(partDir).filter((f) => f.endsWith(".json")).map((f) => readJsonSafe(
|
|
7272
|
+
parts = fs9.readdirSync(partDir).filter((f) => f.endsWith(".json")).map((f) => readJsonSafe(path8.join(partDir, f))).filter((p) => p !== null);
|
|
7226
7273
|
} catch {
|
|
7227
7274
|
}
|
|
7228
7275
|
}
|
|
@@ -7259,7 +7306,7 @@ var require_openCode = __commonJS({
|
|
|
7259
7306
|
this.seenMessages.clear();
|
|
7260
7307
|
}
|
|
7261
7308
|
exists() {
|
|
7262
|
-
return fs9.existsSync(
|
|
7309
|
+
return fs9.existsSync(path8.join(this.storageBase, "message", this.sessionId));
|
|
7263
7310
|
}
|
|
7264
7311
|
flush() {
|
|
7265
7312
|
}
|
|
@@ -7476,7 +7523,7 @@ var require_openCode = __commonJS({
|
|
|
7476
7523
|
const db = this.ensureDb();
|
|
7477
7524
|
if (!db)
|
|
7478
7525
|
return false;
|
|
7479
|
-
const projectId = extractProjectIdFromDbPath(dir +
|
|
7526
|
+
const projectId = extractProjectIdFromDbPath(dir + path8.sep + "dummy.json") || path8.basename(dir);
|
|
7480
7527
|
return projectId.length > 0 && db.hasProject(projectId);
|
|
7481
7528
|
}
|
|
7482
7529
|
mapDbSessions(projectId) {
|
|
@@ -7501,14 +7548,14 @@ var require_openCode = __commonJS({
|
|
|
7501
7548
|
const projectId = resolveProjectId(workspacePath, db, dbStatus);
|
|
7502
7549
|
if (projectId) {
|
|
7503
7550
|
if (db) {
|
|
7504
|
-
return
|
|
7551
|
+
return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
|
|
7505
7552
|
}
|
|
7506
|
-
return
|
|
7553
|
+
return path8.join(getStorageDir(), "session", projectId);
|
|
7507
7554
|
}
|
|
7508
7555
|
if (dbStatus.kind !== "db_missing") {
|
|
7509
|
-
return
|
|
7556
|
+
return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX);
|
|
7510
7557
|
}
|
|
7511
|
-
return
|
|
7558
|
+
return path8.join(getStorageDir(), "session");
|
|
7512
7559
|
}
|
|
7513
7560
|
discoverSessionDirectory(workspacePath) {
|
|
7514
7561
|
const db = this.ensureDb();
|
|
@@ -7518,13 +7565,13 @@ var require_openCode = __commonJS({
|
|
|
7518
7565
|
return null;
|
|
7519
7566
|
if (db) {
|
|
7520
7567
|
if (db.hasProject(projectId)) {
|
|
7521
|
-
return
|
|
7568
|
+
return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
|
|
7522
7569
|
}
|
|
7523
7570
|
}
|
|
7524
7571
|
if (dbStatus.kind !== "db_missing") {
|
|
7525
7572
|
return null;
|
|
7526
7573
|
}
|
|
7527
|
-
const dir =
|
|
7574
|
+
const dir = path8.join(getStorageDir(), "session", projectId);
|
|
7528
7575
|
return fs9.existsSync(dir) ? dir : null;
|
|
7529
7576
|
}
|
|
7530
7577
|
// --- Session discovery ---
|
|
@@ -7551,7 +7598,7 @@ var require_openCode = __commonJS({
|
|
|
7551
7598
|
return this.findActiveSessionFromFiles(projectId);
|
|
7552
7599
|
}
|
|
7553
7600
|
findActiveSessionFromFiles(projectId) {
|
|
7554
|
-
const sessionDir =
|
|
7601
|
+
const sessionDir = path8.join(getStorageDir(), "session", projectId);
|
|
7555
7602
|
if (!fs9.existsSync(sessionDir))
|
|
7556
7603
|
return null;
|
|
7557
7604
|
let bestPath = null;
|
|
@@ -7559,7 +7606,7 @@ var require_openCode = __commonJS({
|
|
|
7559
7606
|
try {
|
|
7560
7607
|
const files = fs9.readdirSync(sessionDir).filter((f) => f.endsWith(".json"));
|
|
7561
7608
|
for (const file of files) {
|
|
7562
|
-
const fullPath =
|
|
7609
|
+
const fullPath = path8.join(sessionDir, file);
|
|
7563
7610
|
try {
|
|
7564
7611
|
const stats = fs9.statSync(fullPath);
|
|
7565
7612
|
if (stats.size > 0 && stats.mtime.getTime() > bestMtime) {
|
|
@@ -7573,14 +7620,14 @@ var require_openCode = __commonJS({
|
|
|
7573
7620
|
return null;
|
|
7574
7621
|
}
|
|
7575
7622
|
if (bestPath) {
|
|
7576
|
-
const sessionId =
|
|
7577
|
-
const messageDir =
|
|
7623
|
+
const sessionId = path8.basename(bestPath, ".json");
|
|
7624
|
+
const messageDir = path8.join(getStorageDir(), "message", sessionId);
|
|
7578
7625
|
if (fs9.existsSync(messageDir)) {
|
|
7579
7626
|
try {
|
|
7580
7627
|
const messageFiles = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
|
|
7581
7628
|
for (const mf of messageFiles) {
|
|
7582
7629
|
try {
|
|
7583
|
-
const mstat = fs9.statSync(
|
|
7630
|
+
const mstat = fs9.statSync(path8.join(messageDir, mf));
|
|
7584
7631
|
if (mstat.mtime.getTime() > bestMtime) {
|
|
7585
7632
|
bestMtime = mstat.mtime.getTime();
|
|
7586
7633
|
}
|
|
@@ -7610,20 +7657,20 @@ var require_openCode = __commonJS({
|
|
|
7610
7657
|
if (dbStatus.kind !== "db_missing") {
|
|
7611
7658
|
return [];
|
|
7612
7659
|
}
|
|
7613
|
-
const sessionDir =
|
|
7660
|
+
const sessionDir = path8.join(getStorageDir(), "session", projectId);
|
|
7614
7661
|
return this.findSessionsInDirectoryFromFiles(sessionDir);
|
|
7615
7662
|
}
|
|
7616
7663
|
findSessionsInDirectory(dir) {
|
|
7617
7664
|
const db = this.ensureDb();
|
|
7618
7665
|
const dbStatus = this.getRuntimeStatus();
|
|
7619
|
-
if (db && dir.includes(
|
|
7620
|
-
const projectId = extractProjectIdFromDbPath(dir +
|
|
7666
|
+
if (db && dir.includes(path8.sep + DB_SESSION_PREFIX + path8.sep)) {
|
|
7667
|
+
const projectId = extractProjectIdFromDbPath(dir + path8.sep + "dummy.json");
|
|
7621
7668
|
if (projectId) {
|
|
7622
7669
|
return this.mapDbSessions(projectId);
|
|
7623
7670
|
}
|
|
7624
7671
|
}
|
|
7625
7672
|
if (db) {
|
|
7626
|
-
const dirName =
|
|
7673
|
+
const dirName = path8.basename(dir);
|
|
7627
7674
|
if (db.hasProject(dirName)) {
|
|
7628
7675
|
return this.mapDbSessions(dirName);
|
|
7629
7676
|
}
|
|
@@ -7638,7 +7685,7 @@ var require_openCode = __commonJS({
|
|
|
7638
7685
|
if (!fs9.existsSync(dir))
|
|
7639
7686
|
return [];
|
|
7640
7687
|
return fs9.readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => {
|
|
7641
|
-
const fullPath =
|
|
7688
|
+
const fullPath = path8.join(dir, f);
|
|
7642
7689
|
try {
|
|
7643
7690
|
const stats = fs9.statSync(fullPath);
|
|
7644
7691
|
return { path: fullPath, mtime: stats.mtime.getTime(), size: stats.size };
|
|
@@ -7668,7 +7715,7 @@ var require_openCode = __commonJS({
|
|
|
7668
7715
|
if (!projStats || projStats.sessionCount === 0)
|
|
7669
7716
|
continue;
|
|
7670
7717
|
folders.push({
|
|
7671
|
-
dir:
|
|
7718
|
+
dir: path8.join(dataDir, DB_SESSION_PREFIX, project.id),
|
|
7672
7719
|
name: project.worktree || project.name || project.id,
|
|
7673
7720
|
encodedName: project.id,
|
|
7674
7721
|
sessionCount: projStats.sessionCount,
|
|
@@ -7696,23 +7743,23 @@ var require_openCode = __commonJS({
|
|
|
7696
7743
|
}
|
|
7697
7744
|
getAllProjectFoldersFromFiles(workspacePath) {
|
|
7698
7745
|
const folders = [];
|
|
7699
|
-
const sessionBase =
|
|
7746
|
+
const sessionBase = path8.join(getStorageDir(), "session");
|
|
7700
7747
|
try {
|
|
7701
7748
|
if (!fs9.existsSync(sessionBase))
|
|
7702
7749
|
return [];
|
|
7703
7750
|
const projectIds = fs9.readdirSync(sessionBase).filter((name) => {
|
|
7704
7751
|
try {
|
|
7705
|
-
return fs9.statSync(
|
|
7752
|
+
return fs9.statSync(path8.join(sessionBase, name)).isDirectory();
|
|
7706
7753
|
} catch {
|
|
7707
7754
|
return false;
|
|
7708
7755
|
}
|
|
7709
7756
|
});
|
|
7710
|
-
const projectDir =
|
|
7757
|
+
const projectDir = path8.join(getStorageDir(), "project");
|
|
7711
7758
|
const projectNames = /* @__PURE__ */ new Map();
|
|
7712
7759
|
if (fs9.existsSync(projectDir)) {
|
|
7713
7760
|
try {
|
|
7714
7761
|
for (const file of fs9.readdirSync(projectDir).filter((f) => f.endsWith(".json"))) {
|
|
7715
|
-
const proj = readJsonSafe(
|
|
7762
|
+
const proj = readJsonSafe(path8.join(projectDir, file));
|
|
7716
7763
|
if (proj) {
|
|
7717
7764
|
projectNames.set(proj.id, proj.path || proj.name || proj.id);
|
|
7718
7765
|
}
|
|
@@ -7725,14 +7772,14 @@ var require_openCode = __commonJS({
|
|
|
7725
7772
|
currentProjectId = resolveProjectIdFromFiles(workspacePath);
|
|
7726
7773
|
}
|
|
7727
7774
|
for (const projectId of projectIds) {
|
|
7728
|
-
const projSessionDir =
|
|
7775
|
+
const projSessionDir = path8.join(sessionBase, projectId);
|
|
7729
7776
|
let sessionCount = 0;
|
|
7730
7777
|
let lastModified = /* @__PURE__ */ new Date(0);
|
|
7731
7778
|
try {
|
|
7732
7779
|
const sessions = fs9.readdirSync(projSessionDir).filter((f) => f.endsWith(".json"));
|
|
7733
7780
|
for (const session of sessions) {
|
|
7734
7781
|
try {
|
|
7735
|
-
const fstats = fs9.statSync(
|
|
7782
|
+
const fstats = fs9.statSync(path8.join(projSessionDir, session));
|
|
7736
7783
|
if (fstats.size > 0) {
|
|
7737
7784
|
sessionCount++;
|
|
7738
7785
|
if (fstats.mtime > lastModified) {
|
|
@@ -7773,7 +7820,7 @@ var require_openCode = __commonJS({
|
|
|
7773
7820
|
return filename.endsWith(".json");
|
|
7774
7821
|
}
|
|
7775
7822
|
getSessionId(sessionPath) {
|
|
7776
|
-
return
|
|
7823
|
+
return path8.basename(sessionPath, ".json");
|
|
7777
7824
|
}
|
|
7778
7825
|
encodeWorkspacePath(workspacePath) {
|
|
7779
7826
|
const db = this.ensureDb();
|
|
@@ -7801,19 +7848,19 @@ var require_openCode = __commonJS({
|
|
|
7801
7848
|
if (session?.title) {
|
|
7802
7849
|
return truncateTitle(session.title);
|
|
7803
7850
|
}
|
|
7804
|
-
const messageDir =
|
|
7851
|
+
const messageDir = path8.join(getStorageDir(), "message", sessionId);
|
|
7805
7852
|
if (!fs9.existsSync(messageDir))
|
|
7806
7853
|
return null;
|
|
7807
7854
|
try {
|
|
7808
7855
|
const files = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json")).slice(0, 5);
|
|
7809
7856
|
for (const file of files) {
|
|
7810
|
-
const msg = readJsonSafe(
|
|
7857
|
+
const msg = readJsonSafe(path8.join(messageDir, file));
|
|
7811
7858
|
if (msg?.role === "user") {
|
|
7812
|
-
const partDir =
|
|
7859
|
+
const partDir = path8.join(getStorageDir(), "part", msg.id);
|
|
7813
7860
|
if (fs9.existsSync(partDir)) {
|
|
7814
7861
|
const partFiles = fs9.readdirSync(partDir).filter((f) => f.endsWith(".json"));
|
|
7815
7862
|
for (const pf of partFiles) {
|
|
7816
|
-
const part = readJsonSafe(
|
|
7863
|
+
const part = readJsonSafe(path8.join(partDir, pf));
|
|
7817
7864
|
if (part?.type === "text" && part.text.trim().length > 0) {
|
|
7818
7865
|
let text = part.text.trim().replace(/\s+/g, " ");
|
|
7819
7866
|
if (text.length > 60) {
|
|
@@ -7997,7 +8044,7 @@ var require_openCode = __commonJS({
|
|
|
7997
8044
|
}
|
|
7998
8045
|
searchInSessionFromFiles(sessionPath, sessionId, queryLower, query, maxResults) {
|
|
7999
8046
|
const results = [];
|
|
8000
|
-
const messageDir =
|
|
8047
|
+
const messageDir = path8.join(getStorageDir(), "message", sessionId);
|
|
8001
8048
|
if (!fs9.existsSync(messageDir))
|
|
8002
8049
|
return results;
|
|
8003
8050
|
try {
|
|
@@ -8007,10 +8054,10 @@ var require_openCode = __commonJS({
|
|
|
8007
8054
|
for (const file of messageFiles) {
|
|
8008
8055
|
if (results.length >= maxResults)
|
|
8009
8056
|
break;
|
|
8010
|
-
const msg = readJsonSafe(
|
|
8057
|
+
const msg = readJsonSafe(path8.join(messageDir, file));
|
|
8011
8058
|
if (!msg)
|
|
8012
8059
|
continue;
|
|
8013
|
-
const partDir =
|
|
8060
|
+
const partDir = path8.join(getStorageDir(), "part", msg.id);
|
|
8014
8061
|
if (!fs9.existsSync(partDir))
|
|
8015
8062
|
continue;
|
|
8016
8063
|
try {
|
|
@@ -8018,7 +8065,7 @@ var require_openCode = __commonJS({
|
|
|
8018
8065
|
for (const pf of partFiles) {
|
|
8019
8066
|
if (results.length >= maxResults)
|
|
8020
8067
|
break;
|
|
8021
|
-
const part = readJsonSafe(
|
|
8068
|
+
const part = readJsonSafe(path8.join(partDir, pf));
|
|
8022
8069
|
if (!part)
|
|
8023
8070
|
continue;
|
|
8024
8071
|
let text = "";
|
|
@@ -8055,11 +8102,11 @@ var require_openCode = __commonJS({
|
|
|
8055
8102
|
return results;
|
|
8056
8103
|
}
|
|
8057
8104
|
getProjectsBaseDir() {
|
|
8058
|
-
return
|
|
8105
|
+
return path8.join(getStorageDir(), "session");
|
|
8059
8106
|
}
|
|
8060
8107
|
// --- Stats ---
|
|
8061
8108
|
readSessionStats(sessionPath) {
|
|
8062
|
-
const sessionId =
|
|
8109
|
+
const sessionId = path8.basename(sessionPath, ".json");
|
|
8063
8110
|
const db = this.ensureDb();
|
|
8064
8111
|
let messageCount = 0;
|
|
8065
8112
|
let startTime = "";
|
|
@@ -8931,13 +8978,13 @@ var require_codexDatabase = __commonJS({
|
|
|
8931
8978
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8932
8979
|
exports.CodexDatabase = void 0;
|
|
8933
8980
|
var fs9 = __importStar(__require("fs"));
|
|
8934
|
-
var
|
|
8981
|
+
var path8 = __importStar(__require("path"));
|
|
8935
8982
|
var child_process_1 = __require("child_process");
|
|
8936
8983
|
var CodexDatabase = class {
|
|
8937
8984
|
dbPath;
|
|
8938
8985
|
sqlite3Available = null;
|
|
8939
8986
|
constructor(codexHome) {
|
|
8940
|
-
this.dbPath =
|
|
8987
|
+
this.dbPath = path8.join(codexHome, "state.sqlite");
|
|
8941
8988
|
}
|
|
8942
8989
|
isAvailable() {
|
|
8943
8990
|
try {
|
|
@@ -9002,7 +9049,7 @@ var require_codexDatabase = __commonJS({
|
|
|
9002
9049
|
const all = this.query("SELECT * FROM threads ORDER BY updated_at DESC");
|
|
9003
9050
|
return all.filter((t) => {
|
|
9004
9051
|
const threadCwd = normalizePath(t.cwd);
|
|
9005
|
-
return threadCwd === normalized || normalized.startsWith(threadCwd +
|
|
9052
|
+
return threadCwd === normalized || normalized.startsWith(threadCwd + path8.sep) || threadCwd.startsWith(normalized + path8.sep);
|
|
9006
9053
|
});
|
|
9007
9054
|
}
|
|
9008
9055
|
getMostRecentThread(cwd2) {
|
|
@@ -9032,7 +9079,7 @@ var require_codexDatabase = __commonJS({
|
|
|
9032
9079
|
try {
|
|
9033
9080
|
return fs9.realpathSync(input);
|
|
9034
9081
|
} catch {
|
|
9035
|
-
return
|
|
9082
|
+
return path8.resolve(input);
|
|
9036
9083
|
}
|
|
9037
9084
|
}
|
|
9038
9085
|
}
|
|
@@ -9082,22 +9129,22 @@ var require_codex = __commonJS({
|
|
|
9082
9129
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9083
9130
|
exports.CodexProvider = void 0;
|
|
9084
9131
|
var fs9 = __importStar(__require("fs"));
|
|
9085
|
-
var
|
|
9132
|
+
var path8 = __importStar(__require("path"));
|
|
9086
9133
|
var codexParser_1 = require_codexParser();
|
|
9087
9134
|
var codexDatabase_1 = require_codexDatabase();
|
|
9088
9135
|
var codexProfiles_1 = require_codexProfiles();
|
|
9089
9136
|
var modelContext_1 = require_modelContext();
|
|
9090
|
-
function
|
|
9091
|
-
return (0, codexProfiles_1.
|
|
9137
|
+
function getCodexHomes() {
|
|
9138
|
+
return (0, codexProfiles_1.getCodexMonitoringHomes)();
|
|
9092
9139
|
}
|
|
9093
|
-
function
|
|
9094
|
-
return
|
|
9140
|
+
function getSessionsDirs() {
|
|
9141
|
+
return getCodexHomes().map((home) => path8.join(home, "sessions"));
|
|
9095
9142
|
}
|
|
9096
9143
|
function isRolloutFile(filename) {
|
|
9097
9144
|
return filename.startsWith("rollout-") && filename.endsWith(".jsonl");
|
|
9098
9145
|
}
|
|
9099
9146
|
function extractSessionId(filename) {
|
|
9100
|
-
const base =
|
|
9147
|
+
const base = path8.basename(filename, ".jsonl");
|
|
9101
9148
|
const parts = base.split("-");
|
|
9102
9149
|
if (parts.length >= 6) {
|
|
9103
9150
|
const possibleUuid = parts.slice(-5).join("-");
|
|
@@ -9121,7 +9168,7 @@ var require_codex = __commonJS({
|
|
|
9121
9168
|
return results;
|
|
9122
9169
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
9123
9170
|
for (const entry of entries) {
|
|
9124
|
-
const fullPath =
|
|
9171
|
+
const fullPath = path8.join(dir, entry.name);
|
|
9125
9172
|
if (entry.isDirectory()) {
|
|
9126
9173
|
results.push(...findRolloutFiles(fullPath));
|
|
9127
9174
|
} else if (entry.isFile() && isRolloutFile(entry.name)) {
|
|
@@ -9138,6 +9185,31 @@ var require_codex = __commonJS({
|
|
|
9138
9185
|
}
|
|
9139
9186
|
return results;
|
|
9140
9187
|
}
|
|
9188
|
+
function findRolloutFilesInConfiguredHomes() {
|
|
9189
|
+
const results = [];
|
|
9190
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9191
|
+
for (const sessionsDir of getSessionsDirs()) {
|
|
9192
|
+
for (const file of findRolloutFiles(sessionsDir)) {
|
|
9193
|
+
if (seen.has(file.path))
|
|
9194
|
+
continue;
|
|
9195
|
+
seen.add(file.path);
|
|
9196
|
+
results.push(file);
|
|
9197
|
+
}
|
|
9198
|
+
}
|
|
9199
|
+
return results;
|
|
9200
|
+
}
|
|
9201
|
+
function getSessionsDir() {
|
|
9202
|
+
const dirs = getSessionsDirs();
|
|
9203
|
+
for (const dir of dirs) {
|
|
9204
|
+
if (findRolloutFiles(dir).length > 0) {
|
|
9205
|
+
return dir;
|
|
9206
|
+
}
|
|
9207
|
+
}
|
|
9208
|
+
return dirs[0] ?? path8.join(process.cwd(), ".codex", "sessions");
|
|
9209
|
+
}
|
|
9210
|
+
function getCodexHome() {
|
|
9211
|
+
return path8.dirname(getSessionsDir());
|
|
9212
|
+
}
|
|
9141
9213
|
function isSystemInjection(text) {
|
|
9142
9214
|
const t = text.trimStart();
|
|
9143
9215
|
return t.startsWith("<") || t.startsWith("#");
|
|
@@ -9202,13 +9274,13 @@ var require_codex = __commonJS({
|
|
|
9202
9274
|
function cwdMatches(sessionCwd, workspacePath) {
|
|
9203
9275
|
const normalizedSession = normalizePath(sessionCwd);
|
|
9204
9276
|
const normalizedWorkspace = normalizePath(workspacePath);
|
|
9205
|
-
return normalizedSession === normalizedWorkspace || normalizedWorkspace.startsWith(normalizedSession +
|
|
9277
|
+
return normalizedSession === normalizedWorkspace || normalizedWorkspace.startsWith(normalizedSession + path8.sep) || normalizedSession.startsWith(normalizedWorkspace + path8.sep);
|
|
9206
9278
|
}
|
|
9207
9279
|
function normalizePath(input) {
|
|
9208
9280
|
try {
|
|
9209
9281
|
return fs9.realpathSync(input);
|
|
9210
9282
|
} catch {
|
|
9211
|
-
return
|
|
9283
|
+
return path8.resolve(input);
|
|
9212
9284
|
}
|
|
9213
9285
|
}
|
|
9214
9286
|
function extractFirstUserMessage(rolloutPath) {
|
|
@@ -9430,7 +9502,7 @@ var require_codex = __commonJS({
|
|
|
9430
9502
|
if (db) {
|
|
9431
9503
|
const thread = db.getMostRecentThread(workspacePath);
|
|
9432
9504
|
if (thread?.rollout_path) {
|
|
9433
|
-
return
|
|
9505
|
+
return path8.dirname(thread.rollout_path);
|
|
9434
9506
|
}
|
|
9435
9507
|
}
|
|
9436
9508
|
return getSessionsDir();
|
|
@@ -9440,23 +9512,20 @@ var require_codex = __commonJS({
|
|
|
9440
9512
|
if (db) {
|
|
9441
9513
|
const thread = db.getMostRecentThread(workspacePath);
|
|
9442
9514
|
if (thread?.rollout_path && fs9.existsSync(thread.rollout_path)) {
|
|
9443
|
-
return
|
|
9515
|
+
return path8.dirname(thread.rollout_path);
|
|
9444
9516
|
}
|
|
9445
9517
|
}
|
|
9446
|
-
const
|
|
9447
|
-
if (!fs9.existsSync(sessionsDir))
|
|
9448
|
-
return null;
|
|
9449
|
-
const files = findRolloutFiles(sessionsDir);
|
|
9518
|
+
const files = findRolloutFilesInConfiguredHomes();
|
|
9450
9519
|
if (files.length === 0)
|
|
9451
9520
|
return null;
|
|
9452
9521
|
files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
9453
9522
|
for (const file of files) {
|
|
9454
9523
|
const meta = readSessionMeta(file.path);
|
|
9455
9524
|
if (meta && cwdMatches(meta.cwd, workspacePath)) {
|
|
9456
|
-
return
|
|
9525
|
+
return path8.dirname(file.path);
|
|
9457
9526
|
}
|
|
9458
9527
|
}
|
|
9459
|
-
return
|
|
9528
|
+
return getSessionsDir();
|
|
9460
9529
|
}
|
|
9461
9530
|
// --- Session discovery ---
|
|
9462
9531
|
findActiveSession(workspacePath) {
|
|
@@ -9467,10 +9536,7 @@ var require_codex = __commonJS({
|
|
|
9467
9536
|
return thread.rollout_path;
|
|
9468
9537
|
}
|
|
9469
9538
|
}
|
|
9470
|
-
const
|
|
9471
|
-
if (!fs9.existsSync(sessionsDir))
|
|
9472
|
-
return null;
|
|
9473
|
-
const files = findRolloutFiles(sessionsDir);
|
|
9539
|
+
const files = findRolloutFilesInConfiguredHomes();
|
|
9474
9540
|
files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
9475
9541
|
for (const file of files) {
|
|
9476
9542
|
const meta = readSessionMeta(file.path);
|
|
@@ -9488,10 +9554,7 @@ var require_codex = __commonJS({
|
|
|
9488
9554
|
if (dbPaths.length > 0)
|
|
9489
9555
|
return dbPaths;
|
|
9490
9556
|
}
|
|
9491
|
-
const
|
|
9492
|
-
if (!fs9.existsSync(sessionsDir))
|
|
9493
|
-
return [];
|
|
9494
|
-
const files = findRolloutFiles(sessionsDir);
|
|
9557
|
+
const files = findRolloutFilesInConfiguredHomes();
|
|
9495
9558
|
files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
9496
9559
|
return files.filter((f) => {
|
|
9497
9560
|
const meta = readSessionMeta(f.path);
|
|
@@ -9523,27 +9586,23 @@ var require_codex = __commonJS({
|
|
|
9523
9586
|
});
|
|
9524
9587
|
}
|
|
9525
9588
|
}
|
|
9526
|
-
const
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
if (existing) {
|
|
9535
|
-
if (file.mtime > existing.lastModified) {
|
|
9536
|
-
existing.lastModified = file.mtime;
|
|
9537
|
-
}
|
|
9538
|
-
} else {
|
|
9539
|
-
seenCwds.set(meta.cwd, {
|
|
9540
|
-
dir: path7.dirname(file.path),
|
|
9541
|
-
name: meta.cwd,
|
|
9542
|
-
encodedName: meta.cwd,
|
|
9543
|
-
sessionCount: 1,
|
|
9544
|
-
lastModified: file.mtime
|
|
9545
|
-
});
|
|
9589
|
+
for (const file of findRolloutFilesInConfiguredHomes()) {
|
|
9590
|
+
const meta = readSessionMeta(file.path);
|
|
9591
|
+
if (!meta?.cwd)
|
|
9592
|
+
continue;
|
|
9593
|
+
const existing = seenCwds.get(meta.cwd);
|
|
9594
|
+
if (existing) {
|
|
9595
|
+
if (file.mtime > existing.lastModified) {
|
|
9596
|
+
existing.lastModified = file.mtime;
|
|
9546
9597
|
}
|
|
9598
|
+
} else {
|
|
9599
|
+
seenCwds.set(meta.cwd, {
|
|
9600
|
+
dir: path8.dirname(file.path),
|
|
9601
|
+
name: meta.cwd,
|
|
9602
|
+
encodedName: meta.cwd,
|
|
9603
|
+
sessionCount: 1,
|
|
9604
|
+
lastModified: file.mtime
|
|
9605
|
+
});
|
|
9547
9606
|
}
|
|
9548
9607
|
}
|
|
9549
9608
|
folders.push(...seenCwds.values());
|
|
@@ -9566,7 +9625,7 @@ var require_codex = __commonJS({
|
|
|
9566
9625
|
return isRolloutFile(filename);
|
|
9567
9626
|
}
|
|
9568
9627
|
getSessionId(sessionPath) {
|
|
9569
|
-
return extractSessionId(
|
|
9628
|
+
return extractSessionId(path8.basename(sessionPath));
|
|
9570
9629
|
}
|
|
9571
9630
|
encodeWorkspacePath(workspacePath) {
|
|
9572
9631
|
return workspacePath;
|
|
@@ -9607,16 +9666,13 @@ var require_codex = __commonJS({
|
|
|
9607
9666
|
if (forkedThreads.length > 0)
|
|
9608
9667
|
return subagents;
|
|
9609
9668
|
}
|
|
9610
|
-
const
|
|
9611
|
-
if (!fs9.existsSync(sessionsDir))
|
|
9612
|
-
return subagents;
|
|
9613
|
-
const files = findRolloutFiles(sessionsDir);
|
|
9669
|
+
const files = findRolloutFilesInConfiguredHomes();
|
|
9614
9670
|
files.sort((a, b) => b.mtime.getTime() - a.mtime.getTime());
|
|
9615
9671
|
const filesToCheck = files.slice(0, 50);
|
|
9616
9672
|
for (const file of filesToCheck) {
|
|
9617
9673
|
const meta = readSessionMeta(file.path);
|
|
9618
9674
|
if (meta?.forked_from_id === sessionId) {
|
|
9619
|
-
const childId = extractSessionId(
|
|
9675
|
+
const childId = extractSessionId(path8.basename(file.path));
|
|
9620
9676
|
const stats = this.buildSubagentStats(childId, file.path, meta.source);
|
|
9621
9677
|
if (stats)
|
|
9622
9678
|
subagents.push(stats);
|
|
@@ -9728,7 +9784,7 @@ var require_codex = __commonJS({
|
|
|
9728
9784
|
}
|
|
9729
9785
|
// --- Stats ---
|
|
9730
9786
|
readSessionStats(sessionPath) {
|
|
9731
|
-
const sessionId = extractSessionId(
|
|
9787
|
+
const sessionId = extractSessionId(path8.basename(sessionPath));
|
|
9732
9788
|
let messageCount = 0;
|
|
9733
9789
|
let startTime = "";
|
|
9734
9790
|
let endTime = "";
|
|
@@ -10070,24 +10126,24 @@ var require_toolSummary = __commonJS({
|
|
|
10070
10126
|
if (!pattern)
|
|
10071
10127
|
return "";
|
|
10072
10128
|
const glob = input.glob;
|
|
10073
|
-
const
|
|
10129
|
+
const path8 = input.path;
|
|
10074
10130
|
const type = input.type;
|
|
10075
10131
|
const parts = [truncate2(pattern, 40)];
|
|
10076
10132
|
if (glob)
|
|
10077
10133
|
parts.push(`in ${glob}`);
|
|
10078
10134
|
else if (type)
|
|
10079
10135
|
parts.push(`in *.${type}`);
|
|
10080
|
-
else if (
|
|
10081
|
-
parts.push(`in ${basename5(
|
|
10136
|
+
else if (path8)
|
|
10137
|
+
parts.push(`in ${basename5(path8)}`);
|
|
10082
10138
|
return parts.join(" ");
|
|
10083
10139
|
};
|
|
10084
10140
|
var formatGlob = (input) => {
|
|
10085
10141
|
const pattern = input.pattern;
|
|
10086
10142
|
if (!pattern)
|
|
10087
10143
|
return "";
|
|
10088
|
-
const
|
|
10089
|
-
if (
|
|
10090
|
-
return `${pattern} in ${basename5(
|
|
10144
|
+
const path8 = input.path;
|
|
10145
|
+
if (path8)
|
|
10146
|
+
return `${pattern} in ${basename5(path8)}`;
|
|
10091
10147
|
return pattern;
|
|
10092
10148
|
};
|
|
10093
10149
|
var formatTask = (input) => {
|
|
@@ -10396,12 +10452,12 @@ var require_subagentTraceParser = __commonJS({
|
|
|
10396
10452
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10397
10453
|
exports.scanSubagentTraces = scanSubagentTraces;
|
|
10398
10454
|
var fs9 = __importStar(__require("fs"));
|
|
10399
|
-
var
|
|
10455
|
+
var path8 = __importStar(__require("path"));
|
|
10400
10456
|
var toolSummary_1 = require_toolSummary();
|
|
10401
10457
|
var noiseClassifier_1 = require_noiseClassifier();
|
|
10402
10458
|
var AGENT_FILE_PATTERN = /^agent-(.+)\.jsonl$/;
|
|
10403
10459
|
function scanSubagentTraces(sessionDir, sessionId) {
|
|
10404
|
-
const subagentsDir =
|
|
10460
|
+
const subagentsDir = path8.join(sessionDir, sessionId, "subagents");
|
|
10405
10461
|
try {
|
|
10406
10462
|
if (!fs9.existsSync(subagentsDir))
|
|
10407
10463
|
return [];
|
|
@@ -10412,7 +10468,7 @@ var require_subagentTraceParser = __commonJS({
|
|
|
10412
10468
|
if (!match)
|
|
10413
10469
|
continue;
|
|
10414
10470
|
const agentId = match[1];
|
|
10415
|
-
const filePath =
|
|
10471
|
+
const filePath = path8.join(subagentsDir, file);
|
|
10416
10472
|
const trace = parseAgentTrace(filePath, agentId);
|
|
10417
10473
|
if (trace)
|
|
10418
10474
|
traces.push(trace);
|
|
@@ -10696,8 +10752,8 @@ var require_debugLogParser = __commonJS({
|
|
|
10696
10752
|
exports.collapseDuplicates = collapseDuplicates;
|
|
10697
10753
|
exports.discoverDebugLogs = discoverDebugLogs;
|
|
10698
10754
|
var fs9 = __importStar(__require("fs"));
|
|
10699
|
-
var
|
|
10700
|
-
var
|
|
10755
|
+
var path8 = __importStar(__require("path"));
|
|
10756
|
+
var os6 = __importStar(__require("os"));
|
|
10701
10757
|
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+(.*)$/;
|
|
10702
10758
|
var LEVEL_ORDER = {
|
|
10703
10759
|
DEBUG: 0,
|
|
@@ -10751,12 +10807,12 @@ var require_debugLogParser = __commonJS({
|
|
|
10751
10807
|
return result;
|
|
10752
10808
|
}
|
|
10753
10809
|
function discoverDebugLogs() {
|
|
10754
|
-
const debugDir =
|
|
10810
|
+
const debugDir = path8.join(os6.homedir(), ".claude", "debug");
|
|
10755
10811
|
try {
|
|
10756
10812
|
if (!fs9.existsSync(debugDir))
|
|
10757
10813
|
return [];
|
|
10758
10814
|
return fs9.readdirSync(debugDir).filter((f) => f.endsWith(".log") || f.endsWith(".txt")).map((name) => {
|
|
10759
|
-
const fullPath =
|
|
10815
|
+
const fullPath = path8.join(debugDir, name);
|
|
10760
10816
|
try {
|
|
10761
10817
|
const stat = fs9.statSync(fullPath);
|
|
10762
10818
|
return {
|
|
@@ -10820,7 +10876,7 @@ var require_sessionSearch = __commonJS({
|
|
|
10820
10876
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10821
10877
|
exports.searchSessions = searchSessions2;
|
|
10822
10878
|
var fs9 = __importStar(__require("fs"));
|
|
10823
|
-
var
|
|
10879
|
+
var path8 = __importStar(__require("path"));
|
|
10824
10880
|
async function searchSessions2(provider, query, opts) {
|
|
10825
10881
|
const maxResults = opts?.maxResults ?? 50;
|
|
10826
10882
|
const results = [];
|
|
@@ -10839,7 +10895,7 @@ var require_sessionSearch = __commonJS({
|
|
|
10839
10895
|
const dir = folder.dir;
|
|
10840
10896
|
if (fs9.existsSync(dir)) {
|
|
10841
10897
|
const entries = fs9.readdirSync(dir).filter((f) => f.endsWith(".jsonl") || f.endsWith(".json"));
|
|
10842
|
-
sessionFiles = entries.map((f) =>
|
|
10898
|
+
sessionFiles = entries.map((f) => path8.join(dir, f));
|
|
10843
10899
|
}
|
|
10844
10900
|
} catch {
|
|
10845
10901
|
}
|
|
@@ -11711,7 +11767,7 @@ var require_sqliteWatcher = __commonJS({
|
|
|
11711
11767
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11712
11768
|
exports.SqliteSessionWatcher = void 0;
|
|
11713
11769
|
var fs9 = __importStar(__require("fs"));
|
|
11714
|
-
var
|
|
11770
|
+
var path8 = __importStar(__require("path"));
|
|
11715
11771
|
var openCodeDatabase_1 = require_openCodeDatabase();
|
|
11716
11772
|
var openCodeParser_1 = require_openCodeParser();
|
|
11717
11773
|
var DEBOUNCE_MS = 200;
|
|
@@ -11836,7 +11892,7 @@ var require_sqliteWatcher = __commonJS({
|
|
|
11836
11892
|
this.dbPath = dbPath;
|
|
11837
11893
|
this.sessionId = sessionId;
|
|
11838
11894
|
this.callbacks = callbacks;
|
|
11839
|
-
this.db = new openCodeDatabase_1.OpenCodeDatabase(
|
|
11895
|
+
this.db = new openCodeDatabase_1.OpenCodeDatabase(path8.dirname(dbPath));
|
|
11840
11896
|
}
|
|
11841
11897
|
get isActive() {
|
|
11842
11898
|
return this._isActive;
|
|
@@ -12001,15 +12057,15 @@ var require_factory = __commonJS({
|
|
|
12001
12057
|
}();
|
|
12002
12058
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12003
12059
|
exports.createWatcher = createWatcher5;
|
|
12004
|
-
var
|
|
12005
|
-
var
|
|
12060
|
+
var os6 = __importStar(__require("os"));
|
|
12061
|
+
var path8 = __importStar(__require("path"));
|
|
12006
12062
|
var jsonlWatcher_1 = require_jsonlWatcher();
|
|
12007
12063
|
var sqliteWatcher_1 = require_sqliteWatcher();
|
|
12008
12064
|
function getOpenCodeDataDir() {
|
|
12009
12065
|
const xdg = process.env.XDG_DATA_HOME;
|
|
12010
12066
|
if (xdg)
|
|
12011
|
-
return
|
|
12012
|
-
return
|
|
12067
|
+
return path8.join(xdg, "opencode");
|
|
12068
|
+
return path8.join(os6.homedir(), ".local", "share", "opencode");
|
|
12013
12069
|
}
|
|
12014
12070
|
function createWatcher5(options) {
|
|
12015
12071
|
const { provider, workspacePath, sessionId, callbacks } = options;
|
|
@@ -12021,7 +12077,7 @@ var require_factory = __commonJS({
|
|
|
12021
12077
|
if (sessionId) {
|
|
12022
12078
|
const match = sessions.find((s) => s.includes(sessionId));
|
|
12023
12079
|
if (!match) {
|
|
12024
|
-
throw new Error(`Session ${sessionId} not found. Available: ${sessions.slice(0, 5).map((s) =>
|
|
12080
|
+
throw new Error(`Session ${sessionId} not found. Available: ${sessions.slice(0, 5).map((s) => path8.basename(s)).join(", ")}`);
|
|
12025
12081
|
}
|
|
12026
12082
|
sessionPath = match;
|
|
12027
12083
|
} else {
|
|
@@ -12037,8 +12093,8 @@ var require_factory = __commonJS({
|
|
|
12037
12093
|
return new jsonlWatcher_1.JsonlSessionWatcher(providerId, sessionPath, callbacks);
|
|
12038
12094
|
case "opencode": {
|
|
12039
12095
|
const dataDir = getOpenCodeDataDir();
|
|
12040
|
-
const dbPath =
|
|
12041
|
-
const sid =
|
|
12096
|
+
const dbPath = path8.join(dataDir, "opencode.db");
|
|
12097
|
+
const sid = path8.basename(sessionPath, ".json");
|
|
12042
12098
|
return new sqliteWatcher_1.SqliteSessionWatcher(dbPath, sid, callbacks);
|
|
12043
12099
|
}
|
|
12044
12100
|
default:
|
|
@@ -14433,6 +14489,243 @@ var require_PatternExtractor = __commonJS({
|
|
|
14433
14489
|
}
|
|
14434
14490
|
});
|
|
14435
14491
|
|
|
14492
|
+
// ../sidekick-shared/dist/modelInfo.js
|
|
14493
|
+
var require_modelInfo = __commonJS({
|
|
14494
|
+
"../sidekick-shared/dist/modelInfo.js"(exports) {
|
|
14495
|
+
"use strict";
|
|
14496
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14497
|
+
exports._setPricingOverrides = _setPricingOverrides;
|
|
14498
|
+
exports._getPricingOverrides = _getPricingOverrides;
|
|
14499
|
+
exports._clearPricingOverrides = _clearPricingOverrides;
|
|
14500
|
+
exports.parseModelId = parseModelId;
|
|
14501
|
+
exports.getModelPricing = getModelPricing;
|
|
14502
|
+
exports.getModelInfo = getModelInfo2;
|
|
14503
|
+
exports.calculateCostWithPricing = calculateCostWithPricing;
|
|
14504
|
+
exports.calculateCost = calculateCost;
|
|
14505
|
+
exports.formatCost = formatCost5;
|
|
14506
|
+
var modelContext_1 = require_modelContext();
|
|
14507
|
+
var PRICING_TABLE = {
|
|
14508
|
+
// ── Anthropic: Claude ──
|
|
14509
|
+
"claude-haiku-4.5": {
|
|
14510
|
+
inputCostPerMillion: 1,
|
|
14511
|
+
outputCostPerMillion: 5,
|
|
14512
|
+
cacheWriteCostPerMillion: 1.25,
|
|
14513
|
+
cacheReadCostPerMillion: 0.1
|
|
14514
|
+
},
|
|
14515
|
+
"claude-haiku-3.5": {
|
|
14516
|
+
inputCostPerMillion: 0.8,
|
|
14517
|
+
outputCostPerMillion: 4,
|
|
14518
|
+
cacheWriteCostPerMillion: 1,
|
|
14519
|
+
cacheReadCostPerMillion: 0.08
|
|
14520
|
+
},
|
|
14521
|
+
"claude-sonnet-4.6": {
|
|
14522
|
+
inputCostPerMillion: 3,
|
|
14523
|
+
outputCostPerMillion: 15,
|
|
14524
|
+
cacheWriteCostPerMillion: 3.75,
|
|
14525
|
+
cacheReadCostPerMillion: 0.3
|
|
14526
|
+
},
|
|
14527
|
+
"claude-sonnet-4.5": {
|
|
14528
|
+
inputCostPerMillion: 3,
|
|
14529
|
+
outputCostPerMillion: 15,
|
|
14530
|
+
cacheWriteCostPerMillion: 3.75,
|
|
14531
|
+
cacheReadCostPerMillion: 0.3
|
|
14532
|
+
},
|
|
14533
|
+
"claude-sonnet-4": {
|
|
14534
|
+
inputCostPerMillion: 3,
|
|
14535
|
+
outputCostPerMillion: 15,
|
|
14536
|
+
cacheWriteCostPerMillion: 3.75,
|
|
14537
|
+
cacheReadCostPerMillion: 0.3
|
|
14538
|
+
},
|
|
14539
|
+
"claude-opus-4.6": {
|
|
14540
|
+
inputCostPerMillion: 15,
|
|
14541
|
+
outputCostPerMillion: 75,
|
|
14542
|
+
cacheWriteCostPerMillion: 18.75,
|
|
14543
|
+
cacheReadCostPerMillion: 1.5
|
|
14544
|
+
},
|
|
14545
|
+
"claude-opus-4.5": {
|
|
14546
|
+
inputCostPerMillion: 5,
|
|
14547
|
+
outputCostPerMillion: 25,
|
|
14548
|
+
cacheWriteCostPerMillion: 6.25,
|
|
14549
|
+
cacheReadCostPerMillion: 0.5
|
|
14550
|
+
},
|
|
14551
|
+
"claude-opus-4": {
|
|
14552
|
+
inputCostPerMillion: 15,
|
|
14553
|
+
outputCostPerMillion: 75,
|
|
14554
|
+
cacheWriteCostPerMillion: 18.75,
|
|
14555
|
+
cacheReadCostPerMillion: 1.5
|
|
14556
|
+
},
|
|
14557
|
+
// ── OpenAI: GPT-4.x family ──
|
|
14558
|
+
"gpt-4.1": {
|
|
14559
|
+
inputCostPerMillion: 2,
|
|
14560
|
+
outputCostPerMillion: 8,
|
|
14561
|
+
cacheWriteCostPerMillion: 0,
|
|
14562
|
+
cacheReadCostPerMillion: 0.5
|
|
14563
|
+
},
|
|
14564
|
+
"gpt-4o-mini": {
|
|
14565
|
+
inputCostPerMillion: 0.15,
|
|
14566
|
+
outputCostPerMillion: 0.6,
|
|
14567
|
+
cacheWriteCostPerMillion: 0,
|
|
14568
|
+
cacheReadCostPerMillion: 0.075
|
|
14569
|
+
},
|
|
14570
|
+
"gpt-4o": {
|
|
14571
|
+
inputCostPerMillion: 2.5,
|
|
14572
|
+
outputCostPerMillion: 10,
|
|
14573
|
+
cacheWriteCostPerMillion: 0,
|
|
14574
|
+
cacheReadCostPerMillion: 1.25
|
|
14575
|
+
},
|
|
14576
|
+
"gpt-4-turbo": {
|
|
14577
|
+
inputCostPerMillion: 10,
|
|
14578
|
+
outputCostPerMillion: 30,
|
|
14579
|
+
cacheWriteCostPerMillion: 0,
|
|
14580
|
+
cacheReadCostPerMillion: 0
|
|
14581
|
+
},
|
|
14582
|
+
// ── OpenAI: GPT-5 family (baseline estimate; LiteLLM catalog overrides) ──
|
|
14583
|
+
// Codex emits `gpt-5.4`, `gpt-5.3-codex`, `gpt-5`. Anchoring the static
|
|
14584
|
+
// estimate to gpt-4o-tier rates so offline users see a reasonable ballpark.
|
|
14585
|
+
"gpt-5.4": {
|
|
14586
|
+
inputCostPerMillion: 1.25,
|
|
14587
|
+
outputCostPerMillion: 10,
|
|
14588
|
+
cacheWriteCostPerMillion: 0,
|
|
14589
|
+
cacheReadCostPerMillion: 0.125
|
|
14590
|
+
},
|
|
14591
|
+
"gpt-5.3-codex": {
|
|
14592
|
+
inputCostPerMillion: 1.25,
|
|
14593
|
+
outputCostPerMillion: 10,
|
|
14594
|
+
cacheWriteCostPerMillion: 0,
|
|
14595
|
+
cacheReadCostPerMillion: 0.125
|
|
14596
|
+
},
|
|
14597
|
+
"gpt-5.3": {
|
|
14598
|
+
inputCostPerMillion: 1.25,
|
|
14599
|
+
outputCostPerMillion: 10,
|
|
14600
|
+
cacheWriteCostPerMillion: 0,
|
|
14601
|
+
cacheReadCostPerMillion: 0.125
|
|
14602
|
+
},
|
|
14603
|
+
"gpt-5": {
|
|
14604
|
+
inputCostPerMillion: 1.25,
|
|
14605
|
+
outputCostPerMillion: 10,
|
|
14606
|
+
cacheWriteCostPerMillion: 0,
|
|
14607
|
+
cacheReadCostPerMillion: 0.125
|
|
14608
|
+
},
|
|
14609
|
+
// ── OpenAI: o-series (reasoning models) ──
|
|
14610
|
+
"o3-mini": {
|
|
14611
|
+
inputCostPerMillion: 1.1,
|
|
14612
|
+
outputCostPerMillion: 4.4,
|
|
14613
|
+
cacheWriteCostPerMillion: 0,
|
|
14614
|
+
cacheReadCostPerMillion: 0.55
|
|
14615
|
+
},
|
|
14616
|
+
"o3": {
|
|
14617
|
+
inputCostPerMillion: 2,
|
|
14618
|
+
outputCostPerMillion: 8,
|
|
14619
|
+
cacheWriteCostPerMillion: 0,
|
|
14620
|
+
cacheReadCostPerMillion: 0.5
|
|
14621
|
+
},
|
|
14622
|
+
"o1-mini": {
|
|
14623
|
+
inputCostPerMillion: 3,
|
|
14624
|
+
outputCostPerMillion: 12,
|
|
14625
|
+
cacheWriteCostPerMillion: 0,
|
|
14626
|
+
cacheReadCostPerMillion: 1.5
|
|
14627
|
+
},
|
|
14628
|
+
"o1": {
|
|
14629
|
+
inputCostPerMillion: 15,
|
|
14630
|
+
outputCostPerMillion: 60,
|
|
14631
|
+
cacheWriteCostPerMillion: 0,
|
|
14632
|
+
cacheReadCostPerMillion: 7.5
|
|
14633
|
+
}
|
|
14634
|
+
};
|
|
14635
|
+
var STATIC_SORTED_KEYS = Object.keys(PRICING_TABLE).sort((a, b) => b.length - a.length);
|
|
14636
|
+
var overrideTable = {};
|
|
14637
|
+
var overrideSortedKeys = [];
|
|
14638
|
+
function _setPricingOverrides(overrides) {
|
|
14639
|
+
overrideTable = { ...overrides };
|
|
14640
|
+
overrideSortedKeys = Object.keys(overrideTable).sort((a, b) => b.length - a.length);
|
|
14641
|
+
}
|
|
14642
|
+
function _getPricingOverrides() {
|
|
14643
|
+
return { ...overrideTable };
|
|
14644
|
+
}
|
|
14645
|
+
function _clearPricingOverrides() {
|
|
14646
|
+
overrideTable = {};
|
|
14647
|
+
overrideSortedKeys = [];
|
|
14648
|
+
}
|
|
14649
|
+
var CLAUDE_RE = /^claude-(haiku|sonnet|opus)-([0-9.]+)/i;
|
|
14650
|
+
var GPT_RE = /^gpt-([0-9][0-9.A-Za-z-]*)/i;
|
|
14651
|
+
var O_SERIES_RE = /^o([0-9]+)(-mini|-pro)?/i;
|
|
14652
|
+
var GEMINI_RE = /^gemini-([0-9][0-9.A-Za-z-]*)/i;
|
|
14653
|
+
function parseModelId(modelId) {
|
|
14654
|
+
if (!modelId)
|
|
14655
|
+
return null;
|
|
14656
|
+
const normalized = modelId.replace(/\[1m\]/gi, "");
|
|
14657
|
+
const claude = normalized.match(CLAUDE_RE);
|
|
14658
|
+
if (claude) {
|
|
14659
|
+
return { provider: "anthropic", family: claude[1].toLowerCase(), version: claude[2] };
|
|
14660
|
+
}
|
|
14661
|
+
const gpt = normalized.match(GPT_RE);
|
|
14662
|
+
if (gpt) {
|
|
14663
|
+
return { provider: "openai", family: "gpt", version: gpt[1] };
|
|
14664
|
+
}
|
|
14665
|
+
const oSeries = normalized.match(O_SERIES_RE);
|
|
14666
|
+
if (oSeries) {
|
|
14667
|
+
const suffix = oSeries[2] ? oSeries[2] : "";
|
|
14668
|
+
return { provider: "openai", family: "o", version: `${oSeries[1]}${suffix}` };
|
|
14669
|
+
}
|
|
14670
|
+
const gemini = normalized.match(GEMINI_RE);
|
|
14671
|
+
if (gemini) {
|
|
14672
|
+
return { provider: "google", family: "gemini", version: gemini[1] };
|
|
14673
|
+
}
|
|
14674
|
+
return null;
|
|
14675
|
+
}
|
|
14676
|
+
function findLongestPrefix(keys, modelId) {
|
|
14677
|
+
for (const key of keys) {
|
|
14678
|
+
if (modelId === key || modelId.startsWith(key))
|
|
14679
|
+
return key;
|
|
14680
|
+
}
|
|
14681
|
+
return null;
|
|
14682
|
+
}
|
|
14683
|
+
function getModelPricing(modelId) {
|
|
14684
|
+
if (!modelId)
|
|
14685
|
+
return null;
|
|
14686
|
+
const normalized = modelId.replace(/\[1m\]/gi, "");
|
|
14687
|
+
if (overrideTable[normalized])
|
|
14688
|
+
return overrideTable[normalized];
|
|
14689
|
+
const overridePrefix = findLongestPrefix(overrideSortedKeys, normalized);
|
|
14690
|
+
if (overridePrefix)
|
|
14691
|
+
return overrideTable[overridePrefix];
|
|
14692
|
+
if (PRICING_TABLE[normalized])
|
|
14693
|
+
return PRICING_TABLE[normalized];
|
|
14694
|
+
const staticPrefix = findLongestPrefix(STATIC_SORTED_KEYS, normalized);
|
|
14695
|
+
if (staticPrefix)
|
|
14696
|
+
return PRICING_TABLE[staticPrefix];
|
|
14697
|
+
return null;
|
|
14698
|
+
}
|
|
14699
|
+
function getModelInfo2(modelId) {
|
|
14700
|
+
const parsed = parseModelId(modelId);
|
|
14701
|
+
return {
|
|
14702
|
+
provider: parsed?.provider ?? null,
|
|
14703
|
+
family: parsed?.family ?? null,
|
|
14704
|
+
version: parsed?.version ?? null,
|
|
14705
|
+
contextWindow: (0, modelContext_1.getModelContextWindowSize)(modelId),
|
|
14706
|
+
pricing: getModelPricing(modelId)
|
|
14707
|
+
};
|
|
14708
|
+
}
|
|
14709
|
+
function calculateCostWithPricing(usage, pricing) {
|
|
14710
|
+
const reasoning = usage.reasoningTokens ?? 0;
|
|
14711
|
+
return usage.inputTokens / 1e6 * pricing.inputCostPerMillion + usage.outputTokens / 1e6 * pricing.outputCostPerMillion + reasoning / 1e6 * pricing.outputCostPerMillion + usage.cacheWriteTokens / 1e6 * pricing.cacheWriteCostPerMillion + usage.cacheReadTokens / 1e6 * pricing.cacheReadCostPerMillion;
|
|
14712
|
+
}
|
|
14713
|
+
function calculateCost(usage, modelId) {
|
|
14714
|
+
const pricing = getModelPricing(modelId);
|
|
14715
|
+
if (!pricing)
|
|
14716
|
+
return null;
|
|
14717
|
+
return calculateCostWithPricing(usage, pricing);
|
|
14718
|
+
}
|
|
14719
|
+
function formatCost5(cost) {
|
|
14720
|
+
if (cost === null || cost === void 0)
|
|
14721
|
+
return "\u2014";
|
|
14722
|
+
if (cost < 0.01)
|
|
14723
|
+
return `$${cost.toFixed(4)}`;
|
|
14724
|
+
return `$${cost.toFixed(2)}`;
|
|
14725
|
+
}
|
|
14726
|
+
}
|
|
14727
|
+
});
|
|
14728
|
+
|
|
14436
14729
|
// ../sidekick-shared/dist/aggregation/EventAggregator.js
|
|
14437
14730
|
var require_EventAggregator = __commonJS({
|
|
14438
14731
|
"../sidekick-shared/dist/aggregation/EventAggregator.js"(exports) {
|
|
@@ -14448,6 +14741,7 @@ var require_EventAggregator = __commonJS({
|
|
|
14448
14741
|
var FrequencyTracker_1 = require_FrequencyTracker();
|
|
14449
14742
|
var HeatmapTracker_1 = require_HeatmapTracker();
|
|
14450
14743
|
var PatternExtractor_1 = require_PatternExtractor();
|
|
14744
|
+
var modelInfo_1 = require_modelInfo();
|
|
14451
14745
|
var DEFAULT_TIMELINE_CAP = 200;
|
|
14452
14746
|
var DEFAULT_LATENCY_CAP = 100;
|
|
14453
14747
|
var DEFAULT_BURN_WINDOW_MS = 5 * 6e4;
|
|
@@ -14639,6 +14933,14 @@ var require_EventAggregator = __commonJS({
|
|
|
14639
14933
|
this.currentContextSize = contextSize;
|
|
14640
14934
|
if (event.model) {
|
|
14641
14935
|
const model = event.model;
|
|
14936
|
+
const pricing = event.cost ? null : (0, modelInfo_1.getModelPricing)(model);
|
|
14937
|
+
const computed = event.cost ? event.cost : pricing ? (0, modelInfo_1.calculateCostWithPricing)({
|
|
14938
|
+
inputTokens: inputTok,
|
|
14939
|
+
outputTokens: outputTok,
|
|
14940
|
+
cacheWriteTokens: cacheWrite,
|
|
14941
|
+
cacheReadTokens: cacheRead
|
|
14942
|
+
}, pricing) : 0;
|
|
14943
|
+
const evPriced = event.cost != null || pricing != null;
|
|
14642
14944
|
const acc = this.modelUsage.get(model) ?? {
|
|
14643
14945
|
calls: 0,
|
|
14644
14946
|
tokens: 0,
|
|
@@ -14646,7 +14948,8 @@ var require_EventAggregator = __commonJS({
|
|
|
14646
14948
|
outputTokens: 0,
|
|
14647
14949
|
cacheWriteTokens: 0,
|
|
14648
14950
|
cacheReadTokens: 0,
|
|
14649
|
-
cost: 0
|
|
14951
|
+
cost: 0,
|
|
14952
|
+
priced: true
|
|
14650
14953
|
};
|
|
14651
14954
|
acc.calls++;
|
|
14652
14955
|
acc.tokens += inputTok + outputTok;
|
|
@@ -14654,8 +14957,9 @@ var require_EventAggregator = __commonJS({
|
|
|
14654
14957
|
acc.outputTokens += outputTok;
|
|
14655
14958
|
acc.cacheWriteTokens += cacheWrite;
|
|
14656
14959
|
acc.cacheReadTokens += cacheRead;
|
|
14657
|
-
|
|
14658
|
-
|
|
14960
|
+
acc.cost += computed;
|
|
14961
|
+
if (!evPriced)
|
|
14962
|
+
acc.priced = false;
|
|
14659
14963
|
this.modelUsage.set(model, acc);
|
|
14660
14964
|
}
|
|
14661
14965
|
}
|
|
@@ -14956,7 +15260,26 @@ var require_EventAggregator = __commonJS({
|
|
|
14956
15260
|
const outputTok = usage.output_tokens;
|
|
14957
15261
|
const cacheWrite = usage.cache_creation_input_tokens ?? 0;
|
|
14958
15262
|
const cacheRead = usage.cache_read_input_tokens ?? 0;
|
|
14959
|
-
const
|
|
15263
|
+
const reasoningTok = usage.reasoning_tokens ?? 0;
|
|
15264
|
+
const reported = usage.reported_cost ?? 0;
|
|
15265
|
+
const modelKey = model ?? this.currentModel;
|
|
15266
|
+
const pricing = modelKey ? (0, modelInfo_1.getModelPricing)(modelKey) : null;
|
|
15267
|
+
let priced = reported > 0 || pricing !== null;
|
|
15268
|
+
let cost;
|
|
15269
|
+
if (reported > 0) {
|
|
15270
|
+
cost = reported;
|
|
15271
|
+
} else if (pricing) {
|
|
15272
|
+
cost = (0, modelInfo_1.calculateCostWithPricing)({
|
|
15273
|
+
inputTokens: inputTok,
|
|
15274
|
+
outputTokens: outputTok,
|
|
15275
|
+
cacheWriteTokens: cacheWrite,
|
|
15276
|
+
cacheReadTokens: cacheRead,
|
|
15277
|
+
reasoningTokens: reasoningTok
|
|
15278
|
+
}, pricing);
|
|
15279
|
+
} else {
|
|
15280
|
+
cost = 0;
|
|
15281
|
+
priced = false;
|
|
15282
|
+
}
|
|
14960
15283
|
this.inputTokens += inputTok;
|
|
14961
15284
|
this.outputTokens += outputTok;
|
|
14962
15285
|
this.cacheWriteTokens += cacheWrite;
|
|
@@ -14990,15 +15313,17 @@ var require_EventAggregator = __commonJS({
|
|
|
14990
15313
|
inputTokens: contextSize,
|
|
14991
15314
|
turnIndex: this.contextTurnIndex++
|
|
14992
15315
|
});
|
|
14993
|
-
const
|
|
14994
|
-
const acc = this.modelUsage.get(
|
|
15316
|
+
const perModelKey = model ?? this.currentModel ?? "unknown";
|
|
15317
|
+
const acc = this.modelUsage.get(perModelKey) ?? {
|
|
14995
15318
|
calls: 0,
|
|
14996
15319
|
tokens: 0,
|
|
14997
15320
|
inputTokens: 0,
|
|
14998
15321
|
outputTokens: 0,
|
|
14999
15322
|
cacheWriteTokens: 0,
|
|
15000
15323
|
cacheReadTokens: 0,
|
|
15001
|
-
|
|
15324
|
+
reasoningTokens: 0,
|
|
15325
|
+
cost: 0,
|
|
15326
|
+
priced: true
|
|
15002
15327
|
};
|
|
15003
15328
|
acc.calls++;
|
|
15004
15329
|
acc.tokens += inputTok + outputTok;
|
|
@@ -15006,8 +15331,11 @@ var require_EventAggregator = __commonJS({
|
|
|
15006
15331
|
acc.outputTokens += outputTok;
|
|
15007
15332
|
acc.cacheWriteTokens += cacheWrite;
|
|
15008
15333
|
acc.cacheReadTokens += cacheRead;
|
|
15334
|
+
acc.reasoningTokens = (acc.reasoningTokens ?? 0) + reasoningTok;
|
|
15009
15335
|
acc.cost += cost;
|
|
15010
|
-
|
|
15336
|
+
if (!priced)
|
|
15337
|
+
acc.priced = false;
|
|
15338
|
+
this.modelUsage.set(perModelKey, acc);
|
|
15011
15339
|
this.updateBurnRate(timestamp);
|
|
15012
15340
|
}
|
|
15013
15341
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -16059,15 +16387,15 @@ var require_snapshot = __commonJS({
|
|
|
16059
16387
|
exports.deleteSnapshot = deleteSnapshot2;
|
|
16060
16388
|
exports.isSnapshotValid = isSnapshotValid2;
|
|
16061
16389
|
var fs9 = __importStar(__require("fs"));
|
|
16062
|
-
var
|
|
16390
|
+
var path8 = __importStar(__require("path"));
|
|
16063
16391
|
var paths_1 = require_paths();
|
|
16064
16392
|
var SNAPSHOT_VERSION = 1;
|
|
16065
16393
|
function getSnapshotsDir() {
|
|
16066
|
-
return
|
|
16394
|
+
return path8.join((0, paths_1.getConfigDir)(), "snapshots");
|
|
16067
16395
|
}
|
|
16068
16396
|
function getSnapshotPath(sessionId) {
|
|
16069
16397
|
const safe = sessionId.replace(/[/\\:]/g, "_");
|
|
16070
|
-
return
|
|
16398
|
+
return path8.join(getSnapshotsDir(), `${safe}.json`);
|
|
16071
16399
|
}
|
|
16072
16400
|
function saveSnapshot2(snapshot) {
|
|
16073
16401
|
try {
|
|
@@ -17286,12 +17614,12 @@ var require_credentialIO = __commonJS({
|
|
|
17286
17614
|
exports.readActiveCredentials = readActiveCredentials;
|
|
17287
17615
|
exports.writeActiveCredentials = writeActiveCredentials;
|
|
17288
17616
|
var fs9 = __importStar(__require("fs"));
|
|
17289
|
-
var
|
|
17290
|
-
var
|
|
17617
|
+
var path8 = __importStar(__require("path"));
|
|
17618
|
+
var os6 = __importStar(__require("os"));
|
|
17291
17619
|
var child_process_1 = __require("child_process");
|
|
17292
17620
|
var KEYCHAIN_SERVICE = "Claude Code-credentials";
|
|
17293
17621
|
function getCredentialsFilePath() {
|
|
17294
|
-
return
|
|
17622
|
+
return path8.join(os6.homedir(), ".claude", ".credentials.json");
|
|
17295
17623
|
}
|
|
17296
17624
|
function readActiveCredentials() {
|
|
17297
17625
|
if (process.platform === "darwin") {
|
|
@@ -17436,28 +17764,28 @@ var require_accounts = __commonJS({
|
|
|
17436
17764
|
exports.getActiveAccount = getActiveAccount3;
|
|
17437
17765
|
exports.isMultiAccountEnabled = isMultiAccountEnabled;
|
|
17438
17766
|
var fs9 = __importStar(__require("fs"));
|
|
17439
|
-
var
|
|
17440
|
-
var
|
|
17767
|
+
var path8 = __importStar(__require("path"));
|
|
17768
|
+
var os6 = __importStar(__require("os"));
|
|
17441
17769
|
var credentialIO_1 = require_credentialIO();
|
|
17442
17770
|
var accountRegistry_1 = require_accountRegistry();
|
|
17443
17771
|
function getClaudeDir() {
|
|
17444
|
-
return
|
|
17772
|
+
return path8.join(os6.homedir(), ".claude");
|
|
17445
17773
|
}
|
|
17446
17774
|
function getClaudeConfigPath() {
|
|
17447
|
-
const primary =
|
|
17775
|
+
const primary = path8.join(getClaudeDir(), ".claude.json");
|
|
17448
17776
|
try {
|
|
17449
17777
|
const data = JSON.parse(fs9.readFileSync(primary, "utf8"));
|
|
17450
17778
|
if (data?.oauthAccount)
|
|
17451
17779
|
return primary;
|
|
17452
17780
|
} catch {
|
|
17453
17781
|
}
|
|
17454
|
-
return
|
|
17782
|
+
return path8.join(os6.homedir(), ".claude.json");
|
|
17455
17783
|
}
|
|
17456
17784
|
function getCredentialsDir() {
|
|
17457
|
-
return
|
|
17785
|
+
return path8.join((0, accountRegistry_1.getAccountsDir)(), "credentials");
|
|
17458
17786
|
}
|
|
17459
17787
|
function getConfigsDir() {
|
|
17460
|
-
return
|
|
17788
|
+
return path8.join((0, accountRegistry_1.getAccountsDir)(), "configs");
|
|
17461
17789
|
}
|
|
17462
17790
|
function ensureDirs() {
|
|
17463
17791
|
for (const dir of [(0, accountRegistry_1.getAccountsDir)(), getCredentialsDir(), getConfigsDir()]) {
|
|
@@ -17540,14 +17868,14 @@ var require_accounts = __commonJS({
|
|
|
17540
17868
|
if (existing) {
|
|
17541
17869
|
if (label !== void 0)
|
|
17542
17870
|
existing.label = label;
|
|
17543
|
-
atomicWriteJson(
|
|
17544
|
-
atomicWriteJson(
|
|
17871
|
+
atomicWriteJson(path8.join(getCredentialsDir(), `${active.uuid}.credentials.json`), credBlob);
|
|
17872
|
+
atomicWriteJson(path8.join(getConfigsDir(), `${active.uuid}.config.json`), configBlob);
|
|
17545
17873
|
registry.activeAccountUuid = active.uuid;
|
|
17546
17874
|
writeAccountRegistry(registry);
|
|
17547
17875
|
return { success: true };
|
|
17548
17876
|
}
|
|
17549
|
-
atomicWriteJson(
|
|
17550
|
-
atomicWriteJson(
|
|
17877
|
+
atomicWriteJson(path8.join(getCredentialsDir(), `${active.uuid}.credentials.json`), credBlob);
|
|
17878
|
+
atomicWriteJson(path8.join(getConfigsDir(), `${active.uuid}.config.json`), configBlob);
|
|
17551
17879
|
registry.accounts.push({
|
|
17552
17880
|
uuid: active.uuid,
|
|
17553
17881
|
email: active.email,
|
|
@@ -17581,7 +17909,7 @@ var require_accounts = __commonJS({
|
|
|
17581
17909
|
if (currentActive) {
|
|
17582
17910
|
if (originalCreds) {
|
|
17583
17911
|
try {
|
|
17584
|
-
atomicWriteJson(
|
|
17912
|
+
atomicWriteJson(path8.join(getCredentialsDir(), `${currentActive.uuid}.credentials.json`), originalCreds);
|
|
17585
17913
|
} catch {
|
|
17586
17914
|
}
|
|
17587
17915
|
}
|
|
@@ -17589,7 +17917,7 @@ var require_accounts = __commonJS({
|
|
|
17589
17917
|
try {
|
|
17590
17918
|
const parsed = JSON.parse(originalConfig);
|
|
17591
17919
|
if (parsed.oauthAccount) {
|
|
17592
|
-
atomicWriteJson(
|
|
17920
|
+
atomicWriteJson(path8.join(getConfigsDir(), `${currentActive.uuid}.config.json`), parsed.oauthAccount);
|
|
17593
17921
|
}
|
|
17594
17922
|
} catch {
|
|
17595
17923
|
}
|
|
@@ -17598,12 +17926,12 @@ var require_accounts = __commonJS({
|
|
|
17598
17926
|
let targetCreds;
|
|
17599
17927
|
let targetOauthAccount;
|
|
17600
17928
|
try {
|
|
17601
|
-
targetCreds = JSON.parse(fs9.readFileSync(
|
|
17929
|
+
targetCreds = JSON.parse(fs9.readFileSync(path8.join(getCredentialsDir(), `${uuid}.credentials.json`), "utf8"));
|
|
17602
17930
|
} catch {
|
|
17603
17931
|
return { success: false, error: `Backed-up credentials for ${target.email} not found.` };
|
|
17604
17932
|
}
|
|
17605
17933
|
try {
|
|
17606
|
-
targetOauthAccount = JSON.parse(fs9.readFileSync(
|
|
17934
|
+
targetOauthAccount = JSON.parse(fs9.readFileSync(path8.join(getConfigsDir(), `${uuid}.config.json`), "utf8"));
|
|
17607
17935
|
} catch {
|
|
17608
17936
|
return { success: false, error: `Backed-up config for ${target.email} not found.` };
|
|
17609
17937
|
}
|
|
@@ -17655,11 +17983,11 @@ var require_accounts = __commonJS({
|
|
|
17655
17983
|
return { success: false, error: `Account ${uuid} not found.` };
|
|
17656
17984
|
}
|
|
17657
17985
|
try {
|
|
17658
|
-
fs9.unlinkSync(
|
|
17986
|
+
fs9.unlinkSync(path8.join(getCredentialsDir(), `${uuid}.credentials.json`));
|
|
17659
17987
|
} catch {
|
|
17660
17988
|
}
|
|
17661
17989
|
try {
|
|
17662
|
-
fs9.unlinkSync(
|
|
17990
|
+
fs9.unlinkSync(path8.join(getConfigsDir(), `${uuid}.config.json`));
|
|
17663
17991
|
} catch {
|
|
17664
17992
|
}
|
|
17665
17993
|
registry.accounts.splice(idx, 1);
|
|
@@ -18052,10 +18380,10 @@ var require_quotaSnapshots = __commonJS({
|
|
|
18052
18380
|
exports.writeQuotaSnapshot = writeQuotaSnapshot2;
|
|
18053
18381
|
exports.readQuotaSnapshot = readQuotaSnapshot2;
|
|
18054
18382
|
var fs9 = __importStar(__require("fs"));
|
|
18055
|
-
var
|
|
18383
|
+
var path8 = __importStar(__require("path"));
|
|
18056
18384
|
var paths_1 = require_paths();
|
|
18057
18385
|
function getQuotaSnapshotPath() {
|
|
18058
|
-
return
|
|
18386
|
+
return path8.join((0, paths_1.getConfigDir)(), "quota-snapshots.json");
|
|
18059
18387
|
}
|
|
18060
18388
|
function ensureConfigDir() {
|
|
18061
18389
|
fs9.mkdirSync((0, paths_1.getConfigDir)(), { recursive: true, mode: 448 });
|
|
@@ -18147,109 +18475,175 @@ var require_codexQuota = __commonJS({
|
|
|
18147
18475
|
}
|
|
18148
18476
|
});
|
|
18149
18477
|
|
|
18150
|
-
// ../sidekick-shared/dist/
|
|
18151
|
-
var
|
|
18152
|
-
"../sidekick-shared/dist/
|
|
18478
|
+
// ../sidekick-shared/dist/pricingCatalog.js
|
|
18479
|
+
var require_pricingCatalog = __commonJS({
|
|
18480
|
+
"../sidekick-shared/dist/pricingCatalog.js"(exports) {
|
|
18153
18481
|
"use strict";
|
|
18482
|
+
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
|
|
18483
|
+
if (k2 === void 0) k2 = k;
|
|
18484
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18485
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18486
|
+
desc = { enumerable: true, get: function() {
|
|
18487
|
+
return m[k];
|
|
18488
|
+
} };
|
|
18489
|
+
}
|
|
18490
|
+
Object.defineProperty(o, k2, desc);
|
|
18491
|
+
} : function(o, m, k, k2) {
|
|
18492
|
+
if (k2 === void 0) k2 = k;
|
|
18493
|
+
o[k2] = m[k];
|
|
18494
|
+
});
|
|
18495
|
+
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
|
|
18496
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18497
|
+
} : function(o, v) {
|
|
18498
|
+
o["default"] = v;
|
|
18499
|
+
});
|
|
18500
|
+
var __importStar = exports && exports.__importStar || /* @__PURE__ */ function() {
|
|
18501
|
+
var ownKeys = function(o) {
|
|
18502
|
+
ownKeys = Object.getOwnPropertyNames || function(o2) {
|
|
18503
|
+
var ar = [];
|
|
18504
|
+
for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
|
|
18505
|
+
return ar;
|
|
18506
|
+
};
|
|
18507
|
+
return ownKeys(o);
|
|
18508
|
+
};
|
|
18509
|
+
return function(mod) {
|
|
18510
|
+
if (mod && mod.__esModule) return mod;
|
|
18511
|
+
var result = {};
|
|
18512
|
+
if (mod != null) {
|
|
18513
|
+
for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
18514
|
+
}
|
|
18515
|
+
__setModuleDefault(result, mod);
|
|
18516
|
+
return result;
|
|
18517
|
+
};
|
|
18518
|
+
}();
|
|
18154
18519
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18155
|
-
exports.
|
|
18156
|
-
exports.
|
|
18157
|
-
exports.
|
|
18158
|
-
|
|
18159
|
-
|
|
18160
|
-
|
|
18161
|
-
|
|
18162
|
-
var
|
|
18163
|
-
|
|
18164
|
-
|
|
18165
|
-
|
|
18166
|
-
|
|
18167
|
-
|
|
18168
|
-
|
|
18169
|
-
|
|
18170
|
-
|
|
18171
|
-
|
|
18172
|
-
|
|
18173
|
-
|
|
18174
|
-
|
|
18175
|
-
|
|
18176
|
-
|
|
18177
|
-
outputCostPerMillion: 15,
|
|
18178
|
-
cacheWriteCostPerMillion: 3.75,
|
|
18179
|
-
cacheReadCostPerMillion: 0.3
|
|
18180
|
-
},
|
|
18181
|
-
"sonnet-4": {
|
|
18182
|
-
inputCostPerMillion: 3,
|
|
18183
|
-
outputCostPerMillion: 15,
|
|
18184
|
-
cacheWriteCostPerMillion: 3.75,
|
|
18185
|
-
cacheReadCostPerMillion: 0.3
|
|
18186
|
-
},
|
|
18187
|
-
"sonnet-4.6": {
|
|
18188
|
-
inputCostPerMillion: 3,
|
|
18189
|
-
outputCostPerMillion: 15,
|
|
18190
|
-
cacheWriteCostPerMillion: 3.75,
|
|
18191
|
-
cacheReadCostPerMillion: 0.3
|
|
18192
|
-
},
|
|
18193
|
-
"opus-4.5": {
|
|
18194
|
-
inputCostPerMillion: 5,
|
|
18195
|
-
outputCostPerMillion: 25,
|
|
18196
|
-
cacheWriteCostPerMillion: 6.25,
|
|
18197
|
-
cacheReadCostPerMillion: 0.5
|
|
18198
|
-
},
|
|
18199
|
-
"opus-4": {
|
|
18200
|
-
inputCostPerMillion: 15,
|
|
18201
|
-
outputCostPerMillion: 75,
|
|
18202
|
-
cacheWriteCostPerMillion: 18.75,
|
|
18203
|
-
cacheReadCostPerMillion: 1.5
|
|
18204
|
-
},
|
|
18205
|
-
"opus-4.6": {
|
|
18206
|
-
inputCostPerMillion: 15,
|
|
18207
|
-
outputCostPerMillion: 75,
|
|
18208
|
-
cacheWriteCostPerMillion: 18.75,
|
|
18209
|
-
cacheReadCostPerMillion: 1.5
|
|
18520
|
+
exports.LITELLM_CATALOG_URL = void 0;
|
|
18521
|
+
exports.hydratePricingCatalog = hydratePricingCatalog2;
|
|
18522
|
+
exports.normalizeLiteLlmCatalog = normalizeLiteLlmCatalog;
|
|
18523
|
+
var node_fs_1 = __require("node:fs");
|
|
18524
|
+
var path8 = __importStar(__require("node:path"));
|
|
18525
|
+
var modelInfo_1 = require_modelInfo();
|
|
18526
|
+
exports.LITELLM_CATALOG_URL = "https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json";
|
|
18527
|
+
var CACHE_FILE_NAME = "pricing-catalog.json";
|
|
18528
|
+
var DEFAULT_TTL_MS = 24 * 60 * 60 * 1e3;
|
|
18529
|
+
var DEFAULT_TIMEOUT_MS = 3e3;
|
|
18530
|
+
async function hydratePricingCatalog2(options) {
|
|
18531
|
+
const { cacheDir, fetchImpl = globalThis.fetch, ttlMs = DEFAULT_TTL_MS, timeoutMs = DEFAULT_TIMEOUT_MS, url = exports.LITELLM_CATALOG_URL, logger } = options;
|
|
18532
|
+
const cachePath = path8.join(cacheDir, CACHE_FILE_NAME);
|
|
18533
|
+
const now = Date.now();
|
|
18534
|
+
const cached = await readCache(cachePath);
|
|
18535
|
+
if (cached && now - Date.parse(cached.fetchedAt) < ttlMs) {
|
|
18536
|
+
(0, modelInfo_1._setPricingOverrides)(cached.overrides);
|
|
18537
|
+
return {
|
|
18538
|
+
source: "cache",
|
|
18539
|
+
entries: Object.keys(cached.overrides).length,
|
|
18540
|
+
fetchedAt: cached.fetchedAt
|
|
18541
|
+
};
|
|
18210
18542
|
}
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18543
|
+
if (fetchImpl) {
|
|
18544
|
+
const fetched = await fetchCatalog(url, fetchImpl, timeoutMs, logger);
|
|
18545
|
+
if (fetched) {
|
|
18546
|
+
const overrides = normalizeLiteLlmCatalog(fetched);
|
|
18547
|
+
const payload = {
|
|
18548
|
+
fetchedAt: new Date(now).toISOString(),
|
|
18549
|
+
url,
|
|
18550
|
+
overrides
|
|
18551
|
+
};
|
|
18552
|
+
await writeCache(cachePath, payload, logger);
|
|
18553
|
+
(0, modelInfo_1._setPricingOverrides)(overrides);
|
|
18554
|
+
return {
|
|
18555
|
+
source: "network",
|
|
18556
|
+
entries: Object.keys(overrides).length,
|
|
18557
|
+
fetchedAt: payload.fetchedAt
|
|
18558
|
+
};
|
|
18559
|
+
}
|
|
18560
|
+
}
|
|
18561
|
+
if (cached) {
|
|
18562
|
+
(0, modelInfo_1._setPricingOverrides)(cached.overrides);
|
|
18563
|
+
return {
|
|
18564
|
+
source: "cache",
|
|
18565
|
+
entries: Object.keys(cached.overrides).length,
|
|
18566
|
+
fetchedAt: cached.fetchedAt
|
|
18567
|
+
};
|
|
18568
|
+
}
|
|
18569
|
+
return { source: "offline", entries: 0, fetchedAt: new Date(now).toISOString() };
|
|
18217
18570
|
}
|
|
18218
|
-
function
|
|
18219
|
-
const
|
|
18220
|
-
if (!
|
|
18221
|
-
return
|
|
18222
|
-
const
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
|
|
18227
|
-
|
|
18228
|
-
|
|
18229
|
-
|
|
18571
|
+
function normalizeLiteLlmCatalog(raw) {
|
|
18572
|
+
const out = {};
|
|
18573
|
+
if (!raw || typeof raw !== "object")
|
|
18574
|
+
return out;
|
|
18575
|
+
for (const [key, entry] of Object.entries(raw)) {
|
|
18576
|
+
if (key === "sample_spec")
|
|
18577
|
+
continue;
|
|
18578
|
+
if (!entry || typeof entry !== "object")
|
|
18579
|
+
continue;
|
|
18580
|
+
const pricing = liteLlmEntryToPricing(entry);
|
|
18581
|
+
if (!pricing)
|
|
18582
|
+
continue;
|
|
18583
|
+
out[key] = pricing;
|
|
18584
|
+
const bare = stripProviderPrefix(key);
|
|
18585
|
+
if (bare && bare !== key && !out[bare]) {
|
|
18586
|
+
out[bare] = pricing;
|
|
18587
|
+
}
|
|
18588
|
+
}
|
|
18589
|
+
return out;
|
|
18230
18590
|
}
|
|
18231
|
-
function
|
|
18232
|
-
const
|
|
18591
|
+
function liteLlmEntryToPricing(entry) {
|
|
18592
|
+
const input = entry.input_cost_per_token;
|
|
18593
|
+
const output = entry.output_cost_per_token;
|
|
18594
|
+
if (typeof input !== "number" || typeof output !== "number")
|
|
18595
|
+
return null;
|
|
18596
|
+
const cacheRead = typeof entry.cache_read_input_token_cost === "number" ? entry.cache_read_input_token_cost : typeof entry.input_cost_per_token_cached === "number" ? entry.input_cost_per_token_cached : 0;
|
|
18597
|
+
const cacheWrite = typeof entry.cache_creation_input_token_cost === "number" ? entry.cache_creation_input_token_cost : 0;
|
|
18233
18598
|
return {
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18599
|
+
inputCostPerMillion: input * 1e6,
|
|
18600
|
+
outputCostPerMillion: output * 1e6,
|
|
18601
|
+
cacheWriteCostPerMillion: cacheWrite * 1e6,
|
|
18602
|
+
cacheReadCostPerMillion: cacheRead * 1e6
|
|
18238
18603
|
};
|
|
18239
18604
|
}
|
|
18240
|
-
function
|
|
18241
|
-
const
|
|
18242
|
-
if (
|
|
18243
|
-
return
|
|
18244
|
-
return
|
|
18605
|
+
function stripProviderPrefix(key) {
|
|
18606
|
+
const slash = key.indexOf("/");
|
|
18607
|
+
if (slash < 0)
|
|
18608
|
+
return null;
|
|
18609
|
+
return key.slice(slash + 1);
|
|
18245
18610
|
}
|
|
18246
|
-
function
|
|
18247
|
-
|
|
18611
|
+
async function readCache(cachePath) {
|
|
18612
|
+
try {
|
|
18613
|
+
const raw = await node_fs_1.promises.readFile(cachePath, "utf8");
|
|
18614
|
+
const parsed = JSON.parse(raw);
|
|
18615
|
+
if (!parsed || typeof parsed !== "object" || typeof parsed.fetchedAt !== "string" || !parsed.overrides || typeof parsed.overrides !== "object") {
|
|
18616
|
+
return null;
|
|
18617
|
+
}
|
|
18618
|
+
return parsed;
|
|
18619
|
+
} catch {
|
|
18620
|
+
return null;
|
|
18621
|
+
}
|
|
18248
18622
|
}
|
|
18249
|
-
function
|
|
18250
|
-
|
|
18251
|
-
|
|
18252
|
-
|
|
18623
|
+
async function writeCache(cachePath, payload, logger) {
|
|
18624
|
+
try {
|
|
18625
|
+
await node_fs_1.promises.mkdir(path8.dirname(cachePath), { recursive: true });
|
|
18626
|
+
await node_fs_1.promises.writeFile(cachePath, JSON.stringify(payload, null, 2), "utf8");
|
|
18627
|
+
} catch (err) {
|
|
18628
|
+
logger?.(`pricingCatalog: failed to write cache: ${String(err)}`);
|
|
18629
|
+
}
|
|
18630
|
+
}
|
|
18631
|
+
async function fetchCatalog(url, fetchImpl, timeoutMs, logger) {
|
|
18632
|
+
const controller = new AbortController();
|
|
18633
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
18634
|
+
try {
|
|
18635
|
+
const res = await fetchImpl(url, { signal: controller.signal });
|
|
18636
|
+
if (!res.ok) {
|
|
18637
|
+
logger?.(`pricingCatalog: HTTP ${res.status} from ${url}`);
|
|
18638
|
+
return null;
|
|
18639
|
+
}
|
|
18640
|
+
return await res.json();
|
|
18641
|
+
} catch (err) {
|
|
18642
|
+
logger?.(`pricingCatalog: fetch failed: ${String(err)}`);
|
|
18643
|
+
return null;
|
|
18644
|
+
} finally {
|
|
18645
|
+
clearTimeout(timer);
|
|
18646
|
+
}
|
|
18253
18647
|
}
|
|
18254
18648
|
}
|
|
18255
18649
|
});
|
|
@@ -18562,10 +18956,10 @@ var require_util = __commonJS({
|
|
|
18562
18956
|
function cloneDef(schema) {
|
|
18563
18957
|
return mergeDefs(schema._zod.def);
|
|
18564
18958
|
}
|
|
18565
|
-
function getElementAtPath(obj,
|
|
18566
|
-
if (!
|
|
18959
|
+
function getElementAtPath(obj, path8) {
|
|
18960
|
+
if (!path8)
|
|
18567
18961
|
return obj;
|
|
18568
|
-
return
|
|
18962
|
+
return path8.reduce((acc, key) => acc?.[key], obj);
|
|
18569
18963
|
}
|
|
18570
18964
|
function promiseAllObject(promisesObj) {
|
|
18571
18965
|
const keys = Object.keys(promisesObj);
|
|
@@ -18949,11 +19343,11 @@ var require_util = __commonJS({
|
|
|
18949
19343
|
}
|
|
18950
19344
|
return false;
|
|
18951
19345
|
}
|
|
18952
|
-
function prefixIssues(
|
|
19346
|
+
function prefixIssues(path8, issues) {
|
|
18953
19347
|
return issues.map((iss) => {
|
|
18954
19348
|
var _a;
|
|
18955
19349
|
(_a = iss).path ?? (_a.path = []);
|
|
18956
|
-
iss.path.unshift(
|
|
19350
|
+
iss.path.unshift(path8);
|
|
18957
19351
|
return iss;
|
|
18958
19352
|
});
|
|
18959
19353
|
}
|
|
@@ -19178,7 +19572,7 @@ var require_errors = __commonJS({
|
|
|
19178
19572
|
}
|
|
19179
19573
|
function treeifyError(error, mapper = (issue) => issue.message) {
|
|
19180
19574
|
const result = { errors: [] };
|
|
19181
|
-
const processError = (error2,
|
|
19575
|
+
const processError = (error2, path8 = []) => {
|
|
19182
19576
|
var _a, _b;
|
|
19183
19577
|
for (const issue of error2.issues) {
|
|
19184
19578
|
if (issue.code === "invalid_union" && issue.errors.length) {
|
|
@@ -19188,7 +19582,7 @@ var require_errors = __commonJS({
|
|
|
19188
19582
|
} else if (issue.code === "invalid_element") {
|
|
19189
19583
|
processError({ issues: issue.issues }, issue.path);
|
|
19190
19584
|
} else {
|
|
19191
|
-
const fullpath = [...
|
|
19585
|
+
const fullpath = [...path8, ...issue.path];
|
|
19192
19586
|
if (fullpath.length === 0) {
|
|
19193
19587
|
result.errors.push(mapper(issue));
|
|
19194
19588
|
continue;
|
|
@@ -19220,8 +19614,8 @@ var require_errors = __commonJS({
|
|
|
19220
19614
|
}
|
|
19221
19615
|
function toDotPath(_path) {
|
|
19222
19616
|
const segs = [];
|
|
19223
|
-
const
|
|
19224
|
-
for (const seg of
|
|
19617
|
+
const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
19618
|
+
for (const seg of path8) {
|
|
19225
19619
|
if (typeof seg === "number")
|
|
19226
19620
|
segs.push(`[${seg}]`);
|
|
19227
19621
|
else if (typeof seg === "symbol")
|
|
@@ -33722,13 +34116,13 @@ var require_from_json_schema = __commonJS({
|
|
|
33722
34116
|
if (!ref.startsWith("#")) {
|
|
33723
34117
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
33724
34118
|
}
|
|
33725
|
-
const
|
|
33726
|
-
if (
|
|
34119
|
+
const path8 = ref.slice(1).split("/").filter(Boolean);
|
|
34120
|
+
if (path8.length === 0) {
|
|
33727
34121
|
return ctx.rootSchema;
|
|
33728
34122
|
}
|
|
33729
34123
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
33730
|
-
if (
|
|
33731
|
-
const key =
|
|
34124
|
+
if (path8[0] === defsKey) {
|
|
34125
|
+
const key = path8[1];
|
|
33732
34126
|
if (!key || !ctx.defs[key]) {
|
|
33733
34127
|
throw new Error(`Reference not found: ${ref}`);
|
|
33734
34128
|
}
|
|
@@ -34436,8 +34830,8 @@ var require_dist = __commonJS({
|
|
|
34436
34830
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34437
34831
|
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;
|
|
34438
34832
|
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;
|
|
34439
|
-
exports.
|
|
34440
|
-
exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.extractToolCalls = exports.extractTokenUsage = void 0;
|
|
34833
|
+
exports.calculateCost = exports.getModelInfo = exports.getModelPricing = exports.parseModelId = exports.DEFAULT_CONTEXT_WINDOW = exports.getModelContextWindowSize = exports.quotaFromCodexRateLimits = exports.writeQuotaSnapshot = exports.readQuotaSnapshot = exports.QuotaPoller = exports.describeQuotaFailure = exports.fetchQuota = exports.removeCodexAccount = exports.switchToCodexAccount = exports.finalizeCodexAccount = exports.prepareCodexAccount = exports.getCodexExecutionEnv = exports.resolveSidekickCodexHome = exports.getActiveCodexAccount = exports.listCodexAccounts = exports.getSystemCodexHome = exports.getCodexMonitoringHomes = exports.getCodexProfileHome = exports.getCodexProfilesDir = exports.removeSavedAccountProfile = exports.replaceSavedAccountProfiles = exports.setActiveSavedAccount = exports.upsertSavedAccountProfile = exports.getActiveSavedAccount = exports.listSavedAccountProfiles = exports.writeSavedAccountRegistry = exports.readSavedAccountRegistry = exports.getAccountsDir = exports.isMultiAccountEnabled = exports.getActiveAccount = exports.listAccounts = exports.removeAccount = exports.switchToAccount = exports.addCurrentAccount = exports.readActiveClaudeAccount = exports.writeAccountRegistry = exports.readAccountRegistry = exports.readClaudeMaxAccessTokenSync = exports.readClaudeMaxCredentials = exports.writeActiveCredentials = exports.readActiveCredentials = exports.openInBrowser = exports.parseTranscript = exports.generateHtmlReport = exports.PatternExtractor = void 0;
|
|
34834
|
+
exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.extractToolCalls = exports.extractTokenUsage = exports.LITELLM_CATALOG_URL = exports.normalizeLiteLlmCatalog = exports.hydratePricingCatalog = exports.formatCost = exports.calculateCostWithPricing = void 0;
|
|
34441
34835
|
var taskPersistence_1 = require_taskPersistence();
|
|
34442
34836
|
Object.defineProperty(exports, "TASK_PERSISTENCE_SCHEMA_VERSION", { enumerable: true, get: function() {
|
|
34443
34837
|
return taskPersistence_1.TASK_PERSISTENCE_SCHEMA_VERSION;
|
|
@@ -34871,6 +35265,12 @@ var require_dist = __commonJS({
|
|
|
34871
35265
|
Object.defineProperty(exports, "getCodexProfileHome", { enumerable: true, get: function() {
|
|
34872
35266
|
return codexProfiles_1.getCodexProfileHome;
|
|
34873
35267
|
} });
|
|
35268
|
+
Object.defineProperty(exports, "getCodexMonitoringHomes", { enumerable: true, get: function() {
|
|
35269
|
+
return codexProfiles_1.getCodexMonitoringHomes;
|
|
35270
|
+
} });
|
|
35271
|
+
Object.defineProperty(exports, "getSystemCodexHome", { enumerable: true, get: function() {
|
|
35272
|
+
return codexProfiles_1.getSystemCodexHome;
|
|
35273
|
+
} });
|
|
34874
35274
|
Object.defineProperty(exports, "listCodexAccounts", { enumerable: true, get: function() {
|
|
34875
35275
|
return codexProfiles_1.listCodexAccounts;
|
|
34876
35276
|
} });
|
|
@@ -34944,6 +35344,16 @@ var require_dist = __commonJS({
|
|
|
34944
35344
|
Object.defineProperty(exports, "formatCost", { enumerable: true, get: function() {
|
|
34945
35345
|
return modelInfo_1.formatCost;
|
|
34946
35346
|
} });
|
|
35347
|
+
var pricingCatalog_1 = require_pricingCatalog();
|
|
35348
|
+
Object.defineProperty(exports, "hydratePricingCatalog", { enumerable: true, get: function() {
|
|
35349
|
+
return pricingCatalog_1.hydratePricingCatalog;
|
|
35350
|
+
} });
|
|
35351
|
+
Object.defineProperty(exports, "normalizeLiteLlmCatalog", { enumerable: true, get: function() {
|
|
35352
|
+
return pricingCatalog_1.normalizeLiteLlmCatalog;
|
|
35353
|
+
} });
|
|
35354
|
+
Object.defineProperty(exports, "LITELLM_CATALOG_URL", { enumerable: true, get: function() {
|
|
35355
|
+
return pricingCatalog_1.LITELLM_CATALOG_URL;
|
|
35356
|
+
} });
|
|
34947
35357
|
var tokenUsage_1 = require_tokenUsage();
|
|
34948
35358
|
Object.defineProperty(exports, "extractTokenUsage", { enumerable: true, get: function() {
|
|
34949
35359
|
return tokenUsage_1.extractTokenUsage;
|
|
@@ -36682,7 +37092,8 @@ var init_DashboardState = __esm({
|
|
|
36682
37092
|
model: ms.model,
|
|
36683
37093
|
calls: ms.calls,
|
|
36684
37094
|
tokens: ms.tokens,
|
|
36685
|
-
cost: ms.cost
|
|
37095
|
+
cost: ms.cost,
|
|
37096
|
+
priced: ms.priced
|
|
36686
37097
|
}));
|
|
36687
37098
|
const taskMap = /* @__PURE__ */ new Map();
|
|
36688
37099
|
for (const t of m.taskState.tasks.values()) {
|
|
@@ -37187,7 +37598,7 @@ var init_UpdateCheckService = __esm({
|
|
|
37187
37598
|
/** Run the update check (one-shot). */
|
|
37188
37599
|
async check() {
|
|
37189
37600
|
try {
|
|
37190
|
-
const current = "0.17.
|
|
37601
|
+
const current = "0.17.2";
|
|
37191
37602
|
const cached = this.readCache();
|
|
37192
37603
|
let latest;
|
|
37193
37604
|
if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
|
|
@@ -38757,7 +39168,8 @@ ${hint}{/grey-fg}`;
|
|
|
38757
39168
|
lines.push("", sectionHeader("Model Usage", w2));
|
|
38758
39169
|
for (const ms of m.modelStats) {
|
|
38759
39170
|
const modelName = ms.model.length > 20 ? ms.model.substring(0, 17) + "..." : ms.model;
|
|
38760
|
-
|
|
39171
|
+
const costDisplay = ms.priced === false ? "{yellow-fg}\u2014{/yellow-fg}" : `{green-fg}${(0, import_sidekick_shared11.formatCost)(ms.cost)}{/green-fg}`;
|
|
39172
|
+
lines.push(` ${modelName.padEnd(20)} {bold}${String(ms.calls).padStart(4)}{/bold}{grey-fg} calls{/grey-fg} ${costDisplay}`);
|
|
38761
39173
|
}
|
|
38762
39174
|
}
|
|
38763
39175
|
const quotaLabel = m.providerId === "codex" ? "Rate Limits" : "Quota";
|
|
@@ -51571,10 +51983,10 @@ var require_react_reconciler_development = __commonJS({
|
|
|
51571
51983
|
fiber = fiber.next, id--;
|
|
51572
51984
|
return fiber;
|
|
51573
51985
|
}
|
|
51574
|
-
function copyWithSetImpl(obj,
|
|
51575
|
-
if (index >=
|
|
51576
|
-
var key =
|
|
51577
|
-
updated[key] = copyWithSetImpl(obj[key],
|
|
51986
|
+
function copyWithSetImpl(obj, path8, index, value) {
|
|
51987
|
+
if (index >= path8.length) return value;
|
|
51988
|
+
var key = path8[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
|
|
51989
|
+
updated[key] = copyWithSetImpl(obj[key], path8, index + 1, value);
|
|
51578
51990
|
return updated;
|
|
51579
51991
|
}
|
|
51580
51992
|
function copyWithRename(obj, oldPath, newPath) {
|
|
@@ -51601,11 +52013,11 @@ var require_react_reconciler_development = __commonJS({
|
|
|
51601
52013
|
);
|
|
51602
52014
|
return updated;
|
|
51603
52015
|
}
|
|
51604
|
-
function copyWithDeleteImpl(obj,
|
|
51605
|
-
var key =
|
|
51606
|
-
if (index + 1 ===
|
|
52016
|
+
function copyWithDeleteImpl(obj, path8, index) {
|
|
52017
|
+
var key = path8[index], updated = isArrayImpl(obj) ? obj.slice() : assign({}, obj);
|
|
52018
|
+
if (index + 1 === path8.length)
|
|
51607
52019
|
return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
|
|
51608
|
-
updated[key] = copyWithDeleteImpl(obj[key],
|
|
52020
|
+
updated[key] = copyWithDeleteImpl(obj[key], path8, index + 1);
|
|
51609
52021
|
return updated;
|
|
51610
52022
|
}
|
|
51611
52023
|
function shouldSuspendImpl() {
|
|
@@ -64882,29 +65294,29 @@ var require_react_reconciler_development = __commonJS({
|
|
|
64882
65294
|
var didWarnAboutNestedUpdates = false;
|
|
64883
65295
|
var didWarnAboutFindNodeInStrictMode = {};
|
|
64884
65296
|
var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
|
|
64885
|
-
overrideHookState = function(fiber, id,
|
|
65297
|
+
overrideHookState = function(fiber, id, path8, value) {
|
|
64886
65298
|
id = findHook(fiber, id);
|
|
64887
|
-
null !== id && (
|
|
65299
|
+
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));
|
|
64888
65300
|
};
|
|
64889
|
-
overrideHookStateDeletePath = function(fiber, id,
|
|
65301
|
+
overrideHookStateDeletePath = function(fiber, id, path8) {
|
|
64890
65302
|
id = findHook(fiber, id);
|
|
64891
|
-
null !== id && (
|
|
65303
|
+
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));
|
|
64892
65304
|
};
|
|
64893
65305
|
overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
|
|
64894
65306
|
id = findHook(fiber, id);
|
|
64895
65307
|
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));
|
|
64896
65308
|
};
|
|
64897
|
-
overrideProps = function(fiber,
|
|
64898
|
-
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps,
|
|
65309
|
+
overrideProps = function(fiber, path8, value) {
|
|
65310
|
+
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path8, 0, value);
|
|
64899
65311
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
64900
|
-
|
|
64901
|
-
null !==
|
|
65312
|
+
path8 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
65313
|
+
null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2);
|
|
64902
65314
|
};
|
|
64903
|
-
overridePropsDeletePath = function(fiber,
|
|
64904
|
-
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps,
|
|
65315
|
+
overridePropsDeletePath = function(fiber, path8) {
|
|
65316
|
+
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path8, 0);
|
|
64905
65317
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
64906
|
-
|
|
64907
|
-
null !==
|
|
65318
|
+
path8 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
65319
|
+
null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2);
|
|
64908
65320
|
};
|
|
64909
65321
|
overridePropsRenamePath = function(fiber, oldPath, newPath) {
|
|
64910
65322
|
fiber.pendingProps = copyWithRename(
|
|
@@ -74821,8 +75233,8 @@ var init_ErrorOverview = __esm({
|
|
|
74821
75233
|
init_dist3();
|
|
74822
75234
|
init_Box();
|
|
74823
75235
|
init_Text();
|
|
74824
|
-
cleanupPath = (
|
|
74825
|
-
return
|
|
75236
|
+
cleanupPath = (path8) => {
|
|
75237
|
+
return path8?.replace(`file://${cwd()}/`, "");
|
|
74826
75238
|
};
|
|
74827
75239
|
stackUtils = new import_stack_utils.default({
|
|
74828
75240
|
cwd: cwd(),
|
|
@@ -77804,7 +78216,7 @@ function StatusBar({
|
|
|
77804
78216
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: parseBlessedTags(BRAND_INLINE) }),
|
|
77805
78217
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
77806
78218
|
" v",
|
|
77807
|
-
"0.17.
|
|
78219
|
+
"0.17.2"
|
|
77808
78220
|
] }),
|
|
77809
78221
|
updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
77810
78222
|
" (v",
|
|
@@ -78194,7 +78606,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
|
|
|
78194
78606
|
" ",
|
|
78195
78607
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
|
|
78196
78608
|
"Terminal Dashboard v",
|
|
78197
|
-
"0.17.
|
|
78609
|
+
"0.17.2"
|
|
78198
78610
|
] }),
|
|
78199
78611
|
latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
|
|
78200
78612
|
" \u2014 ",
|
|
@@ -78516,7 +78928,7 @@ var init_mouse = __esm({
|
|
|
78516
78928
|
var CHANGELOG_default;
|
|
78517
78929
|
var init_CHANGELOG = __esm({
|
|
78518
78930
|
"CHANGELOG.md"() {
|
|
78519
|
-
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.17.0] - 2026-04-13\n\n### Added\n\n- **Multi-provider account management**: `sidekick account` now supports `--provider codex` for Codex profile management alongside Claude Code accounts\n- **Codex account lifecycle**: `--add` prepares a profile and spawns `codex login`; `--switch-to` and `--remove` accept email, label, or profile ID\n- **Quota snapshot fallback**: `sidekick quota` for Codex shows cached rate-limit snapshots when no active session exists, with "cached from" timestamp\n\n### Fixed\n\n- **Email normalization**: Claude account lookup normalizes email case for reliable matching\n\n## [0.16.1] - 2026-03-27\n\n### Fixed\n\n- **Dashboard provider status scoping**: The TUI now shows degraded-service notices only for the monitored provider \u2014 Claude for Claude Code sessions, OpenAI for Codex sessions, and no status banner for OpenCode\n\n## [0.16.0] - 2026-03-23\n\n### Changed\n\n- **Consistent cost formatting**: All cost displays (`stats`, `context`, Sessions panel, narrative prompt) now use shared `formatCost()` with intelligent decimal precision (4 places for < $0.01, 2 otherwise)\n- **QuotaService**: Rewritten to wrap shared `QuotaPoller` with exponential backoff instead of manual polling loop\n- **modelContext**: Now re-exports `getModelInfo` from shared library alongside `getContextWindowSize`\n\n## [0.15.2] - 2026-03-18\n\n### Fixed\n\n- **CLI help descriptions**: Updated `quota` and `status` command descriptions to reflect provider-aware behavior\n- **`sidekick quota --provider`**: Added local `--provider` option so `sidekick quota --provider codex` works naturally\n\n## [0.15.0] - 2026-03-18\n\n### Added\n\n- **OpenAI status page monitoring**: CLI dashboard now shows OpenAI API status alongside Claude API status\n- **Codex rate limits in dashboard**: Sessions panel displays Codex rate-limit data with "Rate Limits" header instead of "Quota"\n- **Provider-aware `sidekick quota` command**: Detects active provider and shows Codex rate limits, Claude subscription quota, or an informational message for OpenCode\n\n### Fixed\n\n- **QuotaService polling for Codex**: Dashboard no longer starts Claude OAuth quota polling when the active provider is Codex\n\n## [0.14.2] - 2026-03-16\n\n### Fixed\n\n- **Quota polling interval**: Reduced quota refresh from every 30 seconds to every 5 minutes to avoid unnecessary API calls\n- **SessionsPanel `detailWidth()` call**: Removed unused parameter from `detailWidth()` in the Sessions panel quota rendering\n\n## [0.14.1] - 2026-03-14\n\n### Fixed\n\n- **Per-model context window sizes**: Dashboard context gauge now shows correct utilization for Claude Opus 4.6 (1M context) and other models with non-200K windows\n\n### Changed\n\n- **Shared model context lookup**: CLI dashboard now uses the centralized `getModelContextWindowSize()` from `sidekick-shared` instead of a local duplicate map\n\n## [0.14.0] - 2026-03-12\n\n### Added\n\n- **`sidekick account` Command**: Manage Claude Code accounts from the terminal \u2014 list saved accounts, add the current account with an optional label, switch to the next or a specific account, and remove accounts. Supports `--json` output for scripting\n- **Quota Account Label**: `sidekick quota` now shows the active account email and label above the quota bars when multi-account is enabled\n- **macOS Keychain Support**: `sidekick account` and `sidekick quota` now read and write credentials via the system Keychain on macOS, fixing account switching and quota checks on Mac\n\n## [0.13.8] - 2026-03-12\n\n### Changed\n\n- **Structured quota failure output**: `sidekick quota` now renders consistent auth, rate-limit, server, network, and unexpected-failure copy from shared quota failure descriptors while preserving `--json` machine-readable output\n- **Dashboard unavailable quota rendering**: The Sessions panel now shows Claude Code quota failures inline instead of hiding the quota section whenever subscription data is unavailable\n- **Quota transition toasts**: The Ink dashboard now fires low-noise toast notifications only when Claude Code quota failure state changes, avoiding repeated alerts every polling interval\n\n## [0.13.7] - 2026-03-11\n\n### Changed\n\n- **npm README sync**: Updated the published CLI package README to reflect current OpenCode monitoring behavior, platform-specific data directories, and the `sqlite3` runtime requirement\n- **README badge cleanup**: Removed the Ask DeepWiki badge from the published CLI package README; the repo root README still keeps it\n\n## [0.13.6] - 2026-03-11\n\n### Changed\n\n- **Refreshed CLI Dashboard Wordmark**: Updated the dashboard wordmark/header styling for a cleaner splash and dashboard identity\n\n### Fixed\n\n- **OpenCode dashboard startup**: OpenCode DB-backed session discovery now resolves projects by worktree, sandboxes, and session directory instead of quietly behaving like no session exists\n- **OpenCode runtime notices**: The CLI now prints an OpenCode-only actionable notice when `opencode.db` exists but `sqlite3` is missing, blocked, or otherwise unusable in the current shell environment\n\n## [0.13.5] - 2026-03-10\n\n### Added\n\n- **`sidekick status` Command**: One-shot Claude API status check with color-coded text output and `--json` mode\n- **Dashboard Status Banner**: Status bar shows a colored `\u25CF API minor/major/critical` indicator when Claude is degraded; Sessions panel Summary tab shows an "API Status" section with affected components and active incident details. Polls every 60s\n\n## [0.13.4] - 2026-03-08\n\n### Fixed\n\n- **Onboarding Phrase Spam**: Splash screen and detail pane motivational phrases memoized \u2014 no longer flicker every render tick (fixes [#13](https://github.com/cesarandreslopez/sidekick-agent-hub/issues/13))\n\n### Changed\n\n- **Simplified Logo**: Replaced 6-line ASCII robot art with compact text header in splash, help, and changelog overlays\n- **Removed Dead Code**: Removed unused `getSplashContent()` and `HELP_HEADER` exports from branding module\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';
|
|
78931
|
+
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## [Unreleased]\n\n## [0.17.2] - 2026-04-17\n\n### Added\n\n- **LiteLLM pricing hydration on startup**: The CLI now fetches the LiteLLM pricing catalog on startup and caches to `~/.config/sidekick/pricing-catalog.json` with a 24-hour TTL, 3s timeout, and stale-cache fallback \u2014 new model prices are picked up without a CLI upgrade\n- **Expanded pricing coverage**: GPT-4o, GPT-4.1, GPT-5.x, o1, o3, and o3-mini families are now priced alongside the existing Claude entries\n- **Real-dollar Codex / Claude Code costs**: `EventAggregator` computes cost from the pricing table when the session provider doesn\'t report one, so `sidekick` live dashboards now show actual dollars for Codex and Claude Code sessions\n- **`stats` footer lists unpriced models**: `sidekick stats` prints any models encountered with no pricing entry so missing coverage is visible\n\n### Fixed\n\n- **Context-gauge % wrong for Opus 4.7 (1M) and other new models**: The dashboard\'s context gauge was dividing by 200K for Claude Opus 4.7 (native 1M), inflating the displayed %. The shared model \u2192 context-window map now includes Opus/Sonnet 4.7 (1M), GPT-5.4 (1.05M), GPT-5.3-Codex (400K), and GPT-5.3-Codex-Spark (128K). Claude Code\'s `[1m]` suffix is now also honored as an explicit 1M marker\n- **Silent Sonnet-priced fallback for unknown models**: Codex, GPT-5.x, and o-series rows were being rendered at Sonnet rates. Unknown-model rows now render as `\u2014` in yellow instead of inventing a dollar figure\n\n### Changed\n\n- **`historical-data.json` schema v2**: reads `priced` flag and `unpricedModelIds` from records written by the latest VS Code extension; v1 records still read correctly\n\n## [0.17.1] - 2026-04-13\n\n### Fixed\n\n- **Codex multi-home session discovery**: Provider detection now scans all candidate Codex home directories, fixing missed sessions when the managed profile home is empty but the system `~/.codex/` has activity\n\n## [0.17.0] - 2026-04-13\n\n### Added\n\n- **Multi-provider account management**: `sidekick account` now supports `--provider codex` for Codex profile management alongside Claude Code accounts\n- **Codex account lifecycle**: `--add` prepares a profile and spawns `codex login`; `--switch-to` and `--remove` accept email, label, or profile ID\n- **Quota snapshot fallback**: `sidekick quota` for Codex shows cached rate-limit snapshots when no active session exists, with "cached from" timestamp\n\n### Fixed\n\n- **Email normalization**: Claude account lookup normalizes email case for reliable matching\n\n## [0.16.1] - 2026-03-27\n\n### Fixed\n\n- **Dashboard provider status scoping**: The TUI now shows degraded-service notices only for the monitored provider \u2014 Claude for Claude Code sessions, OpenAI for Codex sessions, and no status banner for OpenCode\n\n## [0.16.0] - 2026-03-23\n\n### Changed\n\n- **Consistent cost formatting**: All cost displays (`stats`, `context`, Sessions panel, narrative prompt) now use shared `formatCost()` with intelligent decimal precision (4 places for < $0.01, 2 otherwise)\n- **QuotaService**: Rewritten to wrap shared `QuotaPoller` with exponential backoff instead of manual polling loop\n- **modelContext**: Now re-exports `getModelInfo` from shared library alongside `getContextWindowSize`\n\n## [0.15.2] - 2026-03-18\n\n### Fixed\n\n- **CLI help descriptions**: Updated `quota` and `status` command descriptions to reflect provider-aware behavior\n- **`sidekick quota --provider`**: Added local `--provider` option so `sidekick quota --provider codex` works naturally\n\n## [0.15.0] - 2026-03-18\n\n### Added\n\n- **OpenAI status page monitoring**: CLI dashboard now shows OpenAI API status alongside Claude API status\n- **Codex rate limits in dashboard**: Sessions panel displays Codex rate-limit data with "Rate Limits" header instead of "Quota"\n- **Provider-aware `sidekick quota` command**: Detects active provider and shows Codex rate limits, Claude subscription quota, or an informational message for OpenCode\n\n### Fixed\n\n- **QuotaService polling for Codex**: Dashboard no longer starts Claude OAuth quota polling when the active provider is Codex\n\n## [0.14.2] - 2026-03-16\n\n### Fixed\n\n- **Quota polling interval**: Reduced quota refresh from every 30 seconds to every 5 minutes to avoid unnecessary API calls\n- **SessionsPanel `detailWidth()` call**: Removed unused parameter from `detailWidth()` in the Sessions panel quota rendering\n\n## [0.14.1] - 2026-03-14\n\n### Fixed\n\n- **Per-model context window sizes**: Dashboard context gauge now shows correct utilization for Claude Opus 4.6 (1M context) and other models with non-200K windows\n\n### Changed\n\n- **Shared model context lookup**: CLI dashboard now uses the centralized `getModelContextWindowSize()` from `sidekick-shared` instead of a local duplicate map\n\n## [0.14.0] - 2026-03-12\n\n### Added\n\n- **`sidekick account` Command**: Manage Claude Code accounts from the terminal \u2014 list saved accounts, add the current account with an optional label, switch to the next or a specific account, and remove accounts. Supports `--json` output for scripting\n- **Quota Account Label**: `sidekick quota` now shows the active account email and label above the quota bars when multi-account is enabled\n- **macOS Keychain Support**: `sidekick account` and `sidekick quota` now read and write credentials via the system Keychain on macOS, fixing account switching and quota checks on Mac\n\n## [0.13.8] - 2026-03-12\n\n### Changed\n\n- **Structured quota failure output**: `sidekick quota` now renders consistent auth, rate-limit, server, network, and unexpected-failure copy from shared quota failure descriptors while preserving `--json` machine-readable output\n- **Dashboard unavailable quota rendering**: The Sessions panel now shows Claude Code quota failures inline instead of hiding the quota section whenever subscription data is unavailable\n- **Quota transition toasts**: The Ink dashboard now fires low-noise toast notifications only when Claude Code quota failure state changes, avoiding repeated alerts every polling interval\n\n## [0.13.7] - 2026-03-11\n\n### Changed\n\n- **npm README sync**: Updated the published CLI package README to reflect current OpenCode monitoring behavior, platform-specific data directories, and the `sqlite3` runtime requirement\n- **README badge cleanup**: Removed the Ask DeepWiki badge from the published CLI package README; the repo root README still keeps it\n\n## [0.13.6] - 2026-03-11\n\n### Changed\n\n- **Refreshed CLI Dashboard Wordmark**: Updated the dashboard wordmark/header styling for a cleaner splash and dashboard identity\n\n### Fixed\n\n- **OpenCode dashboard startup**: OpenCode DB-backed session discovery now resolves projects by worktree, sandboxes, and session directory instead of quietly behaving like no session exists\n- **OpenCode runtime notices**: The CLI now prints an OpenCode-only actionable notice when `opencode.db` exists but `sqlite3` is missing, blocked, or otherwise unusable in the current shell environment\n\n## [0.13.5] - 2026-03-10\n\n### Added\n\n- **`sidekick status` Command**: One-shot Claude API status check with color-coded text output and `--json` mode\n- **Dashboard Status Banner**: Status bar shows a colored `\u25CF API minor/major/critical` indicator when Claude is degraded; Sessions panel Summary tab shows an "API Status" section with affected components and active incident details. Polls every 60s\n\n## [0.13.4] - 2026-03-08\n\n### Fixed\n\n- **Onboarding Phrase Spam**: Splash screen and detail pane motivational phrases memoized \u2014 no longer flicker every render tick (fixes [#13](https://github.com/cesarandreslopez/sidekick-agent-hub/issues/13))\n\n### Changed\n\n- **Simplified Logo**: Replaced 6-line ASCII robot art with compact text header in splash, help, and changelog overlays\n- **Removed Dead Code**: Removed unused `getSplashContent()` and `HELP_HEADER` exports from branding module\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';
|
|
78520
78932
|
}
|
|
78521
78933
|
});
|
|
78522
78934
|
|
|
@@ -80149,8 +80561,8 @@ async function searchAction(_opts, cmd) {
|
|
|
80149
80561
|
const projectPath = globalOpts.project || void 0;
|
|
80150
80562
|
let projectSlug;
|
|
80151
80563
|
if (projectPath) {
|
|
80152
|
-
const
|
|
80153
|
-
const resolved =
|
|
80564
|
+
const path8 = await import("path");
|
|
80565
|
+
const resolved = path8.resolve(projectPath);
|
|
80154
80566
|
const { encodeWorkspacePath } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
|
|
80155
80567
|
projectSlug = encodeWorkspacePath(resolved);
|
|
80156
80568
|
}
|
|
@@ -80511,10 +80923,22 @@ function printStatsSummary(history) {
|
|
|
80511
80923
|
process.stdout.write(source_default.bold("Model Usage\n"));
|
|
80512
80924
|
process.stdout.write(source_default.dim("\u2500".repeat(50) + "\n"));
|
|
80513
80925
|
const sorted = [...at.modelUsage].sort((a, b) => b.calls - a.calls);
|
|
80926
|
+
const unpricedModels = [];
|
|
80514
80927
|
for (const m of sorted) {
|
|
80515
|
-
|
|
80928
|
+
let costStr = "";
|
|
80929
|
+
if (m.priced === false) {
|
|
80930
|
+
costStr = source_default.yellow(" (\u2014)");
|
|
80931
|
+
unpricedModels.push(m.model);
|
|
80932
|
+
} else if (m.cost > 0) {
|
|
80933
|
+
costStr = source_default.dim(` (${(0, import_sidekick_shared27.formatCost)(m.cost)})`);
|
|
80934
|
+
}
|
|
80516
80935
|
process.stdout.write(` ${source_default.cyan(m.model.padEnd(30))} ${formatNumber(m.calls).padStart(8)} calls${costStr}
|
|
80517
80936
|
`);
|
|
80937
|
+
}
|
|
80938
|
+
if (unpricedModels.length > 0) {
|
|
80939
|
+
const label = unpricedModels.length === 1 ? "1 model unpriced" : `${unpricedModels.length} models unpriced`;
|
|
80940
|
+
process.stdout.write(source_default.dim(` \u26A0 ${label}: ${unpricedModels.join(", ")} \u2014 no pricing catalog entry.
|
|
80941
|
+
`));
|
|
80518
80942
|
}
|
|
80519
80943
|
process.stdout.write("\n");
|
|
80520
80944
|
}
|
|
@@ -81229,6 +81653,8 @@ var init_handoff = __esm({
|
|
|
81229
81653
|
});
|
|
81230
81654
|
|
|
81231
81655
|
// src/cli.ts
|
|
81656
|
+
import * as os5 from "node:os";
|
|
81657
|
+
import * as path7 from "node:path";
|
|
81232
81658
|
function resolveProviderId(opts, defaultProvider = "auto") {
|
|
81233
81659
|
if (opts.provider && opts.provider !== "auto") {
|
|
81234
81660
|
return opts.provider;
|
|
@@ -81256,8 +81682,12 @@ var init_cli = __esm({
|
|
|
81256
81682
|
init_esm();
|
|
81257
81683
|
import_sidekick_shared32 = __toESM(require_dist(), 1);
|
|
81258
81684
|
import_sidekick_shared33 = __toESM(require_dist(), 1);
|
|
81685
|
+
(0, import_sidekick_shared32.hydratePricingCatalog)({
|
|
81686
|
+
cacheDir: path7.join(os5.homedir(), ".config", "sidekick")
|
|
81687
|
+
}).catch(() => {
|
|
81688
|
+
});
|
|
81259
81689
|
program2 = new Command();
|
|
81260
|
-
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.17.
|
|
81690
|
+
program2.name("sidekick").description("Query Sidekick project intelligence from the command line").version("0.17.2").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
|
|
81261
81691
|
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) => {
|
|
81262
81692
|
const { dashboardAction: dashboardAction2 } = await init_dashboard().then(() => dashboard_exports);
|
|
81263
81693
|
return dashboardAction2(_opts, cmd);
|