modelstat 0.0.43 → 0.0.45
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/cli.mjs +203 -125
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -3
package/dist/cli.mjs
CHANGED
|
@@ -4550,6 +4550,8 @@ function sourceEventId(deviceId, sourceOrFilePath, byteOffsetMaybe) {
|
|
|
4550
4550
|
key = `fs::${sourceOrFilePath}::${byteOffset}`;
|
|
4551
4551
|
} else if ("file" in sourceOrFilePath) {
|
|
4552
4552
|
key = `fs::${sourceOrFilePath.file}::${sourceOrFilePath.byteOffset}`;
|
|
4553
|
+
} else if ("lineUuid" in sourceOrFilePath) {
|
|
4554
|
+
key = `uuid::${sourceOrFilePath.lineUuid}`;
|
|
4553
4555
|
} else {
|
|
4554
4556
|
key = `web::${sourceOrFilePath.host}::${sourceOrFilePath.conversationId}::${sourceOrFilePath.messageId}`;
|
|
4555
4557
|
}
|
|
@@ -4682,9 +4684,20 @@ var init_src = __esm({
|
|
|
4682
4684
|
|
|
4683
4685
|
// ../../packages/parsers/src/claude-code/index.ts
|
|
4684
4686
|
import { createHash } from "crypto";
|
|
4685
|
-
import { createReadStream } from "fs";
|
|
4687
|
+
import { createReadStream, existsSync as existsSync2, readdirSync } from "fs";
|
|
4686
4688
|
import { stat } from "fs/promises";
|
|
4689
|
+
import { dirname as dirname2, join } from "path";
|
|
4687
4690
|
import { createInterface } from "readline";
|
|
4691
|
+
function countToolCalls(content) {
|
|
4692
|
+
const counts = {};
|
|
4693
|
+
if (!Array.isArray(content)) return counts;
|
|
4694
|
+
for (const block of content) {
|
|
4695
|
+
if (block && block.type === "tool_use" && typeof block.name === "string" && block.name) {
|
|
4696
|
+
counts[block.name] = (counts[block.name] ?? 0) + 1;
|
|
4697
|
+
}
|
|
4698
|
+
}
|
|
4699
|
+
return counts;
|
|
4700
|
+
}
|
|
4688
4701
|
function extractExcerpt(content) {
|
|
4689
4702
|
if (!content) return void 0;
|
|
4690
4703
|
let text = "";
|
|
@@ -4722,6 +4735,37 @@ async function parseClaudeCodeJsonl(ctx) {
|
|
|
4722
4735
|
let cwd = null;
|
|
4723
4736
|
let gitBranch = null;
|
|
4724
4737
|
let lastModel = null;
|
|
4738
|
+
const filenameSessionId = deriveSessionIdFromFilename(ctx.sourceFile);
|
|
4739
|
+
const ancestorExistsCache = /* @__PURE__ */ new Map();
|
|
4740
|
+
function ancestorFileExists(sid) {
|
|
4741
|
+
const cached2 = ancestorExistsCache.get(sid);
|
|
4742
|
+
if (cached2 !== void 0) return cached2;
|
|
4743
|
+
let found = false;
|
|
4744
|
+
const dir = dirname2(ctx.sourceFile);
|
|
4745
|
+
try {
|
|
4746
|
+
if (existsSync2(join(dir, `${sid}.jsonl`))) {
|
|
4747
|
+
found = true;
|
|
4748
|
+
} else {
|
|
4749
|
+
const root = dirname2(dir);
|
|
4750
|
+
for (const entry of readdirSync(root, { withFileTypes: true })) {
|
|
4751
|
+
if (!entry.isDirectory()) continue;
|
|
4752
|
+
if (existsSync2(join(root, entry.name, `${sid}.jsonl`))) {
|
|
4753
|
+
found = true;
|
|
4754
|
+
break;
|
|
4755
|
+
}
|
|
4756
|
+
}
|
|
4757
|
+
}
|
|
4758
|
+
} catch {
|
|
4759
|
+
}
|
|
4760
|
+
ancestorExistsCache.set(sid, found);
|
|
4761
|
+
return found;
|
|
4762
|
+
}
|
|
4763
|
+
function dedupeIdFor(lineUuid, byteOffset) {
|
|
4764
|
+
const isResumeCopy = filenameSessionId !== null && sessionId !== filenameSessionId;
|
|
4765
|
+
if (!isResumeCopy) return sourceEventId(ctx.deviceId, ctx.sourceFile, byteOffset);
|
|
4766
|
+
if (ancestorFileExists(sessionId)) return null;
|
|
4767
|
+
return sourceEventId(ctx.deviceId, { lineUuid });
|
|
4768
|
+
}
|
|
4725
4769
|
for await (const line of rl) {
|
|
4726
4770
|
const byteLen = Buffer.byteLength(line, "utf8") + 1;
|
|
4727
4771
|
const offsetAtLineStart = startOffset + bytePos;
|
|
@@ -4758,10 +4802,15 @@ async function parseClaudeCodeJsonl(ctx) {
|
|
|
4758
4802
|
skipped += 1;
|
|
4759
4803
|
continue;
|
|
4760
4804
|
}
|
|
4805
|
+
const eventId = dedupeIdFor(a.uuid, offsetAtLineStart);
|
|
4806
|
+
if (eventId === null) {
|
|
4807
|
+
skipped += 1;
|
|
4808
|
+
continue;
|
|
4809
|
+
}
|
|
4761
4810
|
const slug = guessRepoSlugFromPath(cwd);
|
|
4762
4811
|
const excerpt = extractExcerpt(a.message?.content);
|
|
4763
4812
|
events.push({
|
|
4764
|
-
source_event_id:
|
|
4813
|
+
source_event_id: eventId,
|
|
4765
4814
|
ts: a.timestamp,
|
|
4766
4815
|
kind: "assistant_message",
|
|
4767
4816
|
tool: "claude_code",
|
|
@@ -4786,7 +4835,7 @@ async function parseClaudeCodeJsonl(ctx) {
|
|
|
4786
4835
|
reasoning: 0
|
|
4787
4836
|
},
|
|
4788
4837
|
duration_ms: null,
|
|
4789
|
-
tool_calls:
|
|
4838
|
+
tool_calls: countToolCalls(a.message?.content),
|
|
4790
4839
|
files_touched: [],
|
|
4791
4840
|
...excerpt ? { content_excerpt: excerpt } : {},
|
|
4792
4841
|
source_file: ctx.sourceFile,
|
|
@@ -4803,9 +4852,14 @@ async function parseClaudeCodeJsonl(ctx) {
|
|
|
4803
4852
|
skipped += 1;
|
|
4804
4853
|
continue;
|
|
4805
4854
|
}
|
|
4855
|
+
const eventId = dedupeIdFor(u.uuid, offsetAtLineStart);
|
|
4856
|
+
if (eventId === null) {
|
|
4857
|
+
skipped += 1;
|
|
4858
|
+
continue;
|
|
4859
|
+
}
|
|
4806
4860
|
const excerpt = extractExcerpt(u.message?.content);
|
|
4807
4861
|
events.push({
|
|
4808
|
-
source_event_id:
|
|
4862
|
+
source_event_id: eventId,
|
|
4809
4863
|
ts: u.timestamp,
|
|
4810
4864
|
kind: "user_message",
|
|
4811
4865
|
tool: "claude_code",
|
|
@@ -4835,6 +4889,10 @@ async function parseClaudeCodeJsonl(ctx) {
|
|
|
4835
4889
|
sourceFile: ctx.sourceFile
|
|
4836
4890
|
};
|
|
4837
4891
|
}
|
|
4892
|
+
function deriveSessionIdFromFilename(path5) {
|
|
4893
|
+
const m = /([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})\.jsonl$/.exec(path5);
|
|
4894
|
+
return m ? m[1] ?? null : null;
|
|
4895
|
+
}
|
|
4838
4896
|
async function quickChecksum(path5) {
|
|
4839
4897
|
const st = await stat(path5);
|
|
4840
4898
|
const stream = createReadStream(path5, {
|
|
@@ -7155,9 +7213,9 @@ var init_cursor = __esm({
|
|
|
7155
7213
|
|
|
7156
7214
|
// ../../packages/parsers/src/discovery/index.ts
|
|
7157
7215
|
import { execFile as execFile2, execSync } from "child_process";
|
|
7158
|
-
import { existsSync as
|
|
7216
|
+
import { existsSync as existsSync3, statSync } from "fs";
|
|
7159
7217
|
import { homedir, platform } from "os";
|
|
7160
|
-
import { join, resolve as resolve2 } from "path";
|
|
7218
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
7161
7219
|
import { promisify as promisify2 } from "util";
|
|
7162
7220
|
async function discover(options = {}) {
|
|
7163
7221
|
const os2 = platform() === "darwin" ? "macos" : "linux";
|
|
@@ -7173,7 +7231,7 @@ async function discover(options = {}) {
|
|
|
7173
7231
|
}
|
|
7174
7232
|
for (const extra of options.extraDataDirs?.[spec.tool] ?? []) candidates.add(expandPath(extra));
|
|
7175
7233
|
for (const p of candidates) {
|
|
7176
|
-
if (
|
|
7234
|
+
if (existsSync3(p) && statSync(p).isDirectory()) {
|
|
7177
7235
|
installations.push({
|
|
7178
7236
|
tool: spec.tool,
|
|
7179
7237
|
install_method: "manual",
|
|
@@ -7190,8 +7248,8 @@ async function discover(options = {}) {
|
|
|
7190
7248
|
for (const spec of SOURCES) {
|
|
7191
7249
|
for (const bin of spec.binaries ?? []) {
|
|
7192
7250
|
for (const dir of binDirs) {
|
|
7193
|
-
const p =
|
|
7194
|
-
if (
|
|
7251
|
+
const p = join2(dir, bin);
|
|
7252
|
+
if (existsSync3(p)) {
|
|
7195
7253
|
const version = await safeVersionProbe(p);
|
|
7196
7254
|
installations.push({
|
|
7197
7255
|
tool: spec.tool,
|
|
@@ -7341,7 +7399,7 @@ async function probeIdentities(os2) {
|
|
|
7341
7399
|
`${homedir()}/.codex/auth.json`,
|
|
7342
7400
|
`${homedir()}/.config/codex/auth.json`
|
|
7343
7401
|
]) {
|
|
7344
|
-
if (!
|
|
7402
|
+
if (!existsSync3(candidate)) continue;
|
|
7345
7403
|
try {
|
|
7346
7404
|
const data = await fs4.promises.readFile(candidate, "utf8");
|
|
7347
7405
|
const obj = JSON.parse(data);
|
|
@@ -7389,7 +7447,7 @@ async function probeIdentities(os2) {
|
|
|
7389
7447
|
`${homedir()}/.gemini/oauth_creds.json`,
|
|
7390
7448
|
`${homedir()}/.config/gemini/oauth_creds.json`
|
|
7391
7449
|
]) {
|
|
7392
|
-
if (!
|
|
7450
|
+
if (!existsSync3(candidate)) continue;
|
|
7393
7451
|
try {
|
|
7394
7452
|
const data = await fs4.promises.readFile(candidate, "utf8");
|
|
7395
7453
|
const obj = JSON.parse(data);
|
|
@@ -7411,7 +7469,7 @@ async function probeIdentities(os2) {
|
|
|
7411
7469
|
`${homedir()}/Library/Application Support/Cursor/User/globalStorage/storage.json`,
|
|
7412
7470
|
`${homedir()}/.config/Cursor/User/globalStorage/storage.json`
|
|
7413
7471
|
]) {
|
|
7414
|
-
if (!
|
|
7472
|
+
if (!existsSync3(candidate)) continue;
|
|
7415
7473
|
try {
|
|
7416
7474
|
const data = await fs4.promises.readFile(candidate, "utf8");
|
|
7417
7475
|
const obj = JSON.parse(data);
|
|
@@ -7571,10 +7629,10 @@ import {
|
|
|
7571
7629
|
readFileSync as readFileSync2,
|
|
7572
7630
|
renameSync,
|
|
7573
7631
|
writeFileSync,
|
|
7574
|
-
existsSync as
|
|
7632
|
+
existsSync as existsSync4
|
|
7575
7633
|
} from "fs";
|
|
7576
7634
|
import { homedir as homedir2, hostname as osHostname } from "os";
|
|
7577
|
-
import { join as
|
|
7635
|
+
import { join as join3 } from "path";
|
|
7578
7636
|
function ensureRoot() {
|
|
7579
7637
|
mkdirSync(ROOT, { recursive: true, mode: 448 });
|
|
7580
7638
|
}
|
|
@@ -7592,7 +7650,7 @@ function identityPath() {
|
|
|
7592
7650
|
return IDENTITY_FILE;
|
|
7593
7651
|
}
|
|
7594
7652
|
function hasIdentityFile() {
|
|
7595
|
-
return
|
|
7653
|
+
return existsSync4(IDENTITY_FILE);
|
|
7596
7654
|
}
|
|
7597
7655
|
function parseFile() {
|
|
7598
7656
|
try {
|
|
@@ -7643,7 +7701,7 @@ function saveIdentity(meta) {
|
|
|
7643
7701
|
writeAtomic(meta);
|
|
7644
7702
|
}
|
|
7645
7703
|
function backupIdentity() {
|
|
7646
|
-
if (!
|
|
7704
|
+
if (!existsSync4(IDENTITY_FILE)) return null;
|
|
7647
7705
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
7648
7706
|
const dest = `${IDENTITY_FILE}.bak-${stamp}`;
|
|
7649
7707
|
renameSync(IDENTITY_FILE, dest);
|
|
@@ -7660,8 +7718,8 @@ var ROOT, IDENTITY_FILE;
|
|
|
7660
7718
|
var init_identity = __esm({
|
|
7661
7719
|
"src/identity.ts"() {
|
|
7662
7720
|
"use strict";
|
|
7663
|
-
ROOT =
|
|
7664
|
-
IDENTITY_FILE =
|
|
7721
|
+
ROOT = join3(homedir2(), ".modelstat");
|
|
7722
|
+
IDENTITY_FILE = join3(ROOT, "identity.json");
|
|
7665
7723
|
}
|
|
7666
7724
|
});
|
|
7667
7725
|
|
|
@@ -21162,7 +21220,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
21162
21220
|
"../../node_modules/.pnpm/undici@7.25.0/node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
|
|
21163
21221
|
"use strict";
|
|
21164
21222
|
var { writeFile, readFile, mkdir: mkdir2 } = __require("fs/promises");
|
|
21165
|
-
var { dirname:
|
|
21223
|
+
var { dirname: dirname9, resolve: resolve6 } = __require("path");
|
|
21166
21224
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
|
|
21167
21225
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
21168
21226
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -21393,7 +21451,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
21393
21451
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
21394
21452
|
}
|
|
21395
21453
|
const resolvedPath = resolve6(path5);
|
|
21396
|
-
await mkdir2(
|
|
21454
|
+
await mkdir2(dirname9(resolvedPath), { recursive: true });
|
|
21397
21455
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
21398
21456
|
hash,
|
|
21399
21457
|
snapshot
|
|
@@ -43947,9 +44005,9 @@ var init_source = __esm({
|
|
|
43947
44005
|
});
|
|
43948
44006
|
|
|
43949
44007
|
// src/config.ts
|
|
43950
|
-
import { existsSync as
|
|
44008
|
+
import { existsSync as existsSync5 } from "fs";
|
|
43951
44009
|
import { hostname } from "os";
|
|
43952
|
-
import { dirname as
|
|
44010
|
+
import { dirname as dirname3, resolve as resolve3 } from "path";
|
|
43953
44011
|
import { fileURLToPath } from "url";
|
|
43954
44012
|
function migrateFromConf() {
|
|
43955
44013
|
const bearer = store.get("bearerToken");
|
|
@@ -43989,10 +44047,10 @@ var init_config2 = __esm({
|
|
|
43989
44047
|
import_dotenv = __toESM(require_main(), 1);
|
|
43990
44048
|
init_source();
|
|
43991
44049
|
init_identity();
|
|
43992
|
-
here =
|
|
44050
|
+
here = dirname3(fileURLToPath(import.meta.url));
|
|
43993
44051
|
for (let d = here, i = 0; i < 8; i++, d = resolve3(d, "..")) {
|
|
43994
44052
|
const candidate = resolve3(d, ".env");
|
|
43995
|
-
if (
|
|
44053
|
+
if (existsSync5(candidate)) {
|
|
43996
44054
|
(0, import_dotenv.config)({ path: candidate });
|
|
43997
44055
|
break;
|
|
43998
44056
|
}
|
|
@@ -44801,7 +44859,7 @@ var init_src3 = __esm({
|
|
|
44801
44859
|
|
|
44802
44860
|
// ../../packages/companion-core/src/node/file-queue-store.ts
|
|
44803
44861
|
import { promises as fs3 } from "fs";
|
|
44804
|
-
import { dirname as
|
|
44862
|
+
import { dirname as dirname4 } from "path";
|
|
44805
44863
|
var SENT_TTL_MS, FileQueueStore;
|
|
44806
44864
|
var init_file_queue_store = __esm({
|
|
44807
44865
|
"../../packages/companion-core/src/node/file-queue-store.ts"() {
|
|
@@ -44857,7 +44915,7 @@ var init_file_queue_store = __esm({
|
|
|
44857
44915
|
items: Object.fromEntries(this.items.entries())
|
|
44858
44916
|
};
|
|
44859
44917
|
const tmp = `${this.filePath}.tmp`;
|
|
44860
|
-
await fs3.mkdir(
|
|
44918
|
+
await fs3.mkdir(dirname4(this.filePath), { recursive: true });
|
|
44861
44919
|
await fs3.writeFile(tmp, JSON.stringify(snap), "utf8");
|
|
44862
44920
|
try {
|
|
44863
44921
|
await fs3.rename(this.filePath, `${this.filePath}.bak`);
|
|
@@ -45034,14 +45092,14 @@ var init_ollama = __esm({
|
|
|
45034
45092
|
|
|
45035
45093
|
// ../../packages/companion-core/src/node/llama.ts
|
|
45036
45094
|
import { mkdir } from "fs/promises";
|
|
45037
|
-
import { existsSync as
|
|
45095
|
+
import { existsSync as existsSync6 } from "fs";
|
|
45038
45096
|
import { homedir as homedir4 } from "os";
|
|
45039
|
-
import { dirname as
|
|
45097
|
+
import { dirname as dirname5, join as join4 } from "path";
|
|
45040
45098
|
function defaultLlamaConfig() {
|
|
45041
45099
|
const env2 = globalThis.process?.env ?? {};
|
|
45042
|
-
const modelsDir = env2.MODELSTAT_MODELS_DIR ??
|
|
45100
|
+
const modelsDir = env2.MODELSTAT_MODELS_DIR ?? join4(homedir4(), ".modelstat", "models");
|
|
45043
45101
|
const modelUrl = env2.MODELSTAT_LLAMA_MODEL_URL ?? DEFAULT_LLAMA_MODEL_URL;
|
|
45044
|
-
const modelPath = env2.MODELSTAT_LLAMA_MODEL_PATH ??
|
|
45102
|
+
const modelPath = env2.MODELSTAT_LLAMA_MODEL_PATH ?? join4(modelsDir, basenameFromUrl(modelUrl));
|
|
45045
45103
|
return {
|
|
45046
45104
|
modelPath,
|
|
45047
45105
|
modelUrl,
|
|
@@ -45062,8 +45120,8 @@ function basenameFromUrl(url) {
|
|
|
45062
45120
|
return parts[parts.length - 1] || "model.gguf";
|
|
45063
45121
|
}
|
|
45064
45122
|
async function ensureLlamaModel(cfg = defaultLlamaConfig()) {
|
|
45065
|
-
if (
|
|
45066
|
-
await mkdir(
|
|
45123
|
+
if (existsSync6(cfg.modelPath)) return cfg.modelPath;
|
|
45124
|
+
await mkdir(dirname5(cfg.modelPath), { recursive: true });
|
|
45067
45125
|
const res = await fetch(cfg.modelUrl);
|
|
45068
45126
|
if (!res.ok || !res.body) {
|
|
45069
45127
|
throw new Error(
|
|
@@ -45534,7 +45592,7 @@ var init_pipeline2 = __esm({
|
|
|
45534
45592
|
// src/scan.ts
|
|
45535
45593
|
import { readdir, stat as stat2 } from "fs/promises";
|
|
45536
45594
|
import { homedir as homedir5 } from "os";
|
|
45537
|
-
import { join as
|
|
45595
|
+
import { join as join5 } from "path";
|
|
45538
45596
|
function withNonNullTokens(e) {
|
|
45539
45597
|
return e.tokens ? e : { ...e, tokens: { ...ZERO_TOKENS } };
|
|
45540
45598
|
}
|
|
@@ -45543,16 +45601,16 @@ async function scanAll(cb = {}) {
|
|
|
45543
45601
|
if (!deviceId) throw new Error("agent not enrolled \u2014 run `register` first");
|
|
45544
45602
|
const jobs = [];
|
|
45545
45603
|
try {
|
|
45546
|
-
const base =
|
|
45604
|
+
const base = join5(homedir5(), ".claude/projects");
|
|
45547
45605
|
const projects = await readdir(base).catch(() => []);
|
|
45548
45606
|
for (const p of projects) {
|
|
45549
|
-
const dir =
|
|
45607
|
+
const dir = join5(base, p);
|
|
45550
45608
|
const ds = await stat2(dir).catch(() => null);
|
|
45551
45609
|
if (!ds?.isDirectory()) continue;
|
|
45552
45610
|
const files = await readdir(dir);
|
|
45553
45611
|
for (const f of files) {
|
|
45554
45612
|
if (!f.endsWith(".jsonl")) continue;
|
|
45555
|
-
const full =
|
|
45613
|
+
const full = join5(dir, f);
|
|
45556
45614
|
jobs.push({
|
|
45557
45615
|
path: full,
|
|
45558
45616
|
parse: async () => {
|
|
@@ -45566,17 +45624,17 @@ async function scanAll(cb = {}) {
|
|
|
45566
45624
|
console.warn("claude scan skipped:", e.message);
|
|
45567
45625
|
}
|
|
45568
45626
|
try {
|
|
45569
|
-
const base =
|
|
45627
|
+
const base = join5(homedir5(), ".codex/sessions");
|
|
45570
45628
|
const years = await readdir(base).catch(() => []);
|
|
45571
45629
|
for (const y of years) {
|
|
45572
|
-
const months = await readdir(
|
|
45630
|
+
const months = await readdir(join5(base, y)).catch(() => []);
|
|
45573
45631
|
for (const m of months) {
|
|
45574
|
-
const days = await readdir(
|
|
45632
|
+
const days = await readdir(join5(base, y, m)).catch(() => []);
|
|
45575
45633
|
for (const d of days) {
|
|
45576
|
-
const files = await readdir(
|
|
45634
|
+
const files = await readdir(join5(base, y, m, d)).catch(() => []);
|
|
45577
45635
|
for (const f of files) {
|
|
45578
45636
|
if (!f.startsWith("rollout-") || !f.endsWith(".jsonl")) continue;
|
|
45579
|
-
const full =
|
|
45637
|
+
const full = join5(base, y, m, d, f);
|
|
45580
45638
|
jobs.push({
|
|
45581
45639
|
path: full,
|
|
45582
45640
|
parse: async () => {
|
|
@@ -45671,7 +45729,7 @@ var init_scan = __esm({
|
|
|
45671
45729
|
init_pipeline2();
|
|
45672
45730
|
init_config2();
|
|
45673
45731
|
init_api();
|
|
45674
|
-
AGENT_VERSION = true ? "agent-0.0.
|
|
45732
|
+
AGENT_VERSION = true ? "agent-0.0.45" : "agent-dev";
|
|
45675
45733
|
BATCH_MAX_EVENTS = 2e3;
|
|
45676
45734
|
ZERO_TOKENS = {
|
|
45677
45735
|
input: 0,
|
|
@@ -45686,7 +45744,7 @@ var init_scan = __esm({
|
|
|
45686
45744
|
// src/lock.ts
|
|
45687
45745
|
import {
|
|
45688
45746
|
closeSync,
|
|
45689
|
-
existsSync as
|
|
45747
|
+
existsSync as existsSync8,
|
|
45690
45748
|
mkdirSync as mkdirSync3,
|
|
45691
45749
|
openSync,
|
|
45692
45750
|
readFileSync as readFileSync4,
|
|
@@ -45696,7 +45754,7 @@ import {
|
|
|
45696
45754
|
writeSync
|
|
45697
45755
|
} from "fs";
|
|
45698
45756
|
import { homedir as homedir7 } from "os";
|
|
45699
|
-
import { join as
|
|
45757
|
+
import { join as join7 } from "path";
|
|
45700
45758
|
function isProcessAlive(pid) {
|
|
45701
45759
|
if (!pid || pid <= 0) return false;
|
|
45702
45760
|
try {
|
|
@@ -45797,8 +45855,8 @@ var LOCK_DIR, LOCK_FILE;
|
|
|
45797
45855
|
var init_lock = __esm({
|
|
45798
45856
|
"src/lock.ts"() {
|
|
45799
45857
|
"use strict";
|
|
45800
|
-
LOCK_DIR =
|
|
45801
|
-
LOCK_FILE =
|
|
45858
|
+
LOCK_DIR = join7(homedir7(), ".modelstat");
|
|
45859
|
+
LOCK_FILE = join7(LOCK_DIR, "daemon.lock");
|
|
45802
45860
|
}
|
|
45803
45861
|
});
|
|
45804
45862
|
|
|
@@ -46599,9 +46657,9 @@ var init_handler = __esm({
|
|
|
46599
46657
|
if (this.fsw.closed) {
|
|
46600
46658
|
return;
|
|
46601
46659
|
}
|
|
46602
|
-
const
|
|
46660
|
+
const dirname9 = sysPath.dirname(file);
|
|
46603
46661
|
const basename4 = sysPath.basename(file);
|
|
46604
|
-
const parent = this.fsw._getWatchedDir(
|
|
46662
|
+
const parent = this.fsw._getWatchedDir(dirname9);
|
|
46605
46663
|
let prevStats = stats;
|
|
46606
46664
|
if (parent.has(basename4))
|
|
46607
46665
|
return;
|
|
@@ -46628,7 +46686,7 @@ var init_handler = __esm({
|
|
|
46628
46686
|
prevStats = newStats2;
|
|
46629
46687
|
}
|
|
46630
46688
|
} catch (error) {
|
|
46631
|
-
this.fsw._remove(
|
|
46689
|
+
this.fsw._remove(dirname9, basename4);
|
|
46632
46690
|
}
|
|
46633
46691
|
} else if (parent.has(basename4)) {
|
|
46634
46692
|
const at = newStats.atimeMs;
|
|
@@ -47594,7 +47652,7 @@ __export(daemon_exports, {
|
|
|
47594
47652
|
setQueue: () => setQueue,
|
|
47595
47653
|
setStat: () => setStat
|
|
47596
47654
|
});
|
|
47597
|
-
import { existsSync as
|
|
47655
|
+
import { existsSync as existsSync9, statSync as statSync2 } from "fs";
|
|
47598
47656
|
function setPhase(phase, message) {
|
|
47599
47657
|
status.phase = phase;
|
|
47600
47658
|
status.message = message ?? null;
|
|
@@ -47674,15 +47732,15 @@ async function sendHeartbeat() {
|
|
|
47674
47732
|
}
|
|
47675
47733
|
async function writeLocalStatus(snapshot) {
|
|
47676
47734
|
const { homedir: homedir9 } = await import("os");
|
|
47677
|
-
const { join:
|
|
47735
|
+
const { join: join11 } = await import("path");
|
|
47678
47736
|
const { writeFile, mkdir: mkdir2, rename } = await import("fs/promises");
|
|
47679
47737
|
if (!lastStatusPath) {
|
|
47680
|
-
const dir =
|
|
47738
|
+
const dir = join11(homedir9(), ".modelstat");
|
|
47681
47739
|
try {
|
|
47682
47740
|
await mkdir2(dir, { recursive: true });
|
|
47683
47741
|
} catch {
|
|
47684
47742
|
}
|
|
47685
|
-
lastStatusPath =
|
|
47743
|
+
lastStatusPath = join11(dir, "last-status.json");
|
|
47686
47744
|
}
|
|
47687
47745
|
const tmp = `${lastStatusPath}.tmp`;
|
|
47688
47746
|
try {
|
|
@@ -47805,20 +47863,20 @@ async function runDaemon(opts = {}) {
|
|
|
47805
47863
|
await requestScan("startup");
|
|
47806
47864
|
const chokidar = (await Promise.resolve().then(() => (init_esm2(), esm_exports))).default;
|
|
47807
47865
|
const { homedir: homedir9, platform: platform5 } = await import("os");
|
|
47808
|
-
const { join:
|
|
47866
|
+
const { join: join11 } = await import("path");
|
|
47809
47867
|
const home2 = homedir9();
|
|
47810
47868
|
const dirs = [
|
|
47811
|
-
|
|
47812
|
-
|
|
47813
|
-
|
|
47814
|
-
|
|
47869
|
+
join11(home2, ".claude/projects"),
|
|
47870
|
+
join11(home2, ".codex/sessions"),
|
|
47871
|
+
join11(home2, ".cursor/ai-tracking"),
|
|
47872
|
+
join11(home2, ".gemini"),
|
|
47815
47873
|
...platform5() === "darwin" ? [
|
|
47816
|
-
|
|
47817
|
-
|
|
47874
|
+
join11(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
47875
|
+
join11(home2, "Library/Application Support/Claude")
|
|
47818
47876
|
] : [
|
|
47819
|
-
|
|
47877
|
+
join11(home2, ".config/Cursor/User/workspaceStorage")
|
|
47820
47878
|
]
|
|
47821
|
-
].filter((p) =>
|
|
47879
|
+
].filter((p) => existsSync9(p) && statSync2(p).isDirectory());
|
|
47822
47880
|
setPhase("watching", `Watching ${dirs.length} directories`);
|
|
47823
47881
|
const watcher = chokidar.watch(dirs, {
|
|
47824
47882
|
persistent: true,
|
|
@@ -47871,7 +47929,7 @@ var init_daemon = __esm({
|
|
|
47871
47929
|
init_lock();
|
|
47872
47930
|
init_scan();
|
|
47873
47931
|
init_single_flight();
|
|
47874
|
-
AGENT_VERSION2 = true ? "agent-0.0.
|
|
47932
|
+
AGENT_VERSION2 = true ? "agent-0.0.45" : "agent-dev";
|
|
47875
47933
|
HEARTBEAT_INTERVAL_MS = 1e4;
|
|
47876
47934
|
SCAN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
47877
47935
|
DISCOVERY_INTERVAL_MS = 6e4;
|
|
@@ -47897,37 +47955,37 @@ var watch_exports = {};
|
|
|
47897
47955
|
__export(watch_exports, {
|
|
47898
47956
|
watchForever: () => watchForever
|
|
47899
47957
|
});
|
|
47900
|
-
import { existsSync as
|
|
47958
|
+
import { existsSync as existsSync10 } from "fs";
|
|
47901
47959
|
import { homedir as homedir8, platform as platform3 } from "os";
|
|
47902
|
-
import { join as
|
|
47960
|
+
import { join as join10 } from "path";
|
|
47903
47961
|
function resolveWatchDirs() {
|
|
47904
47962
|
const home2 = homedir8();
|
|
47905
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ??
|
|
47906
|
-
const xdgData = process.env.XDG_DATA_HOME ??
|
|
47963
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME ?? join10(home2, ".config");
|
|
47964
|
+
const xdgData = process.env.XDG_DATA_HOME ?? join10(home2, ".local/share");
|
|
47907
47965
|
const candidates = [
|
|
47908
47966
|
// universal (default HOME-rooted CLI data dirs)
|
|
47909
|
-
|
|
47910
|
-
|
|
47911
|
-
|
|
47912
|
-
|
|
47913
|
-
|
|
47967
|
+
join10(home2, ".claude/projects"),
|
|
47968
|
+
join10(home2, ".codex/sessions"),
|
|
47969
|
+
join10(home2, ".cursor/ai-tracking"),
|
|
47970
|
+
join10(home2, ".gemini"),
|
|
47971
|
+
join10(home2, ".aider"),
|
|
47914
47972
|
// XDG / Linux
|
|
47915
|
-
|
|
47916
|
-
|
|
47917
|
-
|
|
47918
|
-
|
|
47919
|
-
|
|
47920
|
-
|
|
47973
|
+
join10(xdgConfig, "claude/projects"),
|
|
47974
|
+
join10(xdgConfig, "codex/sessions"),
|
|
47975
|
+
join10(xdgConfig, "Cursor/User/workspaceStorage"),
|
|
47976
|
+
join10(xdgConfig, "Code/User/workspaceStorage"),
|
|
47977
|
+
join10(xdgConfig, "Code - Insiders/User/workspaceStorage"),
|
|
47978
|
+
join10(xdgData, "claude/projects"),
|
|
47921
47979
|
// macOS
|
|
47922
47980
|
...platform3() === "darwin" ? [
|
|
47923
|
-
|
|
47924
|
-
|
|
47925
|
-
|
|
47926
|
-
|
|
47927
|
-
|
|
47981
|
+
join10(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
47982
|
+
join10(home2, "Library/Application Support/Claude"),
|
|
47983
|
+
join10(home2, "Library/Application Support/Code/User/workspaceStorage"),
|
|
47984
|
+
join10(home2, "Library/Application Support/Windsurf/User/workspaceStorage"),
|
|
47985
|
+
join10(home2, "Library/Application Support/Zed")
|
|
47928
47986
|
] : []
|
|
47929
47987
|
];
|
|
47930
|
-
return Array.from(new Set(candidates)).filter((p) =>
|
|
47988
|
+
return Array.from(new Set(candidates)).filter((p) => existsSync10(p));
|
|
47931
47989
|
}
|
|
47932
47990
|
async function safeScan(reason) {
|
|
47933
47991
|
if (scanning) {
|
|
@@ -48002,7 +48060,7 @@ import { createInterface as createInterface3 } from "readline";
|
|
|
48002
48060
|
import { spawnSync } from "child_process";
|
|
48003
48061
|
import {
|
|
48004
48062
|
copyFileSync,
|
|
48005
|
-
existsSync as
|
|
48063
|
+
existsSync as existsSync7,
|
|
48006
48064
|
mkdirSync as mkdirSync2,
|
|
48007
48065
|
readFileSync as readFileSync3,
|
|
48008
48066
|
realpathSync,
|
|
@@ -48011,7 +48069,7 @@ import {
|
|
|
48011
48069
|
} from "fs";
|
|
48012
48070
|
import { createRequire } from "module";
|
|
48013
48071
|
import { homedir as homedir6, platform as platform2, userInfo } from "os";
|
|
48014
|
-
import { dirname as
|
|
48072
|
+
import { dirname as dirname6, join as join6 } from "path";
|
|
48015
48073
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
48016
48074
|
var SERVICE_LABEL = "ai.modelstat.agent";
|
|
48017
48075
|
var SYSTEMD_UNIT = "modelstat";
|
|
@@ -48019,16 +48077,16 @@ function home() {
|
|
|
48019
48077
|
return homedir6();
|
|
48020
48078
|
}
|
|
48021
48079
|
function stateDir() {
|
|
48022
|
-
return
|
|
48080
|
+
return join6(home(), ".modelstat");
|
|
48023
48081
|
}
|
|
48024
48082
|
function binDir() {
|
|
48025
|
-
return
|
|
48083
|
+
return join6(stateDir(), "bin");
|
|
48026
48084
|
}
|
|
48027
48085
|
function logDir() {
|
|
48028
|
-
return
|
|
48086
|
+
return join6(stateDir(), "logs");
|
|
48029
48087
|
}
|
|
48030
48088
|
function installedCliPath() {
|
|
48031
|
-
return
|
|
48089
|
+
return join6(binDir(), "modelstat.mjs");
|
|
48032
48090
|
}
|
|
48033
48091
|
function runningCliPath() {
|
|
48034
48092
|
return fileURLToPath2(import.meta.url).replace(/service\.(mjs|js|ts)$/, "cli.mjs");
|
|
@@ -48038,7 +48096,7 @@ function installBundle() {
|
|
|
48038
48096
|
mkdirSync2(logDir(), { recursive: true });
|
|
48039
48097
|
const src = runningCliPath();
|
|
48040
48098
|
const dest = installedCliPath();
|
|
48041
|
-
if (!
|
|
48099
|
+
if (!existsSync7(src)) {
|
|
48042
48100
|
throw new Error(
|
|
48043
48101
|
`Can't find the CLI bundle to install from (${src}). Are you running a local dev build?`
|
|
48044
48102
|
);
|
|
@@ -48054,14 +48112,14 @@ var NODE_LLAMA_CPP_FALLBACK_VERSION = "3.18.1";
|
|
|
48054
48112
|
function sourceLlamaVersion(sourceCli) {
|
|
48055
48113
|
try {
|
|
48056
48114
|
const req = createRequire(sourceCli);
|
|
48057
|
-
let d =
|
|
48115
|
+
let d = dirname6(realpathSync(req.resolve("node-llama-cpp")));
|
|
48058
48116
|
for (let i = 0; i < 10; i++) {
|
|
48059
|
-
const pj =
|
|
48060
|
-
if (
|
|
48117
|
+
const pj = join6(d, "package.json");
|
|
48118
|
+
if (existsSync7(pj)) {
|
|
48061
48119
|
const p = JSON.parse(readFileSync3(pj, "utf8"));
|
|
48062
48120
|
if (p.name === "node-llama-cpp" && p.version) return p.version;
|
|
48063
48121
|
}
|
|
48064
|
-
const up =
|
|
48122
|
+
const up = dirname6(d);
|
|
48065
48123
|
if (up === d) break;
|
|
48066
48124
|
d = up;
|
|
48067
48125
|
}
|
|
@@ -48075,7 +48133,7 @@ function installNativeRuntime(sourceCli) {
|
|
|
48075
48133
|
try {
|
|
48076
48134
|
const have = JSON.parse(
|
|
48077
48135
|
readFileSync3(
|
|
48078
|
-
|
|
48136
|
+
join6(dest, "node_modules", "node-llama-cpp", "package.json"),
|
|
48079
48137
|
"utf8"
|
|
48080
48138
|
)
|
|
48081
48139
|
);
|
|
@@ -48116,21 +48174,21 @@ function nodeBinary() {
|
|
|
48116
48174
|
return process.execPath;
|
|
48117
48175
|
}
|
|
48118
48176
|
function plistPath() {
|
|
48119
|
-
return
|
|
48177
|
+
return join6(home(), "Library", "LaunchAgents", `${SERVICE_LABEL}.plist`);
|
|
48120
48178
|
}
|
|
48121
48179
|
function locateTrayExecutable() {
|
|
48122
48180
|
const candidates = [
|
|
48123
|
-
|
|
48181
|
+
join6(home(), "Applications", "ModelstatTray.app", "Contents", "MacOS", "modelstat-tray"),
|
|
48124
48182
|
"/Applications/ModelstatTray.app/Contents/MacOS/modelstat-tray"
|
|
48125
48183
|
];
|
|
48126
48184
|
for (const p of candidates) {
|
|
48127
|
-
if (
|
|
48185
|
+
if (existsSync7(p)) return p;
|
|
48128
48186
|
}
|
|
48129
48187
|
return null;
|
|
48130
48188
|
}
|
|
48131
48189
|
function writePlist(cliPath) {
|
|
48132
48190
|
const p = plistPath();
|
|
48133
|
-
mkdirSync2(
|
|
48191
|
+
mkdirSync2(dirname6(p), { recursive: true });
|
|
48134
48192
|
const tray = locateTrayExecutable();
|
|
48135
48193
|
const programArgs = tray ? ` <string>${tray}</string>` : [
|
|
48136
48194
|
` <string>${nodeBinary()}</string>`,
|
|
@@ -48150,8 +48208,8 @@ ${programArgs}
|
|
|
48150
48208
|
<key>KeepAlive</key>
|
|
48151
48209
|
<dict><key>SuccessfulExit</key><false/></dict>
|
|
48152
48210
|
<key>ThrottleInterval</key><integer>30</integer>
|
|
48153
|
-
<key>StandardOutPath</key><string>${
|
|
48154
|
-
<key>StandardErrorPath</key><string>${
|
|
48211
|
+
<key>StandardOutPath</key><string>${join6(logDir(), "out.log")}</string>
|
|
48212
|
+
<key>StandardErrorPath</key><string>${join6(logDir(), "err.log")}</string>
|
|
48155
48213
|
<key>EnvironmentVariables</key>
|
|
48156
48214
|
<dict>
|
|
48157
48215
|
<key>PATH</key><string>/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin</string>
|
|
@@ -48196,7 +48254,7 @@ function macUninstall() {
|
|
|
48196
48254
|
const target = `gui/${uid}/${SERVICE_LABEL}`;
|
|
48197
48255
|
launchctl(["bootout", target]);
|
|
48198
48256
|
const plist = plistPath();
|
|
48199
|
-
if (
|
|
48257
|
+
if (existsSync7(plist)) {
|
|
48200
48258
|
try {
|
|
48201
48259
|
unlinkSync(plist);
|
|
48202
48260
|
} catch {
|
|
@@ -48209,12 +48267,12 @@ function macStatus() {
|
|
|
48209
48267
|
return { running: r.ok, hint: r.ok ? "launchd managed" : "not installed" };
|
|
48210
48268
|
}
|
|
48211
48269
|
function systemdUnitPath() {
|
|
48212
|
-
const xdg = process.env.XDG_CONFIG_HOME ??
|
|
48213
|
-
return
|
|
48270
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? join6(home(), ".config");
|
|
48271
|
+
return join6(xdg, "systemd", "user", `${SYSTEMD_UNIT}.service`);
|
|
48214
48272
|
}
|
|
48215
48273
|
function writeSystemdUnit(cliPath) {
|
|
48216
48274
|
const unitPath = systemdUnitPath();
|
|
48217
|
-
mkdirSync2(
|
|
48275
|
+
mkdirSync2(dirname6(unitPath), { recursive: true });
|
|
48218
48276
|
const unit = `[Unit]
|
|
48219
48277
|
Description=modelstat agent
|
|
48220
48278
|
Documentation=https://modelstat.ai
|
|
@@ -48233,8 +48291,8 @@ RestartSec=10
|
|
|
48233
48291
|
# Don't restart-storm if the service is persistently unreachable.
|
|
48234
48292
|
StartLimitIntervalSec=300
|
|
48235
48293
|
StartLimitBurst=10
|
|
48236
|
-
StandardOutput=append:${
|
|
48237
|
-
StandardError=append:${
|
|
48294
|
+
StandardOutput=append:${join6(logDir(), "out.log")}
|
|
48295
|
+
StandardError=append:${join6(logDir(), "err.log")}
|
|
48238
48296
|
|
|
48239
48297
|
[Install]
|
|
48240
48298
|
WantedBy=default.target
|
|
@@ -48259,7 +48317,7 @@ function linuxInstall() {
|
|
|
48259
48317
|
function linuxUninstall() {
|
|
48260
48318
|
systemctl(["disable", "--now", `${SYSTEMD_UNIT}.service`]);
|
|
48261
48319
|
const unit = systemdUnitPath();
|
|
48262
|
-
if (
|
|
48320
|
+
if (existsSync7(unit)) {
|
|
48263
48321
|
try {
|
|
48264
48322
|
unlinkSync(unit);
|
|
48265
48323
|
} catch {
|
|
@@ -48303,9 +48361,9 @@ function logsDir() {
|
|
|
48303
48361
|
}
|
|
48304
48362
|
function installTrayApp(sourceAppPath) {
|
|
48305
48363
|
if (platform2() !== "darwin") return null;
|
|
48306
|
-
if (!
|
|
48307
|
-
const dest =
|
|
48308
|
-
mkdirSync2(
|
|
48364
|
+
if (!existsSync7(sourceAppPath)) return null;
|
|
48365
|
+
const dest = join6(home(), "Applications", "ModelstatTray.app");
|
|
48366
|
+
mkdirSync2(dirname6(dest), { recursive: true });
|
|
48309
48367
|
spawnSync("rm", ["-rf", dest]);
|
|
48310
48368
|
const r = spawnSync("cp", ["-R", sourceAppPath, dest], { encoding: "utf8" });
|
|
48311
48369
|
if (r.status !== 0) {
|
|
@@ -48315,28 +48373,28 @@ function installTrayApp(sourceAppPath) {
|
|
|
48315
48373
|
}
|
|
48316
48374
|
function bundledTrayAppPath() {
|
|
48317
48375
|
if (platform2() !== "darwin") return null;
|
|
48318
|
-
const here2 =
|
|
48376
|
+
const here2 = dirname6(fileURLToPath2(import.meta.url));
|
|
48319
48377
|
const candidates = [
|
|
48320
48378
|
// Pre-built .app — CI with codesigning drops one here.
|
|
48321
|
-
|
|
48379
|
+
join6(here2, "..", "vendor", "ModelstatTray.app"),
|
|
48322
48380
|
// Local dev layout: apps/agent-dev/src/service.ts → ../../tray-mac/build/ModelstatTray.app
|
|
48323
|
-
|
|
48381
|
+
join6(here2, "..", "..", "tray-mac", "build", "ModelstatTray.app")
|
|
48324
48382
|
];
|
|
48325
48383
|
for (const c of candidates) {
|
|
48326
|
-
if (
|
|
48384
|
+
if (existsSync7(c)) return c;
|
|
48327
48385
|
}
|
|
48328
48386
|
const sourceDirs = [
|
|
48329
|
-
|
|
48330
|
-
|
|
48387
|
+
join6(here2, "..", "vendor", "tray-mac"),
|
|
48388
|
+
join6(here2, "..", "..", "tray-mac")
|
|
48331
48389
|
];
|
|
48332
48390
|
for (const src of sourceDirs) {
|
|
48333
|
-
const build =
|
|
48334
|
-
if (!
|
|
48391
|
+
const build = join6(src, "build-app.sh");
|
|
48392
|
+
if (!existsSync7(build)) continue;
|
|
48335
48393
|
if (!hasSwift()) return null;
|
|
48336
48394
|
const r = spawnSync("bash", [build], { cwd: src, encoding: "utf8" });
|
|
48337
48395
|
if (r.status === 0) {
|
|
48338
|
-
const app =
|
|
48339
|
-
if (
|
|
48396
|
+
const app = join6(src, "build", "ModelstatTray.app");
|
|
48397
|
+
if (existsSync7(app)) return app;
|
|
48340
48398
|
}
|
|
48341
48399
|
}
|
|
48342
48400
|
return null;
|
|
@@ -48381,7 +48439,7 @@ function tryOpenBrowser(url) {
|
|
|
48381
48439
|
return false;
|
|
48382
48440
|
}
|
|
48383
48441
|
}
|
|
48384
|
-
var AGENT_VERSION3 = true ? "agent-0.0.
|
|
48442
|
+
var AGENT_VERSION3 = true ? "agent-0.0.45" : "agent-dev";
|
|
48385
48443
|
function osFamily() {
|
|
48386
48444
|
const p = platform4();
|
|
48387
48445
|
if (p === "darwin") return "macos";
|
|
@@ -48776,9 +48834,9 @@ function fmtTokens(v) {
|
|
|
48776
48834
|
async function readLocalStatus() {
|
|
48777
48835
|
try {
|
|
48778
48836
|
const { homedir: homedir9 } = await import("os");
|
|
48779
|
-
const { join:
|
|
48837
|
+
const { join: join11 } = await import("path");
|
|
48780
48838
|
const { readFile } = await import("fs/promises");
|
|
48781
|
-
const p =
|
|
48839
|
+
const p = join11(homedir9(), ".modelstat", "last-status.json");
|
|
48782
48840
|
const txt = await readFile(p, "utf8");
|
|
48783
48841
|
return JSON.parse(txt);
|
|
48784
48842
|
} catch {
|
|
@@ -48911,6 +48969,22 @@ function cmdPaths(args) {
|
|
|
48911
48969
|
console.log(`${k.padEnd(8)} ${String(v)}`);
|
|
48912
48970
|
}
|
|
48913
48971
|
}
|
|
48972
|
+
function cmdToken(args) {
|
|
48973
|
+
if (!state.bearer) {
|
|
48974
|
+
console.error("not paired \u2014 run `npx modelstat@latest` first");
|
|
48975
|
+
process.exit(1);
|
|
48976
|
+
}
|
|
48977
|
+
if (args.includes("--json")) {
|
|
48978
|
+
process.stdout.write(`${JSON.stringify({ token: state.bearer, api: state.apiUrl })}
|
|
48979
|
+
`);
|
|
48980
|
+
return;
|
|
48981
|
+
}
|
|
48982
|
+
process.stdout.write(`${state.bearer}
|
|
48983
|
+
`);
|
|
48984
|
+
if (process.stderr.isTTY) {
|
|
48985
|
+
console.error("(device token \u2014 treat it like a password; rotate via the dashboard if leaked)");
|
|
48986
|
+
}
|
|
48987
|
+
}
|
|
48914
48988
|
function parseConnectOpts(argv) {
|
|
48915
48989
|
return {
|
|
48916
48990
|
json: argv.includes("--json"),
|
|
@@ -48951,6 +49025,9 @@ async function main() {
|
|
|
48951
49025
|
case "paths":
|
|
48952
49026
|
cmdPaths(rest);
|
|
48953
49027
|
return;
|
|
49028
|
+
case "token":
|
|
49029
|
+
cmdToken(rest);
|
|
49030
|
+
return;
|
|
48954
49031
|
case "discover":
|
|
48955
49032
|
return cmdDiscover();
|
|
48956
49033
|
case "scan":
|
|
@@ -48975,6 +49052,7 @@ async function main() {
|
|
|
48975
49052
|
console.log(" npx modelstat@latest stats \u2014 live device summary: sessions \xB7 tokens \xB7 cost (--json)");
|
|
48976
49053
|
console.log(" npx modelstat@latest jobs \u2014 pipeline queue + recent processing ledger (--json)");
|
|
48977
49054
|
console.log(" npx modelstat@latest paths \u2014 print state file + log dir + api URL (--json)");
|
|
49055
|
+
console.log(" npx modelstat@latest token \u2014 print the device token for hosted MCP / API access (--json)");
|
|
48978
49056
|
console.log();
|
|
48979
49057
|
console.log("Dev / one-shots:");
|
|
48980
49058
|
console.log(" npx modelstat@latest scan \u2014 one-shot parse + upload of local JSONL");
|