@forgezero/agent 0.1.39 → 0.1.41
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 +357 -348
- package/dist/agent-heartbeat.js +16 -14
- package/dist/agent-update-helper.js +15 -13
- package/dist/agent-update.js +15 -13
- package/dist/bootstrap.d.ts +13 -0
- package/dist/bootstrap.js +244 -832
- package/dist/cli/index.d.ts +0 -2
- package/dist/cloudflare-bootstrap.d.ts +21 -128
- package/dist/cloudflare-bootstrap.js +146 -788
- package/dist/cloudflare-edge.d.ts +3 -151
- package/dist/cloudflare-edge.js +28 -248
- package/dist/credential-schema.d.ts +60 -0
- package/dist/credential-schema.js +335 -0
- package/dist/definition.js +2 -2
- package/dist/deploy-file.js +2 -2
- package/dist/fz-agent.js +1787 -3387
- package/dist/fz.js +1938 -4712
- package/dist/index.d.ts +33 -0
- package/dist/metal-bootstrap.js +1 -1
- package/dist/platform-bootstrap-runtime.d.ts +5 -0
- package/dist/platform-bootstrap-runtime.js +25 -6
- package/dist/project-context.js +1 -1
- package/dist/provision.js +18 -16
- package/dist/software-helper.js +2 -2
- package/dist/software.js +2 -2
- package/dist/version.d.ts +1 -1
- package/package.json +9 -5
- package/dist/cli/custody.d.ts +0 -35
package/dist/index.d.ts
CHANGED
|
@@ -2,11 +2,14 @@
|
|
|
2
2
|
import { type NodeKeyPair } from '@forgezero/runtime/identity';
|
|
3
3
|
import { startAgent, type AgentOptions, type AttestationSource } from './socket';
|
|
4
4
|
import type { SecretCache } from './cache';
|
|
5
|
+
import { type DeploymentCredentialSchema } from './credential-schema';
|
|
5
6
|
export { VERSION } from './version';
|
|
6
7
|
export { startAgent, handleRequest, handleApplicationRequest } from './socket';
|
|
7
8
|
export type { AgentOptions, AttestationSource, Request, Response } from './socket';
|
|
8
9
|
export { createSecretCache, CacheError } from './cache';
|
|
9
10
|
export type { SecretCache, CacheOptions } from './cache';
|
|
11
|
+
export { AGENT_CREDENTIAL_LOCATIONS, AGENT_CREDENTIAL_POLICY, METAL_SYSTEMD_CREDENTIALS, credentialBinding, deploymentCredentialSchema } from './credential-schema';
|
|
12
|
+
export type { AgentCredentialLocation, DeploymentCredentialBinding, DeploymentCredentialSchema } from './credential-schema';
|
|
10
13
|
export { createDeploymentManager, DeploymentError } from './deployment';
|
|
11
14
|
export type { DeploymentManager, DeploymentOptions, DeploymentRequest, DeploymentResult } from './deployment';
|
|
12
15
|
export { DEFAULT_CONTROL_SOCKET, requestControl, startControlServer } from './control';
|
|
@@ -132,6 +135,36 @@ export declare function createSystemdDeploymentSecrets(names: string | undefined
|
|
|
132
135
|
has(name: string): boolean;
|
|
133
136
|
get(name: string): Promise<string>;
|
|
134
137
|
} | undefined;
|
|
138
|
+
/**
|
|
139
|
+
* Resolve deployment secrets from the project-scoped RAM Vault replica first,
|
|
140
|
+
* then from an explicitly allow-listed systemd credential with the same name.
|
|
141
|
+
* This is shared by platform and tenant deployment managers.
|
|
142
|
+
*/
|
|
143
|
+
export declare function createDeploymentSecretResolver(schema: DeploymentCredentialSchema, primary: Pick<SecretCache, 'get'> | undefined, fallback: {
|
|
144
|
+
has(name: string): boolean;
|
|
145
|
+
get(name: string): Promise<string>;
|
|
146
|
+
} | undefined): Pick<SecretCache, 'get'> | undefined;
|
|
147
|
+
export type InitialVaultReplicaStatus = {
|
|
148
|
+
state: 'ready';
|
|
149
|
+
loaded: number;
|
|
150
|
+
failed: readonly string[];
|
|
151
|
+
} | {
|
|
152
|
+
state: 'partial';
|
|
153
|
+
loaded: number;
|
|
154
|
+
failed: readonly string[];
|
|
155
|
+
} | {
|
|
156
|
+
state: 'unavailable';
|
|
157
|
+
loaded: 0;
|
|
158
|
+
failed: readonly [];
|
|
159
|
+
};
|
|
160
|
+
/**
|
|
161
|
+
* Attempt the in-memory Vault replica without turning a locked or restarting
|
|
162
|
+
* Vault into an Agent outage. Deployment reads still try this cache first and
|
|
163
|
+
* may fall back only through the explicit same-name systemd schema. The sync
|
|
164
|
+
* loop remains active and promotes the cache to a complete replica once Vault
|
|
165
|
+
* is available again.
|
|
166
|
+
*/
|
|
167
|
+
export declare function initializeVaultReplica(cache: Pick<SecretCache, 'load'>): Promise<InitialVaultReplicaStatus>;
|
|
135
168
|
/**
|
|
136
169
|
* Bring the agent up.
|
|
137
170
|
*
|
package/dist/metal-bootstrap.js
CHANGED
|
@@ -82,6 +82,8 @@ export interface ApiRuntimeRenderOptions {
|
|
|
82
82
|
greenPort: number;
|
|
83
83
|
collectorUnit: string;
|
|
84
84
|
credentials: SystemdCredentialSpec[];
|
|
85
|
+
/** Root-owned calibration override, loaded after the ordinary shared environment. */
|
|
86
|
+
capacityEnvironmentFile?: string;
|
|
85
87
|
}
|
|
86
88
|
export declare function renderPlatformApiUnits(input: ApiRuntimeRenderOptions): {
|
|
87
89
|
template: string;
|
|
@@ -90,6 +92,8 @@ export declare function renderPlatformApiUnits(input: ApiRuntimeRenderOptions):
|
|
|
90
92
|
export declare function renderPlatformNginx(input: {
|
|
91
93
|
publicPort: number;
|
|
92
94
|
initialSlotPort: number;
|
|
95
|
+
concurrencyLimit?: number;
|
|
96
|
+
workerDrainSeconds?: number;
|
|
93
97
|
}): {
|
|
94
98
|
upstream: string;
|
|
95
99
|
site: string;
|
|
@@ -109,6 +113,7 @@ export interface PlatformActivationConfig {
|
|
|
109
113
|
greenPort: number;
|
|
110
114
|
healthPath: string;
|
|
111
115
|
keepReleases: number;
|
|
116
|
+
drainDeadlineMs?: number;
|
|
112
117
|
}
|
|
113
118
|
/**
|
|
114
119
|
* Render the fixed privilege boundary used by the credential-free deployment
|
|
@@ -218,6 +218,8 @@ function renderPlatformApiUnits(input) {
|
|
|
218
218
|
throw new Error("Blue and green ports must differ.");
|
|
219
219
|
const credentials = input.credentials.map((credential) => `LoadCredentialEncrypted=${credential.name}:${credential.encryptedPath}`).join(`
|
|
220
220
|
`);
|
|
221
|
+
const capacityEnvironment = input.capacityEnvironmentFile ? `EnvironmentFile=-${input.capacityEnvironmentFile}
|
|
222
|
+
` : "";
|
|
221
223
|
const template = `[Unit]
|
|
222
224
|
Description=ForgeZero (%i slot)
|
|
223
225
|
After=network-online.target ${input.collectorUnit}
|
|
@@ -230,7 +232,7 @@ WorkingDirectory=${input.slotsDirectory}/%i
|
|
|
230
232
|
Environment=NODE_ENV=production
|
|
231
233
|
Environment=FZ_SLOT=%i
|
|
232
234
|
EnvironmentFile=${input.sharedEnvironmentFile}
|
|
233
|
-
${credentials}
|
|
235
|
+
${capacityEnvironment}${credentials}
|
|
234
236
|
ExecStart=/usr/local/bin/bun run ${input.slotsDirectory}/%i/src/index.ts
|
|
235
237
|
Restart=always
|
|
236
238
|
RestartSec=2
|
|
@@ -266,16 +268,24 @@ Environment=PORT=${input.greenPort}
|
|
|
266
268
|
function renderPlatformNginx(input) {
|
|
267
269
|
boundedInteger("publicPort", input.publicPort, 1024, 65535);
|
|
268
270
|
boundedInteger("initialSlotPort", input.initialSlotPort, 1024, 65535);
|
|
271
|
+
const concurrencyLimit = boundedInteger("concurrencyLimit", input.concurrencyLimit ?? 256, 1, 1e6);
|
|
272
|
+
boundedInteger("workerDrainSeconds", input.workerDrainSeconds ?? 35, 1, 300);
|
|
269
273
|
if (input.publicPort === input.initialSlotPort)
|
|
270
274
|
throw new Error("Edge and slot ports must differ.");
|
|
271
275
|
return {
|
|
272
276
|
upstream: `upstream forgezero { server 127.0.0.1:${input.initialSlotPort}; }
|
|
273
277
|
`,
|
|
274
|
-
site: `
|
|
278
|
+
site: `limit_conn_zone $server_name zone=forgezero_admission:10m;
|
|
279
|
+
map $http_upgrade $forgezero_connection { default upgrade; '' close; }
|
|
280
|
+
map $limit_conn_status $forgezero_retry_after { default ''; REJECTED 1; REJECTED_DRY_RUN 1; }
|
|
281
|
+
server {
|
|
275
282
|
listen 127.0.0.1:${input.publicPort};
|
|
276
283
|
server_name _;
|
|
277
|
-
|
|
278
|
-
|
|
284
|
+
limit_conn forgezero_admission ${concurrencyLimit};
|
|
285
|
+
limit_conn_status 503;
|
|
286
|
+
add_header Retry-After $forgezero_retry_after always;
|
|
287
|
+
location ^~ /api/ { proxy_pass http://forgezero; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $forgezero_connection; proxy_read_timeout 3600s; }
|
|
288
|
+
location ^~ /v1/ { proxy_pass http://forgezero; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $forgezero_connection; proxy_read_timeout 3600s; }
|
|
279
289
|
location / { return 404; }
|
|
280
290
|
}
|
|
281
291
|
`
|
|
@@ -301,6 +311,7 @@ function renderPlatformActivationFiles(input) {
|
|
|
301
311
|
if (input.bluePort === input.greenPort)
|
|
302
312
|
throw new Error("Activation slot ports must differ.");
|
|
303
313
|
boundedInteger("keepReleases", input.keepReleases, 2, 100);
|
|
314
|
+
const drainDeadlineMs = boundedInteger("drainDeadlineMs", input.drainDeadlineMs ?? 35000, 1000, 300000);
|
|
304
315
|
if (!/^\/[A-Za-z0-9/_-]{1,128}$/.test(input.healthPath) || input.healthPath.includes("..")) {
|
|
305
316
|
throw new Error("Activation health path is malformed.");
|
|
306
317
|
}
|
|
@@ -310,7 +321,8 @@ function renderPlatformActivationFiles(input) {
|
|
|
310
321
|
`FZ_BLUE_PORT=${input.bluePort}`,
|
|
311
322
|
`FZ_GREEN_PORT=${input.greenPort}`,
|
|
312
323
|
`FZ_HEALTH_PATH=${input.healthPath}`,
|
|
313
|
-
`FZ_KEEP_RELEASES=${input.keepReleases}
|
|
324
|
+
`FZ_KEEP_RELEASES=${input.keepReleases}`,
|
|
325
|
+
`FZ_DRAIN_DEADLINE_MS=${drainDeadlineMs}`
|
|
314
326
|
].join(`
|
|
315
327
|
`) + `
|
|
316
328
|
`;
|
|
@@ -332,7 +344,14 @@ if (( ! healthy )); then systemctl stop "forgezero@\${target}.service" || true;
|
|
|
332
344
|
upstream=/etc/nginx/conf.d/forgezero-upstream.conf; backup="$(mktemp -p /run forgezero-upstream.XXXXXX)"; [[ -f "$upstream" ]] && cp "$upstream" "$backup" || : >"$backup"
|
|
333
345
|
printf 'upstream forgezero { server 127.0.0.1:%s; }\\n' "$port" >"$upstream"
|
|
334
346
|
if ! nginx -t || ! nginx -s reload; then [[ -s "$backup" ]] && cp "$backup" "$upstream" || rm -f "$upstream"; rm -f "$backup"; systemctl stop "forgezero@\${target}.service" || true; [[ -n "$previous_target_link" && -d "$previous_target_link" ]] && ln -sfn "$previous_target_link" "$target_link" || rm -f "$target_link"; nginx -t >/dev/null 2>&1 && nginx -s reload || true; exit 1; fi
|
|
335
|
-
rm -f "$backup"; printf '%s\\n' "$target" >"$slot_file"
|
|
347
|
+
rm -f "$backup"; printf '%s\\n' "$target" >"$slot_file"
|
|
348
|
+
# New nginx workers select the new slot after reload. Keep the old slot alive
|
|
349
|
+
# while old workers drain in-flight requests and upgraded connections.
|
|
350
|
+
if [[ -n "$previous_slot" && "$previous_slot" != "$target" ]]; then
|
|
351
|
+
sleep_seconds="$(( (FZ_DRAIN_DEADLINE_MS + 999) / 1000 ))"
|
|
352
|
+
sleep "$sleep_seconds"
|
|
353
|
+
systemctl stop "forgezero@\${previous_slot}.service" || true
|
|
354
|
+
fi
|
|
336
355
|
mapfile -t old < <(find "$releases" -mindepth 1 -maxdepth 1 -type d -printf '%T@ %p\\n' | sort -rn | tail -n "+$((FZ_KEEP_RELEASES + 1))" | cut -d' ' -f2-)
|
|
337
356
|
for path in "\${old[@]}"; do [[ "$path" == "$release" ]] || rm -rf -- "$path"; done
|
|
338
357
|
printf 'promoted %s on %s\\n' "$release" "$target"
|
package/dist/project-context.js
CHANGED
|
@@ -105,7 +105,7 @@ function defaultProjectContext(root = process.cwd()) {
|
|
|
105
105
|
"Update a truth source instead of copying architecture or progress into another document.",
|
|
106
106
|
"Never report a feature as complete without running its declared verification."
|
|
107
107
|
],
|
|
108
|
-
nonAuthoritative: ["audit/"]
|
|
108
|
+
nonAuthoritative: ["docs/audit/"]
|
|
109
109
|
};
|
|
110
110
|
}
|
|
111
111
|
function renderProjectContext(manifest) {
|
package/dist/provision.js
CHANGED
|
@@ -93,6 +93,8 @@ var checked = async (run, input, label) => {
|
|
|
93
93
|
return result;
|
|
94
94
|
};
|
|
95
95
|
async function validateReleaseDirectory(directory, release, run) {
|
|
96
|
+
chmodSync(directory, 493);
|
|
97
|
+
chmodSync(join(directory, "dist"), 493);
|
|
96
98
|
const manifest = JSON.parse(readFileSync(join(directory, "package.json"), "utf8"));
|
|
97
99
|
if (manifest.name !== release.package || manifest.version !== release.version) {
|
|
98
100
|
throw new Error("agent update manifest does not match the selected release");
|
|
@@ -143,19 +145,19 @@ async function stageAgentRelease(releaseInput, options) {
|
|
|
143
145
|
if (!timingSafeEqual(actual, expected))
|
|
144
146
|
throw new Error("agent update integrity mismatch");
|
|
145
147
|
writeFileSync(archive, bytes, { mode: 384, flag: "wx" });
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
"
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
}
|
|
148
|
+
for (const [member, relative] of [
|
|
149
|
+
["package/package.json", "package.json"],
|
|
150
|
+
["package/dist/fz-agent.js", "dist/fz-agent.js"],
|
|
151
|
+
["package/dist/fz.js", "dist/fz.js"]
|
|
152
|
+
]) {
|
|
153
|
+
const extracted = await checked(run, {
|
|
154
|
+
command: "/usr/bin/tar",
|
|
155
|
+
args: ["-xOzf", archive, member]
|
|
156
|
+
}, `agent update extraction of ${member}`);
|
|
157
|
+
const destination = join(unpacked, relative);
|
|
158
|
+
mkdirSync(dirname(destination), { recursive: true, mode: 448 });
|
|
159
|
+
writeFileSync(destination, extracted.output, { mode: 384, flag: "wx" });
|
|
160
|
+
}
|
|
159
161
|
await validateReleaseDirectory(unpacked, release, run);
|
|
160
162
|
if (!existsSync(finalDirectory)) {
|
|
161
163
|
renameSync(unpacked, finalDirectory);
|
|
@@ -701,8 +703,8 @@ var UBUNTU_2604_X64 = [
|
|
|
701
703
|
},
|
|
702
704
|
{
|
|
703
705
|
requirement: { id: "arangodb", version: "3.11.14" },
|
|
704
|
-
check: `arangod --version 2>/dev/null | head -1 | grep -q '3.11.14'`,
|
|
705
|
-
install: `tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT; ` + `curl -fsSL 'https://download.arangodb.com/arangodb311/DEBIAN/amd64/arangodb3_3.11.14-1_amd64.deb' -o "$tmp/arangodb.deb"; ` + `echo "${ARANGO_SHA256} $tmp/arangodb.deb" | sha256sum -c -; ` + `DEBIAN_FRONTEND=noninteractive dpkg -i "$tmp/arangodb.deb" >/dev/null 2>&1 || ` + `DEBIAN_FRONTEND=noninteractive apt-get -y -f install`
|
|
706
|
+
check: `arangod --version 2>/dev/null | head -1 | grep -q '3.11.14' && ` + `! systemctl is-active --quiet arangodb3.service && ` + `! systemctl is-enabled --quiet arangodb3.service`,
|
|
707
|
+
install: `tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT; ` + `curl -fsSL 'https://download.arangodb.com/arangodb311/DEBIAN/amd64/arangodb3_3.11.14-1_amd64.deb' -o "$tmp/arangodb.deb"; ` + `echo "${ARANGO_SHA256} $tmp/arangodb.deb" | sha256sum -c -; ` + `DEBIAN_FRONTEND=noninteractive dpkg -i "$tmp/arangodb.deb" >/dev/null 2>&1 || ` + `DEBIAN_FRONTEND=noninteractive apt-get -y -f install; ` + `systemctl disable --now arangodb3.service`
|
|
706
708
|
},
|
|
707
709
|
{
|
|
708
710
|
requirement: { id: "cloudflared", version: "2026.7.3" },
|
|
@@ -891,7 +893,7 @@ function requestSoftware(requirements, socketPath = DEFAULT_SOFTWARE_HELPER_SOCK
|
|
|
891
893
|
}
|
|
892
894
|
|
|
893
895
|
// src/version.ts
|
|
894
|
-
var VERSION3 = "0.1.
|
|
896
|
+
var VERSION3 = "0.1.41";
|
|
895
897
|
|
|
896
898
|
// src/egress-policy.ts
|
|
897
899
|
import { realpathSync } from "node:fs";
|
package/dist/software-helper.js
CHANGED
|
@@ -28,8 +28,8 @@ var UBUNTU_2604_X64 = [
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
requirement: { id: "arangodb", version: "3.11.14" },
|
|
31
|
-
check: `arangod --version 2>/dev/null | head -1 | grep -q '3.11.14'`,
|
|
32
|
-
install: `tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT; ` + `curl -fsSL 'https://download.arangodb.com/arangodb311/DEBIAN/amd64/arangodb3_3.11.14-1_amd64.deb' -o "$tmp/arangodb.deb"; ` + `echo "${ARANGO_SHA256} $tmp/arangodb.deb" | sha256sum -c -; ` + `DEBIAN_FRONTEND=noninteractive dpkg -i "$tmp/arangodb.deb" >/dev/null 2>&1 || ` + `DEBIAN_FRONTEND=noninteractive apt-get -y -f install`
|
|
31
|
+
check: `arangod --version 2>/dev/null | head -1 | grep -q '3.11.14' && ` + `! systemctl is-active --quiet arangodb3.service && ` + `! systemctl is-enabled --quiet arangodb3.service`,
|
|
32
|
+
install: `tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT; ` + `curl -fsSL 'https://download.arangodb.com/arangodb311/DEBIAN/amd64/arangodb3_3.11.14-1_amd64.deb' -o "$tmp/arangodb.deb"; ` + `echo "${ARANGO_SHA256} $tmp/arangodb.deb" | sha256sum -c -; ` + `DEBIAN_FRONTEND=noninteractive dpkg -i "$tmp/arangodb.deb" >/dev/null 2>&1 || ` + `DEBIAN_FRONTEND=noninteractive apt-get -y -f install; ` + `systemctl disable --now arangodb3.service`
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
requirement: { id: "cloudflared", version: "2026.7.3" },
|
package/dist/software.js
CHANGED
|
@@ -28,8 +28,8 @@ var UBUNTU_2604_X64 = [
|
|
|
28
28
|
},
|
|
29
29
|
{
|
|
30
30
|
requirement: { id: "arangodb", version: "3.11.14" },
|
|
31
|
-
check: `arangod --version 2>/dev/null | head -1 | grep -q '3.11.14'`,
|
|
32
|
-
install: `tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT; ` + `curl -fsSL 'https://download.arangodb.com/arangodb311/DEBIAN/amd64/arangodb3_3.11.14-1_amd64.deb' -o "$tmp/arangodb.deb"; ` + `echo "${ARANGO_SHA256} $tmp/arangodb.deb" | sha256sum -c -; ` + `DEBIAN_FRONTEND=noninteractive dpkg -i "$tmp/arangodb.deb" >/dev/null 2>&1 || ` + `DEBIAN_FRONTEND=noninteractive apt-get -y -f install`
|
|
31
|
+
check: `arangod --version 2>/dev/null | head -1 | grep -q '3.11.14' && ` + `! systemctl is-active --quiet arangodb3.service && ` + `! systemctl is-enabled --quiet arangodb3.service`,
|
|
32
|
+
install: `tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT; ` + `curl -fsSL 'https://download.arangodb.com/arangodb311/DEBIAN/amd64/arangodb3_3.11.14-1_amd64.deb' -o "$tmp/arangodb.deb"; ` + `echo "${ARANGO_SHA256} $tmp/arangodb.deb" | sha256sum -c -; ` + `DEBIAN_FRONTEND=noninteractive dpkg -i "$tmp/arangodb.deb" >/dev/null 2>&1 || ` + `DEBIAN_FRONTEND=noninteractive apt-get -y -f install; ` + `systemctl disable --now arangodb3.service`
|
|
33
33
|
},
|
|
34
34
|
{
|
|
35
35
|
requirement: { id: "cloudflared", version: "2026.7.3" },
|
package/dist/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
/** One package version shared by both public binaries. Pinned to package.json by tests. */
|
|
2
|
-
export declare const VERSION = "0.1.
|
|
2
|
+
export declare const VERSION = "0.1.41";
|
package/package.json
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forgezero/agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.41",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"check": "tsc --noEmit",
|
|
7
7
|
"prebuild": "rm -rf dist",
|
|
8
|
-
"build": "bun build src/index.ts --outfile dist/fz-agent.js --target bun --format esm && bun build src/cli/index.ts --outfile dist/fz.js --target bun --format esm && bun build src/compute.ts src/provision.ts src/subscribe.ts src/pipeline.ts src/definition.ts src/deploy-file.ts src/ssh-server.ts src/ssh-listen.ts src/provisioning-pull.ts src/migration-pull.ts src/guest-enrolment.ts src/node-vault.ts src/metal-provision.ts src/metal-helper-socket.ts src/lifecycle-helper.ts src/deployment-runner.ts src/agent-update.ts src/agent-update-helper.ts src/agent-heartbeat.ts src/software.ts src/software-helper.ts src/ubuntu.ts src/capacity-calibration.ts src/platform-bootstrap-runtime.ts --root src --outdir dist --target browser --format esm --packages external && bun build src/project-context.ts src/bootstrap.ts src/metal-bootstrap.ts src/cloudflare-bootstrap.ts src/cloudflare-edge.ts --root src --outdir dist --target bun --format esm --packages external && tsc --emitDeclarationOnly --declaration --noEmit false --outDir dist",
|
|
8
|
+
"build": "bun build src/index.ts --outfile dist/fz-agent.js --target bun --format esm && bun build src/cli/index.ts --outfile dist/fz.js --target bun --format esm && bun build src/compute.ts src/provision.ts src/subscribe.ts src/pipeline.ts src/definition.ts src/deploy-file.ts src/ssh-server.ts src/ssh-listen.ts src/provisioning-pull.ts src/migration-pull.ts src/guest-enrolment.ts src/node-vault.ts src/credential-schema.ts src/metal-provision.ts src/metal-helper-socket.ts src/lifecycle-helper.ts src/deployment-runner.ts src/agent-update.ts src/agent-update-helper.ts src/agent-heartbeat.ts src/software.ts src/software-helper.ts src/ubuntu.ts src/capacity-calibration.ts src/platform-bootstrap-runtime.ts --root src --outdir dist --target browser --format esm --packages external && bun build src/project-context.ts src/bootstrap.ts src/metal-bootstrap.ts src/cloudflare-bootstrap.ts src/cloudflare-edge.ts --root src --outdir dist --target bun --format esm --packages external && tsc --emitDeclarationOnly --declaration --noEmit false --outDir dist",
|
|
9
9
|
"prepublishOnly": "bun run check && bun run build"
|
|
10
10
|
},
|
|
11
11
|
"devDependencies": {
|
|
12
12
|
"typescript": "^5.6.0",
|
|
13
13
|
"@types/bun": "latest",
|
|
14
14
|
"@types/node": "^22.0.0",
|
|
15
|
-
"@forgezero/access": "0.1.
|
|
15
|
+
"@forgezero/access": "0.1.3",
|
|
16
16
|
"@noble/curves": "^2.2.0",
|
|
17
17
|
"@noble/post-quantum": "^0.6.1"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
|
|
21
|
-
"@forgezero/vault": "0.1.
|
|
20
|
+
"@forgezero/runtime": "0.1.7",
|
|
21
|
+
"@forgezero/vault": "0.1.11",
|
|
22
22
|
"@noble/curves": "2.2.0",
|
|
23
23
|
"@noble/hashes": "2.2.0",
|
|
24
24
|
"@noble/post-quantum": "0.6.1",
|
|
@@ -150,6 +150,10 @@
|
|
|
150
150
|
"types": "./dist/bootstrap.d.ts",
|
|
151
151
|
"default": "./dist/bootstrap.js"
|
|
152
152
|
},
|
|
153
|
+
"./credential-schema": {
|
|
154
|
+
"types": "./dist/credential-schema.d.ts",
|
|
155
|
+
"default": "./dist/credential-schema.js"
|
|
156
|
+
},
|
|
153
157
|
"./platform-bootstrap-runtime": {
|
|
154
158
|
"types": "./dist/platform-bootstrap-runtime.d.ts",
|
|
155
159
|
"default": "./dist/platform-bootstrap-runtime.js"
|
package/dist/cli/custody.d.ts
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { type AgentIdentity } from '@forgezero/runtime/ssh-agent';
|
|
2
|
-
/**
|
|
3
|
-
* Choosing an SSH key for custody, safely.
|
|
4
|
-
*
|
|
5
|
-
* A real agent is not a clean room. It commonly holds forwarded keys whose
|
|
6
|
-
* upstream connection is gone, and confirm-on-use keys that wait for a human at
|
|
7
|
-
* a terminal nobody is sitting at. Neither fails — both **hang**, which during a
|
|
8
|
-
* genesis ceremony looks exactly like the platform being broken.
|
|
9
|
-
*
|
|
10
|
-
* So every key is probed under a timeout before it is offered, and the one
|
|
11
|
-
* actually chosen is proved deterministic before it is trusted with a share. An
|
|
12
|
-
* agent that signs differently twice would seal a share that can never be
|
|
13
|
-
* reopened, and that failure would surface only during recovery.
|
|
14
|
-
*/
|
|
15
|
-
export declare const PROBE_TIMEOUT_MS = 2000;
|
|
16
|
-
export interface UsableIdentity extends AgentIdentity {
|
|
17
|
-
/** Milliseconds the agent took to sign. Slow keys are usually forwarded. */
|
|
18
|
-
responseMs: number;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Every Ed25519 key in the agent that actually responds.
|
|
22
|
-
*
|
|
23
|
-
* Returns an empty array rather than throwing when the agent holds nothing
|
|
24
|
-
* usable — the caller has a better error to give than this function does.
|
|
25
|
-
*/
|
|
26
|
-
export declare function usableIdentities(socketPath?: string): Promise<UsableIdentity[]>;
|
|
27
|
-
/**
|
|
28
|
-
* Derive the custody key for a chosen identity, having proved it reproduces.
|
|
29
|
-
*
|
|
30
|
-
* `assertDeterministic` signs twice and compares. It costs one extra signature
|
|
31
|
-
* and removes the only failure mode that is invisible until recovery.
|
|
32
|
-
*/
|
|
33
|
-
export declare function custodyKeyFor(identity: AgentIdentity, socketPath?: string): Promise<Uint8Array>;
|
|
34
|
-
/** Match a key by fingerprint prefix, comment, or 1-based index. */
|
|
35
|
-
export declare function selectIdentity(identities: UsableIdentity[], selector: string): UsableIdentity | null;
|