@agentdeck/bridge 1.1.0 → 1.2.1
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 +14 -6
- package/assets/fonts/NOTICE-PocketSansWorld.md +10 -0
- package/assets/fonts/OFL-PocketSansWorld.txt +93 -0
- package/assets/fonts/PocketSansWorld_12.cpfont +0 -0
- package/assets/fonts/pocket-sans-world.manifest.json +49 -0
- package/assets/learning/LICENSE-CC-BY-SA-4.0.txt +10 -0
- package/assets/learning/NOTICE.md +33 -0
- package/assets/learning/jp-n3-ko.manifest.json +27 -0
- package/assets/learning/jp-n3-ko.pdl +0 -0
- package/dist/agent-cli-diagnostics.d.ts +20 -0
- package/dist/agent-cli-diagnostics.d.ts.map +1 -0
- package/dist/agent-cli-diagnostics.js +100 -0
- package/dist/agent-cli-diagnostics.js.map +1 -0
- package/dist/apme/classifier.d.ts.map +1 -1
- package/dist/apme/classifier.js +18 -10
- package/dist/apme/classifier.js.map +1 -1
- package/dist/apme/claude-transcript-reader.d.ts +36 -0
- package/dist/apme/claude-transcript-reader.d.ts.map +1 -1
- package/dist/apme/claude-transcript-reader.js +78 -2
- package/dist/apme/claude-transcript-reader.js.map +1 -1
- package/dist/apme/collector.d.ts +126 -3
- package/dist/apme/collector.d.ts.map +1 -1
- package/dist/apme/collector.js +450 -41
- package/dist/apme/collector.js.map +1 -1
- package/dist/apme/dashboard-html.d.ts.map +1 -1
- package/dist/apme/dashboard-html.js +278 -36
- package/dist/apme/dashboard-html.js.map +1 -1
- package/dist/apme/graph.d.ts +1 -1
- package/dist/apme/graph.d.ts.map +1 -1
- package/dist/apme/graph.js +51 -1
- package/dist/apme/graph.js.map +1 -1
- package/dist/apme/http.d.ts.map +1 -1
- package/dist/apme/http.js +37 -5
- package/dist/apme/http.js.map +1 -1
- package/dist/apme/index.d.ts +4 -0
- package/dist/apme/index.d.ts.map +1 -1
- package/dist/apme/index.js +19 -3
- package/dist/apme/index.js.map +1 -1
- package/dist/apme/runner.d.ts +90 -0
- package/dist/apme/runner.d.ts.map +1 -1
- package/dist/apme/runner.js +524 -48
- package/dist/apme/runner.js.map +1 -1
- package/dist/apme/sample-to-timeline.d.ts.map +1 -1
- package/dist/apme/sample-to-timeline.js +5 -0
- package/dist/apme/sample-to-timeline.js.map +1 -1
- package/dist/apme/settings.d.ts +8 -0
- package/dist/apme/settings.d.ts.map +1 -1
- package/dist/apme/settings.js +4 -0
- package/dist/apme/settings.js.map +1 -1
- package/dist/apme/store.d.ts +118 -9
- package/dist/apme/store.d.ts.map +1 -1
- package/dist/apme/store.js +342 -44
- package/dist/apme/store.js.map +1 -1
- package/dist/apme/task-gradeability.d.ts +82 -0
- package/dist/apme/task-gradeability.d.ts.map +1 -0
- package/dist/apme/task-gradeability.js +126 -0
- package/dist/apme/task-gradeability.js.map +1 -0
- package/dist/awaiting-overlay.d.ts +13 -26
- package/dist/awaiting-overlay.d.ts.map +1 -1
- package/dist/awaiting-overlay.js +7 -40
- package/dist/awaiting-overlay.js.map +1 -1
- package/dist/bridge-core.d.ts +15 -0
- package/dist/bridge-core.d.ts.map +1 -1
- package/dist/bridge-core.js +30 -4
- package/dist/bridge-core.js.map +1 -1
- package/dist/claude-permission-rules.d.ts +20 -32
- package/dist/claude-permission-rules.d.ts.map +1 -1
- package/dist/claude-permission-rules.js +19 -102
- package/dist/claude-permission-rules.js.map +1 -1
- package/dist/claude-usage-recovery.d.ts +54 -0
- package/dist/claude-usage-recovery.d.ts.map +1 -0
- package/dist/claude-usage-recovery.js +200 -0
- package/dist/claude-usage-recovery.js.map +1 -0
- package/dist/cli.d.ts +11 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +81 -14
- package/dist/cli.js.map +1 -1
- package/dist/codex-rate-limits-live.d.ts +180 -10
- package/dist/codex-rate-limits-live.d.ts.map +1 -1
- package/dist/codex-rate-limits-live.js +475 -22
- package/dist/codex-rate-limits-live.js.map +1 -1
- package/dist/codex-rollout-response.d.ts +43 -0
- package/dist/codex-rollout-response.d.ts.map +1 -1
- package/dist/codex-rollout-response.js +67 -0
- package/dist/codex-rollout-response.js.map +1 -1
- package/dist/coordination-evidence.d.ts +150 -0
- package/dist/coordination-evidence.d.ts.map +1 -0
- package/dist/coordination-evidence.js +455 -0
- package/dist/coordination-evidence.js.map +1 -0
- package/dist/daemon-server.d.ts.map +1 -1
- package/dist/daemon-server.js +592 -35
- package/dist/daemon-server.js.map +1 -1
- package/dist/daemon-ws-client.d.ts +1 -0
- package/dist/daemon-ws-client.d.ts.map +1 -1
- package/dist/daemon-ws-client.js +25 -16
- package/dist/daemon-ws-client.js.map +1 -1
- package/dist/daemon.js +1 -1
- package/dist/deferred-reply-read.d.ts +24 -0
- package/dist/deferred-reply-read.d.ts.map +1 -0
- package/dist/deferred-reply-read.js +42 -0
- package/dist/deferred-reply-read.js.map +1 -0
- package/dist/esp32-serial.d.ts +15 -0
- package/dist/esp32-serial.d.ts.map +1 -1
- package/dist/esp32-serial.js +61 -2
- package/dist/esp32-serial.js.map +1 -1
- package/dist/font-pack.d.ts +15 -0
- package/dist/font-pack.d.ts.map +1 -0
- package/dist/font-pack.js +75 -0
- package/dist/font-pack.js.map +1 -0
- package/dist/glance-frame.d.ts.map +1 -1
- package/dist/glance-frame.js +2 -0
- package/dist/glance-frame.js.map +1 -1
- package/dist/hook-codex-sessions.d.ts +9 -0
- package/dist/hook-codex-sessions.d.ts.map +1 -1
- package/dist/hook-codex-sessions.js +35 -2
- package/dist/hook-codex-sessions.js.map +1 -1
- package/dist/hook-opencode-sessions.d.ts +62 -0
- package/dist/hook-opencode-sessions.d.ts.map +1 -0
- package/dist/hook-opencode-sessions.js +180 -0
- package/dist/hook-opencode-sessions.js.map +1 -0
- package/dist/hook-response-source.d.ts +40 -0
- package/dist/hook-response-source.d.ts.map +1 -0
- package/dist/hook-response-source.js +31 -0
- package/dist/hook-response-source.js.map +1 -0
- package/dist/http-auth-gate.d.ts.map +1 -1
- package/dist/http-auth-gate.js +9 -1
- package/dist/http-auth-gate.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- package/dist/index.js.map +1 -1
- package/dist/learning-pack.d.ts +24 -0
- package/dist/learning-pack.d.ts.map +1 -0
- package/dist/learning-pack.js +125 -0
- package/dist/learning-pack.js.map +1 -0
- package/dist/mdns.js +1 -1
- package/dist/mdns.js.map +1 -1
- package/dist/native-dependency-diagnostics.d.ts +29 -0
- package/dist/native-dependency-diagnostics.d.ts.map +1 -0
- package/dist/native-dependency-diagnostics.js +95 -0
- package/dist/native-dependency-diagnostics.js.map +1 -0
- package/dist/observed-steering.d.ts +4 -4
- package/dist/observed-steering.d.ts.map +1 -1
- package/dist/observed-steering.js +28 -32
- package/dist/observed-steering.js.map +1 -1
- package/dist/openclaw-gateway-stability.d.ts +94 -0
- package/dist/openclaw-gateway-stability.d.ts.map +1 -0
- package/dist/openclaw-gateway-stability.js +176 -0
- package/dist/openclaw-gateway-stability.js.map +1 -0
- package/dist/pairing-knocks.d.ts +80 -0
- package/dist/pairing-knocks.d.ts.map +1 -0
- package/dist/pairing-knocks.js +312 -0
- package/dist/pairing-knocks.js.map +1 -0
- package/dist/passive-observer.d.ts +5 -0
- package/dist/passive-observer.d.ts.map +1 -1
- package/dist/passive-observer.js +6 -0
- package/dist/passive-observer.js.map +1 -1
- package/dist/pixoo/micro-glyphs.d.ts +4 -0
- package/dist/pixoo/micro-glyphs.d.ts.map +1 -1
- package/dist/pixoo/micro-glyphs.js +29 -0
- package/dist/pixoo/micro-glyphs.js.map +1 -1
- package/dist/pixoo/pixoo-font.d.ts.map +1 -1
- package/dist/pixoo/pixoo-font.js +3 -1
- package/dist/pixoo/pixoo-font.js.map +1 -1
- package/dist/pixoo/pixoo-renderer.d.ts +1 -1
- package/dist/pixoo/pixoo-renderer.d.ts.map +1 -1
- package/dist/pixoo/pixoo-renderer.js +17 -2
- package/dist/pixoo/pixoo-renderer.js.map +1 -1
- package/dist/pty-manager.d.ts +9 -0
- package/dist/pty-manager.d.ts.map +1 -1
- package/dist/pty-manager.js +63 -4
- package/dist/pty-manager.js.map +1 -1
- package/dist/relayed-usage.d.ts +30 -0
- package/dist/relayed-usage.d.ts.map +1 -1
- package/dist/relayed-usage.js +25 -2
- package/dist/relayed-usage.js.map +1 -1
- package/dist/review-runner.js +1 -1
- package/dist/subagent-timeline.d.ts +27 -0
- package/dist/subagent-timeline.d.ts.map +1 -1
- package/dist/subagent-timeline.js +52 -5
- package/dist/subagent-timeline.js.map +1 -1
- package/dist/surface-protocol.d.ts.map +1 -1
- package/dist/surface-protocol.js +2 -0
- package/dist/surface-protocol.js.map +1 -1
- package/dist/tui/dashboard.d.ts.map +1 -1
- package/dist/tui/dashboard.js +8 -1
- package/dist/tui/dashboard.js.map +1 -1
- package/dist/usage-api.d.ts +3 -0
- package/dist/usage-api.d.ts.map +1 -1
- package/dist/usage-api.js +101 -36
- package/dist/usage-api.js.map +1 -1
- package/dist/usage-event.d.ts.map +1 -1
- package/dist/usage-event.js +2 -1
- package/dist/usage-event.js.map +1 -1
- package/dist/ws-server.d.ts +18 -0
- package/dist/ws-server.d.ts.map +1 -1
- package/dist/ws-server.js +40 -2
- package/dist/ws-server.js.map +1 -1
- package/package.json +6 -5
- package/src/timebox/sync_ble.py +35 -16
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import { execFile } from 'child_process';
|
|
2
|
+
import { createHash } from 'crypto';
|
|
3
|
+
import { mkdirSync, readFileSync, renameSync, statSync, writeFileSync } from 'fs';
|
|
4
|
+
import { homedir, tmpdir } from 'os';
|
|
5
|
+
import { delimiter, join, resolve } from 'path';
|
|
6
|
+
import { logTagged } from './logger.js';
|
|
7
|
+
const RECOVERY_TIMEOUT_MS = 25_000;
|
|
8
|
+
const RETRY_MS = 30 * 60_000;
|
|
9
|
+
const LONG_RETRY_MS = 6 * 60 * 60_000;
|
|
10
|
+
/** The daemon's data directory — `AGENTDECK_DATA_DIR` when set, else
|
|
11
|
+
* `~/.agentdeck`. Every other file in that directory resolves it this way; the
|
|
12
|
+
* cooldown record did not, so two daemons pointed at different data dirs
|
|
13
|
+
* silently shared one retry budget and each spent the other's quota. Kept
|
|
14
|
+
* identical to `usage-api.ts`'s AGENTDECK_DIR — they are the same directory,
|
|
15
|
+
* and item 5 of #286 is explicit that both move together or neither does. */
|
|
16
|
+
const AGENTDECK_DIR = process.env.AGENTDECK_DATA_DIR || join(homedir(), '.agentdeck');
|
|
17
|
+
export const CLAUDE_USAGE_RECOVERY_FILE = join(AGENTDECK_DIR, 'claude-usage-recovery.json');
|
|
18
|
+
/** Claude owns the rotating refresh token and its interprocess lock. Never copy,
|
|
19
|
+
* rotate, or write those credentials ourselves. This bounded turn may consume a
|
|
20
|
+
* small amount of subscription quota; it carries no workspace or user content.
|
|
21
|
+
* --bare is NOT appropriate: that mode explicitly disables OAuth/keychain reads.
|
|
22
|
+
* An older CLI rejecting --safe-mode fails closed rather than loading hooks.
|
|
23
|
+
*/
|
|
24
|
+
export const CLAUDE_USAGE_RECOVERY_ARGS = [
|
|
25
|
+
'--safe-mode', '--print', '--tools', '', '--strict-mcp-config',
|
|
26
|
+
'--mcp-config', '{"mcpServers":{}}', '--settings', '{"disableAllHooks":true}',
|
|
27
|
+
'--no-session-persistence', '--disable-slash-commands', '--no-chrome',
|
|
28
|
+
'--model', 'haiku', '--max-turns', '1', '--max-budget-usd', '0.01',
|
|
29
|
+
'--system-prompt', 'Reply with OK.', '--output-format', 'json', 'Reply with OK.',
|
|
30
|
+
];
|
|
31
|
+
/** Keep the recovery CLI on the same credential store as usage-api.ts.
|
|
32
|
+
* On macOS that reader targets the default Keychain service; a custom config
|
|
33
|
+
* directory can select a DIFFERENT Keychain namespace in Claude. Fail closed
|
|
34
|
+
* rather than spend quota or renew an unrelated account. On other platforms,
|
|
35
|
+
* resolve relative paths before the child changes cwd to the temporary folder.
|
|
36
|
+
*/
|
|
37
|
+
export function buildClaudeUsageRecoveryEnv(source = process.env, platform = process.platform, home = homedir()) {
|
|
38
|
+
const env = { ...source, CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: '1' };
|
|
39
|
+
if (env.CLAUDE_CONFIG_DIR) {
|
|
40
|
+
const configDir = resolve(env.CLAUDE_CONFIG_DIR);
|
|
41
|
+
if (platform === 'darwin' && configDir !== join(home, '.claude'))
|
|
42
|
+
return null;
|
|
43
|
+
env.CLAUDE_CONFIG_DIR = configDir;
|
|
44
|
+
}
|
|
45
|
+
// A daemon started from an agent must not be mistaken for its nested session.
|
|
46
|
+
// API-key / provider overrides must not redirect an OAuth recovery request.
|
|
47
|
+
for (const key of Object.keys(env)) {
|
|
48
|
+
if (key === 'CLAUDECODE' || key === 'ANTHROPIC_API_KEY' || key === 'ANTHROPIC_AUTH_TOKEN'
|
|
49
|
+
|| key === 'ANTHROPIC_BASE_URL' || key === 'CLAUDE_CODE_OAUTH_TOKEN'
|
|
50
|
+
|| key.startsWith('CLAUDE_CODE_USE_') || key.startsWith('AGENTDECK_'))
|
|
51
|
+
delete env[key];
|
|
52
|
+
}
|
|
53
|
+
return env;
|
|
54
|
+
}
|
|
55
|
+
/** `execFile` runs one executable — it does not search PATHEXT and (since the
|
|
56
|
+
* Node 20.12/18.20 spawn hardening) will not run a `.cmd`/`.bat` shim without a
|
|
57
|
+
* shell. A bare `'claude'` was therefore ENOENT on every Windows install, and a
|
|
58
|
+
* LaunchAgent carries the installing shell's PATH, which may not contain the
|
|
59
|
+
* CLI at all — both surfaced only as a recurring generic failure line. Resolve
|
|
60
|
+
* the real file once so the unavailable case can SAY it is unavailable.
|
|
61
|
+
* Returns `{ shim: true }` for a Windows shell shim: shell-quoting a JSON
|
|
62
|
+
* argument through cmd.exe is a worse failure than declining, so recovery is
|
|
63
|
+
* skipped there and says so. */
|
|
64
|
+
export function resolveClaudeCli(env = process.env, platform = process.platform) {
|
|
65
|
+
const isFile = (candidate) => {
|
|
66
|
+
try {
|
|
67
|
+
return statSync(candidate).isFile();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const override = env.AGENTDECK_CLAUDE_CLI;
|
|
74
|
+
if (override)
|
|
75
|
+
return isFile(override) ? { path: override, shim: false } : null;
|
|
76
|
+
const exts = platform === 'win32'
|
|
77
|
+
? (env.PATHEXT || '.COM;.EXE;.BAT;.CMD').split(';').filter(Boolean)
|
|
78
|
+
: [''];
|
|
79
|
+
for (const dir of (env.PATH || '').split(delimiter).filter(Boolean)) {
|
|
80
|
+
for (const ext of exts) {
|
|
81
|
+
const candidate = join(dir, `claude${ext}`);
|
|
82
|
+
if (isFile(candidate))
|
|
83
|
+
return { path: candidate, shim: /\.(cmd|bat)$/i.test(ext) };
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
let reportedUnavailable = false;
|
|
89
|
+
function reportUnavailableOnce(reason) {
|
|
90
|
+
if (reportedUnavailable)
|
|
91
|
+
return;
|
|
92
|
+
reportedUnavailable = true;
|
|
93
|
+
logTagged('usage', `Claude authorization recovery unavailable: ${reason}`);
|
|
94
|
+
}
|
|
95
|
+
export function runClaudeUsageRecovery() {
|
|
96
|
+
const env = buildClaudeUsageRecoveryEnv();
|
|
97
|
+
if (!env) {
|
|
98
|
+
logTagged('usage', 'Claude authorization recovery skipped: custom macOS credential namespace cannot be matched');
|
|
99
|
+
return Promise.resolve();
|
|
100
|
+
}
|
|
101
|
+
const cli = resolveClaudeCli(env);
|
|
102
|
+
if (!cli) {
|
|
103
|
+
reportUnavailableOnce('the claude CLI was not found on this daemon\'s PATH (set AGENTDECK_CLAUDE_CLI to its full path)');
|
|
104
|
+
return Promise.resolve();
|
|
105
|
+
}
|
|
106
|
+
if (cli.shim) {
|
|
107
|
+
reportUnavailableOnce(`only a shell shim is installed (${cli.path}); point AGENTDECK_CLAUDE_CLI at an executable`);
|
|
108
|
+
return Promise.resolve();
|
|
109
|
+
}
|
|
110
|
+
return new Promise((resolve) => {
|
|
111
|
+
const child = execFile(cli.path, CLAUDE_USAGE_RECOVERY_ARGS, {
|
|
112
|
+
cwd: tmpdir(), env, timeout: RECOVERY_TIMEOUT_MS, killSignal: 'SIGKILL',
|
|
113
|
+
maxBuffer: 64 * 1024, windowsHide: true,
|
|
114
|
+
}, (error) => {
|
|
115
|
+
if (error)
|
|
116
|
+
logTagged('usage', `Claude authorization recovery CLI ended (${error.killed ? 'timeout' : error.code ?? 'failed'})`);
|
|
117
|
+
resolve(); // Outcome is verified by re-reading credentials, never stdout.
|
|
118
|
+
});
|
|
119
|
+
child.stdin?.end();
|
|
120
|
+
// The child holds no port and gates no shutdown, but a clean stop that
|
|
121
|
+
// SIGKILLs the daemon takes `execFile`'s timeout with it — the orphan then
|
|
122
|
+
// runs unbounded. Track it so shutdown can end it, and unref it so it can
|
|
123
|
+
// never be the reason this process stays alive.
|
|
124
|
+
child.unref();
|
|
125
|
+
liveRecoveryChildren.add(child);
|
|
126
|
+
// `close`, not `exit`: a spawn that fails outright (the resolved binary
|
|
127
|
+
// vanished between the probe and the spawn) emits `error` + `close` and
|
|
128
|
+
// never `exit`, so an `exit` listener retains a dead ChildProcess for the
|
|
129
|
+
// life of the daemon — one per attempt, against a comment that says "at
|
|
130
|
+
// most one". `close` fires on both paths.
|
|
131
|
+
child.once('close', () => liveRecoveryChildren.delete(child));
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
/** Recovery children currently running. At most one — the class serializes on
|
|
135
|
+
* `pending` — but a Set costs nothing and cannot go negative. */
|
|
136
|
+
const liveRecoveryChildren = new Set();
|
|
137
|
+
/** Kill any in-flight recovery child. Called from the daemon's shutdown path;
|
|
138
|
+
* safe to call with none running. */
|
|
139
|
+
export function stopClaudeUsageRecoveryChildren() {
|
|
140
|
+
for (const child of liveRecoveryChildren) {
|
|
141
|
+
try {
|
|
142
|
+
child.kill('SIGKILL');
|
|
143
|
+
}
|
|
144
|
+
catch { /* already gone */ }
|
|
145
|
+
}
|
|
146
|
+
liveRecoveryChildren.clear();
|
|
147
|
+
}
|
|
148
|
+
/** Single daemon owner; persisted cooldown also survives daemon restart. */
|
|
149
|
+
export class ClaudeUsageRecovery {
|
|
150
|
+
deps;
|
|
151
|
+
pending = null;
|
|
152
|
+
record = null;
|
|
153
|
+
constructor(deps) {
|
|
154
|
+
this.deps = deps;
|
|
155
|
+
}
|
|
156
|
+
async recover(accessToken) {
|
|
157
|
+
if (this.pending)
|
|
158
|
+
return this.pending;
|
|
159
|
+
const credentialHash = createHash('sha256').update(accessToken).digest('hex');
|
|
160
|
+
const previous = this.record ?? this.deps.read();
|
|
161
|
+
if (previous && this.deps.now() < previous.nextAttemptAt)
|
|
162
|
+
return;
|
|
163
|
+
const attempts = previous?.credentialHash === credentialHash ? previous.attempts + 1 : 1;
|
|
164
|
+
this.record = { credentialHash, attempts,
|
|
165
|
+
nextAttemptAt: this.deps.now() + (attempts >= 3 ? LONG_RETRY_MS : RETRY_MS) };
|
|
166
|
+
// Record BEFORE spawning: a crash/restart must not cause a recovery loop.
|
|
167
|
+
try {
|
|
168
|
+
this.deps.write(this.record);
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
logTagged('usage', `Claude usage authorization expired — requesting bounded CLI recovery (attempt ${attempts})`);
|
|
174
|
+
this.pending = this.deps.run().catch(() => { }).finally(() => { this.pending = null; });
|
|
175
|
+
return this.pending;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
export const claudeUsageRecovery = new ClaudeUsageRecovery({
|
|
179
|
+
now: Date.now,
|
|
180
|
+
read: () => {
|
|
181
|
+
try {
|
|
182
|
+
const r = JSON.parse(readFileSync(CLAUDE_USAGE_RECOVERY_FILE, 'utf8'));
|
|
183
|
+
return typeof r.credentialHash === 'string' && Number.isFinite(r.attempts)
|
|
184
|
+
&& Number.isFinite(r.nextAttemptAt) ? r : null;
|
|
185
|
+
}
|
|
186
|
+
catch {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
},
|
|
190
|
+
write: (record) => {
|
|
191
|
+
mkdirSync(AGENTDECK_DIR, { recursive: true });
|
|
192
|
+
// tmp+rename like every other file in this directory: a torn write reads
|
|
193
|
+
// back as "no cooldown", which is the one failure that spends quota.
|
|
194
|
+
const tmp = `${CLAUDE_USAGE_RECOVERY_FILE}.${process.pid}.tmp`;
|
|
195
|
+
writeFileSync(tmp, JSON.stringify(record), { mode: 0o600 });
|
|
196
|
+
renameSync(tmp, CLAUDE_USAGE_RECOVERY_FILE);
|
|
197
|
+
},
|
|
198
|
+
run: runClaudeUsageRecovery,
|
|
199
|
+
});
|
|
200
|
+
//# sourceMappingURL=claude-usage-recovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-usage-recovery.js","sourceRoot":"","sources":["../src/claude-usage-recovery.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
+
export type LegacySessionCommand = 'claude' | 'codex' | 'opencode' | 'monitor';
|
|
4
|
+
/**
|
|
5
|
+
* User-visible compatibility notice for the legacy per-session bridge. Keep
|
|
6
|
+
* this pure so CLI tests can pin the public migration contract without starting
|
|
7
|
+
* a PTY or importing its native dependencies.
|
|
8
|
+
*/
|
|
9
|
+
export declare function managedPtyCompatibilityNotice(command: LegacySessionCommand): string[];
|
|
3
10
|
export declare function daemonPostureArgs(opts: {
|
|
4
11
|
local?: boolean;
|
|
5
12
|
loopback?: boolean;
|
|
@@ -22,6 +29,10 @@ export interface CliOtaIdentity {
|
|
|
22
29
|
board: string;
|
|
23
30
|
updateChannel: string;
|
|
24
31
|
}
|
|
32
|
+
export declare function inlineOtaPayload(target: string, firmwareB64: string, opts?: {
|
|
33
|
+
stage?: boolean;
|
|
34
|
+
identity?: CliOtaIdentity;
|
|
35
|
+
}): Record<string, unknown>;
|
|
25
36
|
/** Resolve one exact OTA namespace from an integration manifest. Ambiguity is
|
|
26
37
|
* an error: a release command must never guess which product or channel owns
|
|
27
38
|
* an image. */
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAwB,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -28,6 +28,25 @@ function warnIfDaemonHostIgnored(opts) {
|
|
|
28
28
|
console.error('[agentdeck] --daemon-host / AGENTDECK_DAEMON_HOST is set but ignored: remote attach requires --remote-daemon (or AGENTDECK_REMOTE_DAEMON=1). Session stays local-only.');
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* User-visible compatibility notice for the legacy per-session bridge. Keep
|
|
33
|
+
* this pure so CLI tests can pin the public migration contract without starting
|
|
34
|
+
* a PTY or importing its native dependencies.
|
|
35
|
+
*/
|
|
36
|
+
export function managedPtyCompatibilityNotice(command) {
|
|
37
|
+
const directLaunch = command === 'monitor'
|
|
38
|
+
? 'run `claude`, `codex`, or `opencode` normally'
|
|
39
|
+
: `run \`${command}\` directly`;
|
|
40
|
+
return [
|
|
41
|
+
`[agentdeck] LEGACY COMPATIBILITY MODE: \`agentdeck ${command}\` uses the managed per-session bridge; daemon-first launch is the recommended default.`,
|
|
42
|
+
`[agentdeck] For ordinary local sessions, run \`agentdeck daemon install\`, then ${directLaunch}.`,
|
|
43
|
+
'[agentdeck] --remote-daemon, --weight, AGENTDECK_<AGENT>_ARGS, and terminal-only controls do not yet have daemon-first equivalents. No removal date is set. Design: https://github.com/puritysb/AgentDeck/discussions/278 Tracking: https://github.com/puritysb/AgentDeck/issues/273',
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
function warnManagedPtyCompatibility(command) {
|
|
47
|
+
for (const line of managedPtyCompatibilityNotice(command))
|
|
48
|
+
console.error(line);
|
|
49
|
+
}
|
|
31
50
|
function log(msg) {
|
|
32
51
|
process.stderr.write(msg + '\n');
|
|
33
52
|
}
|
|
@@ -323,6 +342,14 @@ for (const b of ESP32_OTA_BOARDS) {
|
|
|
323
342
|
export function resolveEsp32OtaDaemonTarget(target) {
|
|
324
343
|
return ESP32_OTA_BY_TARGET[target]?.board ?? target;
|
|
325
344
|
}
|
|
345
|
+
export function inlineOtaPayload(target, firmwareB64, opts = {}) {
|
|
346
|
+
return {
|
|
347
|
+
target,
|
|
348
|
+
firmwareB64,
|
|
349
|
+
...(opts.stage ? { stage: true } : {}),
|
|
350
|
+
...(opts.identity ?? {}),
|
|
351
|
+
};
|
|
352
|
+
}
|
|
326
353
|
/** Resolve one exact OTA namespace from an integration manifest. Ambiguity is
|
|
327
354
|
* an error: a release command must never guess which product or channel owns
|
|
328
355
|
* an image. */
|
|
@@ -552,7 +579,7 @@ weatherCommand
|
|
|
552
579
|
// ===== Agent session commands =====
|
|
553
580
|
program
|
|
554
581
|
.command('claude')
|
|
555
|
-
.description('Start Claude Code
|
|
582
|
+
.description('[legacy compatibility] Start Claude Code in the managed PTY session bridge')
|
|
556
583
|
.option('-p, --port <port>', 'Bridge server port', String(BRIDGE_WS_PORT))
|
|
557
584
|
.option('-c, --command <cmd>', 'Command to spawn', 'claude')
|
|
558
585
|
.option('-d, --debug', 'Enable debug logging')
|
|
@@ -568,6 +595,7 @@ program
|
|
|
568
595
|
.option('--no-env-args', 'Ignore AGENTDECK_COMMANDER_ARGS and AGENTDECK_<AGENT>_ARGS for this invocation')
|
|
569
596
|
.option('--weight <n>', 'Deck/tab sort order override (integer, lower first; default 0)', parseWeight)
|
|
570
597
|
.action(async (opts) => {
|
|
598
|
+
warnManagedPtyCompatibility('claude');
|
|
571
599
|
warnIfDaemonHostIgnored(opts);
|
|
572
600
|
const { startSession } = await import('./index.js');
|
|
573
601
|
await startSession({
|
|
@@ -596,7 +624,7 @@ program
|
|
|
596
624
|
});
|
|
597
625
|
program
|
|
598
626
|
.command('codex')
|
|
599
|
-
.description('Start Codex
|
|
627
|
+
.description('[legacy compatibility] Start Codex in the managed PTY session bridge')
|
|
600
628
|
.option('-p, --port <port>', 'Bridge server port', String(BRIDGE_WS_PORT))
|
|
601
629
|
.option('-c, --command <cmd>', 'Command to spawn', 'codex')
|
|
602
630
|
.option('-d, --debug', 'Enable debug logging')
|
|
@@ -610,6 +638,7 @@ program
|
|
|
610
638
|
.option('--no-env-args', 'Ignore AGENTDECK_COMMANDER_ARGS and AGENTDECK_<AGENT>_ARGS for this invocation')
|
|
611
639
|
.option('--weight <n>', 'Deck/tab sort order override (integer, lower first; default 0)', parseWeight)
|
|
612
640
|
.action(async (opts) => {
|
|
641
|
+
warnManagedPtyCompatibility('codex');
|
|
613
642
|
warnIfDaemonHostIgnored(opts);
|
|
614
643
|
// Install Codex lifecycle hooks before starting the session so the
|
|
615
644
|
// first prompt's UserPromptSubmit / Stop events reach the daemon.
|
|
@@ -657,7 +686,7 @@ program
|
|
|
657
686
|
});
|
|
658
687
|
program
|
|
659
688
|
.command('opencode')
|
|
660
|
-
.description('Start OpenCode
|
|
689
|
+
.description('[legacy compatibility] Start OpenCode in the managed PTY/SSE session bridge')
|
|
661
690
|
.option('-p, --port <port>', 'Bridge server port', String(BRIDGE_WS_PORT))
|
|
662
691
|
.option('-c, --command <cmd>', 'Command to spawn', 'opencode')
|
|
663
692
|
.option('-d, --debug', 'Enable debug logging')
|
|
@@ -671,6 +700,7 @@ program
|
|
|
671
700
|
.option('--no-env-args', 'Ignore AGENTDECK_COMMANDER_ARGS and AGENTDECK_<AGENT>_ARGS for this invocation')
|
|
672
701
|
.option('--weight <n>', 'Deck/tab sort order override (integer, lower first; default 0)', parseWeight)
|
|
673
702
|
.action(async (opts) => {
|
|
703
|
+
warnManagedPtyCompatibility('opencode');
|
|
674
704
|
warnIfDaemonHostIgnored(opts);
|
|
675
705
|
// Install the OpenCode observer plugin so standalone `opencode` runs
|
|
676
706
|
// (outside this managed session) also reach the daemon timeline. The
|
|
@@ -715,7 +745,7 @@ program
|
|
|
715
745
|
});
|
|
716
746
|
program
|
|
717
747
|
.command('monitor')
|
|
718
|
-
.description('Start hook-only bridge
|
|
748
|
+
.description('[legacy compatibility] Start the managed hook-only per-session bridge')
|
|
719
749
|
.option('-p, --port <port>', 'Bridge server port', String(BRIDGE_WS_PORT))
|
|
720
750
|
.option('-d, --debug', 'Enable debug logging')
|
|
721
751
|
.option('--local', 'Disable all device modules')
|
|
@@ -726,6 +756,7 @@ program
|
|
|
726
756
|
.option('--no-env-args', 'Ignore AGENTDECK_COMMANDER_ARGS for this invocation')
|
|
727
757
|
.option('--weight <n>', 'Deck/tab sort order override (integer, lower first; default 0)', parseWeight)
|
|
728
758
|
.action(async (opts) => {
|
|
759
|
+
warnManagedPtyCompatibility('monitor');
|
|
729
760
|
warnIfDaemonHostIgnored(opts);
|
|
730
761
|
const { startSession } = await import('./index.js');
|
|
731
762
|
const port = parseInt(opts.port, 10);
|
|
@@ -1246,8 +1277,13 @@ daemon
|
|
|
1246
1277
|
const targetPort = registryPort ?? port;
|
|
1247
1278
|
try {
|
|
1248
1279
|
const res = await fetch(`http://127.0.0.1:${targetPort}/health`);
|
|
1249
|
-
const data = await res.json();
|
|
1280
|
+
const data = (await res.json());
|
|
1250
1281
|
log(`Daemon status (port ${targetPort}): ${JSON.stringify(data, null, 2)}`);
|
|
1282
|
+
const apmeHealth = data.apme;
|
|
1283
|
+
if (apmeHealth?.enabled === false) {
|
|
1284
|
+
log(`WARNING: APME evaluation is disabled${typeof apmeHealth.error === 'string' ? ` — ${apmeHealth.error}` : '.'}`);
|
|
1285
|
+
log('Run `agentdeck diag native` for the exact Node executable, ABI, and recovery command.');
|
|
1286
|
+
}
|
|
1251
1287
|
// A daemon on a fallback port keeps working — clients resolve it from
|
|
1252
1288
|
// daemon.json — so nothing else ever says it happened. Without this line
|
|
1253
1289
|
// the only symptom is that the canonical port is owned by nobody.
|
|
@@ -1343,6 +1379,12 @@ daemon
|
|
|
1343
1379
|
.option('--loopback', 'Alias for --enterprise')
|
|
1344
1380
|
.action(async (opts) => {
|
|
1345
1381
|
const postureArgs = daemonPostureArgs(opts);
|
|
1382
|
+
const { collectNativeDependencyDiagnostic, formatNativeDependencyDiagnosticReport, } = await import('./native-dependency-diagnostics.js');
|
|
1383
|
+
const nativeReport = collectNativeDependencyDiagnostic();
|
|
1384
|
+
if (!nativeReport.ok) {
|
|
1385
|
+
log('WARNING: daemon autostart will be registered, but APME evaluation cannot start under this runtime.');
|
|
1386
|
+
log(formatNativeDependencyDiagnosticReport(nativeReport));
|
|
1387
|
+
}
|
|
1346
1388
|
if (postureArgs.length > 0) {
|
|
1347
1389
|
log(`Autostart posture: ${postureArgs.join(' ')} (baked into the autostart unit's arguments).`);
|
|
1348
1390
|
}
|
|
@@ -1889,7 +1931,17 @@ program
|
|
|
1889
1931
|
// Pull-OTA staging: for wake-sync-sleep boards (XTeink X3/X4) that never
|
|
1890
1932
|
// hold a live WS. The daemon adverts the build on the board's feed pulls;
|
|
1891
1933
|
// the board downloads + flashes itself on its next wake.
|
|
1892
|
-
|
|
1934
|
+
let { statusCode, body } = await postJsonWithTimeout(`http://127.0.0.1:${port}/esp32/ota`, { target: daemonTarget, firmwarePath, stage: true, ...(otaIdentity ?? {}) }, 30_000);
|
|
1935
|
+
if (body.ok === false && String(body.error ?? '').startsWith('firmware_unreadable')) {
|
|
1936
|
+
// The App Store daemon cannot reopen an arbitrary CLI path. Preserve
|
|
1937
|
+
// the stage bit and exact product namespace when retrying inline — the
|
|
1938
|
+
// live-OTA retry below is a different operation and must not consume a
|
|
1939
|
+
// pull-stage request by accident.
|
|
1940
|
+
log('Daemon cannot read the firmware path (sandbox) — resending stage inline...');
|
|
1941
|
+
const { readFileSync } = await import('fs');
|
|
1942
|
+
const firmwareB64 = readFileSync(firmwarePath).toString('base64');
|
|
1943
|
+
({ statusCode, body } = await postJsonWithTimeout(`http://127.0.0.1:${port}/esp32/ota`, inlineOtaPayload(daemonTarget, firmwareB64, { stage: true, identity: otaIdentity }), 30_000));
|
|
1944
|
+
}
|
|
1893
1945
|
if (statusCode < 200 || statusCode >= 300 || body.ok === false) {
|
|
1894
1946
|
throw new Error(String(body.error ?? `HTTP ${statusCode}`));
|
|
1895
1947
|
}
|
|
@@ -1919,7 +1971,7 @@ program
|
|
|
1919
1971
|
log('Daemon cannot read the firmware path (sandbox) — resending inline...');
|
|
1920
1972
|
const { readFileSync } = await import('fs');
|
|
1921
1973
|
const firmwareB64 = readFileSync(firmwarePath).toString('base64');
|
|
1922
|
-
({ statusCode, body } = await postJsonWithTimeout(`http://127.0.0.1:${port}/esp32/ota`,
|
|
1974
|
+
({ statusCode, body } = await postJsonWithTimeout(`http://127.0.0.1:${port}/esp32/ota`, inlineOtaPayload(daemonTarget, firmwareB64), 15 * 60_000));
|
|
1923
1975
|
}
|
|
1924
1976
|
if (statusCode < 200 || statusCode >= 300 || body.ok === false) {
|
|
1925
1977
|
throw new Error(String(body.error ?? `HTTP ${statusCode}`));
|
|
@@ -2337,15 +2389,15 @@ program
|
|
|
2337
2389
|
});
|
|
2338
2390
|
program
|
|
2339
2391
|
.command('diag [target]')
|
|
2340
|
-
.description('Generate a diagnostic dump, or a
|
|
2392
|
+
.description('Generate a diagnostic dump, or a focused agent/native-runtime diagnostic')
|
|
2341
2393
|
.option('-p, --port <port>', 'Bridge server port', String(BRIDGE_WS_PORT))
|
|
2342
2394
|
.option('-a, --analyze', 'Run AI analysis on the dump')
|
|
2343
2395
|
.option('-t, --tail <lines>', 'Number of journal entries', '200')
|
|
2344
2396
|
.option('--json', 'Print target diagnostics as machine-readable JSON')
|
|
2345
2397
|
.action(async (target, opts) => {
|
|
2346
2398
|
if (target) {
|
|
2347
|
-
if (target !== 'kiro') {
|
|
2348
|
-
log(`Unknown diagnostic target: ${target}. Supported
|
|
2399
|
+
if (target !== 'kiro' && target !== 'agents' && target !== 'native') {
|
|
2400
|
+
log(`Unknown diagnostic target: ${target}. Supported targets: agents, kiro, native`);
|
|
2349
2401
|
process.exitCode = 1;
|
|
2350
2402
|
return;
|
|
2351
2403
|
}
|
|
@@ -2354,6 +2406,20 @@ program
|
|
|
2354
2406
|
process.exitCode = 1;
|
|
2355
2407
|
return;
|
|
2356
2408
|
}
|
|
2409
|
+
if (target === 'agents') {
|
|
2410
|
+
const { collectAgentCliDiagnosticReport, formatAgentCliDiagnosticReport } = await import('./agent-cli-diagnostics.js');
|
|
2411
|
+
const report = collectAgentCliDiagnosticReport();
|
|
2412
|
+
process.stdout.write(`${opts.json ? JSON.stringify(report, null, 2) : formatAgentCliDiagnosticReport(report)}\n`);
|
|
2413
|
+
return;
|
|
2414
|
+
}
|
|
2415
|
+
if (target === 'native') {
|
|
2416
|
+
const { collectNativeDependencyDiagnostic, formatNativeDependencyDiagnosticReport, } = await import('./native-dependency-diagnostics.js');
|
|
2417
|
+
const report = collectNativeDependencyDiagnostic();
|
|
2418
|
+
process.stdout.write(`${opts.json ? JSON.stringify(report, null, 2) : formatNativeDependencyDiagnosticReport(report)}\n`);
|
|
2419
|
+
if (!report.ok)
|
|
2420
|
+
process.exitCode = 1;
|
|
2421
|
+
return;
|
|
2422
|
+
}
|
|
2357
2423
|
const { collectKiroDiagnosticReport, formatKiroDiagnosticReport } = await import('./kiro-diagnostics.js');
|
|
2358
2424
|
const report = await collectKiroDiagnosticReport();
|
|
2359
2425
|
process.stdout.write(`${opts.json ? JSON.stringify(report, null, 2) : formatKiroDiagnosticReport(report)}\n`);
|
|
@@ -3346,22 +3412,23 @@ apme
|
|
|
3346
3412
|
return;
|
|
3347
3413
|
}
|
|
3348
3414
|
log(`\n Turns started in the last ${opts.since} — how each one's end was learned`);
|
|
3349
|
-
log(` ${'Agent'.padEnd(14)} ${'Turns'.padEnd(7)} ${'Stop'.padEnd(7)} ${'Synth'.padEnd(7)} ${'NoStop'.padEnd(7)} ${'Esc'.padEnd(6)} ${'Abort'.padEnd(6)} ${'Folded'.padEnd(7)} ${'SessEnd'.padEnd(8)} ${'Open'.padEnd(6)} ${'?'.padEnd(6)} Stop loss`);
|
|
3350
|
-
log(` ${'─'.repeat(14)} ${'─'.repeat(7)} ${'─'.repeat(7)} ${'─'.repeat(7)} ${'─'.repeat(7)} ${'─'.repeat(6)} ${'─'.repeat(6)} ${'─'.repeat(7)} ${'─'.repeat(8)} ${'─'.repeat(6)} ${'─'.repeat(6)} ${'─'.repeat(9)}`);
|
|
3415
|
+
log(` ${'Agent'.padEnd(14)} ${'Turns'.padEnd(7)} ${'Stop'.padEnd(7)} ${'Synth'.padEnd(7)} ${'NoStop'.padEnd(7)} ${'Esc'.padEnd(6)} ${'Abort'.padEnd(6)} ${'Folded'.padEnd(7)} ${'SessEnd'.padEnd(8)} ${'Reaped'.padEnd(7)} ${'Open'.padEnd(6)} ${'?'.padEnd(6)} Stop loss`);
|
|
3416
|
+
log(` ${'─'.repeat(14)} ${'─'.repeat(7)} ${'─'.repeat(7)} ${'─'.repeat(7)} ${'─'.repeat(7)} ${'─'.repeat(6)} ${'─'.repeat(6)} ${'─'.repeat(7)} ${'─'.repeat(8)} ${'─'.repeat(7)} ${'─'.repeat(6)} ${'─'.repeat(6)} ${'─'.repeat(9)}`);
|
|
3351
3417
|
for (const r of rows) {
|
|
3352
3418
|
// Which buckets the ratio may read is defined once, in shared — see
|
|
3353
3419
|
// `stopDeliveryLoss`. Restating it here is how the instrument would come
|
|
3354
3420
|
// to measure something other than what its legend claims.
|
|
3355
3421
|
const { adjudicated, ratio } = stopDeliveryLoss(r);
|
|
3356
3422
|
const rate = ratio != null ? `${(ratio * 100).toFixed(0)}% of ${adjudicated}` : '—';
|
|
3357
|
-
log(` ${r.agentType.slice(0, 14).padEnd(14)} ${String(r.total).padEnd(7)} ${String(r.stop).padEnd(7)} ${String(r.syntheticStop).padEnd(7)} ${String(r.nextPrompt).padEnd(7)} ${String(r.interrupted).padEnd(6)} ${String(r.aborted).padEnd(6)} ${String(r.superseded).padEnd(7)} ${String(r.sessionEnd).padEnd(8)} ${String(r.open).padEnd(6)} ${String(r.preInstrument).padEnd(6)} ${rate}`);
|
|
3423
|
+
log(` ${r.agentType.slice(0, 14).padEnd(14)} ${String(r.total).padEnd(7)} ${String(r.stop).padEnd(7)} ${String(r.syntheticStop).padEnd(7)} ${String(r.nextPrompt).padEnd(7)} ${String(r.interrupted).padEnd(6)} ${String(r.aborted).padEnd(6)} ${String(r.superseded).padEnd(7)} ${String(r.sessionEnd).padEnd(8)} ${String(r.runClose).padEnd(7)} ${String(r.open).padEnd(6)} ${String(r.preInstrument).padEnd(6)} ${rate}`);
|
|
3358
3424
|
}
|
|
3359
3425
|
log('');
|
|
3360
|
-
log(
|
|
3426
|
+
log(" Synth = Stop hook dropped, recovered from the agent's own record (transcript watchdog; rollout at the next prompt for Codex)");
|
|
3361
3427
|
log(' NoStop = Stop hook dropped and nothing recovered it (closed by the next prompt)');
|
|
3362
3428
|
log(' Esc = user cancelled the turn — Claude Code owes no Stop, so not a loss');
|
|
3363
3429
|
log(' Abort = usage limit / auth / API error ended the turn — no Stop is fired for those');
|
|
3364
3430
|
log(' Folded = a second prompt arrived before this one ran; one turn served both');
|
|
3431
|
+
log(' Reaped = the run was reaped under the open turn — the daemon that would have taken its Stop was gone (a restart)');
|
|
3365
3432
|
log(' ? = closed before end_source existed — signal unknown, never guessed');
|
|
3366
3433
|
log('');
|
|
3367
3434
|
});
|