@camstack/system 1.2.471 → 1.2.473

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.
Files changed (95) hide show
  1. package/dist/addon-runner.js +202 -8
  2. package/dist/addon-runner.mjs +203 -9
  3. package/dist/addon-utils.mjs +1 -1
  4. package/dist/{agent-https-bH6bKDeK.js → agent-https-B9Q3-IKd.js} +2 -5
  5. package/dist/{agent-https-DHBvFZJS.mjs → agent-https-DOwn4pqL.mjs} +3 -6
  6. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +1 -1
  7. package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +4 -4
  8. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +1 -1
  9. package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +5 -5
  10. package/dist/builtins/alerts/alerts.addon.js +1 -1
  11. package/dist/builtins/alerts/alerts.addon.mjs +1 -1
  12. package/dist/builtins/autotrack/index.js +1 -1
  13. package/dist/builtins/autotrack/index.mjs +1 -1
  14. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2 -2
  15. package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +5 -5
  16. package/dist/builtins/calendars/calendars.addon.js +1 -1
  17. package/dist/builtins/calendars/calendars.addon.mjs +1 -1
  18. package/dist/builtins/camera-grid/index.js +1 -1
  19. package/dist/builtins/camera-grid/index.mjs +1 -1
  20. package/dist/builtins/composer/composer.addon.js +2 -2
  21. package/dist/builtins/composer/composer.addon.mjs +2 -2
  22. package/dist/builtins/console-logging/index.js +1 -1
  23. package/dist/builtins/console-logging/index.mjs +1 -1
  24. package/dist/builtins/core-blocks/core-blocks.addon.js +2 -2
  25. package/dist/builtins/core-blocks/core-blocks.addon.mjs +2 -2
  26. package/dist/builtins/device-history/device-history.addon.js +1 -1
  27. package/dist/builtins/device-history/device-history.addon.mjs +1 -1
  28. package/dist/builtins/device-manager/device-manager.addon.js +2 -2
  29. package/dist/builtins/device-manager/device-manager.addon.mjs +2 -2
  30. package/dist/builtins/hub-forwarder/index.js +1 -1
  31. package/dist/builtins/hub-forwarder/index.mjs +1 -1
  32. package/dist/builtins/keychain/index.js +3 -3
  33. package/dist/builtins/keychain/index.mjs +3 -3
  34. package/dist/builtins/liveness-monitor/liveness-monitor.addon.d.ts +9 -25
  35. package/dist/builtins/liveness-monitor/liveness-monitor.addon.js +240 -39
  36. package/dist/builtins/liveness-monitor/liveness-monitor.addon.mjs +237 -38
  37. package/dist/builtins/liveness-monitor/liveness-reporter.d.ts +28 -0
  38. package/dist/builtins/liveness-monitor/storage-root-access.d.ts +53 -0
  39. package/dist/builtins/local-auth/local-auth.addon.js +16 -2
  40. package/dist/builtins/local-auth/local-auth.addon.mjs +19 -5
  41. package/dist/builtins/local-auth/person-scopes.d.ts +7 -0
  42. package/dist/builtins/local-network/local-network.addon.js +2 -2
  43. package/dist/builtins/local-network/local-network.addon.mjs +2 -2
  44. package/dist/builtins/loki-logging/index.js +1 -1
  45. package/dist/builtins/loki-logging/index.mjs +1 -1
  46. package/dist/builtins/native-metrics/native-metrics.addon.js +1 -1
  47. package/dist/builtins/native-metrics/native-metrics.addon.mjs +10 -10
  48. package/dist/builtins/platform-probe/accelerator-facts-probe.d.ts +24 -0
  49. package/dist/builtins/platform-probe/index.js +110 -10
  50. package/dist/builtins/platform-probe/index.mjs +116 -17
  51. package/dist/builtins/platform-probe/platform-scorer.d.ts +10 -2
  52. package/dist/builtins/record-entries/index.js +1 -1
  53. package/dist/builtins/record-entries/index.mjs +1 -1
  54. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +1 -1
  55. package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +1 -1
  56. package/dist/builtins/snapshot/index.js +1 -1
  57. package/dist/builtins/snapshot/index.mjs +1 -1
  58. package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +1 -1
  59. package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +20 -20
  60. package/dist/builtins/sqlite-storage/index.js +1 -1
  61. package/dist/builtins/sqlite-storage/index.mjs +1 -1
  62. package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +3 -3
  63. package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +3 -3
  64. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1 -1
  65. package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1 -1
  66. package/dist/builtins/system-config/system-config.addon.js +3 -3
  67. package/dist/builtins/system-config/system-config.addon.mjs +115 -115
  68. package/dist/builtins/winston-logging/index.js +1 -1
  69. package/dist/builtins/winston-logging/index.mjs +1 -1
  70. package/dist/{composition-sources-B5uJZXZ1.js → composition-sources-Dj_nInUQ.js} +1 -1
  71. package/dist/{composition-sources-DRw_vBKH.mjs → composition-sources-cwD35HB0.mjs} +1 -1
  72. package/dist/{constants-CToE4OFp.js → constants-XkWSVvgY.js} +1 -1
  73. package/dist/{constants-5lA8Z9d8.mjs → constants-p5mPM1iL.mjs} +1 -1
  74. package/dist/{coral-accelerators-BW3OcrLD.mjs → coral-accelerators-DBlgWB8k.mjs} +6 -6
  75. package/dist/{custom-action-registry-BGYDjTqY.mjs → custom-action-registry-DZSCLBuT.mjs} +37 -37
  76. package/dist/{device-ca-nOCYVFS4.js → device-ca-BXzQ1pYj.js} +1 -1
  77. package/dist/{device-ca-URrs1lxK.mjs → device-ca-DyUtcpf4.mjs} +1 -1
  78. package/dist/{dist-BjcWEfRy.js → dist-Bmah6waF.js} +209 -266
  79. package/dist/{dist-5XUG7iYJ.mjs → dist-C9lbdBL5.mjs} +204 -267
  80. package/dist/file-host-worker.js +1 -1
  81. package/dist/file-host-worker.mjs +1 -1
  82. package/dist/{hub-mdns-ciao-zD3JojB_.mjs → hub-mdns-ciao-BemeCNGe.mjs} +2 -2
  83. package/dist/{hub-mdns-ciao-vEWhJ_SD.js → hub-mdns-ciao-CUr6ewsX.js} +2 -2
  84. package/dist/index.js +236 -16
  85. package/dist/index.mjs +455 -235
  86. package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +24 -4
  87. package/dist/kernel/hwaccel/vaapi-init-probe.d.ts +29 -0
  88. package/dist/kernel/moleculer/runner-process-group.d.ts +4 -0
  89. package/dist/{restore-archive-CN1pJTRn.mjs → restore-archive-C0aohmAK.mjs} +94 -94
  90. package/dist/{restore-archive-B64m2nAj.js → restore-archive-DbPmyjiM.js} +1 -1
  91. package/dist/{retired-settings-keys-C_Kjp-Bj.mjs → retired-settings-keys-CWp7ZSeA.mjs} +8 -0
  92. package/dist/{retired-settings-keys-CGUqX-Oz.js → retired-settings-keys-DorakcxV.js} +8 -0
  93. package/dist/{wal-maintenance-BNXVX-ot.js → wal-maintenance-BT8Ns0W3.js} +0 -0
  94. package/dist/{wal-maintenance-Bl2I-ZcR.mjs → wal-maintenance-BuB731DK.mjs} +0 -0
  95. package/package.json +6 -6
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  import { i as __require } from "./chunk-CNf5ZN-e.mjs";
2
- import { $r as errMsg$1, Ar as supportedRuntimes, Cn as isCollectionArrayMethod, Da as EventCategory$1, Dn as isObjectInput, Ea as withoutCallerStamp, Fi as asString$1, J as METHOD_ACCESS_MAP, Jn as objectInputDeclaresAddonId, K as LOG_LEVEL_RANK, Ki as defineRecordKinds, Ni as asJsonObject$1, On as isVoidInput, Pi as asNumber, Pn as lifecycleJobSchema, Rn as logLevelAtMost, Sn as isArrayOutputSchema, Sr as splitTranslationRef, Ta as userError, Ui as createEvent$1, Yi as expandCapMethods, Yn as objectInputDeclaresRequiredDeviceId, _ as CatalogFileSchema, ai as DEVICE_STATUS_METHOD, bi as ReadinessRegistry, da as parseJsonObject, er as procedureAuthKey, fa as parseJsonUnknown, fn as extractNestedAddonId, fr as resolveMethodAuth, ga as resolveCapMount, gr as scopesAllowDeviceCap, hr as scopesAllowAddon, ii as DEVICE_SETTINGS_CONTRIBUTION_METHODS, kn as kebabToCamel$1, ma as readinessKey, n as AGENT_MDNS_TXT_KEYS, ni as CALLER_STAMPED_CAPABILITIES$1, qi as emitDownForOwnedCaps, r as ALL_CAPABILITY_DEFINITIONS, ri as DATAPLANE_SECRET_HEADER$1, t as AGENT_MDNS_SERVICE_TYPE, u as CATALOG_LANGS, va as scopeKey, vn as interpolate, vt as addonSettingsCapability, xi as ReadinessTimeoutError, yi as RUNTIME_DEFAULTS, zn as looseSchema } from "./dist-5XUG7iYJ.mjs";
3
- import { d as JWT_SIGNING_KEY_REF, f as JwtSigningKeyUnavailableError, g as processJwtSigningKey, i as generateDeviceCa, l as verifyDeviceLeaf, m as getProcessJwtSigningKeyState, n as DEVICE_CA_KEY_REF, o as issueDeviceLeaf, p as SYSTEM_SECRET_OWNER, s as loadDeviceCa, u as verifyDeviceSignature, v as staticJwtSigningKey } from "./device-ca-URrs1lxK.mjs";
2
+ import { Cn as isCollectionArrayMethod, Cr as splitTranslationRef, Da as withoutCallerStamp, Dn as isObjectInput, Ea as userError, Fi as asNumber, Ii as asString$1, J as METHOD_ACCESS_MAP, Ji as emitDownForOwnedCaps, Jn as objectInputDeclaresAddonId, K as LOG_LEVEL_RANK, Oa as EventCategory$1, On as isVoidInput, Pi as asJsonObject$1, Pn as lifecycleJobSchema, Rn as logLevelAtMost, Si as ReadinessTimeoutError, Sn as isArrayOutputSchema, Wi as createEvent$1, Xi as expandCapMethods, Yn as objectInputDeclaresRequiredDeviceId, _ as CatalogFileSchema, _a as resolveCapMount, _r as scopesAllowDeviceCap, ai as DEVICE_SETTINGS_CONTRIBUTION_METHODS, bi as RUNTIME_DEFAULTS, ei as errMsg$1, fa as parseJsonObject, fn as extractNestedAddonId, gr as scopesAllowAddon, ha as readinessKey, ii as DATAPLANE_SECRET_HEADER$1, jr as supportedRuntimes, kn as kebabToCamel$1, n as AGENT_MDNS_TXT_KEYS, oi as DEVICE_STATUS_METHOD, pa as parseJsonUnknown, pr as resolveMethodAuth, qi as defineRecordKinds, r as ALL_CAPABILITY_DEFINITIONS, ri as CALLER_STAMPED_CAPABILITIES$1, t as AGENT_MDNS_SERVICE_TYPE, tr as procedureAuthKey, u as CATALOG_LANGS, vn as interpolate, vt as addonSettingsCapability, xi as ReadinessRegistry, ya as scopeKey, zn as looseSchema } from "./dist-C9lbdBL5.mjs";
3
+ import { d as JWT_SIGNING_KEY_REF, f as JwtSigningKeyUnavailableError, g as processJwtSigningKey, i as generateDeviceCa, l as verifyDeviceLeaf, m as getProcessJwtSigningKeyState, n as DEVICE_CA_KEY_REF, o as issueDeviceLeaf, p as SYSTEM_SECRET_OWNER, s as loadDeviceCa, u as verifyDeviceSignature, v as staticJwtSigningKey } from "./device-ca-DyUtcpf4.mjs";
4
4
  import { t as require_read_all_rows } from "./read-all-rows-TaPqdWNF.mjs";
5
5
  import { AlertCenterAddon } from "./builtins/alerts/alerts.addon.mjs";
6
6
  import "./builtins/alerts/index.mjs";
@@ -25,22 +25,22 @@ import { LokiDestination, LokiLoggingAddon } from "./builtins/loki-logging/index
25
25
  import NativeMetricsAddon, { a as NativeMetricsProvider, n as nodeProcReader, r as parseProcStat } from "./builtins/native-metrics/native-metrics.addon.mjs";
26
26
  import { DeviceHistoryAddon } from "./builtins/device-history/device-history.addon.mjs";
27
27
  import { FilesystemStorageAddon, t as FilesystemStorageProvider } from "./builtins/sqlite-storage/filesystem-storage.addon.mjs";
28
- import { C as RecordsEngine, l as SqliteSettingsBackend } from "./wal-maintenance-Bl2I-ZcR.mjs";
28
+ import { C as RecordsEngine, l as SqliteSettingsBackend } from "./wal-maintenance-BuB731DK.mjs";
29
29
  import { SqliteSettingsAddon } from "./builtins/sqlite-storage/sqlite-settings.addon.mjs";
30
30
  import { ConfigStore, DeviceStore } from "./builtins/sqlite-storage/index.mjs";
31
31
  import { StorageOrchestratorAddon, a as stripForwardedCaller, i as createHubCapForwardService, l as STORAGE_DRAIN_STATE_LEGACY, n as HUB_CAP_FWD_ACTION, o as buildStorageLocationRegistry, r as HUB_CAP_FWD_SERVICE, t as StorageOrchestratorService, u as storageOrchestratorRecordKinds } from "./builtins/storage-orchestrator/storage-orchestrator.addon.mjs";
32
32
  import "./builtins/storage-orchestrator/index.mjs";
33
- import { A as buildNameConstraintSet, B as setProcessAgentHttpsNames, C as LEAF_RENEWAL_WINDOW_DAYS, E as evaluateExistingCert, F as readNameConstraints, I as AGENT_HTTPS_NAMES_COLLECTION, L as AGENT_HTTPS_NAMES_COLUMNS, M as isLocalOnlyHostname, N as permitsIdentity, O as PERMITTED_DNS_SUFFIXES, P as permitsName, R as AgentHttpsNames, S as CA_VALIDITY_DAYS, T as SERVER_AUTH_OID, a as collectAgentNames, b as collectCertIdentity, c as installAgentHttps, d as issueAgentHttpsLeaf, f as loadAgentHttps, h as CA_COMMON_NAME, i as certificateNames, j as isConstrainedCa, k as PERMITTED_IP_RANGES, l as isContainerBridgeAddress, m as pinnedHttpsCaFingerprint, n as acceptAgentSans, o as createAgentHttpsRequest, p as pemDigest, r as agentHttpsPaths, s as describeHttpsLeaf, t as AgentHttpsInstallError, u as isPrivateAddress, w as MAX_LEAF_VALIDITY_DAYS, x as systemHostFacts, y as localCaCommonName, z as getProcessAgentHttpsNames } from "./agent-https-DHBvFZJS.mjs";
34
- import { a as MESH_CA_KEY_REF, i as MESH_CA_FIELD, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY } from "./constants-5lA8Z9d8.mjs";
33
+ import { A as buildNameConstraintSet, B as setProcessAgentHttpsNames, C as LEAF_RENEWAL_WINDOW_DAYS, E as evaluateExistingCert, F as readNameConstraints, I as AGENT_HTTPS_NAMES_COLLECTION, L as AGENT_HTTPS_NAMES_COLUMNS, M as isLocalOnlyHostname, N as permitsIdentity, O as PERMITTED_DNS_SUFFIXES, P as permitsName, R as AgentHttpsNames, S as CA_VALIDITY_DAYS, T as SERVER_AUTH_OID, a as collectAgentNames, b as collectCertIdentity, c as installAgentHttps, d as issueAgentHttpsLeaf, f as loadAgentHttps, h as CA_COMMON_NAME, i as certificateNames, j as isConstrainedCa, k as PERMITTED_IP_RANGES, l as isContainerBridgeAddress, m as pinnedHttpsCaFingerprint, n as acceptAgentSans, o as createAgentHttpsRequest, p as pemDigest, r as agentHttpsPaths, s as describeHttpsLeaf, t as AgentHttpsInstallError, u as isPrivateAddress, w as MAX_LEAF_VALIDITY_DAYS, x as systemHostFacts, y as localCaCommonName, z as getProcessAgentHttpsNames } from "./agent-https-DOwn4pqL.mjs";
34
+ import { a as MESH_CA_KEY_REF, i as MESH_CA_FIELD, n as DEFAULT_HUB_TLS_TCP_PORT, o as MESH_CA_SETTINGS_KEY } from "./constants-p5mPM1iL.mjs";
35
35
  import { $ as generateMeshKeyPair, A as setProcessMeshPeerTransportLookup, B as describeMeshLeaf, C as setProcessMeshTlsEnabler, D as getProcessPeerLeaf, E as getProcessNodeMeshTransport, F as setProcessMeshTlsListenerState, G as MeshCaKeeper, H as setProcessMeshCertificateRegistry, I as MESH_NODE_CERTIFICATES_COLLECTION, J as caFingerprint, K as getProcessMeshCaState, L as MESH_NODE_CERTIFICATES_COLUMNS, M as revokeMeshCertificate, N as getProcessMeshTlsListenerState, O as isProcessVerifiedMeshPeer, P as openMeshTlsWhenRevocationsLoaded, Q as generateMeshCa, R as MeshCertificateRegistry, S as ServiceBroker, SystemConfigAddon, T as emitProcessNodeRegistered, U as MeshCrl, V as getProcessMeshCertificateRegistry, W as processMeshCrl, X as createMeshCsrPem, Y as caFingerprintCompact, Z as exportMeshPrivateKeyPem, _ as signPairingProof, _t as readCidrSetting, a as hubHostFromMeshAddress, at as AGENT_UI_UNLOCK_TTL_MS, b as TlsTcpTransporter, c as PAIRING_MAX_SESSIONS, ct as AGENT_UI_UNLOCK_VERSION, d as PAIRING_PROTOCOL, dt as mintAgentUiUnlockTicket, et as isValidAgentNodeId, f as PAIRING_TTL_MS, ft as parseAgentDashboardOrigins, g as keyFingerprintShort, gt as parseCidrList, h as describeCsr, ht as normalizeIp, i as AgentPairing, it as AGENT_DASHBOARD_ORIGINS_FIELD, j as renewMeshCertificate, k as onProcessNodeRegistered, l as PAIRING_PATHS, lt as UnlockTicketJtiStore, m as computePairingSas, mt as createCidrMatcher, n as HubPairing, nt as issueMeshLeafFromCsr, o as PAIRING_CODE_DIGITS, ot as AGENT_UI_UNLOCK_TYP, p as computePairingCommitment, pt as verifyAgentUiUnlockTicket, q as requireProcessMeshCa, r as PairingHttpError, rt as loadMeshCa, s as PAIRING_MAX_CODE_ATTEMPTS, st as AGENT_UI_UNLOCK_USE, tt as issueMeshLeafForNode, u as PAIRING_PIN_DIGITS, ut as isAllowedAgentDashboardReturnTo, v as verifyPairingProof, w as dropProcessPeer, x as Errors, y as MESH_TLS_PORT_HELLO_FIELD, z as RENEWAL_ABANDONED } from "./builtins/system-config/system-config.addon.mjs";
