@prohost/cli 0.16.6 → 0.16.8
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/CHANGELOG.md +46 -0
- package/README.md +6 -2
- package/dist/codehost/filelock.d.ts +44 -0
- package/dist/codehost/filelock.js +239 -0
- package/dist/codehost/folders.d.ts +5 -10
- package/dist/codehost/folders.js +17 -81
- package/dist/codehost/ready.d.ts +69 -6
- package/dist/codehost/ready.js +212 -11
- package/dist/codehost/terminals.js +31 -13
- package/dist/host/api.js +1 -1
- package/dist/host/command.d.ts +5 -0
- package/dist/host/command.js +119 -31
- package/dist/host/install.js +11 -3
- package/dist/host/service.d.ts +4 -0
- package/dist/host/service.js +25 -4
- package/dist/host/status.d.ts +6 -2
- package/dist/host/status.js +26 -8
- package/dist/version.d.ts +2 -2
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/host/service.js
CHANGED
|
@@ -89,6 +89,16 @@ const SAFE_ID = /^[A-Za-z0-9-]{1,64}$/;
|
|
|
89
89
|
export function busyBackoffMs(waits) {
|
|
90
90
|
return Math.min(30_000 * 2 ** waits, 120_000);
|
|
91
91
|
}
|
|
92
|
+
/** A refused status is logged again at most this often while refusals continue. */
|
|
93
|
+
export const STATUS_FAILURE_LOG_MS = 10 * 60_000;
|
|
94
|
+
/** A server's error text with anything shaped like a key or token blanked out. */
|
|
95
|
+
export function redactSecrets(text) {
|
|
96
|
+
return text
|
|
97
|
+
.replace(/\b(pk|sk|rk|whsec)_[A-Za-z0-9_-]{8,}/g, '$1_…')
|
|
98
|
+
.replace(/\bsk-ant-[A-Za-z0-9_-]{8,}/g, 'sk-ant-…')
|
|
99
|
+
.replace(/\bgh[pousr]_[A-Za-z0-9]{8,}/g, 'gh…')
|
|
100
|
+
.replace(/\b(Bearer|token)\s+[A-Za-z0-9._-]{12,}/gi, '$1 …');
|
|
101
|
+
}
|
|
92
102
|
function timestamp() {
|
|
93
103
|
return new Date().toISOString().slice(11, 19);
|
|
94
104
|
}
|
|
@@ -260,12 +270,15 @@ async function serveHost(options) {
|
|
|
260
270
|
// ── What is running ──────────────────────────────────────────────────────
|
|
261
271
|
function runningEntries() {
|
|
262
272
|
const runs = [...active.values()].map((run) => ({ ...run.entry, peak_mem_mb: peak.peakMb(run.entry.run_id) }));
|
|
273
|
+
// A terminal session is no employee's: no employee id (its runtime instead), and no start time
|
|
274
|
+
// this host knows (`started_at: null`, never '' — the server reads both as typed values).
|
|
263
275
|
const terms = (codeHost?.liveTerminals?.() ?? []).map((t) => ({
|
|
264
276
|
run_id: t.terminalId,
|
|
265
|
-
agent_id:
|
|
277
|
+
agent_id: null,
|
|
278
|
+
runtime: t.agent,
|
|
266
279
|
conversation_key: `code_thread:${t.codeThreadId}`,
|
|
267
280
|
kind: 'terminal',
|
|
268
|
-
started_at:
|
|
281
|
+
started_at: null,
|
|
269
282
|
}));
|
|
270
283
|
return [...runs, ...terms];
|
|
271
284
|
}
|
|
@@ -326,6 +339,8 @@ async function serveHost(options) {
|
|
|
326
339
|
let statusTimer;
|
|
327
340
|
let statusInFlight;
|
|
328
341
|
let statusFailures = 0;
|
|
342
|
+
/** When a refused status was last logged: a repeat is logged again (with its count) at most this often. */
|
|
343
|
+
let statusFailureLoggedAt = 0;
|
|
329
344
|
function statusChanged() {
|
|
330
345
|
writeLocalState();
|
|
331
346
|
if (statusTimer)
|
|
@@ -374,8 +389,14 @@ async function serveHost(options) {
|
|
|
374
389
|
return;
|
|
375
390
|
}
|
|
376
391
|
statusFailures += 1;
|
|
377
|
-
|
|
378
|
-
|
|
392
|
+
// The server's reason (a 422 names the field), at the first refusal and then every 10 minutes
|
|
393
|
+
// while it lasts, with how many there were — never only once and then silence.
|
|
394
|
+
if (statusFailures === 1 || now() - statusFailureLoggedAt >= STATUS_FAILURE_LOG_MS) {
|
|
395
|
+
statusFailureLoggedAt = now();
|
|
396
|
+
const why = redactSecrets(response.error ?? '').replace(/\s+/g, ' ').trim().slice(0, 500);
|
|
397
|
+
log(`${timestamp()} ! status not accepted (${response.status || 'no answer'}${statusFailures > 1 ? `, ${statusFailures} times in a row` : ''})` +
|
|
398
|
+
(why ? `: ${why}` : ''));
|
|
399
|
+
}
|
|
379
400
|
})().finally(() => {
|
|
380
401
|
statusInFlight = undefined;
|
|
381
402
|
});
|
package/dist/host/status.d.ts
CHANGED
|
@@ -34,13 +34,17 @@ export declare function parseConfig(body: Record<string, unknown> | undefined, p
|
|
|
34
34
|
/** One run going on this computer. */
|
|
35
35
|
export interface RunningEntry {
|
|
36
36
|
run_id: string;
|
|
37
|
-
|
|
37
|
+
/** The employee's id (a UUID); null for a terminal session, which is no employee's. */
|
|
38
|
+
agent_id: string | null;
|
|
39
|
+
/** A terminal session's agent runtime (`claude_code`, `codex`, …). */
|
|
40
|
+
runtime?: string;
|
|
38
41
|
agent_name?: string;
|
|
39
42
|
agent_avatar_url?: string;
|
|
40
43
|
title?: string;
|
|
41
44
|
conversation_key?: string;
|
|
42
45
|
kind: 'employee' | 'terminal';
|
|
43
|
-
|
|
46
|
+
/** ISO-8601, or null when it isn't known (a terminal session). */
|
|
47
|
+
started_at: string | null;
|
|
44
48
|
peak_mem_mb?: number;
|
|
45
49
|
started_by_user_id?: string;
|
|
46
50
|
}
|
package/dist/host/status.js
CHANGED
|
@@ -69,16 +69,32 @@ export function hostStatsBody(stats) {
|
|
|
69
69
|
battery_pct: stats?.batteryPct ?? null,
|
|
70
70
|
};
|
|
71
71
|
}
|
|
72
|
+
function clip(value, max) {
|
|
73
|
+
if (value === null || value === undefined)
|
|
74
|
+
return null;
|
|
75
|
+
// By code point, as the server counts (`len()` of a Python str): never half a surrogate pair,
|
|
76
|
+
// which it would refuse as invalid Unicode.
|
|
77
|
+
const points = Array.from(value);
|
|
78
|
+
return points.length > max ? points.slice(0, max).join('') : value;
|
|
79
|
+
}
|
|
72
80
|
/** A login as the status body names it: no email, no directory. */
|
|
73
81
|
export function loginBody(login, conversations) {
|
|
74
82
|
return {
|
|
75
83
|
account_key: login.account_key,
|
|
76
|
-
label: login.label,
|
|
77
|
-
runtime: login.runtime,
|
|
78
|
-
subscription_type: login.subscription_type,
|
|
79
|
-
plan_label: login.plan_label,
|
|
84
|
+
label: clip(login.label, 120) || 'login',
|
|
85
|
+
runtime: clip(login.runtime, 40),
|
|
86
|
+
subscription_type: clip(login.subscription_type, 40),
|
|
87
|
+
plan_label: clip(login.plan_label, 80),
|
|
80
88
|
auth_state: login.auth_state,
|
|
81
|
-
quota_windows: login.quota_windows
|
|
89
|
+
quota_windows: login.quota_windows
|
|
90
|
+
.filter((w) => typeof w.kind === 'string' && w.kind.length > 0)
|
|
91
|
+
.slice(0, 16)
|
|
92
|
+
.map((w) => ({
|
|
93
|
+
kind: clip(w.kind, 40),
|
|
94
|
+
used_percent: Math.min(100, Math.max(0, w.used_percent)),
|
|
95
|
+
resets_at: w.resets_at,
|
|
96
|
+
...(w.model_label ? { model_label: clip(w.model_label, 40) } : {}),
|
|
97
|
+
})),
|
|
82
98
|
conversations,
|
|
83
99
|
};
|
|
84
100
|
}
|
|
@@ -89,11 +105,13 @@ export function buildStatusBody(inputs) {
|
|
|
89
105
|
slots: { ...inputs.slots },
|
|
90
106
|
logins: inputs.logins.map((login) => loginBody(login, inputs.conversationsPerLogin.get(login.account_key) ?? 0)),
|
|
91
107
|
running: inputs.running.map((entry) => ({
|
|
92
|
-
run_id: entry.run_id,
|
|
108
|
+
run_id: clip(entry.run_id, 128),
|
|
93
109
|
agent_id: entry.agent_id,
|
|
94
|
-
|
|
110
|
+
...(entry.runtime ? { runtime: clip(entry.runtime, 40) } : {}),
|
|
111
|
+
conversation_key: clip(entry.conversation_key, 256),
|
|
95
112
|
kind: entry.kind,
|
|
96
|
-
|
|
113
|
+
// Never '' (the server reads it as a date): a time, or null.
|
|
114
|
+
started_at: entry.started_at || null,
|
|
97
115
|
peak_mem_mb: entry.peak_mem_mb ?? null,
|
|
98
116
|
...(entry.started_by_user_id ? { started_by_user_id: entry.started_by_user_id } : {}),
|
|
99
117
|
})),
|
package/dist/version.d.ts
CHANGED
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
* `package.json`, so a release bump that forgets this file fails the suite
|
|
8
8
|
* instead of shipping a `User-Agent` that lies about which build is calling.
|
|
9
9
|
*/
|
|
10
|
-
export declare const CLI_VERSION = "0.16.
|
|
10
|
+
export declare const CLI_VERSION = "0.16.8";
|
|
11
11
|
/** Sent on every HTTP request the CLI makes back into ProhostAI. */
|
|
12
|
-
export declare const USER_AGENT = "prohost-cli/0.16.
|
|
12
|
+
export declare const USER_AGENT = "prohost-cli/0.16.8";
|
package/dist/version.js
CHANGED
|
@@ -7,6 +7,6 @@
|
|
|
7
7
|
* `package.json`, so a release bump that forgets this file fails the suite
|
|
8
8
|
* instead of shipping a `User-Agent` that lies about which build is calling.
|
|
9
9
|
*/
|
|
10
|
-
export const CLI_VERSION = '0.16.
|
|
10
|
+
export const CLI_VERSION = '0.16.8';
|
|
11
11
|
/** Sent on every HTTP request the CLI makes back into ProhostAI. */
|
|
12
12
|
export const USER_AGENT = `prohost-cli/${CLI_VERSION}`;
|