linkshell-cli 0.8.2 → 0.10.0
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 +11 -6
- package/dist/cli/src/commands/gateway.d.ts +2 -0
- package/dist/cli/src/commands/gateway.js +29 -0
- package/dist/cli/src/commands/gateway.js.map +1 -0
- package/dist/cli/src/commands/host.d.ts +4 -0
- package/dist/cli/src/commands/host.js +12 -2
- package/dist/cli/src/commands/host.js.map +1 -1
- package/dist/cli/src/commands/screen.d.ts +10 -0
- package/dist/cli/src/commands/screen.js +82 -74
- package/dist/cli/src/commands/screen.js.map +1 -1
- package/dist/cli/src/commands/setup.d.ts +11 -1
- package/dist/cli/src/commands/setup.js +102 -38
- package/dist/cli/src/commands/setup.js.map +1 -1
- package/dist/cli/src/index.js +28 -338
- package/dist/cli/src/index.js.map +1 -1
- package/dist/cli/src/utils/daemon.d.ts +0 -7
- package/dist/cli/src/utils/daemon.js +1 -18
- package/dist/cli/src/utils/daemon.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/dist/gateway/src/accounts.d.ts +6 -0
- package/dist/gateway/src/accounts.js +32 -0
- package/dist/gateway/src/accounts.js.map +1 -0
- package/dist/gateway/src/index.d.ts +4 -0
- package/dist/gateway/src/index.js +5 -0
- package/dist/gateway/src/index.js.map +1 -0
- package/dist/gateway/src/main.d.ts +1 -0
- package/dist/gateway/src/main.js +57 -0
- package/dist/gateway/src/main.js.map +1 -0
- package/dist/gateway/src/rate-limit.d.ts +22 -0
- package/dist/gateway/src/rate-limit.js +66 -0
- package/dist/gateway/src/rate-limit.js.map +1 -0
- package/dist/gateway/src/relay.d.ts +84 -0
- package/dist/gateway/src/relay.js +434 -0
- package/dist/gateway/src/relay.js.map +1 -0
- package/dist/gateway/src/serve.d.ts +34 -0
- package/dist/gateway/src/serve.js +102 -0
- package/dist/gateway/src/serve.js.map +1 -0
- package/dist/gateway/src/store.d.ts +35 -0
- package/dist/gateway/src/store.js +109 -0
- package/dist/gateway/src/store.js.map +1 -0
- package/dist/gateway/src/subscription.d.ts +18 -0
- package/dist/gateway/src/subscription.js +46 -0
- package/dist/gateway/src/subscription.js.map +1 -0
- package/dist/host/src/drivers/claude/transcript.d.ts +23 -23
- package/dist/host/src/fs.d.ts +3 -3
- package/dist/host/src/input.d.ts +112 -27
- package/dist/host/src/input.js +214 -144
- package/dist/host/src/input.js.map +1 -1
- package/dist/host/src/rpc/server.js +1 -1
- package/dist/host/src/rpc/server.js.map +1 -1
- package/dist/host/src/screen-pacer.d.ts +25 -11
- package/dist/host/src/screen-pacer.js +28 -6
- package/dist/host/src/screen-pacer.js.map +1 -1
- package/dist/host/src/screen-viewer.d.ts +5 -0
- package/dist/host/src/screen-viewer.js +1231 -55
- package/dist/host/src/screen-viewer.js.map +1 -1
- package/dist/host/src/screen.d.ts +19 -10
- package/dist/host/src/screen.js +314 -108
- package/dist/host/src/screen.js.map +1 -1
- package/dist/host/src/terminals.d.ts +1 -1
- package/dist/host/src/terminals.js +1 -0
- package/dist/host/src/terminals.js.map +1 -1
- package/dist/wire/src/model.d.ts +6 -6
- package/dist/wire/src/relay.d.ts +8 -8
- package/dist/wire/src/rpc.d.ts +818 -818
- package/dist/wire/src/updates.d.ts +18 -18
- package/package.json +6 -15
- package/src/commands/gateway.ts +31 -0
- package/src/commands/host.ts +15 -2
- package/src/commands/screen.ts +78 -72
- package/src/commands/setup.ts +102 -60
- package/src/index.ts +29 -433
- package/src/utils/daemon.ts +2 -27
- package/dist/cli/src/config.d.ts +0 -14
- package/dist/cli/src/config.js +0 -23
- package/dist/cli/src/config.js.map +0 -1
- package/dist/cli/src/machine-id.d.ts +0 -6
- package/dist/cli/src/machine-id.js +0 -50
- package/dist/cli/src/machine-id.js.map +0 -1
- package/dist/cli/src/providers.d.ts +0 -13
- package/dist/cli/src/providers.js +0 -77
- package/dist/cli/src/providers.js.map +0 -1
- package/dist/cli/src/runtime/acp/acp-client.d.ts +0 -128
- package/dist/cli/src/runtime/acp/acp-client.js +0 -430
- package/dist/cli/src/runtime/acp/acp-client.js.map +0 -1
- package/dist/cli/src/runtime/acp/agent-process-discovery.d.ts +0 -48
- package/dist/cli/src/runtime/acp/agent-process-discovery.js +0 -278
- package/dist/cli/src/runtime/acp/agent-process-discovery.js.map +0 -1
- package/dist/cli/src/runtime/acp/agent-session.d.ts +0 -62
- package/dist/cli/src/runtime/acp/agent-session.js +0 -1081
- package/dist/cli/src/runtime/acp/agent-session.js.map +0 -1
- package/dist/cli/src/runtime/acp/agent-workspace.d.ts +0 -311
- package/dist/cli/src/runtime/acp/agent-workspace.js +0 -6083
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +0 -1
- package/dist/cli/src/runtime/acp/claude-sdk-client.d.ts +0 -121
- package/dist/cli/src/runtime/acp/claude-sdk-client.js +0 -1147
- package/dist/cli/src/runtime/acp/claude-sdk-client.js.map +0 -1
- package/dist/cli/src/runtime/acp/claude-stream-json-client.d.ts +0 -53
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js +0 -552
- package/dist/cli/src/runtime/acp/claude-stream-json-client.js.map +0 -1
- package/dist/cli/src/runtime/acp/json-rpc.d.ts +0 -22
- package/dist/cli/src/runtime/acp/json-rpc.js +0 -160
- package/dist/cli/src/runtime/acp/json-rpc.js.map +0 -1
- package/dist/cli/src/runtime/acp/provider-resolver.d.ts +0 -16
- package/dist/cli/src/runtime/acp/provider-resolver.js +0 -132
- package/dist/cli/src/runtime/acp/provider-resolver.js.map +0 -1
- package/dist/cli/src/runtime/bridge-session.d.ts +0 -97
- package/dist/cli/src/runtime/bridge-session.js +0 -1364
- package/dist/cli/src/runtime/bridge-session.js.map +0 -1
- package/dist/cli/src/runtime/hook-command.d.ts +0 -9
- package/dist/cli/src/runtime/hook-command.js +0 -80
- package/dist/cli/src/runtime/hook-command.js.map +0 -1
- package/dist/cli/src/runtime/screen-fallback.d.ts +0 -22
- package/dist/cli/src/runtime/screen-fallback.js +0 -202
- package/dist/cli/src/runtime/screen-fallback.js.map +0 -1
- package/dist/cli/src/runtime/screen-share.d.ts +0 -34
- package/dist/cli/src/runtime/screen-share.js +0 -376
- package/dist/cli/src/runtime/screen-share.js.map +0 -1
- package/dist/cli/src/runtime/scrollback.d.ts +0 -11
- package/dist/cli/src/runtime/scrollback.js +0 -33
- package/dist/cli/src/runtime/scrollback.js.map +0 -1
- package/dist/cli/src/runtime/usage-report.d.ts +0 -34
- package/dist/cli/src/runtime/usage-report.js +0 -332
- package/dist/cli/src/runtime/usage-report.js.map +0 -1
- package/dist/cli/src/utils/keep-awake.d.ts +0 -6
- package/dist/cli/src/utils/keep-awake.js +0 -48
- package/dist/cli/src/utils/keep-awake.js.map +0 -1
- package/dist/cli/src/utils/lan-ip.d.ts +0 -9
- package/dist/cli/src/utils/lan-ip.js +0 -61
- package/dist/cli/src/utils/lan-ip.js.map +0 -1
- package/dist/host/src/input-helper.d.ts +0 -1
- package/dist/host/src/input-helper.js +0 -564
- package/dist/host/src/input-helper.js.map +0 -1
- package/dist/shared-protocol/src/index.d.ts +0 -17029
- package/dist/shared-protocol/src/index.js +0 -1064
- package/dist/shared-protocol/src/index.js.map +0 -1
- package/scripts/copy-web.mjs +0 -34
- package/src/config.ts +0 -36
- package/src/machine-id.ts +0 -61
- package/src/providers.ts +0 -97
- package/src/runtime/acp/acp-client.ts +0 -521
- package/src/runtime/acp/agent-process-discovery.ts +0 -308
- package/src/runtime/acp/agent-session.ts +0 -1186
- package/src/runtime/acp/agent-workspace.ts +0 -6590
- package/src/runtime/acp/claude-sdk-client.ts +0 -1221
- package/src/runtime/acp/claude-stream-json-client.ts +0 -633
- package/src/runtime/acp/json-rpc.ts +0 -184
- package/src/runtime/acp/provider-resolver.ts +0 -154
- package/src/runtime/bridge-session.ts +0 -1549
- package/src/runtime/hook-command.ts +0 -73
- package/src/runtime/screen-fallback.ts +0 -235
- package/src/runtime/screen-share.ts +0 -426
- package/src/runtime/scrollback.ts +0 -43
- package/src/runtime/usage-report.ts +0 -342
- package/src/utils/keep-awake.ts +0 -61
- package/src/utils/lan-ip.ts +0 -61
- package/web/assets/FileBrowser-wOAfY-xj.js +0 -2
- package/web/assets/PortPreview-Cbvv7yzA.js +0 -2
- package/web/assets/TerminalPanel-CTSklkct.js +0 -1
- package/web/assets/UsageDashboard-CJ1AsNmd.js +0 -1
- package/web/assets/index-BsnDaeCt.css +0 -33
- package/web/assets/index-q85psYZ5.js +0 -36
- package/web/assets/vendor-highlight-NXWAAyIv.js +0 -5
- package/web/assets/vendor-react-M7xG3qiw.js +0 -49
- package/web/assets/vendor-xterm-D15THcI4.js +0 -9
- package/web/index.html +0 -37
- package/web/logos/claude.png +0 -0
- package/web/logos/codex.png +0 -0
- package/web/logos/copilot.png +0 -0
- package/web/logos/gemini.png +0 -0
- package/web/logos/linkshell-1024.png +0 -0
- package/web/logos/linkshell-splash.png +0 -0
- package/web/logos/linkshell.png +0 -0
|
@@ -1,332 +0,0 @@
|
|
|
1
|
-
// Host-side usage aggregator. Scans local agent transcripts on disk and rolls
|
|
2
|
-
// them up into the dimensions a usage dashboard needs (cumulative total, peak
|
|
3
|
-
// day, activity heatmap by day, streaks, longest task). Fully DECOUPLED from any
|
|
4
|
-
// live LinkShell turn — it reads what the agents already wrote to disk, so
|
|
5
|
-
// history and externally-started sessions (any process, not just LinkShell) are
|
|
6
|
-
// all counted, the same way ccusage / vibe-usage / CodeIsland work.
|
|
7
|
-
//
|
|
8
|
-
// Counting convention (matches ccusage): sum usage PER API CALL — context is
|
|
9
|
-
// re-counted every turn, which is why totals reach billions. This is the usage
|
|
10
|
-
// view, the opposite of the single-snapshot "current context occupancy" meter.
|
|
11
|
-
import { readdirSync, readFileSync, statSync, existsSync } from "node:fs";
|
|
12
|
-
import { homedir } from "node:os";
|
|
13
|
-
import { join, basename } from "node:path";
|
|
14
|
-
function emptyTotals() {
|
|
15
|
-
return {
|
|
16
|
-
inputTokens: 0,
|
|
17
|
-
outputTokens: 0,
|
|
18
|
-
cacheReadTokens: 0,
|
|
19
|
-
cacheWriteTokens: 0,
|
|
20
|
-
totalTokens: 0,
|
|
21
|
-
calls: 0,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
function dayKeyOf(ts) {
|
|
25
|
-
const d = new Date(ts);
|
|
26
|
-
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}-${String(d.getDate()).padStart(2, "0")}`;
|
|
27
|
-
}
|
|
28
|
-
class Accumulator {
|
|
29
|
-
totals = emptyTotals();
|
|
30
|
-
day = new Map();
|
|
31
|
-
hw = new Map(); // "weekday:hour" → tokens
|
|
32
|
-
tool = new Map();
|
|
33
|
-
model = new Map();
|
|
34
|
-
project = new Map();
|
|
35
|
-
// Per-session activity timestamps, for longest-continuous-task duration.
|
|
36
|
-
sessionTimes = new Map();
|
|
37
|
-
bump(map, key, s, tokens) {
|
|
38
|
-
let t = map.get(key);
|
|
39
|
-
if (!t) {
|
|
40
|
-
t = emptyTotals();
|
|
41
|
-
map.set(key, t);
|
|
42
|
-
}
|
|
43
|
-
t.inputTokens += s.input;
|
|
44
|
-
t.outputTokens += s.output;
|
|
45
|
-
t.cacheReadTokens += s.cacheRead;
|
|
46
|
-
t.cacheWriteTokens += s.cacheWrite;
|
|
47
|
-
t.totalTokens += tokens;
|
|
48
|
-
t.calls += 1;
|
|
49
|
-
}
|
|
50
|
-
add(s) {
|
|
51
|
-
const tokens = s.input + s.output + s.cacheRead + s.cacheWrite;
|
|
52
|
-
if (tokens <= 0)
|
|
53
|
-
return;
|
|
54
|
-
this.totals.inputTokens += s.input;
|
|
55
|
-
this.totals.outputTokens += s.output;
|
|
56
|
-
this.totals.cacheReadTokens += s.cacheRead;
|
|
57
|
-
this.totals.cacheWriteTokens += s.cacheWrite;
|
|
58
|
-
this.totals.totalTokens += tokens;
|
|
59
|
-
this.totals.calls += 1;
|
|
60
|
-
this.bump(this.day, dayKeyOf(s.ts), s, tokens);
|
|
61
|
-
const d = new Date(s.ts);
|
|
62
|
-
const hwKey = `${d.getDay()}:${d.getHours()}`;
|
|
63
|
-
this.hw.set(hwKey, (this.hw.get(hwKey) ?? 0) + tokens);
|
|
64
|
-
this.bump(this.tool, s.tool, s, tokens);
|
|
65
|
-
this.bump(this.model, s.model || "(unknown)", s, tokens);
|
|
66
|
-
this.bump(this.project, s.project || "(unknown)", s, tokens);
|
|
67
|
-
const times = this.sessionTimes.get(s.sessionId);
|
|
68
|
-
if (!times)
|
|
69
|
-
this.sessionTimes.set(s.sessionId, [s.ts]);
|
|
70
|
-
else
|
|
71
|
-
times.push(s.ts);
|
|
72
|
-
}
|
|
73
|
-
toBuckets(map) {
|
|
74
|
-
return [...map.entries()]
|
|
75
|
-
.map(([key, t]) => ({ key, ...t }))
|
|
76
|
-
.sort((a, b) => b.totalTokens - a.totalTokens);
|
|
77
|
-
}
|
|
78
|
-
finish(sessions, generatedAt) {
|
|
79
|
-
const byDay = [...this.day.entries()]
|
|
80
|
-
.map(([key, t]) => ({ key, ...t }))
|
|
81
|
-
.sort((a, b) => a.key.localeCompare(b.key));
|
|
82
|
-
const peakDayTokens = byDay.reduce((m, d) => Math.max(m, d.totalTokens), 0);
|
|
83
|
-
// Longest CONTINUOUS work segment across all sessions. A Claude session
|
|
84
|
-
// file can be resumed days later, so first→last would absurdly count idle
|
|
85
|
-
// days. Instead, sort each session's call timestamps and split whenever the
|
|
86
|
-
// gap exceeds IDLE_SPLIT_MS; the longest unbroken segment is the task length.
|
|
87
|
-
const IDLE_SPLIT_MS = 30 * 60_000;
|
|
88
|
-
let longestTaskMs = 0;
|
|
89
|
-
for (const times of this.sessionTimes.values()) {
|
|
90
|
-
if (times.length === 0)
|
|
91
|
-
continue;
|
|
92
|
-
times.sort((a, b) => a - b);
|
|
93
|
-
let segStart = times[0];
|
|
94
|
-
let prev = times[0];
|
|
95
|
-
for (let i = 1; i < times.length; i++) {
|
|
96
|
-
const cur = times[i];
|
|
97
|
-
if (cur - prev > IDLE_SPLIT_MS) {
|
|
98
|
-
longestTaskMs = Math.max(longestTaskMs, prev - segStart);
|
|
99
|
-
segStart = cur;
|
|
100
|
-
}
|
|
101
|
-
prev = cur;
|
|
102
|
-
}
|
|
103
|
-
longestTaskMs = Math.max(longestTaskMs, prev - segStart);
|
|
104
|
-
}
|
|
105
|
-
const { currentStreakDays, longestStreakDays } = computeStreaks(byDay.map((d) => d.key), generatedAt);
|
|
106
|
-
const byHourWeekday = [...this.hw.entries()].map(([k, tokens]) => {
|
|
107
|
-
const parts = k.split(":");
|
|
108
|
-
return { weekday: Number(parts[0]), hour: Number(parts[1]), tokens };
|
|
109
|
-
});
|
|
110
|
-
return {
|
|
111
|
-
totals: this.totals,
|
|
112
|
-
sessions,
|
|
113
|
-
peakDayTokens,
|
|
114
|
-
longestTaskMs,
|
|
115
|
-
currentStreakDays,
|
|
116
|
-
longestStreakDays,
|
|
117
|
-
byDay,
|
|
118
|
-
byHourWeekday,
|
|
119
|
-
byTool: this.toBuckets(this.tool),
|
|
120
|
-
byModel: this.toBuckets(this.model),
|
|
121
|
-
byProject: this.toBuckets(this.project),
|
|
122
|
-
generatedAt,
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
// Streaks over a sorted set of active day-keys (YYYY-MM-DD). Current streak
|
|
127
|
-
// counts back from today (or yesterday — a gap of "today not yet active" still
|
|
128
|
-
// keeps an unbroken run alive). Uses UTC-noon to step days, dodging DST edges.
|
|
129
|
-
function computeStreaks(dayKeys, now) {
|
|
130
|
-
if (dayKeys.length === 0)
|
|
131
|
-
return { currentStreakDays: 0, longestStreakDays: 0 };
|
|
132
|
-
const set = new Set(dayKeys);
|
|
133
|
-
const dayMs = 86_400_000;
|
|
134
|
-
const toKey = (ms) => dayKeyOf(ms);
|
|
135
|
-
// Longest run.
|
|
136
|
-
let longest = 1;
|
|
137
|
-
let run = 1;
|
|
138
|
-
const sorted = [...dayKeys].sort();
|
|
139
|
-
for (let i = 1; i < sorted.length; i++) {
|
|
140
|
-
const prev = new Date(sorted[i - 1] + "T12:00:00").getTime();
|
|
141
|
-
const cur = new Date(sorted[i] + "T12:00:00").getTime();
|
|
142
|
-
const gapDays = Math.round((cur - prev) / dayMs);
|
|
143
|
-
if (gapDays === 1)
|
|
144
|
-
run += 1;
|
|
145
|
-
else
|
|
146
|
-
run = 1;
|
|
147
|
-
longest = Math.max(longest, run);
|
|
148
|
-
}
|
|
149
|
-
// Current run: walk backwards from today; if today isn't active, allow
|
|
150
|
-
// starting from yesterday (today simply hasn't happened yet).
|
|
151
|
-
let cursor = new Date(toKey(now) + "T12:00:00").getTime();
|
|
152
|
-
if (!set.has(toKey(cursor)))
|
|
153
|
-
cursor -= dayMs; // today inactive → start at yesterday
|
|
154
|
-
let current = 0;
|
|
155
|
-
while (set.has(toKey(cursor))) {
|
|
156
|
-
current += 1;
|
|
157
|
-
cursor -= dayMs;
|
|
158
|
-
}
|
|
159
|
-
return { currentStreakDays: current, longestStreakDays: longest };
|
|
160
|
-
}
|
|
161
|
-
function parseTs(value) {
|
|
162
|
-
if (typeof value === "number" && Number.isFinite(value)) {
|
|
163
|
-
return value > 10_000_000_000 ? value : value * 1000;
|
|
164
|
-
}
|
|
165
|
-
if (typeof value === "string" && value.trim()) {
|
|
166
|
-
const p = Date.parse(value);
|
|
167
|
-
return Number.isNaN(p) ? undefined : p;
|
|
168
|
-
}
|
|
169
|
-
return undefined;
|
|
170
|
-
}
|
|
171
|
-
function walkJsonl(dir, onFile) {
|
|
172
|
-
let entries;
|
|
173
|
-
try {
|
|
174
|
-
entries = readdirSync(dir);
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
for (const entry of entries) {
|
|
180
|
-
const full = join(dir, entry);
|
|
181
|
-
let st;
|
|
182
|
-
try {
|
|
183
|
-
st = statSync(full);
|
|
184
|
-
}
|
|
185
|
-
catch {
|
|
186
|
-
continue;
|
|
187
|
-
}
|
|
188
|
-
if (st.isDirectory())
|
|
189
|
-
walkJsonl(full, onFile);
|
|
190
|
-
else if (entry.endsWith(".jsonl"))
|
|
191
|
-
onFile(full);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
// Claude: ~/.claude/projects/**/*.jsonl — each assistant line carries
|
|
195
|
-
// message.usage. Skip <synthetic> (internal, no real usage).
|
|
196
|
-
function ingestClaude(acc) {
|
|
197
|
-
const root = join(homedir(), ".claude", "projects");
|
|
198
|
-
if (!existsSync(root))
|
|
199
|
-
return 0;
|
|
200
|
-
let sessions = 0;
|
|
201
|
-
walkJsonl(root, (path) => {
|
|
202
|
-
sessions += 1;
|
|
203
|
-
const sessionId = basename(path, ".jsonl");
|
|
204
|
-
let text;
|
|
205
|
-
try {
|
|
206
|
-
text = readFileSync(path, "utf8");
|
|
207
|
-
}
|
|
208
|
-
catch {
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
let fileCwd = "";
|
|
212
|
-
for (const line of text.split(/\r?\n/)) {
|
|
213
|
-
if (!line.trim())
|
|
214
|
-
continue;
|
|
215
|
-
let o;
|
|
216
|
-
try {
|
|
217
|
-
o = JSON.parse(line);
|
|
218
|
-
}
|
|
219
|
-
catch {
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
222
|
-
if (typeof o?.cwd === "string" && !fileCwd)
|
|
223
|
-
fileCwd = o.cwd;
|
|
224
|
-
if (o?.type !== "assistant")
|
|
225
|
-
continue;
|
|
226
|
-
const msg = o.message;
|
|
227
|
-
const usage = msg?.usage;
|
|
228
|
-
const model = typeof msg?.model === "string" ? msg.model : "";
|
|
229
|
-
if (!usage || model === "<synthetic>" || !model)
|
|
230
|
-
continue;
|
|
231
|
-
const ts = parseTs(o.timestamp);
|
|
232
|
-
if (ts === undefined)
|
|
233
|
-
continue;
|
|
234
|
-
acc.add({
|
|
235
|
-
ts,
|
|
236
|
-
sessionId,
|
|
237
|
-
tool: "claude-code",
|
|
238
|
-
model,
|
|
239
|
-
project: basename(o.cwd || fileCwd || "(unknown)"),
|
|
240
|
-
input: usage.input_tokens || 0,
|
|
241
|
-
output: usage.output_tokens || 0,
|
|
242
|
-
cacheRead: usage.cache_read_input_tokens || 0,
|
|
243
|
-
cacheWrite: usage.cache_creation_input_tokens || 0,
|
|
244
|
-
});
|
|
245
|
-
}
|
|
246
|
-
});
|
|
247
|
-
return sessions;
|
|
248
|
-
}
|
|
249
|
-
// Codex: ~/.codex/sessions/**/rollout-*.jsonl — token_count events carry
|
|
250
|
-
// info.last_token_usage (per-turn delta; total_token_usage is cumulative and
|
|
251
|
-
// would double-count). cached_input_tokens is a subset of input_tokens.
|
|
252
|
-
function ingestCodex(acc) {
|
|
253
|
-
const root = join(homedir(), ".codex", "sessions");
|
|
254
|
-
if (!existsSync(root))
|
|
255
|
-
return 0;
|
|
256
|
-
let sessions = 0;
|
|
257
|
-
walkJsonl(root, (path) => {
|
|
258
|
-
if (!basename(path).startsWith("rollout-"))
|
|
259
|
-
return;
|
|
260
|
-
sessions += 1;
|
|
261
|
-
const sessionId = basename(path, ".jsonl");
|
|
262
|
-
let text;
|
|
263
|
-
try {
|
|
264
|
-
text = readFileSync(path, "utf8");
|
|
265
|
-
}
|
|
266
|
-
catch {
|
|
267
|
-
return;
|
|
268
|
-
}
|
|
269
|
-
let model = "";
|
|
270
|
-
let cwd = "";
|
|
271
|
-
for (const line of text.split(/\r?\n/)) {
|
|
272
|
-
if (!line.trim())
|
|
273
|
-
continue;
|
|
274
|
-
let o;
|
|
275
|
-
try {
|
|
276
|
-
o = JSON.parse(line);
|
|
277
|
-
}
|
|
278
|
-
catch {
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
281
|
-
const p = o?.payload ?? {};
|
|
282
|
-
const type = p.type ?? o?.type;
|
|
283
|
-
if (type === "session_meta") {
|
|
284
|
-
if (typeof p.cwd === "string")
|
|
285
|
-
cwd = p.cwd;
|
|
286
|
-
if (typeof p.model === "string")
|
|
287
|
-
model = p.model;
|
|
288
|
-
continue;
|
|
289
|
-
}
|
|
290
|
-
if (type === "turn_context") {
|
|
291
|
-
if (typeof p.model === "string")
|
|
292
|
-
model = p.model;
|
|
293
|
-
continue;
|
|
294
|
-
}
|
|
295
|
-
if (type !== "token_count")
|
|
296
|
-
continue;
|
|
297
|
-
const last = p.info?.last_token_usage;
|
|
298
|
-
if (!last)
|
|
299
|
-
continue;
|
|
300
|
-
const ts = parseTs(o.timestamp);
|
|
301
|
-
if (ts === undefined)
|
|
302
|
-
continue;
|
|
303
|
-
const cacheRead = last.cached_input_tokens || 0;
|
|
304
|
-
const rawInput = last.input_tokens || 0;
|
|
305
|
-
acc.add({
|
|
306
|
-
ts,
|
|
307
|
-
sessionId,
|
|
308
|
-
tool: "codex",
|
|
309
|
-
model: model || "gpt-5",
|
|
310
|
-
project: basename(cwd || "(unknown)"),
|
|
311
|
-
input: Math.max(0, rawInput - cacheRead),
|
|
312
|
-
output: (last.output_tokens || 0) + (last.reasoning_output_tokens || 0),
|
|
313
|
-
cacheRead,
|
|
314
|
-
cacheWrite: 0,
|
|
315
|
-
});
|
|
316
|
-
}
|
|
317
|
-
});
|
|
318
|
-
return sessions;
|
|
319
|
-
}
|
|
320
|
-
let _cachedReport = null;
|
|
321
|
-
let _cachedAt = 0;
|
|
322
|
-
export function aggregateUsage() {
|
|
323
|
-
const now = Date.now();
|
|
324
|
-
if (_cachedReport && now - _cachedAt < 60_000)
|
|
325
|
-
return _cachedReport;
|
|
326
|
-
const acc = new Accumulator();
|
|
327
|
-
const sessions = ingestClaude(acc) + ingestCodex(acc);
|
|
328
|
-
_cachedReport = acc.finish(sessions, now);
|
|
329
|
-
_cachedAt = now;
|
|
330
|
-
return _cachedReport;
|
|
331
|
-
}
|
|
332
|
-
//# sourceMappingURL=usage-report.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"usage-report.js","sourceRoot":"","sources":["../../../../src/runtime/usage-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { platform } from "node:os";
|
|
3
|
-
export function shouldKeepAwake(optionEnabled) {
|
|
4
|
-
if (process.env.LINKSHELL_KEEP_AWAKE === "0")
|
|
5
|
-
return false;
|
|
6
|
-
if (platform() !== "darwin")
|
|
7
|
-
return false;
|
|
8
|
-
return optionEnabled !== false;
|
|
9
|
-
}
|
|
10
|
-
export function startKeepAwake() {
|
|
11
|
-
if (platform() !== "darwin") {
|
|
12
|
-
return { enabled: false, stop: () => { } };
|
|
13
|
-
}
|
|
14
|
-
let child;
|
|
15
|
-
let stopping = false;
|
|
16
|
-
try {
|
|
17
|
-
child = spawn("caffeinate", ["-i", "-w", String(process.pid)], {
|
|
18
|
-
stdio: "ignore",
|
|
19
|
-
detached: false,
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
process.stderr.write(`[bridge] keep-awake unavailable: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
24
|
-
return { enabled: false, stop: () => { } };
|
|
25
|
-
}
|
|
26
|
-
child.on("error", (error) => {
|
|
27
|
-
if (stopping)
|
|
28
|
-
return;
|
|
29
|
-
process.stderr.write(`[bridge] keep-awake unavailable: ${error.message}\n`);
|
|
30
|
-
});
|
|
31
|
-
child.on("exit", (code, signal) => {
|
|
32
|
-
if (stopping)
|
|
33
|
-
return;
|
|
34
|
-
process.stderr.write(`[bridge] keep-awake stopped unexpectedly (code=${code ?? "null"}, signal=${signal ?? "null"})\n`);
|
|
35
|
-
});
|
|
36
|
-
process.stderr.write("[bridge] keep-awake enabled (macOS idle sleep prevention)\n");
|
|
37
|
-
return {
|
|
38
|
-
enabled: true,
|
|
39
|
-
stop: () => {
|
|
40
|
-
stopping = true;
|
|
41
|
-
if (child && !child.killed) {
|
|
42
|
-
child.kill("SIGTERM");
|
|
43
|
-
}
|
|
44
|
-
child = undefined;
|
|
45
|
-
},
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
//# sourceMappingURL=keep-awake.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"keep-awake.js","sourceRoot":"","sources":["../../../../src/utils/keep-awake.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAOnC,MAAM,UAAU,eAAe,CAAC,aAAkC;IAChE,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAC3D,IAAI,QAAQ,EAAE,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1C,OAAO,aAAa,KAAK,KAAK,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,IAAI,QAAQ,EAAE,KAAK,QAAQ,EAAE,CAAC;QAC5B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,IAAI,KAA+B,CAAC;IACpC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,IAAI,CAAC;QACH,KAAK,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE;YAC7D,KAAK,EAAE,QAAQ;YACf,QAAQ,EAAE,KAAK;SAChB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,oCAAoC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAC/F,CAAC;QACF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC,EAAE,CAAC;IAC5C,CAAC;IAED,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;QAC1B,IAAI,QAAQ;YAAE,OAAO;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,KAAK,CAAC,OAAO,IAAI,CAAC,CAAC;IAC9E,CAAC,CAAC,CAAC;IAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE;QAChC,IAAI,QAAQ;YAAE,OAAO;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,kDAAkD,IAAI,IAAI,MAAM,YAAY,MAAM,IAAI,MAAM,KAAK,CAClG,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,6DAA6D,CAC9D,CAAC;IAEF,OAAO;QACL,OAAO,EAAE,IAAI;QACb,IAAI,EAAE,GAAG,EAAE;YACT,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACxB,CAAC;YACD,KAAK,GAAG,SAAS,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Get the best non-internal IPv4 address (LAN IP).
|
|
3
|
-
*
|
|
4
|
-
* macOS often exposes virtual bridge/VPN interfaces before Wi-Fi/Ethernet,
|
|
5
|
-
* which can produce QR codes that phones cannot reach. Prefer real LAN
|
|
6
|
-
* interfaces and ignore virtual point-to-point bridges.
|
|
7
|
-
* Falls back to 127.0.0.1 if none found.
|
|
8
|
-
*/
|
|
9
|
-
export declare function getLanIp(): string;
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { networkInterfaces } from "node:os";
|
|
2
|
-
const IGNORED_INTERFACE_PATTERNS = [
|
|
3
|
-
/^lo\d*$/i,
|
|
4
|
-
/^bridge\d*$/i,
|
|
5
|
-
/^utun\d*$/i,
|
|
6
|
-
/^awdl\d*$/i,
|
|
7
|
-
/^llw\d*$/i,
|
|
8
|
-
/^vmnet\d*$/i,
|
|
9
|
-
/^vboxnet\d*$/i,
|
|
10
|
-
/^docker\d*$/i,
|
|
11
|
-
/^br-/i,
|
|
12
|
-
/^tun\d*$/i,
|
|
13
|
-
/^tap\d*$/i,
|
|
14
|
-
];
|
|
15
|
-
function isIgnoredInterface(name) {
|
|
16
|
-
return IGNORED_INTERFACE_PATTERNS.some((pattern) => pattern.test(name));
|
|
17
|
-
}
|
|
18
|
-
function isUsableIpv4(address) {
|
|
19
|
-
const parts = address.split(".").map((part) => Number(part));
|
|
20
|
-
if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) {
|
|
21
|
-
return false;
|
|
22
|
-
}
|
|
23
|
-
const [a, b] = parts;
|
|
24
|
-
if (a === 0 || a === 127 || a === 169 && b === 254)
|
|
25
|
-
return false;
|
|
26
|
-
if (a === 198 && (b === 18 || b === 19))
|
|
27
|
-
return false;
|
|
28
|
-
return true;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Get the best non-internal IPv4 address (LAN IP).
|
|
32
|
-
*
|
|
33
|
-
* macOS often exposes virtual bridge/VPN interfaces before Wi-Fi/Ethernet,
|
|
34
|
-
* which can produce QR codes that phones cannot reach. Prefer real LAN
|
|
35
|
-
* interfaces and ignore virtual point-to-point bridges.
|
|
36
|
-
* Falls back to 127.0.0.1 if none found.
|
|
37
|
-
*/
|
|
38
|
-
export function getLanIp() {
|
|
39
|
-
const nets = networkInterfaces();
|
|
40
|
-
const candidates = [];
|
|
41
|
-
for (const name of Object.keys(nets)) {
|
|
42
|
-
if (isIgnoredInterface(name))
|
|
43
|
-
continue;
|
|
44
|
-
const addrs = nets[name];
|
|
45
|
-
if (!addrs)
|
|
46
|
-
continue;
|
|
47
|
-
for (const addr of addrs) {
|
|
48
|
-
if (addr.family !== "IPv4" || addr.internal || !isUsableIpv4(addr.address))
|
|
49
|
-
continue;
|
|
50
|
-
const score = /^en\d+$/i.test(name) ? 100 :
|
|
51
|
-
/^(eth|wlan|wifi|wi-fi)/i.test(name) ? 90 :
|
|
52
|
-
10;
|
|
53
|
-
candidates.push({ address: addr.address, score });
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
candidates.sort((a, b) => b.score - a.score);
|
|
57
|
-
if (candidates[0])
|
|
58
|
-
return candidates[0].address;
|
|
59
|
-
return "127.0.0.1";
|
|
60
|
-
}
|
|
61
|
-
//# sourceMappingURL=lan-ip.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lan-ip.js","sourceRoot":"","sources":["../../../../src/utils/lan-ip.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,0BAA0B,GAAG;IACjC,UAAU;IACV,cAAc;IACd,YAAY;IACZ,YAAY;IACZ,WAAW;IACX,aAAa;IACb,eAAe;IACf,cAAc;IACd,OAAO;IACP,WAAW;IACX,WAAW;CACZ,CAAC;AAEF,SAAS,kBAAkB,CAAC,IAAY;IACtC,OAAO,0BAA0B,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1E,CAAC;AAED,SAAS,YAAY,CAAC,OAAe;IACnC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;IAC7D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;QAClG,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IACjE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAAE,OAAO,KAAK,CAAC;IACtD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,QAAQ;IACtB,MAAM,IAAI,GAAG,iBAAiB,EAAE,CAAC;IACjC,MAAM,UAAU,GAA8C,EAAE,CAAC;IAEjE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,IAAI,kBAAkB,CAAC,IAAI,CAAC;YAAE,SAAS;QACvC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC;gBAAE,SAAS;YACrF,MAAM,KAAK,GACT,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC7B,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;oBAC3C,EAAE,CAAC;YACL,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC;IAED,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAC7C,IAAI,UAAU,CAAC,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAChD,OAAO,WAAW,CAAC;AACrB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const INPUT_HELPER_SOURCE: string;
|