36
36
  import "./builtins/system-config/index.mjs";
37
37
  import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
38
- import { C as isModelDownloaded, T as revisionWeightUrl, _ as downloadFile, a as startEventLoopStallMonitor, b as fetchJson, c as createAuthenticatedFileServer, d as resolveFilePath, f as ModelDownloadService, g as deleteModelFromDisk, h as collectModelFiles, i as attributeStall, l as parseRangeHeader, m as adoptModelRevisions, n as STALL_REPORT_MS, o as createFileDataPlaneHandler, r as STALL_TICK_MS, s as contentTypeFor, t as CustomActionRegistry, u as parseTokenizedUrl, v as downloadModel, w as resolveFormatRevision, x as getModelFilePath, y as ensureModel } from "./custom-action-registry-BGYDjTqY.mjs";
39
- import { A as allFamiliesListenHost, C as caReplacementMarkerFile, D as replaceUnconstrainedLocalCa, E as reissueTlsLeaf, F as registerLanHttpHandler, M as bindPendingLanHttp, N as closeLanHttp, O as retirePreviousLocalCa, P as readLanHttpState, S as validateUploadedTls, T as loadTlsCert, _ as splitPemCertificates, a as storeUploadedCertificate, b as chainsToPublicRoot, c as leafFingerprintOf, d as servedHttpsLeafFingerprint, f as prepareBootTls, g as readTlsMode, h as readTlsAccessStatus, i as revertToGeneratedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, l as registerHttpsListener, m as readExtraSans, n as applyCertificateToListener, o as useStoredUploadedCertificate, p as UPLOADED_CA_FILE, r as regenerateCertificate, s as clearHttpsListener, t as createCiaoPublisher, u as reloadHttpsListener, v as writeExtraSans, w as ensureTlsCert, x as checkUploadedCa, y as writeTlsMode } from "./hub-mdns-ciao-zD3JojB_.mjs";
38
+ import { C as isModelDownloaded, T as revisionWeightUrl, _ as downloadFile, a as startEventLoopStallMonitor, b as fetchJson, c as createAuthenticatedFileServer, d as resolveFilePath, f as ModelDownloadService, g as deleteModelFromDisk, h as collectModelFiles, i as attributeStall, l as parseRangeHeader, m as adoptModelRevisions, n as STALL_REPORT_MS, o as createFileDataPlaneHandler, r as STALL_TICK_MS, s as contentTypeFor, t as CustomActionRegistry, u as parseTokenizedUrl, v as downloadModel, w as resolveFormatRevision, x as getModelFilePath, y as ensureModel } from "./custom-action-registry-DZSCLBuT.mjs";
39
+ import { A as allFamiliesListenHost, C as caReplacementMarkerFile, D as replaceUnconstrainedLocalCa, E as reissueTlsLeaf, F as registerLanHttpHandler, M as bindPendingLanHttp, N as closeLanHttp, O as retirePreviousLocalCa, P as readLanHttpState, S as validateUploadedTls, T as loadTlsCert, _ as splitPemCertificates, a as storeUploadedCertificate, b as chainsToPublicRoot, c as leafFingerprintOf, d as servedHttpsLeafFingerprint, f as prepareBootTls, g as readTlsMode, h as readTlsAccessStatus, i as revertToGeneratedCertificate, j as applyLanHttp, k as DEFAULT_LAN_HTTP_PORT, l as registerHttpsListener, m as readExtraSans, n as applyCertificateToListener, o as useStoredUploadedCertificate, p as UPLOADED_CA_FILE, r as regenerateCertificate, s as clearHttpsListener, t as createCiaoPublisher, u as reloadHttpsListener, v as writeExtraSans, w as ensureTlsCert, x as checkUploadedCa, y as writeTlsMode } from "./hub-mdns-ciao-BemeCNGe.mjs";
40
40
  import { n as getPlatformKeychainKey, r as setPlatformKeychainKey, t as clearPlatformKeychainKey } from "./platform-key-source-BWlq0jjn.mjs";
41
41
  import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-Di9daRwI.mjs";
42
- import { _ as backupRecordStoresOf, c as BackupDecryptError, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, h as readBackupEncryptionHeader, l as BackupKeyFormatError, r as prepareRestoreArchive, s as SystemBackupService, t as BackupKeyRequiredError, u as BackupKeyMismatchError } from "./restore-archive-CN1pJTRn.mjs";
43
- import { r as nodeCoralFs, t as classifyCoralAccelerator } from "./coral-accelerators-BW3OcrLD.mjs";
42
+ import { _ as backupRecordStoresOf, c as BackupDecryptError, f as generateBackupKeyPair, g as backupOrchestratorRecordKinds, h as readBackupEncryptionHeader, l as BackupKeyFormatError, r as prepareRestoreArchive, s as SystemBackupService, t as BackupKeyRequiredError, u as BackupKeyMismatchError } from "./restore-archive-C0aohmAK.mjs";
43
+ import { r as nodeCoralFs, t as classifyCoralAccelerator } from "./coral-accelerators-DBlgWB8k.mjs";
44
44
  import { z } from "zod";
45
45
  import * as crypto$1 from "node:crypto";
46
46
  import { createHash, randomBytes, randomUUID } from "node:crypto";
