@slock-ai/computer 0.0.13 → 0.0.14
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/index.js +1053 -539
- package/dist/lib/index.d.ts +250 -0
- package/dist/lib/index.js +107 -0
- package/package.json +9 -2
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IPC error code family — the seed that `ServiceClient.request` and
|
|
3
|
+
* `ServiceClient.events` propagate. Forward-only post v9-sign: additions
|
|
4
|
+
* are additive minor library bumps; renames / removals are major.
|
|
5
|
+
*
|
|
6
|
+
* Full §7.3 enumeration (SETUP/ATTACH/MIGRATE/UPGRADE/SERVICE families)
|
|
7
|
+
* lands in a follow-up reconcile commit that also unifies the codes
|
|
8
|
+
* currently emitted via `ComputerServiceError` across services/*.
|
|
9
|
+
*/
|
|
10
|
+
declare const IPC_ERROR_CODES: readonly ["IPC_FRAME_TOO_LARGE", "IPC_PROTOCOL_VERSION_UNSUPPORTED", "IPC_HEARTBEAT_TIMEOUT", "IPC_MALFORMED_FRAME", "IPC_REQUEST_TIMEOUT", "IPC_REQUEST_CANCELED", "IPC_CLIENT_CLOSED"];
|
|
11
|
+
type IpcErrorCode = (typeof IPC_ERROR_CODES)[number];
|
|
12
|
+
/**
|
|
13
|
+
* Runtime narrow guard — exposed so consumers can pattern-match without
|
|
14
|
+
* pulling in a generic `as` cast. The CI gate (§7.4) over a final
|
|
15
|
+
* `ERROR_CODES` union will subsume this once the reconcile lands.
|
|
16
|
+
*/
|
|
17
|
+
declare function isIpcErrorCode(value: unknown): value is IpcErrorCode;
|
|
18
|
+
/**
|
|
19
|
+
* Caller-facing options for `ServiceClient.request`. Pairs active cancel
|
|
20
|
+
* (`signal` — primary G-stage unmount path) with passive deadline
|
|
21
|
+
* (`timeoutMs` — library-side safety net). On either path the client
|
|
22
|
+
* emits an IPC `cancel` frame for the in-flight request id and rejects
|
|
23
|
+
* the returned promise with `IPC_REQUEST_CANCELED` or
|
|
24
|
+
* `IPC_REQUEST_TIMEOUT` respectively (§4.4).
|
|
25
|
+
*/
|
|
26
|
+
interface RequestOptions {
|
|
27
|
+
signal?: AbortSignal;
|
|
28
|
+
timeoutMs?: number;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Typed RPC table — keys are kebab-case wire literals (§5.5), values are
|
|
32
|
+
* per-method `{ params, result }` pairs. The v9 sign-lock seed listed
|
|
33
|
+
* here is the §3.2 6-method floor; new methods are additive minor bumps
|
|
34
|
+
* (extending this map). Param/result payload shapes are intentionally
|
|
35
|
+
* `unknown` in this seed — they are pinned in the follow-up commit that
|
|
36
|
+
* lands the state-reader surface (`readServiceStatus` / `readRunnerStatus`
|
|
37
|
+
* / `listRunners`) alongside the IPC handler signatures.
|
|
38
|
+
*/
|
|
39
|
+
interface RequestMethodMap {
|
|
40
|
+
"service-status": {
|
|
41
|
+
params: void;
|
|
42
|
+
result: unknown;
|
|
43
|
+
};
|
|
44
|
+
"runner-status": {
|
|
45
|
+
params: {
|
|
46
|
+
serverId: string;
|
|
47
|
+
};
|
|
48
|
+
result: unknown;
|
|
49
|
+
};
|
|
50
|
+
"list-runners": {
|
|
51
|
+
params: void;
|
|
52
|
+
result: unknown;
|
|
53
|
+
};
|
|
54
|
+
"upgrade-start": {
|
|
55
|
+
params: {
|
|
56
|
+
target?: string;
|
|
57
|
+
};
|
|
58
|
+
result: unknown;
|
|
59
|
+
};
|
|
60
|
+
"reset-service": {
|
|
61
|
+
params: void;
|
|
62
|
+
result: unknown;
|
|
63
|
+
};
|
|
64
|
+
"reset-runner": {
|
|
65
|
+
params: {
|
|
66
|
+
serverId: string;
|
|
67
|
+
};
|
|
68
|
+
result: unknown;
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Server-pushed event over `ServiceClient.events`. The discriminant field
|
|
73
|
+
* is `kind` (§5.5 — established at v9.7 sign); values are past-participle
|
|
74
|
+
* kebab-case literals. The 6-kind enumeration is the v9.8 §4.4 floor.
|
|
75
|
+
*
|
|
76
|
+
* Payload shapes finalize alongside §4 IPC impl (PR-impl-2, liuliu-owned);
|
|
77
|
+
* the discriminator is locked here so consumers can write exhaustive
|
|
78
|
+
* switches today.
|
|
79
|
+
*
|
|
80
|
+
* Note: v9.8 §4.4 has an example block still showing the v9.7-pre field
|
|
81
|
+
* name `topic` + present-tense values; §5.5 is the byte-pin source of
|
|
82
|
+
* truth (`kind` + past-participle). The §4.4 example will be reconciled
|
|
83
|
+
* in a follow-up doc-clean pass.
|
|
84
|
+
*/
|
|
85
|
+
type ServiceEvent = {
|
|
86
|
+
kind: "service-state-changed";
|
|
87
|
+
payload: unknown;
|
|
88
|
+
} | {
|
|
89
|
+
kind: "runner-state-changed";
|
|
90
|
+
payload: unknown;
|
|
91
|
+
} | {
|
|
92
|
+
kind: "runner-attached";
|
|
93
|
+
payload: unknown;
|
|
94
|
+
} | {
|
|
95
|
+
kind: "runner-detached";
|
|
96
|
+
payload: unknown;
|
|
97
|
+
} | {
|
|
98
|
+
kind: "upgrade-log-appended";
|
|
99
|
+
payload: unknown;
|
|
100
|
+
} | {
|
|
101
|
+
kind: "heartbeat";
|
|
102
|
+
payload: unknown;
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Library-side error envelope thrown by `ServiceClient`. `code` is a
|
|
106
|
+
* member of the §7 closed-set; `cause` is retained in-process only and
|
|
107
|
+
* MUST NOT cross IPC / CLI fail boundaries (§7.4 redaction).
|
|
108
|
+
*/
|
|
109
|
+
declare class ServiceClientError extends Error {
|
|
110
|
+
readonly code: IpcErrorCode;
|
|
111
|
+
readonly cause?: unknown;
|
|
112
|
+
constructor(code: IpcErrorCode, message: string, cause?: unknown);
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Typed IPC client. The implementation in PR-impl-2 §4 satisfies this
|
|
116
|
+
* interface; this commit only locks the surface.
|
|
117
|
+
*
|
|
118
|
+
* Termination semantics (§4.7):
|
|
119
|
+
* - `events` completes naturally (`Symbol.asyncIterator` return) on any
|
|
120
|
+
* socket-close path (graceful local/remote, transient, TCP RST). The
|
|
121
|
+
* `for-await` loop exits without throwing — idiomatic reconnect is a
|
|
122
|
+
* plain outer `while (!stopped) { … }` wrap, no try/catch.
|
|
123
|
+
* - `events` THROWS `ServiceClientError` only on protocol-level
|
|
124
|
+
* failures: handshake mismatch, frame parse, frame > 1 MiB.
|
|
125
|
+
* The disjoint split lets consumers distinguish "retry" (iterator end)
|
|
126
|
+
* from "give up" (throw) without runtime classification.
|
|
127
|
+
*/
|
|
128
|
+
interface ServiceClient {
|
|
129
|
+
events: AsyncIterable<ServiceEvent>;
|
|
130
|
+
request<M extends keyof RequestMethodMap>(method: M, params: RequestMethodMap[M]["params"], options?: RequestOptions): Promise<RequestMethodMap[M]["result"]>;
|
|
131
|
+
close(): Promise<void>;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Connection options. `protocolVersion` lets a consumer opt-in to a
|
|
135
|
+
* specific handshake version; the service negotiates highest mutually
|
|
136
|
+
* supported (§4.3) and may reject with `IPC_PROTOCOL_VERSION_UNSUPPORTED`.
|
|
137
|
+
*/
|
|
138
|
+
interface ConnectServiceOptions {
|
|
139
|
+
protocolVersion?: number;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Open a typed IPC connection to the Computer service. Throws
|
|
143
|
+
* `ServiceClientError` on handshake failure. Concrete implementation
|
|
144
|
+
* lands in PR-impl-2 §4 (liuliu-owned); the type is locked here so
|
|
145
|
+
* `apps/slock-computer-app` and other library consumers can type-check
|
|
146
|
+
* call sites before the transport ships.
|
|
147
|
+
*/
|
|
148
|
+
type ConnectService = (installRoot: string, options?: ConnectServiceOptions) => Promise<ServiceClient>;
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Per-runner lifecycle states (§3.2). One state at a time per runner.
|
|
152
|
+
*
|
|
153
|
+
* starting — spawned, not yet reporting ready
|
|
154
|
+
* running — healthy, reporting heartbeats
|
|
155
|
+
* degraded — alive but not satisfying health invariants (e.g. crash
|
|
156
|
+
* budget near breach, see §1/§2)
|
|
157
|
+
* crashed — observed exit / fatal signal
|
|
158
|
+
* stopped — intentional stop (operator-driven via `runners stop` or
|
|
159
|
+
* supervisor shutdown)
|
|
160
|
+
*/
|
|
161
|
+
declare const RUNNER_STATE_VALUES: readonly ["starting", "running", "degraded", "crashed", "stopped"];
|
|
162
|
+
type RunnerState = (typeof RUNNER_STATE_VALUES)[number];
|
|
163
|
+
declare function isRunnerState(value: unknown): value is RunnerState;
|
|
164
|
+
/**
|
|
165
|
+
* Service (supervisor) lifecycle states (§3.2). Mirrors runner shape but
|
|
166
|
+
* narrower — the service is a singleton per install root.
|
|
167
|
+
*
|
|
168
|
+
* starting — pidfile written, socket not yet listening
|
|
169
|
+
* running — socket listening, heartbeat active
|
|
170
|
+
* degraded — service alive but one or more invariants violated
|
|
171
|
+
* (e.g. SERVICE_DEGRADED §7.3 crash-budget breach)
|
|
172
|
+
* stopping — graceful shutdown in flight (SERVICE_SHUTTING_DOWN
|
|
173
|
+
* §7.3 emitted to clients)
|
|
174
|
+
* stopped — pidfile cleared, socket closed
|
|
175
|
+
*/
|
|
176
|
+
declare const SERVICE_STATE_VALUES: readonly ["starting", "running", "degraded", "stopping", "stopped"];
|
|
177
|
+
type ServiceState = (typeof SERVICE_STATE_VALUES)[number];
|
|
178
|
+
declare function isServiceState(value: unknown): value is ServiceState;
|
|
179
|
+
|
|
180
|
+
type UpgradeTrigger = "cli" | "web" | "tray";
|
|
181
|
+
/**
|
|
182
|
+
* v8.3.3 §4.4 (6) closed-set, verbatim 7 values. Adding / renaming /
|
|
183
|
+
* deleting any value requires an RFC bump (locked discipline). This
|
|
184
|
+
* constant array is the runtime source of truth for `assertUpgradeLogEntry`
|
|
185
|
+
* membership check; the type alias below mirrors it.
|
|
186
|
+
*/
|
|
187
|
+
declare const UPGRADE_ERROR_CODES: readonly ["UPGRADE_DEPS_CHANGED", "UPGRADE_NETWORK_FAILED", "UPGRADE_INTEGRITY_FAILED", "UPGRADE_SWAP_FAILED", "UPGRADE_RESTART_FAILED", "UPGRADE_NO_TARGET", "UPGRADE_ALREADY_RUNNING"];
|
|
188
|
+
type UpgradeErrorCode = (typeof UPGRADE_ERROR_CODES)[number];
|
|
189
|
+
interface UpgradeBundle {
|
|
190
|
+
computerVersion: string;
|
|
191
|
+
/**
|
|
192
|
+
* Forensic-only per v8.3.2 cleanup. May be omitted; consumers MUST
|
|
193
|
+
* NOT treat presence/absence as a user-facing contract. The bundled
|
|
194
|
+
* daemon version plumbing (read from Computer package
|
|
195
|
+
* `dependencies["@slock-ai/daemon"]`) lands as a follow-up; until
|
|
196
|
+
* then writers emit just `computerVersion` and downstream readers
|
|
197
|
+
* default to "unknown" when the field is absent.
|
|
198
|
+
*/
|
|
199
|
+
bundledDaemonVersion?: string;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* v8.3.3 audit-log entry shape, discriminated on `outcome`. Splitting
|
|
203
|
+
* the union means:
|
|
204
|
+
* - `outcome: "ok"` forbids `errorCode` at the type level
|
|
205
|
+
* (`errorCode?: never`)
|
|
206
|
+
* - `outcome: "err"` requires `errorCode: UpgradeErrorCode` (closed-set
|
|
207
|
+
* 7-value membership enforced by TS)
|
|
208
|
+
*
|
|
209
|
+
* Together with the runtime `assertUpgradeLogEntry` guard below, this
|
|
210
|
+
* eliminates the prior "caller-discipline only" silent contract drift
|
|
211
|
+
* (Hao caveat msg=308d99db — `errorCode?: string` allowed any string +
|
|
212
|
+
* silent omission on `err` paths).
|
|
213
|
+
*/
|
|
214
|
+
type UpgradeLogEntry = UpgradeLogEntryOk | UpgradeLogEntryErr;
|
|
215
|
+
interface UpgradeLogEntryOk {
|
|
216
|
+
/** ISO timestamp via formatUpgradeLogTimestamp(); caller may omit to auto-fill. */
|
|
217
|
+
at?: string;
|
|
218
|
+
fromBundle: UpgradeBundle;
|
|
219
|
+
toBundle: UpgradeBundle;
|
|
220
|
+
channel: string;
|
|
221
|
+
trigger: UpgradeTrigger;
|
|
222
|
+
outcome: "ok";
|
|
223
|
+
/** Forbidden on ok entries — discriminated-union enforcement. */
|
|
224
|
+
errorCode?: never;
|
|
225
|
+
}
|
|
226
|
+
interface UpgradeLogEntryErr {
|
|
227
|
+
at?: string;
|
|
228
|
+
fromBundle: UpgradeBundle;
|
|
229
|
+
toBundle: UpgradeBundle;
|
|
230
|
+
channel: string;
|
|
231
|
+
trigger: UpgradeTrigger;
|
|
232
|
+
outcome: "err";
|
|
233
|
+
/** Required iff outcome === "err"; one of the v8.3.3 closed 7-value set. */
|
|
234
|
+
errorCode: UpgradeErrorCode;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Runtime assertion: `entry` is a valid `UpgradeLogEntry`. Throws
|
|
238
|
+
* `TypeError` with an actionable message on contract violation. Defense
|
|
239
|
+
* in depth against JS-interop callers, JSON-deserialized payloads, and
|
|
240
|
+
* future type-system escapes.
|
|
241
|
+
*
|
|
242
|
+
* Validations:
|
|
243
|
+
* - `outcome === "ok"` AND `errorCode` is set → reject
|
|
244
|
+
* - `outcome === "err"` AND `errorCode` is missing → reject
|
|
245
|
+
* - `outcome === "err"` AND `errorCode` not in 7-value closed set → reject
|
|
246
|
+
* - Both bundle objects must have a non-empty `computerVersion` string
|
|
247
|
+
*/
|
|
248
|
+
declare function assertUpgradeLogEntry(entry: UpgradeLogEntry): void;
|
|
249
|
+
|
|
250
|
+
export { type ConnectService, type ConnectServiceOptions, IPC_ERROR_CODES, type IpcErrorCode, RUNNER_STATE_VALUES, type RequestMethodMap, type RequestOptions, type RunnerState, SERVICE_STATE_VALUES, type ServiceClient, ServiceClientError, type ServiceEvent, type ServiceState, UPGRADE_ERROR_CODES, type UpgradeBundle, type UpgradeErrorCode, type UpgradeLogEntry, type UpgradeLogEntryErr, type UpgradeLogEntryOk, type UpgradeTrigger, assertUpgradeLogEntry, isIpcErrorCode, isRunnerState, isServiceState };
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// src/lib/types.ts
|
|
2
|
+
var IPC_ERROR_CODES = [
|
|
3
|
+
"IPC_FRAME_TOO_LARGE",
|
|
4
|
+
"IPC_PROTOCOL_VERSION_UNSUPPORTED",
|
|
5
|
+
"IPC_HEARTBEAT_TIMEOUT",
|
|
6
|
+
"IPC_MALFORMED_FRAME",
|
|
7
|
+
"IPC_REQUEST_TIMEOUT",
|
|
8
|
+
"IPC_REQUEST_CANCELED",
|
|
9
|
+
"IPC_CLIENT_CLOSED"
|
|
10
|
+
];
|
|
11
|
+
function isIpcErrorCode(value) {
|
|
12
|
+
return typeof value === "string" && IPC_ERROR_CODES.includes(value);
|
|
13
|
+
}
|
|
14
|
+
var ServiceClientError = class extends Error {
|
|
15
|
+
code;
|
|
16
|
+
cause;
|
|
17
|
+
constructor(code, message, cause) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = "ServiceClientError";
|
|
20
|
+
this.code = code;
|
|
21
|
+
if (cause !== void 0) this.cause = cause;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
// src/lib/state.ts
|
|
26
|
+
var RUNNER_STATE_VALUES = [
|
|
27
|
+
"starting",
|
|
28
|
+
"running",
|
|
29
|
+
"degraded",
|
|
30
|
+
"crashed",
|
|
31
|
+
"stopped"
|
|
32
|
+
];
|
|
33
|
+
function isRunnerState(value) {
|
|
34
|
+
return typeof value === "string" && RUNNER_STATE_VALUES.includes(value);
|
|
35
|
+
}
|
|
36
|
+
var SERVICE_STATE_VALUES = [
|
|
37
|
+
"starting",
|
|
38
|
+
"running",
|
|
39
|
+
"degraded",
|
|
40
|
+
"stopping",
|
|
41
|
+
"stopped"
|
|
42
|
+
];
|
|
43
|
+
function isServiceState(value) {
|
|
44
|
+
return typeof value === "string" && SERVICE_STATE_VALUES.includes(value);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/upgradeLog.ts
|
|
48
|
+
import { chmod, mkdir, open } from "fs/promises";
|
|
49
|
+
|
|
50
|
+
// src/paths.ts
|
|
51
|
+
import { createHash } from "crypto";
|
|
52
|
+
import os from "os";
|
|
53
|
+
import path from "path";
|
|
54
|
+
|
|
55
|
+
// src/upgradeLog.ts
|
|
56
|
+
var UPGRADE_ERROR_CODES = [
|
|
57
|
+
"UPGRADE_DEPS_CHANGED",
|
|
58
|
+
"UPGRADE_NETWORK_FAILED",
|
|
59
|
+
"UPGRADE_INTEGRITY_FAILED",
|
|
60
|
+
"UPGRADE_SWAP_FAILED",
|
|
61
|
+
"UPGRADE_RESTART_FAILED",
|
|
62
|
+
"UPGRADE_NO_TARGET",
|
|
63
|
+
"UPGRADE_ALREADY_RUNNING"
|
|
64
|
+
];
|
|
65
|
+
var UPGRADE_ERROR_CODE_SET = new Set(UPGRADE_ERROR_CODES);
|
|
66
|
+
function assertUpgradeLogEntry(entry) {
|
|
67
|
+
const e = entry;
|
|
68
|
+
if (e.outcome === "ok") {
|
|
69
|
+
if (e.errorCode !== void 0) {
|
|
70
|
+
throw new TypeError(
|
|
71
|
+
`UpgradeLogEntry contract violation: outcome="ok" must not carry errorCode (got "${e.errorCode}").`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
} else if (e.outcome === "err") {
|
|
75
|
+
if (e.errorCode === void 0) {
|
|
76
|
+
throw new TypeError(
|
|
77
|
+
`UpgradeLogEntry contract violation: outcome="err" requires errorCode from the v8.3.3 closed-set (${UPGRADE_ERROR_CODES.join(" | ")}).`
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
if (!UPGRADE_ERROR_CODE_SET.has(e.errorCode)) {
|
|
81
|
+
throw new TypeError(
|
|
82
|
+
`UpgradeLogEntry contract violation: errorCode "${e.errorCode}" is not in the v8.3.3 closed 7-value set (${UPGRADE_ERROR_CODES.join(" | ")}).`
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
} else {
|
|
86
|
+
throw new TypeError(
|
|
87
|
+
`UpgradeLogEntry contract violation: outcome must be "ok" or "err" (got "${e.outcome}").`
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
if (typeof e.fromBundle?.computerVersion !== "string" || e.fromBundle.computerVersion.length === 0) {
|
|
91
|
+
throw new TypeError(`UpgradeLogEntry contract violation: fromBundle.computerVersion must be a non-empty string.`);
|
|
92
|
+
}
|
|
93
|
+
if (typeof e.toBundle?.computerVersion !== "string" || e.toBundle.computerVersion.length === 0) {
|
|
94
|
+
throw new TypeError(`UpgradeLogEntry contract violation: toBundle.computerVersion must be a non-empty string.`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
IPC_ERROR_CODES,
|
|
99
|
+
RUNNER_STATE_VALUES,
|
|
100
|
+
SERVICE_STATE_VALUES,
|
|
101
|
+
ServiceClientError,
|
|
102
|
+
UPGRADE_ERROR_CODES,
|
|
103
|
+
assertUpgradeLogEntry,
|
|
104
|
+
isIpcErrorCode,
|
|
105
|
+
isRunnerState,
|
|
106
|
+
isServiceState
|
|
107
|
+
};
|
package/package.json
CHANGED
|
@@ -1,11 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@slock-ai/computer",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.14",
|
|
4
4
|
"description": "Slock Computer — standalone human/local-machine control-plane CLI (login + attach). Distinct from the agent-facing @slock-ai/cli.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"slock-computer": "dist/index.js"
|
|
8
8
|
},
|
|
9
|
+
"exports": {
|
|
10
|
+
"./lib": {
|
|
11
|
+
"types": "./dist/lib/index.d.ts",
|
|
12
|
+
"default": "./dist/lib/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./package.json": "./package.json"
|
|
15
|
+
},
|
|
9
16
|
"files": [
|
|
10
17
|
"dist"
|
|
11
18
|
],
|
|
@@ -21,7 +28,7 @@
|
|
|
21
28
|
"commander": "^12.1.0",
|
|
22
29
|
"proper-lockfile": "^4.1.2",
|
|
23
30
|
"undici": "^7.24.7",
|
|
24
|
-
"@slock-ai/daemon": "0.
|
|
31
|
+
"@slock-ai/daemon": "0.55.0"
|
|
25
32
|
},
|
|
26
33
|
"devDependencies": {
|
|
27
34
|
"@types/node": "^25.5.0",
|