sidekick-agent-hub 0.17.1 → 0.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/sidekick-cli.mjs +767 -390
- 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 });
|
|
@@ -4520,13 +4520,13 @@ var require_codexProfiles = __commonJS({
|
|
|
4520
4520
|
exports.switchToCodexAccount = switchToCodexAccount2;
|
|
4521
4521
|
exports.removeCodexAccount = removeCodexAccount2;
|
|
4522
4522
|
var fs9 = __importStar(__require("fs"));
|
|
4523
|
-
var
|
|
4524
|
-
var
|
|
4523
|
+
var os6 = __importStar(__require("os"));
|
|
4524
|
+
var path8 = __importStar(__require("path"));
|
|
4525
4525
|
var child_process_1 = __require("child_process");
|
|
4526
4526
|
var crypto_1 = __require("crypto");
|
|
4527
4527
|
var accountRegistry_1 = require_accountRegistry();
|
|
4528
4528
|
function getDefaultSystemCodexHome() {
|
|
4529
|
-
return
|
|
4529
|
+
return path8.join(os6.homedir(), ".codex");
|
|
4530
4530
|
}
|
|
4531
4531
|
function getExplicitCodexHome() {
|
|
4532
4532
|
const explicitHome = process.env.CODEX_HOME?.trim();
|
|
@@ -4536,7 +4536,7 @@ var require_codexProfiles = __commonJS({
|
|
|
4536
4536
|
const seen = /* @__PURE__ */ new Set();
|
|
4537
4537
|
const unique = [];
|
|
4538
4538
|
for (const candidate of paths) {
|
|
4539
|
-
const normalized =
|
|
4539
|
+
const normalized = path8.resolve(candidate);
|
|
4540
4540
|
if (seen.has(normalized))
|
|
4541
4541
|
continue;
|
|
4542
4542
|
seen.add(normalized);
|
|
@@ -4560,16 +4560,16 @@ var require_codexProfiles = __commonJS({
|
|
|
4560
4560
|
return dedupePaths(homes);
|
|
4561
4561
|
}
|
|
4562
4562
|
function getCodexProfilesDir() {
|
|
4563
|
-
return
|
|
4563
|
+
return path8.join((0, accountRegistry_1.getAccountsDir)(), "codex", "profiles");
|
|
4564
4564
|
}
|
|
4565
4565
|
function getCodexProfileDir(profileId) {
|
|
4566
|
-
return
|
|
4566
|
+
return path8.join(getCodexProfilesDir(), profileId);
|
|
4567
4567
|
}
|
|
4568
4568
|
function getCodexProfileHome(profileId) {
|
|
4569
|
-
return
|
|
4569
|
+
return path8.join(getCodexProfileDir(profileId), "codex-home");
|
|
4570
4570
|
}
|
|
4571
4571
|
function getCodexProfileStatePath(profileId) {
|
|
4572
|
-
return
|
|
4572
|
+
return path8.join(getCodexProfileDir(profileId), "profile.json");
|
|
4573
4573
|
}
|
|
4574
4574
|
function ensureCodexProfileDirs(profileId) {
|
|
4575
4575
|
fs9.mkdirSync(getCodexProfileHome(profileId), { recursive: true, mode: 448 });
|
|
@@ -4595,16 +4595,16 @@ var require_codexProfiles = __commonJS({
|
|
|
4595
4595
|
function copyIfExists(source, destination) {
|
|
4596
4596
|
if (!fs9.existsSync(source))
|
|
4597
4597
|
return false;
|
|
4598
|
-
fs9.mkdirSync(
|
|
4598
|
+
fs9.mkdirSync(path8.dirname(destination), { recursive: true, mode: 448 });
|
|
4599
4599
|
fs9.copyFileSync(source, destination);
|
|
4600
4600
|
return true;
|
|
4601
4601
|
}
|
|
4602
4602
|
function copySourceCodexConfig(sourceHome, targetHome) {
|
|
4603
|
-
copyIfExists(
|
|
4603
|
+
copyIfExists(path8.join(sourceHome, "config.toml"), path8.join(targetHome, "config.toml"));
|
|
4604
4604
|
}
|
|
4605
4605
|
function importCurrentCodexAuth(sourceHome, targetHome) {
|
|
4606
|
-
const authCopied = copyIfExists(
|
|
4607
|
-
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"));
|
|
4608
4608
|
return authCopied || legacyCredsCopied;
|
|
4609
4609
|
}
|
|
4610
4610
|
function parseJwtPayload(jwt) {
|
|
@@ -4619,7 +4619,7 @@ var require_codexProfiles = __commonJS({
|
|
|
4619
4619
|
}
|
|
4620
4620
|
}
|
|
4621
4621
|
function readMetadataFromAuthJson(codexHome) {
|
|
4622
|
-
const authPath =
|
|
4622
|
+
const authPath = path8.join(codexHome, "auth.json");
|
|
4623
4623
|
if (!fs9.existsSync(authPath))
|
|
4624
4624
|
return {};
|
|
4625
4625
|
try {
|
|
@@ -4643,7 +4643,7 @@ var require_codexProfiles = __commonJS({
|
|
|
4643
4643
|
}
|
|
4644
4644
|
}
|
|
4645
4645
|
function readMetadataFromLegacyCredentials(codexHome) {
|
|
4646
|
-
const legacyPath =
|
|
4646
|
+
const legacyPath = path8.join(codexHome, ".credentials.json");
|
|
4647
4647
|
if (!fs9.existsSync(legacyPath))
|
|
4648
4648
|
return {};
|
|
4649
4649
|
try {
|
|
@@ -4694,7 +4694,7 @@ var require_codexProfiles = __commonJS({
|
|
|
4694
4694
|
return {};
|
|
4695
4695
|
}
|
|
4696
4696
|
function isCodexProfileAuthenticated(codexHome) {
|
|
4697
|
-
if (fs9.existsSync(
|
|
4697
|
+
if (fs9.existsSync(path8.join(codexHome, "auth.json")) || fs9.existsSync(path8.join(codexHome, ".credentials.json"))) {
|
|
4698
4698
|
return true;
|
|
4699
4699
|
}
|
|
4700
4700
|
return getCodexLoginStatus(codexHome).loggedIn;
|
|
@@ -4848,19 +4848,19 @@ var require_detect = __commonJS({
|
|
|
4848
4848
|
exports.getAllDetectedProviders = getAllDetectedProviders2;
|
|
4849
4849
|
exports.detectProvider = detectProvider2;
|
|
4850
4850
|
var fs9 = __importStar(__require("fs"));
|
|
4851
|
-
var
|
|
4852
|
-
var
|
|
4851
|
+
var os6 = __importStar(__require("os"));
|
|
4852
|
+
var path8 = __importStar(__require("path"));
|
|
4853
4853
|
var codexProfiles_1 = require_codexProfiles();
|
|
4854
4854
|
function getOpenCodeDataDir() {
|
|
4855
4855
|
const xdg = process.env.XDG_DATA_HOME;
|
|
4856
4856
|
if (xdg)
|
|
4857
|
-
return
|
|
4857
|
+
return path8.join(xdg, "opencode");
|
|
4858
4858
|
if (process.platform === "darwin")
|
|
4859
|
-
return
|
|
4859
|
+
return path8.join(os6.homedir(), "Library", "Application Support", "opencode");
|
|
4860
4860
|
if (process.platform === "win32") {
|
|
4861
|
-
return
|
|
4861
|
+
return path8.join(process.env.LOCALAPPDATA || process.env.APPDATA || path8.join(os6.homedir(), "AppData", "Local"), "opencode");
|
|
4862
4862
|
}
|
|
4863
|
-
return
|
|
4863
|
+
return path8.join(os6.homedir(), ".local", "share", "opencode");
|
|
4864
4864
|
}
|
|
4865
4865
|
function getCodexHomes() {
|
|
4866
4866
|
return (0, codexProfiles_1.getCodexMonitoringHomes)();
|
|
@@ -4873,7 +4873,7 @@ var require_detect = __commonJS({
|
|
|
4873
4873
|
const entries = fs9.readdirSync(dir);
|
|
4874
4874
|
for (const entry of entries) {
|
|
4875
4875
|
try {
|
|
4876
|
-
const stats = fs9.statSync(
|
|
4876
|
+
const stats = fs9.statSync(path8.join(dir, entry));
|
|
4877
4877
|
if (stats.mtime.getTime() > latest) {
|
|
4878
4878
|
latest = stats.mtime.getTime();
|
|
4879
4879
|
}
|
|
@@ -4887,43 +4887,43 @@ var require_detect = __commonJS({
|
|
|
4887
4887
|
}
|
|
4888
4888
|
function getOpenCodeActivityMtime() {
|
|
4889
4889
|
const dataDir = getOpenCodeDataDir();
|
|
4890
|
-
const dbPath =
|
|
4890
|
+
const dbPath = path8.join(dataDir, "opencode.db");
|
|
4891
4891
|
try {
|
|
4892
4892
|
const dbMtime = fs9.statSync(dbPath).mtime.getTime();
|
|
4893
4893
|
if (dbMtime > 0)
|
|
4894
4894
|
return dbMtime;
|
|
4895
4895
|
} catch {
|
|
4896
4896
|
}
|
|
4897
|
-
const storageDir =
|
|
4898
|
-
const sessionMtime = getMostRecentMtime(
|
|
4899
|
-
const messageMtime = getMostRecentMtime(
|
|
4900
|
-
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"));
|
|
4901
4901
|
return Math.max(sessionMtime, messageMtime, partMtime);
|
|
4902
4902
|
}
|
|
4903
4903
|
function getCodexActivityMtime() {
|
|
4904
4904
|
let latest = 0;
|
|
4905
4905
|
for (const codexHome of getCodexHomes()) {
|
|
4906
|
-
const dbPath =
|
|
4906
|
+
const dbPath = path8.join(codexHome, "state.sqlite");
|
|
4907
4907
|
try {
|
|
4908
4908
|
const dbMtime = fs9.statSync(dbPath).mtime.getTime();
|
|
4909
4909
|
if (dbMtime > latest)
|
|
4910
4910
|
latest = dbMtime;
|
|
4911
4911
|
} catch {
|
|
4912
4912
|
}
|
|
4913
|
-
const sessionsMtime = getMostRecentMtime(
|
|
4913
|
+
const sessionsMtime = getMostRecentMtime(path8.join(codexHome, "sessions"));
|
|
4914
4914
|
if (sessionsMtime > latest)
|
|
4915
4915
|
latest = sessionsMtime;
|
|
4916
4916
|
}
|
|
4917
4917
|
return latest;
|
|
4918
4918
|
}
|
|
4919
4919
|
function getProviderPaths() {
|
|
4920
|
-
const claudeBase =
|
|
4920
|
+
const claudeBase = path8.join(os6.homedir(), ".claude", "projects");
|
|
4921
4921
|
const openCodeDataDir = getOpenCodeDataDir();
|
|
4922
4922
|
const codexHomes = getCodexHomes();
|
|
4923
4923
|
return {
|
|
4924
4924
|
claudeBase,
|
|
4925
|
-
openCodeDbPath:
|
|
4926
|
-
openCodeStorageDir:
|
|
4925
|
+
openCodeDbPath: path8.join(openCodeDataDir, "opencode.db"),
|
|
4926
|
+
openCodeStorageDir: path8.join(openCodeDataDir, "storage"),
|
|
4927
4927
|
codexHomes
|
|
4928
4928
|
};
|
|
4929
4929
|
}
|
|
@@ -4931,7 +4931,7 @@ var require_detect = __commonJS({
|
|
|
4931
4931
|
const { claudeBase, openCodeDbPath, openCodeStorageDir, codexHomes } = getProviderPaths();
|
|
4932
4932
|
const hasClaude = fs9.existsSync(claudeBase);
|
|
4933
4933
|
const hasOpenCode = fs9.existsSync(openCodeStorageDir) || fs9.existsSync(openCodeDbPath);
|
|
4934
|
-
const hasCodex = codexHomes.some((codexHome) => fs9.existsSync(
|
|
4934
|
+
const hasCodex = codexHomes.some((codexHome) => fs9.existsSync(path8.join(codexHome, "sessions")) || fs9.existsSync(path8.join(codexHome, "state.sqlite")));
|
|
4935
4935
|
const available = [];
|
|
4936
4936
|
if (hasClaude)
|
|
4937
4937
|
available.push({ id: "claude-code", mtime: getMostRecentMtime(claudeBase) });
|
|
@@ -4948,7 +4948,7 @@ var require_detect = __commonJS({
|
|
|
4948
4948
|
const { claudeBase, openCodeDbPath, openCodeStorageDir, codexHomes } = getProviderPaths();
|
|
4949
4949
|
const hasClaude = fs9.existsSync(claudeBase);
|
|
4950
4950
|
const hasOpenCode = fs9.existsSync(openCodeStorageDir) || fs9.existsSync(openCodeDbPath);
|
|
4951
|
-
const hasCodex = codexHomes.some((codexHome) => fs9.existsSync(
|
|
4951
|
+
const hasCodex = codexHomes.some((codexHome) => fs9.existsSync(path8.join(codexHome, "sessions")) || fs9.existsSync(path8.join(codexHome, "state.sqlite")));
|
|
4952
4952
|
const available = [];
|
|
4953
4953
|
if (hasClaude) {
|
|
4954
4954
|
available.push({ id: "claude-code", mtime: getMostRecentMtime(claudeBase) });
|
|
@@ -5093,26 +5093,26 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5093
5093
|
exports.discoverWorktreeSiblings = discoverWorktreeSiblings;
|
|
5094
5094
|
exports.findAllSessionsWithWorktrees = findAllSessionsWithWorktrees;
|
|
5095
5095
|
var fs9 = __importStar(__require("fs"));
|
|
5096
|
-
var
|
|
5097
|
-
var
|
|
5096
|
+
var path8 = __importStar(__require("path"));
|
|
5097
|
+
var os6 = __importStar(__require("os"));
|
|
5098
5098
|
function encodeWorkspacePath(workspacePath) {
|
|
5099
5099
|
const normalized = workspacePath.replace(/\\/g, "/");
|
|
5100
5100
|
return normalized.replace(/[:/_]/g, "-");
|
|
5101
5101
|
}
|
|
5102
5102
|
function getSessionDirectory(workspacePath) {
|
|
5103
5103
|
const encoded = encodeWorkspacePath(workspacePath);
|
|
5104
|
-
return
|
|
5104
|
+
return path8.join(os6.homedir(), ".claude", "projects", encoded);
|
|
5105
5105
|
}
|
|
5106
5106
|
var ACTIVE_SESSION_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
5107
5107
|
function findSubdirectorySessionDirs(workspacePath) {
|
|
5108
|
-
const projectsDir =
|
|
5108
|
+
const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
|
|
5109
5109
|
try {
|
|
5110
5110
|
if (!fs9.existsSync(projectsDir)) {
|
|
5111
5111
|
return [];
|
|
5112
5112
|
}
|
|
5113
5113
|
const encodedPrefix = encodeWorkspacePath(workspacePath).toLowerCase();
|
|
5114
5114
|
const allDirs = fs9.readdirSync(projectsDir).filter((name) => {
|
|
5115
|
-
const fullPath =
|
|
5115
|
+
const fullPath = path8.join(projectsDir, name);
|
|
5116
5116
|
try {
|
|
5117
5117
|
return fs9.statSync(fullPath).isDirectory();
|
|
5118
5118
|
} catch {
|
|
@@ -5123,7 +5123,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5123
5123
|
for (const dir of allDirs) {
|
|
5124
5124
|
const dirLower = dir.toLowerCase();
|
|
5125
5125
|
if (dirLower.startsWith(encodedPrefix + "-")) {
|
|
5126
|
-
matches.push(
|
|
5126
|
+
matches.push(path8.join(projectsDir, dir));
|
|
5127
5127
|
}
|
|
5128
5128
|
}
|
|
5129
5129
|
return matches;
|
|
@@ -5139,7 +5139,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5139
5139
|
const files = fs9.readdirSync(dir).filter((file) => file.endsWith(".jsonl"));
|
|
5140
5140
|
for (const file of files) {
|
|
5141
5141
|
try {
|
|
5142
|
-
const fullPath =
|
|
5142
|
+
const fullPath = path8.join(dir, file);
|
|
5143
5143
|
const stats = fs9.statSync(fullPath);
|
|
5144
5144
|
if (stats.size > 0 && stats.mtime.getTime() > mostRecentMtime) {
|
|
5145
5145
|
mostRecentMtime = stats.mtime.getTime();
|
|
@@ -5154,7 +5154,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5154
5154
|
return mostRecentDir;
|
|
5155
5155
|
}
|
|
5156
5156
|
function discoverSessionDirectory(workspacePath) {
|
|
5157
|
-
const projectsDir =
|
|
5157
|
+
const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
|
|
5158
5158
|
const computedDir = getSessionDirectory(workspacePath);
|
|
5159
5159
|
if (fs9.existsSync(computedDir)) {
|
|
5160
5160
|
return computedDir;
|
|
@@ -5169,7 +5169,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5169
5169
|
try {
|
|
5170
5170
|
if (fs9.existsSync(projectsDir)) {
|
|
5171
5171
|
const existingDirs = fs9.readdirSync(projectsDir).filter((name) => {
|
|
5172
|
-
const fullPath =
|
|
5172
|
+
const fullPath = path8.join(projectsDir, name);
|
|
5173
5173
|
try {
|
|
5174
5174
|
return fs9.statSync(fullPath).isDirectory();
|
|
5175
5175
|
} catch {
|
|
@@ -5179,35 +5179,35 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5179
5179
|
const normalizedWorkspace = workspacePath.replace(/\\/g, "/").replace(/:/g, "-").replace(/_/g, "-").replace(/\//g, "-").toLowerCase();
|
|
5180
5180
|
for (const dir of existingDirs) {
|
|
5181
5181
|
if (dir.toLowerCase() === normalizedWorkspace) {
|
|
5182
|
-
return
|
|
5182
|
+
return path8.join(projectsDir, dir);
|
|
5183
5183
|
}
|
|
5184
5184
|
}
|
|
5185
|
-
const workspaceBasename =
|
|
5185
|
+
const workspaceBasename = path8.basename(workspacePath).replace(/_/g, "-").toLowerCase();
|
|
5186
5186
|
for (const dir of existingDirs) {
|
|
5187
5187
|
const dirLower = dir.toLowerCase();
|
|
5188
5188
|
if (dirLower.endsWith("-" + workspaceBasename) || dirLower === workspaceBasename) {
|
|
5189
|
-
return
|
|
5189
|
+
return path8.join(projectsDir, dir);
|
|
5190
5190
|
}
|
|
5191
5191
|
}
|
|
5192
5192
|
}
|
|
5193
5193
|
} catch {
|
|
5194
5194
|
}
|
|
5195
5195
|
try {
|
|
5196
|
-
const claudeTempDir =
|
|
5196
|
+
const claudeTempDir = path8.join(os6.tmpdir(), "claude");
|
|
5197
5197
|
if (fs9.existsSync(claudeTempDir)) {
|
|
5198
5198
|
const tempDirs = fs9.readdirSync(claudeTempDir).filter((name) => {
|
|
5199
|
-
const fullPath =
|
|
5199
|
+
const fullPath = path8.join(claudeTempDir, name);
|
|
5200
5200
|
try {
|
|
5201
5201
|
return fs9.statSync(fullPath).isDirectory();
|
|
5202
5202
|
} catch {
|
|
5203
5203
|
return false;
|
|
5204
5204
|
}
|
|
5205
5205
|
});
|
|
5206
|
-
const workspaceBasename =
|
|
5206
|
+
const workspaceBasename = path8.basename(workspacePath).replace(/_/g, "-").toLowerCase();
|
|
5207
5207
|
for (const encodedDir of tempDirs) {
|
|
5208
5208
|
const encodedLower = encodedDir.toLowerCase();
|
|
5209
5209
|
if (encodedLower.endsWith("-" + workspaceBasename) || encodedLower === workspaceBasename) {
|
|
5210
|
-
const sessionDir =
|
|
5210
|
+
const sessionDir = path8.join(projectsDir, encodedDir);
|
|
5211
5211
|
if (fs9.existsSync(sessionDir)) {
|
|
5212
5212
|
return sessionDir;
|
|
5213
5213
|
}
|
|
@@ -5226,7 +5226,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5226
5226
|
}
|
|
5227
5227
|
const now = Date.now();
|
|
5228
5228
|
const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
|
|
5229
|
-
const fullPath =
|
|
5229
|
+
const fullPath = path8.join(sessionDir, file);
|
|
5230
5230
|
const stats = fs9.statSync(fullPath);
|
|
5231
5231
|
const mtime = stats.mtime.getTime();
|
|
5232
5232
|
return {
|
|
@@ -5259,7 +5259,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5259
5259
|
return [];
|
|
5260
5260
|
}
|
|
5261
5261
|
const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
|
|
5262
|
-
const fullPath =
|
|
5262
|
+
const fullPath = path8.join(sessionDir, file);
|
|
5263
5263
|
const stats = fs9.statSync(fullPath);
|
|
5264
5264
|
return {
|
|
5265
5265
|
path: fullPath,
|
|
@@ -5286,7 +5286,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5286
5286
|
return encoded.replace(/-/g, "/");
|
|
5287
5287
|
}
|
|
5288
5288
|
function getAllProjectFolders(workspacePath) {
|
|
5289
|
-
const projectsDir =
|
|
5289
|
+
const projectsDir = path8.join(os6.homedir(), ".claude", "projects");
|
|
5290
5290
|
const folders = [];
|
|
5291
5291
|
try {
|
|
5292
5292
|
if (!fs9.existsSync(projectsDir)) {
|
|
@@ -5294,7 +5294,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5294
5294
|
}
|
|
5295
5295
|
const entries = fs9.readdirSync(projectsDir);
|
|
5296
5296
|
for (const entry of entries) {
|
|
5297
|
-
const fullPath =
|
|
5297
|
+
const fullPath = path8.join(projectsDir, entry);
|
|
5298
5298
|
try {
|
|
5299
5299
|
const stats = fs9.statSync(fullPath);
|
|
5300
5300
|
if (!stats.isDirectory()) {
|
|
@@ -5305,7 +5305,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5305
5305
|
let sessionCount = 0;
|
|
5306
5306
|
for (const sessionFile of sessionFiles) {
|
|
5307
5307
|
try {
|
|
5308
|
-
const sessionPath =
|
|
5308
|
+
const sessionPath = path8.join(fullPath, sessionFile);
|
|
5309
5309
|
const sessionStats = fs9.statSync(sessionPath);
|
|
5310
5310
|
if (sessionStats.size > 0) {
|
|
5311
5311
|
sessionCount++;
|
|
@@ -5357,7 +5357,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5357
5357
|
return [];
|
|
5358
5358
|
}
|
|
5359
5359
|
const files = fs9.readdirSync(sessionDir).filter((file) => file.endsWith(".jsonl")).map((file) => {
|
|
5360
|
-
const fullPath =
|
|
5360
|
+
const fullPath = path8.join(sessionDir, file);
|
|
5361
5361
|
try {
|
|
5362
5362
|
const stats = fs9.statSync(fullPath);
|
|
5363
5363
|
return {
|
|
@@ -5375,7 +5375,7 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5375
5375
|
}
|
|
5376
5376
|
}
|
|
5377
5377
|
function resolveWorktreeMainRepo(workspacePath) {
|
|
5378
|
-
const gitPath =
|
|
5378
|
+
const gitPath = path8.join(workspacePath, ".git");
|
|
5379
5379
|
try {
|
|
5380
5380
|
const stat = fs9.statSync(gitPath);
|
|
5381
5381
|
if (stat.isDirectory()) {
|
|
@@ -5386,31 +5386,31 @@ var require_sessionPathResolver = __commonJS({
|
|
|
5386
5386
|
if (!match)
|
|
5387
5387
|
return null;
|
|
5388
5388
|
const gitdir = match[1].trim();
|
|
5389
|
-
const resolvedGitdir =
|
|
5390
|
-
const worktreesDir =
|
|
5391
|
-
if (
|
|
5389
|
+
const resolvedGitdir = path8.isAbsolute(gitdir) ? gitdir : path8.resolve(workspacePath, gitdir);
|
|
5390
|
+
const worktreesDir = path8.dirname(resolvedGitdir);
|
|
5391
|
+
if (path8.basename(worktreesDir) !== "worktrees")
|
|
5392
5392
|
return null;
|
|
5393
|
-
const dotGit =
|
|
5394
|
-
if (
|
|
5393
|
+
const dotGit = path8.dirname(worktreesDir);
|
|
5394
|
+
if (path8.basename(dotGit) !== ".git")
|
|
5395
5395
|
return null;
|
|
5396
|
-
return
|
|
5396
|
+
return path8.dirname(dotGit);
|
|
5397
5397
|
} catch {
|
|
5398
5398
|
return null;
|
|
5399
5399
|
}
|
|
5400
5400
|
}
|
|
5401
5401
|
function discoverWorktreeSiblings(mainRepoPath) {
|
|
5402
|
-
const worktreesDir =
|
|
5402
|
+
const worktreesDir = path8.join(mainRepoPath, ".git", "worktrees");
|
|
5403
5403
|
const siblings = [];
|
|
5404
5404
|
try {
|
|
5405
5405
|
if (!fs9.existsSync(worktreesDir))
|
|
5406
5406
|
return siblings;
|
|
5407
5407
|
const entries = fs9.readdirSync(worktreesDir);
|
|
5408
5408
|
for (const entry of entries) {
|
|
5409
|
-
const gitdirFile =
|
|
5409
|
+
const gitdirFile = path8.join(worktreesDir, entry, "gitdir");
|
|
5410
5410
|
try {
|
|
5411
5411
|
const content = fs9.readFileSync(gitdirFile, "utf-8").trim();
|
|
5412
|
-
const worktreeGit =
|
|
5413
|
-
const worktreeDir =
|
|
5412
|
+
const worktreeGit = path8.isAbsolute(content) ? content : path8.resolve(worktreesDir, entry, content);
|
|
5413
|
+
const worktreeDir = path8.dirname(worktreeGit);
|
|
5414
5414
|
if (fs9.existsSync(worktreeDir)) {
|
|
5415
5415
|
siblings.push(worktreeDir);
|
|
5416
5416
|
}
|
|
@@ -5504,7 +5504,7 @@ var require_subagentScanner = __commonJS({
|
|
|
5504
5504
|
exports.handleTaskUpdate = handleTaskUpdate;
|
|
5505
5505
|
exports.extractTaskInfo = extractTaskInfo;
|
|
5506
5506
|
var fs9 = __importStar(__require("fs"));
|
|
5507
|
-
var
|
|
5507
|
+
var path8 = __importStar(__require("path"));
|
|
5508
5508
|
var AGENT_FILE_PATTERN = /^agent-(.+)\.jsonl$/;
|
|
5509
5509
|
var TASK_TOOLS = ["TaskCreate", "TaskUpdate", "TaskGet", "TaskList"];
|
|
5510
5510
|
function extractTaskIdFromResult(resultContent) {
|
|
@@ -5523,7 +5523,7 @@ var require_subagentScanner = __commonJS({
|
|
|
5523
5523
|
function scanSubagentDir(sessionDir, sessionId, logger) {
|
|
5524
5524
|
const log = logger || (() => {
|
|
5525
5525
|
});
|
|
5526
|
-
const subagentsDir =
|
|
5526
|
+
const subagentsDir = path8.join(sessionDir, sessionId, "subagents");
|
|
5527
5527
|
const results = [];
|
|
5528
5528
|
try {
|
|
5529
5529
|
if (!fs9.existsSync(subagentsDir)) {
|
|
@@ -5542,7 +5542,7 @@ var require_subagentScanner = __commonJS({
|
|
|
5542
5542
|
continue;
|
|
5543
5543
|
}
|
|
5544
5544
|
const agentId = match[1];
|
|
5545
|
-
const filePath =
|
|
5545
|
+
const filePath = path8.join(subagentsDir, file);
|
|
5546
5546
|
const agentStats = parseAgentFile(filePath, agentId, log);
|
|
5547
5547
|
if (agentStats) {
|
|
5548
5548
|
log(`[SubagentScanner] Agent ${agentId}: ${agentStats.toolCalls.length} tool calls`);
|
|
@@ -5752,8 +5752,10 @@ var require_modelContext = __commonJS({
|
|
|
5752
5752
|
exports.DEFAULT_CONTEXT_WINDOW = void 0;
|
|
5753
5753
|
exports.getModelContextWindowSize = getModelContextWindowSize2;
|
|
5754
5754
|
var MODEL_CONTEXT_SIZES = {
|
|
5755
|
-
// Claude 4.6
|
|
5755
|
+
// Claude — native 1M context (Opus 4.6+, Sonnet 4.6+)
|
|
5756
|
+
"claude-opus-4-7": 1e6,
|
|
5756
5757
|
"claude-opus-4-6": 1e6,
|
|
5758
|
+
"claude-sonnet-4-7": 1e6,
|
|
5757
5759
|
"claude-sonnet-4-6": 1e6,
|
|
5758
5760
|
// Claude 4 family
|
|
5759
5761
|
"claude-opus-4": 2e5,
|
|
@@ -5769,7 +5771,11 @@ var require_modelContext = __commonJS({
|
|
|
5769
5771
|
"claude-3-haiku": 2e5,
|
|
5770
5772
|
// OpenAI GPT-4.1 series (1M context)
|
|
5771
5773
|
"gpt-4.1": 1048576,
|
|
5772
|
-
// 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,
|
|
5773
5779
|
"gpt-5": 4e5,
|
|
5774
5780
|
// OpenAI reasoning
|
|
5775
5781
|
"o1": 2e5,
|
|
@@ -5789,11 +5795,14 @@ var require_modelContext = __commonJS({
|
|
|
5789
5795
|
function getModelContextWindowSize2(modelId) {
|
|
5790
5796
|
if (!modelId)
|
|
5791
5797
|
return exports.DEFAULT_CONTEXT_WINDOW;
|
|
5792
|
-
if (
|
|
5793
|
-
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];
|
|
5794
5803
|
}
|
|
5795
5804
|
for (const key of SORTED_KEYS) {
|
|
5796
|
-
if (
|
|
5805
|
+
if (normalized.startsWith(key)) {
|
|
5797
5806
|
return MODEL_CONTEXT_SIZES[key];
|
|
5798
5807
|
}
|
|
5799
5808
|
}
|
|
@@ -5846,8 +5855,8 @@ var require_claudeCode = __commonJS({
|
|
|
5846
5855
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5847
5856
|
exports.ClaudeCodeProvider = void 0;
|
|
5848
5857
|
var fs9 = __importStar(__require("fs"));
|
|
5849
|
-
var
|
|
5850
|
-
var
|
|
5858
|
+
var os6 = __importStar(__require("os"));
|
|
5859
|
+
var path8 = __importStar(__require("path"));
|
|
5851
5860
|
var jsonl_1 = require_jsonl();
|
|
5852
5861
|
var sessionPathResolver_1 = require_sessionPathResolver();
|
|
5853
5862
|
var subagentScanner_1 = require_subagentScanner();
|
|
@@ -5984,7 +5993,7 @@ var require_claudeCode = __commonJS({
|
|
|
5984
5993
|
return filename.endsWith(".jsonl");
|
|
5985
5994
|
}
|
|
5986
5995
|
getSessionId(sessionPath) {
|
|
5987
|
-
return
|
|
5996
|
+
return path8.basename(sessionPath, ".jsonl");
|
|
5988
5997
|
}
|
|
5989
5998
|
encodeWorkspacePath(workspacePath) {
|
|
5990
5999
|
return (0, sessionPathResolver_1.encodeWorkspacePath)(workspacePath);
|
|
@@ -6049,7 +6058,7 @@ var require_claudeCode = __commonJS({
|
|
|
6049
6058
|
try {
|
|
6050
6059
|
const content = fs9.readFileSync(sessionPath, "utf8");
|
|
6051
6060
|
const lines = content.split("\n");
|
|
6052
|
-
const projectDir =
|
|
6061
|
+
const projectDir = path8.basename(path8.dirname(sessionPath));
|
|
6053
6062
|
const projectPath = (0, sessionPathResolver_1.decodeEncodedPath)(projectDir);
|
|
6054
6063
|
for (const line of lines) {
|
|
6055
6064
|
if (results.length >= maxResults)
|
|
@@ -6083,11 +6092,11 @@ var require_claudeCode = __commonJS({
|
|
|
6083
6092
|
return results;
|
|
6084
6093
|
}
|
|
6085
6094
|
getProjectsBaseDir() {
|
|
6086
|
-
return
|
|
6095
|
+
return path8.join(os6.homedir(), ".claude", "projects");
|
|
6087
6096
|
}
|
|
6088
6097
|
// --- Stats ---
|
|
6089
6098
|
readSessionStats(sessionPath) {
|
|
6090
|
-
const sessionId =
|
|
6099
|
+
const sessionId = path8.basename(sessionPath, ".jsonl");
|
|
6091
6100
|
let messageCount = 0;
|
|
6092
6101
|
let startTime = "";
|
|
6093
6102
|
let endTime = "";
|
|
@@ -6739,13 +6748,13 @@ var require_openCodeDatabase = __commonJS({
|
|
|
6739
6748
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6740
6749
|
exports.OpenCodeDatabase = void 0;
|
|
6741
6750
|
var fs9 = __importStar(__require("fs"));
|
|
6742
|
-
var
|
|
6751
|
+
var path8 = __importStar(__require("path"));
|
|
6743
6752
|
var child_process_1 = __require("child_process");
|
|
6744
6753
|
var OpenCodeDatabase = class {
|
|
6745
6754
|
dbPath;
|
|
6746
6755
|
runtimeStatus = null;
|
|
6747
6756
|
constructor(dataDir) {
|
|
6748
|
-
this.dbPath =
|
|
6757
|
+
this.dbPath = path8.join(dataDir, "opencode.db");
|
|
6749
6758
|
}
|
|
6750
6759
|
isAvailable() {
|
|
6751
6760
|
return fs9.existsSync(this.dbPath);
|
|
@@ -6964,7 +6973,7 @@ var require_openCodeDatabase = __commonJS({
|
|
|
6964
6973
|
try {
|
|
6965
6974
|
return fs9.realpathSync(input);
|
|
6966
6975
|
} catch {
|
|
6967
|
-
return
|
|
6976
|
+
return path8.resolve(input);
|
|
6968
6977
|
}
|
|
6969
6978
|
}
|
|
6970
6979
|
function parseStringArray(value) {
|
|
@@ -6988,8 +6997,8 @@ var require_openCodeDatabase = __commonJS({
|
|
|
6988
6997
|
const normalizedWorkspace = normalizeForCompare(workspacePath);
|
|
6989
6998
|
if (normalizedCandidate === normalizedWorkspace)
|
|
6990
6999
|
return 1e4 + normalizedCandidate.length;
|
|
6991
|
-
const candidatePrefix = normalizedCandidate.endsWith(
|
|
6992
|
-
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;
|
|
6993
7002
|
if (normalizedWorkspace.startsWith(candidatePrefix))
|
|
6994
7003
|
return 5e3 + normalizedCandidate.length;
|
|
6995
7004
|
if (normalizedCandidate.startsWith(workspacePrefix))
|
|
@@ -7056,8 +7065,8 @@ var require_openCode = __commonJS({
|
|
|
7056
7065
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7057
7066
|
exports.OpenCodeProvider = void 0;
|
|
7058
7067
|
var fs9 = __importStar(__require("fs"));
|
|
7059
|
-
var
|
|
7060
|
-
var
|
|
7068
|
+
var os6 = __importStar(__require("os"));
|
|
7069
|
+
var path8 = __importStar(__require("path"));
|
|
7061
7070
|
var child_process_1 = __require("child_process");
|
|
7062
7071
|
var openCodeParser_1 = require_openCodeParser();
|
|
7063
7072
|
var openCodeDatabase_1 = require_openCodeDatabase();
|
|
@@ -7065,18 +7074,18 @@ var require_openCode = __commonJS({
|
|
|
7065
7074
|
function getOpenCodeDataDir() {
|
|
7066
7075
|
const xdg = process.env.XDG_DATA_HOME;
|
|
7067
7076
|
if (xdg) {
|
|
7068
|
-
return
|
|
7077
|
+
return path8.join(xdg, "opencode");
|
|
7069
7078
|
}
|
|
7070
7079
|
if (process.platform === "darwin") {
|
|
7071
|
-
return
|
|
7080
|
+
return path8.join(os6.homedir(), "Library", "Application Support", "opencode");
|
|
7072
7081
|
}
|
|
7073
7082
|
if (process.platform === "win32") {
|
|
7074
|
-
return
|
|
7083
|
+
return path8.join(process.env.LOCALAPPDATA || process.env.APPDATA || path8.join(os6.homedir(), "AppData", "Local"), "opencode");
|
|
7075
7084
|
}
|
|
7076
|
-
return
|
|
7085
|
+
return path8.join(os6.homedir(), ".local", "share", "opencode");
|
|
7077
7086
|
}
|
|
7078
7087
|
function getStorageDir() {
|
|
7079
|
-
return
|
|
7088
|
+
return path8.join(getOpenCodeDataDir(), "storage");
|
|
7080
7089
|
}
|
|
7081
7090
|
var GENERIC_AGENT_RE = /^(gpt-|claude-|o[1-9]|gemini|default|agent|worker)/i;
|
|
7082
7091
|
function isGenericAgentType(type) {
|
|
@@ -7107,18 +7116,18 @@ var require_openCode = __commonJS({
|
|
|
7107
7116
|
}
|
|
7108
7117
|
var DB_SESSION_PREFIX = "db-sessions";
|
|
7109
7118
|
function makeDbSessionPath(dataDir, projectId, sessionId) {
|
|
7110
|
-
return
|
|
7119
|
+
return path8.join(dataDir, DB_SESSION_PREFIX, projectId, `${sessionId}.json`);
|
|
7111
7120
|
}
|
|
7112
7121
|
function isDbSessionPath(sessionPath) {
|
|
7113
|
-
return sessionPath.includes(
|
|
7122
|
+
return sessionPath.includes(path8.sep + DB_SESSION_PREFIX + path8.sep);
|
|
7114
7123
|
}
|
|
7115
7124
|
function extractProjectIdFromDbPath(sessionPath) {
|
|
7116
|
-
const prefix =
|
|
7125
|
+
const prefix = path8.sep + DB_SESSION_PREFIX + path8.sep;
|
|
7117
7126
|
const idx = sessionPath.indexOf(prefix);
|
|
7118
7127
|
if (idx < 0)
|
|
7119
7128
|
return null;
|
|
7120
7129
|
const rest = sessionPath.substring(idx + prefix.length);
|
|
7121
|
-
const slashIdx = rest.indexOf(
|
|
7130
|
+
const slashIdx = rest.indexOf(path8.sep);
|
|
7122
7131
|
return slashIdx > 0 ? rest.substring(0, slashIdx) : null;
|
|
7123
7132
|
}
|
|
7124
7133
|
function extractRoleFromDbMessage(row) {
|
|
@@ -7156,25 +7165,25 @@ var require_openCode = __commonJS({
|
|
|
7156
7165
|
function resolveProjectIdFromFiles(workspacePath) {
|
|
7157
7166
|
const workspaceResolved = normalizePath(workspacePath);
|
|
7158
7167
|
try {
|
|
7159
|
-
const projectDir =
|
|
7168
|
+
const projectDir = path8.join(getStorageDir(), "project");
|
|
7160
7169
|
if (!fs9.existsSync(projectDir))
|
|
7161
7170
|
return resolveProjectIdFromGit(workspacePath);
|
|
7162
7171
|
const files = fs9.readdirSync(projectDir).filter((f) => f.endsWith(".json"));
|
|
7163
7172
|
const matches = [];
|
|
7164
7173
|
for (const file of files) {
|
|
7165
7174
|
try {
|
|
7166
|
-
const project = JSON.parse(fs9.readFileSync(
|
|
7175
|
+
const project = JSON.parse(fs9.readFileSync(path8.join(projectDir, file), "utf-8"));
|
|
7167
7176
|
if (project.path) {
|
|
7168
7177
|
const projectPath = normalizePath(project.path);
|
|
7169
7178
|
if (projectPath === workspaceResolved) {
|
|
7170
7179
|
matches.push({ id: project.id, path: projectPath });
|
|
7171
7180
|
continue;
|
|
7172
7181
|
}
|
|
7173
|
-
if (workspaceResolved.startsWith(projectPath +
|
|
7182
|
+
if (workspaceResolved.startsWith(projectPath + path8.sep)) {
|
|
7174
7183
|
matches.push({ id: project.id, path: projectPath });
|
|
7175
7184
|
continue;
|
|
7176
7185
|
}
|
|
7177
|
-
if (projectPath.startsWith(workspaceResolved +
|
|
7186
|
+
if (projectPath.startsWith(workspaceResolved + path8.sep)) {
|
|
7178
7187
|
matches.push({ id: project.id, path: projectPath });
|
|
7179
7188
|
}
|
|
7180
7189
|
}
|
|
@@ -7222,7 +7231,7 @@ var require_openCode = __commonJS({
|
|
|
7222
7231
|
try {
|
|
7223
7232
|
return fs9.realpathSync(input);
|
|
7224
7233
|
} catch {
|
|
7225
|
-
return
|
|
7234
|
+
return path8.resolve(input);
|
|
7226
7235
|
}
|
|
7227
7236
|
}
|
|
7228
7237
|
var OpenCodeFileReader = class {
|
|
@@ -7234,7 +7243,7 @@ var require_openCode = __commonJS({
|
|
|
7234
7243
|
this.storageBase = getStorageDir();
|
|
7235
7244
|
}
|
|
7236
7245
|
readNew() {
|
|
7237
|
-
const messageDir =
|
|
7246
|
+
const messageDir = path8.join(this.storageBase, "message", this.sessionId);
|
|
7238
7247
|
if (!fs9.existsSync(messageDir))
|
|
7239
7248
|
return [];
|
|
7240
7249
|
let messageFiles;
|
|
@@ -7245,8 +7254,8 @@ var require_openCode = __commonJS({
|
|
|
7245
7254
|
}
|
|
7246
7255
|
const newEvents = [];
|
|
7247
7256
|
for (const file of messageFiles) {
|
|
7248
|
-
const msgId =
|
|
7249
|
-
const messagePath =
|
|
7257
|
+
const msgId = path8.basename(file, ".json");
|
|
7258
|
+
const messagePath = path8.join(messageDir, file);
|
|
7250
7259
|
const message = readJsonSafe(messagePath);
|
|
7251
7260
|
if (!message)
|
|
7252
7261
|
continue;
|
|
@@ -7256,11 +7265,11 @@ var require_openCode = __commonJS({
|
|
|
7256
7265
|
} catch {
|
|
7257
7266
|
messageMtimeMs = 0;
|
|
7258
7267
|
}
|
|
7259
|
-
const partDir =
|
|
7268
|
+
const partDir = path8.join(this.storageBase, "part", msgId);
|
|
7260
7269
|
let parts = [];
|
|
7261
7270
|
if (fs9.existsSync(partDir)) {
|
|
7262
7271
|
try {
|
|
7263
|
-
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);
|
|
7264
7273
|
} catch {
|
|
7265
7274
|
}
|
|
7266
7275
|
}
|
|
@@ -7297,7 +7306,7 @@ var require_openCode = __commonJS({
|
|
|
7297
7306
|
this.seenMessages.clear();
|
|
7298
7307
|
}
|
|
7299
7308
|
exists() {
|
|
7300
|
-
return fs9.existsSync(
|
|
7309
|
+
return fs9.existsSync(path8.join(this.storageBase, "message", this.sessionId));
|
|
7301
7310
|
}
|
|
7302
7311
|
flush() {
|
|
7303
7312
|
}
|
|
@@ -7514,7 +7523,7 @@ var require_openCode = __commonJS({
|
|
|
7514
7523
|
const db = this.ensureDb();
|
|
7515
7524
|
if (!db)
|
|
7516
7525
|
return false;
|
|
7517
|
-
const projectId = extractProjectIdFromDbPath(dir +
|
|
7526
|
+
const projectId = extractProjectIdFromDbPath(dir + path8.sep + "dummy.json") || path8.basename(dir);
|
|
7518
7527
|
return projectId.length > 0 && db.hasProject(projectId);
|
|
7519
7528
|
}
|
|
7520
7529
|
mapDbSessions(projectId) {
|
|
@@ -7539,14 +7548,14 @@ var require_openCode = __commonJS({
|
|
|
7539
7548
|
const projectId = resolveProjectId(workspacePath, db, dbStatus);
|
|
7540
7549
|
if (projectId) {
|
|
7541
7550
|
if (db) {
|
|
7542
|
-
return
|
|
7551
|
+
return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
|
|
7543
7552
|
}
|
|
7544
|
-
return
|
|
7553
|
+
return path8.join(getStorageDir(), "session", projectId);
|
|
7545
7554
|
}
|
|
7546
7555
|
if (dbStatus.kind !== "db_missing") {
|
|
7547
|
-
return
|
|
7556
|
+
return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX);
|
|
7548
7557
|
}
|
|
7549
|
-
return
|
|
7558
|
+
return path8.join(getStorageDir(), "session");
|
|
7550
7559
|
}
|
|
7551
7560
|
discoverSessionDirectory(workspacePath) {
|
|
7552
7561
|
const db = this.ensureDb();
|
|
@@ -7556,13 +7565,13 @@ var require_openCode = __commonJS({
|
|
|
7556
7565
|
return null;
|
|
7557
7566
|
if (db) {
|
|
7558
7567
|
if (db.hasProject(projectId)) {
|
|
7559
|
-
return
|
|
7568
|
+
return path8.join(getOpenCodeDataDir(), DB_SESSION_PREFIX, projectId);
|
|
7560
7569
|
}
|
|
7561
7570
|
}
|
|
7562
7571
|
if (dbStatus.kind !== "db_missing") {
|
|
7563
7572
|
return null;
|
|
7564
7573
|
}
|
|
7565
|
-
const dir =
|
|
7574
|
+
const dir = path8.join(getStorageDir(), "session", projectId);
|
|
7566
7575
|
return fs9.existsSync(dir) ? dir : null;
|
|
7567
7576
|
}
|
|
7568
7577
|
// --- Session discovery ---
|
|
@@ -7589,7 +7598,7 @@ var require_openCode = __commonJS({
|
|
|
7589
7598
|
return this.findActiveSessionFromFiles(projectId);
|
|
7590
7599
|
}
|
|
7591
7600
|
findActiveSessionFromFiles(projectId) {
|
|
7592
|
-
const sessionDir =
|
|
7601
|
+
const sessionDir = path8.join(getStorageDir(), "session", projectId);
|
|
7593
7602
|
if (!fs9.existsSync(sessionDir))
|
|
7594
7603
|
return null;
|
|
7595
7604
|
let bestPath = null;
|
|
@@ -7597,7 +7606,7 @@ var require_openCode = __commonJS({
|
|
|
7597
7606
|
try {
|
|
7598
7607
|
const files = fs9.readdirSync(sessionDir).filter((f) => f.endsWith(".json"));
|
|
7599
7608
|
for (const file of files) {
|
|
7600
|
-
const fullPath =
|
|
7609
|
+
const fullPath = path8.join(sessionDir, file);
|
|
7601
7610
|
try {
|
|
7602
7611
|
const stats = fs9.statSync(fullPath);
|
|
7603
7612
|
if (stats.size > 0 && stats.mtime.getTime() > bestMtime) {
|
|
@@ -7611,14 +7620,14 @@ var require_openCode = __commonJS({
|
|
|
7611
7620
|
return null;
|
|
7612
7621
|
}
|
|
7613
7622
|
if (bestPath) {
|
|
7614
|
-
const sessionId =
|
|
7615
|
-
const messageDir =
|
|
7623
|
+
const sessionId = path8.basename(bestPath, ".json");
|
|
7624
|
+
const messageDir = path8.join(getStorageDir(), "message", sessionId);
|
|
7616
7625
|
if (fs9.existsSync(messageDir)) {
|
|
7617
7626
|
try {
|
|
7618
7627
|
const messageFiles = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json"));
|
|
7619
7628
|
for (const mf of messageFiles) {
|
|
7620
7629
|
try {
|
|
7621
|
-
const mstat = fs9.statSync(
|
|
7630
|
+
const mstat = fs9.statSync(path8.join(messageDir, mf));
|
|
7622
7631
|
if (mstat.mtime.getTime() > bestMtime) {
|
|
7623
7632
|
bestMtime = mstat.mtime.getTime();
|
|
7624
7633
|
}
|
|
@@ -7648,20 +7657,20 @@ var require_openCode = __commonJS({
|
|
|
7648
7657
|
if (dbStatus.kind !== "db_missing") {
|
|
7649
7658
|
return [];
|
|
7650
7659
|
}
|
|
7651
|
-
const sessionDir =
|
|
7660
|
+
const sessionDir = path8.join(getStorageDir(), "session", projectId);
|
|
7652
7661
|
return this.findSessionsInDirectoryFromFiles(sessionDir);
|
|
7653
7662
|
}
|
|
7654
7663
|
findSessionsInDirectory(dir) {
|
|
7655
7664
|
const db = this.ensureDb();
|
|
7656
7665
|
const dbStatus = this.getRuntimeStatus();
|
|
7657
|
-
if (db && dir.includes(
|
|
7658
|
-
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");
|
|
7659
7668
|
if (projectId) {
|
|
7660
7669
|
return this.mapDbSessions(projectId);
|
|
7661
7670
|
}
|
|
7662
7671
|
}
|
|
7663
7672
|
if (db) {
|
|
7664
|
-
const dirName =
|
|
7673
|
+
const dirName = path8.basename(dir);
|
|
7665
7674
|
if (db.hasProject(dirName)) {
|
|
7666
7675
|
return this.mapDbSessions(dirName);
|
|
7667
7676
|
}
|
|
@@ -7676,7 +7685,7 @@ var require_openCode = __commonJS({
|
|
|
7676
7685
|
if (!fs9.existsSync(dir))
|
|
7677
7686
|
return [];
|
|
7678
7687
|
return fs9.readdirSync(dir).filter((f) => f.endsWith(".json")).map((f) => {
|
|
7679
|
-
const fullPath =
|
|
7688
|
+
const fullPath = path8.join(dir, f);
|
|
7680
7689
|
try {
|
|
7681
7690
|
const stats = fs9.statSync(fullPath);
|
|
7682
7691
|
return { path: fullPath, mtime: stats.mtime.getTime(), size: stats.size };
|
|
@@ -7706,7 +7715,7 @@ var require_openCode = __commonJS({
|
|
|
7706
7715
|
if (!projStats || projStats.sessionCount === 0)
|
|
7707
7716
|
continue;
|
|
7708
7717
|
folders.push({
|
|
7709
|
-
dir:
|
|
7718
|
+
dir: path8.join(dataDir, DB_SESSION_PREFIX, project.id),
|
|
7710
7719
|
name: project.worktree || project.name || project.id,
|
|
7711
7720
|
encodedName: project.id,
|
|
7712
7721
|
sessionCount: projStats.sessionCount,
|
|
@@ -7734,23 +7743,23 @@ var require_openCode = __commonJS({
|
|
|
7734
7743
|
}
|
|
7735
7744
|
getAllProjectFoldersFromFiles(workspacePath) {
|
|
7736
7745
|
const folders = [];
|
|
7737
|
-
const sessionBase =
|
|
7746
|
+
const sessionBase = path8.join(getStorageDir(), "session");
|
|
7738
7747
|
try {
|
|
7739
7748
|
if (!fs9.existsSync(sessionBase))
|
|
7740
7749
|
return [];
|
|
7741
7750
|
const projectIds = fs9.readdirSync(sessionBase).filter((name) => {
|
|
7742
7751
|
try {
|
|
7743
|
-
return fs9.statSync(
|
|
7752
|
+
return fs9.statSync(path8.join(sessionBase, name)).isDirectory();
|
|
7744
7753
|
} catch {
|
|
7745
7754
|
return false;
|
|
7746
7755
|
}
|
|
7747
7756
|
});
|
|
7748
|
-
const projectDir =
|
|
7757
|
+
const projectDir = path8.join(getStorageDir(), "project");
|
|
7749
7758
|
const projectNames = /* @__PURE__ */ new Map();
|
|
7750
7759
|
if (fs9.existsSync(projectDir)) {
|
|
7751
7760
|
try {
|
|
7752
7761
|
for (const file of fs9.readdirSync(projectDir).filter((f) => f.endsWith(".json"))) {
|
|
7753
|
-
const proj = readJsonSafe(
|
|
7762
|
+
const proj = readJsonSafe(path8.join(projectDir, file));
|
|
7754
7763
|
if (proj) {
|
|
7755
7764
|
projectNames.set(proj.id, proj.path || proj.name || proj.id);
|
|
7756
7765
|
}
|
|
@@ -7763,14 +7772,14 @@ var require_openCode = __commonJS({
|
|
|
7763
7772
|
currentProjectId = resolveProjectIdFromFiles(workspacePath);
|
|
7764
7773
|
}
|
|
7765
7774
|
for (const projectId of projectIds) {
|
|
7766
|
-
const projSessionDir =
|
|
7775
|
+
const projSessionDir = path8.join(sessionBase, projectId);
|
|
7767
7776
|
let sessionCount = 0;
|
|
7768
7777
|
let lastModified = /* @__PURE__ */ new Date(0);
|
|
7769
7778
|
try {
|
|
7770
7779
|
const sessions = fs9.readdirSync(projSessionDir).filter((f) => f.endsWith(".json"));
|
|
7771
7780
|
for (const session of sessions) {
|
|
7772
7781
|
try {
|
|
7773
|
-
const fstats = fs9.statSync(
|
|
7782
|
+
const fstats = fs9.statSync(path8.join(projSessionDir, session));
|
|
7774
7783
|
if (fstats.size > 0) {
|
|
7775
7784
|
sessionCount++;
|
|
7776
7785
|
if (fstats.mtime > lastModified) {
|
|
@@ -7811,7 +7820,7 @@ var require_openCode = __commonJS({
|
|
|
7811
7820
|
return filename.endsWith(".json");
|
|
7812
7821
|
}
|
|
7813
7822
|
getSessionId(sessionPath) {
|
|
7814
|
-
return
|
|
7823
|
+
return path8.basename(sessionPath, ".json");
|
|
7815
7824
|
}
|
|
7816
7825
|
encodeWorkspacePath(workspacePath) {
|
|
7817
7826
|
const db = this.ensureDb();
|
|
@@ -7839,19 +7848,19 @@ var require_openCode = __commonJS({
|
|
|
7839
7848
|
if (session?.title) {
|
|
7840
7849
|
return truncateTitle(session.title);
|
|
7841
7850
|
}
|
|
7842
|
-
const messageDir =
|
|
7851
|
+
const messageDir = path8.join(getStorageDir(), "message", sessionId);
|
|
7843
7852
|
if (!fs9.existsSync(messageDir))
|
|
7844
7853
|
return null;
|
|
7845
7854
|
try {
|
|
7846
7855
|
const files = fs9.readdirSync(messageDir).filter((f) => f.endsWith(".json")).slice(0, 5);
|
|
7847
7856
|
for (const file of files) {
|
|
7848
|
-
const msg = readJsonSafe(
|
|
7857
|
+
const msg = readJsonSafe(path8.join(messageDir, file));
|
|
7849
7858
|
if (msg?.role === "user") {
|
|
7850
|
-
const partDir =
|
|
7859
|
+
const partDir = path8.join(getStorageDir(), "part", msg.id);
|
|
7851
7860
|
if (fs9.existsSync(partDir)) {
|
|
7852
7861
|
const partFiles = fs9.readdirSync(partDir).filter((f) => f.endsWith(".json"));
|
|
7853
7862
|
for (const pf of partFiles) {
|
|
7854
|
-
const part = readJsonSafe(
|
|
7863
|
+
const part = readJsonSafe(path8.join(partDir, pf));
|
|
7855
7864
|
if (part?.type === "text" && part.text.trim().length > 0) {
|
|
7856
7865
|
let text = part.text.trim().replace(/\s+/g, " ");
|
|
7857
7866
|
if (text.length > 60) {
|
|
@@ -8035,7 +8044,7 @@ var require_openCode = __commonJS({
|
|
|
8035
8044
|
}
|
|
8036
8045
|
searchInSessionFromFiles(sessionPath, sessionId, queryLower, query, maxResults) {
|
|
8037
8046
|
const results = [];
|
|
8038
|
-
const messageDir =
|
|
8047
|
+
const messageDir = path8.join(getStorageDir(), "message", sessionId);
|
|
8039
8048
|
if (!fs9.existsSync(messageDir))
|
|
8040
8049
|
return results;
|
|
8041
8050
|
try {
|
|
@@ -8045,10 +8054,10 @@ var require_openCode = __commonJS({
|
|
|
8045
8054
|
for (const file of messageFiles) {
|
|
8046
8055
|
if (results.length >= maxResults)
|
|
8047
8056
|
break;
|
|
8048
|
-
const msg = readJsonSafe(
|
|
8057
|
+
const msg = readJsonSafe(path8.join(messageDir, file));
|
|
8049
8058
|
if (!msg)
|
|
8050
8059
|
continue;
|
|
8051
|
-
const partDir =
|
|
8060
|
+
const partDir = path8.join(getStorageDir(), "part", msg.id);
|
|
8052
8061
|
if (!fs9.existsSync(partDir))
|
|
8053
8062
|
continue;
|
|
8054
8063
|
try {
|
|
@@ -8056,7 +8065,7 @@ var require_openCode = __commonJS({
|
|
|
8056
8065
|
for (const pf of partFiles) {
|
|
8057
8066
|
if (results.length >= maxResults)
|
|
8058
8067
|
break;
|
|
8059
|
-
const part = readJsonSafe(
|
|
8068
|
+
const part = readJsonSafe(path8.join(partDir, pf));
|
|
8060
8069
|
if (!part)
|
|
8061
8070
|
continue;
|
|
8062
8071
|
let text = "";
|
|
@@ -8093,11 +8102,11 @@ var require_openCode = __commonJS({
|
|
|
8093
8102
|
return results;
|
|
8094
8103
|
}
|
|
8095
8104
|
getProjectsBaseDir() {
|
|
8096
|
-
return
|
|
8105
|
+
return path8.join(getStorageDir(), "session");
|
|
8097
8106
|
}
|
|
8098
8107
|
// --- Stats ---
|
|
8099
8108
|
readSessionStats(sessionPath) {
|
|
8100
|
-
const sessionId =
|
|
8109
|
+
const sessionId = path8.basename(sessionPath, ".json");
|
|
8101
8110
|
const db = this.ensureDb();
|
|
8102
8111
|
let messageCount = 0;
|
|
8103
8112
|
let startTime = "";
|
|
@@ -8969,13 +8978,13 @@ var require_codexDatabase = __commonJS({
|
|
|
8969
8978
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8970
8979
|
exports.CodexDatabase = void 0;
|
|
8971
8980
|
var fs9 = __importStar(__require("fs"));
|
|
8972
|
-
var
|
|
8981
|
+
var path8 = __importStar(__require("path"));
|
|
8973
8982
|
var child_process_1 = __require("child_process");
|
|
8974
8983
|
var CodexDatabase = class {
|
|
8975
8984
|
dbPath;
|
|
8976
8985
|
sqlite3Available = null;
|
|
8977
8986
|
constructor(codexHome) {
|
|
8978
|
-
this.dbPath =
|
|
8987
|
+
this.dbPath = path8.join(codexHome, "state.sqlite");
|
|
8979
8988
|
}
|
|
8980
8989
|
isAvailable() {
|
|
8981
8990
|
try {
|
|
@@ -9040,7 +9049,7 @@ var require_codexDatabase = __commonJS({
|
|
|
9040
9049
|
const all = this.query("SELECT * FROM threads ORDER BY updated_at DESC");
|
|
9041
9050
|
return all.filter((t) => {
|
|
9042
9051
|
const threadCwd = normalizePath(t.cwd);
|
|
9043
|
-
return threadCwd === normalized || normalized.startsWith(threadCwd +
|
|
9052
|
+
return threadCwd === normalized || normalized.startsWith(threadCwd + path8.sep) || threadCwd.startsWith(normalized + path8.sep);
|
|
9044
9053
|
});
|
|
9045
9054
|
}
|
|
9046
9055
|
getMostRecentThread(cwd2) {
|
|
@@ -9070,7 +9079,7 @@ var require_codexDatabase = __commonJS({
|
|
|
9070
9079
|
try {
|
|
9071
9080
|
return fs9.realpathSync(input);
|
|
9072
9081
|
} catch {
|
|
9073
|
-
return
|
|
9082
|
+
return path8.resolve(input);
|
|
9074
9083
|
}
|
|
9075
9084
|
}
|
|
9076
9085
|
}
|
|
@@ -9120,7 +9129,7 @@ var require_codex = __commonJS({
|
|
|
9120
9129
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9121
9130
|
exports.CodexProvider = void 0;
|
|
9122
9131
|
var fs9 = __importStar(__require("fs"));
|
|
9123
|
-
var
|
|
9132
|
+
var path8 = __importStar(__require("path"));
|
|
9124
9133
|
var codexParser_1 = require_codexParser();
|
|
9125
9134
|
var codexDatabase_1 = require_codexDatabase();
|
|
9126
9135
|
var codexProfiles_1 = require_codexProfiles();
|
|
@@ -9129,13 +9138,13 @@ var require_codex = __commonJS({
|
|
|
9129
9138
|
return (0, codexProfiles_1.getCodexMonitoringHomes)();
|
|
9130
9139
|
}
|
|
9131
9140
|
function getSessionsDirs() {
|
|
9132
|
-
return getCodexHomes().map((home) =>
|
|
9141
|
+
return getCodexHomes().map((home) => path8.join(home, "sessions"));
|
|
9133
9142
|
}
|
|
9134
9143
|
function isRolloutFile(filename) {
|
|
9135
9144
|
return filename.startsWith("rollout-") && filename.endsWith(".jsonl");
|
|
9136
9145
|
}
|
|
9137
9146
|
function extractSessionId(filename) {
|
|
9138
|
-
const base =
|
|
9147
|
+
const base = path8.basename(filename, ".jsonl");
|
|
9139
9148
|
const parts = base.split("-");
|
|
9140
9149
|
if (parts.length >= 6) {
|
|
9141
9150
|
const possibleUuid = parts.slice(-5).join("-");
|
|
@@ -9159,7 +9168,7 @@ var require_codex = __commonJS({
|
|
|
9159
9168
|
return results;
|
|
9160
9169
|
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
9161
9170
|
for (const entry of entries) {
|
|
9162
|
-
const fullPath =
|
|
9171
|
+
const fullPath = path8.join(dir, entry.name);
|
|
9163
9172
|
if (entry.isDirectory()) {
|
|
9164
9173
|
results.push(...findRolloutFiles(fullPath));
|
|
9165
9174
|
} else if (entry.isFile() && isRolloutFile(entry.name)) {
|
|
@@ -9196,10 +9205,10 @@ var require_codex = __commonJS({
|
|
|
9196
9205
|
return dir;
|
|
9197
9206
|
}
|
|
9198
9207
|
}
|
|
9199
|
-
return dirs[0] ??
|
|
9208
|
+
return dirs[0] ?? path8.join(process.cwd(), ".codex", "sessions");
|
|
9200
9209
|
}
|
|
9201
9210
|
function getCodexHome() {
|
|
9202
|
-
return
|
|
9211
|
+
return path8.dirname(getSessionsDir());
|
|
9203
9212
|
}
|
|
9204
9213
|
function isSystemInjection(text) {
|
|
9205
9214
|
const t = text.trimStart();
|
|
@@ -9265,13 +9274,13 @@ var require_codex = __commonJS({
|
|
|
9265
9274
|
function cwdMatches(sessionCwd, workspacePath) {
|
|
9266
9275
|
const normalizedSession = normalizePath(sessionCwd);
|
|
9267
9276
|
const normalizedWorkspace = normalizePath(workspacePath);
|
|
9268
|
-
return normalizedSession === normalizedWorkspace || normalizedWorkspace.startsWith(normalizedSession +
|
|
9277
|
+
return normalizedSession === normalizedWorkspace || normalizedWorkspace.startsWith(normalizedSession + path8.sep) || normalizedSession.startsWith(normalizedWorkspace + path8.sep);
|
|
9269
9278
|
}
|
|
9270
9279
|
function normalizePath(input) {
|
|
9271
9280
|
try {
|
|
9272
9281
|
return fs9.realpathSync(input);
|
|
9273
9282
|
} catch {
|
|
9274
|
-
return
|
|
9283
|
+
return path8.resolve(input);
|
|
9275
9284
|
}
|
|
9276
9285
|
}
|
|
9277
9286
|
function extractFirstUserMessage(rolloutPath) {
|
|
@@ -9493,7 +9502,7 @@ var require_codex = __commonJS({
|
|
|
9493
9502
|
if (db) {
|
|
9494
9503
|
const thread = db.getMostRecentThread(workspacePath);
|
|
9495
9504
|
if (thread?.rollout_path) {
|
|
9496
|
-
return
|
|
9505
|
+
return path8.dirname(thread.rollout_path);
|
|
9497
9506
|
}
|
|
9498
9507
|
}
|
|
9499
9508
|
return getSessionsDir();
|
|
@@ -9503,7 +9512,7 @@ var require_codex = __commonJS({
|
|
|
9503
9512
|
if (db) {
|
|
9504
9513
|
const thread = db.getMostRecentThread(workspacePath);
|
|
9505
9514
|
if (thread?.rollout_path && fs9.existsSync(thread.rollout_path)) {
|
|
9506
|
-
return
|
|
9515
|
+
return path8.dirname(thread.rollout_path);
|
|
9507
9516
|
}
|
|
9508
9517
|
}
|
|
9509
9518
|
const files = findRolloutFilesInConfiguredHomes();
|
|
@@ -9513,7 +9522,7 @@ var require_codex = __commonJS({
|
|
|
9513
9522
|
for (const file of files) {
|
|
9514
9523
|
const meta = readSessionMeta(file.path);
|
|
9515
9524
|
if (meta && cwdMatches(meta.cwd, workspacePath)) {
|
|
9516
|
-
return
|
|
9525
|
+
return path8.dirname(file.path);
|
|
9517
9526
|
}
|
|
9518
9527
|
}
|
|
9519
9528
|
return getSessionsDir();
|
|
@@ -9588,7 +9597,7 @@ var require_codex = __commonJS({
|
|
|
9588
9597
|
}
|
|
9589
9598
|
} else {
|
|
9590
9599
|
seenCwds.set(meta.cwd, {
|
|
9591
|
-
dir:
|
|
9600
|
+
dir: path8.dirname(file.path),
|
|
9592
9601
|
name: meta.cwd,
|
|
9593
9602
|
encodedName: meta.cwd,
|
|
9594
9603
|
sessionCount: 1,
|
|
@@ -9616,7 +9625,7 @@ var require_codex = __commonJS({
|
|
|
9616
9625
|
return isRolloutFile(filename);
|
|
9617
9626
|
}
|
|
9618
9627
|
getSessionId(sessionPath) {
|
|
9619
|
-
return extractSessionId(
|
|
9628
|
+
return extractSessionId(path8.basename(sessionPath));
|
|
9620
9629
|
}
|
|
9621
9630
|
encodeWorkspacePath(workspacePath) {
|
|
9622
9631
|
return workspacePath;
|
|
@@ -9663,7 +9672,7 @@ var require_codex = __commonJS({
|
|
|
9663
9672
|
for (const file of filesToCheck) {
|
|
9664
9673
|
const meta = readSessionMeta(file.path);
|
|
9665
9674
|
if (meta?.forked_from_id === sessionId) {
|
|
9666
|
-
const childId = extractSessionId(
|
|
9675
|
+
const childId = extractSessionId(path8.basename(file.path));
|
|
9667
9676
|
const stats = this.buildSubagentStats(childId, file.path, meta.source);
|
|
9668
9677
|
if (stats)
|
|
9669
9678
|
subagents.push(stats);
|
|
@@ -9775,7 +9784,7 @@ var require_codex = __commonJS({
|
|
|
9775
9784
|
}
|
|
9776
9785
|
// --- Stats ---
|
|
9777
9786
|
readSessionStats(sessionPath) {
|
|
9778
|
-
const sessionId = extractSessionId(
|
|
9787
|
+
const sessionId = extractSessionId(path8.basename(sessionPath));
|
|
9779
9788
|
let messageCount = 0;
|
|
9780
9789
|
let startTime = "";
|
|
9781
9790
|
let endTime = "";
|
|
@@ -10117,24 +10126,24 @@ var require_toolSummary = __commonJS({
|
|
|
10117
10126
|
if (!pattern)
|
|
10118
10127
|
return "";
|
|
10119
10128
|
const glob = input.glob;
|
|
10120
|
-
const
|
|
10129
|
+
const path8 = input.path;
|
|
10121
10130
|
const type = input.type;
|
|
10122
10131
|
const parts = [truncate2(pattern, 40)];
|
|
10123
10132
|
if (glob)
|
|
10124
10133
|
parts.push(`in ${glob}`);
|
|
10125
10134
|
else if (type)
|
|
10126
10135
|
parts.push(`in *.${type}`);
|
|
10127
|
-
else if (
|
|
10128
|
-
parts.push(`in ${basename5(
|
|
10136
|
+
else if (path8)
|
|
10137
|
+
parts.push(`in ${basename5(path8)}`);
|
|
10129
10138
|
return parts.join(" ");
|
|
10130
10139
|
};
|
|
10131
10140
|
var formatGlob = (input) => {
|
|
10132
10141
|
const pattern = input.pattern;
|
|
10133
10142
|
if (!pattern)
|
|
10134
10143
|
return "";
|
|
10135
|
-
const
|
|
10136
|
-
if (
|
|
10137
|
-
return `${pattern} in ${basename5(
|
|
10144
|
+
const path8 = input.path;
|
|
10145
|
+
if (path8)
|
|
10146
|
+
return `${pattern} in ${basename5(path8)}`;
|
|
10138
10147
|
return pattern;
|
|
10139
10148
|
};
|
|
10140
10149
|
var formatTask = (input) => {
|
|
@@ -10443,12 +10452,12 @@ var require_subagentTraceParser = __commonJS({
|
|
|
10443
10452
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10444
10453
|
exports.scanSubagentTraces = scanSubagentTraces;
|
|
10445
10454
|
var fs9 = __importStar(__require("fs"));
|
|
10446
|
-
var
|
|
10455
|
+
var path8 = __importStar(__require("path"));
|
|
10447
10456
|
var toolSummary_1 = require_toolSummary();
|
|
10448
10457
|
var noiseClassifier_1 = require_noiseClassifier();
|
|
10449
10458
|
var AGENT_FILE_PATTERN = /^agent-(.+)\.jsonl$/;
|
|
10450
10459
|
function scanSubagentTraces(sessionDir, sessionId) {
|
|
10451
|
-
const subagentsDir =
|
|
10460
|
+
const subagentsDir = path8.join(sessionDir, sessionId, "subagents");
|
|
10452
10461
|
try {
|
|
10453
10462
|
if (!fs9.existsSync(subagentsDir))
|
|
10454
10463
|
return [];
|
|
@@ -10459,7 +10468,7 @@ var require_subagentTraceParser = __commonJS({
|
|
|
10459
10468
|
if (!match)
|
|
10460
10469
|
continue;
|
|
10461
10470
|
const agentId = match[1];
|
|
10462
|
-
const filePath =
|
|
10471
|
+
const filePath = path8.join(subagentsDir, file);
|
|
10463
10472
|
const trace = parseAgentTrace(filePath, agentId);
|
|
10464
10473
|
if (trace)
|
|
10465
10474
|
traces.push(trace);
|
|
@@ -10743,8 +10752,8 @@ var require_debugLogParser = __commonJS({
|
|
|
10743
10752
|
exports.collapseDuplicates = collapseDuplicates;
|
|
10744
10753
|
exports.discoverDebugLogs = discoverDebugLogs;
|
|
10745
10754
|
var fs9 = __importStar(__require("fs"));
|
|
10746
|
-
var
|
|
10747
|
-
var
|
|
10755
|
+
var path8 = __importStar(__require("path"));
|
|
10756
|
+
var os6 = __importStar(__require("os"));
|
|
10748
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+(.*)$/;
|
|
10749
10758
|
var LEVEL_ORDER = {
|
|
10750
10759
|
DEBUG: 0,
|
|
@@ -10798,12 +10807,12 @@ var require_debugLogParser = __commonJS({
|
|
|
10798
10807
|
return result;
|
|
10799
10808
|
}
|
|
10800
10809
|
function discoverDebugLogs() {
|
|
10801
|
-
const debugDir =
|
|
10810
|
+
const debugDir = path8.join(os6.homedir(), ".claude", "debug");
|
|
10802
10811
|
try {
|
|
10803
10812
|
if (!fs9.existsSync(debugDir))
|
|
10804
10813
|
return [];
|
|
10805
10814
|
return fs9.readdirSync(debugDir).filter((f) => f.endsWith(".log") || f.endsWith(".txt")).map((name) => {
|
|
10806
|
-
const fullPath =
|
|
10815
|
+
const fullPath = path8.join(debugDir, name);
|
|
10807
10816
|
try {
|
|
10808
10817
|
const stat = fs9.statSync(fullPath);
|
|
10809
10818
|
return {
|
|
@@ -10867,7 +10876,7 @@ var require_sessionSearch = __commonJS({
|
|
|
10867
10876
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10868
10877
|
exports.searchSessions = searchSessions2;
|
|
10869
10878
|
var fs9 = __importStar(__require("fs"));
|
|
10870
|
-
var
|
|
10879
|
+
var path8 = __importStar(__require("path"));
|
|
10871
10880
|
async function searchSessions2(provider, query, opts) {
|
|
10872
10881
|
const maxResults = opts?.maxResults ?? 50;
|
|
10873
10882
|
const results = [];
|
|
@@ -10886,7 +10895,7 @@ var require_sessionSearch = __commonJS({
|
|
|
10886
10895
|
const dir = folder.dir;
|
|
10887
10896
|
if (fs9.existsSync(dir)) {
|
|
10888
10897
|
const entries = fs9.readdirSync(dir).filter((f) => f.endsWith(".jsonl") || f.endsWith(".json"));
|
|
10889
|
-
sessionFiles = entries.map((f) =>
|
|
10898
|
+
sessionFiles = entries.map((f) => path8.join(dir, f));
|
|
10890
10899
|
}
|
|
10891
10900
|
} catch {
|
|
10892
10901
|
}
|
|
@@ -11758,7 +11767,7 @@ var require_sqliteWatcher = __commonJS({
|
|
|
11758
11767
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11759
11768
|
exports.SqliteSessionWatcher = void 0;
|
|
11760
11769
|
var fs9 = __importStar(__require("fs"));
|
|
11761
|
-
var
|
|
11770
|
+
var path8 = __importStar(__require("path"));
|
|
11762
11771
|
var openCodeDatabase_1 = require_openCodeDatabase();
|
|
11763
11772
|
var openCodeParser_1 = require_openCodeParser();
|
|
11764
11773
|
var DEBOUNCE_MS = 200;
|
|
@@ -11883,7 +11892,7 @@ var require_sqliteWatcher = __commonJS({
|
|
|
11883
11892
|
this.dbPath = dbPath;
|
|
11884
11893
|
this.sessionId = sessionId;
|
|
11885
11894
|
this.callbacks = callbacks;
|
|
11886
|
-
this.db = new openCodeDatabase_1.OpenCodeDatabase(
|
|
11895
|
+
this.db = new openCodeDatabase_1.OpenCodeDatabase(path8.dirname(dbPath));
|
|
11887
11896
|
}
|
|
11888
11897
|
get isActive() {
|
|
11889
11898
|
return this._isActive;
|
|
@@ -12048,15 +12057,15 @@ var require_factory = __commonJS({
|
|
|
12048
12057
|
}();
|
|
12049
12058
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12050
12059
|
exports.createWatcher = createWatcher5;
|
|
12051
|
-
var
|
|
12052
|
-
var
|
|
12060
|
+
var os6 = __importStar(__require("os"));
|
|
12061
|
+
var path8 = __importStar(__require("path"));
|
|
12053
12062
|
var jsonlWatcher_1 = require_jsonlWatcher();
|
|
12054
12063
|
var sqliteWatcher_1 = require_sqliteWatcher();
|
|
12055
12064
|
function getOpenCodeDataDir() {
|
|
12056
12065
|
const xdg = process.env.XDG_DATA_HOME;
|
|
12057
12066
|
if (xdg)
|
|
12058
|
-
return
|
|
12059
|
-
return
|
|
12067
|
+
return path8.join(xdg, "opencode");
|
|
12068
|
+
return path8.join(os6.homedir(), ".local", "share", "opencode");
|
|
12060
12069
|
}
|
|
12061
12070
|
function createWatcher5(options) {
|
|
12062
12071
|
const { provider, workspacePath, sessionId, callbacks } = options;
|
|
@@ -12068,7 +12077,7 @@ var require_factory = __commonJS({
|
|
|
12068
12077
|
if (sessionId) {
|
|
12069
12078
|
const match = sessions.find((s) => s.includes(sessionId));
|
|
12070
12079
|
if (!match) {
|
|
12071
|
-
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(", ")}`);
|
|
12072
12081
|
}
|
|
12073
12082
|
sessionPath = match;
|
|
12074
12083
|
} else {
|
|
@@ -12084,8 +12093,8 @@ var require_factory = __commonJS({
|
|
|
12084
12093
|
return new jsonlWatcher_1.JsonlSessionWatcher(providerId, sessionPath, callbacks);
|
|
12085
12094
|
case "opencode": {
|
|
12086
12095
|
const dataDir = getOpenCodeDataDir();
|
|
12087
|
-
const dbPath =
|
|
12088
|
-
const sid =
|
|
12096
|
+
const dbPath = path8.join(dataDir, "opencode.db");
|
|
12097
|
+
const sid = path8.basename(sessionPath, ".json");
|
|
12089
12098
|
return new sqliteWatcher_1.SqliteSessionWatcher(dbPath, sid, callbacks);
|
|
12090
12099
|
}
|
|
12091
12100
|
default:
|
|
@@ -14480,6 +14489,243 @@ var require_PatternExtractor = __commonJS({
|
|
|
14480
14489
|
}
|
|
14481
14490
|
});
|
|
14482
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
|
+
|
|
14483
14729
|
// ../sidekick-shared/dist/aggregation/EventAggregator.js
|
|
14484
14730
|
var require_EventAggregator = __commonJS({
|
|
14485
14731
|
"../sidekick-shared/dist/aggregation/EventAggregator.js"(exports) {
|
|
@@ -14495,6 +14741,7 @@ var require_EventAggregator = __commonJS({
|
|
|
14495
14741
|
var FrequencyTracker_1 = require_FrequencyTracker();
|
|
14496
14742
|
var HeatmapTracker_1 = require_HeatmapTracker();
|
|
14497
14743
|
var PatternExtractor_1 = require_PatternExtractor();
|
|
14744
|
+
var modelInfo_1 = require_modelInfo();
|
|
14498
14745
|
var DEFAULT_TIMELINE_CAP = 200;
|
|
14499
14746
|
var DEFAULT_LATENCY_CAP = 100;
|
|
14500
14747
|
var DEFAULT_BURN_WINDOW_MS = 5 * 6e4;
|
|
@@ -14686,6 +14933,14 @@ var require_EventAggregator = __commonJS({
|
|
|
14686
14933
|
this.currentContextSize = contextSize;
|
|
14687
14934
|
if (event.model) {
|
|
14688
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;
|
|
14689
14944
|
const acc = this.modelUsage.get(model) ?? {
|
|
14690
14945
|
calls: 0,
|
|
14691
14946
|
tokens: 0,
|
|
@@ -14693,7 +14948,8 @@ var require_EventAggregator = __commonJS({
|
|
|
14693
14948
|
outputTokens: 0,
|
|
14694
14949
|
cacheWriteTokens: 0,
|
|
14695
14950
|
cacheReadTokens: 0,
|
|
14696
|
-
cost: 0
|
|
14951
|
+
cost: 0,
|
|
14952
|
+
priced: true
|
|
14697
14953
|
};
|
|
14698
14954
|
acc.calls++;
|
|
14699
14955
|
acc.tokens += inputTok + outputTok;
|
|
@@ -14701,8 +14957,9 @@ var require_EventAggregator = __commonJS({
|
|
|
14701
14957
|
acc.outputTokens += outputTok;
|
|
14702
14958
|
acc.cacheWriteTokens += cacheWrite;
|
|
14703
14959
|
acc.cacheReadTokens += cacheRead;
|
|
14704
|
-
|
|
14705
|
-
|
|
14960
|
+
acc.cost += computed;
|
|
14961
|
+
if (!evPriced)
|
|
14962
|
+
acc.priced = false;
|
|
14706
14963
|
this.modelUsage.set(model, acc);
|
|
14707
14964
|
}
|
|
14708
14965
|
}
|
|
@@ -15003,7 +15260,26 @@ var require_EventAggregator = __commonJS({
|
|
|
15003
15260
|
const outputTok = usage.output_tokens;
|
|
15004
15261
|
const cacheWrite = usage.cache_creation_input_tokens ?? 0;
|
|
15005
15262
|
const cacheRead = usage.cache_read_input_tokens ?? 0;
|
|
15006
|
-
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
|
+
}
|
|
15007
15283
|
this.inputTokens += inputTok;
|
|
15008
15284
|
this.outputTokens += outputTok;
|
|
15009
15285
|
this.cacheWriteTokens += cacheWrite;
|
|
@@ -15037,15 +15313,17 @@ var require_EventAggregator = __commonJS({
|
|
|
15037
15313
|
inputTokens: contextSize,
|
|
15038
15314
|
turnIndex: this.contextTurnIndex++
|
|
15039
15315
|
});
|
|
15040
|
-
const
|
|
15041
|
-
const acc = this.modelUsage.get(
|
|
15316
|
+
const perModelKey = model ?? this.currentModel ?? "unknown";
|
|
15317
|
+
const acc = this.modelUsage.get(perModelKey) ?? {
|
|
15042
15318
|
calls: 0,
|
|
15043
15319
|
tokens: 0,
|
|
15044
15320
|
inputTokens: 0,
|
|
15045
15321
|
outputTokens: 0,
|
|
15046
15322
|
cacheWriteTokens: 0,
|
|
15047
15323
|
cacheReadTokens: 0,
|
|
15048
|
-
|
|
15324
|
+
reasoningTokens: 0,
|
|
15325
|
+
cost: 0,
|
|
15326
|
+
priced: true
|
|
15049
15327
|
};
|
|
15050
15328
|
acc.calls++;
|
|
15051
15329
|
acc.tokens += inputTok + outputTok;
|
|
@@ -15053,8 +15331,11 @@ var require_EventAggregator = __commonJS({
|
|
|
15053
15331
|
acc.outputTokens += outputTok;
|
|
15054
15332
|
acc.cacheWriteTokens += cacheWrite;
|
|
15055
15333
|
acc.cacheReadTokens += cacheRead;
|
|
15334
|
+
acc.reasoningTokens = (acc.reasoningTokens ?? 0) + reasoningTok;
|
|
15056
15335
|
acc.cost += cost;
|
|
15057
|
-
|
|
15336
|
+
if (!priced)
|
|
15337
|
+
acc.priced = false;
|
|
15338
|
+
this.modelUsage.set(perModelKey, acc);
|
|
15058
15339
|
this.updateBurnRate(timestamp);
|
|
15059
15340
|
}
|
|
15060
15341
|
// ═══════════════════════════════════════════════════════════════════════
|
|
@@ -16106,15 +16387,15 @@ var require_snapshot = __commonJS({
|
|
|
16106
16387
|
exports.deleteSnapshot = deleteSnapshot2;
|
|
16107
16388
|
exports.isSnapshotValid = isSnapshotValid2;
|
|
16108
16389
|
var fs9 = __importStar(__require("fs"));
|
|
16109
|
-
var
|
|
16390
|
+
var path8 = __importStar(__require("path"));
|
|
16110
16391
|
var paths_1 = require_paths();
|
|
16111
16392
|
var SNAPSHOT_VERSION = 1;
|
|
16112
16393
|
function getSnapshotsDir() {
|
|
16113
|
-
return
|
|
16394
|
+
return path8.join((0, paths_1.getConfigDir)(), "snapshots");
|
|
16114
16395
|
}
|
|
16115
16396
|
function getSnapshotPath(sessionId) {
|
|
16116
16397
|
const safe = sessionId.replace(/[/\\:]/g, "_");
|
|
16117
|
-
return
|
|
16398
|
+
return path8.join(getSnapshotsDir(), `${safe}.json`);
|
|
16118
16399
|
}
|
|
16119
16400
|
function saveSnapshot2(snapshot) {
|
|
16120
16401
|
try {
|
|
@@ -17333,12 +17614,12 @@ var require_credentialIO = __commonJS({
|
|
|
17333
17614
|
exports.readActiveCredentials = readActiveCredentials;
|
|
17334
17615
|
exports.writeActiveCredentials = writeActiveCredentials;
|
|
17335
17616
|
var fs9 = __importStar(__require("fs"));
|
|
17336
|
-
var
|
|
17337
|
-
var
|
|
17617
|
+
var path8 = __importStar(__require("path"));
|
|
17618
|
+
var os6 = __importStar(__require("os"));
|
|
17338
17619
|
var child_process_1 = __require("child_process");
|
|
17339
17620
|
var KEYCHAIN_SERVICE = "Claude Code-credentials";
|
|
17340
17621
|
function getCredentialsFilePath() {
|
|
17341
|
-
return
|
|
17622
|
+
return path8.join(os6.homedir(), ".claude", ".credentials.json");
|
|
17342
17623
|
}
|
|
17343
17624
|
function readActiveCredentials() {
|
|
17344
17625
|
if (process.platform === "darwin") {
|
|
@@ -17483,28 +17764,28 @@ var require_accounts = __commonJS({
|
|
|
17483
17764
|
exports.getActiveAccount = getActiveAccount3;
|
|
17484
17765
|
exports.isMultiAccountEnabled = isMultiAccountEnabled;
|
|
17485
17766
|
var fs9 = __importStar(__require("fs"));
|
|
17486
|
-
var
|
|
17487
|
-
var
|
|
17767
|
+
var path8 = __importStar(__require("path"));
|
|
17768
|
+
var os6 = __importStar(__require("os"));
|
|
17488
17769
|
var credentialIO_1 = require_credentialIO();
|
|
17489
17770
|
var accountRegistry_1 = require_accountRegistry();
|
|
17490
17771
|
function getClaudeDir() {
|
|
17491
|
-
return
|
|
17772
|
+
return path8.join(os6.homedir(), ".claude");
|
|
17492
17773
|
}
|
|
17493
17774
|
function getClaudeConfigPath() {
|
|
17494
|
-
const primary =
|
|
17775
|
+
const primary = path8.join(getClaudeDir(), ".claude.json");
|
|
17495
17776
|
try {
|
|
17496
17777
|
const data = JSON.parse(fs9.readFileSync(primary, "utf8"));
|
|
17497
17778
|
if (data?.oauthAccount)
|
|
17498
17779
|
return primary;
|
|
17499
17780
|
} catch {
|
|
17500
17781
|
}
|
|
17501
|
-
return
|
|
17782
|
+
return path8.join(os6.homedir(), ".claude.json");
|
|
17502
17783
|
}
|
|
17503
17784
|
function getCredentialsDir() {
|
|
17504
|
-
return
|
|
17785
|
+
return path8.join((0, accountRegistry_1.getAccountsDir)(), "credentials");
|
|
17505
17786
|
}
|
|
17506
17787
|
function getConfigsDir() {
|
|
17507
|
-
return
|
|
17788
|
+
return path8.join((0, accountRegistry_1.getAccountsDir)(), "configs");
|
|
17508
17789
|
}
|
|
17509
17790
|
function ensureDirs() {
|
|
17510
17791
|
for (const dir of [(0, accountRegistry_1.getAccountsDir)(), getCredentialsDir(), getConfigsDir()]) {
|
|
@@ -17587,14 +17868,14 @@ var require_accounts = __commonJS({
|
|
|
17587
17868
|
if (existing) {
|
|
17588
17869
|
if (label !== void 0)
|
|
17589
17870
|
existing.label = label;
|
|
17590
|
-
atomicWriteJson(
|
|
17591
|
-
atomicWriteJson(
|
|
17871
|
+
atomicWriteJson(path8.join(getCredentialsDir(), `${active.uuid}.credentials.json`), credBlob);
|
|
17872
|
+
atomicWriteJson(path8.join(getConfigsDir(), `${active.uuid}.config.json`), configBlob);
|
|
17592
17873
|
registry.activeAccountUuid = active.uuid;
|
|
17593
17874
|
writeAccountRegistry(registry);
|
|
17594
17875
|
return { success: true };
|
|
17595
17876
|
}
|
|
17596
|
-
atomicWriteJson(
|
|
17597
|
-
atomicWriteJson(
|
|
17877
|
+
atomicWriteJson(path8.join(getCredentialsDir(), `${active.uuid}.credentials.json`), credBlob);
|
|
17878
|
+
atomicWriteJson(path8.join(getConfigsDir(), `${active.uuid}.config.json`), configBlob);
|
|
17598
17879
|
registry.accounts.push({
|
|
17599
17880
|
uuid: active.uuid,
|
|
17600
17881
|
email: active.email,
|
|
@@ -17628,7 +17909,7 @@ var require_accounts = __commonJS({
|
|
|
17628
17909
|
if (currentActive) {
|
|
17629
17910
|
if (originalCreds) {
|
|
17630
17911
|
try {
|
|
17631
|
-
atomicWriteJson(
|
|
17912
|
+
atomicWriteJson(path8.join(getCredentialsDir(), `${currentActive.uuid}.credentials.json`), originalCreds);
|
|
17632
17913
|
} catch {
|
|
17633
17914
|
}
|
|
17634
17915
|
}
|
|
@@ -17636,7 +17917,7 @@ var require_accounts = __commonJS({
|
|
|
17636
17917
|
try {
|
|
17637
17918
|
const parsed = JSON.parse(originalConfig);
|
|
17638
17919
|
if (parsed.oauthAccount) {
|
|
17639
|
-
atomicWriteJson(
|
|
17920
|
+
atomicWriteJson(path8.join(getConfigsDir(), `${currentActive.uuid}.config.json`), parsed.oauthAccount);
|
|
17640
17921
|
}
|
|
17641
17922
|
} catch {
|
|
17642
17923
|
}
|
|
@@ -17645,12 +17926,12 @@ var require_accounts = __commonJS({
|
|
|
17645
17926
|
let targetCreds;
|
|
17646
17927
|
let targetOauthAccount;
|
|
17647
17928
|
try {
|
|
17648
|
-
targetCreds = JSON.parse(fs9.readFileSync(
|
|
17929
|
+
targetCreds = JSON.parse(fs9.readFileSync(path8.join(getCredentialsDir(), `${uuid}.credentials.json`), "utf8"));
|
|
17649
17930
|
} catch {
|
|
17650
17931
|
return { success: false, error: `Backed-up credentials for ${target.email} not found.` };
|
|
17651
17932
|
}
|
|
17652
17933
|
try {
|
|
17653
|
-
targetOauthAccount = JSON.parse(fs9.readFileSync(
|
|
17934
|
+
targetOauthAccount = JSON.parse(fs9.readFileSync(path8.join(getConfigsDir(), `${uuid}.config.json`), "utf8"));
|
|
17654
17935
|
} catch {
|
|
17655
17936
|
return { success: false, error: `Backed-up config for ${target.email} not found.` };
|
|
17656
17937
|
}
|
|
@@ -17702,11 +17983,11 @@ var require_accounts = __commonJS({
|
|
|
17702
17983
|
return { success: false, error: `Account ${uuid} not found.` };
|
|
17703
17984
|
}
|
|
17704
17985
|
try {
|
|
17705
|
-
fs9.unlinkSync(
|
|
17986
|
+
fs9.unlinkSync(path8.join(getCredentialsDir(), `${uuid}.credentials.json`));
|
|
17706
17987
|
} catch {
|
|
17707
17988
|
}
|
|
17708
17989
|
try {
|
|
17709
|
-
fs9.unlinkSync(
|
|
17990
|
+
fs9.unlinkSync(path8.join(getConfigsDir(), `${uuid}.config.json`));
|
|
17710
17991
|
} catch {
|
|
17711
17992
|
}
|
|
17712
17993
|
registry.accounts.splice(idx, 1);
|
|
@@ -18099,10 +18380,10 @@ var require_quotaSnapshots = __commonJS({
|
|
|
18099
18380
|
exports.writeQuotaSnapshot = writeQuotaSnapshot2;
|
|
18100
18381
|
exports.readQuotaSnapshot = readQuotaSnapshot2;
|
|
18101
18382
|
var fs9 = __importStar(__require("fs"));
|
|
18102
|
-
var
|
|
18383
|
+
var path8 = __importStar(__require("path"));
|
|
18103
18384
|
var paths_1 = require_paths();
|
|
18104
18385
|
function getQuotaSnapshotPath() {
|
|
18105
|
-
return
|
|
18386
|
+
return path8.join((0, paths_1.getConfigDir)(), "quota-snapshots.json");
|
|
18106
18387
|
}
|
|
18107
18388
|
function ensureConfigDir() {
|
|
18108
18389
|
fs9.mkdirSync((0, paths_1.getConfigDir)(), { recursive: true, mode: 448 });
|
|
@@ -18194,109 +18475,175 @@ var require_codexQuota = __commonJS({
|
|
|
18194
18475
|
}
|
|
18195
18476
|
});
|
|
18196
18477
|
|
|
18197
|
-
// ../sidekick-shared/dist/
|
|
18198
|
-
var
|
|
18199
|
-
"../sidekick-shared/dist/
|
|
18478
|
+
// ../sidekick-shared/dist/pricingCatalog.js
|
|
18479
|
+
var require_pricingCatalog = __commonJS({
|
|
18480
|
+
"../sidekick-shared/dist/pricingCatalog.js"(exports) {
|
|
18200
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
|
+
}();
|
|
18201
18519
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18202
|
-
exports.
|
|
18203
|
-
exports.
|
|
18204
|
-
exports.
|
|
18205
|
-
|
|
18206
|
-
|
|
18207
|
-
|
|
18208
|
-
|
|
18209
|
-
var
|
|
18210
|
-
|
|
18211
|
-
|
|
18212
|
-
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
outputCostPerMillion: 15,
|
|
18225
|
-
cacheWriteCostPerMillion: 3.75,
|
|
18226
|
-
cacheReadCostPerMillion: 0.3
|
|
18227
|
-
},
|
|
18228
|
-
"sonnet-4": {
|
|
18229
|
-
inputCostPerMillion: 3,
|
|
18230
|
-
outputCostPerMillion: 15,
|
|
18231
|
-
cacheWriteCostPerMillion: 3.75,
|
|
18232
|
-
cacheReadCostPerMillion: 0.3
|
|
18233
|
-
},
|
|
18234
|
-
"sonnet-4.6": {
|
|
18235
|
-
inputCostPerMillion: 3,
|
|
18236
|
-
outputCostPerMillion: 15,
|
|
18237
|
-
cacheWriteCostPerMillion: 3.75,
|
|
18238
|
-
cacheReadCostPerMillion: 0.3
|
|
18239
|
-
},
|
|
18240
|
-
"opus-4.5": {
|
|
18241
|
-
inputCostPerMillion: 5,
|
|
18242
|
-
outputCostPerMillion: 25,
|
|
18243
|
-
cacheWriteCostPerMillion: 6.25,
|
|
18244
|
-
cacheReadCostPerMillion: 0.5
|
|
18245
|
-
},
|
|
18246
|
-
"opus-4": {
|
|
18247
|
-
inputCostPerMillion: 15,
|
|
18248
|
-
outputCostPerMillion: 75,
|
|
18249
|
-
cacheWriteCostPerMillion: 18.75,
|
|
18250
|
-
cacheReadCostPerMillion: 1.5
|
|
18251
|
-
},
|
|
18252
|
-
"opus-4.6": {
|
|
18253
|
-
inputCostPerMillion: 15,
|
|
18254
|
-
outputCostPerMillion: 75,
|
|
18255
|
-
cacheWriteCostPerMillion: 18.75,
|
|
18256
|
-
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
|
+
};
|
|
18257
18542
|
}
|
|
18258
|
-
|
|
18259
|
-
|
|
18260
|
-
|
|
18261
|
-
|
|
18262
|
-
|
|
18263
|
-
|
|
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() };
|
|
18264
18570
|
}
|
|
18265
|
-
function
|
|
18266
|
-
const
|
|
18267
|
-
if (!
|
|
18268
|
-
return
|
|
18269
|
-
const
|
|
18270
|
-
|
|
18271
|
-
|
|
18272
|
-
|
|
18273
|
-
|
|
18274
|
-
|
|
18275
|
-
|
|
18276
|
-
|
|
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;
|
|
18277
18590
|
}
|
|
18278
|
-
function
|
|
18279
|
-
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;
|
|
18280
18598
|
return {
|
|
18281
|
-
|
|
18282
|
-
|
|
18283
|
-
|
|
18284
|
-
|
|
18599
|
+
inputCostPerMillion: input * 1e6,
|
|
18600
|
+
outputCostPerMillion: output * 1e6,
|
|
18601
|
+
cacheWriteCostPerMillion: cacheWrite * 1e6,
|
|
18602
|
+
cacheReadCostPerMillion: cacheRead * 1e6
|
|
18285
18603
|
};
|
|
18286
18604
|
}
|
|
18287
|
-
function
|
|
18288
|
-
const
|
|
18289
|
-
if (
|
|
18290
|
-
return
|
|
18291
|
-
return
|
|
18605
|
+
function stripProviderPrefix(key) {
|
|
18606
|
+
const slash = key.indexOf("/");
|
|
18607
|
+
if (slash < 0)
|
|
18608
|
+
return null;
|
|
18609
|
+
return key.slice(slash + 1);
|
|
18292
18610
|
}
|
|
18293
|
-
function
|
|
18294
|
-
|
|
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
|
+
}
|
|
18295
18622
|
}
|
|
18296
|
-
function
|
|
18297
|
-
|
|
18298
|
-
|
|
18299
|
-
|
|
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
|
+
}
|
|
18300
18647
|
}
|
|
18301
18648
|
}
|
|
18302
18649
|
});
|
|
@@ -18609,10 +18956,10 @@ var require_util = __commonJS({
|
|
|
18609
18956
|
function cloneDef(schema) {
|
|
18610
18957
|
return mergeDefs(schema._zod.def);
|
|
18611
18958
|
}
|
|
18612
|
-
function getElementAtPath(obj,
|
|
18613
|
-
if (!
|
|
18959
|
+
function getElementAtPath(obj, path8) {
|
|
18960
|
+
if (!path8)
|
|
18614
18961
|
return obj;
|
|
18615
|
-
return
|
|
18962
|
+
return path8.reduce((acc, key) => acc?.[key], obj);
|
|
18616
18963
|
}
|
|
18617
18964
|
function promiseAllObject(promisesObj) {
|
|
18618
18965
|
const keys = Object.keys(promisesObj);
|
|
@@ -18996,11 +19343,11 @@ var require_util = __commonJS({
|
|
|
18996
19343
|
}
|
|
18997
19344
|
return false;
|
|
18998
19345
|
}
|
|
18999
|
-
function prefixIssues(
|
|
19346
|
+
function prefixIssues(path8, issues) {
|
|
19000
19347
|
return issues.map((iss) => {
|
|
19001
19348
|
var _a;
|
|
19002
19349
|
(_a = iss).path ?? (_a.path = []);
|
|
19003
|
-
iss.path.unshift(
|
|
19350
|
+
iss.path.unshift(path8);
|
|
19004
19351
|
return iss;
|
|
19005
19352
|
});
|
|
19006
19353
|
}
|
|
@@ -19225,7 +19572,7 @@ var require_errors = __commonJS({
|
|
|
19225
19572
|
}
|
|
19226
19573
|
function treeifyError(error, mapper = (issue) => issue.message) {
|
|
19227
19574
|
const result = { errors: [] };
|
|
19228
|
-
const processError = (error2,
|
|
19575
|
+
const processError = (error2, path8 = []) => {
|
|
19229
19576
|
var _a, _b;
|
|
19230
19577
|
for (const issue of error2.issues) {
|
|
19231
19578
|
if (issue.code === "invalid_union" && issue.errors.length) {
|
|
@@ -19235,7 +19582,7 @@ var require_errors = __commonJS({
|
|
|
19235
19582
|
} else if (issue.code === "invalid_element") {
|
|
19236
19583
|
processError({ issues: issue.issues }, issue.path);
|
|
19237
19584
|
} else {
|
|
19238
|
-
const fullpath = [...
|
|
19585
|
+
const fullpath = [...path8, ...issue.path];
|
|
19239
19586
|
if (fullpath.length === 0) {
|
|
19240
19587
|
result.errors.push(mapper(issue));
|
|
19241
19588
|
continue;
|
|
@@ -19267,8 +19614,8 @@ var require_errors = __commonJS({
|
|
|
19267
19614
|
}
|
|
19268
19615
|
function toDotPath(_path) {
|
|
19269
19616
|
const segs = [];
|
|
19270
|
-
const
|
|
19271
|
-
for (const seg of
|
|
19617
|
+
const path8 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
19618
|
+
for (const seg of path8) {
|
|
19272
19619
|
if (typeof seg === "number")
|
|
19273
19620
|
segs.push(`[${seg}]`);
|
|
19274
19621
|
else if (typeof seg === "symbol")
|
|
@@ -33769,13 +34116,13 @@ var require_from_json_schema = __commonJS({
|
|
|
33769
34116
|
if (!ref.startsWith("#")) {
|
|
33770
34117
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
33771
34118
|
}
|
|
33772
|
-
const
|
|
33773
|
-
if (
|
|
34119
|
+
const path8 = ref.slice(1).split("/").filter(Boolean);
|
|
34120
|
+
if (path8.length === 0) {
|
|
33774
34121
|
return ctx.rootSchema;
|
|
33775
34122
|
}
|
|
33776
34123
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
33777
|
-
if (
|
|
33778
|
-
const key =
|
|
34124
|
+
if (path8[0] === defsKey) {
|
|
34125
|
+
const key = path8[1];
|
|
33779
34126
|
if (!key || !ctx.defs[key]) {
|
|
33780
34127
|
throw new Error(`Reference not found: ${ref}`);
|
|
33781
34128
|
}
|
|
@@ -34484,7 +34831,7 @@ var require_dist = __commonJS({
|
|
|
34484
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;
|
|
34485
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;
|
|
34486
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;
|
|
34487
|
-
exports.fetchOpenAIStatus = exports.fetchProviderStatus = exports.permissionModeSchema = exports.sessionEventSchema = exports.sessionMessageSchema = exports.messageUsageSchema = exports.extractToolCalls = exports.extractTokenUsage = exports.formatCost = exports.calculateCostWithPricing = 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;
|
|
34488
34835
|
var taskPersistence_1 = require_taskPersistence();
|
|
34489
34836
|
Object.defineProperty(exports, "TASK_PERSISTENCE_SCHEMA_VERSION", { enumerable: true, get: function() {
|
|
34490
34837
|
return taskPersistence_1.TASK_PERSISTENCE_SCHEMA_VERSION;
|
|
@@ -34997,6 +35344,16 @@ var require_dist = __commonJS({
|
|
|
34997
35344
|
Object.defineProperty(exports, "formatCost", { enumerable: true, get: function() {
|
|
34998
35345
|
return modelInfo_1.formatCost;
|
|
34999
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
|
+
} });
|
|
35000
35357
|
var tokenUsage_1 = require_tokenUsage();
|
|
35001
35358
|
Object.defineProperty(exports, "extractTokenUsage", { enumerable: true, get: function() {
|
|
35002
35359
|
return tokenUsage_1.extractTokenUsage;
|
|
@@ -36735,7 +37092,8 @@ var init_DashboardState = __esm({
|
|
|
36735
37092
|
model: ms.model,
|
|
36736
37093
|
calls: ms.calls,
|
|
36737
37094
|
tokens: ms.tokens,
|
|
36738
|
-
cost: ms.cost
|
|
37095
|
+
cost: ms.cost,
|
|
37096
|
+
priced: ms.priced
|
|
36739
37097
|
}));
|
|
36740
37098
|
const taskMap = /* @__PURE__ */ new Map();
|
|
36741
37099
|
for (const t of m.taskState.tasks.values()) {
|
|
@@ -37240,7 +37598,7 @@ var init_UpdateCheckService = __esm({
|
|
|
37240
37598
|
/** Run the update check (one-shot). */
|
|
37241
37599
|
async check() {
|
|
37242
37600
|
try {
|
|
37243
|
-
const current = "0.17.
|
|
37601
|
+
const current = "0.17.3";
|
|
37244
37602
|
const cached = this.readCache();
|
|
37245
37603
|
let latest;
|
|
37246
37604
|
if (cached && Date.now() - cached.checkedAt < CACHE_TTL_MS) {
|
|
@@ -38810,7 +39168,8 @@ ${hint}{/grey-fg}`;
|
|
|
38810
39168
|
lines.push("", sectionHeader("Model Usage", w2));
|
|
38811
39169
|
for (const ms of m.modelStats) {
|
|
38812
39170
|
const modelName = ms.model.length > 20 ? ms.model.substring(0, 17) + "..." : ms.model;
|
|
38813
|
-
|
|
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}`);
|
|
38814
39173
|
}
|
|
38815
39174
|
}
|
|
38816
39175
|
const quotaLabel = m.providerId === "codex" ? "Rate Limits" : "Quota";
|
|
@@ -51624,10 +51983,10 @@ var require_react_reconciler_development = __commonJS({
|
|
|
51624
51983
|
fiber = fiber.next, id--;
|
|
51625
51984
|
return fiber;
|
|
51626
51985
|
}
|
|
51627
|
-
function copyWithSetImpl(obj,
|
|
51628
|
-
if (index >=
|
|
51629
|
-
var key =
|
|
51630
|
-
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);
|
|
51631
51990
|
return updated;
|
|
51632
51991
|
}
|
|
51633
51992
|
function copyWithRename(obj, oldPath, newPath) {
|
|
@@ -51654,11 +52013,11 @@ var require_react_reconciler_development = __commonJS({
|
|
|
51654
52013
|
);
|
|
51655
52014
|
return updated;
|
|
51656
52015
|
}
|
|
51657
|
-
function copyWithDeleteImpl(obj,
|
|
51658
|
-
var key =
|
|
51659
|
-
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)
|
|
51660
52019
|
return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
|
|
51661
|
-
updated[key] = copyWithDeleteImpl(obj[key],
|
|
52020
|
+
updated[key] = copyWithDeleteImpl(obj[key], path8, index + 1);
|
|
51662
52021
|
return updated;
|
|
51663
52022
|
}
|
|
51664
52023
|
function shouldSuspendImpl() {
|
|
@@ -64935,29 +65294,29 @@ var require_react_reconciler_development = __commonJS({
|
|
|
64935
65294
|
var didWarnAboutNestedUpdates = false;
|
|
64936
65295
|
var didWarnAboutFindNodeInStrictMode = {};
|
|
64937
65296
|
var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
|
|
64938
|
-
overrideHookState = function(fiber, id,
|
|
65297
|
+
overrideHookState = function(fiber, id, path8, value) {
|
|
64939
65298
|
id = findHook(fiber, id);
|
|
64940
|
-
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));
|
|
64941
65300
|
};
|
|
64942
|
-
overrideHookStateDeletePath = function(fiber, id,
|
|
65301
|
+
overrideHookStateDeletePath = function(fiber, id, path8) {
|
|
64943
65302
|
id = findHook(fiber, id);
|
|
64944
|
-
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));
|
|
64945
65304
|
};
|
|
64946
65305
|
overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
|
|
64947
65306
|
id = findHook(fiber, id);
|
|
64948
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));
|
|
64949
65308
|
};
|
|
64950
|
-
overrideProps = function(fiber,
|
|
64951
|
-
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps,
|
|
65309
|
+
overrideProps = function(fiber, path8, value) {
|
|
65310
|
+
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path8, 0, value);
|
|
64952
65311
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
64953
|
-
|
|
64954
|
-
null !==
|
|
65312
|
+
path8 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
65313
|
+
null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2);
|
|
64955
65314
|
};
|
|
64956
|
-
overridePropsDeletePath = function(fiber,
|
|
64957
|
-
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps,
|
|
65315
|
+
overridePropsDeletePath = function(fiber, path8) {
|
|
65316
|
+
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path8, 0);
|
|
64958
65317
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
64959
|
-
|
|
64960
|
-
null !==
|
|
65318
|
+
path8 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
65319
|
+
null !== path8 && scheduleUpdateOnFiber(path8, fiber, 2);
|
|
64961
65320
|
};
|
|
64962
65321
|
overridePropsRenamePath = function(fiber, oldPath, newPath) {
|
|
64963
65322
|
fiber.pendingProps = copyWithRename(
|
|
@@ -74874,8 +75233,8 @@ var init_ErrorOverview = __esm({
|
|
|
74874
75233
|
init_dist3();
|
|
74875
75234
|
init_Box();
|
|
74876
75235
|
init_Text();
|
|
74877
|
-
cleanupPath = (
|
|
74878
|
-
return
|
|
75236
|
+
cleanupPath = (path8) => {
|
|
75237
|
+
return path8?.replace(`file://${cwd()}/`, "");
|
|
74879
75238
|
};
|
|
74880
75239
|
stackUtils = new import_stack_utils.default({
|
|
74881
75240
|
cwd: cwd(),
|
|
@@ -77857,7 +78216,7 @@ function StatusBar({
|
|
|
77857
78216
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Text, { children: parseBlessedTags(BRAND_INLINE) }),
|
|
77858
78217
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { dimColor: true, children: [
|
|
77859
78218
|
" v",
|
|
77860
|
-
"0.17.
|
|
78219
|
+
"0.17.3"
|
|
77861
78220
|
] }),
|
|
77862
78221
|
updateInfo && /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(Text, { color: "yellow", children: [
|
|
77863
78222
|
" (v",
|
|
@@ -78247,7 +78606,7 @@ function ChangelogOverlay({ entries, scrollOffset }) {
|
|
|
78247
78606
|
" ",
|
|
78248
78607
|
/* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { bold: true, color: "cyan", children: [
|
|
78249
78608
|
"Terminal Dashboard v",
|
|
78250
|
-
"0.17.
|
|
78609
|
+
"0.17.3"
|
|
78251
78610
|
] }),
|
|
78252
78611
|
latestDate ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(Text, { color: "gray", children: [
|
|
78253
78612
|
" \u2014 ",
|
|
@@ -78569,7 +78928,7 @@ var init_mouse = __esm({
|
|
|
78569
78928
|
var CHANGELOG_default;
|
|
78570
78929
|
var init_CHANGELOG = __esm({
|
|
78571
78930
|
"CHANGELOG.md"() {
|
|
78572
|
-
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.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';
|
|
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## [0.17.3] - 2026-04-17\n\n### Changed\n\n- **Version sync with the VS Code extension**: Republished to keep CLI, extension, and shared-library versions aligned after a cosmetic changelog fix in 0.17.3. No CLI code changes \u2014 functionally identical to 0.17.2\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';
|
|
78573
78932
|
}
|
|
78574
78933
|
});
|
|
78575
78934
|
|
|
@@ -80202,8 +80561,8 @@ async function searchAction(_opts, cmd) {
|
|
|
80202
80561
|
const projectPath = globalOpts.project || void 0;
|
|
80203
80562
|
let projectSlug;
|
|
80204
80563
|
if (projectPath) {
|
|
80205
|
-
const
|
|
80206
|
-
const resolved =
|
|
80564
|
+
const path8 = await import("path");
|
|
80565
|
+
const resolved = path8.resolve(projectPath);
|
|
80207
80566
|
const { encodeWorkspacePath } = await Promise.resolve().then(() => __toESM(require_dist(), 1));
|
|
80208
80567
|
projectSlug = encodeWorkspacePath(resolved);
|
|
80209
80568
|
}
|
|
@@ -80564,10 +80923,22 @@ function printStatsSummary(history) {
|
|
|
80564
80923
|
process.stdout.write(source_default.bold("Model Usage\n"));
|
|
80565
80924
|
process.stdout.write(source_default.dim("\u2500".repeat(50) + "\n"));
|
|
80566
80925
|
const sorted = [...at.modelUsage].sort((a, b) => b.calls - a.calls);
|
|
80926
|
+
const unpricedModels = [];
|
|
80567
80927
|
for (const m of sorted) {
|
|
80568
|
-
|
|
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
|
+
}
|
|
80569
80935
|
process.stdout.write(` ${source_default.cyan(m.model.padEnd(30))} ${formatNumber(m.calls).padStart(8)} calls${costStr}
|
|
80570
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
|
+
`));
|
|
80571
80942
|
}
|
|
80572
80943
|
process.stdout.write("\n");
|
|
80573
80944
|
}
|
|
@@ -81282,6 +81653,8 @@ var init_handoff = __esm({
|
|
|
81282
81653
|
});
|
|
81283
81654
|
|
|
81284
81655
|
// src/cli.ts
|
|
81656
|
+
import * as os5 from "node:os";
|
|
81657
|
+
import * as path7 from "node:path";
|
|
81285
81658
|
function resolveProviderId(opts, defaultProvider = "auto") {
|
|
81286
81659
|
if (opts.provider && opts.provider !== "auto") {
|
|
81287
81660
|
return opts.provider;
|
|
@@ -81309,8 +81682,12 @@ var init_cli = __esm({
|
|
|
81309
81682
|
init_esm();
|
|
81310
81683
|
import_sidekick_shared32 = __toESM(require_dist(), 1);
|
|
81311
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
|
+
});
|
|
81312
81689
|
program2 = new Command();
|
|
81313
|
-
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.3").option("--json", "Output as JSON").option("--project <path>", "Override project path (default: cwd)").option("--provider <id>", "Provider: claude-code, opencode, codex, auto (default: auto)");
|
|
81314
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) => {
|
|
81315
81692
|
const { dashboardAction: dashboardAction2 } = await init_dashboard().then(() => dashboard_exports);
|
|
81316
81693
|
return dashboardAction2(_opts, cmd);
|