@skrr-ai/cli 0.1.89 → 0.1.91
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/commands/machines/dedicated/exec.js +60 -14
- package/dist/commands/machines/dedicated/index.js +2 -0
- package/dist/commands/machines/dedicated/power/explain.d.ts +13 -0
- package/dist/commands/machines/dedicated/power/explain.js +36 -0
- package/dist/commands/machines/dedicated/power/index.d.ts +10 -0
- package/dist/commands/machines/dedicated/power/index.js +24 -0
- package/dist/commands/machines/dedicated/power/keep-awake.d.ts +20 -0
- package/dist/commands/machines/dedicated/power/keep-awake.js +69 -0
- package/dist/commands/machines/dedicated/power/set.d.ts +23 -0
- package/dist/commands/machines/dedicated/power/set.js +106 -0
- package/dist/commands/machines/dedicated/power/show.d.ts +13 -0
- package/dist/commands/machines/dedicated/power/show.js +36 -0
- package/dist/commands/tasks/start.d.ts +10 -0
- package/dist/commands/tasks/start.js +59 -0
- package/dist/lib/commitments.d.ts +1 -1
- package/dist/lib/commitments.js +4 -2
- package/dist/lib/dedicated-keep-awake.d.ts +19 -0
- package/dist/lib/dedicated-keep-awake.js +64 -0
- package/dist/lib/dedicated-power.d.ts +61 -0
- package/dist/lib/dedicated-power.js +243 -0
- package/dist/lib/format.d.ts +13 -0
- package/dist/lib/format.js +51 -0
- package/dist/lib/keychain.js +3 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.d.ts +32 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/computerWire.js +27 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/dedicatedRuntimeBusyWire.d.ts +107 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/dedicatedRuntimeBusyWire.js +151 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/dedicatedRuntimeWakeWire.d.ts +115 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/dedicatedRuntimeWakeWire.js +117 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +8 -3
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.d.ts +31 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/machineUuid.js +149 -9
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.d.ts +32 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/computerWire.js +24 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/dedicatedRuntimeBusyWire.d.ts +107 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/dedicatedRuntimeBusyWire.js +147 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/dedicatedRuntimeWakeWire.d.ts +115 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/dedicatedRuntimeWakeWire.js +113 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.d.ts +31 -7
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/machineUuid.js +144 -8
- package/dist/node_modules/@skrr-ai/auth-core/package.json +21 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +6393 -6278
- package/oclif.manifest.json +33192 -32826
- package/package.json +1 -1
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Dedicated Runtime busy-report wire contract (power-control task K2,
|
|
3
|
+
* `dedicated-runtime-power-and-demand-wake-2026-10-07.md` §7.3 / §13.5).
|
|
4
|
+
*
|
|
5
|
+
* Declared ONCE, here. The daemon is published and cannot import the API, so
|
|
6
|
+
* the capability name, the payload shape and its bounds live in this package,
|
|
7
|
+
* which every end can import (`@skrr-ai/auth-core/dedicated-runtime-busy-wire`).
|
|
8
|
+
* `dedicatedRuntimeBusyWire.test.ts` fails on a second spelling of the
|
|
9
|
+
* capability anywhere else in the repo.
|
|
10
|
+
*
|
|
11
|
+
* WHAT THE REPORT SAYS
|
|
12
|
+
* ---------------------------------------------------------------------------
|
|
13
|
+
* "Does anything run in the tenant workload slice?" — read by the guest daemon
|
|
14
|
+
* from cgroup v2 `skrr-workload.slice`, recursively (the slice root is empty by
|
|
15
|
+
* contract; processes live in leaves), with the root-owned sshd listener left
|
|
16
|
+
* out. It is a LOCAL read summarised into counts; no per-process list ever
|
|
17
|
+
* crosses the wire.
|
|
18
|
+
*
|
|
19
|
+
* FAIL CLOSED. `busy` is `true | false | 'unknown'`. Any failure to read — a
|
|
20
|
+
* missing slice, an unreadable file, a tree too large to walk, a quiesce in
|
|
21
|
+
* progress, an sshd that is not where the image promises — is `'unknown'`, and
|
|
22
|
+
* a reader MUST treat `'unknown'` as busy. `false` is only ever the daemon
|
|
23
|
+
* having positively read an empty slice.
|
|
24
|
+
*
|
|
25
|
+
* THE POLICY KNOB (OPEN PRODUCT QUESTION — not decided here)
|
|
26
|
+
* ---------------------------------------------------------------------------
|
|
27
|
+
* An idle tmux server or a shell prompt keeps a leaf populated forever. The
|
|
28
|
+
* owner decision is that tmux/SSH shells ARE protected, but whether an IDLE
|
|
29
|
+
* shell should pin the machine is undecided. So the report carries both
|
|
30
|
+
* readings and the server chooses:
|
|
31
|
+
*
|
|
32
|
+
* - `busy` the STRICT reading (`policy: 'strict'`): every
|
|
33
|
+
* process in the slice counts. This is the
|
|
34
|
+
* default and the only one a server should act
|
|
35
|
+
* on until the product question is answered.
|
|
36
|
+
* - `busyIgnoringIdleShells` the same read with the `idleShell` bucket
|
|
37
|
+
* removed. Classification is by process name
|
|
38
|
+
* (a shell or tmux with nothing else running),
|
|
39
|
+
* a HEURISTIC: it cannot see a shell loop, so
|
|
40
|
+
* it must never be the default.
|
|
41
|
+
*
|
|
42
|
+
* The `breakdown` says which bucket made it busy, for the "why" text.
|
|
43
|
+
*/
|
|
44
|
+
export declare const DEDICATED_RUNTIME_BUSY_REPORT_CAPABILITY = "dedicated_runtime_busy_report_v1";
|
|
45
|
+
/** The heartbeat key the report rides under. Sent only by a daemon that announced the capability. */
|
|
46
|
+
export declare const DEDICATED_RUNTIME_BUSY_HEARTBEAT_KEY = "dedicatedRuntimeBusy";
|
|
47
|
+
export declare const DEDICATED_RUNTIME_BUSY_REPORT_VERSION = 1;
|
|
48
|
+
/**
|
|
49
|
+
* `strict`: every process in the slice (less the root sshd listener) counts.
|
|
50
|
+
* The only value v1 sends; the field exists so a later relaxation is a new
|
|
51
|
+
* value rather than a silent change of meaning.
|
|
52
|
+
*/
|
|
53
|
+
export declare const DEDICATED_RUNTIME_BUSY_POLICIES: readonly ["strict"];
|
|
54
|
+
export type DedicatedRuntimeBusyPolicy = (typeof DEDICATED_RUNTIME_BUSY_POLICIES)[number];
|
|
55
|
+
/**
|
|
56
|
+
* Why the daemon could not give a definite answer, or `ok`. Anything but `ok`
|
|
57
|
+
* pairs with `busy: 'unknown'`.
|
|
58
|
+
*/
|
|
59
|
+
export declare const DEDICATED_RUNTIME_BUSY_SLICE_HEALTH: readonly ["ok", "not_a_guest", "slice_missing", "slice_unreadable", "ssh_not_in_slice", "tree_too_large", "quiesced", "read_error"];
|
|
60
|
+
export type DedicatedRuntimeBusySliceHealth = (typeof DEDICATED_RUNTIME_BUSY_SLICE_HEALTH)[number];
|
|
61
|
+
export declare const DEDICATED_RUNTIME_BUSY_LIMITS: {
|
|
62
|
+
/** Service leaf names carried for the "busy because of service X" text. */
|
|
63
|
+
readonly maxServiceNames: 8;
|
|
64
|
+
readonly maxServiceNameLength: 48;
|
|
65
|
+
/** Cgroup leaves the daemon will visit; more is `tree_too_large` -> unknown. */
|
|
66
|
+
readonly maxLeaves: 64;
|
|
67
|
+
readonly maxDepth: 4;
|
|
68
|
+
/** Processes the daemon classifies per read; the rest count as workload. */
|
|
69
|
+
readonly maxClassifiedPids: 256;
|
|
70
|
+
/** Hard ceiling on the serialized report. */
|
|
71
|
+
readonly maxSerializedBytes: 1024;
|
|
72
|
+
};
|
|
73
|
+
export interface DedicatedRuntimeBusyBreakdown {
|
|
74
|
+
/** Processes in non-service, non-ssh leaves (the `default` leaf, the slice root) that are not idle-shell class. */
|
|
75
|
+
workload: number;
|
|
76
|
+
/** Processes in `skrr-svc-*.scope` leaves: a declared service running, always-on by design. */
|
|
77
|
+
service: number;
|
|
78
|
+
/** SSH connection plumbing in `ssh.service` that is not the root listener (non-root sshd, the session helper) and other non-shell processes there. */
|
|
79
|
+
ssh: number;
|
|
80
|
+
/** Shell or tmux processes in `default` / `ssh.service` (heuristic by name; see header). */
|
|
81
|
+
idleShell: number;
|
|
82
|
+
/** Root-owned sshd processes left out of every count above. */
|
|
83
|
+
excludedSshd: number;
|
|
84
|
+
/** True when more processes existed than were classified; the rest are in `workload`. */
|
|
85
|
+
truncated: boolean;
|
|
86
|
+
/** Up to `maxServiceNames` service leaf names that have processes. */
|
|
87
|
+
services: string[];
|
|
88
|
+
}
|
|
89
|
+
export interface DedicatedRuntimeBusyReport {
|
|
90
|
+
version: typeof DEDICATED_RUNTIME_BUSY_REPORT_VERSION;
|
|
91
|
+
policy: DedicatedRuntimeBusyPolicy;
|
|
92
|
+
/** Strict reading. `'unknown'` MUST be treated as busy. */
|
|
93
|
+
busy: boolean | 'unknown';
|
|
94
|
+
/** Same read with the `idleShell` bucket removed; a heuristic, not the default. */
|
|
95
|
+
busyIgnoringIdleShells: boolean | 'unknown';
|
|
96
|
+
breakdown: DedicatedRuntimeBusyBreakdown;
|
|
97
|
+
/** ISO time the daemon read the slice. */
|
|
98
|
+
readAt: string;
|
|
99
|
+
sliceHealth: DedicatedRuntimeBusySliceHealth;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The reader's view of a daemon's heartbeat section. Anything malformed, from
|
|
103
|
+
* a daemon that did not announce the capability, or oversized is `null`, and
|
|
104
|
+
* the caller must then treat the machine as busy. Never trusts a field it did
|
|
105
|
+
* not validate; a value is clamped, not coerced to "idle".
|
|
106
|
+
*/
|
|
107
|
+
export declare function parseDedicatedRuntimeBusyReport(raw: unknown): DedicatedRuntimeBusyReport | null;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The Dedicated Runtime busy-report wire contract (power-control task K2,
|
|
4
|
+
* `dedicated-runtime-power-and-demand-wake-2026-10-07.md` §7.3 / §13.5).
|
|
5
|
+
*
|
|
6
|
+
* Declared ONCE, here. The daemon is published and cannot import the API, so
|
|
7
|
+
* the capability name, the payload shape and its bounds live in this package,
|
|
8
|
+
* which every end can import (`@skrr-ai/auth-core/dedicated-runtime-busy-wire`).
|
|
9
|
+
* `dedicatedRuntimeBusyWire.test.ts` fails on a second spelling of the
|
|
10
|
+
* capability anywhere else in the repo.
|
|
11
|
+
*
|
|
12
|
+
* WHAT THE REPORT SAYS
|
|
13
|
+
* ---------------------------------------------------------------------------
|
|
14
|
+
* "Does anything run in the tenant workload slice?" — read by the guest daemon
|
|
15
|
+
* from cgroup v2 `skrr-workload.slice`, recursively (the slice root is empty by
|
|
16
|
+
* contract; processes live in leaves), with the root-owned sshd listener left
|
|
17
|
+
* out. It is a LOCAL read summarised into counts; no per-process list ever
|
|
18
|
+
* crosses the wire.
|
|
19
|
+
*
|
|
20
|
+
* FAIL CLOSED. `busy` is `true | false | 'unknown'`. Any failure to read — a
|
|
21
|
+
* missing slice, an unreadable file, a tree too large to walk, a quiesce in
|
|
22
|
+
* progress, an sshd that is not where the image promises — is `'unknown'`, and
|
|
23
|
+
* a reader MUST treat `'unknown'` as busy. `false` is only ever the daemon
|
|
24
|
+
* having positively read an empty slice.
|
|
25
|
+
*
|
|
26
|
+
* THE POLICY KNOB (OPEN PRODUCT QUESTION — not decided here)
|
|
27
|
+
* ---------------------------------------------------------------------------
|
|
28
|
+
* An idle tmux server or a shell prompt keeps a leaf populated forever. The
|
|
29
|
+
* owner decision is that tmux/SSH shells ARE protected, but whether an IDLE
|
|
30
|
+
* shell should pin the machine is undecided. So the report carries both
|
|
31
|
+
* readings and the server chooses:
|
|
32
|
+
*
|
|
33
|
+
* - `busy` the STRICT reading (`policy: 'strict'`): every
|
|
34
|
+
* process in the slice counts. This is the
|
|
35
|
+
* default and the only one a server should act
|
|
36
|
+
* on until the product question is answered.
|
|
37
|
+
* - `busyIgnoringIdleShells` the same read with the `idleShell` bucket
|
|
38
|
+
* removed. Classification is by process name
|
|
39
|
+
* (a shell or tmux with nothing else running),
|
|
40
|
+
* a HEURISTIC: it cannot see a shell loop, so
|
|
41
|
+
* it must never be the default.
|
|
42
|
+
*
|
|
43
|
+
* The `breakdown` says which bucket made it busy, for the "why" text.
|
|
44
|
+
*/
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.DEDICATED_RUNTIME_BUSY_LIMITS = exports.DEDICATED_RUNTIME_BUSY_SLICE_HEALTH = exports.DEDICATED_RUNTIME_BUSY_POLICIES = exports.DEDICATED_RUNTIME_BUSY_REPORT_VERSION = exports.DEDICATED_RUNTIME_BUSY_HEARTBEAT_KEY = exports.DEDICATED_RUNTIME_BUSY_REPORT_CAPABILITY = void 0;
|
|
47
|
+
exports.parseDedicatedRuntimeBusyReport = parseDedicatedRuntimeBusyReport;
|
|
48
|
+
exports.DEDICATED_RUNTIME_BUSY_REPORT_CAPABILITY = 'dedicated_runtime_busy_report_v1';
|
|
49
|
+
/** The heartbeat key the report rides under. Sent only by a daemon that announced the capability. */
|
|
50
|
+
exports.DEDICATED_RUNTIME_BUSY_HEARTBEAT_KEY = 'dedicatedRuntimeBusy';
|
|
51
|
+
exports.DEDICATED_RUNTIME_BUSY_REPORT_VERSION = 1;
|
|
52
|
+
/**
|
|
53
|
+
* `strict`: every process in the slice (less the root sshd listener) counts.
|
|
54
|
+
* The only value v1 sends; the field exists so a later relaxation is a new
|
|
55
|
+
* value rather than a silent change of meaning.
|
|
56
|
+
*/
|
|
57
|
+
exports.DEDICATED_RUNTIME_BUSY_POLICIES = ['strict'];
|
|
58
|
+
/**
|
|
59
|
+
* Why the daemon could not give a definite answer, or `ok`. Anything but `ok`
|
|
60
|
+
* pairs with `busy: 'unknown'`.
|
|
61
|
+
*/
|
|
62
|
+
exports.DEDICATED_RUNTIME_BUSY_SLICE_HEALTH = [
|
|
63
|
+
'ok',
|
|
64
|
+
'not_a_guest',
|
|
65
|
+
'slice_missing',
|
|
66
|
+
'slice_unreadable',
|
|
67
|
+
'ssh_not_in_slice',
|
|
68
|
+
'tree_too_large',
|
|
69
|
+
'quiesced',
|
|
70
|
+
'read_error',
|
|
71
|
+
];
|
|
72
|
+
exports.DEDICATED_RUNTIME_BUSY_LIMITS = {
|
|
73
|
+
/** Service leaf names carried for the "busy because of service X" text. */
|
|
74
|
+
maxServiceNames: 8,
|
|
75
|
+
maxServiceNameLength: 48,
|
|
76
|
+
/** Cgroup leaves the daemon will visit; more is `tree_too_large` -> unknown. */
|
|
77
|
+
maxLeaves: 64,
|
|
78
|
+
maxDepth: 4,
|
|
79
|
+
/** Processes the daemon classifies per read; the rest count as workload. */
|
|
80
|
+
maxClassifiedPids: 256,
|
|
81
|
+
/** Hard ceiling on the serialized report. */
|
|
82
|
+
maxSerializedBytes: 1024,
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* The reader's view of a daemon's heartbeat section. Anything malformed, from
|
|
86
|
+
* a daemon that did not announce the capability, or oversized is `null`, and
|
|
87
|
+
* the caller must then treat the machine as busy. Never trusts a field it did
|
|
88
|
+
* not validate; a value is clamped, not coerced to "idle".
|
|
89
|
+
*/
|
|
90
|
+
function parseDedicatedRuntimeBusyReport(raw) {
|
|
91
|
+
if (!raw || typeof raw !== 'object')
|
|
92
|
+
return null;
|
|
93
|
+
const r = raw;
|
|
94
|
+
if (r.version !== exports.DEDICATED_RUNTIME_BUSY_REPORT_VERSION)
|
|
95
|
+
return null;
|
|
96
|
+
if (!exports.DEDICATED_RUNTIME_BUSY_POLICIES.includes(r.policy))
|
|
97
|
+
return null;
|
|
98
|
+
const tri = (v) => v === true || v === false || v === 'unknown' ? v : undefined;
|
|
99
|
+
const busy = tri(r.busy);
|
|
100
|
+
const ignoring = tri(r.busyIgnoringIdleShells);
|
|
101
|
+
if (busy === undefined || ignoring === undefined)
|
|
102
|
+
return null;
|
|
103
|
+
if (!exports.DEDICATED_RUNTIME_BUSY_SLICE_HEALTH.includes(r.sliceHealth)) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
const readAtMs = typeof r.readAt === 'string' ? Date.parse(r.readAt) : NaN;
|
|
107
|
+
if (!Number.isFinite(readAtMs))
|
|
108
|
+
return null;
|
|
109
|
+
const b = r.breakdown;
|
|
110
|
+
if (!b || typeof b !== 'object')
|
|
111
|
+
return null;
|
|
112
|
+
const count = (v) => typeof v === 'number' && Number.isSafeInteger(v) && v >= 0 ? v : null;
|
|
113
|
+
const workload = count(b.workload);
|
|
114
|
+
const service = count(b.service);
|
|
115
|
+
const ssh = count(b.ssh);
|
|
116
|
+
const idleShell = count(b.idleShell);
|
|
117
|
+
const excludedSshd = count(b.excludedSshd);
|
|
118
|
+
if (workload === null ||
|
|
119
|
+
service === null ||
|
|
120
|
+
ssh === null ||
|
|
121
|
+
idleShell === null ||
|
|
122
|
+
excludedSshd === null ||
|
|
123
|
+
typeof b.truncated !== 'boolean' ||
|
|
124
|
+
!Array.isArray(b.services)) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
const services = b.services
|
|
128
|
+
.filter((s) => typeof s === 'string')
|
|
129
|
+
.slice(0, exports.DEDICATED_RUNTIME_BUSY_LIMITS.maxServiceNames)
|
|
130
|
+
.map((s) => s.slice(0, exports.DEDICATED_RUNTIME_BUSY_LIMITS.maxServiceNameLength));
|
|
131
|
+
const report = {
|
|
132
|
+
version: exports.DEDICATED_RUNTIME_BUSY_REPORT_VERSION,
|
|
133
|
+
policy: r.policy,
|
|
134
|
+
busy,
|
|
135
|
+
busyIgnoringIdleShells: ignoring,
|
|
136
|
+
breakdown: {
|
|
137
|
+
workload,
|
|
138
|
+
service,
|
|
139
|
+
ssh,
|
|
140
|
+
idleShell,
|
|
141
|
+
excludedSshd,
|
|
142
|
+
truncated: b.truncated,
|
|
143
|
+
services,
|
|
144
|
+
},
|
|
145
|
+
readAt: new Date(readAtMs).toISOString(),
|
|
146
|
+
sliceHealth: r.sliceHealth,
|
|
147
|
+
};
|
|
148
|
+
if (JSON.stringify(report).length > exports.DEDICATED_RUNTIME_BUSY_LIMITS.maxSerializedBytes)
|
|
149
|
+
return null;
|
|
150
|
+
return report;
|
|
151
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Dedicated Runtime wake-progress wire contract (power-control task W5,
|
|
3
|
+
* `dedicated-runtime-power-and-demand-wake-2026-10-07.md` §5.3, §7.2, §9).
|
|
4
|
+
*
|
|
5
|
+
* Declared ONCE, here, for the same reason `computerWire.ts` is: the browser,
|
|
6
|
+
* the React Native app and the CLI import it, and none of them may spell the
|
|
7
|
+
* event, the capability or a code a second time. `dedicatedRuntimeWakeWire.test.ts`
|
|
8
|
+
* fails on a second spelling in the API.
|
|
9
|
+
*
|
|
10
|
+
* WHAT IT IS
|
|
11
|
+
* ---------------------------------------------------------------------------
|
|
12
|
+
* A person opens a terminal, an SSH channel, a service call or the Computer on a
|
|
13
|
+
* STOPPED Dedicated Runtime. That is wake progress, not an error: the relay asks
|
|
14
|
+
* `requestWake` (source `person`) to start the machine, then tells THAT request,
|
|
15
|
+
* in stages, how far the start has got, until the machine is assignable and the
|
|
16
|
+
* original request is served, or a bound runs out and it says why and what to do.
|
|
17
|
+
*
|
|
18
|
+
* THE CLIENT ANNOUNCES IT
|
|
19
|
+
* ---------------------------------------------------------------------------
|
|
20
|
+
* A client that has not announced `dedicated_wake_progress_v1` in the open
|
|
21
|
+
* request's `capabilities` array is NEVER sent `dedicated:wake:progress` and is
|
|
22
|
+
* never made to wait: it gets an immediate typed refusal instead. (A client
|
|
23
|
+
* socket has no registration step to announce on, so the announcement rides each
|
|
24
|
+
* request — stateless, nothing held in the relay.)
|
|
25
|
+
*
|
|
26
|
+
* THE VOCABULARY
|
|
27
|
+
* ---------------------------------------------------------------------------
|
|
28
|
+
* `phase` uses the cold-start measurement's phase names
|
|
29
|
+
* (`scripts/dedicated-runtime/measure-cold-start.js` `COLD_START_PHASES`), so
|
|
30
|
+
* what the person sees and what F4 measures are the same words. A spec holds the
|
|
31
|
+
* two lists equal.
|
|
32
|
+
*
|
|
33
|
+
* NOT A SPINNER WITHOUT A BOUND
|
|
34
|
+
* ---------------------------------------------------------------------------
|
|
35
|
+
* `boundMs` is carried on every event so a surface can show elapsed-of-bound.
|
|
36
|
+
* The bound sits ABOVE a slow-but-working start (design §9): running out says
|
|
37
|
+
* "this is taking longer than expected" and the machine is left starting; it is
|
|
38
|
+
* never an accusation that the machine is dead.
|
|
39
|
+
*/
|
|
40
|
+
/** API -> client, on the same socket as the request it belongs to. */
|
|
41
|
+
export declare const DEDICATED_WAKE_EVENTS: {
|
|
42
|
+
readonly progress: "dedicated:wake:progress";
|
|
43
|
+
};
|
|
44
|
+
/** Announced in the open request's `capabilities` array. */
|
|
45
|
+
export declare const DEDICATED_WAKE_CAPABILITIES: {
|
|
46
|
+
readonly progress: "dedicated_wake_progress_v1";
|
|
47
|
+
};
|
|
48
|
+
export type DedicatedWakeCapability = (typeof DEDICATED_WAKE_CAPABILITIES)[keyof typeof DEDICATED_WAKE_CAPABILITIES];
|
|
49
|
+
/** Same names, same order as `WAKE_PHASES` in api/server/services/DedicatedRuntime/wakePhases.js (pinned by a test). */
|
|
50
|
+
export declare const DEDICATED_WAKE_PHASES: readonly ["start_requested", "provider_start_accepted", "instance_running", "daemon_connected", "first_heartbeat", "assignable"];
|
|
51
|
+
export type DedicatedWakePhase = (typeof DEDICATED_WAKE_PHASES)[number];
|
|
52
|
+
/**
|
|
53
|
+
* - `waking` a start is in flight; `phase` says how far.
|
|
54
|
+
* - `ready` assignable; the original request is about to be served.
|
|
55
|
+
* - `deferred` the machine is stopping; nothing was started. Retry after `retryAfterSeconds`.
|
|
56
|
+
* - `refused` the start was refused, with `code`, `reason`, `detail`, `fix`.
|
|
57
|
+
* - `timed_out` the bound ran out while it was still starting. Not a failure of the machine.
|
|
58
|
+
*/
|
|
59
|
+
export declare const DEDICATED_WAKE_STATES: readonly ["waking", "ready", "deferred", "refused", "timed_out"];
|
|
60
|
+
export type DedicatedWakeState = (typeof DEDICATED_WAKE_STATES)[number];
|
|
61
|
+
/** The surfaces a wake can be asked from. */
|
|
62
|
+
export declare const DEDICATED_WAKE_SURFACES: readonly ["terminal", "ssh", "services", "templates", "computer", "http"];
|
|
63
|
+
export type DedicatedWakeSurface = (typeof DEDICATED_WAKE_SURFACES)[number];
|
|
64
|
+
/**
|
|
65
|
+
* Typed refusals. Each is a different fact with a different next step; none of
|
|
66
|
+
* them is the generic "Dedicated Runtime dispatch was refused".
|
|
67
|
+
*/
|
|
68
|
+
export declare const DEDICATED_WAKE_CODES: {
|
|
69
|
+
/** Stopped, and this request did not (or could not) wake it. */
|
|
70
|
+
readonly stopped: "DEDICATED_RUNTIME_STOPPED";
|
|
71
|
+
/** A stop is finishing; retry when it has. */
|
|
72
|
+
readonly stopping: "DEDICATED_RUNTIME_STOPPING";
|
|
73
|
+
/** A start is in flight (ours or someone's). */
|
|
74
|
+
readonly starting: "DEDICATED_RUNTIME_STARTING";
|
|
75
|
+
/** The bound ran out while it was still starting. */
|
|
76
|
+
readonly timeout: "DEDICATED_RUNTIME_WAKE_TIMEOUT";
|
|
77
|
+
/** The start was refused: the plan no longer includes the machine. */
|
|
78
|
+
readonly entitlement: "DEDICATED_RUNTIME_WAKE_REFUSED_ENTITLEMENT";
|
|
79
|
+
/** The start was refused: the spend cap was reached. */
|
|
80
|
+
readonly spendCap: "DEDICATED_RUNTIME_WAKE_REFUSED_SPEND_CAP";
|
|
81
|
+
/** Any other refusal; `reason` names it. */
|
|
82
|
+
readonly refused: "DEDICATED_RUNTIME_WAKE_REFUSED";
|
|
83
|
+
/** The start was requested and the machine fell back to stopped or failed. */
|
|
84
|
+
readonly failed: "DEDICATED_RUNTIME_WAKE_FAILED";
|
|
85
|
+
};
|
|
86
|
+
export type DedicatedWakeCode = (typeof DEDICATED_WAKE_CODES)[keyof typeof DEDICATED_WAKE_CODES];
|
|
87
|
+
/**
|
|
88
|
+
* How long a surface waits for a start before saying it is taking longer than
|
|
89
|
+
* expected. Above the slow-but-working case: a cold start on a fresh guest
|
|
90
|
+
* takes 25-30 s for the browser alone, and the AMI boot is longer. It is a
|
|
91
|
+
* bound on what we show, never a verdict on the machine.
|
|
92
|
+
*/
|
|
93
|
+
export declare const DEDICATED_WAKE_BOUND_MS = 180000;
|
|
94
|
+
/** How often the relay re-reads the lease while waiting. */
|
|
95
|
+
export declare const DEDICATED_WAKE_POLL_MS = 2000;
|
|
96
|
+
export interface DedicatedWakeProgress {
|
|
97
|
+
leaseId: string;
|
|
98
|
+
surface: DedicatedWakeSurface;
|
|
99
|
+
/** The id of the request this belongs to (`requestId`, `channelId`, ...). */
|
|
100
|
+
ref?: string;
|
|
101
|
+
state: DedicatedWakeState;
|
|
102
|
+
/** Present while `waking`, and on `timed_out` (where the machine had got to). */
|
|
103
|
+
phase?: DedicatedWakePhase;
|
|
104
|
+
elapsedMs: number;
|
|
105
|
+
boundMs: number;
|
|
106
|
+
/** Power reason (e.g. `wake_refused_spend_cap`) or a lifecycle reason. */
|
|
107
|
+
reason?: string;
|
|
108
|
+
/** One of `DEDICATED_WAKE_CODES` on `refused`, `deferred` and `timed_out`. */
|
|
109
|
+
code?: DedicatedWakeCode;
|
|
110
|
+
detail?: string;
|
|
111
|
+
/** What the person can do next. */
|
|
112
|
+
fix?: string | null;
|
|
113
|
+
retryAfterSeconds?: number;
|
|
114
|
+
}
|
|
115
|
+
export declare function clientAnnouncesWakeProgress(capabilities: unknown): boolean;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The Dedicated Runtime wake-progress wire contract (power-control task W5,
|
|
4
|
+
* `dedicated-runtime-power-and-demand-wake-2026-10-07.md` §5.3, §7.2, §9).
|
|
5
|
+
*
|
|
6
|
+
* Declared ONCE, here, for the same reason `computerWire.ts` is: the browser,
|
|
7
|
+
* the React Native app and the CLI import it, and none of them may spell the
|
|
8
|
+
* event, the capability or a code a second time. `dedicatedRuntimeWakeWire.test.ts`
|
|
9
|
+
* fails on a second spelling in the API.
|
|
10
|
+
*
|
|
11
|
+
* WHAT IT IS
|
|
12
|
+
* ---------------------------------------------------------------------------
|
|
13
|
+
* A person opens a terminal, an SSH channel, a service call or the Computer on a
|
|
14
|
+
* STOPPED Dedicated Runtime. That is wake progress, not an error: the relay asks
|
|
15
|
+
* `requestWake` (source `person`) to start the machine, then tells THAT request,
|
|
16
|
+
* in stages, how far the start has got, until the machine is assignable and the
|
|
17
|
+
* original request is served, or a bound runs out and it says why and what to do.
|
|
18
|
+
*
|
|
19
|
+
* THE CLIENT ANNOUNCES IT
|
|
20
|
+
* ---------------------------------------------------------------------------
|
|
21
|
+
* A client that has not announced `dedicated_wake_progress_v1` in the open
|
|
22
|
+
* request's `capabilities` array is NEVER sent `dedicated:wake:progress` and is
|
|
23
|
+
* never made to wait: it gets an immediate typed refusal instead. (A client
|
|
24
|
+
* socket has no registration step to announce on, so the announcement rides each
|
|
25
|
+
* request — stateless, nothing held in the relay.)
|
|
26
|
+
*
|
|
27
|
+
* THE VOCABULARY
|
|
28
|
+
* ---------------------------------------------------------------------------
|
|
29
|
+
* `phase` uses the cold-start measurement's phase names
|
|
30
|
+
* (`scripts/dedicated-runtime/measure-cold-start.js` `COLD_START_PHASES`), so
|
|
31
|
+
* what the person sees and what F4 measures are the same words. A spec holds the
|
|
32
|
+
* two lists equal.
|
|
33
|
+
*
|
|
34
|
+
* NOT A SPINNER WITHOUT A BOUND
|
|
35
|
+
* ---------------------------------------------------------------------------
|
|
36
|
+
* `boundMs` is carried on every event so a surface can show elapsed-of-bound.
|
|
37
|
+
* The bound sits ABOVE a slow-but-working start (design §9): running out says
|
|
38
|
+
* "this is taking longer than expected" and the machine is left starting; it is
|
|
39
|
+
* never an accusation that the machine is dead.
|
|
40
|
+
*/
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.DEDICATED_WAKE_POLL_MS = exports.DEDICATED_WAKE_BOUND_MS = exports.DEDICATED_WAKE_CODES = exports.DEDICATED_WAKE_SURFACES = exports.DEDICATED_WAKE_STATES = exports.DEDICATED_WAKE_PHASES = exports.DEDICATED_WAKE_CAPABILITIES = exports.DEDICATED_WAKE_EVENTS = void 0;
|
|
43
|
+
exports.clientAnnouncesWakeProgress = clientAnnouncesWakeProgress;
|
|
44
|
+
/** API -> client, on the same socket as the request it belongs to. */
|
|
45
|
+
exports.DEDICATED_WAKE_EVENTS = {
|
|
46
|
+
progress: 'dedicated:wake:progress',
|
|
47
|
+
};
|
|
48
|
+
/** Announced in the open request's `capabilities` array. */
|
|
49
|
+
exports.DEDICATED_WAKE_CAPABILITIES = {
|
|
50
|
+
progress: 'dedicated_wake_progress_v1',
|
|
51
|
+
};
|
|
52
|
+
/** Same names, same order as `WAKE_PHASES` in api/server/services/DedicatedRuntime/wakePhases.js (pinned by a test). */
|
|
53
|
+
exports.DEDICATED_WAKE_PHASES = [
|
|
54
|
+
'start_requested',
|
|
55
|
+
'provider_start_accepted',
|
|
56
|
+
'instance_running',
|
|
57
|
+
'daemon_connected',
|
|
58
|
+
'first_heartbeat',
|
|
59
|
+
'assignable',
|
|
60
|
+
];
|
|
61
|
+
/**
|
|
62
|
+
* - `waking` a start is in flight; `phase` says how far.
|
|
63
|
+
* - `ready` assignable; the original request is about to be served.
|
|
64
|
+
* - `deferred` the machine is stopping; nothing was started. Retry after `retryAfterSeconds`.
|
|
65
|
+
* - `refused` the start was refused, with `code`, `reason`, `detail`, `fix`.
|
|
66
|
+
* - `timed_out` the bound ran out while it was still starting. Not a failure of the machine.
|
|
67
|
+
*/
|
|
68
|
+
exports.DEDICATED_WAKE_STATES = [
|
|
69
|
+
'waking',
|
|
70
|
+
'ready',
|
|
71
|
+
'deferred',
|
|
72
|
+
'refused',
|
|
73
|
+
'timed_out',
|
|
74
|
+
];
|
|
75
|
+
/** The surfaces a wake can be asked from. */
|
|
76
|
+
exports.DEDICATED_WAKE_SURFACES = [
|
|
77
|
+
'terminal',
|
|
78
|
+
'ssh',
|
|
79
|
+
'services',
|
|
80
|
+
'templates',
|
|
81
|
+
'computer',
|
|
82
|
+
'http',
|
|
83
|
+
];
|
|
84
|
+
/**
|
|
85
|
+
* Typed refusals. Each is a different fact with a different next step; none of
|
|
86
|
+
* them is the generic "Dedicated Runtime dispatch was refused".
|
|
87
|
+
*/
|
|
88
|
+
exports.DEDICATED_WAKE_CODES = {
|
|
89
|
+
/** Stopped, and this request did not (or could not) wake it. */
|
|
90
|
+
stopped: 'DEDICATED_RUNTIME_STOPPED',
|
|
91
|
+
/** A stop is finishing; retry when it has. */
|
|
92
|
+
stopping: 'DEDICATED_RUNTIME_STOPPING',
|
|
93
|
+
/** A start is in flight (ours or someone's). */
|
|
94
|
+
starting: 'DEDICATED_RUNTIME_STARTING',
|
|
95
|
+
/** The bound ran out while it was still starting. */
|
|
96
|
+
timeout: 'DEDICATED_RUNTIME_WAKE_TIMEOUT',
|
|
97
|
+
/** The start was refused: the plan no longer includes the machine. */
|
|
98
|
+
entitlement: 'DEDICATED_RUNTIME_WAKE_REFUSED_ENTITLEMENT',
|
|
99
|
+
/** The start was refused: the spend cap was reached. */
|
|
100
|
+
spendCap: 'DEDICATED_RUNTIME_WAKE_REFUSED_SPEND_CAP',
|
|
101
|
+
/** Any other refusal; `reason` names it. */
|
|
102
|
+
refused: 'DEDICATED_RUNTIME_WAKE_REFUSED',
|
|
103
|
+
/** The start was requested and the machine fell back to stopped or failed. */
|
|
104
|
+
failed: 'DEDICATED_RUNTIME_WAKE_FAILED',
|
|
105
|
+
};
|
|
106
|
+
/**
|
|
107
|
+
* How long a surface waits for a start before saying it is taking longer than
|
|
108
|
+
* expected. Above the slow-but-working case: a cold start on a fresh guest
|
|
109
|
+
* takes 25-30 s for the browser alone, and the AMI boot is longer. It is a
|
|
110
|
+
* bound on what we show, never a verdict on the machine.
|
|
111
|
+
*/
|
|
112
|
+
exports.DEDICATED_WAKE_BOUND_MS = 180_000;
|
|
113
|
+
/** How often the relay re-reads the lease while waiting. */
|
|
114
|
+
exports.DEDICATED_WAKE_POLL_MS = 2_000;
|
|
115
|
+
function clientAnnouncesWakeProgress(capabilities) {
|
|
116
|
+
return Array.isArray(capabilities) && capabilities.includes(exports.DEDICATED_WAKE_CAPABILITIES.progress);
|
|
117
|
+
}
|
|
@@ -30,7 +30,7 @@ export { buildProof as buildDeviceProof, generateDeviceKeyPair, jwkThumbprint, n
|
|
|
30
30
|
export { DPOP_HEADER, DPOP_MAX_AGE_SECONDS, DPOP_PROOF_INVALID, DPOP_PROOF_REQUIRED, DPOP_PROOF_TYP, DPOP_PROOF_VERIFY_UNAVAILABLE, accessTokenHash, createDpopKey, isAth, isJwkThumbprint, normalizeDpopHtu, verifyDpopProof, type DpopKey, type DpopProofClaims, type DpopProofRequest, type DpopVerifyFailureReason, type DpopVerifyOptions, type DpopVerifyResult, } from './dpop.js';
|
|
31
31
|
export { initCredEnvelope, resetCredEnvelope, shutdownCredEnvelope, isCredEnvelopeActive, hasCredEnvelopePathConflict, describeCredEnvelopeState, splitKeyConvergencePolicy, maybeEncryptForWrite, maybeDecryptOnRead, DEFAULT_UNREADABLE_CREDENTIAL_HINT, type DecryptOnReadOptions, __wrappedDekFilePathForTest, __setStateForTest as __setCredEnvelopeStateForTest, __getStateForTest as __getCredEnvelopeStateForTest, __resetShutdownGuardForTest, type ReadTransformResult, } from './credentialEnvelopeBridge.js';
|
|
32
32
|
export { initDeviceIdentity, resetDeviceIdentity, signServerRequest, enrollWithServer, clearEnrollmentMarker, isDeviceIdentityActive, getDevicePublicKey, describeDeviceIdentityState, describeDeviceKeySplit, __publicKeyPathForTest, __privateKeyPathForTest, __enrollmentMarkerPathForTest, __enrollmentBackoffPathForTest, __setStateForTest as __setDeviceIdentityStateForTest, __getStateForTest as __getDeviceIdentityStateForTest, type EnrollmentResult, } from './deviceIdentityBridge.js';
|
|
33
|
-
export { getMachineUuid, hostedRuntimeIdOverride, HOSTED_RUNTIME_MACHINE_SOURCES, __resetMachineUuidCacheForTest, } from './machineUuid.js';
|
|
33
|
+
export { getMachineUuid, getHardwareMachineUuid, setMachineUuidProfile, getMachineUuidProfile, qualifyMachineUuid, MACHINE_IDENTITY_FILENAME, hostedRuntimeIdOverride, HOSTED_RUNTIME_MACHINE_SOURCES, __resetMachineUuidCacheForTest, } from './machineUuid.js';
|
|
34
34
|
export { ensureMachineDaemonId, legacyDaemonUuids, __resetCachedDaemonIdForTest, } from './machineId.js';
|
|
35
35
|
export { PAIR_AAD_PREFIX, PAIR_AAD_MAX_LEN, PAIR_BUNDLE_MAX_BASE64_LEN, PAIR_NONCE_LEN, PAIR_PUBKEY_LEN, PAIR_SECRET_LEN, PairBundleError, assemblePairBundleBase64, base64ToUint8Array as pairBase64ToUint8Array, base64UrlToUint8Array as pairBase64UrlToUint8Array, buildPairAad, buildPairUrl, generatePairKeyPair, openPairBundleBase64, parsePairBundle, parsePairPlaintext, parsePairUrl, uint8ArrayToBase64 as pairUint8ArrayToBase64, uint8ArrayToBase64Url as pairUint8ArrayToBase64Url, type AssembleBundleOptions as PairAssembleBundleOptions, type OpenBundleOptions as PairOpenBundleOptions, type PairBundle, type PairBundleErrorCode, type PairKeyPair, type PairPlaintextV1, type PairUrlFields, } from './daemonPair.js';
|
|
36
36
|
export { HARNESS_TIERS, getHarnessTier, credentialPolicyForTier, tierPermitsConfiguredAutoMode, type HarnessTrustTier, type CredentialDeliveryPolicy, type CredentialMode, } from './harnessTrust.js';
|
|
@@ -24,9 +24,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
24
24
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
25
|
exports.runHeadersHelper = exports.SENTINEL_TRIGGERING_FAILURES = exports.__resetAuthHelperFailureReasonForTest = exports.getLastAuthHelperFailureReason = exports.getDefaultHelperTtlMs = exports.invokeAuthHelper = exports.AuthHelperUnavailableError = exports.AuthHelperUntrustedError = exports.isStaticTokenKind = exports.PERSONAL_ACCESS_TOKEN_PREFIX = exports.CI_TOKEN_PREFIX = exports.classifyTokenKind = exports.invalidateAuthHelperCache = exports.__resetCredentialResolverForTest = exports.CREDENTIAL_PRECEDENCE = exports.CredentialResolver = exports.__setFdReaderForTest = exports.readAuthFromFd = exports.createRefreshScheduler = exports.UNKNOWN_401_BUDGET = exports.__resetUnknown401StreaksForTest = exports.__refreshDiagnostics = exports.installLockExitHandlers = exports.clearReauthState = exports.needsReauthState = exports.persistReauthState = exports.withAuthLock = exports.revokeDaemonRefreshSession = exports.refreshDaemonToken = exports.classifyRefreshResponse = exports.EXIT_NEEDS_REAUTH = exports.reauthCommand = exports.formatReauthMessage = exports.handleMidStreamAuthExpiry = exports.isAuthExpiredSseEvent = exports.decodeJwtPayload = exports.decodeJwtExpiry = exports.TransientAuthFailure = exports.PermanentAuthFailure = exports.emitAuthTelemetry = exports.getAuthBinaryName = exports.getAuthKillSwitches = exports.getAuthConfigDir = exports.getAuthLogger = exports.configureAuthCore = exports.OAUTH_CLI_SCOPE = exports.isDaemonScope = exports.VALID_DAEMON_SCOPE_SET = exports.ALL_DAEMON_SCOPES = exports.SCOPES = void 0;
|
|
26
26
|
exports.jwkThumbprint = exports.generateDeviceKeyPair = exports.buildDeviceProof = exports.zeroizeKekCaches = exports.WindowsKek = exports.registerZeroizeHook = exports.MacosKek = exports.LinuxKek = exports.KekUnavailableError = exports.UnavailableKek = exports.InMemoryKek = exports.getKekStrategy = exports.__setKekStrategyForTest = exports.credEnvelopeWrap = exports.credEnvelopeUnwrap = exports.credEnvelopeSerialize = exports.credSealBuffer = exports.credOpenBuffer = exports.CRED_KEY_LEN = exports.isCredEnvelopeString = exports.generateDek = exports.CRED_ENVELOPE_MAGIC = exports.credEnvelopeEncrypt = exports.credEnvelopeDeserialize = exports.credEnvelopeDecrypt = exports.buildCredentialAad = exports.isValidRecoveryCode = exports.normalizeRecoveryCode = exports.parseRecoveryCode = exports.formatRecoveryCode = exports.MAX_TTL_DAYS = exports.MIN_TTL_DAYS = exports.parseTtlDays = exports.LoginExchangeError = exports.LoginInitError = exports.loginWithLocalhost = exports.LocalCallbackMalformedError = exports.LocalCallbackDeniedError = exports.LocalCallbackStateMismatchError = exports.LocalCallbackTimeoutError = exports.LocalCallbackBindError = exports.LocalCallbackError = exports.DEFAULT_LOGIN_TIMEOUT_MS = exports.startLocalCallback = exports.verifyChallenge = exports.safeEqual = exports.generateState = exports.challenge = exports.generateVerifier = exports.invalidateHeadersHelperCache = void 0;
|
|
27
|
-
exports.
|
|
28
|
-
exports.
|
|
29
|
-
exports.consolidateProfileState = exports.profileStateFilePathsToClear = exports.profileStateFileLocations = exports.resolveProfileStateFile = exports.resolveProfileStateDir = exports.legacyProfileStateDir = exports.profileStateDir = exports.SUPERSEDED_COPY_SUFFIX = exports.SUPERSEDED_MARKER_SUFFIX = exports.PROFILES_SEGMENT = exports.isConfigRootOverridden = exports.configRootPath = exports.resolveConfigRoot = exports.verifyManifest = exports.verifyArtifact = exports.isTrustedArtifactOrigin = exports.getDeltaFor = exports.buildManifestMessage = exports.buildArtifactMessage = exports.TRUSTED_FEED_ORIGINS = exports.MAX_SIGS = exports.OVERSKY_RELEASE_PUBLIC_KEYS = exports.resolveFirstPartyHarnessChannel = exports.resolveChannelManifestUrl = exports.isFirstPartyHarnessChannel = exports.firstPartyHarnessFeedCandidates = exports.firstPartyHarnessFeedBase = exports.firstPartyHarnessChannelPrefix = exports.FIRST_PARTY_HARNESS_CHANNELS = exports.DEFAULT_FIRST_PARTY_HARNESS_CHANNEL = exports.migrateFirstPartyHarnessHome = exports.linkFirstPartyHarnessAliases = exports.firstPartyHarnessInstalledBinaryPath = exports.firstPartyHarnessHomeDir = exports.firstPartyHarnessBinDir = exports.FIRST_PARTY_HARNESS_PROVENANCE_SUFFIX = exports.FIRST_PARTY_HARNESS_PREVIOUS_SUFFIX = exports.describeLegacyState = exports.findLegacyLocalState = void 0;
|
|
27
|
+
exports.qualifyMachineUuid = exports.getMachineUuidProfile = exports.setMachineUuidProfile = exports.getHardwareMachineUuid = exports.getMachineUuid = exports.__getDeviceIdentityStateForTest = exports.__setDeviceIdentityStateForTest = exports.__enrollmentBackoffPathForTest = exports.__enrollmentMarkerPathForTest = exports.__privateKeyPathForTest = exports.__publicKeyPathForTest = exports.describeDeviceKeySplit = exports.describeDeviceIdentityState = exports.getDevicePublicKey = exports.isDeviceIdentityActive = exports.clearEnrollmentMarker = exports.enrollWithServer = exports.signServerRequest = exports.resetDeviceIdentity = exports.initDeviceIdentity = exports.__resetShutdownGuardForTest = exports.__getCredEnvelopeStateForTest = exports.__setCredEnvelopeStateForTest = exports.__wrappedDekFilePathForTest = exports.DEFAULT_UNREADABLE_CREDENTIAL_HINT = exports.maybeDecryptOnRead = exports.maybeEncryptForWrite = exports.splitKeyConvergencePolicy = exports.describeCredEnvelopeState = exports.hasCredEnvelopePathConflict = exports.isCredEnvelopeActive = exports.shutdownCredEnvelope = exports.resetCredEnvelope = exports.initCredEnvelope = exports.verifyDpopProof = exports.normalizeDpopHtu = exports.isJwkThumbprint = exports.isAth = exports.createDpopKey = exports.accessTokenHash = exports.DPOP_PROOF_VERIFY_UNAVAILABLE = exports.DPOP_PROOF_TYP = exports.DPOP_PROOF_REQUIRED = exports.DPOP_PROOF_INVALID = exports.DPOP_MAX_AGE_SECONDS = exports.DPOP_HEADER = exports.verifyDeviceProof = exports.tokenHash = exports.publicJwkFromX = exports.normalizeHtu = void 0;
|
|
28
|
+
exports.LOOPBACK_DEFAULT_MAX_BODY_BYTES = exports.LoopbackTargetRefusedError = exports.isLoopbackAddress = exports.isLoopbackHostname = exports.assertLoopbackHttpUrl = exports.loopbackFetch = exports.withLoopbackNoProxy = exports.envHasProxy = exports.LOOPBACK_NO_PROXY_HOSTS = exports.isDaemonChildEnv = exports.DAEMON_CHILD_ENV = exports.SENSITIVE_ENV_PREFIX_EXCEPTIONS = exports.SENSITIVE_ENV_NAME_TOKENS = exports.SENSITIVE_ENV_SUFFIXES = exports.SENSITIVE_ENV_PREFIXES = exports.SENSITIVE_ENV_VARS = exports.sanitizeSpawnEnv = exports.harnessLoadsClaudeSkillsLayout = exports.claudeSkillsLayoutEvidence = exports.HARNESSES_LOADING_CLAUDE_SKILLS_LAYOUT = exports.tierPermitsConfiguredAutoMode = exports.credentialPolicyForTier = exports.getHarnessTier = exports.HARNESS_TIERS = exports.pairUint8ArrayToBase64Url = exports.pairUint8ArrayToBase64 = exports.parsePairUrl = exports.parsePairPlaintext = exports.parsePairBundle = exports.openPairBundleBase64 = exports.generatePairKeyPair = exports.buildPairUrl = exports.buildPairAad = exports.pairBase64UrlToUint8Array = exports.pairBase64ToUint8Array = exports.assemblePairBundleBase64 = exports.PairBundleError = exports.PAIR_SECRET_LEN = exports.PAIR_PUBKEY_LEN = exports.PAIR_NONCE_LEN = exports.PAIR_BUNDLE_MAX_BASE64_LEN = exports.PAIR_AAD_MAX_LEN = exports.PAIR_AAD_PREFIX = exports.__resetCachedDaemonIdForTest = exports.legacyDaemonUuids = exports.ensureMachineDaemonId = exports.__resetMachineUuidCacheForTest = exports.HOSTED_RUNTIME_MACHINE_SOURCES = exports.hostedRuntimeIdOverride = exports.MACHINE_IDENTITY_FILENAME = void 0;
|
|
29
|
+
exports.consolidateProfileState = exports.profileStateFilePathsToClear = exports.profileStateFileLocations = exports.resolveProfileStateFile = exports.resolveProfileStateDir = exports.legacyProfileStateDir = exports.profileStateDir = exports.SUPERSEDED_COPY_SUFFIX = exports.SUPERSEDED_MARKER_SUFFIX = exports.PROFILES_SEGMENT = exports.isConfigRootOverridden = exports.configRootPath = exports.resolveConfigRoot = exports.verifyManifest = exports.verifyArtifact = exports.isTrustedArtifactOrigin = exports.getDeltaFor = exports.buildManifestMessage = exports.buildArtifactMessage = exports.TRUSTED_FEED_ORIGINS = exports.MAX_SIGS = exports.OVERSKY_RELEASE_PUBLIC_KEYS = exports.resolveFirstPartyHarnessChannel = exports.resolveChannelManifestUrl = exports.isFirstPartyHarnessChannel = exports.firstPartyHarnessFeedCandidates = exports.firstPartyHarnessFeedBase = exports.firstPartyHarnessChannelPrefix = exports.FIRST_PARTY_HARNESS_CHANNELS = exports.DEFAULT_FIRST_PARTY_HARNESS_CHANNEL = exports.migrateFirstPartyHarnessHome = exports.linkFirstPartyHarnessAliases = exports.firstPartyHarnessInstalledBinaryPath = exports.firstPartyHarnessHomeDir = exports.firstPartyHarnessBinDir = exports.FIRST_PARTY_HARNESS_PROVENANCE_SUFFIX = exports.FIRST_PARTY_HARNESS_PREVIOUS_SUFFIX = exports.describeLegacyState = exports.findLegacyLocalState = exports.DEFAULT_BINARY_NAME = exports.LEGACY_NATIVE_ID_PREFIXES = exports.NATIVE_ID_PREFIX = exports.LEGACY_CONFIG_DIR_NAMES = exports.CONFIG_DIR_NAME = void 0;
|
|
30
30
|
// Daemon scope vocabulary — single source of truth for non-Mongoose tiers
|
|
31
31
|
// (daemon, desktop, cli). Schema-bound canonical lives in
|
|
32
32
|
// `@skrr-ai/data-schemas/common/daemonScopes`; the two are kept byte-equal
|
|
@@ -284,6 +284,11 @@ Object.defineProperty(exports, "__getDeviceIdentityStateForTest", { enumerable:
|
|
|
284
284
|
// OSK-12063. Also exposed dependency-free as `@skrr-ai/auth-core/machine-uuid`.
|
|
285
285
|
var machineUuid_js_1 = require("./machineUuid.js");
|
|
286
286
|
Object.defineProperty(exports, "getMachineUuid", { enumerable: true, get: function () { return machineUuid_js_1.getMachineUuid; } });
|
|
287
|
+
Object.defineProperty(exports, "getHardwareMachineUuid", { enumerable: true, get: function () { return machineUuid_js_1.getHardwareMachineUuid; } });
|
|
288
|
+
Object.defineProperty(exports, "setMachineUuidProfile", { enumerable: true, get: function () { return machineUuid_js_1.setMachineUuidProfile; } });
|
|
289
|
+
Object.defineProperty(exports, "getMachineUuidProfile", { enumerable: true, get: function () { return machineUuid_js_1.getMachineUuidProfile; } });
|
|
290
|
+
Object.defineProperty(exports, "qualifyMachineUuid", { enumerable: true, get: function () { return machineUuid_js_1.qualifyMachineUuid; } });
|
|
291
|
+
Object.defineProperty(exports, "MACHINE_IDENTITY_FILENAME", { enumerable: true, get: function () { return machineUuid_js_1.MACHINE_IDENTITY_FILENAME; } });
|
|
287
292
|
Object.defineProperty(exports, "hostedRuntimeIdOverride", { enumerable: true, get: function () { return machineUuid_js_1.hostedRuntimeIdOverride; } });
|
|
288
293
|
Object.defineProperty(exports, "HOSTED_RUNTIME_MACHINE_SOURCES", { enumerable: true, get: function () { return machineUuid_js_1.HOSTED_RUNTIME_MACHINE_SOURCES; } });
|
|
289
294
|
Object.defineProperty(exports, "__resetMachineUuidCacheForTest", { enumerable: true, get: function () { return machineUuid_js_1.__resetMachineUuidCacheForTest; } });
|
|
@@ -18,19 +18,43 @@ export declare const HOSTED_RUNTIME_MACHINE_SOURCES: ReadonlySet<string>;
|
|
|
18
18
|
*/
|
|
19
19
|
export declare function hostedRuntimeIdOverride(name: string, env?: NodeJS.ProcessEnv): string | null;
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
21
|
+
* The HARDWARE identity of this machine (IOPlatformUUID / machine-id /
|
|
22
|
+
* MachineGuid, or a control-plane-issued value on a hosted runtime). Cached for
|
|
23
|
+
* the process lifetime. Same machine -> same value across reboots.
|
|
22
24
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
* The guarantee is only: same machine -> same value across reboots, and the
|
|
26
|
-
* same value from every binary that calls this function.
|
|
27
|
-
*
|
|
28
|
-
* On a hosted runtime the control-plane-issued `OVERSKY_MACHINE_UUID` wins.
|
|
25
|
+
* Almost nothing should call this: `getMachineUuid()` is what goes on the wire,
|
|
26
|
+
* and it equals this for the default profile.
|
|
29
27
|
*
|
|
30
28
|
* Falls back to a deterministic hostname+username hash if the platform
|
|
31
29
|
* probe fails. This preserves server-side record continuity even on
|
|
32
30
|
* locked-down machines that refuse ioreg / registry access.
|
|
33
31
|
*/
|
|
32
|
+
export declare function getHardwareMachineUuid(): string;
|
|
33
|
+
/** The profile's persisted machine-identity choice, beside its other state. */
|
|
34
|
+
export declare const MACHINE_IDENTITY_FILENAME = "machine-identity.json";
|
|
35
|
+
/** The server caps `machineUuid` at 64 characters; 36 + 15 fits, and so does a 41-character fallback. */
|
|
36
|
+
export declare function qualifyMachineUuid(hardware: string, profile: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Tell this module which profile the process runs as. Called wherever a binary
|
|
39
|
+
* resolves its profile (`setActiveProfile` in the daemon and in the CLI), so the
|
|
40
|
+
* identity cannot depend on call order. `null`, '' and the default profile all
|
|
41
|
+
* mean "the hardware identity".
|
|
42
|
+
*/
|
|
43
|
+
export declare function setMachineUuidProfile(profile: string | null | undefined): void;
|
|
44
|
+
export declare function getMachineUuidProfile(): string | null;
|
|
45
|
+
/**
|
|
46
|
+
* Return the `machineUuid` this process sends to the server.
|
|
47
|
+
*
|
|
48
|
+
* Callers should treat this as opaque: the format differs per platform
|
|
49
|
+
* (macOS IOPlatformUUID, Linux systemd machine-id, Windows MachineGuid), and a
|
|
50
|
+
* non-default profile that started new carries a `:p-<hash>` suffix. The
|
|
51
|
+
* guarantee is only: same machine + same profile -> same value across reboots,
|
|
52
|
+
* and the same value from every binary of that profile that calls this function.
|
|
53
|
+
*
|
|
54
|
+
* Equals the hardware identity for the default profile, for a hosted runtime
|
|
55
|
+
* (the control-plane-issued `OVERSKY_MACHINE_UUID` wins) and for a non-default
|
|
56
|
+
* profile that already held credentials; see the block above.
|
|
57
|
+
*/
|
|
34
58
|
export declare function getMachineUuid(): string;
|
|
35
59
|
/** @internal test seam — forget the cached value so the next call re-probes. */
|
|
36
60
|
export declare function __resetMachineUuidCacheForTest(): void;
|