@usagefleet/cli 1.2.163 → 1.2.164
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/README.md +3 -2
- package/dist/collector.js +10 -6
- package/dist/config.js +2 -1
- package/dist/index.js +3 -2
- package/dist/jcode.js +5 -5
- package/dist/paths.js +4 -0
- package/dist/release.js +1 -1
- package/dist/store.js +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -78,8 +78,8 @@ shell once. `uninstall` removes both again, and self-update keeps them current.
|
|
|
78
78
|
Desktop agent-mode (Cowork) sessions, and the
|
|
79
79
|
[pi](https://github.com/badlogic/pi-mono) agent (`~/.pi/agent/sessions`,
|
|
80
80
|
`anthropic` and `claude-bridge` provider records only; other providers don't
|
|
81
|
-
touch Claude limits), and the jcode agent (`~/.jcode/sessions
|
|
82
|
-
subscription turns only
|
|
81
|
+
touch Claude limits), and the jcode agent (`~/.jcode/sessions`) and its pj fork
|
|
82
|
+
(`~/.pj/sessions`), Claude subscription turns only.
|
|
83
83
|
A per-file byte offset in the config file means each line is sent once;
|
|
84
84
|
rotation and truncation are handled and partial lines are never sent. Delivery
|
|
85
85
|
is at-least-once — the server dedups on `uuid`.
|
|
@@ -159,6 +159,7 @@ it (`usagefleet config` prints this same table):
|
|
|
159
159
|
| `desktopDir` | `USAGEFLEET_DESKTOP` | override the Claude Desktop sessions dir; `off` to skip it |
|
|
160
160
|
| `piDir` | `USAGEFLEET_PI` | pi sessions dirs — string or array in the file, comma-separated in env; `off` to skip |
|
|
161
161
|
| `jcodeDir` | `USAGEFLEET_JCODE` | override the jcode sessions dir (`~/.jcode/sessions`); `off` to skip it |
|
|
162
|
+
| `pjDir` | `USAGEFLEET_PJ` | override the pj sessions dir (`~/.pj/sessions`); `off` to skip it |
|
|
162
163
|
| `interval` | `USAGEFLEET_INTERVAL` | watch poll seconds (default 15) |
|
|
163
164
|
| `limitsInterval` | `USAGEFLEET_LIMITS_INTERVAL` | seconds between limit reports (default 60; 300 on API keys, where each report costs a 1-token ping) |
|
|
164
165
|
| `notifications` | `USAGEFLEET_NOTIFY` | desktop notifications, on by default (`false`/`0` disables) |
|
package/dist/collector.js
CHANGED
|
@@ -52,12 +52,16 @@ export async function runOnce(cfg, log = () => {
|
|
|
52
52
|
files.push({ fp, source: root.source });
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
const
|
|
55
|
+
const jcodeRoots = [
|
|
56
|
+
{ dir: cfg.jcodeDir, source: 'jcode' },
|
|
57
|
+
{ dir: cfg.pjDir, source: 'pj' },
|
|
58
|
+
];
|
|
59
|
+
const jcodeSessions = jcodeRoots.flatMap(({ dir, source }) => dir ? listJcodeSessions(dir).map(fp => ({ fp, source })) : []);
|
|
56
60
|
// Each source yields its new records and how to commit having sent them, so both
|
|
57
|
-
// share one upload path: offsets for appended JSONL, a watermark for jcode.
|
|
61
|
+
// share one upload path: offsets for appended JSONL, a watermark for jcode and pj.
|
|
58
62
|
const reads = [
|
|
59
63
|
...files.map(({ fp, source }) => ({ fp, read: () => tailPending(fp, source, state.files) })),
|
|
60
|
-
...jcodeSessions.map(fp => ({ fp, read: () => jcodePending(fp, state.jcode) })),
|
|
64
|
+
...jcodeSessions.map(({ fp, source }) => ({ fp, read: () => jcodePending(fp, source, state.jcode) })),
|
|
61
65
|
];
|
|
62
66
|
const result = {
|
|
63
67
|
accepted: 0,
|
|
@@ -140,7 +144,7 @@ export async function runOnce(cfg, log = () => {
|
|
|
140
144
|
// dedups. Only our own section is replaced, so a token written by a
|
|
141
145
|
// concurrent `usagefleet login` survives.
|
|
142
146
|
const pruned = pruneMissingFiles(state, files);
|
|
143
|
-
const prunedJcode = pruneGoneSessions(state.jcode, jcodeSessions);
|
|
147
|
+
const prunedJcode = pruneGoneSessions(state.jcode, jcodeSessions.map(s => s.fp));
|
|
144
148
|
if (pruned || prunedJcode || advanced) {
|
|
145
149
|
updateStore(cfg.storePath, store => {
|
|
146
150
|
store.state.files = state.files;
|
|
@@ -224,8 +228,8 @@ function tailPending(fp, source, files) {
|
|
|
224
228
|
segments: tail.segments,
|
|
225
229
|
};
|
|
226
230
|
}
|
|
227
|
-
function jcodePending(fp, sessions) {
|
|
228
|
-
const session = readJcodeSession(fp, sessions[fp]);
|
|
231
|
+
function jcodePending(fp, source, sessions) {
|
|
232
|
+
const session = readJcodeSession(fp, source, sessions[fp]);
|
|
229
233
|
if (!session) {
|
|
230
234
|
return null;
|
|
231
235
|
}
|
package/dist/config.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defaultDesktopSessionsDir, defaultJcodeSessionsDir, defaultPiSessionsDirs, defaultProjectsDir, } from './paths.js';
|
|
1
|
+
import { defaultDesktopSessionsDir, defaultJcodeSessionsDir, defaultPiSessionsDirs, defaultPjSessionsDir, defaultProjectsDir, } from './paths.js';
|
|
2
2
|
import { readStore, storePath } from './store.js';
|
|
3
3
|
/** Matches the server's BatchSchema `.max(1000)`. */
|
|
4
4
|
const MAX_BATCH = 1000;
|
|
@@ -28,6 +28,7 @@ export function loadConfig() {
|
|
|
28
28
|
desktopDir: resolveOptionalDir(process.env.USAGEFLEET_DESKTOP, file.desktopDir, defaultDesktopSessionsDir()),
|
|
29
29
|
jcodeDir: resolveOptionalDir(process.env.USAGEFLEET_JCODE, file.jcodeDir, defaultJcodeSessionsDir()),
|
|
30
30
|
piDirs: resolvePiDirs(process.env.USAGEFLEET_PI, file.piDir),
|
|
31
|
+
pjDir: resolveOptionalDir(process.env.USAGEFLEET_PJ, file.pjDir, defaultPjSessionsDir()),
|
|
31
32
|
projectsDir: process.env.USAGEFLEET_PROJECTS || file.projectsDir || defaultProjectsDir(),
|
|
32
33
|
storePath: storePath(),
|
|
33
34
|
token,
|
package/dist/index.js
CHANGED
|
@@ -89,7 +89,7 @@ async function cmdWatch() {
|
|
|
89
89
|
const rawUpdate = positiveNumber(process.env.USAGEFLEET_UPDATE_INTERVAL, settings.updateInterval) ?? 6 * 60 * 60;
|
|
90
90
|
const updateInterval = Math.max(60, rawUpdate) * 1000;
|
|
91
91
|
let lastUpdateAt = 0;
|
|
92
|
-
const watching = [cfg.projectsDir, cfg.desktopDir, ...cfg.piDirs, cfg.jcodeDir].filter((d) => !!d);
|
|
92
|
+
const watching = [cfg.projectsDir, cfg.desktopDir, ...cfg.piDirs, cfg.jcodeDir, cfg.pjDir].filter((d) => !!d);
|
|
93
93
|
console.log(header(`watching every ${interval / 1000}s`));
|
|
94
94
|
console.log(hint(`${watching.map(tilde).join(' · ')} → ${host(ENDPOINT)}`));
|
|
95
95
|
console.log('');
|
|
@@ -192,7 +192,7 @@ async function cmdStatus() {
|
|
|
192
192
|
console.log('');
|
|
193
193
|
console.log(row('endpoint', host(ENDPOINT)));
|
|
194
194
|
console.log(row('device', `${state.deviceId} · token ${tokenFor(cfg, detectClaudeAccount()?.extId).slice(0, 8)}…`));
|
|
195
|
-
const watching = [cfg.projectsDir, cfg.desktopDir, ...cfg.piDirs, cfg.jcodeDir].filter((d) => !!d);
|
|
195
|
+
const watching = [cfg.projectsDir, cfg.desktopDir, ...cfg.piDirs, cfg.jcodeDir, cfg.pjDir].filter((d) => !!d);
|
|
196
196
|
for (const [i, dir] of watching.entries()) {
|
|
197
197
|
console.log(row(i === 0 ? 'watching' : '', tilde(dir)));
|
|
198
198
|
}
|
|
@@ -283,6 +283,7 @@ function cmdConfig() {
|
|
|
283
283
|
['desktopDir', 'USAGEFLEET_DESKTOP', 'override the Claude Desktop dir ("off" disables)'],
|
|
284
284
|
['piDir', 'USAGEFLEET_PI', 'pi session dirs · string or array; env comma-separated'],
|
|
285
285
|
['jcodeDir', 'USAGEFLEET_JCODE', 'override ~/.jcode/sessions ("off" disables)'],
|
|
286
|
+
['pjDir', 'USAGEFLEET_PJ', 'override ~/.pj/sessions ("off" disables)'],
|
|
286
287
|
['interval', 'USAGEFLEET_INTERVAL', 'watch interval seconds (default 15)'],
|
|
287
288
|
[
|
|
288
289
|
'limitsInterval',
|
package/dist/jcode.js
CHANGED
|
@@ -20,7 +20,7 @@ export function listJcodeSessions(dir) {
|
|
|
20
20
|
* (an interrupted one leaves a turn in both). So both are read and turns key on their
|
|
21
21
|
* id, and anything at or before `prev.uploadedThrough` was already sent.
|
|
22
22
|
*/
|
|
23
|
-
export function readJcodeSession(snapshotPath, prev) {
|
|
23
|
+
export function readJcodeSession(snapshotPath, source, prev) {
|
|
24
24
|
const journalPath = snapshotPath.replace(/\.json$/, '.journal.jsonl');
|
|
25
25
|
const mtimeMs = Math.max(statSync(snapshotPath).mtimeMs, existsSync(journalPath) ? statSync(journalPath).mtimeMs : 0);
|
|
26
26
|
if (prev?.mtimeMs === mtimeMs) {
|
|
@@ -40,7 +40,7 @@ export function readJcodeSession(snapshotPath, prev) {
|
|
|
40
40
|
const seen = new Set();
|
|
41
41
|
const records = [];
|
|
42
42
|
for (const [message, meta] of turns) {
|
|
43
|
-
const record = toRecord(message, meta, str(snapshot.id));
|
|
43
|
+
const record = toRecord(message, meta, str(snapshot.id), source);
|
|
44
44
|
if (!record || seen.has(record.uuid) || Date.parse(record.timestamp) <= uploadedThrough) {
|
|
45
45
|
continue;
|
|
46
46
|
}
|
|
@@ -69,7 +69,7 @@ function readJournal(path) {
|
|
|
69
69
|
return lines;
|
|
70
70
|
}
|
|
71
71
|
/** jcode's `token_usage` is Anthropic's usage block (`prompt_tokens` is their sum, left out). */
|
|
72
|
-
function toRecord(m, meta, sessionId) {
|
|
72
|
+
function toRecord(m, meta, sessionId, source) {
|
|
73
73
|
const u = m.token_usage;
|
|
74
74
|
const id = str(m.id);
|
|
75
75
|
const timestamp = str(m.timestamp);
|
|
@@ -96,9 +96,9 @@ function toRecord(m, meta, sessionId) {
|
|
|
96
96
|
requestId: null,
|
|
97
97
|
serviceTier: null,
|
|
98
98
|
sessionId,
|
|
99
|
-
source
|
|
99
|
+
source,
|
|
100
100
|
timestamp,
|
|
101
|
-
uuid:
|
|
101
|
+
uuid: `${source}:${id}`,
|
|
102
102
|
version: null,
|
|
103
103
|
};
|
|
104
104
|
}
|
package/dist/paths.js
CHANGED
|
@@ -68,6 +68,10 @@ function realDir(dir) {
|
|
|
68
68
|
export function defaultJcodeSessionsDir() {
|
|
69
69
|
return join(homedir(), '.jcode', 'sessions');
|
|
70
70
|
}
|
|
71
|
+
/** pj is a jcode fork that keeps its sessions in `~/.pj/sessions`; JCODE_HOME moves it too. */
|
|
72
|
+
export function defaultPjSessionsDir() {
|
|
73
|
+
return join(homedir(), '.pj', 'sessions');
|
|
74
|
+
}
|
|
71
75
|
/** pi's agent dir, the root for its sessions and extensions.
|
|
72
76
|
* PI_CODING_AGENT_DIR is pi's own relocation knob; unlike the service-side
|
|
73
77
|
* scan above, the guard installer runs from the user's shell where that env
|
package/dist/release.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by .github/workflows/release.yml.
|
|
2
|
-
export const RELEASE_VERSION = "1.2.
|
|
2
|
+
export const RELEASE_VERSION = "1.2.164";
|
package/dist/store.js
CHANGED