modelstat 0.0.26 → 0.0.28
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 +119 -34
- package/dist/cli.mjs.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall.mjs +91 -1
package/dist/cli.mjs
CHANGED
|
@@ -21132,7 +21132,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
21132
21132
|
"../../node_modules/.pnpm/undici@7.25.0/node_modules/undici/lib/mock/snapshot-recorder.js"(exports, module) {
|
|
21133
21133
|
"use strict";
|
|
21134
21134
|
var { writeFile, readFile, mkdir: mkdir2 } = __require("fs/promises");
|
|
21135
|
-
var { dirname:
|
|
21135
|
+
var { dirname: dirname9, resolve: resolve6 } = __require("path");
|
|
21136
21136
|
var { setTimeout: setTimeout2, clearTimeout: clearTimeout2 } = __require("timers");
|
|
21137
21137
|
var { InvalidArgumentError, UndiciError } = require_errors();
|
|
21138
21138
|
var { hashId, isUrlExcludedFactory, normalizeHeaders, createHeaderFilters } = require_snapshot_utils();
|
|
@@ -21363,7 +21363,7 @@ var require_snapshot_recorder = __commonJS({
|
|
|
21363
21363
|
throw new InvalidArgumentError("Snapshot path is required");
|
|
21364
21364
|
}
|
|
21365
21365
|
const resolvedPath = resolve6(path5);
|
|
21366
|
-
await mkdir2(
|
|
21366
|
+
await mkdir2(dirname9(resolvedPath), { recursive: true });
|
|
21367
21367
|
const data = Array.from(this.#snapshots.entries()).map(([hash, snapshot]) => ({
|
|
21368
21368
|
hash,
|
|
21369
21369
|
snapshot
|
|
@@ -43981,7 +43981,8 @@ var init_config2 = __esm({
|
|
|
43981
43981
|
claimUrl: null,
|
|
43982
43982
|
userEmail: null,
|
|
43983
43983
|
defaultOrgId: null,
|
|
43984
|
-
cursor: {}
|
|
43984
|
+
cursor: {},
|
|
43985
|
+
processingVersion: null
|
|
43985
43986
|
}
|
|
43986
43987
|
});
|
|
43987
43988
|
cachedIdentity = (() => {
|
|
@@ -44073,6 +44074,19 @@ var init_config2 = __esm({
|
|
|
44073
44074
|
map[path5] = v;
|
|
44074
44075
|
store.set("cursor", map);
|
|
44075
44076
|
},
|
|
44077
|
+
/** Drop every per-file cursor so the next scan re-reads every
|
|
44078
|
+
* JSONL from byte 0. Called when the local processing-pipeline
|
|
44079
|
+
* version bumps (see processing-version.ts) or via the
|
|
44080
|
+
* `modelstat rescan` CLI command. */
|
|
44081
|
+
wipeCursors() {
|
|
44082
|
+
store.set("cursor", {});
|
|
44083
|
+
},
|
|
44084
|
+
get processingVersion() {
|
|
44085
|
+
return store.get("processingVersion");
|
|
44086
|
+
},
|
|
44087
|
+
setProcessingVersion(v) {
|
|
44088
|
+
store.set("processingVersion", v);
|
|
44089
|
+
},
|
|
44076
44090
|
get storePath() {
|
|
44077
44091
|
return store.path;
|
|
44078
44092
|
}
|
|
@@ -45220,6 +45234,29 @@ var init_lock = __esm({
|
|
|
45220
45234
|
}
|
|
45221
45235
|
});
|
|
45222
45236
|
|
|
45237
|
+
// src/processing-version.ts
|
|
45238
|
+
var processing_version_exports = {};
|
|
45239
|
+
__export(processing_version_exports, {
|
|
45240
|
+
PROCESSING_VERSION: () => PROCESSING_VERSION,
|
|
45241
|
+
reconcileProcessingVersion: () => reconcileProcessingVersion
|
|
45242
|
+
});
|
|
45243
|
+
function reconcileProcessingVersion(state2) {
|
|
45244
|
+
const stored = state2.processingVersion ?? 1;
|
|
45245
|
+
if (stored >= PROCESSING_VERSION) {
|
|
45246
|
+
return { changed: false, from: stored, to: PROCESSING_VERSION };
|
|
45247
|
+
}
|
|
45248
|
+
state2.wipeCursors();
|
|
45249
|
+
state2.setProcessingVersion(PROCESSING_VERSION);
|
|
45250
|
+
return { changed: true, from: stored, to: PROCESSING_VERSION };
|
|
45251
|
+
}
|
|
45252
|
+
var PROCESSING_VERSION;
|
|
45253
|
+
var init_processing_version = __esm({
|
|
45254
|
+
"src/processing-version.ts"() {
|
|
45255
|
+
"use strict";
|
|
45256
|
+
PROCESSING_VERSION = 2;
|
|
45257
|
+
}
|
|
45258
|
+
});
|
|
45259
|
+
|
|
45223
45260
|
// ../../node_modules/.pnpm/readdirp@4.1.2/node_modules/readdirp/esm/index.js
|
|
45224
45261
|
import { stat as stat3, lstat, readdir as readdir2, realpath } from "fs/promises";
|
|
45225
45262
|
import { Readable as Readable2 } from "stream";
|
|
@@ -45953,9 +45990,9 @@ var init_handler = __esm({
|
|
|
45953
45990
|
if (this.fsw.closed) {
|
|
45954
45991
|
return;
|
|
45955
45992
|
}
|
|
45956
|
-
const
|
|
45993
|
+
const dirname9 = sysPath.dirname(file);
|
|
45957
45994
|
const basename4 = sysPath.basename(file);
|
|
45958
|
-
const parent = this.fsw._getWatchedDir(
|
|
45995
|
+
const parent = this.fsw._getWatchedDir(dirname9);
|
|
45959
45996
|
let prevStats = stats;
|
|
45960
45997
|
if (parent.has(basename4))
|
|
45961
45998
|
return;
|
|
@@ -45982,7 +46019,7 @@ var init_handler = __esm({
|
|
|
45982
46019
|
prevStats = newStats2;
|
|
45983
46020
|
}
|
|
45984
46021
|
} catch (error) {
|
|
45985
|
-
this.fsw._remove(
|
|
46022
|
+
this.fsw._remove(dirname9, basename4);
|
|
45986
46023
|
}
|
|
45987
46024
|
} else if (parent.has(basename4)) {
|
|
45988
46025
|
const at = newStats.atimeMs;
|
|
@@ -46947,6 +46984,9 @@ __export(daemon_exports, {
|
|
|
46947
46984
|
setQueue: () => setQueue
|
|
46948
46985
|
});
|
|
46949
46986
|
import { existsSync as existsSync8, statSync as statSync2 } from "fs";
|
|
46987
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
46988
|
+
import { dirname as dirname8, join as join9 } from "path";
|
|
46989
|
+
import { fileURLToPath as __agentFileURLToPath } from "url";
|
|
46950
46990
|
function setPhase(phase, message) {
|
|
46951
46991
|
status.phase = phase;
|
|
46952
46992
|
status.message = message ?? null;
|
|
@@ -47074,22 +47114,29 @@ async function runDaemon(opts = {}) {
|
|
|
47074
47114
|
setPhase("error", `summariser preflight failed: ${err.message}`);
|
|
47075
47115
|
throw err;
|
|
47076
47116
|
}
|
|
47117
|
+
const { reconcileProcessingVersion: reconcileProcessingVersion2 } = await Promise.resolve().then(() => (init_processing_version(), processing_version_exports));
|
|
47118
|
+
const pv = reconcileProcessingVersion2(state);
|
|
47119
|
+
if (pv.changed) {
|
|
47120
|
+
console.log(
|
|
47121
|
+
`[modelstat] processing pipeline v${pv.from} \u2192 v${pv.to} \u2014 wiped file cursors so every session is re-processed by the new pipeline`
|
|
47122
|
+
);
|
|
47123
|
+
}
|
|
47077
47124
|
await runDiscovery();
|
|
47078
47125
|
await runScanCycle("startup");
|
|
47079
47126
|
const chokidar = (await Promise.resolve().then(() => (init_esm2(), esm_exports))).default;
|
|
47080
47127
|
const { homedir: homedir9, platform: platform5 } = await import("os");
|
|
47081
|
-
const { join:
|
|
47128
|
+
const { join: join11 } = await import("path");
|
|
47082
47129
|
const home2 = homedir9();
|
|
47083
47130
|
const dirs = [
|
|
47084
|
-
|
|
47085
|
-
|
|
47086
|
-
|
|
47087
|
-
|
|
47131
|
+
join11(home2, ".claude/projects"),
|
|
47132
|
+
join11(home2, ".codex/sessions"),
|
|
47133
|
+
join11(home2, ".cursor/ai-tracking"),
|
|
47134
|
+
join11(home2, ".gemini"),
|
|
47088
47135
|
...platform5() === "darwin" ? [
|
|
47089
|
-
|
|
47090
|
-
|
|
47136
|
+
join11(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
47137
|
+
join11(home2, "Library/Application Support/Claude")
|
|
47091
47138
|
] : [
|
|
47092
|
-
|
|
47139
|
+
join11(home2, ".config/Cursor/User/workspaceStorage")
|
|
47093
47140
|
]
|
|
47094
47141
|
].filter((p) => existsSync8(p) && statSync2(p).isDirectory());
|
|
47095
47142
|
setPhase("watching", `Watching ${dirs.length} directories`);
|
|
@@ -47138,7 +47185,24 @@ var init_daemon = __esm({
|
|
|
47138
47185
|
init_config2();
|
|
47139
47186
|
init_lock();
|
|
47140
47187
|
init_scan();
|
|
47141
|
-
AGENT_VERSION2 =
|
|
47188
|
+
AGENT_VERSION2 = (() => {
|
|
47189
|
+
try {
|
|
47190
|
+
const here2 = dirname8(__agentFileURLToPath(import.meta.url));
|
|
47191
|
+
const candidates = [
|
|
47192
|
+
join9(here2, "..", "package.json"),
|
|
47193
|
+
join9(here2, "..", "..", "package.json")
|
|
47194
|
+
];
|
|
47195
|
+
for (const c of candidates) {
|
|
47196
|
+
try {
|
|
47197
|
+
const v = JSON.parse(readFileSync4(c, "utf8")).version;
|
|
47198
|
+
if (typeof v === "string") return `agent-${v}`;
|
|
47199
|
+
} catch {
|
|
47200
|
+
}
|
|
47201
|
+
}
|
|
47202
|
+
} catch {
|
|
47203
|
+
}
|
|
47204
|
+
return "agent-unknown";
|
|
47205
|
+
})();
|
|
47142
47206
|
HEARTBEAT_INTERVAL_MS = 1e4;
|
|
47143
47207
|
SCAN_INTERVAL_MS = 5 * 60 * 1e3;
|
|
47144
47208
|
status = {
|
|
@@ -47160,32 +47224,32 @@ __export(watch_exports, {
|
|
|
47160
47224
|
});
|
|
47161
47225
|
import { existsSync as existsSync9 } from "fs";
|
|
47162
47226
|
import { homedir as homedir8, platform as platform3 } from "os";
|
|
47163
|
-
import { join as
|
|
47227
|
+
import { join as join10 } from "path";
|
|
47164
47228
|
function resolveWatchDirs() {
|
|
47165
47229
|
const home2 = homedir8();
|
|
47166
|
-
const xdgConfig = process.env.XDG_CONFIG_HOME ??
|
|
47167
|
-
const xdgData = process.env.XDG_DATA_HOME ??
|
|
47230
|
+
const xdgConfig = process.env.XDG_CONFIG_HOME ?? join10(home2, ".config");
|
|
47231
|
+
const xdgData = process.env.XDG_DATA_HOME ?? join10(home2, ".local/share");
|
|
47168
47232
|
const candidates = [
|
|
47169
47233
|
// universal (default HOME-rooted CLI data dirs)
|
|
47170
|
-
|
|
47171
|
-
|
|
47172
|
-
|
|
47173
|
-
|
|
47174
|
-
|
|
47234
|
+
join10(home2, ".claude/projects"),
|
|
47235
|
+
join10(home2, ".codex/sessions"),
|
|
47236
|
+
join10(home2, ".cursor/ai-tracking"),
|
|
47237
|
+
join10(home2, ".gemini"),
|
|
47238
|
+
join10(home2, ".aider"),
|
|
47175
47239
|
// XDG / Linux
|
|
47176
|
-
|
|
47177
|
-
|
|
47178
|
-
|
|
47179
|
-
|
|
47180
|
-
|
|
47181
|
-
|
|
47240
|
+
join10(xdgConfig, "claude/projects"),
|
|
47241
|
+
join10(xdgConfig, "codex/sessions"),
|
|
47242
|
+
join10(xdgConfig, "Cursor/User/workspaceStorage"),
|
|
47243
|
+
join10(xdgConfig, "Code/User/workspaceStorage"),
|
|
47244
|
+
join10(xdgConfig, "Code - Insiders/User/workspaceStorage"),
|
|
47245
|
+
join10(xdgData, "claude/projects"),
|
|
47182
47246
|
// macOS
|
|
47183
47247
|
...platform3() === "darwin" ? [
|
|
47184
|
-
|
|
47185
|
-
|
|
47186
|
-
|
|
47187
|
-
|
|
47188
|
-
|
|
47248
|
+
join10(home2, "Library/Application Support/Cursor/User/workspaceStorage"),
|
|
47249
|
+
join10(home2, "Library/Application Support/Claude"),
|
|
47250
|
+
join10(home2, "Library/Application Support/Code/User/workspaceStorage"),
|
|
47251
|
+
join10(home2, "Library/Application Support/Windsurf/User/workspaceStorage"),
|
|
47252
|
+
join10(home2, "Library/Application Support/Zed")
|
|
47189
47253
|
] : []
|
|
47190
47254
|
];
|
|
47191
47255
|
return Array.from(new Set(candidates)).filter((p) => existsSync9(p));
|
|
@@ -47847,12 +47911,30 @@ async function cmdScan() {
|
|
|
47847
47911
|
const { preflightSummariser: preflightSummariser2 } = await Promise.resolve().then(() => (init_pipeline2(), pipeline_exports));
|
|
47848
47912
|
const sample = await preflightSummariser2();
|
|
47849
47913
|
console.log(`[modelstat] summariser preflight ok: "${sample}"`);
|
|
47914
|
+
const { reconcileProcessingVersion: reconcileProcessingVersion2 } = await Promise.resolve().then(() => (init_processing_version(), processing_version_exports));
|
|
47915
|
+
const pv = reconcileProcessingVersion2(state);
|
|
47916
|
+
if (pv.changed) {
|
|
47917
|
+
console.log(
|
|
47918
|
+
`[modelstat] processing pipeline v${pv.from} \u2192 v${pv.to} \u2014 wiped file cursors so every session is re-processed`
|
|
47919
|
+
);
|
|
47920
|
+
}
|
|
47850
47921
|
const r = await scanAll();
|
|
47851
47922
|
console.log();
|
|
47852
47923
|
console.log(
|
|
47853
47924
|
`Done: ${r.filesScanned} files scanned, ${r.filesUnchanged} unchanged, ${r.batchesUploaded} batches, ${r.eventsUploaded} events uploaded`
|
|
47854
47925
|
);
|
|
47855
47926
|
}
|
|
47927
|
+
async function cmdRescan() {
|
|
47928
|
+
const { PROCESSING_VERSION: PROCESSING_VERSION2 } = await Promise.resolve().then(() => (init_processing_version(), processing_version_exports));
|
|
47929
|
+
state.wipeCursors();
|
|
47930
|
+
state.setProcessingVersion(PROCESSING_VERSION2);
|
|
47931
|
+
console.log(
|
|
47932
|
+
`[modelstat] cursors wiped \u2014 next \`modelstat scan\` (or daemon scan cycle) will re-read every JSONL from the start and re-summarise every session at processing version v${PROCESSING_VERSION2}.`
|
|
47933
|
+
);
|
|
47934
|
+
console.log(
|
|
47935
|
+
" If the daemon is running, kick it with: modelstat stop && modelstat start"
|
|
47936
|
+
);
|
|
47937
|
+
}
|
|
47856
47938
|
async function cmdWatch() {
|
|
47857
47939
|
const { watchForever: watchForever2 } = await Promise.resolve().then(() => (init_watch(), watch_exports));
|
|
47858
47940
|
await watchForever2();
|
|
@@ -48041,6 +48123,8 @@ async function main() {
|
|
|
48041
48123
|
return cmdDiscover();
|
|
48042
48124
|
case "scan":
|
|
48043
48125
|
return cmdScan();
|
|
48126
|
+
case "rescan":
|
|
48127
|
+
return cmdRescan();
|
|
48044
48128
|
case "watch":
|
|
48045
48129
|
return cmdWatch();
|
|
48046
48130
|
case "stop":
|
|
@@ -48073,6 +48157,7 @@ async function main() {
|
|
|
48073
48157
|
console.log(" start \u2014 run the daemon (used by the installed service)");
|
|
48074
48158
|
console.log(" discover \u2014 one-shot report of installs/identities");
|
|
48075
48159
|
console.log(" scan \u2014 one-shot parse + upload of local JSONL");
|
|
48160
|
+
console.log(" rescan \u2014 wipe file cursors so next scan re-reads & re-summarises everything");
|
|
48076
48161
|
console.log(" watch \u2014 continuous (chokidar) with periodic backstop");
|
|
48077
48162
|
process.exit(1);
|
|
48078
48163
|
}
|