linkshell-cli 0.5.16 → 0.5.17
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/src/runtime/acp/agent-workspace.d.ts +1 -0
- package/dist/cli/src/runtime/acp/agent-workspace.js +23 -17
- package/dist/cli/src/runtime/acp/agent-workspace.js.map +1 -1
- package/dist/cli/src/runtime/usage-report.js +8 -1
- package/dist/cli/src/runtime/usage-report.js.map +1 -1
- package/dist/cli/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/runtime/acp/agent-workspace.ts +23 -16
- package/src/runtime/usage-report.ts +8 -1
- package/web/assets/{index-CpannLtQ.js → index-B4Wh4MQf.js} +37 -37
- package/web/assets/{index-Cxv9bt2l.css → index-CLbwsKyd.css} +1 -1
- package/web/index.html +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linkshell-cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.17",
|
|
4
4
|
"description": "Remote terminal bridge for Claude Code / Codex / Gemini / Copilot — control from your phone",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"qrcode-terminal": "^0.12.0",
|
|
37
37
|
"ws": "^8.18.1",
|
|
38
38
|
"zod": "^3.24.3",
|
|
39
|
-
"@linkshell/
|
|
40
|
-
"@linkshell/
|
|
39
|
+
"@linkshell/protocol": "0.4.7",
|
|
40
|
+
"@linkshell/gateway": "0.4.36"
|
|
41
41
|
},
|
|
42
42
|
"optionalDependencies": {
|
|
43
43
|
"@anthropic-ai/claude-agent-sdk": "^0.2.128",
|
|
@@ -1709,6 +1709,7 @@ export class AgentWorkspaceProxy {
|
|
|
1709
1709
|
case "agent.v2.capabilities.request":
|
|
1710
1710
|
await this.initialize();
|
|
1711
1711
|
this.sendCapabilities();
|
|
1712
|
+
this.sendUsageReport();
|
|
1712
1713
|
break;
|
|
1713
1714
|
case "agent.v2.conversation.open": {
|
|
1714
1715
|
const payload = parseTypedPayload("agent.v2.conversation.open", envelope.payload);
|
|
@@ -1775,22 +1776,7 @@ export class AgentWorkspaceProxy {
|
|
|
1775
1776
|
break;
|
|
1776
1777
|
}
|
|
1777
1778
|
case "agent.v2.usage.request": {
|
|
1778
|
-
|
|
1779
|
-
// scan is synchronous (~3s over a large corpus); acceptable for an
|
|
1780
|
-
// explicit, on-demand dashboard open. Errors must never break the
|
|
1781
|
-
// session, so swallow + send an empty report.
|
|
1782
|
-
try {
|
|
1783
|
-
const report = aggregateUsage();
|
|
1784
|
-
this.input.send(createEnvelope({
|
|
1785
|
-
type: "agent.v2.usage.report",
|
|
1786
|
-
sessionId: this.input.sessionId,
|
|
1787
|
-
payload: report,
|
|
1788
|
-
}));
|
|
1789
|
-
} catch (error) {
|
|
1790
|
-
if (this.input.verbose) {
|
|
1791
|
-
process.stderr.write(`[agent:v2] usage aggregation failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
1792
|
-
}
|
|
1793
|
-
}
|
|
1779
|
+
this.sendUsageReport();
|
|
1794
1780
|
break;
|
|
1795
1781
|
}
|
|
1796
1782
|
case "agent.v2.prompt": {
|
|
@@ -4282,6 +4268,27 @@ export class AgentWorkspaceProxy {
|
|
|
4282
4268
|
}
|
|
4283
4269
|
return firstString(raw, ["turnId", "id"]);
|
|
4284
4270
|
}
|
|
4271
|
+
|
|
4272
|
+
// Fire-and-forget usage report — sent on init so the session list page shows
|
|
4273
|
+
// summary cards without anyone clicking a button. First call scans disk (~3s)
|
|
4274
|
+
// so it's deferred off the handler's critical path; cached (60s TTL)
|
|
4275
|
+
// thereafter. Errors silently swallowed (best-effort, never blocks).
|
|
4276
|
+
private sendUsageReport(): void {
|
|
4277
|
+
setTimeout(() => {
|
|
4278
|
+
try {
|
|
4279
|
+
const report = aggregateUsage();
|
|
4280
|
+
this.input.send(createEnvelope({
|
|
4281
|
+
type: "agent.v2.usage.report",
|
|
4282
|
+
sessionId: this.input.sessionId,
|
|
4283
|
+
payload: report,
|
|
4284
|
+
}));
|
|
4285
|
+
} catch (error) {
|
|
4286
|
+
if (this.input.verbose) {
|
|
4287
|
+
process.stderr.write(`[agent:v2] usage aggregation failed: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
4288
|
+
}
|
|
4289
|
+
}
|
|
4290
|
+
}, 0);
|
|
4291
|
+
}
|
|
4285
4292
|
}
|
|
4286
4293
|
|
|
4287
4294
|
function parsePermissionOptions(value: unknown): AgentPermission["options"] {
|
|
@@ -328,8 +328,15 @@ function ingestCodex(acc: Accumulator): number {
|
|
|
328
328
|
return sessions;
|
|
329
329
|
}
|
|
330
330
|
|
|
331
|
+
let _cachedReport: UsageReport | null = null;
|
|
332
|
+
let _cachedAt = 0;
|
|
333
|
+
|
|
331
334
|
export function aggregateUsage(): UsageReport {
|
|
335
|
+
const now = Date.now();
|
|
336
|
+
if (_cachedReport && now - _cachedAt < 60_000) return _cachedReport;
|
|
332
337
|
const acc = new Accumulator();
|
|
333
338
|
const sessions = ingestClaude(acc) + ingestCodex(acc);
|
|
334
|
-
|
|
339
|
+
_cachedReport = acc.finish(sessions, now);
|
|
340
|
+
_cachedAt = now;
|
|
341
|
+
return _cachedReport;
|
|
335
342
|
}
|