@@ -48,14 +48,14 @@ import { PYTHON_VERSION, buildBinaryPath, declaresEdgetpuDelegate, downloadBinar
48
48
  import { connect, createConnection, createServer } from "node:net";
49
49
  import { mkdir, rm, stat, unlink } from "node:fs/promises";
50
50
  import * as path$1 from "node:path";
51
- import { dirname, isAbsolute, join, resolve } from "node:path";
51
+ import { basename, dirname, isAbsolute, join, resolve } from "node:path";
52
52
  import * as util from "node:util";
53
53
  import { promisify } from "node:util";
54
54
  import * as os$1 from "node:os";
55
55
  import { tmpdir } from "node:os";
56
56
  import { pathToFileURL } from "node:url";
57
57
  import { BOOT_RECOVERY_BACKOFF_MS, CALLER_STAMPED_CAPABILITIES, DATAPLANE_SECRET_HEADER, DEVICE_CHILDREN_BATCH_MAX, DeviceType, DisposerChain, ErrorI18nPayloadSchema, EventCategory, PEER_BYTES_CHUNK_BYTES, PEER_BYTES_MAX_OUTSTANDING, PEER_BYTES_STALL_MS, PEER_BYTES_TICKET_TTL_MS, ReadinessRegistry as ReadinessRegistry$1, addonSliceHandleApi, asJsonObject, asString, collectZodSecretPaths, createDeviceProxy, createEvent, createEventBusSliceSource, createRecordsAccess, createSecretsAccess, deviceOpsCapability, emitReadiness, errMsg, expandCapMethods as expandCapMethods$1, maskUrlCredentials, readErrorI18n, readNodePin, scopeKey as scopeKey$1, scrubKnownSecrets, sleep, withCapInputDefaults } from "@camstack/types/addon";
58
- import * as fs from "node:fs";
58
+ import * as fs$1 from "node:fs";
59
59
  import { accessSync, constants, createReadStream, createWriteStream, existsSync, readFileSync, readdirSync } from "node:fs";
60
60
  import { execFile, spawn } from "node:child_process";
61
61
  import { once } from "node:events";
@@ -5029,7 +5029,7 @@ var PythonEnvManager = class {
5029
5029
  async ensure(options) {
5030
5030
  const probe = await this.probe();
5031
5031
  if (!probe.available || !probe.path) throw userError("system.python-required", void 0, "Python 3.10+ is required but not found on this system");
5032
- if (!fs.existsSync(path$1.join(this.venvPath, "bin", "python"))) await execFileAsync$7(probe.path, [
5032
+ if (!fs$1.existsSync(path$1.join(this.venvPath, "bin", "python"))) await execFileAsync$7(probe.path, [
5033
5033
  "-m",
5034
5034
  "venv",
5035
5035
  this.venvPath
@@ -5052,7 +5052,7 @@ var PythonEnvManager = class {
5052
5052
  }
5053
5053
  spawn(script, args) {
5054
5054
  const venvPython = path$1.join(this.venvPath, "bin", "python");
5055
- if (!fs.existsSync(venvPython)) throw new Error("Python venv not initialized. Call ensure() first.");
5055
+ if (!fs$1.existsSync(venvPython)) throw new Error("Python venv not initialized. Call ensure() first.");
5056
5056
  return spawn(venvPython, [script, ...args]);
5057
5057
  }
5058
5058
  };
@@ -5404,20 +5404,20 @@ var StorageManager = class {
5404
5404
  const basePath = this.locationManager.getBackend(mappedName).basePath;
5405
5405
  location.files = {
5406
5406
  async readFile(p) {
5407
- return fs.promises.readFile(path$1.join(basePath, p));
5407
+ return fs$1.promises.readFile(path$1.join(basePath, p));
5408
5408
  },
5409
5409
  async writeFile(p, data) {
5410
5410
  const full = path$1.join(basePath, p);
5411
- await fs.promises.mkdir(path$1.dirname(full), { recursive: true });
5412
- await fs.promises.writeFile(full, data);
5411
+ await fs$1.promises.mkdir(path$1.dirname(full), { recursive: true });
5412
+ await fs$1.promises.writeFile(full, data);
5413
5413
  },
5414
5414
  async deleteFile(p) {
5415
- await fs.promises.rm(path$1.join(basePath, p), { force: true });
5415
+ await fs$1.promises.rm(path$1.join(basePath, p), { force: true });
5416
5416
  },
5417
5417
  async listFiles(prefix) {
5418
5418
  const dir = prefix ? path$1.join(basePath, prefix) : basePath;
5419
5419
  try {
5420
- return (await fs.promises.readdir(dir)).map((f) => prefix ? `${prefix}/${f}` : f);
5420
+ return (await fs$1.promises.readdir(dir)).map((f) => prefix ? `${prefix}/${f}` : f);
5421
5421
  } catch {
5422
5422
  return [];
5423
5423
  }
@@ -5427,7 +5427,7 @@ var StorageManager = class {
5427
5427
  },
5428
5428
  async exists(p) {
5429
5429
  try {
5430
- await fs.promises.access(path$1.join(basePath, p));
5430
+ await fs$1.promises.access(path$1.join(basePath, p));
5431
5431
  return true;
5432
5432
  } catch {
5433
5433
  return false;
@@ -6169,7 +6169,7 @@ var TRADITIONAL_NATIVE_PACKAGES = ["better-sqlite3"];
6169
6169
  function hasDotNode(dir, maxDepth) {
6170
6170
  let entries;
6171
6171
  try {
6172
- entries = fs.readdirSync(dir, { withFileTypes: true });
6172
+ entries = fs$1.readdirSync(dir, { withFileTypes: true });
6173
6173
  } catch {
6174
6174
  return false;
6175
6175
  }
@@ -6180,7 +6180,7 @@ function hasDotNode(dir, maxDepth) {
6180
6180
  }
6181
6181
  /** Locate the bundled `prebuild-install` bin.js inside the staged closure. */
6182
6182
  function resolvePrebuildInstallBin(closureDir, moduleDir) {
6183
- return [path$1.join(moduleDir, "node_modules", "prebuild-install", "bin.js"), path$1.join(closureDir, "node_modules", "prebuild-install", "bin.js")].find((c) => fs.existsSync(c)) ?? null;
6183
+ return [path$1.join(moduleDir, "node_modules", "prebuild-install", "bin.js"), path$1.join(closureDir, "node_modules", "prebuild-install", "bin.js")].find((c) => fs$1.existsSync(c)) ?? null;
6184
6184
  }
6185
6185
  /**
6186
6186
  * Default fetcher: run the closure's own `prebuild-install` under the CURRENT
@@ -6233,7 +6233,7 @@ async function ensureNativePrebuilds(closureDir, options) {
6233
6233
  const fetched = [];
6234
6234
  for (const pkg of packages) {
6235
6235
  const moduleDir = path$1.join(nm, pkg);
6236
- if (!fs.existsSync(moduleDir)) continue;
6236
+ if (!fs$1.existsSync(moduleDir)) continue;
6237
6237
  if (hasDotNode(moduleDir, 4)) continue;
6238
6238
  options.logger.warn("staged closure native prebuild missing — fetching for running ABI", { meta: {
6239
6239
  pkg,
@@ -6296,12 +6296,12 @@ async function ensureNativePrebuilds(closureDir, options) {
6296
6296
  function replantFromBundled(srcModuleDir, dstModuleDir, hasNative) {
6297
6297
  if (!hasNative(srcModuleDir)) return false;
6298
6298
  try {
6299
- fs.rmSync(dstModuleDir, {
6299
+ fs$1.rmSync(dstModuleDir, {
6300
6300
  recursive: true,
6301
6301
  force: true
6302
6302
  });
6303
- fs.mkdirSync(path$1.dirname(dstModuleDir), { recursive: true });
6304
- fs.cpSync(srcModuleDir, dstModuleDir, {
6303
+ fs$1.mkdirSync(path$1.dirname(dstModuleDir), { recursive: true });
6304
+ fs$1.cpSync(srcModuleDir, dstModuleDir, {
6305
6305
  recursive: true,
6306
6306
  dereference: true
6307
6307
  });
@@ -6330,7 +6330,7 @@ async function ensureAddonNativePrebuilds(addonDir, options) {
6330
6330
  const missing = [];
6331
6331
  for (const pkg of packages) {
6332
6332
  const moduleDir = path$1.join(nm, pkg);
6333
- if (!fs.existsSync(moduleDir)) continue;
6333
+ if (!fs$1.existsSync(moduleDir)) continue;
6334
6334
  if (hasNative(moduleDir)) {
6335
6335
  results.push({
6336
6336
  pkg,
@@ -6429,7 +6429,7 @@ async function defaultDownloadTarball(url, destTgz) {
6429
6429
  const res = await fetch(url);
6430
6430
  if (!res.ok || !res.body) throw new Error(`HTTP ${res.status} downloading ${url}`);
6431
6431
  const bytes = Buffer.from(await res.arrayBuffer());
6432
- await fs.promises.writeFile(destTgz, bytes);
6432
+ await fs$1.promises.writeFile(destTgz, bytes);
6433
6433
  }
6434
6434
  async function defaultExtractTarball(tgzPath, destDir) {
6435
6435
  await execFileAsync$5("tar", [
@@ -6515,7 +6515,7 @@ async function resolveUncached(options) {
6515
6515
  argsPrefix: []
6516
6516
  };
6517
6517
  const cliPath = bootstrappedCliPath(options.cacheDir);
6518
- if (fs.existsSync(cliPath)) {
6518
+ if (fs$1.existsSync(cliPath)) {
6519
6519
  options.logger.info("system npm unavailable — using bootstrapped npm", { meta: { cliPath } });
6520
6520
  return {
6521
6521
  command: process.execPath,
@@ -6527,12 +6527,12 @@ async function resolveUncached(options) {
6527
6527
  const registry = (options.registry ?? DEFAULT_REGISTRY).replace(/\/+$/, "");
6528
6528
  const tarballUrl = tarballUrlOf(await (options.fetchJson ?? defaultFetchJson)(`${registry}/npm/latest`));
6529
6529
  if (!tarballUrl) throw new Error(`registry metadata for 'npm' carries no dist.tarball (${registry})`);
6530
- await fs.promises.mkdir(options.cacheDir, { recursive: true });
6530
+ await fs$1.promises.mkdir(options.cacheDir, { recursive: true });
6531
6531
  const tgzPath = path$1.join(options.cacheDir, "npm-bootstrap.tgz");
6532
6532
  await (options.downloadTarball ?? defaultDownloadTarball)(tarballUrl, tgzPath);
6533
6533
  await (options.extractTarball ?? defaultExtractTarball)(tgzPath, options.cacheDir);
6534
- await fs.promises.rm(tgzPath, { force: true });
6535
- if (!fs.existsSync(cliPath)) throw new Error(`extracted npm tarball is missing ${cliPath}`);
6534
+ await fs$1.promises.rm(tgzPath, { force: true });
6535
+ if (!fs$1.existsSync(cliPath)) throw new Error(`extracted npm tarball is missing ${cliPath}`);
6536
6536
  options.logger.info("npm bootstrapped", { meta: { cliPath } });
6537
6537
  return {
6538
6538
  command: process.execPath,
@@ -6598,7 +6598,7 @@ function readOwningPackageVersion(entryPath) {
6598
6598
  let dir = path$1.dirname(entryPath);
6599
6599
  for (let hop = 0; hop < PACKAGE_JSON_LOOKUP_DEPTH; hop++) {
6600
6600
  try {
6601
- const version = asJsonObject$1(parseJsonUnknown(fs.readFileSync(path$1.join(dir, "package.json"), "utf-8")))?.["version"];
6601
+ const version = asJsonObject$1(parseJsonUnknown(fs$1.readFileSync(path$1.join(dir, "package.json"), "utf-8")))?.["version"];
6602
6602
  if (typeof version === "string" && version.length > 0) return version;
6603
6603
  } catch {}
6604
6604
  const parent = path$1.dirname(dir);
@@ -6642,14 +6642,14 @@ function readOwningPackageVersion(entryPath) {
6642
6642
  function addonModuleCacheKey(entryPath) {
6643
6643
  let stat;
6644
6644
  try {
6645
- stat = fs.statSync(entryPath);
6645
+ stat = fs$1.statSync(entryPath);
6646
6646
  } catch {
6647
6647
  return null;
6648
6648
  }
6649
6649
  const version = readOwningPackageVersion(entryPath) ?? `m${stat.mtimeMs}`;
6650
6650
  let content;
6651
6651
  try {
6652
- content = createHash("sha1").update(fs.readFileSync(entryPath)).digest("hex").slice(0, 16);
6652
+ content = createHash("sha1").update(fs$1.readFileSync(entryPath)).digest("hex").slice(0, 16);
6653
6653
  } catch {
6654
6654
  content = `m${stat.mtimeMs}s${stat.size}`;
6655
6655
  }
@@ -6753,14 +6753,14 @@ var AddonLoader = class {
6753
6753
  * BUILTINS from the active closure, not the (now-inert) addons-dir copy, so
6754
6754
  * the addons-dir `@camstack/system` must NOT be double-loaded here. */
6755
6755
  async loadFromDirectory(addonsDir, skipPackages = []) {
6756
- if (!fs.existsSync(addonsDir)) return;
6756
+ if (!fs$1.existsSync(addonsDir)) return;
6757
6757
  const skip = new Set(skipPackages);
6758
- const entries = fs.readdirSync(addonsDir, { withFileTypes: true });
6758
+ const entries = fs$1.readdirSync(addonsDir, { withFileTypes: true });
6759
6759
  for (const entry of entries) {
6760
6760
  if (!isDirectoryEntry(entry, addonsDir)) continue;
6761
6761
  if (entry.name.startsWith("@")) {
6762
6762
  const scopeDir = path$1.join(addonsDir, entry.name);
6763
- const scopeEntries = fs.readdirSync(scopeDir, { withFileTypes: true });
6763
+ const scopeEntries = fs$1.readdirSync(scopeDir, { withFileTypes: true });
6764
6764
  for (const scopeEntry of scopeEntries) {
6765
6765
  if (!isDirectoryEntry(scopeEntry, scopeDir)) continue;
6766
6766
  if (skip.has(`${entry.name}/${scopeEntry.name}`)) continue;
@@ -6774,7 +6774,7 @@ var AddonLoader = class {
6774
6774
  }
6775
6775
  async tryLoadAddon(addonDir) {
6776
6776
  const pkgJsonPath = path$1.join(addonDir, "package.json");
6777
- if (!fs.existsSync(pkgJsonPath)) return;
6777
+ if (!fs$1.existsSync(pkgJsonPath)) return;
6778
6778
  try {
6779
6779
  await this.loadFromAddonDir(addonDir);
6780
6780
  } catch (err) {
@@ -6792,7 +6792,7 @@ var AddonLoader = class {
6792
6792
  /** Load addon from a specific directory (package.json + dist/) */
6793
6793
  async loadFromAddonDir(addonDir) {
6794
6794
  const pkgJsonPath = path$1.join(addonDir, "package.json");
6795
- const pkgJson = asJsonObject$1(parseJsonUnknown(fs.readFileSync(pkgJsonPath, "utf-8"))) ?? {};
6795
+ const pkgJson = asJsonObject$1(parseJsonUnknown(fs$1.readFileSync(pkgJsonPath, "utf-8"))) ?? {};
6796
6796
  const packageNameRaw = pkgJson["name"];
6797
6797
  const packageName = typeof packageNameRaw === "string" ? packageNameRaw : "";
6798
6798
  const packageVersionRaw = pkgJson["version"];
@@ -6839,7 +6839,7 @@ var AddonLoader = class {
6839
6839
  }
6840
6840
  const entryFile = declaration.entry.replace(/^\.\//, "").replace(/^src\//, "dist/").replace(/\.ts$/, ".js");
6841
6841
  let entryPath = path$1.resolve(addonDir, entryFile);
6842
- if (!fs.existsSync(entryPath)) {
6842
+ if (!fs$1.existsSync(entryPath)) {
6843
6843
  const base = entryPath.replace(/\.(js|cjs|mjs)$/, "");
6844
6844
  entryPath = [
6845
6845
  `${base}.cjs`,
@@ -6848,9 +6848,9 @@ var AddonLoader = class {
6848
6848
  path$1.resolve(addonDir, "dist", "index.cjs"),
6849
6849
  path$1.resolve(addonDir, "dist", "index.mjs"),
6850
6850
  path$1.resolve(addonDir, declaration.entry)
6851
- ].find((p) => fs.existsSync(p)) ?? entryPath;
6851
+ ].find((p) => fs$1.existsSync(p)) ?? entryPath;
6852
6852
  }
6853
- if (!fs.existsSync(entryPath)) throw new Error(`Entry not found: ${entryPath}`);
6853
+ if (!fs$1.existsSync(entryPath)) throw new Error(`Entry not found: ${entryPath}`);
6854
6854
  const modUnknown = await importAddonModuleFresh(entryPath);
6855
6855
  const mod = isRecord$4(modUnknown) ? modUnknown : {};
6856
6856
  const AddonClass = resolveAddonClass(mod);
@@ -6935,7 +6935,7 @@ function isDirectoryEntry(entry, parentDir) {
6935
6935
  if (entry.name.startsWith(".")) return false;
6936
6936
  if (entry.isDirectory()) return true;
6937
6937
  if (entry.isSymbolicLink()) try {
6938
- return fs.statSync(path$1.join(parentDir, entry.name)).isDirectory();
6938
+ return fs$1.statSync(path$1.join(parentDir, entry.name)).isDirectory();
6939
6939
  } catch {
6940
6940
  return false;
6941
6941
  }
@@ -7029,7 +7029,7 @@ var execFileAsync$4 = promisify(execFile);
7029
7029
  * Single source of truth — replaces scattered mkdirSync calls.
7030
7030
  */
7031
7031
  function ensureDir(dirPath) {
7032
- fs.mkdirSync(dirPath, { recursive: true });
7032
+ fs$1.mkdirSync(dirPath, { recursive: true });
7033
7033
  }
7034
7034
  /**
7035
7035
  * Copy a directory recursively — ASYNC so it never blocks the event loop.
@@ -7042,7 +7042,7 @@ function ensureDir(dirPath) {
7042
7042
  * `fs.promises.cp` keeps the I/O off the event loop. (Node ≥18 stable.)
7043
7043
  */
7044
7044
  async function copyDirRecursive(src, dest) {
7045
- await fs.promises.cp(src, dest, {
7045
+ await fs$1.promises.cp(src, dest, {
7046
7046
  recursive: true,
7047
7047
  force: true
7048
7048
  });
@@ -7147,13 +7147,13 @@ async function copyExtraFileDirs(pkgJson, sourceDir, destDir) {
7147
7147
  if (typeof fileEntry !== "string") continue;
7148
7148
  if (fileEntry === "dist" || fileEntry.includes("*")) continue;
7149
7149
  const srcPath = path$1.join(sourceDir, fileEntry);
7150
- if (!fs.existsSync(srcPath)) continue;
7150
+ if (!fs$1.existsSync(srcPath)) continue;
7151
7151
  const destPath = path$1.join(destDir, fileEntry);
7152
- const stat = await fs.promises.stat(srcPath);
7152
+ const stat = await fs$1.promises.stat(srcPath);
7153
7153
  if (stat.isDirectory()) await copyDirRecursive(srcPath, destPath);
7154
7154
  else if (stat.isFile()) {
7155
7155
  ensureDir(path$1.dirname(destPath));
7156
- await fs.promises.copyFile(srcPath, destPath);
7156
+ await fs$1.promises.copyFile(srcPath, destPath);
7157
7157
  }
7158
7158
  }
7159
7159
  }
@@ -7164,10 +7164,10 @@ async function copyExtraFileDirs(pkgJson, sourceDir, destDir) {
7164
7164
  function isSourceNewer(packageDir) {
7165
7165
  const srcDir = path$1.join(packageDir, "src");
7166
7166
  const distDir = path$1.join(packageDir, "dist");
7167
- if (!fs.existsSync(srcDir) || !fs.existsSync(distDir)) return true;
7167
+ if (!fs$1.existsSync(srcDir) || !fs$1.existsSync(distDir)) return true;
7168
7168
  try {
7169
- const distMtime = fs.statSync(distDir).mtimeMs;
7170
- const entries = fs.readdirSync(srcDir, {
7169
+ const distMtime = fs$1.statSync(distDir).mtimeMs;
7170
+ const entries = fs$1.readdirSync(srcDir, {
7171
7171
  withFileTypes: true,
7172
7172
  recursive: true
7173
7173
  });
@@ -7175,7 +7175,7 @@ function isSourceNewer(packageDir) {
7175
7175
  if (!entry.isFile()) continue;
7176
7176
  const parentDir = entry.parentPath ?? String(Reflect.get(entry, "path") ?? "");
7177
7177
  const filePath = path$1.join(parentDir, entry.name);
7178
- if (fs.statSync(filePath).mtimeMs > distMtime) return true;
7178
+ if (fs$1.statSync(filePath).mtimeMs > distMtime) return true;
7179
7179
  }
7180
7180
  return false;
7181
7181
  } catch {
@@ -7190,9 +7190,9 @@ function isSourceNewer(packageDir) {
7190
7190
  function ensureLibraryBuilt(packageName, packagesDir) {
7191
7191
  const dirName = packageName.replace("@camstack/", "");
7192
7192
  const sourceDir = path$1.join(packagesDir, dirName);
7193
- if (!fs.existsSync(sourceDir)) return;
7193
+ if (!fs$1.existsSync(sourceDir)) return;
7194
7194
  const distDir = path$1.join(sourceDir, "dist");
7195
- if (fs.existsSync(path$1.join(distDir, "index.js")) || fs.existsSync(path$1.join(distDir, "index.mjs"))) return;
7195
+ if (fs$1.existsSync(path$1.join(distDir, "index.js")) || fs$1.existsSync(path$1.join(distDir, "index.mjs"))) return;
7196
7196
  console.warn(`[ensureLibraryBuilt] ${packageName} has no dist/ — run 'npm run build' first`);
7197
7197
  }
7198
7198
  /**
@@ -7205,7 +7205,7 @@ function ensureLibraryBuilt(packageName, packagesDir) {
7205
7205
  * `copyDirRecursive` for the wedge this prevents.
7206
7206
  */
7207
7207
  async function installPackageFromNpm(packageName, targetDir) {
7208
- const tmpDir = await fs.promises.mkdtemp(path$1.join(os$1.tmpdir(), "camstack-install-"));
7208
+ const tmpDir = await fs$1.promises.mkdtemp(path$1.join(os$1.tmpdir(), "camstack-install-"));
7209
7209
  try {
7210
7210
  const { stdout } = await execFileAsync$4("npm", [
7211
7211
  "pack",
@@ -7228,21 +7228,21 @@ async function installPackageFromNpm(packageName, targetDir) {
7228
7228
  extractDir
7229
7229
  ], { timeout: 3e4 });
7230
7230
  const packageSubDir = path$1.join(extractDir, "package");
7231
- const srcPkgJsonDir = fs.existsSync(path$1.join(packageSubDir, "package.json")) ? packageSubDir : extractDir;
7232
- await fs.promises.rm(targetDir, {
7231
+ const srcPkgJsonDir = fs$1.existsSync(path$1.join(packageSubDir, "package.json")) ? packageSubDir : extractDir;
7232
+ await fs$1.promises.rm(targetDir, {
7233
7233
  recursive: true,
7234
7234
  force: true
7235
7235
  });
7236
7236
  ensureDir(targetDir);
7237
- await fs.promises.copyFile(path$1.join(srcPkgJsonDir, "package.json"), path$1.join(targetDir, "package.json"));
7237
+ await fs$1.promises.copyFile(path$1.join(srcPkgJsonDir, "package.json"), path$1.join(targetDir, "package.json"));
7238
7238
  const distSrc = path$1.join(srcPkgJsonDir, "dist");
7239
- if (fs.existsSync(distSrc)) await copyDirRecursive(distSrc, path$1.join(targetDir, "dist"));
7239
+ if (fs$1.existsSync(distSrc)) await copyDirRecursive(distSrc, path$1.join(targetDir, "dist"));
7240
7240
  try {
7241
- const npmPkg = asJsonObject$1(parseJsonUnknown(await fs.promises.readFile(path$1.join(srcPkgJsonDir, "package.json"), "utf-8")));
7241
+ const npmPkg = asJsonObject$1(parseJsonUnknown(await fs$1.promises.readFile(path$1.join(srcPkgJsonDir, "package.json"), "utf-8")));
7242
7242
  if (npmPkg) await copyExtraFileDirs(npmPkg, srcPkgJsonDir, targetDir);
7243
7243
  } catch {}
7244
7244
  } finally {
7245
- await fs.promises.rm(tmpDir, {
7245
+ await fs$1.promises.rm(tmpDir, {
7246
7246
  recursive: true,
7247
7247
  force: true
7248
7248
  });
@@ -7267,7 +7267,7 @@ function packageDirName$1(declaredName) {
7267
7267
  }
7268
7268
  function isDirLike$1(p) {
7269
7269
  try {
7270
- return fs.statSync(p).isDirectory();
7270
+ return fs$1.statSync(p).isDirectory();
7271
7271
  } catch {
7272
7272
  return false;
7273
7273
  }
@@ -7285,12 +7285,12 @@ var AddonManifest = class {
7285
7285
  */
7286
7286
  read() {
7287
7287
  if (this.cache != null) return this.cache;
7288
- if (!fs.existsSync(this.manifestPath)) {
7288
+ if (!fs$1.existsSync(this.manifestPath)) {
7289
7289
  this.cache = this.empty();
7290
7290
  return this.cache;
7291
7291
  }
7292
7292
  try {
7293
- const raw = fs.readFileSync(this.manifestPath, "utf-8");
7293
+ const raw = fs$1.readFileSync(this.manifestPath, "utf-8");
7294
7294
  const parsed = JSON.parse(raw);
7295
7295
  if (parsed.version !== MANIFEST_VERSION) {
7296
7296
  process.stderr.write(`[AddonManifest] schema mismatch (file=${parsed.version} vs runtime=${MANIFEST_VERSION}); starting empty\n`);
@@ -7311,13 +7311,13 @@ var AddonManifest = class {
7311
7311
  * a half-written file.
7312
7312
  */
7313
7313
  write(manifest) {
7314
- fs.mkdirSync(path$1.dirname(this.manifestPath), { recursive: true });
7314
+ fs$1.mkdirSync(path$1.dirname(this.manifestPath), { recursive: true });
7315
7315
  const tmp = `${this.manifestPath}.tmp.${process.pid}.${Date.now()}`;
7316
- fs.writeFileSync(tmp, JSON.stringify(manifest, null, 2), {
7316
+ fs$1.writeFileSync(tmp, JSON.stringify(manifest, null, 2), {
7317
7317
  encoding: "utf-8",
7318
7318
  mode: 384
7319
7319
  });
7320
- fs.renameSync(tmp, this.manifestPath);
7320
+ fs$1.renameSync(tmp, this.manifestPath);
7321
7321
  this.cache = manifest;
7322
7322
  }
7323
7323
  /** Lookup a single addon's manifest entry, or `null` if not tracked. */
@@ -7392,22 +7392,22 @@ var AddonManifest = class {
7392
7392
  * exactly what moved. Returns the total number of changes.
7393
7393
  */
7394
7394
  reconcileFromDisk(addonsDir, onChange) {
7395
- if (!fs.existsSync(addonsDir)) return 0;
7395
+ if (!fs$1.existsSync(addonsDir)) return 0;
7396
7396
  const m = this.read();
7397
7397
  let changes = 0;
7398
7398
  const now = (/* @__PURE__ */ new Date()).toISOString();
7399
7399
  /** Package name → version, for every ADDON package actually installed. */
7400
7400
  const onDisk = /* @__PURE__ */ new Map();
7401
- for (const scope of fs.readdirSync(addonsDir, { withFileTypes: true })) {
7401
+ for (const scope of fs$1.readdirSync(addonsDir, { withFileTypes: true })) {
7402
7402
  if (!scope.name.startsWith("@") || !isDirLike$1(path$1.join(addonsDir, scope.name))) continue;
7403
7403
  const scopeDir = path$1.join(addonsDir, scope.name);
7404
- for (const pkg of fs.readdirSync(scopeDir, { withFileTypes: true })) {
7404
+ for (const pkg of fs$1.readdirSync(scopeDir, { withFileTypes: true })) {
7405
7405
  if (!isDirLike$1(path$1.join(scopeDir, pkg.name))) continue;
7406
7406
  const pkgJsonPath = path$1.join(scopeDir, pkg.name, "package.json");
7407
- if (!fs.existsSync(pkgJsonPath)) continue;
7407
+ if (!fs$1.existsSync(pkgJsonPath)) continue;
7408
7408
  let pkgJson;
7409
7409
  try {
7410
- const parsed = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
7410
+ const parsed = JSON.parse(fs$1.readFileSync(pkgJsonPath, "utf-8"));
7411
7411
  if (typeof parsed !== "object" || parsed == null) continue;
7412
7412
  pkgJson = parsed;
7413
7413
  } catch {
@@ -7478,28 +7478,28 @@ var AddonManifest = class {
7478
7478
  migrateFromInstallSourceMarkers(addonsDir) {
7479
7479
  const m = this.read();
7480
7480
  if (Object.keys(m.addons).length > 0) return 0;
7481
- if (!fs.existsSync(addonsDir)) return 0;
7481
+ if (!fs$1.existsSync(addonsDir)) return 0;
7482
7482
  let migrated = 0;
7483
7483
  const now = (/* @__PURE__ */ new Date()).toISOString();
7484
- for (const scope of fs.readdirSync(addonsDir, { withFileTypes: true })) {
7484
+ for (const scope of fs$1.readdirSync(addonsDir, { withFileTypes: true })) {
7485
7485
  if (!scope.isDirectory() || !scope.name.startsWith("@")) continue;
7486
7486
  const scopeDir = path$1.join(addonsDir, scope.name);
7487
- for (const pkg of fs.readdirSync(scopeDir, { withFileTypes: true })) {
7487
+ for (const pkg of fs$1.readdirSync(scopeDir, { withFileTypes: true })) {
7488
7488
  if (!pkg.isDirectory()) continue;
7489
7489
  const pkgDir = path$1.join(scopeDir, pkg.name);
7490
7490
  const markerPath = path$1.join(pkgDir, ".install-source");
7491
7491
  const pkgJsonPath = path$1.join(pkgDir, "package.json");
7492
- if (!fs.existsSync(pkgJsonPath)) continue;
7492
+ if (!fs$1.existsSync(pkgJsonPath)) continue;
7493
7493
  let pkgJson;
7494
7494
  try {
7495
- const parsed = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
7495
+ const parsed = JSON.parse(fs$1.readFileSync(pkgJsonPath, "utf-8"));
7496
7496
  if (typeof parsed !== "object" || parsed == null) continue;
7497
7497
  pkgJson = parsed;
7498
7498
  } catch {
7499
7499
  continue;
7500
7500
  }
7501
7501
  if (!pkgJson.name || !pkgJson.version) continue;
7502
- const source = fs.existsSync(markerPath) ? fs.readFileSync(markerPath, "utf-8").trim() : "bundled";
7502
+ const source = fs$1.existsSync(markerPath) ? fs$1.readFileSync(markerPath, "utf-8").trim() : "bundled";
7503
7503
  m.addons[pkgJson.name] = {
7504
7504
  name: pkgJson.name,
7505
7505
  version: pkgJson.version,
@@ -7676,7 +7676,7 @@ function planClosureDedupe(input) {
7676
7676
  function readTreeManifest(pkgJsonPath) {
7677
7677
  let raw;
7678
7678
  try {
7679
- raw = asJsonObject$1(parseJsonUnknown(fs.readFileSync(pkgJsonPath, "utf-8")));
7679
+ raw = asJsonObject$1(parseJsonUnknown(fs$1.readFileSync(pkgJsonPath, "utf-8")));
7680
7680
  } catch {
7681
7681
  return null;
7682
7682
  }
@@ -7701,7 +7701,7 @@ function readTreeManifest(pkgJsonPath) {
7701
7701
  function listTopLevelEntries(nodeModulesDir) {
7702
7702
  let entries;
7703
7703
  try {
7704
- entries = fs.readdirSync(nodeModulesDir, { withFileTypes: true });
7704
+ entries = fs$1.readdirSync(nodeModulesDir, { withFileTypes: true });
7705
7705
  } catch {
7706
7706
  return [];
7707
7707
  }
@@ -7711,7 +7711,7 @@ function listTopLevelEntries(nodeModulesDir) {
7711
7711
  if (entry.name.startsWith("@")) {
7712
7712
  let inner;
7713
7713
  try {
7714
- inner = fs.readdirSync(path$1.join(nodeModulesDir, entry.name), { withFileTypes: true });
7714
+ inner = fs$1.readdirSync(path$1.join(nodeModulesDir, entry.name), { withFileTypes: true });
7715
7715
  } catch {
7716
7716
  continue;
7717
7717
  }
@@ -7744,14 +7744,14 @@ function collectAddonTreeState(addonDir) {
7744
7744
  const entryDir = path$1.join(nodeModulesDir, name);
7745
7745
  let isLink = false;
7746
7746
  try {
7747
- isLink = fs.lstatSync(entryDir).isSymbolicLink();
7747
+ isLink = fs$1.lstatSync(entryDir).isSymbolicLink();
7748
7748
  } catch {
7749
7749
  continue;
7750
7750
  }
7751
7751
  if (isLink) {
7752
7752
  let target = "";
7753
7753
  try {
7754
- target = fs.readlinkSync(entryDir);
7754
+ target = fs$1.readlinkSync(entryDir);
7755
7755
  } catch {}
7756
7756
  existingLinks.push({
7757
7757
  name,
@@ -7765,7 +7765,7 @@ function collectAddonTreeState(addonDir) {
7765
7765
  version: manifest.version
7766
7766
  });
7767
7767
  for (const [depName, range] of manifest.ranges) {
7768
- if (fs.existsSync(path$1.join(entryDir, "node_modules", depName))) continue;
7768
+ if (fs$1.existsSync(path$1.join(entryDir, "node_modules", depName))) continue;
7769
7769
  addRange(depName, range);
7770
7770
  }
7771
7771
  }
@@ -7795,7 +7795,7 @@ function resolveClosureNodeModulesDir(explicitDir) {
7795
7795
  const frameworkDir = explicitDir ?? process.env["CAMSTACK_FRAMEWORK_DIR"];
7796
7796
  if (frameworkDir === void 0 || frameworkDir.length === 0) return null;
7797
7797
  const nodeModulesDir = explicitDir ?? path$1.join(frameworkDir, "node_modules");
7798
- return fs.existsSync(nodeModulesDir) ? nodeModulesDir : null;
7798
+ return fs$1.existsSync(nodeModulesDir) ? nodeModulesDir : null;
7799
7799
  }
7800
7800
  function symlinkType() {
7801
7801
  return process.platform === "win32" ? "junction" : "dir";
@@ -7814,10 +7814,10 @@ function executeClosureDedupe(addonDir, closureNodeModulesDir, plan, logger) {
7814
7814
  const nodeModulesDir = path$1.join(addonDir, "node_modules");
7815
7815
  const probePath = path$1.join(nodeModulesDir, ".closure-link-probe");
7816
7816
  try {
7817
- fs.mkdirSync(nodeModulesDir, { recursive: true });
7818
- fs.rmSync(probePath, { force: true });
7819
- fs.symlinkSync(closureNodeModulesDir, probePath, symlinkType());
7820
- fs.rmSync(probePath, { force: true });
7817
+ fs$1.mkdirSync(nodeModulesDir, { recursive: true });
7818
+ fs$1.rmSync(probePath, { force: true });
7819
+ fs$1.symlinkSync(closureNodeModulesDir, probePath, symlinkType());
7820
+ fs$1.rmSync(probePath, { force: true });
7821
7821
  } catch (err) {
7822
7822
  logger.warn("closure dedupe skipped — symlinks unavailable on this volume", { meta: {
7823
7823
  addonDir,
@@ -7839,12 +7839,12 @@ function executeClosureDedupe(addonDir, closureNodeModulesDir, plan, logger) {
7839
7839
  }
7840
7840
  const entryDir = path$1.join(nodeModulesDir, link.name);
7841
7841
  try {
7842
- fs.rmSync(entryDir, {
7842
+ fs$1.rmSync(entryDir, {
7843
7843
  recursive: true,
7844
7844
  force: true
7845
7845
  });
7846
- fs.mkdirSync(path$1.dirname(entryDir), { recursive: true });
7847
- fs.symlinkSync(target, entryDir, symlinkType());
7846
+ fs$1.mkdirSync(path$1.dirname(entryDir), { recursive: true });
7847
+ fs$1.symlinkSync(target, entryDir, symlinkType());
7848
7848
  linked.push(link.name);
7849
7849
  } catch (err) {
7850
7850
  logger.warn("closure dedupe — link failed; entry removed copy may need reinstall", { meta: {
@@ -7920,7 +7920,7 @@ async function installManifestNativeDeps(addonDir, pkgRaw, logger, registry, npm
7920
7920
  count: Object.keys(native).length
7921
7921
  } });
7922
7922
  try {
7923
- fs.writeFileSync(markerFile, markerHash);
7923
+ fs$1.writeFileSync(markerFile, markerHash);
7924
7924
  } catch (err) {
7925
7925
  logger.warn("Failed to write native deps marker", { meta: {
7926
7926
  markerFile,
@@ -7958,7 +7958,7 @@ async function installManifestNativeDeps(addonDir, pkgRaw, logger, registry, npm
7958
7958
  }
7959
7959
  await rebuildNativeDeps(addonDir, pending.map(([name]) => name), logger, npmCacheDir ?? defaultNpmCacheDir(), registry);
7960
7960
  try {
7961
- fs.writeFileSync(markerFile, markerHash);
7961
+ fs$1.writeFileSync(markerFile, markerHash);
7962
7962
  } catch (err) {
7963
7963
  logger.warn("Failed to write native deps marker", { meta: {
7964
7964
  markerFile,
@@ -7980,12 +7980,12 @@ function copyPrebuiltNativeDep(name, addonDir, logger) {
7980
7980
  if (source === target) continue;
7981
7981
  if (!hasBuiltBinary(source)) continue;
7982
7982
  try {
7983
- fs.rmSync(target, {
7983
+ fs$1.rmSync(target, {
7984
7984
  recursive: true,
7985
7985
  force: true
7986
7986
  });
7987
- fs.mkdirSync(path$1.dirname(target), { recursive: true });
7988
- fs.cpSync(source, target, {
7987
+ fs$1.mkdirSync(path$1.dirname(target), { recursive: true });
7988
+ fs$1.cpSync(source, target, {
7989
7989
  recursive: true,
7990
7990
  dereference: true
7991
7991
  });
@@ -8021,7 +8021,7 @@ var BUNDLED_NATIVE_SIBLING_SCOPES = {
8021
8021
  function hasAnyDotNode(dir, maxDepth) {
8022
8022
  let entries;
8023
8023
  try {
8024
- entries = fs.readdirSync(dir, { withFileTypes: true });
8024
+ entries = fs$1.readdirSync(dir, { withFileTypes: true });
8025
8025
  } catch {
8026
8026
  return false;
8027
8027
  }
@@ -8035,12 +8035,12 @@ function copyPrebuiltModuleDir(src, dst, label, logger) {
8035
8035
  if (!hasAnyDotNode(src, 5)) return;
8036
8036
  if (hasAnyDotNode(dst, 5)) return;
8037
8037
  try {
8038
- fs.rmSync(dst, {
8038
+ fs$1.rmSync(dst, {
8039
8039
  recursive: true,
8040
8040
  force: true
8041
8041
  });
8042
- fs.mkdirSync(path$1.dirname(dst), { recursive: true });
8043
- fs.cpSync(src, dst, {
8042
+ fs$1.mkdirSync(path$1.dirname(dst), { recursive: true });
8043
+ fs$1.cpSync(src, dst, {
8044
8044
  recursive: true,
8045
8045
  dereference: true
8046
8046
  });
@@ -8075,7 +8075,7 @@ function copyPrebuiltModuleDir(src, dst, label, logger) {
8075
8075
  */
8076
8076
  function copyBundledNativeModules(sourceDir, targetDir, logger) {
8077
8077
  const srcNm = path$1.join(sourceDir, "node_modules");
8078
- if (!fs.existsSync(srcNm)) return;
8078
+ if (!fs$1.existsSync(srcNm)) return;
8079
8079
  const dstNm = path$1.join(targetDir, "node_modules");
8080
8080
  for (const [name, scopes] of Object.entries(BUNDLED_NATIVE_SIBLING_SCOPES)) {
8081
8081
  copyPrebuiltModuleDir(path$1.join(srcNm, name), path$1.join(dstNm, name), name, logger);
@@ -8083,7 +8083,7 @@ function copyBundledNativeModules(sourceDir, targetDir, logger) {
8083
8083
  const scopeSrc = path$1.join(srcNm, scope);
8084
8084
  let siblings;
8085
8085
  try {
8086
- siblings = fs.readdirSync(scopeSrc);
8086
+ siblings = fs$1.readdirSync(scopeSrc);
8087
8087
  } catch {
8088
8088
  continue;
8089
8089
  }
@@ -8093,12 +8093,12 @@ function copyBundledNativeModules(sourceDir, targetDir, logger) {
8093
8093
  }
8094
8094
  /** A package dir is "built" when it carries a compiled `.node` or a prebuilds tree. */
8095
8095
  function hasBuiltBinary(pkgDir) {
8096
- if (!fs.existsSync(path$1.join(pkgDir, "package.json"))) return false;
8096
+ if (!fs$1.existsSync(path$1.join(pkgDir, "package.json"))) return false;
8097
8097
  const releaseDir = path$1.join(pkgDir, "build", "Release");
8098
8098
  try {
8099
- if (fs.existsSync(releaseDir) && fs.readdirSync(releaseDir).some((f) => f.endsWith(".node"))) return true;
8099
+ if (fs$1.existsSync(releaseDir) && fs$1.readdirSync(releaseDir).some((f) => f.endsWith(".node"))) return true;
8100
8100
  } catch {}
8101
- return fs.existsSync(path$1.join(pkgDir, "prebuilds"));
8101
+ return fs$1.existsSync(path$1.join(pkgDir, "prebuilds"));
8102
8102
  }
8103
8103
  /** Candidate hoisted locations for `<name>`: NODE_PATH entries + ancestors of `addonDir`. */
8104
8104
  function candidateHoistedDirs(name, addonDir) {
@@ -8136,7 +8136,7 @@ function hashDeclaration(deps) {
8136
8136
  }
8137
8137
  function markerMatches(markerFile, expected) {
8138
8138
  try {
8139
- return fs.readFileSync(markerFile, "utf-8").trim() === expected;
8139
+ return fs$1.readFileSync(markerFile, "utf-8").trim() === expected;
8140
8140
  } catch {
8141
8141
  return false;
8142
8142
  }
@@ -8243,7 +8243,7 @@ function parseInstallSource(value) {
8243
8243
  function readPackageJson(pkgJsonPath) {
8244
8244
  let raw;
8245
8245
  try {
8246
- raw = asJsonObject$1(parseJsonUnknown(fs.readFileSync(pkgJsonPath, "utf-8")));
8246
+ raw = asJsonObject$1(parseJsonUnknown(fs$1.readFileSync(pkgJsonPath, "utf-8")));
8247
8247
  } catch {
8248
8248
  return null;
8249
8249
  }
@@ -8406,7 +8406,7 @@ var AddonInstaller = class AddonInstaller {
8406
8406
  } catch {
8407
8407
  return Object.freeze([]);
8408
8408
  }
8409
- const raw = fs.readFileSync(pkgPath, "utf-8");
8409
+ const raw = fs$1.readFileSync(pkgPath, "utf-8");
8410
8410
  const parsed = JSON.parse(raw);
8411
8411
  const deps = Object.keys(parsed.dependencies ?? {});
8412
8412
  const agentOnly = new Set(parsed.camstack?.agentOnlyBootstrapAddons ?? []);
@@ -8451,7 +8451,7 @@ var AddonInstaller = class AddonInstaller {
8451
8451
  } catch {
8452
8452
  return Object.freeze([]);
8453
8453
  }
8454
- const raw = fs.readFileSync(pkgPath, "utf-8");
8454
+ const raw = fs$1.readFileSync(pkgPath, "utf-8");
8455
8455
  const addons = JSON.parse(raw).camstack?.agentBootstrapAddons ?? [];
8456
8456
  return Object.freeze(["@camstack/system", ...addons]);
8457
8457
  }
@@ -8482,7 +8482,7 @@ var AddonInstaller = class AddonInstaller {
8482
8482
  }
8483
8483
  for (const packageName of pkgList) {
8484
8484
  const addonDir = path$1.join(this.addonsDir, packageName);
8485
- if (fs.existsSync(path$1.join(addonDir, "package.json"))) {
8485
+ if (fs$1.existsSync(path$1.join(addonDir, "package.json"))) {
8486
8486
  this.logger.debug(`${packageName} — already installed, skipping`);
8487
8487
  continue;
8488
8488
  }
@@ -8567,7 +8567,7 @@ var AddonInstaller = class AddonInstaller {
8567
8567
  const installedPackages = this.listInstalled();
8568
8568
  for (const pkg of installedPackages) {
8569
8569
  try {
8570
- if (fs.lstatSync(pkg.dir).isSymbolicLink()) continue;
8570
+ if (fs$1.lstatSync(pkg.dir).isSymbolicLink()) continue;
8571
8571
  } catch {
8572
8572
  continue;
8573
8573
  }
@@ -8607,7 +8607,7 @@ var AddonInstaller = class AddonInstaller {
8607
8607
  if (closureNodeModules !== null) for (const link of state.existingLinks) {
8608
8608
  if (!isClosureLinkTarget(link.target, closureNodeModules)) continue;
8609
8609
  const linkDir = path$1.join(nodeModulesDir, link.name);
8610
- const targetManifest = fs.existsSync(path$1.join(linkDir, "package.json"));
8610
+ const targetManifest = fs$1.existsSync(path$1.join(linkDir, "package.json"));
8611
8611
  const ranges = state.requirements.get(link.name) ?? [];
8612
8612
  let holds = targetManifest;
8613
8613
  if (holds && ranges.length > 0) {
@@ -8616,14 +8616,14 @@ var AddonInstaller = class AddonInstaller {
8616
8616
  }
8617
8617
  if (!holds) {
8618
8618
  this.logger.warn(`${packageName} — closure link for ${link.name} no longer holds; reinstalling this addon's deps`, { meta: { target: link.target } });
8619
- fs.rmSync(linkDir, { force: true });
8619
+ fs$1.rmSync(linkDir, { force: true });
8620
8620
  needsInstall = true;
8621
8621
  }
8622
8622
  }
8623
8623
  const linked = [];
8624
8624
  for (const [depName, range] of declaredEntries) {
8625
8625
  if (typeof range !== "string") continue;
8626
- if (fs.existsSync(path$1.join(nodeModulesDir, depName, "package.json"))) continue;
8626
+ if (fs$1.existsSync(path$1.join(nodeModulesDir, depName, "package.json"))) continue;
8627
8627
  const closureVersion = closureNodeModules === null ? void 0 : readClosureVersions(closureNodeModules, [depName]).get(depName);
8628
8628
  if (closureNodeModules !== null && closureVersion !== void 0 && closureSatisfiesRange(range, closureVersion)) {
8629
8629
  if (executeClosureDedupe(addonDir, closureNodeModules, {
@@ -8656,7 +8656,7 @@ var AddonInstaller = class AddonInstaller {
8656
8656
  const closureNodeModules = resolveClosureNodeModulesDir(this.closureNodeModulesDir);
8657
8657
  if (closureNodeModules !== null) {
8658
8658
  const state = collectAddonTreeState(addonDir);
8659
- for (const link of state.existingLinks) if (isClosureLinkTarget(link.target, closureNodeModules)) fs.rmSync(path$1.join(addonDir, "node_modules", link.name), { force: true });
8659
+ for (const link of state.existingLinks) if (isClosureLinkTarget(link.target, closureNodeModules)) fs$1.rmSync(path$1.join(addonDir, "node_modules", link.name), { force: true });
8660
8660
  }
8661
8661
  this.logger.info(`${packageName} — reinstalling runtime dependencies`, { meta: { addonDir } });
8662
8662
  await runNpm([
@@ -8715,7 +8715,7 @@ var AddonInstaller = class AddonInstaller {
8715
8715
  async realignFromClosure(packageName, closureDir) {
8716
8716
  const targetDir = path$1.join(this.addonsDir, packageName);
8717
8717
  const result = await this.installLocal(packageName, closureDir);
8718
- await fs.promises.writeFile(path$1.join(targetDir, ".install-source"), "closure");
8718
+ await fs$1.promises.writeFile(path$1.join(targetDir, ".install-source"), "closure");
8719
8719
  this.manifest.upsert(result.name, {
8720
8720
  version: result.version,
8721
8721
  source: "closure"
@@ -8750,12 +8750,12 @@ var AddonInstaller = class AddonInstaller {
8750
8750
  */
8751
8751
  async installSymlink(packageName, sourceDir, pkgData, targetDir) {
8752
8752
  await this.ensureBuilt(packageName, sourceDir, pkgData);
8753
- fs.rmSync(targetDir, {
8753
+ fs$1.rmSync(targetDir, {
8754
8754
  recursive: true,
8755
8755
  force: true
8756
8756
  });
8757
8757
  ensureDir(path$1.dirname(targetDir));
8758
- fs.symlinkSync(sourceDir, targetDir, "dir");
8758
+ fs$1.symlinkSync(sourceDir, targetDir, "dir");
8759
8759
  this.manifest.upsert(packageName, {
8760
8760
  version: asString$1(pkgData.version, "0.0.0"),
8761
8761
  source: "local"
@@ -8769,17 +8769,17 @@ var AddonInstaller = class AddonInstaller {
8769
8769
  async installCopy(packageName, sourceDir, pkgData, targetDir) {
8770
8770
  await this.ensureBuilt(packageName, sourceDir, pkgData);
8771
8771
  const distDir = path$1.join(sourceDir, "dist");
8772
- if (!fs.existsSync(distDir)) throw new Error(`${packageName} has no dist/ after build`);
8773
- await fs.promises.rm(targetDir, {
8772
+ if (!fs$1.existsSync(distDir)) throw new Error(`${packageName} has no dist/ after build`);
8773
+ await fs$1.promises.rm(targetDir, {
8774
8774
  recursive: true,
8775
8775
  force: true
8776
8776
  });
8777
8777
  ensureDir(targetDir);
8778
- await fs.promises.writeFile(path$1.join(targetDir, "package.json"), JSON.stringify(stripBundledDeps(pkgData), null, 2));
8778
+ await fs$1.promises.writeFile(path$1.join(targetDir, "package.json"), JSON.stringify(stripBundledDeps(pkgData), null, 2));
8779
8779
  await copyDirRecursive(distDir, path$1.join(targetDir, "dist"));
8780
8780
  await copyExtraFileDirs(pkgData, sourceDir, targetDir);
8781
8781
  copyBundledNativeModules(sourceDir, targetDir, this.logger);
8782
- await fs.promises.writeFile(path$1.join(targetDir, ".install-source"), "local");
8782
+ await fs$1.promises.writeFile(path$1.join(targetDir, ".install-source"), "local");
8783
8783
  const localPkgVersion = asString$1(pkgData.version, "0.0.0");
8784
8784
  this.manifest.upsert(packageName, {
8785
8785
  version: localPkgVersion,
@@ -8820,7 +8820,7 @@ var AddonInstaller = class AddonInstaller {
8820
8820
  * unusual auth, offline mode, etc).
8821
8821
  */
8822
8822
  async installFromNpm(packageName, version) {
8823
- const tmpDir = fs.mkdtempSync(path$1.join(os$1.tmpdir(), "camstack-addon-npm-"));
8823
+ const tmpDir = fs$1.mkdtempSync(path$1.join(os$1.tmpdir(), "camstack-addon-npm-"));
8824
8824
  const packageSpec = version ? `${packageName}@${version}` : packageName;
8825
8825
  this.logger.info(`${packageName} — installing from npm`);
8826
8826
  try {
@@ -8834,19 +8834,19 @@ var AddonInstaller = class AddonInstaller {
8834
8834
  ];
8835
8835
  if (this.registry) args.push("--registry", this.registry);
8836
8836
  const { stdout } = await runNpm(args, this.npmRunOptions(tmpDir, 12e4));
8837
- const tgzFiles = fs.readdirSync(tmpDir).filter((f) => f.endsWith(".tgz"));
8837
+ const tgzFiles = fs$1.readdirSync(tmpDir).filter((f) => f.endsWith(".tgz"));
8838
8838
  if (tgzFiles.length === 0) throw new Error(`npm pack produced no tgz. stdout: ${stdout.trim()}`);
8839
8839
  return path$1.join(tmpDir, tgzFiles[0]);
8840
8840
  });
8841
8841
  const result = await this.installFromTgz(tgzPath);
8842
- fs.writeFileSync(path$1.join(this.addonsDir, result.name, ".install-source"), "npm");
8842
+ fs$1.writeFileSync(path$1.join(this.addonsDir, result.name, ".install-source"), "npm");
8843
8843
  this.manifest.upsert(result.name, {
8844
8844
  version: result.version,
8845
8845
  source: "npm"
8846
8846
  });
8847
8847
  return result;
8848
8848
  } finally {
8849
- fs.rmSync(tmpDir, {
8849
+ fs$1.rmSync(tmpDir, {
8850
8850
  recursive: true,
8851
8851
  force: true
8852
8852
  });
@@ -8884,7 +8884,7 @@ var AddonInstaller = class AddonInstaller {
8884
8884
  if (!tarRes.ok) throw new Error(`tarball GET ${tarballUrl} → ${tarRes.status}`);
8885
8885
  const tgzPath = path$1.join(tmpDir, `${packageName.replace(/[/@]/g, "-").replace(/^-+/, "")}-${resolvedVersion}.tgz`);
8886
8886
  const buf = Buffer.from(await tarRes.arrayBuffer());
8887
- fs.writeFileSync(tgzPath, buf);
8887
+ fs$1.writeFileSync(tgzPath, buf);
8888
8888
  return tgzPath;
8889
8889
  }
8890
8890
  /**
@@ -8905,7 +8905,7 @@ var AddonInstaller = class AddonInstaller {
8905
8905
  * on the next deploy.
8906
8906
  */
8907
8907
  async evictInstallDir(targetDir) {
8908
- if (!fs.existsSync(targetDir)) return;
8908
+ if (!fs$1.existsSync(targetDir)) return;
8909
8909
  const graveyard = path$1.join(this.addonsDir, ".evicting");
8910
8910
  ensureDir(graveyard);
8911
8911
  await this.sweepGraveyard(graveyard);
@@ -8913,10 +8913,10 @@ var AddonInstaller = class AddonInstaller {
8913
8913
  const flatName = path$1.relative(this.addonsDir, targetDir).replace(/[/\\]/g, "-");
8914
8914
  const asideDir = path$1.join(graveyard, `${flatName}-${ts}`);
8915
8915
  try {
8916
- fs.renameSync(targetDir, asideDir);
8916
+ fs$1.renameSync(targetDir, asideDir);
8917
8917
  } catch (renameErr) {
8918
8918
  if (renameErr.code === "EXDEV") {
8919
- await fs.promises.rm(targetDir, {
8919
+ await fs$1.promises.rm(targetDir, {
8920
8920
  recursive: true,
8921
8921
  force: true
8922
8922
  });
@@ -8924,7 +8924,7 @@ var AddonInstaller = class AddonInstaller {
8924
8924
  }
8925
8925
  throw renameErr;
8926
8926
  }
8927
- await fs.promises.rm(asideDir, {
8927
+ await fs$1.promises.rm(asideDir, {
8928
8928
  recursive: true,
8929
8929
  force: true
8930
8930
  }).catch((cleanupErr) => {
@@ -8945,14 +8945,14 @@ var AddonInstaller = class AddonInstaller {
8945
8945
  async sweepStagingResidue(stagingRoot) {
8946
8946
  let names;
8947
8947
  try {
8948
- names = fs.readdirSync(stagingRoot);
8948
+ names = fs$1.readdirSync(stagingRoot);
8949
8949
  } catch {
8950
8950
  return;
8951
8951
  }
8952
8952
  const now = Date.now();
8953
8953
  const ages = [];
8954
8954
  for (const name of names) try {
8955
- const stat = fs.statSync(path$1.join(stagingRoot, name));
8955
+ const stat = fs$1.statSync(path$1.join(stagingRoot, name));
8956
8956
  ages.push({
8957
8957
  name,
8958
8958
  ageMs: now - stat.mtimeMs
@@ -8963,7 +8963,7 @@ var AddonInstaller = class AddonInstaller {
8963
8963
  stagingRoot,
8964
8964
  entries: sweepable
8965
8965
  } });
8966
- await Promise.all(sweepable.map((name) => fs.promises.rm(path$1.join(stagingRoot, name), {
8966
+ await Promise.all(sweepable.map((name) => fs$1.promises.rm(path$1.join(stagingRoot, name), {
8967
8967
  recursive: true,
8968
8968
  force: true
8969
8969
  }).catch(() => void 0)));
@@ -8972,11 +8972,11 @@ var AddonInstaller = class AddonInstaller {
8972
8972
  async sweepGraveyard(graveyard) {
8973
8973
  let entries;
8974
8974
  try {
8975
- entries = fs.readdirSync(graveyard);
8975
+ entries = fs$1.readdirSync(graveyard);
8976
8976
  } catch {
8977
8977
  return;
8978
8978
  }
8979
- await Promise.all(entries.map((name) => fs.promises.rm(path$1.join(graveyard, name), {
8979
+ await Promise.all(entries.map((name) => fs$1.promises.rm(path$1.join(graveyard, name), {
8980
8980
  recursive: true,
8981
8981
  force: true
8982
8982
  }).catch(() => void 0)));
@@ -9027,7 +9027,7 @@ var AddonInstaller = class AddonInstaller {
9027
9027
  return;
9028
9028
  }
9029
9029
  const strippedManifest = stripBundledDeps(pkgView.raw);
9030
- await fs.promises.writeFile(pkgJsonPath, JSON.stringify(strippedManifest, null, 2));
9030
+ await fs$1.promises.writeFile(pkgJsonPath, JSON.stringify(strippedManifest, null, 2));
9031
9031
  const deps = asJsonObject$1(strippedManifest["dependencies"]);
9032
9032
  const depNames = deps ? Object.keys(deps) : [];
9033
9033
  if (depNames.length === 0) return;
@@ -9159,9 +9159,9 @@ var AddonInstaller = class AddonInstaller {
9159
9159
  "-C",
9160
9160
  stagingDir
9161
9161
  ], { timeout: 12e4 });
9162
- const pkgDir = fs.existsSync(path$1.join(stagingDir, "package", "package.json")) ? path$1.join(stagingDir, "package") : stagingDir;
9162
+ const pkgDir = fs$1.existsSync(path$1.join(stagingDir, "package", "package.json")) ? path$1.join(stagingDir, "package") : stagingDir;
9163
9163
  const pkgJsonPath = path$1.join(pkgDir, "package.json");
9164
- if (!fs.existsSync(pkgJsonPath)) throw new Error("No package.json found in tgz archive");
9164
+ if (!fs$1.existsSync(pkgJsonPath)) throw new Error("No package.json found in tgz archive");
9165
9165
  const pkgView = readPackageJson(pkgJsonPath);
9166
9166
  if (!pkgView) throw new Error(`Invalid package.json at ${pkgJsonPath}`);
9167
9167
  if (!pkgView.camstackAddons) throw new Error(`Package ${pkgView.name} has no camstack.addons manifest`);
@@ -9171,7 +9171,7 @@ var AddonInstaller = class AddonInstaller {
9171
9171
  this.dedupeTreeAgainstClosure(pkgDir, pkgView.name);
9172
9172
  await this.evictInstallDir(targetDir);
9173
9173
  ensureDir(path$1.dirname(targetDir));
9174
- await fs.promises.rename(pkgDir, targetDir);
9174
+ await fs$1.promises.rename(pkgDir, targetDir);
9175
9175
  this.manifest.upsert(pkgView.name, {
9176
9176
  version: pkgView.version,
9177
9177
  source: "bundled"
@@ -9182,7 +9182,7 @@ var AddonInstaller = class AddonInstaller {
9182
9182
  };
9183
9183
  } finally {
9184
9184
  this.inFlightStaging.delete(stagingName);
9185
- await fs.promises.rm(stagingDir, {
9185
+ await fs$1.promises.rm(stagingDir, {
9186
9186
  recursive: true,
9187
9187
  force: true
9188
9188
  }).catch(() => void 0);
@@ -9212,13 +9212,13 @@ var AddonInstaller = class AddonInstaller {
9212
9212
  const current = this.manifest.get(packageName);
9213
9213
  if (current == null) throw new Error(`Cannot update ${packageName}: not currently tracked in manifest`);
9214
9214
  const addonDir = path$1.join(this.addonsDir, packageName);
9215
- if (!fs.existsSync(addonDir)) throw new Error(`Cannot update ${packageName}: install dir ${addonDir} missing`);
9215
+ if (!fs$1.existsSync(addonDir)) throw new Error(`Cannot update ${packageName}: install dir ${addonDir} missing`);
9216
9216
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
9217
9217
  const backupRoot = path$1.join(this.addonsDir, ".backups", packageName);
9218
9218
  ensureDir(backupRoot);
9219
9219
  const backupDir = path$1.join(backupRoot, ts);
9220
9220
  this.logger.info(`${packageName} — backing up v${current.version} → ${backupDir}`);
9221
- fs.renameSync(addonDir, backupDir);
9221
+ fs$1.renameSync(addonDir, backupDir);
9222
9222
  let result;
9223
9223
  try {
9224
9224
  if (this.installSource === "local" || this.installSource === "symlink") {
@@ -9233,11 +9233,11 @@ var AddonInstaller = class AddonInstaller {
9233
9233
  } catch (installErr) {
9234
9234
  this.logger.error(`${packageName} — install failed, restoring backup`, { meta: { error: errMsg$1(installErr) } });
9235
9235
  try {
9236
- if (fs.existsSync(addonDir)) fs.rmSync(addonDir, {
9236
+ if (fs$1.existsSync(addonDir)) fs$1.rmSync(addonDir, {
9237
9237
  recursive: true,
9238
9238
  force: true
9239
9239
  });
9240
- fs.renameSync(backupDir, addonDir);
9240
+ fs$1.renameSync(backupDir, addonDir);
9241
9241
  this.manifest.upsert(packageName, {
9242
9242
  version: current.version,
9243
9243
  source: current.source,
@@ -9298,7 +9298,7 @@ var AddonInstaller = class AddonInstaller {
9298
9298
  const current = this.manifest.get(packageName);
9299
9299
  if (current == null) throw new Error(`Cannot update ${packageName}: not currently tracked in manifest`);
9300
9300
  const addonDir = path$1.join(this.addonsDir, packageName);
9301
- if (!fs.existsSync(addonDir)) throw new Error(`Cannot update ${packageName}: install dir ${addonDir} missing`);
9301
+ if (!fs$1.existsSync(addonDir)) throw new Error(`Cannot update ${packageName}: install dir ${addonDir} missing`);
9302
9302
  await this.installRuntimeDependencies(stagedPath, packageName);
9303
9303
  await this.installNativeDependencies(stagedPath, packageName);
9304
9304
  this.dedupeTreeAgainstClosure(stagedPath, packageName);
@@ -9307,14 +9307,14 @@ var AddonInstaller = class AddonInstaller {
9307
9307
  ensureDir(backupRoot);
9308
9308
  const backupDir = path$1.join(backupRoot, ts);
9309
9309
  this.logger.info(`${packageName} — backing up v${current.version} → ${backupDir}`);
9310
- fs.renameSync(addonDir, backupDir);
9310
+ fs$1.renameSync(addonDir, backupDir);
9311
9311
  try {
9312
9312
  try {
9313
- fs.renameSync(stagedPath, addonDir);
9313
+ fs$1.renameSync(stagedPath, addonDir);
9314
9314
  } catch (renameErr) {
9315
9315
  if (renameErr.code === "EXDEV") {
9316
- fs.cpSync(stagedPath, addonDir, { recursive: true });
9317
- fs.rmSync(stagedPath, {
9316
+ fs$1.cpSync(stagedPath, addonDir, { recursive: true });
9317
+ fs$1.rmSync(stagedPath, {
9318
9318
  recursive: true,
9319
9319
  force: true
9320
9320
  });
@@ -9323,11 +9323,11 @@ var AddonInstaller = class AddonInstaller {
9323
9323
  } catch (swapErr) {
9324
9324
  this.logger.error(`${packageName} — staged swap failed, restoring backup`, { meta: { error: errMsg$1(swapErr) } });
9325
9325
  try {
9326
- if (fs.existsSync(addonDir)) fs.rmSync(addonDir, {
9326
+ if (fs$1.existsSync(addonDir)) fs$1.rmSync(addonDir, {
9327
9327
  recursive: true,
9328
9328
  force: true
9329
9329
  });
9330
- fs.renameSync(backupDir, addonDir);
9330
+ fs$1.renameSync(backupDir, addonDir);
9331
9331
  this.manifest.upsert(packageName, {
9332
9332
  version: current.version,
9333
9333
  source: current.source,
@@ -9366,20 +9366,20 @@ var AddonInstaller = class AddonInstaller {
9366
9366
  this.logger.warn(`${packageName} — no backup to rollback to`);
9367
9367
  return null;
9368
9368
  }
9369
- if (!fs.existsSync(entry.lastBackupDir)) {
9369
+ if (!fs$1.existsSync(entry.lastBackupDir)) {
9370
9370
  this.logger.warn(`${packageName} — backup dir vanished: ${entry.lastBackupDir}`);
9371
9371
  return null;
9372
9372
  }
9373
9373
  const addonDir = path$1.join(this.addonsDir, packageName);
9374
- if (fs.existsSync(addonDir)) fs.rmSync(addonDir, {
9374
+ if (fs$1.existsSync(addonDir)) fs$1.rmSync(addonDir, {
9375
9375
  recursive: true,
9376
9376
  force: true
9377
9377
  });
9378
- fs.renameSync(entry.lastBackupDir, addonDir);
9378
+ fs$1.renameSync(entry.lastBackupDir, addonDir);
9379
9379
  const pkgJsonPath = path$1.join(addonDir, "package.json");
9380
9380
  let restoredVersion = entry.version;
9381
- if (fs.existsSync(pkgJsonPath)) try {
9382
- const parsed = JSON.parse(fs.readFileSync(pkgJsonPath, "utf-8"));
9381
+ if (fs$1.existsSync(pkgJsonPath)) try {
9382
+ const parsed = JSON.parse(fs$1.readFileSync(pkgJsonPath, "utf-8"));
9383
9383
  if (typeof parsed === "object" && parsed != null) {
9384
9384
  const v = parsed.version;
9385
9385
  if (typeof v === "string" && v.length > 0) restoredVersion = v;
@@ -9427,7 +9427,7 @@ var AddonInstaller = class AddonInstaller {
9427
9427
  return false;
9428
9428
  }
9429
9429
  try {
9430
- await fs.promises.rm(target, {
9430
+ await fs$1.promises.rm(target, {
9431
9431
  recursive: true,
9432
9432
  force: true
9433
9433
  });
@@ -9445,7 +9445,7 @@ var AddonInstaller = class AddonInstaller {
9445
9445
  listBackupsFor(packageName) {
9446
9446
  const dir = path$1.join(this.backupsRoot, packageName);
9447
9447
  try {
9448
- return fs.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path$1.join(dir, e.name)).sort();
9448
+ return fs$1.readdirSync(dir, { withFileTypes: true }).filter((e) => e.isDirectory()).map((e) => path$1.join(dir, e.name)).sort();
9449
9449
  } catch {
9450
9450
  return [];
9451
9451
  }
@@ -9477,7 +9477,7 @@ var AddonInstaller = class AddonInstaller {
9477
9477
  for (const dir of [pkgDir, path$1.dirname(pkgDir)]) {
9478
9478
  if (!this.isInsideBackups(dir)) continue;
9479
9479
  try {
9480
- await fs.promises.rmdir(dir);
9480
+ await fs$1.promises.rmdir(dir);
9481
9481
  } catch {
9482
9482
  return;
9483
9483
  }
@@ -9559,7 +9559,7 @@ var AddonInstaller = class AddonInstaller {
9559
9559
  */
9560
9560
  resolveBackupToKeep(packageName, backups) {
9561
9561
  const liveDir = path$1.join(this.addonsDir, packageName);
9562
- if (!fs.existsSync(liveDir)) {
9562
+ if (!fs$1.existsSync(liveDir)) {
9563
9563
  const newest = backups[backups.length - 1] ?? null;
9564
9564
  if (newest != null) this.logger.warn(`${packageName} — live install dir missing; retaining its newest backup as the only surviving copy`, { meta: {
9565
9565
  liveDir,
@@ -9576,7 +9576,7 @@ var AddonInstaller = class AddonInstaller {
9576
9576
  listBackedUpPackages() {
9577
9577
  let entries;
9578
9578
  try {
9579
- entries = fs.readdirSync(this.backupsRoot, { withFileTypes: true });
9579
+ entries = fs$1.readdirSync(this.backupsRoot, { withFileTypes: true });
9580
9580
  } catch {
9581
9581
  return [];
9582
9582
  }
@@ -9588,14 +9588,14 @@ var AddonInstaller = class AddonInstaller {
9588
9588
  continue;
9589
9589
  }
9590
9590
  const scopeDir = path$1.join(this.backupsRoot, entry.name);
9591
- for (const inner of fs.readdirSync(scopeDir, { withFileTypes: true })) if (inner.isDirectory()) names.push(`${entry.name}/${inner.name}`);
9591
+ for (const inner of fs$1.readdirSync(scopeDir, { withFileTypes: true })) if (inner.isDirectory()) names.push(`${entry.name}/${inner.name}`);
9592
9592
  }
9593
9593
  return names;
9594
9594
  }
9595
9595
  async uninstall(packageName) {
9596
9596
  const addonDir = path$1.join(this.addonsDir, packageName);
9597
- if (fs.existsSync(addonDir)) {
9598
- fs.rmSync(addonDir, {
9597
+ if (fs$1.existsSync(addonDir)) {
9598
+ fs$1.rmSync(addonDir, {
9599
9599
  recursive: true,
9600
9600
  force: true
9601
9601
  });
@@ -9603,8 +9603,8 @@ var AddonInstaller = class AddonInstaller {
9603
9603
  return;
9604
9604
  }
9605
9605
  const legacyDir = path$1.join(this.addonsDir, packageName.replace(/^@[^/]+\//, ""));
9606
- if (fs.existsSync(legacyDir)) {
9607
- fs.rmSync(legacyDir, {
9606
+ if (fs$1.existsSync(legacyDir)) {
9607
+ fs$1.rmSync(legacyDir, {
9608
9608
  recursive: true,
9609
9609
  force: true
9610
9610
  });
@@ -9612,22 +9612,22 @@ var AddonInstaller = class AddonInstaller {
9612
9612
  }
9613
9613
  }
9614
9614
  listInstalled() {
9615
- if (!fs.existsSync(this.addonsDir)) return [];
9615
+ if (!fs$1.existsSync(this.addonsDir)) return [];
9616
9616
  const packageDirs = [];
9617
- for (const entry of fs.readdirSync(this.addonsDir, { withFileTypes: true })) {
9617
+ for (const entry of fs$1.readdirSync(this.addonsDir, { withFileTypes: true })) {
9618
9618
  if (!isDirEntry(entry, this.addonsDir)) continue;
9619
9619
  if (entry.name.startsWith("@")) {
9620
9620
  const scopeDir = path$1.join(this.addonsDir, entry.name);
9621
- for (const inner of fs.readdirSync(scopeDir, { withFileTypes: true })) if (isDirEntry(inner, scopeDir)) packageDirs.push(path$1.join(scopeDir, inner.name));
9621
+ for (const inner of fs$1.readdirSync(scopeDir, { withFileTypes: true })) if (isDirEntry(inner, scopeDir)) packageDirs.push(path$1.join(scopeDir, inner.name));
9622
9622
  } else packageDirs.push(path$1.join(this.addonsDir, entry.name));
9623
9623
  }
9624
9624
  return packageDirs.map((dir) => {
9625
9625
  const pkgPath = path$1.join(dir, "package.json");
9626
- if (!fs.existsSync(pkgPath)) return null;
9626
+ if (!fs$1.existsSync(pkgPath)) return null;
9627
9627
  const pkg = readPackageJson(pkgPath);
9628
9628
  if (!pkg || !pkg.camstackAddons) return null;
9629
9629
  const sourceFile = path$1.join(dir, ".install-source");
9630
- const installSource = fs.existsSync(sourceFile) ? parseInstallSource(fs.readFileSync(sourceFile, "utf-8").trim()) : void 0;
9630
+ const installSource = fs$1.existsSync(sourceFile) ? parseInstallSource(fs$1.readFileSync(sourceFile, "utf-8").trim()) : void 0;
9631
9631
  return {
9632
9632
  name: pkg.name,
9633
9633
  version: pkg.version,
@@ -9637,13 +9637,13 @@ var AddonInstaller = class AddonInstaller {
9637
9637
  }).filter((item) => item !== null);
9638
9638
  }
9639
9639
  isInstalled(packageName) {
9640
- if (fs.existsSync(path$1.join(this.addonsDir, packageName, "package.json"))) return true;
9641
- return fs.existsSync(path$1.join(this.addonsDir, packageName.replace(/^@[^/]+\//, ""), "package.json"));
9640
+ if (fs$1.existsSync(path$1.join(this.addonsDir, packageName, "package.json"))) return true;
9641
+ return fs$1.existsSync(path$1.join(this.addonsDir, packageName.replace(/^@[^/]+\//, ""), "package.json"));
9642
9642
  }
9643
9643
  getInstalledPackage(packageName) {
9644
9644
  let pkgPath = path$1.join(this.addonsDir, packageName, "package.json");
9645
- if (!fs.existsSync(pkgPath)) pkgPath = path$1.join(this.addonsDir, packageName.replace(/^@[^/]+\//, ""), "package.json");
9646
- if (!fs.existsSync(pkgPath)) return null;
9645
+ if (!fs$1.existsSync(pkgPath)) pkgPath = path$1.join(this.addonsDir, packageName.replace(/^@[^/]+\//, ""), "package.json");
9646
+ if (!fs$1.existsSync(pkgPath)) return null;
9647
9647
  const pkg = readPackageJson(pkgPath);
9648
9648
  if (!pkg) return null;
9649
9649
  return {
@@ -9662,7 +9662,7 @@ var AddonInstaller = class AddonInstaller {
9662
9662
  ]) {
9663
9663
  const candidate = path$1.join(this.workspaceDir, dirName);
9664
9664
  try {
9665
- const pkg = asJsonObject$1(parseJsonUnknown(fs.readFileSync(path$1.join(candidate, "package.json"), "utf-8")));
9665
+ const pkg = asJsonObject$1(parseJsonUnknown(fs$1.readFileSync(path$1.join(candidate, "package.json"), "utf-8")));
9666
9666
  if (pkg && asString$1(pkg["name"]) === packageName) return candidate;
9667
9667
  } catch {}
9668
9668
  }
@@ -9671,7 +9671,7 @@ var AddonInstaller = class AddonInstaller {
9671
9671
  /** Ensure a package is built (dist/ exists and page bundles present) */
9672
9672
  async ensureBuilt(packageName, sourceDir, pkgData) {
9673
9673
  const distDir = path$1.join(sourceDir, "dist");
9674
- if (!(!fs.existsSync(distDir) || this.isDistIncomplete(pkgData, sourceDir))) return;
9674
+ if (!(!fs$1.existsSync(distDir) || this.isDistIncomplete(pkgData, sourceDir))) return;
9675
9675
  this.logger.info(`${packageName} — building (dist/ missing or incomplete)`);
9676
9676
  try {
9677
9677
  await runNpm(["run", "build"], this.npmRunOptions(sourceDir, 18e4));
@@ -9686,7 +9686,7 @@ var AddonInstaller = class AddonInstaller {
9686
9686
  if (!camstack?.addons) return false;
9687
9687
  for (const addon of camstack.addons) {
9688
9688
  if (!addon.pages) continue;
9689
- for (const page of addon.pages) if (page.bundle && !fs.existsSync(path$1.join(sourceDir, "dist", page.bundle))) return true;
9689
+ for (const page of addon.pages) if (page.bundle && !fs$1.existsSync(path$1.join(sourceDir, "dist", page.bundle))) return true;
9690
9690
  }
9691
9691
  return false;
9692
9692
  }
@@ -9695,7 +9695,7 @@ var AddonInstaller = class AddonInstaller {
9695
9695
  function isDirEntry(entry, parentDir) {
9696
9696
  if (entry.isDirectory()) return true;
9697
9697
  if (entry.isSymbolicLink()) try {
9698
- return fs.statSync(path$1.join(parentDir, entry.name)).isDirectory();
9698
+ return fs$1.statSync(path$1.join(parentDir, entry.name)).isDirectory();
9699
9699
  } catch {
9700
9700
  return false;
9701
9701
  }
@@ -9794,7 +9794,7 @@ function selectAddonResidue(candidates) {
9794
9794
  }
9795
9795
  function readDeclaredName(dir) {
9796
9796
  try {
9797
- const parsed = JSON.parse(fs.readFileSync(path$1.join(dir, "package.json"), "utf-8"));
9797
+ const parsed = JSON.parse(fs$1.readFileSync(path$1.join(dir, "package.json"), "utf-8"));
9798
9798
  if (typeof parsed !== "object" || parsed === null) return null;
9799
9799
  const name = parsed.name;
9800
9800
  return typeof name === "string" ? name : null;
@@ -9804,7 +9804,7 @@ function readDeclaredName(dir) {
9804
9804
  }
9805
9805
  function readDeclaredVersion(dir) {
9806
9806
  try {
9807
- const parsed = JSON.parse(fs.readFileSync(path$1.join(dir, "package.json"), "utf-8"));
9807
+ const parsed = JSON.parse(fs$1.readFileSync(path$1.join(dir, "package.json"), "utf-8"));
9808
9808
  if (typeof parsed !== "object" || parsed === null) return null;
9809
9809
  const version = parsed.version;
9810
9810
  return typeof version === "string" ? version : null;
@@ -9814,7 +9814,7 @@ function readDeclaredVersion(dir) {
9814
9814
  }
9815
9815
  function isDirLike(p) {
9816
9816
  try {
9817
- return fs.statSync(p).isDirectory();
9817
+ return fs$1.statSync(p).isDirectory();
9818
9818
  } catch {
9819
9819
  return false;
9820
9820
  }
@@ -9824,7 +9824,7 @@ function freeQuarantineTarget(store, scope, dirName) {
9824
9824
  const base = scope === null ? dirName : `${scope.replace("@", "")}__${dirName}`;
9825
9825
  let candidate = path$1.join(store, base);
9826
9826
  let n = 1;
9827
- while (fs.existsSync(candidate)) {
9827
+ while (fs$1.existsSync(candidate)) {
9828
9828
  candidate = path$1.join(store, `${base}-${n}`);
9829
9829
  n += 1;
9830
9830
  }
@@ -9841,7 +9841,7 @@ function freeQuarantineTarget(store, scope, dirName) {
9841
9841
  function quarantineAddonResidue(addonsDir, log) {
9842
9842
  const quarantined = [];
9843
9843
  const failed = [];
9844
- if (!fs.existsSync(addonsDir)) return {
9844
+ if (!fs$1.existsSync(addonsDir)) return {
9845
9845
  quarantined,
9846
9846
  failed
9847
9847
  };
@@ -9849,7 +9849,7 @@ function quarantineAddonResidue(addonsDir, log) {
9849
9849
  const scan = (parent, scope) => {
9850
9850
  let names;
9851
9851
  try {
9852
- names = fs.readdirSync(parent);
9852
+ names = fs$1.readdirSync(parent);
9853
9853
  } catch {
9854
9854
  return;
9855
9855
  }
@@ -9868,8 +9868,8 @@ function quarantineAddonResidue(addonsDir, log) {
9868
9868
  const version = readDeclaredVersion(full);
9869
9869
  const to = freeQuarantineTarget(store, scope, dirName);
9870
9870
  try {
9871
- fs.mkdirSync(store, { recursive: true });
9872
- fs.renameSync(full, to);
9871
+ fs$1.mkdirSync(store, { recursive: true });
9872
+ fs$1.renameSync(full, to);
9873
9873
  } catch (err) {
9874
9874
  const error = err instanceof Error ? err.message : String(err);
9875
9875
  failed.push({
@@ -9910,8 +9910,8 @@ function detectWorkspacePackagesDir(startDir) {
9910
9910
  current = path$1.dirname(current);
9911
9911
  const packagesDir = path$1.join(current, "packages");
9912
9912
  const rootPkgJson = path$1.join(current, "package.json");
9913
- if (fs.existsSync(packagesDir) && fs.existsSync(rootPkgJson)) try {
9914
- const rootPkg = JSON.parse(fs.readFileSync(rootPkgJson, "utf-8"));
9913
+ if (fs$1.existsSync(packagesDir) && fs$1.existsSync(rootPkgJson)) try {
9914
+ const rootPkg = JSON.parse(fs$1.readFileSync(rootPkgJson, "utf-8"));
9915
9915
  if (rootPkg.workspaces || rootPkg.name === "camstack-server" || rootPkg.name === "camstack") return packagesDir;
9916
9916
  } catch {}
9917
9917
  }
@@ -9950,11 +9950,11 @@ function getRestartMarkerPath(dataDir) {
9950
9950
  * intact or no marker at all (never a half-written file).
9951
9951
  */
9952
9952
  function writePendingRestart(dataDir, marker) {
9953
- fs.mkdirSync(dataDir, { recursive: true });
9953
+ fs$1.mkdirSync(dataDir, { recursive: true });
9954
9954
  const markerPath = getRestartMarkerPath(dataDir);
9955
9955
  const tmpPath = `${markerPath}.tmp`;
9956
- fs.writeFileSync(tmpPath, JSON.stringify(marker, null, 2), "utf-8");
9957
- fs.renameSync(tmpPath, markerPath);
9956
+ fs$1.writeFileSync(tmpPath, JSON.stringify(marker, null, 2), "utf-8");
9957
+ fs$1.renameSync(tmpPath, markerPath);
9958
9958
  }
9959
9959
  /**
9960
9960
  * Read + consume the marker. Returns the parsed payload on success and
@@ -9979,10 +9979,10 @@ function writePendingRestart(dataDir, marker) {
9979
9979
  */
9980
9980
  function readPendingRestart(dataDir) {
9981
9981
  const markerPath = getRestartMarkerPath(dataDir);
9982
- if (!fs.existsSync(markerPath)) return null;
9982
+ if (!fs$1.existsSync(markerPath)) return null;
9983
9983
  let raw;
9984
9984
  try {
9985
- raw = fs.readFileSync(markerPath, "utf-8");
9985
+ raw = fs$1.readFileSync(markerPath, "utf-8");
9986
9986
  } catch (err) {
9987
9987
  console.error("[restart-coordinator] Marker unreadable — leaving in place:", err);
9988
9988
  return null;
@@ -10021,7 +10021,7 @@ function readPendingRestart(dataDir) {
10021
10021
  /** Remove the marker if present. No-op if missing. */
10022
10022
  function clearPendingRestart(dataDir) {
10023
10023
  const markerPath = getRestartMarkerPath(dataDir);
10024
- fs.rmSync(markerPath, { force: true });
10024
+ fs$1.rmSync(markerPath, { force: true });
10025
10025
  }
10026
10026
  function isRestartKind(value) {
10027
10027
  return value === "framework-update" || value === "manual" || value === "system";
@@ -10033,7 +10033,7 @@ function scheduleSelfRestart(options = {}) {
10033
10033
  const touchTarget = process.env["CAMSTACK_RESTART_TOUCH_FILE"];
10034
10034
  if (touchTarget !== void 0 && touchTarget.length > 0) try {
10035
10035
  const now = /* @__PURE__ */ new Date();
10036
- fs.utimesSync(touchTarget, now, now);
10036
+ fs$1.utimesSync(touchTarget, now, now);
10037
10037
  return;
10038
10038
  } catch (err) {
10039
10039
  console.error("[restart-coordinator] dev touch-reload failed; falling through to process exit:", err);
@@ -14400,7 +14400,7 @@ function loadBootstrapConfig(configPath) {
14400
14400
  function writeBootstrapSection(configPath, section, data) {
14401
14401
  if (!BOOTSTRAP_SECTIONS.has(section)) throw new Error(`[ConfigManager] Section "${section}" is a runtime setting — use setSection() to persist via the settings-store, not update() which writes to config.yaml`);
14402
14402
  let raw = {};
14403
- if (fs.existsSync(configPath)) raw = asJsonObject(load(fs.readFileSync(configPath, "utf-8"))) ?? {};
14403
+ if (fs$1.existsSync(configPath)) raw = asJsonObject(load(fs$1.readFileSync(configPath, "utf-8"))) ?? {};
14404
14404
  const existing = asJsonObject(raw[section]) ?? {};
14405
14405
  raw[section] = {
14406
14406
  ...existing,
@@ -14409,12 +14409,12 @@ function writeBootstrapSection(configPath, section, data) {
14409
14409
  const validation = bootstrapSchema.safeParse(raw);
14410
14410
  if (!validation.success) throw new Error(`[ConfigManager] Invalid config update for section "${section}": ${validation.error.message}`);
14411
14411
  const tmpPath = `${configPath}.tmp`;
14412
- fs.writeFileSync(tmpPath, dump(raw, {
14412
+ fs$1.writeFileSync(tmpPath, dump(raw, {
14413
14413
  lineWidth: 120,
14414
14414
  indent: 2,
14415
14415
  quotingType: "\""
14416
14416
  }), "utf-8");
14417
- fs.renameSync(tmpPath, configPath);
14417
+ fs$1.renameSync(tmpPath, configPath);
14418
14418
  return validation.data;
14419
14419
  }
14420
14420
  /**
@@ -14485,11 +14485,11 @@ function applyEnvOverrides(raw) {
14485
14485
  return result;
14486
14486
  }
14487
14487
  function loadYaml(configPath) {
14488
- if (!fs.existsSync(configPath)) {
14488
+ if (!fs$1.existsSync(configPath)) {
14489
14489
  console.warn(`[ConfigManager] Config file not found at: ${configPath}\n → Using built-in defaults. Set CONFIG_PATH env var or create the file.\n → Example path from project root: ./server/backend/data/config.yaml`);
14490
14490
  return {};
14491
14491
  }
14492
- const parsed = load(fs.readFileSync(configPath, "utf-8")) ?? {};
14492
+ const parsed = load(fs$1.readFileSync(configPath, "utf-8")) ?? {};
14493
14493
  console.log(`[ConfigManager] Loaded config from: ${configPath}`);
14494
14494
  return parsed;
14495
14495
  }
@@ -21786,7 +21786,7 @@ function toKebab(name) {
21786
21786
  return name.replace(/[A-Z]/g, (m, i) => (i > 0 ? "-" : "") + m.toLowerCase());
21787
21787
  }
21788
21788
  /**
21789
- * Parse an `op.path` (e.g. `"pipelineExecutor.getDefaultSteps"`) into
21789
+ * Parse an `op.path` (e.g. `"pipelineExecutor.getAvailableEngines"`) into
21790
21790
  * the capability name (kebab-case) and the method name.
21791
21791
  */
21792
21792
  function parsePath(path) {
@@ -22296,6 +22296,148 @@ function buildLinkChain(target, localResolver, hookup) {
22296
22296
  return links;
22297
22297
  }
22298
22298
  //#endregion
22299
+ //#region src/kernel/hwaccel/vaapi-init-probe.ts
22300
+ /**
22301
+ * Can libva initialise the VA driver on this node's render node? (D926)
22302
+ *
22303
+ * Measured 2026-10-23 (intel-1.2.509, hub + little-unraid): Intel's iHD 25.2.4
22304
+ * exports only `__vaDriverInit_1_22`, the container's Ubuntu libva 2.20 looks
22305
+ * for `_1_20`, and `vaInitialize` failed — while the resolver kept offering
22306
+ * `qsv, vaapi`. Every session tried, failed and fell back to software: 722
22307
+ * `hwaccel 'vaapi' failed` lines a day and nothing that named the cause.
22308
+ *
22309
+ * One `vainfo --display drm --device <node>` per process answers it. A failure
22310
+ * reads the driver's exported `__vaDriverInit_1_N` so the verdict names the gap
22311
+ * (`driver iHD needs VA-API >= 1.22, libva has 1.20`). No `vainfo` on the host
22312
+ * (a bare install) is `unknown` — the resolver then behaves as it always did.
22313
+ */
22314
+ var VAINFO_TIMEOUT_MS = 1e4;
22315
+ var INIT_SYMBOL = /__vaDriverInit_(\d+)_(\d+)/g;
22316
+ var VA_API_VERSION = /VA-API version:? (\d+)\.(\d+)/;
22317
+ var DRIVER_OPEN = /Trying to open (\S+_drv_video\.so)/g;
22318
+ function newestInitVersion(symbols) {
22319
+ let best = null;
22320
+ for (const symbol of symbols) for (const m of symbol.matchAll(INIT_SYMBOL)) {
22321
+ const v = {
22322
+ major: Number(m[1]),
22323
+ minor: Number(m[2])
22324
+ };
22325
+ if (!best || v.major > best.major || v.major === best.major && v.minor > best.minor) best = v;
22326
+ }
22327
+ return best;
22328
+ }
22329
+ function lastMatch(text, re) {
22330
+ let last = null;
22331
+ for (const m of text.matchAll(re)) last = m[1] ?? null;
22332
+ return last;
22333
+ }
22334
+ function lastLine(text) {
22335
+ const lines = text.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
22336
+ return lines[lines.length - 1] ?? "no output";
22337
+ }
22338
+ function driverName(driverPath) {
22339
+ if (!driverPath) return "unknown";
22340
+ return basename(driverPath).replace(/_drv_video\.so$/, "");
22341
+ }
22342
+ /** Classify one vainfo run plus the driver's exported init symbols. Pure. */
22343
+ function classifyVainfo(run, driverSymbols) {
22344
+ const va = VA_API_VERSION.exec(run.output);
22345
+ const vaApiVersion = va ? `${va[1]}.${va[2]}` : null;
22346
+ const driverPath = lastMatch(run.output, DRIVER_OPEN);
22347
+ const needs = newestInitVersion(driverSymbols);
22348
+ const driverNeedsVaApi = needs ? `${needs.major}.${needs.minor}` : null;
22349
+ const base = {
22350
+ vaApiVersion,
22351
+ driverPath,
22352
+ driverNeedsVaApi
22353
+ };
22354
+ if (run.spawnError !== null) return {
22355
+ ...base,
22356
+ state: "unknown",
22357
+ summary: `vaapi: unknown (vainfo not run: ${run.spawnError})`
22358
+ };
22359
+ if (run.exitCode === 0) return {
22360
+ ...base,
22361
+ state: "ok",
22362
+ summary: `vaapi: ok (VA-API ${vaApiVersion ?? "?"}, driver ${driverName(driverPath)})`
22363
+ };
22364
+ const reason = needs !== null && va !== null && (needs.major > Number(va[1]) || needs.major === Number(va[1]) && needs.minor > Number(va[2])) ? `driver ${driverName(driverPath)} needs VA-API >= ${driverNeedsVaApi}, libva has ${vaApiVersion}` : lastLine(run.output);
22365
+ return {
22366
+ ...base,
22367
+ state: "init-failed",
22368
+ summary: `vaapi: init-failed (${reason})`
22369
+ };
22370
+ }
22371
+ /** Run `vainfo` against one render node; never throws. */
22372
+ function runVainfo(renderNode) {
22373
+ return new Promise((resolve) => {
22374
+ execFile("vainfo", [
22375
+ "--display",
22376
+ "drm",
22377
+ "--device",
22378
+ renderNode
22379
+ ], {
22380
+ timeout: VAINFO_TIMEOUT_MS,
22381
+ encoding: "utf8"
22382
+ }, (err, stdout, stderr) => {
22383
+ const output = `${stdout}\n${stderr}`;
22384
+ if (err === null) {
22385
+ resolve({
22386
+ exitCode: 0,
22387
+ output,
22388
+ spawnError: null
22389
+ });
22390
+ return;
22391
+ }
22392
+ const code = err.code;
22393
+ if (typeof code === "number") {
22394
+ resolve({
22395
+ exitCode: code,
22396
+ output,
22397
+ spawnError: null
22398
+ });
22399
+ return;
22400
+ }
22401
+ resolve({
22402
+ exitCode: null,
22403
+ output,
22404
+ spawnError: code ?? (err.killed ? "timeout" : err.message)
22405
+ });
22406
+ });
22407
+ });
22408
+ }
22409
+ /**
22410
+ * The `__vaDriverInit_N_M` names in a driver file, streamed (iHD is ~43 MB),
22411
+ * with an overlap so a name split across two chunks is still found.
22412
+ */
22413
+ function readDriverInitSymbols(driverPath) {
22414
+ return new Promise((resolve) => {
22415
+ const found = /* @__PURE__ */ new Set();
22416
+ let carry = "";
22417
+ const stream = createReadStream(driverPath, {
22418
+ encoding: "latin1",
22419
+ highWaterMark: 64 * 1024
22420
+ });
22421
+ stream.on("data", (chunk) => {
22422
+ const text = carry + String(chunk);
22423
+ for (const m of text.matchAll(INIT_SYMBOL)) if (m.index + m[0].length < text.length) found.add(m[0]);
22424
+ carry = text.slice(-32);
22425
+ });
22426
+ stream.on("error", () => resolve([]));
22427
+ stream.on("end", () => {
22428
+ for (const m of carry.matchAll(INIT_SYMBOL)) found.add(m[0]);
22429
+ resolve([...found].sort());
22430
+ });
22431
+ });
22432
+ }
22433
+ /** Probe one render node: vainfo, and on failure the driver's init symbols. */
22434
+ async function probeVaapiInit(renderNode) {
22435
+ const run = await runVainfo(renderNode);
22436
+ if (run.spawnError !== null || run.exitCode === 0) return classifyVainfo(run, []);
22437
+ const driverPath = lastMatch(run.output, DRIVER_OPEN);
22438
+ return classifyVainfo(run, driverPath ? await readDriverInitSymbols(driverPath) : []);
22439
+ }
22440
+ //#endregion
22299
22441
  //#region src/kernel/hwaccel/hwaccel-resolver.ts
22300
22442
  /**
22301
22443
  * Platform-probe for hardware video decode acceleration.
@@ -22315,7 +22457,7 @@ function buildLinkChain(target, localResolver, hookup) {
22315
22457
  */
22316
22458
  function safeExistsSync(path) {
22317
22459
  try {
22318
- return fs.existsSync(path);
22460
+ return fs$1.existsSync(path);
22319
22461
  } catch {
22320
22462
  return false;
22321
22463
  }
@@ -22334,11 +22476,11 @@ function probeLinuxGpus() {
22334
22476
  if (safeExistsSync("/dev/nvidia0") || safeExistsSync("/proc/driver/nvidia/version")) signals.hasNvidiaGpu = true;
22335
22477
  try {
22336
22478
  const drmDir = "/sys/class/drm";
22337
- if (fs.existsSync(drmDir)) for (const entry of fs.readdirSync(drmDir)) {
22479
+ if (fs$1.existsSync(drmDir)) for (const entry of fs$1.readdirSync(drmDir)) {
22338
22480
  if (!entry.startsWith("card")) continue;
22339
22481
  const vendorPath = `${drmDir}/${entry}/device/vendor`;
22340
22482
  if (!safeExistsSync(vendorPath)) continue;
22341
- const vendor = fs.readFileSync(vendorPath, "utf8").trim().toLowerCase();
22483
+ const vendor = fs$1.readFileSync(vendorPath, "utf8").trim().toLowerCase();
22342
22484
  if (vendor === "0x10de") signals.hasNvidiaGpu = true;
22343
22485
  else if (vendor === "0x1002") signals.hasAmdGpu = true;
22344
22486
  else if (vendor === "0x8086") signals.hasIntelGpu = true;
@@ -22365,7 +22507,23 @@ function probePlatform() {
22365
22507
  coral: classifyCoralAccelerator(nodeCoralFs)
22366
22508
  };
22367
22509
  }
22368
- function pickBackendsForPlatform(signals) {
22510
+ /** The backends that open their device through libva on Linux. */
22511
+ var LIBVA_BACKENDS = ["vaapi", "qsv"];
22512
+ /**
22513
+ * The preference list for these signals. A `vaapi` verdict of `init-failed`
22514
+ * (libva cannot initialise the driver — D926) removes every libva-backed
22515
+ * backend and names the cause in the rationale; `ok`, `unknown` or `null`
22516
+ * change nothing.
22517
+ */
22518
+ function pickBackendsForPlatform(signals, vaapi = null) {
22519
+ const res = pickBackendsFromSignals(signals);
22520
+ if (signals.platform !== "linux" || vaapi?.state !== "init-failed") return res;
22521
+ return {
22522
+ preferred: res.preferred.filter((b) => !LIBVA_BACKENDS.includes(b)),
22523
+ rationale: `${res.rationale} ${vaapi.summary} — vaapi/qsv withheld, decode runs in software.`
22524
+ };
22525
+ }
22526
+ function pickBackendsFromSignals(signals) {
22369
22527
  switch (signals.platform) {
22370
22528
  case "darwin": return {
22371
22529
  preferred: ["videotoolbox"],
@@ -22426,13 +22584,49 @@ function resolveHwAccel(prefer) {
22426
22584
  };
22427
22585
  return pickBackendsForPlatform(probePlatform());
22428
22586
  }
22587
+ var RENDER_NODE = "/dev/dri/renderD128";
22588
+ /** Process-wide: the VA init failure is logged once per process, not per resolver. */
22589
+ var PROCESS_VAAPI_REPORT = { reported: false };
22590
+ /** Process-wide: hub-main builds one resolver per in-process addon; vainfo runs once. */
22591
+ var PROCESS_VAAPI_PROBES = /* @__PURE__ */ new Map();
22592
+ function probeVaapiOncePerProcess(renderNode) {
22593
+ const known = PROCESS_VAAPI_PROBES.get(renderNode);
22594
+ if (known) return known;
22595
+ const probe = probeVaapiInit(renderNode);
22596
+ PROCESS_VAAPI_PROBES.set(renderNode, probe);
22597
+ return probe;
22598
+ }
22429
22599
  /**
22430
22600
  * Build the `IKernelHwAccel` provider used to populate `ctx.kernel.hwaccel`.
22431
- * Thin async wrapper around the sync `resolveHwAccel` function so the
22432
- * contract matches the per-node `$hwaccel.resolve` Moleculer action.
22433
- */
22434
- function createKernelHwAccel() {
22435
- return { resolve: async (prefer) => resolveHwAccel(prefer) };
22601
+ * An auto resolve on a Linux host with a render node asks libva ONCE per
22602
+ * provider whether it can initialise the driver (D926); an explicit override
22603
+ * is never second-guessed.
22604
+ */
22605
+ function createKernelHwAccel(options = {}) {
22606
+ const probeSignals = options.probeSignals ?? probePlatform;
22607
+ const probeVaapi = options.probeVaapi ?? probeVaapiOncePerProcess;
22608
+ const reportOnce = options.reportOnce ?? PROCESS_VAAPI_REPORT;
22609
+ let vaapi = null;
22610
+ const vaapiVerdict = async () => {
22611
+ if (vaapi === null) vaapi = probeVaapi(RENDER_NODE);
22612
+ const status = await vaapi;
22613
+ if (status.state === "init-failed" && !reportOnce.reported) {
22614
+ reportOnce.reported = true;
22615
+ options.logger?.error(`hwaccel: ${status.summary} — vaapi/qsv withheld, decode runs in software`, { meta: {
22616
+ renderNode: RENDER_NODE,
22617
+ vaApiVersion: status.vaApiVersion,
22618
+ driverPath: status.driverPath,
22619
+ driverNeedsVaApi: status.driverNeedsVaApi
22620
+ } });
22621
+ }
22622
+ return status;
22623
+ };
22624
+ return { resolve: async (prefer) => {
22625
+ if (prefer === "none" || prefer !== null && prefer !== void 0 && prefer.length > 0) return resolveHwAccel(prefer);
22626
+ const signals = probeSignals();
22627
+ if (signals.platform !== "linux" || !signals.hasRenderNode) return pickBackendsForPlatform(signals);
22628
+ return pickBackendsForPlatform(signals, await vaapiVerdict());
22629
+ } };
22436
22630
  }
22437
22631
  //#endregion
22438
22632
  //#region src/kernel/inference/inference-resolver.ts
@@ -22504,21 +22698,21 @@ function sleep$1(ms) {
22504
22698
  * crashed holder) is stolen.
22505
22699
  */
22506
22700
  async function withFileLock(lockPath, fn) {
22507
- fs.mkdirSync(join(lockPath, ".."), { recursive: true });
22701
+ fs$1.mkdirSync(join(lockPath, ".."), { recursive: true });
22508
22702
  for (;;) try {
22509
- const fd = fs.openSync(lockPath, "wx");
22510
- fs.closeSync(fd);
22703
+ const fd = fs$1.openSync(lockPath, "wx");
22704
+ fs$1.closeSync(fd);
22511
22705
  break;
22512
22706
  } catch {
22513
22707
  try {
22514
- if (Date.now() - fs.statSync(lockPath).mtimeMs > LOCK_STALE_MS) fs.rmSync(lockPath, { force: true });
22708
+ if (Date.now() - fs$1.statSync(lockPath).mtimeMs > LOCK_STALE_MS) fs$1.rmSync(lockPath, { force: true });
22515
22709
  else await sleep$1(LOCK_POLL_MS);
22516
22710
  } catch {}
22517
22711
  }
22518
22712
  try {
22519
22713
  return await fn();
22520
22714
  } finally {
22521
- fs.rmSync(lockPath, { force: true });
22715
+ fs$1.rmSync(lockPath, { force: true });
22522
22716
  }
22523
22717
  }
22524
22718
  /** Coalesce in-process + serialize cross-process for one binary id. */
@@ -22576,7 +22770,7 @@ var AddonDepsManager = class {
22576
22770
  * failed or tampered download throws, and provisioning reports it.
22577
22771
  */
22578
22772
  async stageNativeDepsDeclaredBy(requirementsFile) {
22579
- if (!declaresEdgetpuDelegate(fs.readFileSync(requirementsFile, "utf8"))) return;
22773
+ if (!declaresEdgetpuDelegate(fs$1.readFileSync(requirementsFile, "utf8"))) return;
22580
22774
  await singleFlight(this.depsDir, "edgetpu-delegate", () => ensureEdgetpuDelegate(this.nodeRoot, this.logger));
22581
22775
  }
22582
22776
  getDepsDir() {
@@ -23586,7 +23780,7 @@ async function buildAddonContext(runtime, declaration, dataDir, options) {
23586
23780
  const addonId = declaration.id;
23587
23781
  const nodeDataDir = process.env["CAMSTACK_DATA"] ?? dataDir;
23588
23782
  const addonDataDir = path$1.resolve(nodeDataDir, "addons-data", addonId);
23589
- fs.mkdirSync(addonDataDir, { recursive: true });
23783
+ fs$1.mkdirSync(addonDataDir, { recursive: true });
23590
23784
  if (runtime.mode === "broker") ensureBindingSubscription(runtime.broker);
23591
23785
  const regs = getRegistries(nodeId);
23592
23786
  const workerResolver = {
@@ -23825,7 +24019,7 @@ async function buildAddonContext(runtime, declaration, dataDir, options) {
23825
24019
  value
23826
24020
  })
23827
24021
  };
23828
- const hwaccel = createKernelHwAccel();
24022
+ const hwaccel = createKernelHwAccel({ logger: scopedLogger });
23829
24023
  const inferenceEngine = createKernelInferenceEngine();
23830
24024
  return {
23831
24025
  localNodeId: nodeId,
@@ -25379,7 +25573,7 @@ function readAddonHeapDeclaration(spec) {
25379
25573
  if (cached !== void 0) return cached;
25380
25574
  let declaration = EMPTY_HEAP_DECLARATION;
25381
25575
  for (const manifestPath of [path$1.join(spec.addonDir, "package.json"), path$1.join(path$1.dirname(spec.addonDir), "package.json")]) try {
25382
- const raw = fs.readFileSync(manifestPath, "utf8");
25576
+ const raw = fs$1.readFileSync(manifestPath, "utf8");
25383
25577
  const parsed = JSON.parse(raw);
25384
25578
  const profile = extractHeapProfile(parsed, spec.addonId);
25385
25579
  const maxOldSpaceMb = extractMaxOldSpaceMb(parsed, spec.addonId);
@@ -25871,6 +26065,7 @@ function releaseRunnerGroup(pgid) {
25871
26065
  * Returns how many groups were signalled.
25872
26066
  */
25873
26067
  function signalAllRunnerGroups(signal) {
26068
+ beginRunnerShutdown();
25874
26069
  let signalled = 0;
25875
26070
  for (const [pgid, group] of ownedGroups) try {
25876
26071
  group.kill(-pgid, signal);
@@ -25878,6 +26073,21 @@ function signalAllRunnerGroups(signal) {
25878
26073
  } catch {}
25879
26074
  return signalled;
25880
26075
  }
26076
+ /**
26077
+ * Set once this process has begun an ORDERLY shutdown (hub-main's SIGTERM/SIGINT
26078
+ * handler, through {@link signalAllRunnerGroups}, which signals every runner
26079
+ * BEFORE the broker stops the process service). A runner that exits after this point is part of the
26080
+ * shutdown, not a crash: its exit is INFO and it is never respawned. Without it
26081
+ * a clean hub stop logged `ERROR Process exited (code=0)` once per runner and
26082
+ * scheduled a respawn into the dying node (CT200, 2026-10-23).
26083
+ */
26084
+ var runnerShutdownInProgress = false;
26085
+ function beginRunnerShutdown() {
26086
+ runnerShutdownInProgress = true;
26087
+ }
26088
+ function isRunnerShutdownInProgress() {
26089
+ return runnerShutdownInProgress;
26090
+ }
25881
26091
  //#endregion
25882
26092
  //#region src/kernel/moleculer/process-service.ts
25883
26093
  /**
@@ -26115,6 +26325,12 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
26115
26325
  console.error(`[process-service EXIT] runner=${runnerId} code=${String(code)} signal=${String(signal)} state=${entry.state}`);
26116
26326
  const groupReap = reapRunnerGroup(entry);
26117
26327
  if (entry.state === "stopped") return;
26328
+ if (isRunnerShutdownInProgress()) {
26329
+ entry.state = "stopped";
26330
+ emitStateChange(entry);
26331
+ capturedBroker?.logger.info(`[${runnerId}] Process exited during shutdown (code=${code}, signal=${signal})`, { tags: { runnerId } });
26332
+ return;
26333
+ }
26118
26334
  const announced = entry.announcedRefusal;
26119
26335
  entry.announcedRefusal = null;
26120
26336
  if (code === 78) {
@@ -26142,7 +26358,9 @@ function createProcessService(parentNodeId, dataDir, deps, parentTcpPort, parent
26142
26358
  }
26143
26359
  entry.state = "crashed";
26144
26360
  emitStateChange(entry);
26145
- capturedBroker?.logger.error(`[${runnerId}] Process exited (code=${code}, signal=${signal})`);
26361
+ const exitLine = `[${runnerId}] Process exited (code=${code}, signal=${signal})`;
26362
+ if (code === 0 && signal === null) capturedBroker?.logger.warn(`${exitLine} — unexpected clean exit, respawning`, { tags: { runnerId } });
26363
+ else capturedBroker?.logger.error(exitLine, { tags: { runnerId } });
26146
26364
  const decision = crashSupervisor.recordCrash(runnerId);
26147
26365
  emitRunnerEvent(EventCategory$1.ProcessCrashed, runnerId, {
26148
26366
  processId: runnerId,
@@ -26557,17 +26775,17 @@ var JobJournal = class {
26557
26775
  return path$1.join(this.jobsDir, `${id}.json`);
26558
26776
  }
26559
26777
  writeAtomic(filePath, data) {
26560
- fs.mkdirSync(path$1.dirname(filePath), { recursive: true });
26778
+ fs$1.mkdirSync(path$1.dirname(filePath), { recursive: true });
26561
26779
  const tmp = `${filePath}.tmp.${process.pid}.${Date.now()}`;
26562
- fs.writeFileSync(tmp, JSON.stringify(data, null, 2), {
26780
+ fs$1.writeFileSync(tmp, JSON.stringify(data, null, 2), {
26563
26781
  encoding: "utf-8",
26564
26782
  mode: 384
26565
26783
  });
26566
- fs.renameSync(tmp, filePath);
26784
+ fs$1.renameSync(tmp, filePath);
26567
26785
  }
26568
26786
  readIndex() {
26569
26787
  try {
26570
- const raw = JSON.parse(fs.readFileSync(this.indexPath, "utf-8"));
26788
+ const raw = JSON.parse(fs$1.readFileSync(this.indexPath, "utf-8"));
26571
26789
  if (raw && Array.isArray(raw.jobIds)) return {
26572
26790
  version: 1,
26573
26791
  jobIds: raw.jobIds
@@ -26592,7 +26810,7 @@ var JobJournal = class {
26592
26810
  }
26593
26811
  getJob(id) {
26594
26812
  try {
26595
- const parsed = lifecycleJobSchema.safeParse(JSON.parse(fs.readFileSync(this.jobPath(id), "utf-8")));
26813
+ const parsed = lifecycleJobSchema.safeParse(JSON.parse(fs$1.readFileSync(this.jobPath(id), "utf-8")));
26596
26814
  return parsed.success ? parsed.data : null;
26597
26815
  } catch {
26598
26816
  return null;
@@ -26657,14 +26875,14 @@ var StagingArea = class {
26657
26875
  }
26658
26876
  async fetchAndStage(input) {
26659
26877
  const destDir = path$1.join(this.stagingDir, input.jobId, safeSegment(input.name));
26660
- fs.rmSync(destDir, {
26878
+ fs$1.rmSync(destDir, {
26661
26879
  recursive: true,
26662
26880
  force: true
26663
26881
  });
26664
26882
  const tgz = await this.deps.fetchTarball(input.name, input.version, input.signal);
26665
26883
  if (input.signal.aborted) throw new Error("staging aborted after fetch");
26666
26884
  await this.deps.extract(tgz, destDir);
26667
- const raw = JSON.parse(fs.readFileSync(path$1.join(destDir, "package.json"), "utf-8"));
26885
+ const raw = JSON.parse(fs$1.readFileSync(path$1.join(destDir, "package.json"), "utf-8"));
26668
26886
  if (typeof raw.version !== "string" || raw.version.length === 0) throw new Error(`staging validation failed: ${input.name} staged a package.json with no version`);
26669
26887
  if (EXACT_SEMVER.test(input.version) && raw.version !== input.version) throw new Error(`staging validation failed: ${input.name} expected version ${input.version}, got ${raw.version}`);
26670
26888
  return {
@@ -26673,7 +26891,7 @@ var StagingArea = class {
26673
26891
  };
26674
26892
  }
26675
26893
  cleanup(jobId) {
26676
- fs.rmSync(path$1.join(this.stagingDir, jobId), {
26894
+ fs$1.rmSync(path$1.join(this.stagingDir, jobId), {
26677
26895
  recursive: true,
26678
26896
  force: true
26679
26897
  });
@@ -26688,13 +26906,13 @@ var StagingArea = class {
26688
26906
  sweepOrphans() {
26689
26907
  let entries;
26690
26908
  try {
26691
- entries = fs.readdirSync(this.stagingDir);
26909
+ entries = fs$1.readdirSync(this.stagingDir);
26692
26910
  } catch {
26693
26911
  return 0;
26694
26912
  }
26695
26913
  let removed = 0;
26696
26914
  for (const name of entries) try {
26697
- fs.rmSync(path$1.join(this.stagingDir, name), {
26915
+ fs$1.rmSync(path$1.join(this.stagingDir, name), {
26698
26916
  recursive: true,
26699
26917
  force: true
26700
26918
  });
@@ -26872,7 +27090,7 @@ var LifecycleJobEngine = class {
26872
27090
  * on failure → `failed`.
26873
27091
  */
26874
27092
  async reconcileJob(job) {
26875
- const exists = this.deps.stagedPathExists ?? ((p) => fs.existsSync(p));
27093
+ const exists = this.deps.stagedPathExists ?? ((p) => fs$1.existsSync(p));
26876
27094
  for (const task of job.tasks) {
26877
27095
  if (task.target === "framework") {
26878
27096
  if (!this.isTerminal(task.phase)) this.skipFrameworkTask(job, task);
@@ -26964,6 +27182,7 @@ var en_default = {
26964
27182
  "auth.session-ended": "Session ended — sign in again",
26965
27183
  "auth.access-denied": "Access denied",
26966
27184
  "auth.totp-confirm-failed": "TOTP confirmation failed — code did not match",
27185
+ "auth.person-scopes-refused": "A person is an admin, with no scope rows, or holds exactly one viewer grant",
26967
27186
  "device.certificates-unavailable": "Device certificates are not available",
26968
27187
  "device.not-found": "Device {id} not found",
26969
27188
  "device.credentials-unavailable": "Device credentials not available",
@@ -27215,6 +27434,7 @@ var it_default = {
27215
27434
  "auth.session-ended": "Sessione terminata — accedi di nuovo",
27216
27435
  "auth.access-denied": "Accesso negato",
27217
27436
  "auth.totp-confirm-failed": "Conferma TOTP non riuscita — il codice non corrisponde",
27437
+ "auth.person-scopes-refused": "Una persona è amministratore, senza righe di permesso, oppure ha esattamente un permesso visualizzatore",
27218
27438
  "device.certificates-unavailable": "I certificati dei dispositivi non sono disponibili",
27219
27439
  "device.not-found": "Dispositivo {id} non trovato",
27220
27440
  "device.credentials-unavailable": "Le credenziali del dispositivo non sono disponibili",
@@ -27485,7 +27705,7 @@ var CatalogRegistry = class {
27485
27705
  const file = path$1.join(packageDir, "i18n", `${lang}.json`);
27486
27706
  let text;
27487
27707
  try {
27488
- text = fs.readFileSync(file, "utf8");
27708
+ text = fs$1.readFileSync(file, "utf8");
27489
27709
  } catch {
27490
27710
  continue;
27491
27711
  }