@camstack/server 1.2.594 → 1.2.596
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/addon-root-inventory.js +50 -11
- package/dist/agent/addon-scan.js +44 -6
- package/dist/agent/agent-addon-runtime.js +8 -3
- package/dist/agent/agent-addon-updates.js +52 -12
- package/dist/agent/agent-cap-dispatch-service.js +5 -3
- package/dist/agent/agent-config.js +42 -7
- package/dist/agent/agent-deploy-swap.js +41 -5
- package/dist/agent/agent-group-runner.js +47 -8
- package/dist/agent/agent-http-auth.js +22 -10
- package/dist/agent/agent-http.js +113 -64
- package/dist/agent/agent-hub-addon-update.js +16 -10
- package/dist/agent/agent-hub-registration.js +7 -4
- package/dist/agent/agent-infra-capabilities.js +9 -5
- package/dist/agent/agent-json-file.js +42 -5
- package/dist/agent/agent-mesh-gate.js +8 -5
- package/dist/agent/agent-node-certificates.js +28 -25
- package/dist/agent/agent-pairing-local.js +47 -10
- package/dist/agent/agent-pairing-routes.js +20 -16
- package/dist/agent/agent-pairing-store.js +58 -18
- package/dist/agent/agent-reconnect.js +4 -1
- package/dist/agent/agent-service.js +71 -35
- package/dist/agent/agent-sniffing-listener.js +48 -11
- package/dist/agent/agent-undeploy.js +41 -5
- package/dist/agent/agent-update-routes.js +19 -14
- package/dist/agent/agent-update-service.js +80 -38
- package/dist/agent/apply-model-distribution.js +4 -1
- package/dist/agent/apply-stage-dev-uploads.js +9 -6
- package/dist/agent/derive-hub-url.js +8 -3
- package/dist/agent/fetch-bundle-from-hub.js +9 -6
- package/dist/agent/hubs-found.js +43 -6
- package/dist/agent/infra-boot-guard.js +4 -1
- package/dist/agent/infra-boot-plan.js +6 -2
- package/dist/agent/main.js +183 -148
- package/dist/agent/register-agent-cap-dispatch.js +6 -3
- package/dist/agent/serial-queue.js +7 -2
- package/dist/agent-status-page.js +4 -1
- package/dist/api/addon-upload.js +61 -22
- package/dist/api/agent-addon-delivery.js +11 -6
- package/dist/api/auth-whoami.js +4 -1
- package/dist/api/backup-download-pump.js +9 -5
- package/dist/api/backup-download.js +10 -7
- package/dist/api/core/addon-settings.router.js +19 -16
- package/dist/api/core/agent-pairing.router.js +79 -76
- package/dist/api/core/agents.router.js +24 -21
- package/dist/api/core/auth-admin-tokens.procedures.js +52 -48
- package/dist/api/core/auth-device-cert.procedures.js +67 -62
- package/dist/api/core/auth-limits.js +25 -16
- package/dist/api/core/auth-reauth.procedures.js +37 -32
- package/dist/api/core/auth-revoke-credentials.procedures.js +26 -22
- package/dist/api/core/auth-sessions.procedures.js +56 -52
- package/dist/api/core/auth.router.js +304 -300
- package/dist/api/core/cap-providers.js +121 -74
- package/dist/api/core/capabilities.router.js +37 -34
- package/dist/api/core/capability-preference-writes.js +17 -10
- package/dist/api/core/certificates.router.js +109 -106
- package/dist/api/core/cluster-nodes.router.js +18 -15
- package/dist/api/core/collection-preference.js +6 -2
- package/dist/api/core/event-bus-proxy.router.js +37 -34
- package/dist/api/core/failure-contributions.js +8 -4
- package/dist/api/core/hwaccel.router.js +20 -17
- package/dist/api/core/integration-secrets.js +12 -8
- package/dist/api/core/lifecycle-job-runner.js +49 -13
- package/dist/api/core/live-events.router.js +32 -29
- package/dist/api/core/load-contributions.js +8 -4
- package/dist/api/core/logging-settings.js +43 -30
- package/dist/api/core/logs.router.js +43 -40
- package/dist/api/core/notifications.router.js +18 -15
- package/dist/api/core/public-event-filter.js +8 -4
- package/dist/api/core/repl.router.js +21 -18
- package/dist/api/core/request-census-settings.js +16 -11
- package/dist/api/core/server-management.provider.js +4 -1
- package/dist/api/core/server-name.js +17 -9
- package/dist/api/core/site-location.js +24 -16
- package/dist/api/core/stream-probe.router.js +24 -21
- package/dist/api/core/system-events.router.js +26 -23
- package/dist/api/cors/cors-policy.js +29 -20
- package/dist/api/cors/register-cors-policy.js +14 -9
- package/dist/api/deploy-stage-registry.js +10 -6
- package/dist/api/dev-uploads-bundle.js +50 -12
- package/dist/api/health/adaptive-probe.routes.js +13 -9
- package/dist/api/health/health.routes.js +13 -8
- package/dist/api/hub-cluster-url.js +9 -3
- package/dist/api/model-distributor.js +50 -12
- package/dist/api/oauth2/consent-page.js +13 -10
- package/dist/api/oauth2/oauth2-routes.js +25 -17
- package/dist/api/oauth2/private-host.js +4 -1
- package/dist/api/server-upload-propagate.js +51 -15
- package/dist/api/server-upload.js +50 -13
- package/dist/api/sse-no-compression.js +4 -1
- package/dist/api/static/frame-policy.js +9 -4
- package/dist/api/static/precompressed-asset.js +57 -15
- package/dist/api/static/spa-mount.js +47 -8
- package/dist/api/static/spa-static.js +12 -5
- package/dist/api/tarball-manifest.js +44 -7
- package/dist/api/trpc/cap-mount-helpers.js +12 -7
- package/dist/api/trpc/cap-route-error-formatter.js +13 -10
- package/dist/api/trpc/cap-router-runtime.js +51 -40
- package/dist/api/trpc/client-ip.js +20 -9
- package/dist/api/trpc/core-cap-bridge.js +42 -32
- package/dist/api/trpc/device-collection-dispatch.js +27 -23
- package/dist/api/trpc/device-config-secret-redaction.js +40 -24
- package/dist/api/trpc/generated-cap-mounts.js +225 -219
- package/dist/api/trpc/generated-cap-routers.js +5167 -4852
- package/dist/api/trpc/http-request-census-hook.js +11 -8
- package/dist/api/trpc/http-request-census.js +41 -34
- package/dist/api/trpc/http-request-census.singleton.js +8 -4
- package/dist/api/trpc/localized-schema-paths.js +4 -1
- package/dist/api/trpc/principal-visibility.js +22 -14
- package/dist/api/trpc/remote-addon-update-grant.js +4 -1
- package/dist/api/trpc/scope-access.js +15 -10
- package/dist/api/trpc/server-provided-caps.js +7 -3
- package/dist/api/trpc/share-view-access.js +14 -6
- package/dist/api/trpc/trpc-error-device-tags.js +6 -3
- package/dist/api/trpc/trpc-error-principal.js +6 -2
- package/dist/api/trpc/trpc.context.js +25 -20
- package/dist/api/trpc/trpc.middleware.js +46 -38
- package/dist/api/trpc/trpc.router.js +99 -58
- package/dist/api/trpc/user-error.js +8 -5
- package/dist/api/trpc/ws-request-census.js +24 -17
- package/dist/api/trpc/ws-slow-consumer-guard.js +16 -11
- package/dist/api/upload-auth.js +9 -5
- package/dist/auth/addon-route-jwt-gate.js +7 -4
- package/dist/auth/addon-route-share-gate.js +12 -7
- package/dist/auth/app-confirm-page.js +22 -17
- package/dist/auth/app-confirm-routes.js +31 -26
- package/dist/auth/app-confirmations.js +44 -7
- package/dist/auth/app-page-shell.js +30 -17
- package/dist/auth/app-page-strings.js +17 -11
- package/dist/auth/app-passkey-page.js +21 -16
- package/dist/auth/app-passkey-routes.js +41 -37
- package/dist/auth/app-refused-route.js +18 -13
- package/dist/auth/auth-network-policy.js +15 -11
- package/dist/auth/auth-provider-gate.js +9 -4
- package/dist/auth/auth-rate-limit.js +7 -3
- package/dist/auth/client-address.js +9 -6
- package/dist/auth/device-enroll-proofs.js +43 -6
- package/dist/auth/external-link-intents.js +7 -3
- package/dist/auth/hub-sessions.js +12 -6
- package/dist/auth/native-link-completions.js +11 -7
- package/dist/auth/native-return.js +13 -9
- package/dist/auth/passkey-provider.js +32 -26
- package/dist/auth/second-factors.js +10 -6
- package/dist/auth/session-connections.js +12 -6
- package/dist/auth/session-cookie.js +23 -12
- package/dist/auth/session-lifetimes.js +12 -8
- package/dist/auth/session-mint.js +11 -4
- package/dist/auth/sso-finish-app.js +16 -13
- package/dist/auth/sso-finish-deps.js +27 -21
- package/dist/auth/sso-finish.js +38 -28
- package/dist/auth/sso-routes.js +25 -22
- package/dist/auth/used-bridge-ids.js +5 -1
- package/dist/boot/boot-config.js +55 -16
- package/dist/boot/init-sequence.js +4 -1
- package/dist/boot/integration-id-backfill.js +8 -3
- package/dist/boot/platform-keychain-key.js +42 -5
- package/dist/boot/post-boot.service.js +18 -14
- package/dist/boot/reconcile-lifecycle-jobs.js +6 -3
- package/dist/boot/retired-public-url-env.js +8 -4
- package/dist/bootstrap-packages.js +4 -1
- package/dist/closure-node-modules.js +38 -2
- package/dist/core/addon/addon-call-gateway.js +5 -1
- package/dist/core/addon/addon-package.service.js +123 -83
- package/dist/core/addon/addon-process-view.js +6 -2
- package/dist/core/addon/addon-realign-plan.js +4 -1
- package/dist/core/addon/addon-registry.service.js +187 -146
- package/dist/core/addon/addon-row-manifest.js +4 -1
- package/dist/core/addon/addon-search.service.js +7 -3
- package/dist/core/addon/addon-settings-provider.js +3 -1
- package/dist/core/addon/addon-uninstall.js +11 -4
- package/dist/core/addon/addon.tokens.js +5 -2
- package/dist/core/addon/device-meta-mirror.js +13 -8
- package/dist/core/addon/forked-custom-actions.js +11 -6
- package/dist/core/addon/integration-visibility.js +6 -3
- package/dist/core/addon/materialize-route-path.js +4 -1
- package/dist/core/addon/package-dir-utils.js +45 -8
- package/dist/core/addon/prune-misplaced-addons.js +43 -5
- package/dist/core/addon/runner-convergence.js +4 -1
- package/dist/core/addon/runner-serialization.js +4 -1
- package/dist/core/addon/runner-spawn-fanout.js +8 -3
- package/dist/core/addon/settings-door-wiring.js +8 -5
- package/dist/core/addon/single-flight-refresh.js +4 -1
- package/dist/core/addon-bridge/addon-bridge.service.js +44 -7
- package/dist/core/addon-pages/addon-pages.service.js +40 -3
- package/dist/core/addon-widgets/addon-widgets.service.js +42 -4
- package/dist/core/agent/agent-addon-backfill.js +17 -9
- package/dist/core/agent/agent-delivery-ledger.js +7 -3
- package/dist/core/agent/agent-liveness-event.js +6 -2
- package/dist/core/agent/agent-pairing-http.js +45 -41
- package/dist/core/agent/agent-registry.service.js +89 -50
- package/dist/core/agent/cluster-node-history-mirror.js +7 -3
- package/dist/core/agent/cluster-node-history-store.js +35 -31
- package/dist/core/agent/hub-agent-pairing.js +5 -1
- package/dist/core/agent/node-certificates-client.js +6 -3
- package/dist/core/agent/node-directory.js +4 -1
- package/dist/core/app-links/well-known-app-links.js +6 -2
- package/dist/core/auth/auth.service.js +8 -3
- package/dist/core/auth/handoff-code.service.js +49 -11
- package/dist/core/auth/record-kinds.js +19 -16
- package/dist/core/auth/share-token.service.js +79 -42
- package/dist/core/capability/capability.service.js +5 -1
- package/dist/core/config/config.schema.js +6 -1
- package/dist/core/config/config.service.js +6 -2
- package/dist/core/events/event-bus.service.js +7 -3
- package/dist/core/feature/feature.service.js +6 -2
- package/dist/core/lifecycle/lifecycle-runner.singleton.js +10 -5
- package/dist/core/lifecycle/lifecycle-state-machine.js +5 -1
- package/dist/core/logging/log-ring-buffer.js +5 -1
- package/dist/core/logging/logging.service.js +9 -5
- package/dist/core/logging/scoped-logger.js +5 -1
- package/dist/core/moleculer/agent-readiness-pull.js +4 -1
- package/dist/core/moleculer/agent-registration-request.js +7 -3
- package/dist/core/moleculer/cap-call-fn.js +7 -4
- package/dist/core/moleculer/cap-route-authority.js +8 -3
- package/dist/core/moleculer/hub-mesh-guard.js +9 -5
- package/dist/core/moleculer/moleculer.service.js +86 -79
- package/dist/core/network/network-quality.service.js +6 -2
- package/dist/core/notification/notification-wrapper.service.js +7 -3
- package/dist/core/notification/toast-wrapper.service.js +7 -3
- package/dist/core/provider/provider.tokens.js +4 -1
- package/dist/core/repl/repl-engine.service.js +8 -4
- package/dist/core/runner-health/runner-boot-check.js +15 -7
- package/dist/core/runner-health/update-preflight.js +14 -9
- package/dist/core/server-update/server-update.service.js +49 -12
- package/dist/core/server-update/system-apply-closure-patches.js +42 -6
- package/dist/core/server-update/system-ensure-prebuilds.js +6 -3
- package/dist/core/server-update/system-exec-npm.js +5 -2
- package/dist/core/storage/fs-storage-backend.js +5 -1
- package/dist/core/storage/storage-location-manager.js +5 -1
- package/dist/core/storage/storage.service.js +6 -2
- package/dist/core/streaming/ffmpeg-stream-info.js +8 -3
- package/dist/core/streaming/stream-probe.service.js +16 -12
- package/dist/core/streaming/ttl-cache.js +5 -1
- package/dist/core/topology/topology-emitter.service.js +23 -19
- package/dist/core/update-availability-emitter.js +7 -3
- package/dist/core/update-availability-store.js +45 -8
- package/dist/core/updates/agent-installed-packages.js +9 -5
- package/dist/core/updates/restart-marker.js +8 -3
- package/dist/core/updates/update-check-scheduler.js +18 -13
- package/dist/core/updates/wrapper-update-checker.js +7 -3
- package/dist/first-boot-addon-plan.js +6 -2
- package/dist/framework-nodepath.js +38 -2
- package/dist/i18n/request-lang.js +11 -7
- package/dist/launcher.js +65 -30
- package/dist/lifecycle-journal-path.js +38 -2
- package/dist/main.js +324 -286
- package/dist/manual-boot.js +156 -117
- package/dist/node-role.js +4 -1
- package/dist/package-inventory.js +48 -7
- package/dist/pending-restore.js +43 -7
- package/dist/single-copy-cleanup-runner.js +45 -9
- package/dist/single-copy-cleanup.js +15 -7
- package/dist/sqlite-restore.js +48 -9
- package/dist/starter.js +39 -4
- package/dist/ui-serving/lazy-ui-serving.js +39 -3
- package/package.json +7 -7
|
@@ -1,3 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AgentUpdateService = exports.AgentRestartAnnouncer = exports.AGENT_RESTART_GRACE_MS = exports.AGENT_RUNTIME_ADDON_ID = void 0;
|
|
37
|
+
exports.isRunningInContainer = isRunningInContainer;
|
|
38
|
+
exports.resolveAgentPackageJsonPath = resolveAgentPackageJsonPath;
|
|
39
|
+
exports.scheduleAgentRestart = scheduleAgentRestart;
|
|
40
|
+
exports.agentRuntimeManifestEntry = agentRuntimeManifestEntry;
|
|
1
41
|
/**
|
|
2
42
|
* AgentUpdateService — agent-side adapter over the SHARED `RootUpdateService`
|
|
3
43
|
* (`@camstack/node-root`, bundled into the `@camstack/server` dist by tsup).
|
|
@@ -20,33 +60,33 @@
|
|
|
20
60
|
*
|
|
21
61
|
* Spec: docs/superpowers/specs/2026-07-18-single-framework-copy-collapse-design.md
|
|
22
62
|
*/
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
63
|
+
const node_crypto_1 = require("node:crypto");
|
|
64
|
+
const fs = __importStar(require("node:fs"));
|
|
65
|
+
const path = __importStar(require("node:path"));
|
|
66
|
+
const system_1 = require("@camstack/system");
|
|
67
|
+
const types_1 = require("@camstack/types");
|
|
68
|
+
const system_ensure_prebuilds_js_1 = require("../core/server-update/system-ensure-prebuilds.js");
|
|
69
|
+
const system_apply_closure_patches_js_1 = require("../core/server-update/system-apply-closure-patches.js");
|
|
70
|
+
const system_exec_npm_js_1 = require("../core/server-update/system-exec-npm.js");
|
|
71
|
+
const update_availability_emitter_js_1 = require("../core/update-availability-emitter.js");
|
|
72
|
+
const update_availability_store_js_1 = require("../core/update-availability-store.js");
|
|
73
|
+
const index_js_1 = require("../server-root/index.js");
|
|
74
|
+
const restart_marker_js_1 = require("../core/updates/restart-marker.js");
|
|
35
75
|
/**
|
|
36
76
|
* The synthetic addonId the agent's OWN runtime registers infra providers
|
|
37
77
|
* under (no addon owns them — the bootstrap does). Appears in the agent's
|
|
38
78
|
* `$hub.registerNode` manifest so the hub's cap routing can reach the
|
|
39
79
|
* agent-hosted `server-management` provider via `nodeId` pinning.
|
|
40
80
|
*/
|
|
41
|
-
|
|
81
|
+
exports.AGENT_RUNTIME_ADDON_ID = 'agent-runtime';
|
|
42
82
|
/** Grace before the self-SIGTERM so the tRPC reply can flush to the hub. */
|
|
43
|
-
|
|
83
|
+
exports.AGENT_RESTART_GRACE_MS = 2_000;
|
|
44
84
|
/**
|
|
45
85
|
* Best-effort container detection for the restart-policy startup warning
|
|
46
86
|
* (security review #3). `/.dockerenv` is present in Docker/Podman containers;
|
|
47
87
|
* this is diagnostic only — never gates any logic.
|
|
48
88
|
*/
|
|
49
|
-
|
|
89
|
+
function isRunningInContainer(existsSyncFn) {
|
|
50
90
|
return existsSyncFn('/.dockerenv');
|
|
51
91
|
}
|
|
52
92
|
/**
|
|
@@ -55,7 +95,7 @@ export function isRunningInContainer(existsSyncFn) {
|
|
|
55
95
|
* `<pkg>/dist/*.js`, so `../package.json` is the normal hit; the second
|
|
56
96
|
* candidate covers a nested layout.
|
|
57
97
|
*/
|
|
58
|
-
|
|
98
|
+
function resolveAgentPackageJsonPath(fromDir) {
|
|
59
99
|
const candidates = [
|
|
60
100
|
path.resolve(fromDir, '..', 'package.json'),
|
|
61
101
|
path.resolve(fromDir, '..', '..', 'package.json'),
|
|
@@ -63,7 +103,7 @@ export function resolveAgentPackageJsonPath(fromDir) {
|
|
|
63
103
|
for (const candidate of candidates) {
|
|
64
104
|
try {
|
|
65
105
|
const raw = JSON.parse(fs.readFileSync(candidate, 'utf-8'));
|
|
66
|
-
if (raw.name === HUB_ROOT_SPEC.packageName)
|
|
106
|
+
if (raw.name === index_js_1.HUB_ROOT_SPEC.packageName)
|
|
67
107
|
return candidate;
|
|
68
108
|
}
|
|
69
109
|
catch {
|
|
@@ -85,10 +125,10 @@ export function resolveAgentPackageJsonPath(fromDir) {
|
|
|
85
125
|
* marker (it relaunches regardless), so this is a no-op there. Best-effort: a
|
|
86
126
|
* marker-write failure must never block the restart.
|
|
87
127
|
*/
|
|
88
|
-
|
|
128
|
+
function scheduleAgentRestart(logger, requestedBy, dataDir) {
|
|
89
129
|
if (dataDir !== undefined && dataDir.length > 0) {
|
|
90
130
|
try {
|
|
91
|
-
writeRestartIntentMarker(serverRootDir(dataDir), {
|
|
131
|
+
(0, index_js_1.writeRestartIntentMarker)((0, index_js_1.serverRootDir)(dataDir), {
|
|
92
132
|
requestedAtMs: Date.now(),
|
|
93
133
|
reason: requestedBy,
|
|
94
134
|
});
|
|
@@ -100,13 +140,13 @@ export function scheduleAgentRestart(logger, requestedBy, dataDir) {
|
|
|
100
140
|
}
|
|
101
141
|
}
|
|
102
142
|
logger.warn('agent restart requested — exiting for supervisor relaunch', {
|
|
103
|
-
meta: { requestedBy, graceMs: AGENT_RESTART_GRACE_MS },
|
|
143
|
+
meta: { requestedBy, graceMs: exports.AGENT_RESTART_GRACE_MS },
|
|
104
144
|
});
|
|
105
145
|
const grace = setTimeout(() => {
|
|
106
146
|
process.kill(process.pid, 'SIGTERM');
|
|
107
147
|
const hard = setTimeout(() => process.exit(0), 15_000);
|
|
108
148
|
hard.unref();
|
|
109
|
-
}, AGENT_RESTART_GRACE_MS);
|
|
149
|
+
}, exports.AGENT_RESTART_GRACE_MS);
|
|
110
150
|
grace.unref();
|
|
111
151
|
}
|
|
112
152
|
/**
|
|
@@ -121,7 +161,7 @@ export function scheduleAgentRestart(logger, requestedBy, dataDir) {
|
|
|
121
161
|
* once the mesh is up). A restart before that has nobody to tell — said, never
|
|
122
162
|
* silent.
|
|
123
163
|
*/
|
|
124
|
-
|
|
164
|
+
class AgentRestartAnnouncer {
|
|
125
165
|
logger;
|
|
126
166
|
eventBus;
|
|
127
167
|
nodeId;
|
|
@@ -145,10 +185,10 @@ export class AgentRestartAnnouncer {
|
|
|
145
185
|
const payload = { ...marker, nodeId: this.nodeId };
|
|
146
186
|
try {
|
|
147
187
|
bus.emit({
|
|
148
|
-
id: randomUUID(),
|
|
188
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
149
189
|
timestamp: new Date(),
|
|
150
190
|
source: { type: 'core', id: 'agent-update-service' },
|
|
151
|
-
category: EventCategory.SystemRestarting,
|
|
191
|
+
category: types_1.EventCategory.SystemRestarting,
|
|
152
192
|
data: payload,
|
|
153
193
|
});
|
|
154
194
|
}
|
|
@@ -161,7 +201,8 @@ export class AgentRestartAnnouncer {
|
|
|
161
201
|
}
|
|
162
202
|
}
|
|
163
203
|
}
|
|
164
|
-
|
|
204
|
+
exports.AgentRestartAnnouncer = AgentRestartAnnouncer;
|
|
205
|
+
class AgentUpdateService extends index_js_1.RootUpdateService {
|
|
165
206
|
restartAnnouncer;
|
|
166
207
|
updateAvailability;
|
|
167
208
|
eventBus;
|
|
@@ -179,7 +220,7 @@ export class AgentUpdateService extends RootUpdateService {
|
|
|
179
220
|
const nodeId = options.nodeId ?? process.env['CAMSTACK_NODE_ID'] ?? 'agent';
|
|
180
221
|
const restartAnnouncer = new AgentRestartAnnouncer(options.logger, options.eventBus ?? null, nodeId);
|
|
181
222
|
super({
|
|
182
|
-
spec: HUB_ROOT_SPEC,
|
|
223
|
+
spec: index_js_1.HUB_ROOT_SPEC,
|
|
183
224
|
nodeId,
|
|
184
225
|
// The agent's on-disk root IS `@camstack/server` (booted via
|
|
185
226
|
// CAMSTACK_ROLE=agent by the shared starter), so it reads the SAME
|
|
@@ -202,19 +243,19 @@ export class AgentUpdateService extends RootUpdateService {
|
|
|
202
243
|
// bare Node with no system npm, so the raw `execFile('npm')` default would
|
|
203
244
|
// ENOENT. `cacheDir` mirrors AddonInstaller's `<dataDir>/addons/.npm-bootstrap`.
|
|
204
245
|
execNpm: options.execNpm ??
|
|
205
|
-
buildSystemExecNpm({
|
|
246
|
+
(0, system_exec_npm_js_1.buildSystemExecNpm)({
|
|
206
247
|
cacheDir: path.join(options.dataDir, 'addons', '.npm-bootstrap'),
|
|
207
248
|
logger: options.logger,
|
|
208
249
|
}),
|
|
209
250
|
// Same native-prebuild ensure step as the hub — a packaged desktop AGENT
|
|
210
251
|
// ships the identical bare Node, so its `applyServerUpdate` staging would
|
|
211
252
|
// hit the same source-only `better-sqlite3` miss without this.
|
|
212
|
-
ensureNativePrebuilds: options.ensureNativePrebuilds ?? buildSystemEnsureNativePrebuilds(options.logger),
|
|
253
|
+
ensureNativePrebuilds: options.ensureNativePrebuilds ?? (0, system_ensure_prebuilds_js_1.buildSystemEnsureNativePrebuilds)(options.logger),
|
|
213
254
|
// Apply the closure patches ourselves. npm 12 blocks the root package's
|
|
214
255
|
// postinstall by default, and a silently-unpatched closure is refused by
|
|
215
256
|
// the validator — an update that can never apply. Idempotent, so this
|
|
216
257
|
// costs nothing where npm did run the lifecycle.
|
|
217
|
-
applyClosurePatches: options.applyClosurePatches ?? buildSystemApplyClosurePatches(options.logger),
|
|
258
|
+
applyClosurePatches: options.applyClosurePatches ?? (0, system_apply_closure_patches_js_1.buildSystemApplyClosurePatches)(options.logger),
|
|
218
259
|
env: options.env,
|
|
219
260
|
now: options.now,
|
|
220
261
|
...(options.runnerBootCheck !== undefined
|
|
@@ -228,7 +269,7 @@ export class AgentUpdateService extends RootUpdateService {
|
|
|
228
269
|
this.eventBus = options.eventBus ?? null;
|
|
229
270
|
this.updateAvailability =
|
|
230
271
|
options.eventBus !== undefined
|
|
231
|
-
? new UpdateAvailabilityEmitter(options.eventBus, { type: 'core', id: 'agent-update-service' }, options.updateAvailabilityStore)
|
|
272
|
+
? new update_availability_emitter_js_1.UpdateAvailabilityEmitter(options.eventBus, { type: 'core', id: 'agent-update-service' }, options.updateAvailabilityStore)
|
|
232
273
|
: null;
|
|
233
274
|
}
|
|
234
275
|
/**
|
|
@@ -240,7 +281,7 @@ export class AgentUpdateService extends RootUpdateService {
|
|
|
240
281
|
this.eventBus = eventBus;
|
|
241
282
|
this.nodeId = nodeId;
|
|
242
283
|
this.restartAnnouncer.bind(eventBus, nodeId);
|
|
243
|
-
this.updateAvailability = new UpdateAvailabilityEmitter(eventBus, { type: 'core', id: 'agent-update-service' }, new FileUpdateAvailabilityStore(this.agentDataDir, 'agent-update', this.agentLogger));
|
|
284
|
+
this.updateAvailability = new update_availability_emitter_js_1.UpdateAvailabilityEmitter(eventBus, { type: 'core', id: 'agent-update-service' }, new update_availability_store_js_1.FileUpdateAvailabilityStore(this.agentDataDir, 'agent-update', this.agentLogger));
|
|
244
285
|
}
|
|
245
286
|
async checkServerUpdate() {
|
|
246
287
|
const result = await super.checkServerUpdate();
|
|
@@ -264,7 +305,7 @@ export class AgentUpdateService extends RootUpdateService {
|
|
|
264
305
|
const bus = this.eventBus;
|
|
265
306
|
if (bus === null)
|
|
266
307
|
return;
|
|
267
|
-
const marker = readPendingRestart(this.agentDataDir);
|
|
308
|
+
const marker = (0, system_1.readPendingRestart)(this.agentDataDir);
|
|
268
309
|
if (marker === null)
|
|
269
310
|
return;
|
|
270
311
|
const payload = {
|
|
@@ -277,25 +318,26 @@ export class AgentUpdateService extends RootUpdateService {
|
|
|
277
318
|
...(marker.requestedBy !== undefined ? { requestedBy: marker.requestedBy } : {}),
|
|
278
319
|
};
|
|
279
320
|
bus.emit({
|
|
280
|
-
id: randomUUID(),
|
|
321
|
+
id: (0, node_crypto_1.randomUUID)(),
|
|
281
322
|
timestamp: new Date(),
|
|
282
323
|
source: { type: 'core', id: 'agent-update-service' },
|
|
283
|
-
category: EventCategory.SystemRestartCompleted,
|
|
324
|
+
category: types_1.EventCategory.SystemRestartCompleted,
|
|
284
325
|
data: payload,
|
|
285
326
|
});
|
|
286
327
|
}
|
|
287
328
|
}
|
|
329
|
+
exports.AgentUpdateService = AgentUpdateService;
|
|
288
330
|
/** Write the marker and return it — the same payload is the announcement (D723). */
|
|
289
331
|
function writeAgentRestartMarker(dataDir, requestedBy, update) {
|
|
290
332
|
// Same builder as the hub: an agent's "Server aggiornato" notification must
|
|
291
333
|
// name both versions too — see `core/updates/restart-marker.ts`.
|
|
292
|
-
const marker = buildRestartMarker({
|
|
334
|
+
const marker = (0, restart_marker_js_1.buildRestartMarker)({
|
|
293
335
|
requestedAt: Date.now(),
|
|
294
336
|
requestedBy,
|
|
295
337
|
...(update !== undefined ? { update } : {}),
|
|
296
338
|
});
|
|
297
339
|
try {
|
|
298
|
-
writePendingRestart(dataDir, marker);
|
|
340
|
+
(0, system_1.writePendingRestart)(dataDir, marker);
|
|
299
341
|
}
|
|
300
342
|
catch {
|
|
301
343
|
// Marker write must never block the restart.
|
|
@@ -308,9 +350,9 @@ function writeAgentRestartMarker(dataDir, requestedBy, update) {
|
|
|
308
350
|
* `HubNodeRegistry` (and therefore `createCapabilityProxy` node routing) even
|
|
309
351
|
* though no `loadedAddons` entry owns it.
|
|
310
352
|
*/
|
|
311
|
-
|
|
353
|
+
function agentRuntimeManifestEntry() {
|
|
312
354
|
return {
|
|
313
|
-
addonId: AGENT_RUNTIME_ADDON_ID,
|
|
355
|
+
addonId: exports.AGENT_RUNTIME_ADDON_ID,
|
|
314
356
|
capabilities: ['server-management', 'node-certificates'],
|
|
315
357
|
};
|
|
316
358
|
}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Agent-side model distribution (P2): pull a staged model tarball from the hub
|
|
3
4
|
* and untar it into this node's modelsDir. Factored behind a seam so the
|
|
4
5
|
* fetch/extract/fs effects are injectable in tests.
|
|
5
6
|
*/
|
|
6
|
-
|
|
7
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
|
+
exports.applyModelDistribution = applyModelDistribution;
|
|
9
|
+
async function applyModelDistribution(seam, params) {
|
|
7
10
|
seam.mkdirp(seam.modelsDir);
|
|
8
11
|
const buffer = await seam.fetchBundle(params.source);
|
|
9
12
|
await seam.extract(buffer, seam.modelsDir);
|
|
@@ -1,18 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.applyStageDevUploads = applyStageDevUploads;
|
|
1
4
|
/**
|
|
2
5
|
* Pure seam for `$agent.stageDevUploads` — fetch a hub-staged pack of
|
|
3
6
|
* `dev-uploads/<version>/` and write it under this node's server-root.
|
|
4
7
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const index_js_1 = require("../server-root/index.js");
|
|
10
|
+
async function applyStageDevUploads(seam, params) {
|
|
8
11
|
const { version, source } = params;
|
|
9
|
-
if (!isDevChannelVersion(version)) {
|
|
12
|
+
if (!(0, index_js_1.isDevChannelVersion)(version)) {
|
|
10
13
|
throw new Error(`$agent.stageDevUploads: version "${version}" is not dev-channel shaped`);
|
|
11
14
|
}
|
|
12
15
|
const bundle = await seam.fetchBundle(source);
|
|
13
|
-
const appliedSha256 = createHash('sha256').update(bundle).digest('hex');
|
|
16
|
+
const appliedSha256 = (0, node_crypto_1.createHash)('sha256').update(bundle).digest('hex');
|
|
14
17
|
const unpacked = await seam.unpack({
|
|
15
|
-
serverRoot: serverRootDir(seam.dataDir),
|
|
18
|
+
serverRoot: (0, index_js_1.serverRootDir)(seam.dataDir),
|
|
16
19
|
version,
|
|
17
20
|
bundle,
|
|
18
21
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* Derive the agent's `CAMSTACK_HUB_URL` from its friendly `hubAddress`.
|
|
3
4
|
*
|
|
@@ -23,8 +24,12 @@
|
|
|
23
24
|
* Because every current consumer keeps only the host, the port is convention;
|
|
24
25
|
* a future full-URL consumer must treat it as the default, not authoritative.
|
|
25
26
|
*/
|
|
27
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
+
exports.deriveHubUrlFromHubAddress = deriveHubUrlFromHubAddress;
|
|
29
|
+
exports.deriveHubUrlForExport = deriveHubUrlForExport;
|
|
30
|
+
exports.pickIpv4 = pickIpv4;
|
|
26
31
|
const HUB_API_PORT = 4443;
|
|
27
|
-
|
|
32
|
+
function deriveHubUrlFromHubAddress(hubAddress) {
|
|
28
33
|
const trimmed = hubAddress.trim();
|
|
29
34
|
if (trimmed.length === 0)
|
|
30
35
|
return undefined;
|
|
@@ -44,7 +49,7 @@ export function deriveHubUrlFromHubAddress(hubAddress) {
|
|
|
44
49
|
* today's working deployments. Kept pure (env is passed in) so both the
|
|
45
50
|
* boot-time derivation and the reconnect path can be unit-tested.
|
|
46
51
|
*/
|
|
47
|
-
|
|
52
|
+
function deriveHubUrlForExport(hubUrlWasExplicit, hubAddress) {
|
|
48
53
|
if (hubUrlWasExplicit)
|
|
49
54
|
return undefined;
|
|
50
55
|
if (hubAddress === undefined)
|
|
@@ -70,7 +75,7 @@ function extractHostFromAuthority(authority) {
|
|
|
70
75
|
* Canonical home of this helper — `resolveHubEndpoint` in `agent-http.ts`
|
|
71
76
|
* (UI-facing `resolvedHubAddress`) re-exports and reuses it.
|
|
72
77
|
*/
|
|
73
|
-
|
|
78
|
+
function pickIpv4(ipList) {
|
|
74
79
|
if (!ipList)
|
|
75
80
|
return null;
|
|
76
81
|
for (const ip of ipList) {
|
|
@@ -1,10 +1,13 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchBundleFromHub = fetchBundleFromHub;
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const undici_1 = require("undici");
|
|
3
6
|
/**
|
|
4
7
|
* Stream a staged addon tgz from the hub's one-time-token bundle route and
|
|
5
8
|
* verify integrity (byte count + sha256) before handing it to the installer.
|
|
6
9
|
*/
|
|
7
|
-
|
|
10
|
+
async function fetchBundleFromHub(opts) {
|
|
8
11
|
// When a fetchImpl is injected (tests), call it as-is — the stub ignores dispatcher.
|
|
9
12
|
// For production (global fetch against the real hub's self-signed TLS cert), use
|
|
10
13
|
// undici.fetch with an Agent that disables CA verification. The hub serves HTTPS with a
|
|
@@ -24,9 +27,9 @@ export async function fetchBundleFromHub(opts) {
|
|
|
24
27
|
const authHeader = { Authorization: `Bearer ${opts.token}`, 'accept-encoding': 'identity' };
|
|
25
28
|
const res = opts.fetchImpl
|
|
26
29
|
? await opts.fetchImpl(opts.url, { headers: authHeader })
|
|
27
|
-
: await
|
|
30
|
+
: await (0, undici_1.fetch)(opts.url, {
|
|
28
31
|
headers: authHeader,
|
|
29
|
-
dispatcher: new Agent({ connect: { rejectUnauthorized: false } }),
|
|
32
|
+
dispatcher: new undici_1.Agent({ connect: { rejectUnauthorized: false } }),
|
|
30
33
|
});
|
|
31
34
|
if (!res.ok) {
|
|
32
35
|
throw new Error(`bundle fetch failed: HTTP ${res.status}`);
|
|
@@ -35,7 +38,7 @@ export async function fetchBundleFromHub(opts) {
|
|
|
35
38
|
if (buffer.length !== opts.bytes) {
|
|
36
39
|
throw new Error(`bundle bytes mismatch: expected ${opts.bytes}, got ${buffer.length}`);
|
|
37
40
|
}
|
|
38
|
-
const sha = createHash('sha256').update(buffer).digest('hex');
|
|
41
|
+
const sha = (0, node_crypto_1.createHash)('sha256').update(buffer).digest('hex');
|
|
39
42
|
if (sha !== opts.sha256) {
|
|
40
43
|
throw new Error(`bundle sha256 mismatch: expected ${opts.sha256}, got ${sha}`);
|
|
41
44
|
}
|
package/dist/agent/hubs-found.js
CHANGED
|
@@ -1,6 +1,43 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CONFIGURED_HUB_SOURCE = void 0;
|
|
37
|
+
exports.createHubsFinder = createHubsFinder;
|
|
38
|
+
const derive_hub_url_js_1 = require("./derive-hub-url.js");
|
|
2
39
|
/** Label of the configured hub in {@link FoundHub.sources}. */
|
|
3
|
-
|
|
40
|
+
exports.CONFIGURED_HUB_SOURCE = 'configured hub address';
|
|
4
41
|
/** A scan newer than this answers a refresh without scanning again. */
|
|
5
42
|
const MIN_RESCAN_INTERVAL_MS = 5_000;
|
|
6
43
|
const BROWSE_TIMEOUT_MS = 3_000;
|
|
@@ -15,10 +52,10 @@ function toFoundHub(candidate) {
|
|
|
15
52
|
}
|
|
16
53
|
async function defaultDiscover(deps) {
|
|
17
54
|
// Lazy: the socket library is only loaded when an operator asks.
|
|
18
|
-
const { discoverHubs } = await
|
|
55
|
+
const { discoverHubs } = await Promise.resolve().then(() => __importStar(require('@camstack/develop/hub-discovery')));
|
|
19
56
|
return discoverHubs(deps);
|
|
20
57
|
}
|
|
21
|
-
|
|
58
|
+
function createHubsFinder(deps) {
|
|
22
59
|
const discover = deps.discover ?? defaultDiscover;
|
|
23
60
|
const now = deps.now ?? Date.now;
|
|
24
61
|
let hubs = [];
|
|
@@ -27,13 +64,13 @@ export function createHubsFinder(deps) {
|
|
|
27
64
|
const snapshot = () => ({ hubs, scannedAt, scanning: inFlight !== null });
|
|
28
65
|
const scan = async () => {
|
|
29
66
|
const configured = deps.getConfiguredHubAddress();
|
|
30
|
-
const configuredUrl = configured === null ? undefined : deriveHubUrlFromHubAddress(configured);
|
|
67
|
+
const configuredUrl = configured === null ? undefined : (0, derive_hub_url_js_1.deriveHubUrlFromHubAddress)(configured);
|
|
31
68
|
try {
|
|
32
69
|
const found = await discover({
|
|
33
70
|
mdnsTimeoutMs: BROWSE_TIMEOUT_MS,
|
|
34
71
|
known: configuredUrl === undefined
|
|
35
72
|
? []
|
|
36
|
-
: [{ url: configuredUrl, source: CONFIGURED_HUB_SOURCE }],
|
|
73
|
+
: [{ url: configuredUrl, source: exports.CONFIGURED_HUB_SOURCE }],
|
|
37
74
|
onProblem: (message) => deps.log?.(`hub browse problem: ${message}`),
|
|
38
75
|
});
|
|
39
76
|
hubs = found.map(toFoundHub);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
"use strict";
|
|
1
2
|
/**
|
|
2
3
|
* infra-boot-guard.ts — the agent's "did my infrastructure actually load?" gate.
|
|
3
4
|
*
|
|
@@ -32,6 +33,8 @@
|
|
|
32
33
|
* first — an operator staring at a crash-loop needs the whole list, and the
|
|
33
34
|
* four that vanished together on little-unraid vanished for one single reason.
|
|
34
35
|
*/
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
exports.assertRequiredInfraResolved = assertRequiredInfraResolved;
|
|
35
38
|
/**
|
|
36
39
|
* Throw when any `required` infra capability resolved to no addon at all.
|
|
37
40
|
*
|
|
@@ -40,7 +43,7 @@
|
|
|
40
43
|
* `metrics-provider`, `log-destination`) are the caller's business — they are
|
|
41
44
|
* already logged individually and are legitimately absent on some nodes.
|
|
42
45
|
*/
|
|
43
|
-
|
|
46
|
+
function assertRequiredInfraResolved(resolutions, addonsDir) {
|
|
44
47
|
const missing = resolutions.filter((r) => r.required && r.addonId === null).map((r) => r.name);
|
|
45
48
|
if (missing.length === 0)
|
|
46
49
|
return;
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.planInfraBoot = planInfraBoot;
|
|
4
|
+
exports.planToResolutions = planToResolutions;
|
|
1
5
|
/**
|
|
2
6
|
* `log-destination` prefers `hub-forwarder` (ships agent logs to the hub)
|
|
3
7
|
* over a local winston — mirrors the historical inline choice.
|
|
@@ -8,7 +12,7 @@ function pickCandidate(capName, candidates) {
|
|
|
8
12
|
}
|
|
9
13
|
return candidates[0];
|
|
10
14
|
}
|
|
11
|
-
|
|
15
|
+
function planInfraBoot(addons, infraList) {
|
|
12
16
|
const initialized = new Set();
|
|
13
17
|
const steps = [];
|
|
14
18
|
for (const infra of infraList) {
|
|
@@ -36,6 +40,6 @@ export function planInfraBoot(addons, infraList) {
|
|
|
36
40
|
return steps;
|
|
37
41
|
}
|
|
38
42
|
/** Project a plan onto the guard's resolution shape. */
|
|
39
|
-
|
|
43
|
+
function planToResolutions(steps) {
|
|
40
44
|
return steps.map((s) => ({ name: s.capName, required: s.required, addonId: s.addonId }));
|
|
41
45
|
}
|