openmeld 0.3.206 → 0.3.207
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{add-me-membership-BkHWMxE4.js → add-me-membership-1JHMjZoR.js} +2 -2
- package/dist/{add-me-membership-BkHWMxE4.js.map → add-me-membership-1JHMjZoR.js.map} +1 -1
- package/dist/{agents-BOTlKiwS.js → agents-CIDsThyG.js} +150 -108
- package/dist/agents-CIDsThyG.js.map +1 -0
- package/dist/{api-client-foundation-6ms5gSu8.js → api-client-foundation-D6_NXHPV.js} +1 -1
- package/dist/{api-client-foundation-DpgDs0rw.js → api-client-foundation-DSurenul.js} +3 -3
- package/dist/{api-client-foundation-DpgDs0rw.js.map → api-client-foundation-DSurenul.js.map} +1 -1
- package/dist/auth-session-B7QMhHwh.js +4 -0
- package/dist/{auth-session-BjSqMLTz.js → auth-session-CO5XtFaq.js} +266 -75
- package/dist/auth-session-CO5XtFaq.js.map +1 -0
- package/dist/{base-url-CRAYNW-4.js → base-url-BE3pFiOZ.js} +1 -1
- package/dist/{base-url-9A557X2K.js → base-url-C6sHRNGu.js} +2 -2
- package/dist/{base-url-9A557X2K.js.map → base-url-C6sHRNGu.js.map} +1 -1
- package/dist/cli-binary-manifest-DiUulkp0.js +117 -0
- package/dist/cli-binary-manifest-DiUulkp0.js.map +1 -0
- package/dist/{command-CkbzbvXy.js → command-Bzt9zgnI.js} +13 -11
- package/dist/{command-CkbzbvXy.js.map → command-Bzt9zgnI.js.map} +1 -1
- package/dist/computer-connection-BOl79Ftf.js +54 -0
- package/dist/computer-connection-BOl79Ftf.js.map +1 -0
- package/dist/computer-connection-review-BTOvbJYL.js +39 -0
- package/dist/computer-connection-review-BTOvbJYL.js.map +1 -0
- package/dist/{computer-setup-continuation-Cd9nhLQ-.js → computer-setup-continuation-DmKdhR5u.js} +4 -4
- package/dist/{computer-setup-continuation-Cd9nhLQ-.js.map → computer-setup-continuation-DmKdhR5u.js.map} +1 -1
- package/dist/control-plane-D9jDcbMZ.js +1211 -0
- package/dist/control-plane-D9jDcbMZ.js.map +1 -0
- package/dist/daemon-local-state-file-jOXuXrky.js +45 -0
- package/dist/daemon-local-state-file-jOXuXrky.js.map +1 -0
- package/dist/daemon-runtime-lease-Dd4hdHNo.js +50 -0
- package/dist/daemon-runtime-lease-Dd4hdHNo.js.map +1 -0
- package/dist/{daemon-runtime-lease-BG9g0a6Z.js → daemon-runtime-lease-y3n1K0-C.js} +1 -1
- package/dist/{daemon-service-manager-DqVtRLBY.js → daemon-service-manager-Bh0LoLed.js} +1 -1
- package/dist/{daemon-service-manager-BVipiZwK.js → daemon-service-manager-GiMCiTmu.js} +99 -85
- package/dist/daemon-service-manager-GiMCiTmu.js.map +1 -0
- package/dist/daemon-service-runtime-DQW9gSLT.js +3642 -0
- package/dist/daemon-service-runtime-DQW9gSLT.js.map +1 -0
- package/dist/{daemon-state-BwIoDq7_.js → daemon-state-C37ZtIZK.js} +11 -5
- package/dist/daemon-state-C37ZtIZK.js.map +1 -0
- package/dist/{dist-CxadJClH.js → dist-D-kJdWZE.js} +726 -579
- package/dist/dist-D-kJdWZE.js.map +1 -0
- package/dist/dist-DTG_Vqc7.js +4 -0
- package/dist/distribution-DY2fBeSW.js +72 -0
- package/dist/distribution-DY2fBeSW.js.map +1 -0
- package/dist/{elapsed-time-C7P-nWIO.js → elapsed-time-CcoM2R3N.js} +7 -4
- package/dist/{elapsed-time-C7P-nWIO.js.map → elapsed-time-CcoM2R3N.js.map} +1 -1
- package/dist/{installation-inventory-P49sTjhe.js → installation-inventory-DJlwXa1q.js} +7 -6
- package/dist/{installation-inventory-P49sTjhe.js.map → installation-inventory-DJlwXa1q.js.map} +1 -1
- package/dist/{lock-CvBnBcFK.js → lock-Dxp6o_t_.js} +56 -7
- package/dist/lock-Dxp6o_t_.js.map +1 -0
- package/dist/{openmeld-ChOHuaqH.js → openmeld-CiL4AiB0.js} +226 -21
- package/dist/openmeld-CiL4AiB0.js.map +1 -0
- package/dist/openmeld-dev.js +1 -1
- package/dist/openmeld-environment-target-NtJYJe1D.js +256 -0
- package/dist/openmeld-environment-target-NtJYJe1D.js.map +1 -0
- package/dist/{openmeld-maintenance-worker-C7WykyDt.js → openmeld-maintenance-worker-DjdmRASI.js} +9 -8
- package/dist/{openmeld-maintenance-worker-C7WykyDt.js.map → openmeld-maintenance-worker-DjdmRASI.js.map} +1 -1
- package/dist/{openmeld-tools-update-coordinator-BBZhGo1A.js → openmeld-tools-update-coordinator-D9Skj8IE.js} +52 -4013
- package/dist/openmeld-tools-update-coordinator-D9Skj8IE.js.map +1 -0
- package/dist/openmeld.js +3 -3
- package/dist/{prepare-session-executor-CLmDoHom.js → prepare-session-executor-B0NtjHEL.js} +15 -13
- package/dist/{prepare-session-executor-CLmDoHom.js.map → prepare-session-executor-B0NtjHEL.js.map} +1 -1
- package/dist/{profiles-BCecj4Pj.js → runtime-transport-QIZmAo4-.js} +936 -2127
- package/dist/runtime-transport-QIZmAo4-.js.map +1 -0
- package/dist/service-account-authorization-Dt8kGvq8.js +56 -0
- package/dist/service-account-authorization-Dt8kGvq8.js.map +1 -0
- package/dist/service-control-capabilities-BU5F75zi.js +54 -0
- package/dist/service-control-capabilities-BU5F75zi.js.map +1 -0
- package/dist/service-control-capabilities-CzUB1ovW.js +4 -0
- package/dist/upgrade-DLECkjMt.js +4 -0
- package/dist/{upgrade-l_5Tge_z.js → upgrade-NxpTydHp.js} +6 -4
- package/dist/upgrade-NxpTydHp.js.map +1 -0
- package/package.json +2 -2
- package/dist/agents-BOTlKiwS.js.map +0 -1
- package/dist/auth-session-BjSqMLTz.js.map +0 -1
- package/dist/auth-session-ahQ5VXiF.js +0 -4
- package/dist/daemon-runtime-lease-CXlGR-iA.js +0 -87
- package/dist/daemon-runtime-lease-CXlGR-iA.js.map +0 -1
- package/dist/daemon-service-manager-BVipiZwK.js.map +0 -1
- package/dist/daemon-state-BwIoDq7_.js.map +0 -1
- package/dist/dist-0boZRalP.js +0 -4
- package/dist/dist-CxadJClH.js.map +0 -1
- package/dist/lock-CvBnBcFK.js.map +0 -1
- package/dist/openmeld-ChOHuaqH.js.map +0 -1
- package/dist/openmeld-tools-update-coordinator-BBZhGo1A.js.map +0 -1
- package/dist/profiles-BCecj4Pj.js.map +0 -1
- package/dist/upgrade-BKEAZKre.js +0 -4
- package/dist/upgrade-l_5Tge_z.js.map +0 -1
|
@@ -1,25 +1,30 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { n as toDaemonRouteObservationUrl
|
|
3
|
+
import { n as toDaemonRouteObservationUrl } from "./urls-CY2uzH2-.js";
|
|
4
4
|
import { t as isLoopbackHostname } from "./loopback-hostname-DHQPKq8N.js";
|
|
5
|
-
import {
|
|
5
|
+
import { B as deviceOpenClawProfileBootstrapPath, C as isProcessIdentityAlive, H as deviceOpenClawProfileWorkspaceDir, I as accountProfileViewPath, L as accountProfileWorkspacePath, N as OPENMELD_HOME_ENV_KEY, P as accountProfileLocalMetaPath, Q as openMeldBackupsDir, S as CURRENT_PROCESS_START_IDENTITY, V as deviceOpenClawProfileDir, X as normalizeAccountKey, Z as normalizeOpenMeldProfileId, _ as resolveCliContext, a as isOpenMeldOrphanedLockError, d as runWithHeldLock, dt as resolveOpenMeldEnvPreset, ft as resolveOpenMeldRootDir, g as readCliContextState, h as listCliContextStates, ht as runtimeDir, i as isOpenMeldLockError, q as isPublishedOpenMeldHome, rt as openMeldRootDir, t as acquireLock, tt as openMeldManagedVersionBinaryPath, y as writeCliContextState, yt as systemDir } from "./lock-Dxp6o_t_.js";
|
|
6
|
+
import { Cn as toStructuredApiClientFailure, Gt as createLocalRuntimeExpectedRoutesApi, Hn as toErrorMessage$24, Ln as OPENMELD_HEADER_PROFILE_ID, Mt as createAgentProfileBindingApi, Rt as createCurrentDeviceApi, ci as agentControllerPermissionModeSchema, gr as modelCatalogSchema, li as agentControllerCollaborationModeSchema, si as openCodePermissionConfigSchema, t as OpenMeldApiClientHttpError } from "./dist-D-kJdWZE.js";
|
|
6
7
|
import { _ as canonicalizeAgentControllerRef, b as normalizeKnownBuiltinAgentControllerId, d as resolveBuiltinAgentControllerConversationKind, f as HOSTED_CENTER_AGENT_CONTROLLER_REF, g as buildAgentControllerRoutingKey, l as buildAgentControllerConversationRef, m as HOSTED_REMOTE_AGENT_CONTROLLER_REF, n as runtimeAgentControllerConversationIdMappingSpecSchema, o as runtimeStreamingModeSchema, p as HOSTED_CENTER_AGENT_CONTROLLER_REF_ID, r as runtimeAgentControllerLaunchContractSchema, s as runtimeTransportModeSchema, u as conversationPolicySchema, v as canonicalizeBuiltinAgentControllerRef, x as parseAgentControllerRef$1 } from "./controller-contract-pe3_Re-c.js";
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { r as daemonServiceLaneSchema
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
8
|
+
import { B as isOriginalErrorSafeForMessageDetails, Br as profileCapabilitiesResponseSchema, Fr as ADDITIONAL_HUMAN_PROFILE_CREATION_DISABLED_CODE, G as openMeldDaemonTaskResultOpenClawGatewayVisibilityStatusSchema, Gr as openMeldProfileIdSchema, Ir as ADDITIONAL_HUMAN_PROFILE_CREATION_DISABLED_MESSAGE, Jr as resolveCommandAgentWorkActivity, N as runtimeTransportRejectedProfileRegistrationSchema, Nr as localAgentCatalogSchema, O as runtimeTransportLookupRouteOwnerServiceEvidenceSchema, Rr as authProfileManagedRoleSchema, U as openMeldDaemonProviderAccessEvidenceSchema, Vr as profileErrorResponseSchema, W as openMeldDaemonTaskResultEnvelopeWriteSchema, _ as runtimeTransportErrorCodeSchema, _n as formatCanonicalMentionLiteral, _t as agentInteractionResolutionSchema, bn as normalizeMessageEnvelope, br as resolvePublicAgentAvailabilityCopy, i as localWakeRouteReportSchema, n as daemonExecutionCompatibilitySchema, o as runtimeTransportCapabilitiesSchema, t as CURRENT_DAEMON_EXECUTION_CONTRACT_EPOCH, xr as resolvePublicAgentFailureRecovery, z as OPENMELD_ORIGINAL_ERROR_MAX_LENGTH } from "./runtime-transport-QIZmAo4-.js";
|
|
9
|
+
import { L as openMeldToolsUpdateAttemptSchema, St as profileWorkspaceModeSchema, V as openMeldToolsUpdateRequestSourceSchema, _ as providerDispatchRuntimeContextSchema, a as openMeldDaemonControlPlaneResponseSchema, g as skippedDaemonProfileSchema, ht as normalizeOptionalWorkingDirectory, i as openMeldDaemonControlPlaneRequestSchema, mt as agentProfileIdSchema, pt as MAX_PROFILE_WORKING_DIRECTORY_LENGTH, y as conversationExecutionStateSchema } from "./control-plane-D9jDcbMZ.js";
|
|
10
|
+
import { r as daemonServiceLaneSchema } from "./service-contract-CRyDcIIf.js";
|
|
11
|
+
import { $ as RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS$1, F as DAEMON_STREAM_CONNECT_TIMEOUT_MS$1, H as MAX_HEARTBEAT_INTERVAL_MS$2, I as DAEMON_STREAM_KEEPALIVE_INTERVAL_MS$1, J as PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS$1, K as OPENCLAW_CLI_TIMEOUT_MS$1, L as DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS$1, M as CATALOG_SYNC_RETRY_INTERVAL_MS$1, N as CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS$1, P as DAEMON_RUNTIME_CONTRACT_EPOCH$1, Q as RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS$1, R as DEFAULT_GATEWAY_CHAIN_TIMEOUT_MS$1, V as HEARTBEAT_RESPONSE_TIMEOUT_MS$1, W as MIN_HEARTBEAT_INTERVAL_MS$2, Y as REGISTER_RESPONSE_TIMEOUT_MS$1, Z as RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS$1, p as hasPendingComputerSetupContinuation, q as PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS$1, u as getAuthSessionState, z as DEFAULT_HEARTBEAT_INTERVAL_MS$1 } from "./auth-session-CO5XtFaq.js";
|
|
12
|
+
import { n as resolveOpenMeldDistribution, t as isBinaryDistribution } from "./distribution-DY2fBeSW.js";
|
|
13
|
+
import { r as readDaemonRuntimeLease } from "./daemon-runtime-lease-Dd4hdHNo.js";
|
|
14
|
+
import { $ as readManagedCliInstallation, A as prepareDaemonServiceBundle, B as resolveDaemonServiceArtifact, Bt as readDaemonServiceContract, C as daemonServiceExecutableWrapperPath, Ct as resolveDaemonServiceUpdateWorkerLaunchdPlistPath, D as ensureDaemonServiceStableBinaryExecutable, Dt as resolveDaemonServiceUpdateWorkerWindowsScriptPath, E as discardPreparedDaemonServiceBundle, Et as resolveDaemonServiceUpdateWorkerSystemdUnitPath, F as restoreDaemonActiveBundleStateSnapshot, Ft as requestLocalSyncRouteCatalog, I as runAuditedServiceManagerCarrierMutation, L as verifyDaemonActiveBundleIntegrity, Lt as clearDaemonServiceContract, N as resolveDaemonBundleEntryPathFromState, Nt as requestLocalDaemonServiceUpdateReadiness, O as ensureDaemonServiceUpdateWorkerBinaryExecutable, P as resolveInstalledDaemonBundleFingerprint, Pt as requestLocalDaemonShutdown, Q as pruneManagedInstallVersions, R as writeDaemonServiceExecutableWrapper, Rt as isDaemonServiceContractIdentityReusable, S as daemonServiceBinaryExecutablePath, St as resolveDaemonServiceUpdateWorkerIdentity, T as daemonServiceUpdateWorkerBinaryPath, Tt as resolveDaemonServiceUpdateWorkerSystemdTimerUnitPath, U as readLatestDaemonLifecycleConnectionStateEvent, V as emitDaemonLifecycleEvent, Vt as upsertDaemonServiceContract, W as readLatestDaemonLifecycleOriginEvent, _ as matchesExpectedDaemonServiceManagerDefinition, a as resolveDaemonRuntimeState, at as persistPendingDaemonServiceUpdate, bt as daemonServiceUpdateWorkerNpmEntryPath, c as resolveObservedDaemonRuntimeStatus, ct as buildNextVersionState, d as inspectLegacySharedDaemonService, et as resolveCliSelfVersion, f as listDaemonOwnedProcesses, ft as fetchLatestPackageInfo, g as assertDaemonMaintenanceInstallationOwnership, gt as resolveBundledServiceRelease, ht as writeVersionState, i as readCurrentObservedDaemonRuntimeStatus, it as completePendingDaemonServiceUpdate, j as readDaemonActiveBundleState, jt as LocalDaemonControlPlaneClientError, k as isDaemonBundleSourceAllowedForLane, l as resolveObservedRuntimeCommandEntryPath, lt as compareSemver, m as normalizeDaemonCommandPath, mt as readVersionState, n as getEffectiveDaemonRuntimeStatus, nt as OPENMELD_VERSION, o as resolveDaemonServiceManagerForRuntimeState, pt as isPlainReleaseVersion, q as runDaemonServiceManagerAction, r as readCurrentDaemonRuntimeContext, rt as DAEMON_SERVICE_UPDATE_JOB_SCHEMA, s as waitForDaemonSystemServiceToStop, st as readPendingDaemonServiceUpdate, t as clearDaemonRuntimeStateIfDefinitelyStopped, tt as withManagedInstallTransaction, u as cleanupLegacySharedDaemonServiceState, vt as INDEPENDENT_MAINTENANCE_REGISTRATION, w as daemonServiceLauncherPath, wt as resolveDaemonServiceUpdateWorkerSystemdPathUnitPath, x as clearDaemonServiceUpdateWorkerBinaryExecutable, xt as hasIndependentMaintenanceRegistration, y as activateDaemonServiceBundle, yt as configureDaemonMaintenanceEnvironment, z as writeDaemonServiceLauncher, zt as isUnsafeProductionDeviceId } from "./daemon-service-runtime-DQW9gSLT.js";
|
|
12
15
|
import { i as windowsTaskActionArguments, n as runWindowsUserTask, r as windowsPowerShellPath } from "./windows-user-task-DqJWtlAm.js";
|
|
13
|
-
import { C as updateConfiguredDeviceRuntimeState, T as updateConfiguredSkillsConfig, _ as getConfiguredViewCustomization, a as resolveBaseUrl, c as resolveExplicitGatewayUrlOrThrow, d as createDefaultRuntimeAgentControllerSettings, g as getConfiguredSkillsConfig, h as getConfiguredOpenMeldToolsMaintenance, i as normalizeGatewayBaseUrlOrNull, o as resolveBaseUrlOrNull, p as getConfiguredDeviceRuntimeState,
|
|
14
|
-
import { n as
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
16
|
+
import { C as updateConfiguredDeviceRuntimeState, T as updateConfiguredSkillsConfig, _ as getConfiguredViewCustomization, a as resolveBaseUrl, c as resolveExplicitGatewayUrlOrThrow, d as createDefaultRuntimeAgentControllerSettings, g as getConfiguredSkillsConfig, h as getConfiguredOpenMeldToolsMaintenance, i as normalizeGatewayBaseUrlOrNull, o as resolveBaseUrlOrNull, p as getConfiguredDeviceRuntimeState, v as getRuntimeConfigReadHealth, x as setConfiguredOpenMeldToolsMaintenance, y as resolveRuntimeSkillsCustomTargetId } from "./base-url-C6sHRNGu.js";
|
|
17
|
+
import { n as writeDaemonLocalStateFile, t as readDaemonLocalStateFile } from "./daemon-local-state-file-jOXuXrky.js";
|
|
18
|
+
import { A as getDaemonStatus, B as restoreDaemonInstallStateSnapshot, F as readDaemonServiceLifecycleLockMetaWithCleanup, I as readDaemonServiceRuntimeSnapshot, V as rotateDaemonControlPlaneTokenIfExpired, W as withDaemonServiceReconcileLock, _ as daemonRuntimeStateRootPath, a as DAEMON_SERVICE_RUNTIME_MODE_ENV, f as daemonLifecycleJournalPath, h as daemonRuntimeRootPath, i as DAEMON_SERVICE_RUNTIME_DETACHED_ENV, j as installDaemon, m as daemonRuntimeDataPath, n as DAEMON_SERVICE_RUNTIME_AUTO_START_ENV, r as DAEMON_SERVICE_RUNTIME_CONTROLLER_ENV, s as DAEMON_SERVICE_RUNTIME_SYSTEM_SERVICE_ENV } from "./daemon-state-C37ZtIZK.js";
|
|
19
|
+
import { O as assertSafePublishedProductionServiceRegistrationMutation, S as resolveDaemonServiceManager, T as waitForLaunchdJobUnloaded, a as disableDaemonServiceAutostartIfConfigured, c as getDaemonSystemServiceLogPath, o as formatDaemonServiceJobDiagnosticsEvidence, s as getDaemonServiceLaunchdLabel, v as readDaemonServiceStartupPolicyCurrent, w as startLaunchdService } from "./daemon-service-manager-GiMCiTmu.js";
|
|
20
|
+
import { a as formatOpenMeldCliCommand, c as formatOpenMeldCliTextBlock, i as formatInlineOpenMeldCliCommands, n as resolveOpenMeldEnvironmentTargetFromEnv, o as formatOpenMeldCliCommands, r as resolveAuthBaseUrl, t as resolveOpenMeldEnvironmentTarget } from "./openmeld-environment-target-NtJYJe1D.js";
|
|
21
|
+
import { n as toErrorMessage$25, t as sleep } from "./dist-o3UL1EGQ.js";
|
|
22
|
+
import { c as buildRequestAuthHeaders, d as buildOpenMeldRequestContextFromProfile, n as fetchSpaceRequestWithTimeout, s as buildOpenMeldRequestContextHeadersWithAuth, t as createCliApiClientFoundation } from "./api-client-foundation-DSurenul.js";
|
|
18
23
|
import { createRequire } from "node:module";
|
|
19
24
|
import { createHash, randomUUID } from "node:crypto";
|
|
20
25
|
import { homedir, loadavg, tmpdir, userInfo } from "node:os";
|
|
21
|
-
import
|
|
22
|
-
import { access,
|
|
26
|
+
import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, parse, relative, resolve, sep } from "node:path";
|
|
27
|
+
import { access, chmod, copyFile, cp, mkdir, mkdtemp, open, readFile, readdir, realpath, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
23
28
|
import * as z$1 from "zod/v4";
|
|
24
29
|
import { accessSync, constants, existsSync, readFileSync, realpathSync, statSync, watch } from "node:fs";
|
|
25
30
|
import process$1 from "node:process";
|
|
@@ -27,8 +32,7 @@ import { execFile, spawn } from "node:child_process";
|
|
|
27
32
|
import { setTimeout as setTimeout$1 } from "node:timers/promises";
|
|
28
33
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
29
34
|
import { promisify } from "node:util";
|
|
30
|
-
import {
|
|
31
|
-
import { connect, createConnection, createServer } from "node:net";
|
|
35
|
+
import { connect, createServer } from "node:net";
|
|
32
36
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
33
37
|
import { createOpencodeClient } from "@opencode-ai/sdk/v2";
|
|
34
38
|
//#region ../../packages/schemas/dist/agent-controller-brand.js
|
|
@@ -171,172 +175,6 @@ const daemonRouteCatalogCacheSchema = z$1.discriminatedUnion("v", [
|
|
|
171
175
|
});
|
|
172
176
|
});
|
|
173
177
|
//#endregion
|
|
174
|
-
//#region ../../packages/schemas/dist/schemas/daemon/service-update-job.js
|
|
175
|
-
const OPENMELD_DAEMON_SERVICE_UPDATE_JOB_SCHEMA = "openmeld-daemon-service-update-job-v2";
|
|
176
|
-
const daemonServiceUpdatePreparedBundleSchema = z$1.strictObject({
|
|
177
|
-
v: z$1.literal(2),
|
|
178
|
-
schema: z$1.literal("openmeld-daemon-active-bundle-v2"),
|
|
179
|
-
bundleId: z$1.string().min(1),
|
|
180
|
-
daemonVersion: z$1.string().min(1),
|
|
181
|
-
entryScriptRelativePath: z$1.string().min(1),
|
|
182
|
-
bundleFormat: z$1.enum([
|
|
183
|
-
"legacy_linked_v1",
|
|
184
|
-
"self_contained_v1",
|
|
185
|
-
"binary_v1"
|
|
186
|
-
]),
|
|
187
|
-
sourceEntryScriptPath: z$1.string().min(1),
|
|
188
|
-
sourcePackageRootPath: z$1.string().min(1),
|
|
189
|
-
sourceDistRootPath: z$1.string().min(1),
|
|
190
|
-
sourceDistFingerprint: z$1.string().min(1).nullable().optional(),
|
|
191
|
-
sourceKind: z$1.enum([
|
|
192
|
-
"workspace",
|
|
193
|
-
"package_install",
|
|
194
|
-
"npx_cache",
|
|
195
|
-
"unknown"
|
|
196
|
-
]),
|
|
197
|
-
createdAt: z$1.iso.datetime({ offset: true }),
|
|
198
|
-
updatedAt: z$1.iso.datetime({ offset: true })
|
|
199
|
-
});
|
|
200
|
-
const daemonServiceUpdateJobBodySchema = z$1.strictObject({
|
|
201
|
-
attempts: z$1.number().int().nonnegative(),
|
|
202
|
-
desiredState: z$1.enum(["background", "stopped"]),
|
|
203
|
-
errorMessage: z$1.string().min(1).nullable(),
|
|
204
|
-
jobId: z$1.string().min(1),
|
|
205
|
-
preparedBundle: daemonServiceUpdatePreparedBundleSchema,
|
|
206
|
-
requestedAt: z$1.iso.datetime({ offset: true }),
|
|
207
|
-
targetVersion: z$1.string().min(1),
|
|
208
|
-
updatedAt: z$1.iso.datetime({ offset: true }),
|
|
209
|
-
urgency: z$1.enum(["available", "required"])
|
|
210
|
-
});
|
|
211
|
-
const daemonServiceUpdateJobV1Schema = daemonServiceUpdateJobBodySchema.extend({
|
|
212
|
-
v: z$1.literal(1),
|
|
213
|
-
schema: z$1.literal("openmeld-daemon-service-update-job-v1"),
|
|
214
|
-
status: z$1.enum([
|
|
215
|
-
"scheduled",
|
|
216
|
-
"running",
|
|
217
|
-
"completed",
|
|
218
|
-
"failed"
|
|
219
|
-
])
|
|
220
|
-
});
|
|
221
|
-
const daemonServiceUpdateJobSchema = daemonServiceUpdateJobBodySchema.extend({
|
|
222
|
-
v: z$1.literal(2),
|
|
223
|
-
schema: z$1.literal(OPENMELD_DAEMON_SERVICE_UPDATE_JOB_SCHEMA),
|
|
224
|
-
phase: openMeldToolsUpdateOperationPhaseSchema,
|
|
225
|
-
requestSource: openMeldToolsUpdateRequestSourceSchema
|
|
226
|
-
});
|
|
227
|
-
const storedDaemonServiceUpdateJobSchema = z$1.discriminatedUnion("v", [daemonServiceUpdateJobV1Schema, daemonServiceUpdateJobSchema]);
|
|
228
|
-
//#endregion
|
|
229
|
-
//#region ../../packages/schemas/dist/schemas/http/cli-binary-manifest.js
|
|
230
|
-
const SHA256_HEX_PATTERN = /^[a-f0-9]{64}$/u;
|
|
231
|
-
function isBase64(value) {
|
|
232
|
-
if (value.length === 0 || value.length % 4 !== 0) return false;
|
|
233
|
-
let contentEnd = value.length;
|
|
234
|
-
if (value.endsWith("==")) contentEnd -= 2;
|
|
235
|
-
else if (value.endsWith("=")) contentEnd -= 1;
|
|
236
|
-
for (let index = 0; index < contentEnd; index += 1) {
|
|
237
|
-
const code = value.charCodeAt(index);
|
|
238
|
-
if (!(code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 43 || code === 47)) return false;
|
|
239
|
-
}
|
|
240
|
-
return true;
|
|
241
|
-
}
|
|
242
|
-
const cliBinaryArtifactSchema = z$1.object({
|
|
243
|
-
sha256: z$1.string().regex(SHA256_HEX_PATTERN),
|
|
244
|
-
sizeBytes: z$1.number().int().positive(),
|
|
245
|
-
url: z$1.url()
|
|
246
|
-
});
|
|
247
|
-
const cliBinaryArchiveTransportSchema = z$1.object({
|
|
248
|
-
archiveFormat: z$1.literal("gzip"),
|
|
249
|
-
archiveSha256: z$1.string().regex(SHA256_HEX_PATTERN),
|
|
250
|
-
archiveSizeBytes: z$1.number().int().positive(),
|
|
251
|
-
archiveUrl: z$1.url()
|
|
252
|
-
});
|
|
253
|
-
cliBinaryArtifactSchema.extend(cliBinaryArchiveTransportSchema.shape);
|
|
254
|
-
const cliBinaryDeltaPatchSchema = z$1.object({
|
|
255
|
-
baseSha256: z$1.string().regex(SHA256_HEX_PATTERN),
|
|
256
|
-
baseSizeBytes: z$1.number().int().positive(),
|
|
257
|
-
blockSizeBytes: z$1.literal(4096),
|
|
258
|
-
patchFormat: z$1.literal("block-ranges-v1"),
|
|
259
|
-
schemaVersion: z$1.literal(1),
|
|
260
|
-
segments: z$1.array(z$1.object({
|
|
261
|
-
dataBase64: z$1.string().min(4).refine(isBase64, "invalid base64"),
|
|
262
|
-
offset: z$1.number().int().nonnegative()
|
|
263
|
-
})).max(1e5),
|
|
264
|
-
targetSha256: z$1.string().regex(SHA256_HEX_PATTERN),
|
|
265
|
-
targetSizeBytes: z$1.number().int().positive()
|
|
266
|
-
});
|
|
267
|
-
const cliBinaryDeltaTransportSchema = z$1.object({
|
|
268
|
-
fromSha256: z$1.string().regex(SHA256_HEX_PATTERN),
|
|
269
|
-
fromSizeBytes: z$1.number().int().positive(),
|
|
270
|
-
fromVersion: z$1.string().trim().min(1),
|
|
271
|
-
patchCompression: z$1.literal("gzip"),
|
|
272
|
-
patchFormat: z$1.literal("block-ranges-v1"),
|
|
273
|
-
patchPayloadSizeBytes: z$1.number().int().positive(),
|
|
274
|
-
patchSha256: z$1.string().regex(SHA256_HEX_PATTERN),
|
|
275
|
-
patchSizeBytes: z$1.number().int().positive(),
|
|
276
|
-
patchUrl: z$1.url()
|
|
277
|
-
});
|
|
278
|
-
const cliBinaryReleaseSchema = cliBinaryArtifactSchema.extend({
|
|
279
|
-
archiveFormat: cliBinaryArchiveTransportSchema.shape.archiveFormat.optional(),
|
|
280
|
-
archiveSha256: cliBinaryArchiveTransportSchema.shape.archiveSha256.optional(),
|
|
281
|
-
archiveSizeBytes: cliBinaryArchiveTransportSchema.shape.archiveSizeBytes.optional(),
|
|
282
|
-
archiveUrl: cliBinaryArchiveTransportSchema.shape.archiveUrl.optional(),
|
|
283
|
-
codeIdentifier: z$1.string().trim().min(1).optional(),
|
|
284
|
-
deltas: z$1.array(cliBinaryDeltaTransportSchema).max(8).optional(),
|
|
285
|
-
teamIdentifier: z$1.string().trim().min(1).optional()
|
|
286
|
-
}).superRefine((release, context) => {
|
|
287
|
-
const archiveFields = [
|
|
288
|
-
release.archiveFormat,
|
|
289
|
-
release.archiveSha256,
|
|
290
|
-
release.archiveSizeBytes,
|
|
291
|
-
release.archiveUrl
|
|
292
|
-
];
|
|
293
|
-
if (!(archiveFields.every((value) => value === void 0) || archiveFields.every((value) => value !== void 0))) context.addIssue({
|
|
294
|
-
code: "custom",
|
|
295
|
-
message: "compressed transport fields must be provided together"
|
|
296
|
-
});
|
|
297
|
-
if (release.codeIdentifier === void 0 !== (release.teamIdentifier === void 0)) context.addIssue({
|
|
298
|
-
code: "custom",
|
|
299
|
-
message: "signature identity fields must be provided together"
|
|
300
|
-
});
|
|
301
|
-
const deltaBases = /* @__PURE__ */ new Set();
|
|
302
|
-
for (const delta of release.deltas ?? []) {
|
|
303
|
-
const baseKey = `${delta.fromVersion}:${delta.fromSha256}`;
|
|
304
|
-
if (deltaBases.has(baseKey)) {
|
|
305
|
-
context.addIssue({
|
|
306
|
-
code: "custom",
|
|
307
|
-
message: "delta base records must be unique"
|
|
308
|
-
});
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
deltaBases.add(baseKey);
|
|
312
|
-
}
|
|
313
|
-
});
|
|
314
|
-
const binaryPlatformsSchema = z$1.record(z$1.string().trim().min(1), cliBinaryReleaseSchema).refine((platforms) => Object.keys(platforms).length > 0, { message: "at least one platform is required" });
|
|
315
|
-
const cliBinaryServiceReleaseSchema = z$1.object({
|
|
316
|
-
platforms: binaryPlatformsSchema,
|
|
317
|
-
version: z$1.string().trim().min(1)
|
|
318
|
-
});
|
|
319
|
-
const cliBinaryManifestSchema = z$1.object({
|
|
320
|
-
channels: z$1.object({ stable: z$1.object({
|
|
321
|
-
minRequiredCliVersion: z$1.string().trim().min(1).nullable().optional(),
|
|
322
|
-
platforms: binaryPlatformsSchema,
|
|
323
|
-
service: cliBinaryServiceReleaseSchema.optional(),
|
|
324
|
-
version: z$1.string().trim().min(1)
|
|
325
|
-
}).superRefine((stable, context) => {
|
|
326
|
-
if (!stable.service) return;
|
|
327
|
-
for (const platform of Object.keys(stable.platforms)) if (!stable.service.platforms[platform]) context.addIssue({
|
|
328
|
-
code: "custom",
|
|
329
|
-
path: [
|
|
330
|
-
"service",
|
|
331
|
-
"platforms",
|
|
332
|
-
platform
|
|
333
|
-
],
|
|
334
|
-
message: "a Service artifact is required for every CLI platform"
|
|
335
|
-
});
|
|
336
|
-
}) }),
|
|
337
|
-
schemaVersion: z$1.literal(1)
|
|
338
|
-
});
|
|
339
|
-
//#endregion
|
|
340
178
|
//#region ../../packages/schemas/dist/schemas/http/daemon-route-observation.js
|
|
341
179
|
const daemonRouteObservationRouteSchema = z$1.discriminatedUnion("online", [z$1.strictObject({
|
|
342
180
|
online: z$1.literal(true),
|
|
@@ -365,186 +203,6 @@ const daemonRouteObservationResponseSchema = z$1.strictObject({
|
|
|
365
203
|
route: daemonRouteObservationRouteSchema
|
|
366
204
|
});
|
|
367
205
|
//#endregion
|
|
368
|
-
//#region src/runtime/cli-entry-command.ts
|
|
369
|
-
const OPENMELD_CLI_COMMAND = "openmeld";
|
|
370
|
-
const OPENMELD_CLI_NPX_COMMAND = "npx -y openmeld@latest";
|
|
371
|
-
const OPENMELD_SETUP_FOLLOW_UP_CLI_COMMAND_ENV = "OPENMELD_SETUP_FOLLOW_UP_CLI_COMMAND";
|
|
372
|
-
const OPENMELD_USER_FACING_CLI_COMMAND_ENV$1 = "OPENMELD_USER_FACING_CLI_COMMAND";
|
|
373
|
-
const OPENMELD_TOP_LEVEL_COMMANDS = [
|
|
374
|
-
"adapter",
|
|
375
|
-
"agents",
|
|
376
|
-
"auth",
|
|
377
|
-
"computer",
|
|
378
|
-
"daemon",
|
|
379
|
-
"doctor",
|
|
380
|
-
"help",
|
|
381
|
-
"login",
|
|
382
|
-
"profile",
|
|
383
|
-
"profiles",
|
|
384
|
-
"prompt",
|
|
385
|
-
"reset",
|
|
386
|
-
"send",
|
|
387
|
-
"service",
|
|
388
|
-
"setup",
|
|
389
|
-
"skills",
|
|
390
|
-
"space",
|
|
391
|
-
"start",
|
|
392
|
-
"tail",
|
|
393
|
-
"upgrade",
|
|
394
|
-
"view",
|
|
395
|
-
"whoami"
|
|
396
|
-
];
|
|
397
|
-
const OPENMELD_COMMAND_PREFIX_RE$1 = /^openmeld(?=$|\s)/u;
|
|
398
|
-
const OPENMELD_COMMAND_LINE_RE = /^(?<prefix>\s*(?:(?:[$*-])\s+|\d+\)\s+)??)(?<command>openmeld(?=$|\s).*)$/u;
|
|
399
|
-
const OPENMELD_COMMAND_AFTER_PIPE_RE = /^(?<prefix>.*\|\s+)(?<command>openmeld(?=$|\s).*)$/u;
|
|
400
|
-
const INLINE_OPENMELD_COMMAND_RE = /`(openmeld(?: [^`]*)?)`/gu;
|
|
401
|
-
const CLI_OPTION_NAME_RE = /^[a-z][a-z0-9-]*$/u;
|
|
402
|
-
const FIRST_CLI_OPERAND_OR_OPTION_RE = /^(?<commandPath>.*?)(?<tail>\s+(?:--|<).*)$/u;
|
|
403
|
-
const INLINE_OPENMELD_TOP_LEVEL_MENTION_RE = new RegExp(`\\bats (?<command>${OPENMELD_TOP_LEVEL_COMMANDS.join("|")})\\b`, "gu");
|
|
404
|
-
const NEWLINE_SPLIT_RE = /\r?\n/u;
|
|
405
|
-
const WHITESPACE_SPLIT_RE = /\s+/u;
|
|
406
|
-
const PROFILE_AWARE_TOP_LEVEL_COMMANDS = /* @__PURE__ */ new Set(["whoami"]);
|
|
407
|
-
const PROFILE_AWARE_SPACE_COMMANDS = /* @__PURE__ */ new Set([
|
|
408
|
-
"add-me",
|
|
409
|
-
"add-agents",
|
|
410
|
-
"add-human-profiles",
|
|
411
|
-
"add-members",
|
|
412
|
-
"contract",
|
|
413
|
-
"create",
|
|
414
|
-
"delete",
|
|
415
|
-
"guide",
|
|
416
|
-
"history",
|
|
417
|
-
"join",
|
|
418
|
-
"leave",
|
|
419
|
-
"list",
|
|
420
|
-
"password",
|
|
421
|
-
"publication",
|
|
422
|
-
"remove-members",
|
|
423
|
-
"result",
|
|
424
|
-
"send",
|
|
425
|
-
"status",
|
|
426
|
-
"updates",
|
|
427
|
-
"watch"
|
|
428
|
-
]);
|
|
429
|
-
const SPACE_PARENT_OPTIONS_WITH_VALUE = /* @__PURE__ */ new Set(["--gateway-url"]);
|
|
430
|
-
function resolveUserFacingCliEntryCommand(input = {}) {
|
|
431
|
-
const explicitCommand = normalizeText$12((input.env ?? process$1.env)[OPENMELD_USER_FACING_CLI_COMMAND_ENV$1]);
|
|
432
|
-
if (explicitCommand.length > 0) return explicitCommand;
|
|
433
|
-
return isNpxCliInvocation(input) ? OPENMELD_CLI_NPX_COMMAND : OPENMELD_CLI_COMMAND;
|
|
434
|
-
}
|
|
435
|
-
function resolveSetupFollowUpCliEntryCommand(input = {}) {
|
|
436
|
-
const setupCommand = normalizeText$12((input.env ?? process$1.env)[OPENMELD_SETUP_FOLLOW_UP_CLI_COMMAND_ENV]);
|
|
437
|
-
if (setupCommand.length > 0) return setupCommand;
|
|
438
|
-
return resolveUserFacingCliEntryCommand(input);
|
|
439
|
-
}
|
|
440
|
-
function formatOpenMeldCliCommand(command, input = {}) {
|
|
441
|
-
if (!OPENMELD_COMMAND_PREFIX_RE$1.test(command)) return command;
|
|
442
|
-
return command.replace(OPENMELD_COMMAND_PREFIX_RE$1, resolveUserFacingCliEntryCommand(input));
|
|
443
|
-
}
|
|
444
|
-
function formatOpenMeldCliCommands(commands, input = {}) {
|
|
445
|
-
return commands.map((command) => formatOpenMeldCliLine(command, input));
|
|
446
|
-
}
|
|
447
|
-
function formatProfileAwareOpenMeldCliCommand(command, input = {}) {
|
|
448
|
-
return formatOpenMeldCliCommand(applyProfileAwareCommandScope(command, input), input);
|
|
449
|
-
}
|
|
450
|
-
function formatProfileAwareOpenMeldCliCommands(commands, input = {}) {
|
|
451
|
-
return commands.map((command) => formatProfileAwareOpenMeldCliCommand(command, input));
|
|
452
|
-
}
|
|
453
|
-
function formatInlineOpenMeldCliCommands(text, input = {}) {
|
|
454
|
-
return text.replace(INLINE_OPENMELD_COMMAND_RE, (_, command) => {
|
|
455
|
-
return `\`${formatOpenMeldCliCommand(command, input)}\``;
|
|
456
|
-
});
|
|
457
|
-
}
|
|
458
|
-
function formatOpenMeldCliLine(text, input = {}) {
|
|
459
|
-
const inlineFormatted = formatInlineOpenMeldCliCommands(text, input);
|
|
460
|
-
const lineMatch = OPENMELD_COMMAND_LINE_RE.exec(inlineFormatted);
|
|
461
|
-
if (lineMatch?.groups?.command) return formatBareOpenMeldCliMentions(`${lineMatch.groups.prefix ?? ""}${formatOpenMeldCliCommand(lineMatch.groups.command, input)}`, input);
|
|
462
|
-
const pipeMatch = OPENMELD_COMMAND_AFTER_PIPE_RE.exec(inlineFormatted);
|
|
463
|
-
if (pipeMatch?.groups?.command) return formatBareOpenMeldCliMentions(`${pipeMatch.groups.prefix}${formatOpenMeldCliCommand(pipeMatch.groups.command, input)}`, input);
|
|
464
|
-
return formatBareOpenMeldCliMentions(inlineFormatted, input);
|
|
465
|
-
}
|
|
466
|
-
function formatOpenMeldCliTextBlock(text, input = {}) {
|
|
467
|
-
return text.split(NEWLINE_SPLIT_RE).map((line) => formatOpenMeldCliLine(line, input)).join("\n");
|
|
468
|
-
}
|
|
469
|
-
function isNpxCliInvocation(input) {
|
|
470
|
-
const env = input.env ?? process$1.env;
|
|
471
|
-
const argv = input.argv ?? process$1.argv;
|
|
472
|
-
const npmCommand = normalizeText$12(env.npm_command).toLowerCase();
|
|
473
|
-
const npmExecPath = normalizePath(env.npm_execpath);
|
|
474
|
-
const npmUserAgent = normalizeText$12(env.npm_config_user_agent).toLowerCase();
|
|
475
|
-
if (npmCommand === "exec" && npmExecTargetIsOpenMeldCli(env) && (npmUserAgent.startsWith("npm/") || npmExecPath.includes("/npm/") || npmExecPath.endsWith("/npm-cli.js"))) return true;
|
|
476
|
-
const scriptPath = normalizePath(argv[1]);
|
|
477
|
-
return scriptPath.includes("/.npm/") && scriptPath.includes("_npx");
|
|
478
|
-
}
|
|
479
|
-
function npmExecTargetIsOpenMeldCli(env) {
|
|
480
|
-
return normalizeText$12(env.npm_lifecycle_script).replaceAll("\"", "") === OPENMELD_CLI_COMMAND;
|
|
481
|
-
}
|
|
482
|
-
function formatBareOpenMeldCliMentions(text, input = {}) {
|
|
483
|
-
return text.replace(INLINE_OPENMELD_TOP_LEVEL_MENTION_RE, (_, command) => {
|
|
484
|
-
return formatOpenMeldCliCommand(`openmeld ${command}`, input);
|
|
485
|
-
});
|
|
486
|
-
}
|
|
487
|
-
function applyProfileAwareCommandScope(command, input) {
|
|
488
|
-
if (!OPENMELD_COMMAND_PREFIX_RE$1.test(command)) return command;
|
|
489
|
-
let scopedCommand = command.trimEnd();
|
|
490
|
-
const profileId = normalizeText$12(input.profileId ?? void 0);
|
|
491
|
-
if (profileId.length > 0) scopedCommand = appendCliOption(scopedCommand, "profile", profileId);
|
|
492
|
-
if (input.resolvedView === "agent") scopedCommand = appendCliOption(scopedCommand, "view", "agent");
|
|
493
|
-
return scopedCommand;
|
|
494
|
-
}
|
|
495
|
-
function appendCliOption(command, optionName, value) {
|
|
496
|
-
if (!CLI_OPTION_NAME_RE.test(optionName) || hasCliOption(command, optionName)) return command;
|
|
497
|
-
if (optionName === "profile") return insertCliOptionBeforeFirstOperandOrOption(command, optionName, value);
|
|
498
|
-
return `${command} --${optionName} ${value}`;
|
|
499
|
-
}
|
|
500
|
-
function insertCliOptionBeforeFirstOperandOrOption(command, optionName, value) {
|
|
501
|
-
if (optionName !== "profile") {
|
|
502
|
-
const match = FIRST_CLI_OPERAND_OR_OPTION_RE.exec(command);
|
|
503
|
-
if (!(match?.groups?.commandPath && match.groups.tail)) return `${command} --${optionName} ${value}`;
|
|
504
|
-
return `${match.groups.commandPath} --${optionName} ${value}${match.groups.tail}`;
|
|
505
|
-
}
|
|
506
|
-
const tokens = command.trim().split(WHITESPACE_SPLIT_RE);
|
|
507
|
-
const insertionIndex = resolveProfileOptionInsertionIndex(tokens);
|
|
508
|
-
if (insertionIndex === null) return command;
|
|
509
|
-
return [
|
|
510
|
-
...tokens.slice(0, insertionIndex),
|
|
511
|
-
`--${optionName}`,
|
|
512
|
-
value,
|
|
513
|
-
...tokens.slice(insertionIndex)
|
|
514
|
-
].join(" ");
|
|
515
|
-
}
|
|
516
|
-
function hasCliOption(command, optionName) {
|
|
517
|
-
return new RegExp(`(?:^|\\s)--${optionName}(?:=|\\s|$)`, "u").test(command);
|
|
518
|
-
}
|
|
519
|
-
function resolveProfileOptionInsertionIndex(tokens) {
|
|
520
|
-
if (tokens[0] !== OPENMELD_CLI_COMMAND) return null;
|
|
521
|
-
const topLevelCommand = tokens[1] ?? "";
|
|
522
|
-
if (PROFILE_AWARE_TOP_LEVEL_COMMANDS.has(topLevelCommand)) return 2;
|
|
523
|
-
if (topLevelCommand !== "space") return null;
|
|
524
|
-
let index = 2;
|
|
525
|
-
while (index < tokens.length) {
|
|
526
|
-
const token = tokens[index] ?? "";
|
|
527
|
-
if (SPACE_PARENT_OPTIONS_WITH_VALUE.has(token)) {
|
|
528
|
-
index += 2;
|
|
529
|
-
continue;
|
|
530
|
-
}
|
|
531
|
-
if ([...SPACE_PARENT_OPTIONS_WITH_VALUE].some((option) => token.startsWith(`${option}=`))) {
|
|
532
|
-
index += 1;
|
|
533
|
-
continue;
|
|
534
|
-
}
|
|
535
|
-
break;
|
|
536
|
-
}
|
|
537
|
-
const spaceCommand = tokens[index] ?? "";
|
|
538
|
-
if (!PROFILE_AWARE_SPACE_COMMANDS.has(spaceCommand)) return null;
|
|
539
|
-
return index + 1;
|
|
540
|
-
}
|
|
541
|
-
function normalizePath(value) {
|
|
542
|
-
return normalizeText$12(value).replaceAll("\\", "/").toLowerCase();
|
|
543
|
-
}
|
|
544
|
-
function normalizeText$12(value) {
|
|
545
|
-
return String(value ?? "").trim();
|
|
546
|
-
}
|
|
547
|
-
//#endregion
|
|
548
206
|
//#region src/auth/auth-guidance.ts
|
|
549
207
|
const AUTH_MISMATCH_ERROR_RE = /session auth:\s*(.+?),\s*gateway:\s*(.+?)\);?\s*run/u;
|
|
550
208
|
const AUTH_MISMATCH_SUMMARY_RE = /Current session is for\s+(.+?),\s+but.+?\s+is\s+(.+?)\./u;
|
|
@@ -1214,2865 +872,6 @@ function isRecord$4(value) {
|
|
|
1214
872
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1215
873
|
}
|
|
1216
874
|
//#endregion
|
|
1217
|
-
//#region src/config/version-state.ts
|
|
1218
|
-
const VERSION_STATE_FILENAME = "version.json";
|
|
1219
|
-
const NPM_REGISTRY_LATEST_TIMEOUT_MS = 5e3;
|
|
1220
|
-
const VERSION_CHECK_CACHE_TTL_MS = 1440 * 60 * 1e3;
|
|
1221
|
-
const LEADING_V_PREFIX_REGEX = /^v/;
|
|
1222
|
-
const SEMVER_CORE_REGEX = /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+.*)?$/;
|
|
1223
|
-
const NUMERIC_SEMVER_IDENTIFIER_REGEX = /^\d+$/;
|
|
1224
|
-
const versionCache = /* @__PURE__ */ new Map();
|
|
1225
|
-
const inFlightVersionRequests = /* @__PURE__ */ new Map();
|
|
1226
|
-
function versionStatePath() {
|
|
1227
|
-
return join(openMeldRootDir(), VERSION_STATE_FILENAME);
|
|
1228
|
-
}
|
|
1229
|
-
async function readVersionState() {
|
|
1230
|
-
const raw = await readFile(versionStatePath(), "utf8").catch(() => null);
|
|
1231
|
-
if (!raw) return null;
|
|
1232
|
-
try {
|
|
1233
|
-
const parsed = JSON.parse(raw);
|
|
1234
|
-
if (parsed.v !== 1 || typeof parsed.updated_at !== "string") return null;
|
|
1235
|
-
const lastVersion = toNonEmptyString(parsed.last_version);
|
|
1236
|
-
const latestVersion = toNonEmptyString(parsed.latest_version);
|
|
1237
|
-
const lastCheckedAt = toNonEmptyString(parsed.last_checked_at);
|
|
1238
|
-
const dismissedVersion = parsed.dismissed_version === null ? null : toNonEmptyString(parsed.dismissed_version);
|
|
1239
|
-
const requiredFloor = parseStoredRequiredFloor(parsed.required_floor);
|
|
1240
|
-
return {
|
|
1241
|
-
v: 1,
|
|
1242
|
-
...lastVersion ? { last_version: lastVersion } : {},
|
|
1243
|
-
...latestVersion ? { latest_version: latestVersion } : {},
|
|
1244
|
-
...lastCheckedAt ? { last_checked_at: lastCheckedAt } : {},
|
|
1245
|
-
...dismissedVersion === void 0 ? {} : { dismissed_version: dismissedVersion },
|
|
1246
|
-
...requiredFloor === void 0 ? {} : { required_floor: requiredFloor },
|
|
1247
|
-
updated_at: parsed.updated_at
|
|
1248
|
-
};
|
|
1249
|
-
} catch {
|
|
1250
|
-
return null;
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
async function writeVersionState(state) {
|
|
1254
|
-
await mkdir(openMeldRootDir(), { recursive: true });
|
|
1255
|
-
await writeFile(versionStatePath(), `${JSON.stringify(state, null, 2)}\n`);
|
|
1256
|
-
}
|
|
1257
|
-
function createInitialVersionState(input) {
|
|
1258
|
-
const checkedAt = input.checkedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
1259
|
-
return {
|
|
1260
|
-
v: 1,
|
|
1261
|
-
last_version: input.currentVersion,
|
|
1262
|
-
latest_version: input.currentVersion,
|
|
1263
|
-
last_checked_at: checkedAt,
|
|
1264
|
-
dismissed_version: null,
|
|
1265
|
-
updated_at: checkedAt
|
|
1266
|
-
};
|
|
1267
|
-
}
|
|
1268
|
-
function hasValidLastVersion(state) {
|
|
1269
|
-
return Boolean(toNonEmptyString(state?.last_version));
|
|
1270
|
-
}
|
|
1271
|
-
async function ensureVersionStateReady(input) {
|
|
1272
|
-
const previousVersionState = await readVersionState();
|
|
1273
|
-
if (!previousVersionState) {
|
|
1274
|
-
const nextState = createInitialVersionState({ currentVersion: input.currentVersion });
|
|
1275
|
-
await writeVersionState(nextState);
|
|
1276
|
-
return nextState;
|
|
1277
|
-
}
|
|
1278
|
-
if (hasValidLastVersion(previousVersionState)) return previousVersionState;
|
|
1279
|
-
const nextState = {
|
|
1280
|
-
...previousVersionState,
|
|
1281
|
-
last_version: input.currentVersion,
|
|
1282
|
-
latest_version: previousVersionState.latest_version ?? input.currentVersion
|
|
1283
|
-
};
|
|
1284
|
-
await writeVersionState(nextState);
|
|
1285
|
-
return nextState;
|
|
1286
|
-
}
|
|
1287
|
-
function buildNextVersionState(input) {
|
|
1288
|
-
const checkedAt = input.checkedAt ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
1289
|
-
const latestVersion = toNonEmptyString(input.latestVersion) ?? toNonEmptyString(input.previous?.latest_version) ?? input.currentVersion;
|
|
1290
|
-
const requiredFloor = input.requiredFloor === void 0 ? input.previous?.required_floor ?? null : input.requiredFloor;
|
|
1291
|
-
return {
|
|
1292
|
-
v: 1,
|
|
1293
|
-
last_version: input.currentVersion,
|
|
1294
|
-
latest_version: latestVersion,
|
|
1295
|
-
last_checked_at: checkedAt,
|
|
1296
|
-
dismissed_version: input.dismissedVersion ?? input.previous?.dismissed_version ?? null,
|
|
1297
|
-
...requiredFloor ? { required_floor: requiredFloor } : {},
|
|
1298
|
-
updated_at: checkedAt
|
|
1299
|
-
};
|
|
1300
|
-
}
|
|
1301
|
-
function parseStoredRequiredFloor(value) {
|
|
1302
|
-
if (value === void 0) return;
|
|
1303
|
-
if (value === null) return null;
|
|
1304
|
-
return toNonEmptyString(value);
|
|
1305
|
-
}
|
|
1306
|
-
async function fetchLatestPackageInfo(packageName, input = {}) {
|
|
1307
|
-
const now = Date.now();
|
|
1308
|
-
const cached = input.forceRefresh ? void 0 : versionCache.get(packageName);
|
|
1309
|
-
if (cached && now - cached.fetchedAt < VERSION_CHECK_CACHE_TTL_MS) return cached.info;
|
|
1310
|
-
const requestKey = input.forceRefresh ? `${packageName}:force_refresh` : packageName;
|
|
1311
|
-
const inFlight = inFlightVersionRequests.get(requestKey);
|
|
1312
|
-
if (inFlight) return inFlight;
|
|
1313
|
-
const request = requestLatestPackageInfo(packageName);
|
|
1314
|
-
inFlightVersionRequests.set(requestKey, request);
|
|
1315
|
-
try {
|
|
1316
|
-
const info = await request;
|
|
1317
|
-
versionCache.set(packageName, {
|
|
1318
|
-
info,
|
|
1319
|
-
fetchedAt: Date.now()
|
|
1320
|
-
});
|
|
1321
|
-
return info;
|
|
1322
|
-
} finally {
|
|
1323
|
-
inFlightVersionRequests.delete(requestKey);
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
async function fetchLatestCliBinaryRelease(input) {
|
|
1327
|
-
const manifest = await requestCliBinaryManifest();
|
|
1328
|
-
const platform = toNonEmptyString(input?.platform) ?? `${process$1.platform}-${process$1.arch}`;
|
|
1329
|
-
const release = manifest.platforms[platform];
|
|
1330
|
-
if (!release) throw new Error(`version check failed: invalid CLI manifest response: missing platform ${platform}`);
|
|
1331
|
-
const serviceRelease = manifest.service?.platforms[platform];
|
|
1332
|
-
return {
|
|
1333
|
-
version: manifest.version,
|
|
1334
|
-
minRequiredCliVersion: manifest.minRequiredCliVersion,
|
|
1335
|
-
platform,
|
|
1336
|
-
...release,
|
|
1337
|
-
...manifest.service && serviceRelease ? { service: {
|
|
1338
|
-
...serviceRelease,
|
|
1339
|
-
version: manifest.service.version,
|
|
1340
|
-
platform
|
|
1341
|
-
} } : {}
|
|
1342
|
-
};
|
|
1343
|
-
}
|
|
1344
|
-
async function requestLatestPackageInfo(packageName) {
|
|
1345
|
-
if (isBinaryDistribution()) return await requestLatestPackageInfoFromCliManifest();
|
|
1346
|
-
const response = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}/latest`, {
|
|
1347
|
-
method: "GET",
|
|
1348
|
-
signal: AbortSignal.timeout(NPM_REGISTRY_LATEST_TIMEOUT_MS)
|
|
1349
|
-
});
|
|
1350
|
-
const raw = await response.text();
|
|
1351
|
-
if (!response.ok) throw new Error(`version check failed: HTTP ${response.status}: ${raw}`);
|
|
1352
|
-
try {
|
|
1353
|
-
const parsed = JSON.parse(raw);
|
|
1354
|
-
const version = typeof parsed.version === "string" ? parsed.version.trim() : "";
|
|
1355
|
-
if (!version) throw new Error("missing version");
|
|
1356
|
-
return {
|
|
1357
|
-
version,
|
|
1358
|
-
minRequiredCliVersion: readMinRequiredCliVersion(parsed.openmeld)
|
|
1359
|
-
};
|
|
1360
|
-
} catch (error) {
|
|
1361
|
-
throw new Error(`version check failed: invalid registry response: ${toErrorMessage$24(error)}`);
|
|
1362
|
-
}
|
|
1363
|
-
}
|
|
1364
|
-
const CLI_BINARY_MANIFEST_URL = toNonEmptyString(process$1.env.OPENMELD_CLI_BINARY_MANIFEST_URL) ?? "https://openmeld.ai/cli/manifest.json";
|
|
1365
|
-
async function requestLatestPackageInfoFromCliManifest() {
|
|
1366
|
-
const manifest = await requestCliBinaryManifest();
|
|
1367
|
-
return {
|
|
1368
|
-
version: manifest.version,
|
|
1369
|
-
minRequiredCliVersion: manifest.minRequiredCliVersion,
|
|
1370
|
-
...manifest.service ? { serviceVersion: manifest.service.version } : {}
|
|
1371
|
-
};
|
|
1372
|
-
}
|
|
1373
|
-
async function requestCliBinaryManifest() {
|
|
1374
|
-
const response = await fetch(CLI_BINARY_MANIFEST_URL, {
|
|
1375
|
-
method: "GET",
|
|
1376
|
-
signal: AbortSignal.timeout(NPM_REGISTRY_LATEST_TIMEOUT_MS)
|
|
1377
|
-
});
|
|
1378
|
-
const raw = await response.text();
|
|
1379
|
-
if (!response.ok) throw new Error(`version check failed: HTTP ${response.status}: ${raw}`);
|
|
1380
|
-
try {
|
|
1381
|
-
return parseCliBinaryManifest(raw);
|
|
1382
|
-
} catch (error) {
|
|
1383
|
-
throw new Error(`version check failed: invalid CLI manifest response: ${toErrorMessage$24(error)}`);
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
function parseCliBinaryManifest(raw) {
|
|
1387
|
-
const parsed = cliBinaryManifestSchema.safeParse(JSON.parse(raw));
|
|
1388
|
-
if (!parsed.success) throw new Error(parsed.error.message);
|
|
1389
|
-
const stable = parsed.data.channels.stable;
|
|
1390
|
-
return {
|
|
1391
|
-
...stable,
|
|
1392
|
-
minRequiredCliVersion: stable.minRequiredCliVersion ?? null
|
|
1393
|
-
};
|
|
1394
|
-
}
|
|
1395
|
-
function readMinRequiredCliVersion(openmeld) {
|
|
1396
|
-
if (!openmeld || typeof openmeld !== "object") return null;
|
|
1397
|
-
const value = openmeld.minRequiredCliVersion;
|
|
1398
|
-
if (typeof value !== "string") return null;
|
|
1399
|
-
const trimmed = value.trim();
|
|
1400
|
-
return trimmed.length > 0 && isPlainReleaseVersion(trimmed) ? trimmed : null;
|
|
1401
|
-
}
|
|
1402
|
-
const PLAIN_RELEASE_VERSION_RE = /^\d+\.\d+\.\d+$/;
|
|
1403
|
-
function isPlainReleaseVersion(value) {
|
|
1404
|
-
return PLAIN_RELEASE_VERSION_RE.test(value.trim());
|
|
1405
|
-
}
|
|
1406
|
-
function compareSemver(a, b) {
|
|
1407
|
-
const left = parseSemver(a);
|
|
1408
|
-
const right = parseSemver(b);
|
|
1409
|
-
if (!(left && right)) return a.localeCompare(b);
|
|
1410
|
-
if (left.major !== right.major) return left.major > right.major ? 1 : -1;
|
|
1411
|
-
if (left.minor !== right.minor) return left.minor > right.minor ? 1 : -1;
|
|
1412
|
-
if (left.patch !== right.patch) return left.patch > right.patch ? 1 : -1;
|
|
1413
|
-
return comparePrereleaseIdentifiers(left.prerelease, right.prerelease);
|
|
1414
|
-
}
|
|
1415
|
-
function parseSemver(value) {
|
|
1416
|
-
const match = value.trim().replace(LEADING_V_PREFIX_REGEX, "").match(SEMVER_CORE_REGEX);
|
|
1417
|
-
if (!match) return null;
|
|
1418
|
-
return {
|
|
1419
|
-
major: Number(match[1]),
|
|
1420
|
-
minor: Number(match[2]),
|
|
1421
|
-
patch: Number(match[3]),
|
|
1422
|
-
prerelease: match[4] ? match[4].split(".") : null
|
|
1423
|
-
};
|
|
1424
|
-
}
|
|
1425
|
-
function comparePrereleaseIdentifiers(left, right) {
|
|
1426
|
-
if (!(left || right)) return 0;
|
|
1427
|
-
if (!left) return 1;
|
|
1428
|
-
if (!right) return -1;
|
|
1429
|
-
const maxLength = Math.max(left.length, right.length);
|
|
1430
|
-
for (let index = 0; index < maxLength; index += 1) {
|
|
1431
|
-
const leftIdentifier = left[index];
|
|
1432
|
-
const rightIdentifier = right[index];
|
|
1433
|
-
const lengthComparison = comparePrereleaseLengthAtIndex(leftIdentifier, rightIdentifier);
|
|
1434
|
-
if (lengthComparison !== 0) return lengthComparison;
|
|
1435
|
-
if (!(leftIdentifier && rightIdentifier)) continue;
|
|
1436
|
-
const compared = compareSinglePrereleaseIdentifier(leftIdentifier, rightIdentifier);
|
|
1437
|
-
if (compared !== 0) return compared;
|
|
1438
|
-
}
|
|
1439
|
-
return 0;
|
|
1440
|
-
}
|
|
1441
|
-
function comparePrereleaseLengthAtIndex(leftIdentifier, rightIdentifier) {
|
|
1442
|
-
if (leftIdentifier === void 0 && rightIdentifier === void 0) return 0;
|
|
1443
|
-
if (leftIdentifier === void 0) return -1;
|
|
1444
|
-
if (rightIdentifier === void 0) return 1;
|
|
1445
|
-
return 0;
|
|
1446
|
-
}
|
|
1447
|
-
function compareSinglePrereleaseIdentifier(leftIdentifier, rightIdentifier) {
|
|
1448
|
-
if (leftIdentifier === rightIdentifier) return 0;
|
|
1449
|
-
const leftNumber = toNumericPrereleaseIdentifier(leftIdentifier);
|
|
1450
|
-
const rightNumber = toNumericPrereleaseIdentifier(rightIdentifier);
|
|
1451
|
-
if (leftNumber !== null && rightNumber !== null) {
|
|
1452
|
-
if (leftNumber === rightNumber) return 0;
|
|
1453
|
-
return leftNumber > rightNumber ? 1 : -1;
|
|
1454
|
-
}
|
|
1455
|
-
if (leftNumber !== null) return -1;
|
|
1456
|
-
if (rightNumber !== null) return 1;
|
|
1457
|
-
return leftIdentifier > rightIdentifier ? 1 : -1;
|
|
1458
|
-
}
|
|
1459
|
-
function toNumericPrereleaseIdentifier(identifier) {
|
|
1460
|
-
if (!NUMERIC_SEMVER_IDENTIFIER_REGEX.test(identifier)) return null;
|
|
1461
|
-
return Number(identifier);
|
|
1462
|
-
}
|
|
1463
|
-
function toNonEmptyString(value) {
|
|
1464
|
-
if (typeof value !== "string") return null;
|
|
1465
|
-
const normalized = value.trim();
|
|
1466
|
-
return normalized.length > 0 ? normalized : null;
|
|
1467
|
-
}
|
|
1468
|
-
function toErrorMessage$24(error) {
|
|
1469
|
-
if (error instanceof Error) return error.message;
|
|
1470
|
-
return String(error);
|
|
1471
|
-
}
|
|
1472
|
-
//#endregion
|
|
1473
|
-
//#region src/config/daemon-service-contract.ts
|
|
1474
|
-
const DAEMON_SERVICE_CONTRACT_FILENAME = "service-contract.json";
|
|
1475
|
-
function daemonServiceContractPath(pathInput = {}) {
|
|
1476
|
-
return join(daemonRuntimeStateRootPath(pathInput), DAEMON_SERVICE_CONTRACT_FILENAME);
|
|
1477
|
-
}
|
|
1478
|
-
async function readDaemonServiceContract(pathInput = {}) {
|
|
1479
|
-
return await readDaemonLocalStateFile({
|
|
1480
|
-
path: daemonServiceContractPath(pathInput),
|
|
1481
|
-
schema: daemonServiceContractSchema
|
|
1482
|
-
});
|
|
1483
|
-
}
|
|
1484
|
-
async function upsertDaemonServiceContract(input, pathInput = {}) {
|
|
1485
|
-
assertDaemonServiceContractMutationAllowed(pathInput);
|
|
1486
|
-
const current = await readDaemonServiceContract(pathInput);
|
|
1487
|
-
const candidate = buildContractCandidate(input, pathInput, current);
|
|
1488
|
-
assertDaemonServiceContractIdentityAllowed(candidate, pathInput);
|
|
1489
|
-
if (current && isSameContractState(current, candidate)) return current;
|
|
1490
|
-
const next = {
|
|
1491
|
-
...candidate,
|
|
1492
|
-
generation: current ? current.generation + 1 : 1,
|
|
1493
|
-
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1494
|
-
};
|
|
1495
|
-
await writeDaemonLocalStateFile({
|
|
1496
|
-
path: daemonServiceContractPath(pathInput),
|
|
1497
|
-
schema: daemonServiceContractSchema,
|
|
1498
|
-
value: next,
|
|
1499
|
-
mode: 384
|
|
1500
|
-
});
|
|
1501
|
-
return next;
|
|
1502
|
-
}
|
|
1503
|
-
async function clearDaemonServiceContract(pathInput = {}) {
|
|
1504
|
-
assertDaemonServiceContractMutationAllowed(pathInput);
|
|
1505
|
-
await rm(daemonServiceContractPath(pathInput), { force: true });
|
|
1506
|
-
}
|
|
1507
|
-
function assertDaemonServiceContractMutationAllowed(pathInput) {
|
|
1508
|
-
assertNoPublishedProductionMutationDuringTests(pathInput, "OpenMeld Service contract");
|
|
1509
|
-
}
|
|
1510
|
-
function assertDaemonServiceContractIdentityAllowed(candidate, pathInput) {
|
|
1511
|
-
if (!isUnsafeProductionDaemonServiceContractIdentity(candidate)) return;
|
|
1512
|
-
if (isTestProcess(pathInput) && !isPublishedProductionOpenMeldRoot(pathInput)) return;
|
|
1513
|
-
throw new Error(["Refusing to write OpenMeld Service contract with a test fixture identity in the published production lane.", "Run `openmeld service repair --profile <profile-id>` from the signed-in production lane, or clear the polluted local service state before retrying."].join(" "));
|
|
1514
|
-
}
|
|
1515
|
-
function isDaemonServiceContractIdentityReusable(contract, pathInput = {}) {
|
|
1516
|
-
if (!contract) return false;
|
|
1517
|
-
if (contract.lane !== resolveOpenMeldEnvPreset(pathInput)) return false;
|
|
1518
|
-
return !isUnsafeProductionDaemonServiceContractIdentity(contract);
|
|
1519
|
-
}
|
|
1520
|
-
function isUnsafeProductionDaemonServiceContractIdentity(contract) {
|
|
1521
|
-
if (contract.lane !== "prod") return false;
|
|
1522
|
-
return isUnsafeProductionDeviceId(contract.deviceId) || (contract.profileId ? isUnsafeProductionProfileId(contract.profileId) : false);
|
|
1523
|
-
}
|
|
1524
|
-
function isUnsafeProductionDeviceId(deviceId) {
|
|
1525
|
-
return normalizeFixtureText(deviceId) === "device_123";
|
|
1526
|
-
}
|
|
1527
|
-
function isUnsafeProductionProfileId(profileId) {
|
|
1528
|
-
return UNSAFE_PRODUCTION_PROFILE_IDS.has(normalizeFixtureText(profileId));
|
|
1529
|
-
}
|
|
1530
|
-
const UNSAFE_PRODUCTION_PROFILE_IDS = /* @__PURE__ */ new Set([
|
|
1531
|
-
"agt_existing",
|
|
1532
|
-
"11111111-1111-1111-1111-111111111111",
|
|
1533
|
-
"agt_11111111-1111-1111-1111-111111111111",
|
|
1534
|
-
"11111111-1111-4111-8111-111111111111",
|
|
1535
|
-
"agt_11111111-1111-4111-8111-111111111111"
|
|
1536
|
-
]);
|
|
1537
|
-
function normalizeFixtureText(value) {
|
|
1538
|
-
return value.trim().toLowerCase();
|
|
1539
|
-
}
|
|
1540
|
-
function buildContractCandidate(input, pathInput, current) {
|
|
1541
|
-
const lane = input.lane ?? resolveOpenMeldEnvPreset(pathInput);
|
|
1542
|
-
const connectedComputerId = input.connectedComputerId ?? (current && canReuseConnectedComputerEvidence(current, input, lane) ? current.connectedComputerId : void 0);
|
|
1543
|
-
return {
|
|
1544
|
-
schema: "openmeld-daemon-service-contract-v1",
|
|
1545
|
-
v: 1,
|
|
1546
|
-
lane,
|
|
1547
|
-
daemonVersion: input.daemonVersion,
|
|
1548
|
-
bundleId: input.bundleId,
|
|
1549
|
-
desiredState: input.desiredState,
|
|
1550
|
-
serviceController: input.serviceController,
|
|
1551
|
-
autoStart: input.autoStart,
|
|
1552
|
-
gatewayUrl: input.gatewayUrl,
|
|
1553
|
-
...input.ownerUserId ? { ownerUserId: input.ownerUserId } : {},
|
|
1554
|
-
...input.profileId ? { profileId: input.profileId } : {},
|
|
1555
|
-
deviceId: input.deviceId,
|
|
1556
|
-
...connectedComputerId ? { connectedComputerId } : {},
|
|
1557
|
-
heartbeatMs: input.heartbeatMs
|
|
1558
|
-
};
|
|
1559
|
-
}
|
|
1560
|
-
function canReuseConnectedComputerEvidence(current, input, lane) {
|
|
1561
|
-
if (current.lane !== lane || current.gatewayUrl !== input.gatewayUrl || current.deviceId !== input.deviceId) return false;
|
|
1562
|
-
if (current.ownerUserId && input.ownerUserId) return current.ownerUserId === input.ownerUserId;
|
|
1563
|
-
if (current.profileId && input.profileId) return current.profileId === input.profileId;
|
|
1564
|
-
return !(current.ownerUserId || input.ownerUserId);
|
|
1565
|
-
}
|
|
1566
|
-
function isSameContractState(current, candidate) {
|
|
1567
|
-
return current.schema === candidate.schema && current.v === candidate.v && current.lane === candidate.lane && current.daemonVersion === candidate.daemonVersion && current.bundleId === candidate.bundleId && current.desiredState === candidate.desiredState && current.serviceController === candidate.serviceController && current.autoStart === candidate.autoStart && current.gatewayUrl === candidate.gatewayUrl && current.ownerUserId === candidate.ownerUserId && current.profileId === candidate.profileId && current.deviceId === candidate.deviceId && current.connectedComputerId === candidate.connectedComputerId && current.heartbeatMs === candidate.heartbeatMs;
|
|
1568
|
-
}
|
|
1569
|
-
//#endregion
|
|
1570
|
-
//#region src/config/daemon-service-update-worker-registration.ts
|
|
1571
|
-
const MANAGED_VERSION_FROM_EXECUTABLE_PATTERN = /[\\/]versions[\\/](v?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?)[\\/]openmeld(?:\.exe)?/gu;
|
|
1572
|
-
const SELF_CONTAINED_BUNDLE_FROM_EXECUTABLE_PATTERN = /[\\/]runtime[\\/]daemon[\\/]bundles[\\/]([0-9A-Za-z._-]+)[\\/]/gu;
|
|
1573
|
-
const INDEPENDENT_MAINTENANCE_REGISTRATION = "openmeld-independent-maintenance-v1";
|
|
1574
|
-
function configureDaemonMaintenanceEnvironment(env) {
|
|
1575
|
-
for (const key of [
|
|
1576
|
-
DAEMON_SERVICE_RUNTIME_AUTO_START_ENV,
|
|
1577
|
-
DAEMON_SERVICE_RUNTIME_CONTROLLER_ENV,
|
|
1578
|
-
DAEMON_SERVICE_RUNTIME_DETACHED_ENV,
|
|
1579
|
-
DAEMON_SERVICE_RUNTIME_MODE_ENV,
|
|
1580
|
-
DAEMON_SERVICE_RUNTIME_SYSTEM_SERVICE_ENV
|
|
1581
|
-
]) delete env[key];
|
|
1582
|
-
env.OPENMELD_INTERNAL_MAINTENANCE_WORKER = "1";
|
|
1583
|
-
}
|
|
1584
|
-
const NPM_ENTRY_IMPORT_PATTERN = /^await import\((".*")\);$/mu;
|
|
1585
|
-
function daemonServiceUpdateWorkerNpmEntryPath(pathInput = {}) {
|
|
1586
|
-
return join(daemonRuntimeRootPath(pathInput), "service-update-worker.mjs");
|
|
1587
|
-
}
|
|
1588
|
-
async function hasIndependentMaintenanceRegistration(pathInput = {}, platform = process$1.platform, expectedDefinition) {
|
|
1589
|
-
if (platform === "win32") {
|
|
1590
|
-
const { runWindowsUserTask, readWindowsTaskAction } = await import("./windows-user-task-DxPN7TzK.js");
|
|
1591
|
-
const task = await runWindowsUserTask({
|
|
1592
|
-
name: resolveDaemonServiceUpdateWorkerIdentity(pathInput).windowsServiceName,
|
|
1593
|
-
legacyScript: resolveDaemonServiceUpdateWorkerWindowsScriptPath(pathInput),
|
|
1594
|
-
operation: "status"
|
|
1595
|
-
});
|
|
1596
|
-
return Boolean(task.installed && !task.legacy && task.actionArguments && (expectedDefinition === void 0 || task.actionArguments === expectedDefinition) && resolveOpenMeldRootDir({ env: readWindowsTaskAction(task.actionArguments).env }) === resolveOpenMeldRootDir(pathInput));
|
|
1597
|
-
}
|
|
1598
|
-
const registration = await readDaemonServiceUpdateWorkerRegistration(pathInput, platform);
|
|
1599
|
-
if (!registration?.includes("openmeld-independent-maintenance-v1")) return false;
|
|
1600
|
-
if (expectedDefinition !== void 0 && registration !== expectedDefinition) return false;
|
|
1601
|
-
const { parseDaemonServiceEnvironmentFromDefinition } = await import("./daemon-service-manager-DqVtRLBY.js");
|
|
1602
|
-
return resolveOpenMeldRootDir({ env: parseDaemonServiceEnvironmentFromDefinition({
|
|
1603
|
-
controller: platform === "darwin" ? "launchd" : "systemd",
|
|
1604
|
-
definition: registration
|
|
1605
|
-
}) }) === resolveOpenMeldRootDir(pathInput);
|
|
1606
|
-
}
|
|
1607
|
-
function resolveDaemonServiceUpdateWorkerIdentity(pathInput = {}) {
|
|
1608
|
-
const preset = resolveOpenMeldEnvPreset(pathInput);
|
|
1609
|
-
const scope = resolveOpenMeldServiceScope(pathInput);
|
|
1610
|
-
const suffix = (preset === "prod" ? "" : `-${preset}`) + (scope ? `-${scope}` : "");
|
|
1611
|
-
return {
|
|
1612
|
-
launchdLabel: `com.openmeld.openmeld-service-update${(preset === "prod" ? "" : `.${preset}`) + (scope ? `.${scope}` : "")}`,
|
|
1613
|
-
serviceName: `openmeld-service-update${suffix}`,
|
|
1614
|
-
windowsDisplayName: `OpenMeld Service Update${preset === "prod" ? "" : ` (${preset})`}`,
|
|
1615
|
-
windowsServiceName: `OpenMeld-Service-Update${suffix}`
|
|
1616
|
-
};
|
|
1617
|
-
}
|
|
1618
|
-
function resolveDaemonServiceUpdateWorkerLaunchdPlistPath(pathInput = {}) {
|
|
1619
|
-
return join(pathInput.homeDir ?? homedir(), "Library", "LaunchAgents", `${resolveDaemonServiceUpdateWorkerIdentity(pathInput).launchdLabel}.plist`);
|
|
1620
|
-
}
|
|
1621
|
-
function resolveDaemonServiceUpdateWorkerSystemdUnitPath(pathInput = {}) {
|
|
1622
|
-
return join(pathInput.homeDir ?? homedir(), ".config", "systemd", "user", `${resolveDaemonServiceUpdateWorkerIdentity(pathInput).serviceName}.service`);
|
|
1623
|
-
}
|
|
1624
|
-
function resolveDaemonServiceUpdateWorkerSystemdPathUnitPath(pathInput = {}) {
|
|
1625
|
-
return join(pathInput.homeDir ?? homedir(), ".config", "systemd", "user", `${resolveDaemonServiceUpdateWorkerIdentity(pathInput).serviceName}.path`);
|
|
1626
|
-
}
|
|
1627
|
-
function resolveDaemonServiceUpdateWorkerWindowsScriptPath(pathInput = {}) {
|
|
1628
|
-
return join(daemonRuntimeRootPath(pathInput), "service-update-worker.bat");
|
|
1629
|
-
}
|
|
1630
|
-
function resolveDaemonServiceUpdateWorkerSystemdTimerUnitPath(pathInput = {}) {
|
|
1631
|
-
return join(pathInput.homeDir ?? homedir(), ".config", "systemd", "user", `${resolveDaemonServiceUpdateWorkerIdentity(pathInput).serviceName}.timer`);
|
|
1632
|
-
}
|
|
1633
|
-
async function readDaemonServiceUpdateWorkerProtectedManagedVersions(pathInput = {}, platform = process$1.platform) {
|
|
1634
|
-
const contents = await readDaemonServiceUpdateWorkerRegistration(pathInput, platform);
|
|
1635
|
-
return contents === null ? /* @__PURE__ */ new Set() : readManagedVersionsFromUpdateWorkerRegistration(contents);
|
|
1636
|
-
}
|
|
1637
|
-
async function readDaemonServiceUpdateWorkerProtectedBundleIds(pathInput = {}, platform = process$1.platform) {
|
|
1638
|
-
const contents = await readDaemonServiceUpdateWorkerRegistration(pathInput, platform);
|
|
1639
|
-
const protectedIds = contents === null ? /* @__PURE__ */ new Set() : readBundleIdsFromUpdateWorkerRegistration(contents);
|
|
1640
|
-
const launcher = await readFile(daemonServiceUpdateWorkerNpmEntryPath(pathInput), "utf8").catch((error) => {
|
|
1641
|
-
if (getErrorCode$2(error) === "ENOENT") return null;
|
|
1642
|
-
throw error;
|
|
1643
|
-
});
|
|
1644
|
-
if (launcher !== null) {
|
|
1645
|
-
const importLine = launcher.trim().match(NPM_ENTRY_IMPORT_PATTERN);
|
|
1646
|
-
if (!importLine?.[1]) throw new Error("OpenMeld maintenance launcher is invalid; bundle cleanup was stopped.");
|
|
1647
|
-
const entryPath = fileURLToPath(JSON.parse(importLine[1]));
|
|
1648
|
-
for (const id of readBundleIdsFromUpdateWorkerRegistration(entryPath)) protectedIds.add(id);
|
|
1649
|
-
}
|
|
1650
|
-
return protectedIds;
|
|
1651
|
-
}
|
|
1652
|
-
function readManagedVersionsFromUpdateWorkerRegistration(contents) {
|
|
1653
|
-
const versions = /* @__PURE__ */ new Set();
|
|
1654
|
-
for (const match of contents.matchAll(MANAGED_VERSION_FROM_EXECUTABLE_PATTERN)) {
|
|
1655
|
-
const version = match[1];
|
|
1656
|
-
if (version) versions.add(version);
|
|
1657
|
-
}
|
|
1658
|
-
return versions;
|
|
1659
|
-
}
|
|
1660
|
-
function readBundleIdsFromUpdateWorkerRegistration(contents) {
|
|
1661
|
-
const bundleIds = /* @__PURE__ */ new Set();
|
|
1662
|
-
for (const match of contents.matchAll(SELF_CONTAINED_BUNDLE_FROM_EXECUTABLE_PATTERN)) {
|
|
1663
|
-
const bundleId = match[1];
|
|
1664
|
-
if (bundleId) bundleIds.add(bundleId);
|
|
1665
|
-
}
|
|
1666
|
-
return bundleIds;
|
|
1667
|
-
}
|
|
1668
|
-
function resolveDaemonServiceUpdateWorkerRegistrationPath(pathInput, platform) {
|
|
1669
|
-
if (platform === "darwin") return resolveDaemonServiceUpdateWorkerLaunchdPlistPath(pathInput);
|
|
1670
|
-
if (platform === "linux") return resolveDaemonServiceUpdateWorkerSystemdUnitPath(pathInput);
|
|
1671
|
-
if (platform === "win32") return resolveDaemonServiceUpdateWorkerWindowsScriptPath(pathInput);
|
|
1672
|
-
return null;
|
|
1673
|
-
}
|
|
1674
|
-
async function readDaemonServiceUpdateWorkerRegistration(pathInput, platform) {
|
|
1675
|
-
const registrationPath = resolveDaemonServiceUpdateWorkerRegistrationPath(pathInput, platform);
|
|
1676
|
-
if (registrationPath === null) return null;
|
|
1677
|
-
return await readFile(registrationPath, "utf8").catch((error) => {
|
|
1678
|
-
if (getErrorCode$2(error) === "ENOENT") return null;
|
|
1679
|
-
throw error;
|
|
1680
|
-
});
|
|
1681
|
-
}
|
|
1682
|
-
function getErrorCode$2(error) {
|
|
1683
|
-
return error && typeof error === "object" && "code" in error ? String(error.code) : null;
|
|
1684
|
-
}
|
|
1685
|
-
//#endregion
|
|
1686
|
-
//#region package.json
|
|
1687
|
-
var package_default = {
|
|
1688
|
-
$schema: "https://www.schemastore.org/package.json",
|
|
1689
|
-
name: "openmeld",
|
|
1690
|
-
version: "0.3.206",
|
|
1691
|
-
openMeldReleaseDate: "2026-09-14",
|
|
1692
|
-
description: "OpenMeld CLI - https://openmeld.ai",
|
|
1693
|
-
license: "MIT",
|
|
1694
|
-
type: "module",
|
|
1695
|
-
bin: { "openmeld": "dist/openmeld.js" },
|
|
1696
|
-
"private": false,
|
|
1697
|
-
publishConfig: { "access": "public" },
|
|
1698
|
-
engines: { "node": "20.x || >=22 <26" },
|
|
1699
|
-
files: [
|
|
1700
|
-
"README.md",
|
|
1701
|
-
"dist",
|
|
1702
|
-
"!dist/binary/**",
|
|
1703
|
-
"skills"
|
|
1704
|
-
],
|
|
1705
|
-
scripts: {
|
|
1706
|
-
"build": "tsdown && node scripts/build-macos-keychain-addon.mjs --copy-npm",
|
|
1707
|
-
"prepack": "pnpm -C ../.. run verify:release-ready -- --force && pnpm run verify:pack-readme",
|
|
1708
|
-
"deploy": "pnpm -C ../.. run release:deploy:local -- --scope cli",
|
|
1709
|
-
"publish:npm": "npm publish",
|
|
1710
|
-
"prepublishOnly": "pnpm run verify:pack-readme",
|
|
1711
|
-
"verify:pack-readme": "node scripts/verify-npm-pack-readme.mjs",
|
|
1712
|
-
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
1713
|
-
"check": "biome check --no-errors-on-unmatched ./ && tsc -p tsconfig.json --noEmit",
|
|
1714
|
-
"test": "vitest run --config vitest.config.ts",
|
|
1715
|
-
"test:integration": "node scripts/run-integration-tests.mjs",
|
|
1716
|
-
"test:full": "pnpm run test && pnpm run test:integration",
|
|
1717
|
-
"test:local-service": "vitest run --config vitest.integration.config.ts tests/local-service-state.integration.test.ts tests/local-service-command.integration.test.ts tests/local-service-menu.integration.test.ts tests/local-service-run.integration.test.ts tests/local-service-bootstrap-recommendation.test.ts",
|
|
1718
|
-
"test:watch": "vitest"
|
|
1719
|
-
},
|
|
1720
|
-
dependencies: {
|
|
1721
|
-
"@anthropic-ai/claude-agent-sdk": "^0.3.195",
|
|
1722
|
-
"@anthropic-ai/sdk": "^0.93.0",
|
|
1723
|
-
"@clack/prompts": "^1.0.1",
|
|
1724
|
-
"@mariozechner/pi-tui": "0.57.1",
|
|
1725
|
-
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
1726
|
-
"@opencode-ai/sdk": "^1.18.7",
|
|
1727
|
-
"better-sqlite3": "^12.6.2",
|
|
1728
|
-
"commander": "^14.0.0",
|
|
1729
|
-
"picocolors": "^1.1.1",
|
|
1730
|
-
"string-width": "^8.1.0",
|
|
1731
|
-
"wrap-ansi": "10.0.0",
|
|
1732
|
-
"ws": "^8.18.3",
|
|
1733
|
-
"zod": "^4.3.6"
|
|
1734
|
-
},
|
|
1735
|
-
devDependencies: {
|
|
1736
|
-
"@openmeld/adapter-claude-code": "workspace:*",
|
|
1737
|
-
"@openmeld/adapter-codex": "workspace:*",
|
|
1738
|
-
"@openmeld/adapter-core": "workspace:*",
|
|
1739
|
-
"@openmeld/adapter-cursor": "workspace:*",
|
|
1740
|
-
"@openmeld/adapter-grok-build": "workspace:*",
|
|
1741
|
-
"@openmeld/adapter-openclaw": "workspace:*",
|
|
1742
|
-
"@openmeld/adapter-opencode": "workspace:*",
|
|
1743
|
-
"@openmeld/agent-runtime": "workspace:*",
|
|
1744
|
-
"@openmeld/api-client": "workspace:*",
|
|
1745
|
-
"@openmeld/gateway-contract": "workspace:*",
|
|
1746
|
-
"@openmeld/local-execution": "workspace:*",
|
|
1747
|
-
"@openmeld/local-service": "workspace:*",
|
|
1748
|
-
"@openmeld/projects": "workspace:*",
|
|
1749
|
-
"@openmeld/protocol": "workspace:*",
|
|
1750
|
-
"@openmeld/routine-schedule": "workspace:*",
|
|
1751
|
-
"@openmeld/schemas": "workspace:*",
|
|
1752
|
-
"@openmeld/space": "workspace:*",
|
|
1753
|
-
"@openmeld/space-mesh": "workspace:*",
|
|
1754
|
-
"@openmeld/start": "workspace:*",
|
|
1755
|
-
"@openmeld/utils": "workspace:*",
|
|
1756
|
-
"@types/better-sqlite3": "^7.6.13",
|
|
1757
|
-
"@types/node": "^24.3.0",
|
|
1758
|
-
"@types/ws": "^8.18.1",
|
|
1759
|
-
"node-gyp": "^12.4.0",
|
|
1760
|
-
"oxc-resolver": "^11.0.0",
|
|
1761
|
-
"tsdown": "^0.20.3",
|
|
1762
|
-
"typescript": "^5.9.3",
|
|
1763
|
-
"unplugin-lightningcss": "^0.4.0",
|
|
1764
|
-
"vitest": "~3.2.0"
|
|
1765
|
-
},
|
|
1766
|
-
openmeld: {
|
|
1767
|
-
"releaseLine": "openmeld-greenfield-2026-07",
|
|
1768
|
-
"minRequiredCliVersion": "0.3.198"
|
|
1769
|
-
}
|
|
1770
|
-
};
|
|
1771
|
-
//#endregion
|
|
1772
|
-
//#region src/config/service-release.ts
|
|
1773
|
-
function resolveBundledServiceRelease() {
|
|
1774
|
-
if (!isBinaryDistribution()) return;
|
|
1775
|
-
const metadata = package_default;
|
|
1776
|
-
const selection = typeof __OPENMELD_SERVICE_RELEASE__ === "undefined" ? metadata.openmeld?.service : __OPENMELD_SERVICE_RELEASE__;
|
|
1777
|
-
if (selection === void 0) return;
|
|
1778
|
-
const parsed = cliBinaryServiceReleaseSchema.safeParse(selection);
|
|
1779
|
-
if (!parsed.success) throw new Error("The installed CLI contains invalid Service release metadata.");
|
|
1780
|
-
const platform = `${process.platform}-${process.arch}`;
|
|
1781
|
-
const artifact = parsed.data.platforms[platform];
|
|
1782
|
-
if (!artifact) throw new Error(`The installed CLI has no Service artifact for ${platform}.`);
|
|
1783
|
-
return {
|
|
1784
|
-
...artifact,
|
|
1785
|
-
version: parsed.data.version,
|
|
1786
|
-
platform,
|
|
1787
|
-
minRequiredCliVersion: null
|
|
1788
|
-
};
|
|
1789
|
-
}
|
|
1790
|
-
//#endregion
|
|
1791
|
-
//#region src/runtime/cli-binary-delta.ts
|
|
1792
|
-
function reconstructCliBinaryDelta(input) {
|
|
1793
|
-
verifyBytes({
|
|
1794
|
-
bytes: input.baseBytes,
|
|
1795
|
-
expectedSha256: input.delta.fromSha256,
|
|
1796
|
-
expectedSizeBytes: input.delta.fromSizeBytes,
|
|
1797
|
-
label: "delta base"
|
|
1798
|
-
});
|
|
1799
|
-
const patch = parseCliBinaryDeltaPatch(input.patchPayloadBytes);
|
|
1800
|
-
assertPatchMatchesRelease({
|
|
1801
|
-
delta: input.delta,
|
|
1802
|
-
patch,
|
|
1803
|
-
targetSha256: input.targetSha256,
|
|
1804
|
-
targetSizeBytes: input.targetSizeBytes
|
|
1805
|
-
});
|
|
1806
|
-
const targetBytes = Buffer.alloc(input.targetSizeBytes);
|
|
1807
|
-
input.baseBytes.copy(targetBytes, 0, 0, Math.min(input.baseBytes.byteLength, targetBytes.byteLength));
|
|
1808
|
-
let previousEnd = 0;
|
|
1809
|
-
for (const segment of patch.segments) {
|
|
1810
|
-
const bytes = Buffer.from(segment.dataBase64, "base64");
|
|
1811
|
-
const segmentEnd = segment.offset + bytes.byteLength;
|
|
1812
|
-
if (segment.offset < previousEnd) throw new Error("delta patch segments must be sorted and non-overlapping");
|
|
1813
|
-
if (segmentEnd > targetBytes.byteLength) throw new Error("delta patch segment exceeds the target binary size");
|
|
1814
|
-
bytes.copy(targetBytes, segment.offset);
|
|
1815
|
-
previousEnd = segmentEnd;
|
|
1816
|
-
}
|
|
1817
|
-
verifyBytes({
|
|
1818
|
-
bytes: targetBytes,
|
|
1819
|
-
expectedSha256: input.targetSha256,
|
|
1820
|
-
expectedSizeBytes: input.targetSizeBytes,
|
|
1821
|
-
label: "reconstructed binary"
|
|
1822
|
-
});
|
|
1823
|
-
return targetBytes;
|
|
1824
|
-
}
|
|
1825
|
-
function parseCliBinaryDeltaPatch(bytes) {
|
|
1826
|
-
let value;
|
|
1827
|
-
try {
|
|
1828
|
-
value = JSON.parse(bytes.toString("utf8"));
|
|
1829
|
-
} catch (error) {
|
|
1830
|
-
throw new Error(`delta patch is not valid JSON: ${error instanceof Error ? error.message : String(error)}`);
|
|
1831
|
-
}
|
|
1832
|
-
const parsed = cliBinaryDeltaPatchSchema.safeParse(value);
|
|
1833
|
-
if (!parsed.success) throw new Error(`delta patch is invalid: ${parsed.error.message}`);
|
|
1834
|
-
return parsed.data;
|
|
1835
|
-
}
|
|
1836
|
-
function assertPatchMatchesRelease(input) {
|
|
1837
|
-
const mismatches = [
|
|
1838
|
-
[
|
|
1839
|
-
"format",
|
|
1840
|
-
input.patch.patchFormat,
|
|
1841
|
-
input.delta.patchFormat
|
|
1842
|
-
],
|
|
1843
|
-
[
|
|
1844
|
-
"base sha256",
|
|
1845
|
-
input.patch.baseSha256,
|
|
1846
|
-
input.delta.fromSha256
|
|
1847
|
-
],
|
|
1848
|
-
[
|
|
1849
|
-
"base size",
|
|
1850
|
-
input.patch.baseSizeBytes,
|
|
1851
|
-
input.delta.fromSizeBytes
|
|
1852
|
-
],
|
|
1853
|
-
[
|
|
1854
|
-
"target sha256",
|
|
1855
|
-
input.patch.targetSha256,
|
|
1856
|
-
input.targetSha256
|
|
1857
|
-
],
|
|
1858
|
-
[
|
|
1859
|
-
"target size",
|
|
1860
|
-
input.patch.targetSizeBytes,
|
|
1861
|
-
input.targetSizeBytes
|
|
1862
|
-
]
|
|
1863
|
-
].filter(([, actual, expected]) => actual !== expected);
|
|
1864
|
-
if (mismatches.length > 0) throw new Error(`delta patch metadata mismatch: ${mismatches.map(([label]) => label).join(", ")}`);
|
|
1865
|
-
}
|
|
1866
|
-
function verifyBytes(input) {
|
|
1867
|
-
if (input.bytes.byteLength !== input.expectedSizeBytes) throw new Error(`${input.label} size mismatch: expected ${input.expectedSizeBytes} bytes, received ${input.bytes.byteLength} bytes`);
|
|
1868
|
-
const actualSha256 = createHash("sha256").update(input.bytes).digest("hex");
|
|
1869
|
-
if (actualSha256 !== input.expectedSha256.toLowerCase()) throw new Error(`${input.label} sha256 mismatch: expected ${input.expectedSha256.toLowerCase()}, received ${actualSha256}`);
|
|
1870
|
-
}
|
|
1871
|
-
//#endregion
|
|
1872
|
-
//#region src/runtime/cli-binary-update-artifact.ts
|
|
1873
|
-
const HARDENED_RUNTIME_FLAG_RE = /flags=.*runtime/iu;
|
|
1874
|
-
const SIGNING_TIMESTAMP_RE = /^Timestamp=/mu;
|
|
1875
|
-
async function resolveCliBinaryUpdatePlan(input) {
|
|
1876
|
-
const fullDownloadPlan = resolveFullCliBinaryUpdatePlan(input.release);
|
|
1877
|
-
const versionDeltas = input.release.deltas?.filter((candidate) => candidate.fromVersion === input.currentVersion);
|
|
1878
|
-
if (!versionDeltas?.length) return fullDownloadPlan;
|
|
1879
|
-
let baseBytes;
|
|
1880
|
-
try {
|
|
1881
|
-
baseBytes = await readFile(input.baseBinaryPath);
|
|
1882
|
-
} catch (error) {
|
|
1883
|
-
input.onDeltaFallback(toError(error));
|
|
1884
|
-
return fullDownloadPlan;
|
|
1885
|
-
}
|
|
1886
|
-
const baseSha256 = createHash("sha256").update(baseBytes).digest("hex");
|
|
1887
|
-
const delta = versionDeltas.find((candidate) => candidate.fromSizeBytes === baseBytes.byteLength && candidate.fromSha256.toLowerCase() === baseSha256);
|
|
1888
|
-
if (!delta) return fullDownloadPlan;
|
|
1889
|
-
return {
|
|
1890
|
-
baseBytes,
|
|
1891
|
-
delta,
|
|
1892
|
-
downloadSizeBytes: delta.patchSizeBytes,
|
|
1893
|
-
transport: "delta"
|
|
1894
|
-
};
|
|
1895
|
-
}
|
|
1896
|
-
async function downloadCliBinaryUpdateArtifact(input) {
|
|
1897
|
-
if (input.plan.transport === "delta") {
|
|
1898
|
-
try {
|
|
1899
|
-
return await downloadCliBinaryDelta({
|
|
1900
|
-
...input,
|
|
1901
|
-
baseBytes: input.plan.baseBytes,
|
|
1902
|
-
delta: input.plan.delta
|
|
1903
|
-
});
|
|
1904
|
-
} catch (error) {
|
|
1905
|
-
input.onDeltaFallback(toError(error));
|
|
1906
|
-
}
|
|
1907
|
-
return downloadFullCliBinaryArtifact({
|
|
1908
|
-
...input,
|
|
1909
|
-
plan: resolveFullCliBinaryUpdatePlan(input.release)
|
|
1910
|
-
});
|
|
1911
|
-
}
|
|
1912
|
-
return downloadFullCliBinaryArtifact({
|
|
1913
|
-
...input,
|
|
1914
|
-
plan: input.plan
|
|
1915
|
-
});
|
|
1916
|
-
}
|
|
1917
|
-
async function verifyCliBinaryCodeSignature(input) {
|
|
1918
|
-
const { codeIdentifier, teamIdentifier } = input.release;
|
|
1919
|
-
if (!(codeIdentifier && teamIdentifier)) return;
|
|
1920
|
-
if (process.platform !== "darwin") throw new Error("signed OpenMeld CLI verification requires macOS");
|
|
1921
|
-
const verification = await input.runCommand("/usr/bin/codesign", [
|
|
1922
|
-
"--verify",
|
|
1923
|
-
"--strict",
|
|
1924
|
-
"--verbose=2",
|
|
1925
|
-
input.artifactPath
|
|
1926
|
-
]);
|
|
1927
|
-
if (verification.code !== 0) throw new Error(`binary code signature verification failed: ${commandFailureDetails(verification)}`);
|
|
1928
|
-
const inspection = await input.runCommand("/usr/bin/codesign", [
|
|
1929
|
-
"--display",
|
|
1930
|
-
"--verbose=4",
|
|
1931
|
-
input.artifactPath
|
|
1932
|
-
]);
|
|
1933
|
-
if (inspection.code !== 0) throw new Error(`binary code signature inspection failed: ${commandFailureDetails(inspection)}`);
|
|
1934
|
-
const details = `${inspection.stdout}\n${inspection.stderr}`;
|
|
1935
|
-
for (const expected of [
|
|
1936
|
-
`Identifier=${codeIdentifier}`,
|
|
1937
|
-
`TeamIdentifier=${teamIdentifier}`,
|
|
1938
|
-
"Authority=Developer ID Application:"
|
|
1939
|
-
]) if (!details.includes(expected)) throw new Error(`binary code signature is missing expected identity: ${expected}`);
|
|
1940
|
-
if (!HARDENED_RUNTIME_FLAG_RE.test(details)) throw new Error("binary code signature is missing the hardened runtime");
|
|
1941
|
-
if (!SIGNING_TIMESTAMP_RE.test(details)) throw new Error("binary code signature is missing a trusted timestamp");
|
|
1942
|
-
}
|
|
1943
|
-
async function downloadCliBinaryDelta(input) {
|
|
1944
|
-
const response = await input.fetchImpl(input.delta.patchUrl, {
|
|
1945
|
-
method: "GET",
|
|
1946
|
-
signal: AbortSignal.timeout(input.downloadTimeoutMs)
|
|
1947
|
-
});
|
|
1948
|
-
if (!response.ok) {
|
|
1949
|
-
const body = await response.text().catch(() => "");
|
|
1950
|
-
throw new Error(`binary delta download failed: HTTP ${response.status}${body ? `: ${body}` : ""}`);
|
|
1951
|
-
}
|
|
1952
|
-
const patchBytes = Buffer.from(await response.arrayBuffer());
|
|
1953
|
-
verifyBinaryBytes({
|
|
1954
|
-
bytes: patchBytes,
|
|
1955
|
-
expectedSha256: input.delta.patchSha256,
|
|
1956
|
-
expectedSizeBytes: input.delta.patchSizeBytes,
|
|
1957
|
-
label: "binary delta archive"
|
|
1958
|
-
});
|
|
1959
|
-
let patchPayloadBytes;
|
|
1960
|
-
try {
|
|
1961
|
-
patchPayloadBytes = gunzipSync(patchBytes, { maxOutputLength: input.delta.patchPayloadSizeBytes });
|
|
1962
|
-
} catch (error) {
|
|
1963
|
-
throw new Error(`binary delta could not be decompressed: ${toError(error).message}`);
|
|
1964
|
-
}
|
|
1965
|
-
if (patchPayloadBytes.byteLength !== input.delta.patchPayloadSizeBytes) throw new Error(`binary delta payload size mismatch: expected ${input.delta.patchPayloadSizeBytes} bytes, received ${patchPayloadBytes.byteLength} bytes`);
|
|
1966
|
-
return reconstructCliBinaryDelta({
|
|
1967
|
-
baseBytes: input.baseBytes,
|
|
1968
|
-
delta: input.delta,
|
|
1969
|
-
patchPayloadBytes,
|
|
1970
|
-
targetSha256: input.release.sha256,
|
|
1971
|
-
targetSizeBytes: input.release.sizeBytes
|
|
1972
|
-
});
|
|
1973
|
-
}
|
|
1974
|
-
function resolveFullCliBinaryUpdatePlan(release) {
|
|
1975
|
-
if (hasCompressedCliBinaryTransport(release)) return {
|
|
1976
|
-
downloadSha256: release.archiveSha256,
|
|
1977
|
-
downloadSizeBytes: release.archiveSizeBytes,
|
|
1978
|
-
downloadUrl: release.archiveUrl,
|
|
1979
|
-
transport: "archive"
|
|
1980
|
-
};
|
|
1981
|
-
return {
|
|
1982
|
-
downloadSha256: release.sha256,
|
|
1983
|
-
downloadSizeBytes: release.sizeBytes,
|
|
1984
|
-
downloadUrl: release.url,
|
|
1985
|
-
transport: "raw"
|
|
1986
|
-
};
|
|
1987
|
-
}
|
|
1988
|
-
async function downloadFullCliBinaryArtifact(input) {
|
|
1989
|
-
const response = await input.fetchImpl(input.plan.downloadUrl, {
|
|
1990
|
-
method: "GET",
|
|
1991
|
-
signal: AbortSignal.timeout(input.downloadTimeoutMs)
|
|
1992
|
-
});
|
|
1993
|
-
if (!response.ok) {
|
|
1994
|
-
const body = await response.text().catch(() => "");
|
|
1995
|
-
throw new Error(`binary download failed: HTTP ${response.status}${body ? `: ${body}` : ""}`);
|
|
1996
|
-
}
|
|
1997
|
-
const downloadBytes = Buffer.from(await response.arrayBuffer());
|
|
1998
|
-
verifyBinaryBytes({
|
|
1999
|
-
bytes: downloadBytes,
|
|
2000
|
-
expectedSha256: input.plan.downloadSha256,
|
|
2001
|
-
expectedSizeBytes: input.plan.downloadSizeBytes,
|
|
2002
|
-
label: input.plan.transport === "archive" ? "binary archive" : "binary download"
|
|
2003
|
-
});
|
|
2004
|
-
let artifactBytes = downloadBytes;
|
|
2005
|
-
if (input.plan.transport === "archive") try {
|
|
2006
|
-
artifactBytes = gunzipSync(downloadBytes, { maxOutputLength: input.release.sizeBytes });
|
|
2007
|
-
} catch (error) {
|
|
2008
|
-
throw new Error(`binary archive could not be decompressed: ${toError(error).message}`);
|
|
2009
|
-
}
|
|
2010
|
-
verifyBinaryBytes({
|
|
2011
|
-
bytes: artifactBytes,
|
|
2012
|
-
expectedSha256: input.release.sha256,
|
|
2013
|
-
expectedSizeBytes: input.release.sizeBytes,
|
|
2014
|
-
label: "binary download"
|
|
2015
|
-
});
|
|
2016
|
-
return artifactBytes;
|
|
2017
|
-
}
|
|
2018
|
-
function hasCompressedCliBinaryTransport(release) {
|
|
2019
|
-
return release.archiveFormat === "gzip" && typeof release.archiveUrl === "string" && typeof release.archiveSha256 === "string" && typeof release.archiveSizeBytes === "number";
|
|
2020
|
-
}
|
|
2021
|
-
function verifyBinaryBytes(input) {
|
|
2022
|
-
if (input.bytes.byteLength !== input.expectedSizeBytes) throw new Error(`${input.label} size mismatch: expected ${input.expectedSizeBytes} bytes, received ${input.bytes.byteLength} bytes`);
|
|
2023
|
-
const actualSha256 = createHash("sha256").update(input.bytes).digest("hex");
|
|
2024
|
-
if (actualSha256 !== input.expectedSha256.toLowerCase()) throw new Error(`${input.label} sha256 mismatch: expected ${input.expectedSha256.toLowerCase()}, received ${actualSha256}`);
|
|
2025
|
-
}
|
|
2026
|
-
function commandFailureDetails(result) {
|
|
2027
|
-
return result.stderr.trim() || result.stdout.trim() || `exit ${result.code}`;
|
|
2028
|
-
}
|
|
2029
|
-
function toError(error) {
|
|
2030
|
-
return error instanceof Error ? error : new Error(String(error));
|
|
2031
|
-
}
|
|
2032
|
-
//#endregion
|
|
2033
|
-
//#region src/system/local-operation-diagnostics.ts
|
|
2034
|
-
const ERROR_CODES = /* @__PURE__ */ new Set([
|
|
2035
|
-
"EPERM",
|
|
2036
|
-
"EACCES",
|
|
2037
|
-
"ENOENT",
|
|
2038
|
-
"ENOTDIR",
|
|
2039
|
-
"EISDIR",
|
|
2040
|
-
"EROFS",
|
|
2041
|
-
"ENOSPC",
|
|
2042
|
-
"EBUSY",
|
|
2043
|
-
"ETXTBSY",
|
|
2044
|
-
"EEXIST",
|
|
2045
|
-
"EIO",
|
|
2046
|
-
"EMFILE",
|
|
2047
|
-
"ENFILE",
|
|
2048
|
-
"EINVAL",
|
|
2049
|
-
"ENAMETOOLONG"
|
|
2050
|
-
]);
|
|
2051
|
-
const SYSCALLS = /* @__PURE__ */ new Set([
|
|
2052
|
-
"access",
|
|
2053
|
-
"open",
|
|
2054
|
-
"read",
|
|
2055
|
-
"write",
|
|
2056
|
-
"chmod",
|
|
2057
|
-
"chown",
|
|
2058
|
-
"copyfile",
|
|
2059
|
-
"rename",
|
|
2060
|
-
"unlink",
|
|
2061
|
-
"rmdir",
|
|
2062
|
-
"mkdir",
|
|
2063
|
-
"stat",
|
|
2064
|
-
"lstat",
|
|
2065
|
-
"realpath",
|
|
2066
|
-
"spawn"
|
|
2067
|
-
]);
|
|
2068
|
-
const APP_BUNDLE_PATH_PATTERN = /(?:^|[/\\])[^/\\]+\.app(?:[/\\]|$)/iu;
|
|
2069
|
-
function classifyDiagnosticPath(value) {
|
|
2070
|
-
if (typeof value !== "string" || !value) return "unknown";
|
|
2071
|
-
if (APP_BUNDLE_PATH_PATTERN.test(value)) return "app_bundle";
|
|
2072
|
-
return isAbsolute(value) ? "absolute_other" : "relative";
|
|
2073
|
-
}
|
|
2074
|
-
function collectLocalOperationFailure(error) {
|
|
2075
|
-
let current = error;
|
|
2076
|
-
for (let depth = 0; depth < 4 && current instanceof Error; depth += 1) {
|
|
2077
|
-
const native = current;
|
|
2078
|
-
if (native.code && ERROR_CODES.has(native.code)) return {
|
|
2079
|
-
code: native.code,
|
|
2080
|
-
...Number.isSafeInteger(native.errno) ? { errno: native.errno } : {},
|
|
2081
|
-
...native.syscall && SYSCALLS.has(native.syscall) ? { syscall: native.syscall } : {},
|
|
2082
|
-
pathCategory: classifyDiagnosticPath(native.path),
|
|
2083
|
-
...native.dest === void 0 ? {} : { destinationCategory: classifyDiagnosticPath(native.dest) }
|
|
2084
|
-
};
|
|
2085
|
-
current = current.cause;
|
|
2086
|
-
}
|
|
2087
|
-
}
|
|
2088
|
-
//#endregion
|
|
2089
|
-
//#region src/local-service/lifecycle/daemon-lifecycle-journal.ts
|
|
2090
|
-
const DAEMON_LIFECYCLE_EVENT_TYPES = [
|
|
2091
|
-
"connection.state",
|
|
2092
|
-
"daemon.crash",
|
|
2093
|
-
"lifecycle.command.begin",
|
|
2094
|
-
"lifecycle.command.end",
|
|
2095
|
-
"owner.snapshot",
|
|
2096
|
-
"route_catalog.initial_load",
|
|
2097
|
-
"runtime_state.takeover",
|
|
2098
|
-
"stop.controlled_drain",
|
|
2099
|
-
"stop.strategy.selected",
|
|
2100
|
-
"service_manager.action",
|
|
2101
|
-
"service_manager.registration_reconcile",
|
|
2102
|
-
"process_stop.action",
|
|
2103
|
-
"service_contract.write",
|
|
2104
|
-
"stop.signal.observed"
|
|
2105
|
-
];
|
|
2106
|
-
const DAEMON_STOP_CAUSES = [
|
|
2107
|
-
"user_stop",
|
|
2108
|
-
"controlled_service_update",
|
|
2109
|
-
"service_crash",
|
|
2110
|
-
"network_disconnect",
|
|
2111
|
-
"unknown"
|
|
2112
|
-
];
|
|
2113
|
-
function toJournalErrorMessage(error) {
|
|
2114
|
-
return error instanceof Error ? error.message : String(error);
|
|
2115
|
-
}
|
|
2116
|
-
function normalizeSessionId(value) {
|
|
2117
|
-
const normalized = typeof value === "string" ? value.trim() : "";
|
|
2118
|
-
return normalized.length > 0 ? normalized : null;
|
|
2119
|
-
}
|
|
2120
|
-
function resolveDaemonStopCause(input) {
|
|
2121
|
-
if (input.explicitCause) return input.explicitCause;
|
|
2122
|
-
if (input.type === "daemon.crash") return "service_crash";
|
|
2123
|
-
if (input.type === "connection.state") return "unknown";
|
|
2124
|
-
if (input.intent === "stop") return "user_stop";
|
|
2125
|
-
if (input.intent === "upgrade_reconcile" || input.intent === "reinstall" || input.intent === "startup_check" || input.intent === "status_cleanup") return "controlled_service_update";
|
|
2126
|
-
return "unknown";
|
|
2127
|
-
}
|
|
2128
|
-
function isDaemonLifecycleEvent(event) {
|
|
2129
|
-
if (typeof event !== "object" || event === null) return false;
|
|
2130
|
-
const candidate = event;
|
|
2131
|
-
return candidate.schema === "openmeld-daemon-lifecycle-event-v1" && candidate.v === 1 && DAEMON_LIFECYCLE_EVENT_TYPES.includes(candidate.type) && typeof candidate.timestamp === "string" && candidate.timestamp.length > 0 && typeof candidate.lane === "string" && candidate.lane.length > 0 && typeof candidate.intent === "string" && candidate.intent.length > 0 && typeof candidate.command === "string" && candidate.command.length > 0 && typeof candidate.pid === "number" && Number.isInteger(candidate.pid) && candidate.pid > 0 && (candidate.sessionId === null || typeof candidate.sessionId === "string" && candidate.sessionId.length > 0) && (candidate.stopCause === void 0 || DAEMON_STOP_CAUSES.includes(candidate.stopCause)) && typeof candidate.result === "string" && candidate.result.length > 0;
|
|
2132
|
-
}
|
|
2133
|
-
async function resolveDaemonLifecycleAttribution(input) {
|
|
2134
|
-
const lockMeta = await readDaemonServiceLifecycleLockMeta().catch(() => null);
|
|
2135
|
-
return {
|
|
2136
|
-
command: input.command?.trim() || (typeof lockMeta?.command === "string" ? lockMeta.command.trim() : "") || "unknown",
|
|
2137
|
-
intent: input.intent ?? (typeof lockMeta?.intent === "string" ? lockMeta.intent : "unknown"),
|
|
2138
|
-
lane: resolveOpenMeldEnvPreset(input.pathInput),
|
|
2139
|
-
pid: typeof lockMeta?.pid === "number" && lockMeta.pid > 0 ? lockMeta.pid : process$1.pid,
|
|
2140
|
-
sessionId: normalizeSessionId(lockMeta?.sessionId) ?? resolveCliContextId()
|
|
2141
|
-
};
|
|
2142
|
-
}
|
|
2143
|
-
async function emitDaemonLifecycleEvent(input) {
|
|
2144
|
-
assertNoPublishedProductionMutationDuringTests(input.pathInput ?? {}, "OpenMeld Service lifecycle journal");
|
|
2145
|
-
const journalPath = daemonLifecycleJournalPath(input.pathInput);
|
|
2146
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
2147
|
-
const attribution = input.type === "connection.state" ? {
|
|
2148
|
-
command: "openmeld service run",
|
|
2149
|
-
intent: "unknown",
|
|
2150
|
-
lane: resolveOpenMeldEnvPreset(input.pathInput),
|
|
2151
|
-
pid: process$1.pid,
|
|
2152
|
-
sessionId: resolveCliContextId()
|
|
2153
|
-
} : await resolveDaemonLifecycleAttribution(input);
|
|
2154
|
-
const event = {
|
|
2155
|
-
schema: "openmeld-daemon-lifecycle-event-v1",
|
|
2156
|
-
v: 1,
|
|
2157
|
-
type: input.type,
|
|
2158
|
-
timestamp,
|
|
2159
|
-
lane: attribution.lane,
|
|
2160
|
-
intent: attribution.intent,
|
|
2161
|
-
command: attribution.command,
|
|
2162
|
-
pid: attribution.pid,
|
|
2163
|
-
sessionId: attribution.sessionId,
|
|
2164
|
-
stopCause: resolveDaemonStopCause({
|
|
2165
|
-
explicitCause: input.stopCause,
|
|
2166
|
-
intent: attribution.intent,
|
|
2167
|
-
result: input.result,
|
|
2168
|
-
type: input.type
|
|
2169
|
-
}),
|
|
2170
|
-
result: input.result,
|
|
2171
|
-
...input.metadata ? { metadata: input.metadata } : {}
|
|
2172
|
-
};
|
|
2173
|
-
if (!isDaemonLifecycleEvent(event)) {
|
|
2174
|
-
console.warn(`[openmeld:lifecycle-journal] rejected invalid event ${input.type}`);
|
|
2175
|
-
return;
|
|
2176
|
-
}
|
|
2177
|
-
try {
|
|
2178
|
-
await mkdir(dirname(journalPath), { recursive: true });
|
|
2179
|
-
await appendFile(journalPath, `${JSON.stringify(event)}\n`, "utf8");
|
|
2180
|
-
} catch (error) {
|
|
2181
|
-
console.warn(`[openmeld:lifecycle-journal] failed to append event ${input.type}: ${toJournalErrorMessage(error)}`);
|
|
2182
|
-
}
|
|
2183
|
-
}
|
|
2184
|
-
async function runWithDaemonLifecycleCommandJournal(input) {
|
|
2185
|
-
await emitDaemonLifecycleEvent({
|
|
2186
|
-
type: "lifecycle.command.begin",
|
|
2187
|
-
result: "started",
|
|
2188
|
-
metadata: input.includeProcessUptime ? {
|
|
2189
|
-
...input.metadata,
|
|
2190
|
-
processUptimeMs: Math.round(process$1.uptime() * 1e3)
|
|
2191
|
-
} : input.metadata,
|
|
2192
|
-
pathInput: input.pathInput,
|
|
2193
|
-
command: input.command,
|
|
2194
|
-
intent: input.intent
|
|
2195
|
-
});
|
|
2196
|
-
try {
|
|
2197
|
-
const result = await input.run();
|
|
2198
|
-
const resolvedResult = input.resolveResult?.(result) ?? { result: "completed" };
|
|
2199
|
-
await emitDaemonLifecycleEvent({
|
|
2200
|
-
type: "lifecycle.command.end",
|
|
2201
|
-
result: resolvedResult.result,
|
|
2202
|
-
metadata: resolvedResult.metadata,
|
|
2203
|
-
pathInput: input.pathInput,
|
|
2204
|
-
command: input.command,
|
|
2205
|
-
intent: input.intent
|
|
2206
|
-
});
|
|
2207
|
-
return result;
|
|
2208
|
-
} catch (error) {
|
|
2209
|
-
await emitDaemonLifecycleEvent({
|
|
2210
|
-
type: "lifecycle.command.end",
|
|
2211
|
-
result: "failed",
|
|
2212
|
-
metadata: { errorMessage: toJournalErrorMessage(error) },
|
|
2213
|
-
pathInput: input.pathInput,
|
|
2214
|
-
command: input.command,
|
|
2215
|
-
intent: input.intent
|
|
2216
|
-
});
|
|
2217
|
-
throw error;
|
|
2218
|
-
}
|
|
2219
|
-
}
|
|
2220
|
-
async function runDaemonServiceManagerAction(input) {
|
|
2221
|
-
const startedAtMs = Date.now();
|
|
2222
|
-
try {
|
|
2223
|
-
const result = await input.run();
|
|
2224
|
-
await emitDaemonLifecycleEvent({
|
|
2225
|
-
type: "service_manager.action",
|
|
2226
|
-
result: "completed",
|
|
2227
|
-
metadata: {
|
|
2228
|
-
action: input.action,
|
|
2229
|
-
controller: input.controller,
|
|
2230
|
-
durationMs: Date.now() - startedAtMs,
|
|
2231
|
-
...input.metadata ?? {}
|
|
2232
|
-
},
|
|
2233
|
-
pathInput: input.pathInput,
|
|
2234
|
-
command: input.command,
|
|
2235
|
-
intent: input.intent
|
|
2236
|
-
});
|
|
2237
|
-
return result;
|
|
2238
|
-
} catch (error) {
|
|
2239
|
-
let errorMetadata = null;
|
|
2240
|
-
try {
|
|
2241
|
-
errorMetadata = input.resolveErrorMetadata?.(error) ?? null;
|
|
2242
|
-
} catch {
|
|
2243
|
-
errorMetadata = null;
|
|
2244
|
-
}
|
|
2245
|
-
await emitDaemonLifecycleEvent({
|
|
2246
|
-
type: "service_manager.action",
|
|
2247
|
-
result: "failed",
|
|
2248
|
-
metadata: {
|
|
2249
|
-
action: input.action,
|
|
2250
|
-
controller: input.controller,
|
|
2251
|
-
durationMs: Date.now() - startedAtMs,
|
|
2252
|
-
errorMessage: toJournalErrorMessage(error),
|
|
2253
|
-
...errorMetadata ?? {},
|
|
2254
|
-
...input.metadata ?? {}
|
|
2255
|
-
},
|
|
2256
|
-
pathInput: input.pathInput,
|
|
2257
|
-
command: input.command,
|
|
2258
|
-
intent: input.intent
|
|
2259
|
-
});
|
|
2260
|
-
throw error;
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
const DAEMON_LIFECYCLE_ORIGIN_EVENT_TYPES = /* @__PURE__ */ new Set([
|
|
2264
|
-
"daemon.crash",
|
|
2265
|
-
"lifecycle.command.end",
|
|
2266
|
-
"process_stop.action",
|
|
2267
|
-
"runtime_state.takeover",
|
|
2268
|
-
"service_contract.write",
|
|
2269
|
-
"service_manager.action"
|
|
2270
|
-
]);
|
|
2271
|
-
async function readLatestDaemonLifecycleOriginEvent(input = {}) {
|
|
2272
|
-
return await readLatestDaemonLifecycleEvent({
|
|
2273
|
-
pathInput: input.pathInput,
|
|
2274
|
-
typeFilter: DAEMON_LIFECYCLE_ORIGIN_EVENT_TYPES
|
|
2275
|
-
});
|
|
2276
|
-
}
|
|
2277
|
-
async function readLatestDaemonLifecycleConnectionStateEvent(input = {}) {
|
|
2278
|
-
return await readLatestDaemonLifecycleEvent({
|
|
2279
|
-
pathInput: input.pathInput,
|
|
2280
|
-
typeFilter: /* @__PURE__ */ new Set(["connection.state"])
|
|
2281
|
-
});
|
|
2282
|
-
}
|
|
2283
|
-
async function readLatestDaemonLifecycleEvent(input) {
|
|
2284
|
-
const journalPath = daemonLifecycleJournalPath(input.pathInput);
|
|
2285
|
-
let content;
|
|
2286
|
-
try {
|
|
2287
|
-
content = await readFile(journalPath, "utf8");
|
|
2288
|
-
} catch (error) {
|
|
2289
|
-
if (error.code === "ENOENT") return null;
|
|
2290
|
-
throw error;
|
|
2291
|
-
}
|
|
2292
|
-
const lines = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
2293
|
-
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
2294
|
-
const line = lines[index];
|
|
2295
|
-
if (!line) continue;
|
|
2296
|
-
try {
|
|
2297
|
-
const parsed = JSON.parse(line);
|
|
2298
|
-
if (isDaemonLifecycleEvent(parsed) && input.typeFilter.has(parsed.type)) return parsed;
|
|
2299
|
-
} catch {}
|
|
2300
|
-
}
|
|
2301
|
-
return null;
|
|
2302
|
-
}
|
|
2303
|
-
async function readRecentDaemonLifecycleEvents(input) {
|
|
2304
|
-
if (input.maxEntries <= 0) return [];
|
|
2305
|
-
const journalPath = daemonLifecycleJournalPath(input.pathInput);
|
|
2306
|
-
let content;
|
|
2307
|
-
try {
|
|
2308
|
-
content = await readFile(journalPath, "utf8");
|
|
2309
|
-
} catch (error) {
|
|
2310
|
-
if (error.code === "ENOENT") return [];
|
|
2311
|
-
throw error;
|
|
2312
|
-
}
|
|
2313
|
-
const lines = content.split("\n").map((line) => line.trim()).filter((line) => line.length > 0);
|
|
2314
|
-
const recent = [];
|
|
2315
|
-
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
2316
|
-
const line = lines[index];
|
|
2317
|
-
if (!line) continue;
|
|
2318
|
-
try {
|
|
2319
|
-
const parsed = JSON.parse(line);
|
|
2320
|
-
if (isDaemonLifecycleEvent(parsed)) {
|
|
2321
|
-
recent.push(parsed);
|
|
2322
|
-
if (recent.length >= input.maxEntries) break;
|
|
2323
|
-
}
|
|
2324
|
-
} catch {}
|
|
2325
|
-
}
|
|
2326
|
-
return recent.reverse();
|
|
2327
|
-
}
|
|
2328
|
-
async function resolveRecentDaemonSignalStopCause(input = {}) {
|
|
2329
|
-
const nowMs = Date.now();
|
|
2330
|
-
const maxAgeMs = input.maxAgeMs ?? 3e4;
|
|
2331
|
-
const events = await readRecentDaemonLifecycleEvents({
|
|
2332
|
-
maxEntries: 32,
|
|
2333
|
-
pathInput: input.pathInput
|
|
2334
|
-
});
|
|
2335
|
-
for (const event of events.toReversed()) {
|
|
2336
|
-
const eventAtMs = Date.parse(event.timestamp);
|
|
2337
|
-
if (!Number.isFinite(eventAtMs) || nowMs - eventAtMs < 0 || nowMs - eventAtMs > maxAgeMs) continue;
|
|
2338
|
-
if (event.stopCause === "user_stop" || event.stopCause === "controlled_service_update") return event.stopCause;
|
|
2339
|
-
}
|
|
2340
|
-
return "unknown";
|
|
2341
|
-
}
|
|
2342
|
-
function formatDaemonLifecycleOriginSummary(event) {
|
|
2343
|
-
const intent = formatDaemonLifecycleIntent(event.intent);
|
|
2344
|
-
return `${event.result} ${intent} from ${event.command} at ${event.timestamp} (pid ${event.pid})`;
|
|
2345
|
-
}
|
|
2346
|
-
function formatDaemonLifecycleIntent(intent) {
|
|
2347
|
-
if (intent === "unknown") return "OpenMeld Service task";
|
|
2348
|
-
return intent.replaceAll("_", " ");
|
|
2349
|
-
}
|
|
2350
|
-
//#endregion
|
|
2351
|
-
//#region src/local-service/lifecycle/daemon-service-artifact.ts
|
|
2352
|
-
function resolveDaemonServiceArtifact(input) {
|
|
2353
|
-
const installVersion = input.installStatus.installed ? input.installStatus.state.daemonVersion : null;
|
|
2354
|
-
const expectedBundleId = input.serviceContract?.bundleId ?? null;
|
|
2355
|
-
const expectedDaemonVersion = input.expectedVersion;
|
|
2356
|
-
const activeBundleVersion = input.activeBundle?.daemonVersion ?? null;
|
|
2357
|
-
const driftReasonCodes = input.activeBundle ? collectActiveBundleDriftReasonCodes({
|
|
2358
|
-
activeBundle: input.activeBundle,
|
|
2359
|
-
activeBundleEntryPath: input.activeBundleEntryPath,
|
|
2360
|
-
activeBundleSourceAvailable: input.activeBundleSourceAvailable,
|
|
2361
|
-
installedBundleFingerprint: input.installedBundleFingerprint,
|
|
2362
|
-
expectedBundleId,
|
|
2363
|
-
expectedDaemonVersion,
|
|
2364
|
-
pathInput: input.pathInput
|
|
2365
|
-
}) : ["bundle_missing"];
|
|
2366
|
-
const isAligned = driftReasonCodes.length === 0;
|
|
2367
|
-
return {
|
|
2368
|
-
expectedVersion: input.expectedVersion,
|
|
2369
|
-
installVersion,
|
|
2370
|
-
activeBundleVersion,
|
|
2371
|
-
resolvedEntryPath: isAligned ? input.activeBundleEntryPath : null,
|
|
2372
|
-
driftReasonCodes,
|
|
2373
|
-
isAligned
|
|
2374
|
-
};
|
|
2375
|
-
}
|
|
2376
|
-
function collectActiveBundleDriftReasonCodes(input) {
|
|
2377
|
-
const driftReasonCodes = [];
|
|
2378
|
-
if (hasBundleVersionDrift(input)) driftReasonCodes.push("bundle_version_drift");
|
|
2379
|
-
if (hasBundleIdDrift(input)) driftReasonCodes.push("bundle_id_drift");
|
|
2380
|
-
if (!isDaemonBundleSourceAllowedForLane({
|
|
2381
|
-
sourceKind: input.activeBundle.sourceKind,
|
|
2382
|
-
pathInput: input.pathInput
|
|
2383
|
-
})) driftReasonCodes.push("bundle_lane_drift");
|
|
2384
|
-
if (input.activeBundle.bundleFormat === "legacy_linked_v1") {
|
|
2385
|
-
driftReasonCodes.push("bundle_strategy_legacy");
|
|
2386
|
-
if (input.activeBundleSourceAvailable === false) driftReasonCodes.push("bundle_provenance_drift");
|
|
2387
|
-
} else if (hasBundleContentDrift(input)) driftReasonCodes.push("bundle_content_drift");
|
|
2388
|
-
if (!input.activeBundleEntryPath) driftReasonCodes.push("bundle_path_invalid");
|
|
2389
|
-
return driftReasonCodes;
|
|
2390
|
-
}
|
|
2391
|
-
function hasBundleVersionDrift(input) {
|
|
2392
|
-
return input.activeBundle.daemonVersion !== input.expectedDaemonVersion;
|
|
2393
|
-
}
|
|
2394
|
-
function hasBundleIdDrift(input) {
|
|
2395
|
-
return input.expectedBundleId !== null && input.activeBundle.bundleId !== input.expectedBundleId;
|
|
2396
|
-
}
|
|
2397
|
-
function hasBundleContentDrift(input) {
|
|
2398
|
-
return input.installedBundleFingerprint === null || input.activeBundle.sourceDistFingerprint !== input.installedBundleFingerprint;
|
|
2399
|
-
}
|
|
2400
|
-
//#endregion
|
|
2401
|
-
//#region src/local-service/lifecycle/daemon-service-update-state.ts
|
|
2402
|
-
const DAEMON_SERVICE_UPDATE_JOB_SCHEMA = OPENMELD_DAEMON_SERVICE_UPDATE_JOB_SCHEMA;
|
|
2403
|
-
function daemonServicePendingUpdatePath(pathInput = {}) {
|
|
2404
|
-
return join(daemonRuntimeStateRootPath(pathInput), "service-update.json");
|
|
2405
|
-
}
|
|
2406
|
-
function daemonServiceLastUpdatePath(pathInput = {}) {
|
|
2407
|
-
return join(daemonRuntimeStateRootPath(pathInput), "service-update-last.json");
|
|
2408
|
-
}
|
|
2409
|
-
async function readPendingDaemonServiceUpdate(pathInput = {}) {
|
|
2410
|
-
return await readDaemonServiceUpdateJob(daemonServicePendingUpdatePath(pathInput));
|
|
2411
|
-
}
|
|
2412
|
-
async function readLastDaemonServiceUpdate(pathInput = {}) {
|
|
2413
|
-
return await readDaemonServiceUpdateJob(daemonServiceLastUpdatePath(pathInput));
|
|
2414
|
-
}
|
|
2415
|
-
async function persistPendingDaemonServiceUpdate(job, pathInput = {}) {
|
|
2416
|
-
await writeUpdateJobAtomically({
|
|
2417
|
-
job,
|
|
2418
|
-
path: daemonServicePendingUpdatePath(pathInput)
|
|
2419
|
-
});
|
|
2420
|
-
}
|
|
2421
|
-
async function completePendingDaemonServiceUpdate(job, pathInput = {}, retainPending = false) {
|
|
2422
|
-
await writeUpdateJobAtomically({
|
|
2423
|
-
job,
|
|
2424
|
-
path: daemonServiceLastUpdatePath(pathInput)
|
|
2425
|
-
});
|
|
2426
|
-
if (retainPending) {
|
|
2427
|
-
await persistPendingDaemonServiceUpdate(job, pathInput);
|
|
2428
|
-
return;
|
|
2429
|
-
}
|
|
2430
|
-
await rm(daemonServicePendingUpdatePath(pathInput), { force: true });
|
|
2431
|
-
}
|
|
2432
|
-
async function readDaemonServiceUpdateJob(path) {
|
|
2433
|
-
const raw = await readFile(path, "utf8").catch((error) => {
|
|
2434
|
-
if (error.code === "ENOENT") return null;
|
|
2435
|
-
throw error;
|
|
2436
|
-
});
|
|
2437
|
-
if (raw === null) return null;
|
|
2438
|
-
const parsed = storedDaemonServiceUpdateJobSchema.safeParse(JSON.parse(raw));
|
|
2439
|
-
if (!parsed.success) throw new Error("OpenMeld Service update state is invalid.");
|
|
2440
|
-
if (parsed.data.v === 2) return parsed.data;
|
|
2441
|
-
const { status, ...legacyJob } = parsed.data;
|
|
2442
|
-
return daemonServiceUpdateJobSchema.parse({
|
|
2443
|
-
...legacyJob,
|
|
2444
|
-
v: 2,
|
|
2445
|
-
schema: DAEMON_SERVICE_UPDATE_JOB_SCHEMA,
|
|
2446
|
-
phase: migrateLegacyPhase(status),
|
|
2447
|
-
requestSource: "cli"
|
|
2448
|
-
});
|
|
2449
|
-
}
|
|
2450
|
-
function migrateLegacyPhase(status) {
|
|
2451
|
-
switch (status) {
|
|
2452
|
-
case "scheduled": return "waiting_for_work";
|
|
2453
|
-
case "running": return "updating";
|
|
2454
|
-
case "completed": return "updated";
|
|
2455
|
-
case "failed": return "needs_help";
|
|
2456
|
-
default: return status;
|
|
2457
|
-
}
|
|
2458
|
-
}
|
|
2459
|
-
async function writeUpdateJobAtomically(input) {
|
|
2460
|
-
const temporaryPath = `${input.path}.${String(process.pid)}.tmp`;
|
|
2461
|
-
await mkdir(dirname(input.path), { recursive: true });
|
|
2462
|
-
await writeFile(temporaryPath, `${JSON.stringify(input.job, null, 2)}\n`, {
|
|
2463
|
-
encoding: "utf8",
|
|
2464
|
-
mode: 384
|
|
2465
|
-
});
|
|
2466
|
-
await rename(temporaryPath, input.path);
|
|
2467
|
-
}
|
|
2468
|
-
//#endregion
|
|
2469
|
-
//#region src/local-service/lifecycle/daemon-service-bundle.ts
|
|
2470
|
-
const DAEMON_ACTIVE_BUNDLE_SCHEMA = "openmeld-daemon-active-bundle-v2";
|
|
2471
|
-
const DAEMON_ACTIVE_BUNDLE_LEGACY_SCHEMA = "openmeld-daemon-active-bundle-v1";
|
|
2472
|
-
const DAEMON_CLI_ENTRY_NAMES = ["openmeld-dev.js", "openmeld.js"];
|
|
2473
|
-
const DAEMON_BUNDLE_SOURCE_KIND_WORKSPACE = "workspace";
|
|
2474
|
-
const DAEMON_BUNDLE_SOURCE_KIND_PACKAGE_INSTALL = "package_install";
|
|
2475
|
-
const DAEMON_BUNDLE_SOURCE_KIND_NPX_CACHE = "npx_cache";
|
|
2476
|
-
const DAEMON_BUNDLE_SOURCE_KIND_UNKNOWN = "unknown";
|
|
2477
|
-
const DAEMON_SOURCE_DIST_IGNORED_TOP_LEVEL_DIRS = /* @__PURE__ */ new Set(["binary", "native"]);
|
|
2478
|
-
function daemonServiceActiveBundlePath(pathInput = {}) {
|
|
2479
|
-
return daemonServiceActiveBundleStatePath(pathInput);
|
|
2480
|
-
}
|
|
2481
|
-
function daemonServiceLauncherPath(pathInput = {}) {
|
|
2482
|
-
return daemonServiceStableLauncherPath(pathInput);
|
|
2483
|
-
}
|
|
2484
|
-
function daemonServiceExecutableWrapperPath(pathInput = {}) {
|
|
2485
|
-
return daemonServiceStableExecutableWrapperPath(pathInput);
|
|
2486
|
-
}
|
|
2487
|
-
function daemonServiceBinaryExecutablePath(pathInput = {}) {
|
|
2488
|
-
return daemonServiceStableBinaryExecutablePath(pathInput);
|
|
2489
|
-
}
|
|
2490
|
-
function daemonServiceUpdateWorkerBinaryPath(pathInput = {}) {
|
|
2491
|
-
return daemonServiceUpdateWorkerBinaryExecutablePath(pathInput);
|
|
2492
|
-
}
|
|
2493
|
-
function daemonServiceExecutableWrapperPaths(pathInput = {}) {
|
|
2494
|
-
return daemonServiceExecutableWrapperPaths$1(pathInput);
|
|
2495
|
-
}
|
|
2496
|
-
function daemonServiceRecognizedExecutablePaths(pathInput = {}) {
|
|
2497
|
-
return daemonServiceRecognizedExecutablePaths$1(pathInput);
|
|
2498
|
-
}
|
|
2499
|
-
function daemonServiceLegacyWrapperPath(pathInput = {}) {
|
|
2500
|
-
return daemonServiceLegacyExecutableWrapperPath(pathInput);
|
|
2501
|
-
}
|
|
2502
|
-
function resolveDaemonBundleRootPath(bundleId, pathInput = {}) {
|
|
2503
|
-
return join(daemonRuntimeBundlesPath(pathInput), bundleId);
|
|
2504
|
-
}
|
|
2505
|
-
function isDaemonBundleSourceAllowedForLane(input) {
|
|
2506
|
-
if (input.sourceKind !== DAEMON_BUNDLE_SOURCE_KIND_WORKSPACE) return true;
|
|
2507
|
-
return resolveOpenMeldEnvPreset(input.pathInput) === "dev-local";
|
|
2508
|
-
}
|
|
2509
|
-
async function readDaemonActiveBundleState(pathInput = {}) {
|
|
2510
|
-
const raw = await readFile(daemonServiceActiveBundlePath(pathInput), "utf8").catch((error) => {
|
|
2511
|
-
if (getErrorCode$1(error) === "ENOENT") return null;
|
|
2512
|
-
throw error;
|
|
2513
|
-
});
|
|
2514
|
-
if (raw === null) return null;
|
|
2515
|
-
try {
|
|
2516
|
-
const parsed = JSON.parse(raw);
|
|
2517
|
-
if (parsed.v === 2 && parsed.schema === DAEMON_ACTIVE_BUNDLE_SCHEMA) {
|
|
2518
|
-
if (typeof parsed.bundleId !== "string" || parsed.bundleId.length === 0 || typeof parsed.daemonVersion !== "string" || parsed.daemonVersion.length === 0 || typeof parsed.entryScriptRelativePath !== "string" || parsed.entryScriptRelativePath.length === 0 || !isDaemonBundleFormat(parsed.bundleFormat) || typeof parsed.sourceEntryScriptPath !== "string" || parsed.sourceEntryScriptPath.length === 0 || typeof parsed.sourcePackageRootPath !== "string" || parsed.sourcePackageRootPath.length === 0 || typeof parsed.sourceDistRootPath !== "string" || parsed.sourceDistRootPath.length === 0 || !isDaemonBundleSourceKind(parsed.sourceKind) || typeof parsed.createdAt !== "string" || parsed.createdAt.length === 0 || typeof parsed.updatedAt !== "string" || parsed.updatedAt.length === 0) return null;
|
|
2519
|
-
return {
|
|
2520
|
-
v: 2,
|
|
2521
|
-
schema: DAEMON_ACTIVE_BUNDLE_SCHEMA,
|
|
2522
|
-
bundleId: parsed.bundleId,
|
|
2523
|
-
daemonVersion: parsed.daemonVersion,
|
|
2524
|
-
entryScriptRelativePath: parsed.entryScriptRelativePath,
|
|
2525
|
-
bundleFormat: parsed.bundleFormat,
|
|
2526
|
-
sourceEntryScriptPath: parsed.sourceEntryScriptPath,
|
|
2527
|
-
sourcePackageRootPath: parsed.sourcePackageRootPath,
|
|
2528
|
-
sourceDistRootPath: parsed.sourceDistRootPath,
|
|
2529
|
-
sourceDistFingerprint: normalizeOptionalText$54(parsed.sourceDistFingerprint),
|
|
2530
|
-
sourceKind: parsed.sourceKind,
|
|
2531
|
-
createdAt: parsed.createdAt,
|
|
2532
|
-
updatedAt: parsed.updatedAt
|
|
2533
|
-
};
|
|
2534
|
-
}
|
|
2535
|
-
const legacyParsed = parsed;
|
|
2536
|
-
if (legacyParsed.v !== 1 || legacyParsed.schema !== DAEMON_ACTIVE_BUNDLE_LEGACY_SCHEMA || typeof legacyParsed.bundleId !== "string" || legacyParsed.bundleId.length === 0 || typeof legacyParsed.daemonVersion !== "string" || legacyParsed.daemonVersion.length === 0 || typeof legacyParsed.entryScriptRelativePath !== "string" || legacyParsed.entryScriptRelativePath.length === 0 || typeof legacyParsed.sourceDistRootPath !== "string" || legacyParsed.sourceDistRootPath.length === 0 || typeof legacyParsed.createdAt !== "string" || legacyParsed.createdAt.length === 0 || typeof legacyParsed.updatedAt !== "string" || legacyParsed.updatedAt.length === 0) return null;
|
|
2537
|
-
const sourceEntryScriptPath = join(legacyParsed.sourceDistRootPath, basename(legacyParsed.entryScriptRelativePath));
|
|
2538
|
-
const sourcePackageRootPath = dirname(legacyParsed.sourceDistRootPath);
|
|
2539
|
-
return {
|
|
2540
|
-
v: 2,
|
|
2541
|
-
schema: DAEMON_ACTIVE_BUNDLE_SCHEMA,
|
|
2542
|
-
bundleId: legacyParsed.bundleId,
|
|
2543
|
-
daemonVersion: legacyParsed.daemonVersion,
|
|
2544
|
-
entryScriptRelativePath: legacyParsed.entryScriptRelativePath,
|
|
2545
|
-
bundleFormat: "legacy_linked_v1",
|
|
2546
|
-
sourceEntryScriptPath,
|
|
2547
|
-
sourcePackageRootPath,
|
|
2548
|
-
sourceDistRootPath: legacyParsed.sourceDistRootPath,
|
|
2549
|
-
sourceDistFingerprint: null,
|
|
2550
|
-
sourceKind: inferDaemonBundleSourceKind(sourcePackageRootPath),
|
|
2551
|
-
createdAt: legacyParsed.createdAt,
|
|
2552
|
-
updatedAt: legacyParsed.updatedAt
|
|
2553
|
-
};
|
|
2554
|
-
} catch {
|
|
2555
|
-
return null;
|
|
2556
|
-
}
|
|
2557
|
-
}
|
|
2558
|
-
async function resolveAlignedDaemonActiveBundleEntryPath(input = {}) {
|
|
2559
|
-
const [installStatus, serviceContract, state] = await Promise.all([
|
|
2560
|
-
getDaemonStatus(),
|
|
2561
|
-
readDaemonServiceContract().catch(() => null),
|
|
2562
|
-
readDaemonActiveBundleState()
|
|
2563
|
-
]);
|
|
2564
|
-
const expectedVersion = input.expectedVersion ?? serviceContract?.daemonVersion ?? (installStatus.installed ? installStatus.state.daemonVersion : state?.daemonVersion ?? "unknown");
|
|
2565
|
-
const matchingServiceContract = input.expectedVersion && serviceContract?.daemonVersion !== input.expectedVersion ? null : serviceContract;
|
|
2566
|
-
const activeBundleEntryPath = await resolveDaemonBundleEntryPathFromState(state);
|
|
2567
|
-
const installedBundleFingerprint = activeBundleEntryPath ? await resolveInstalledDaemonBundleFingerprint(state) : null;
|
|
2568
|
-
return resolveDaemonServiceArtifact({
|
|
2569
|
-
expectedVersion,
|
|
2570
|
-
installStatus,
|
|
2571
|
-
serviceContract: matchingServiceContract,
|
|
2572
|
-
activeBundle: state,
|
|
2573
|
-
activeBundleSourceAvailable: state && state.bundleFormat === "legacy_linked_v1" ? await pathExists$4(state.sourcePackageRootPath).catch(() => null) : null,
|
|
2574
|
-
activeBundleEntryPath,
|
|
2575
|
-
installedBundleFingerprint
|
|
2576
|
-
}).resolvedEntryPath;
|
|
2577
|
-
}
|
|
2578
|
-
async function resolveInstalledDaemonBundleFingerprint(state, pathInput = {}) {
|
|
2579
|
-
if (state?.bundleFormat === "binary_v1") {
|
|
2580
|
-
const entryPath = await resolveDaemonBundleEntryPathFromState(state, pathInput);
|
|
2581
|
-
return entryPath ? await hashDaemonBinaryFile(entryPath) : null;
|
|
2582
|
-
}
|
|
2583
|
-
if (state?.bundleFormat === "self_contained_v1") {
|
|
2584
|
-
const bundleRootPath = resolveDaemonBundleRootPath(state.bundleId, pathInput);
|
|
2585
|
-
const distRootPath = join(bundleRootPath, dirname(state.entryScriptRelativePath));
|
|
2586
|
-
const relativeDistRootPath = relative(bundleRootPath, distRootPath);
|
|
2587
|
-
if (relativeDistRootPath === ".." || relativeDistRootPath.startsWith(`..${sep}`) || isAbsolute(relativeDistRootPath)) return null;
|
|
2588
|
-
return await computeDaemonSourceDistFingerprint(distRootPath);
|
|
2589
|
-
}
|
|
2590
|
-
return null;
|
|
2591
|
-
}
|
|
2592
|
-
async function resolveDaemonBundleEntryPathFromState(state, pathInput = {}) {
|
|
2593
|
-
if (!state) return null;
|
|
2594
|
-
if (state.bundleFormat === "binary_v1") {
|
|
2595
|
-
const stableExecutablePath = daemonServiceBinaryExecutablePath(pathInput);
|
|
2596
|
-
if (await pathExists$4(stableExecutablePath)) return stableExecutablePath;
|
|
2597
|
-
return await pathExists$4(state.sourceEntryScriptPath) ? state.sourceEntryScriptPath : null;
|
|
2598
|
-
}
|
|
2599
|
-
const entryPath = join(resolveDaemonBundleRootPath(state.bundleId, pathInput), state.entryScriptRelativePath);
|
|
2600
|
-
return await pathExists$4(entryPath) ? entryPath : null;
|
|
2601
|
-
}
|
|
2602
|
-
async function prepareDaemonServiceBundle(input) {
|
|
2603
|
-
const preparedBundle = isBinaryDistribution() ? await prepareBinaryDaemonServiceBundle(input) : await prepareNodeDaemonServiceBundle(input);
|
|
2604
|
-
if (input.activate !== false) await activateDaemonServiceBundle(preparedBundle);
|
|
2605
|
-
return preparedBundle;
|
|
2606
|
-
}
|
|
2607
|
-
async function prepareNodeDaemonServiceBundle(input) {
|
|
2608
|
-
const sourceProvenance = await resolveDaemonBundleSourceProvenance(input.cliScriptPath);
|
|
2609
|
-
if (!isDaemonBundleSourceAllowedForLane({ sourceKind: sourceProvenance.sourceKind })) throw new Error("OpenMeld Service cannot use repo-local workspace service files in this lane. Repo-local service files are only allowed through `openmeld-dev`.");
|
|
2610
|
-
const { sourceEntryScriptPath, sourceDistRootPath, sourcePackageRootPath } = sourceProvenance;
|
|
2611
|
-
const sourceDistFingerprint = await computeDaemonSourceDistFingerprint(sourceDistRootPath);
|
|
2612
|
-
const entryScriptRelativePath = basename(sourceEntryScriptPath);
|
|
2613
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2614
|
-
const bundleId = createBundleId(input.daemonVersion);
|
|
2615
|
-
const bundleRootPath = resolveDaemonBundleRootPath(bundleId);
|
|
2616
|
-
const targetDistRootPath = join(bundleRootPath, "dist");
|
|
2617
|
-
await Promise.all([
|
|
2618
|
-
mkdir(daemonRuntimeRootPath(), { recursive: true }),
|
|
2619
|
-
mkdir(daemonRuntimeBundlesPath(), { recursive: true }),
|
|
2620
|
-
mkdir(daemonRuntimeStateRootPath(), { recursive: true }),
|
|
2621
|
-
mkdir(daemonRuntimeServiceManagerPath(), { recursive: true })
|
|
2622
|
-
]);
|
|
2623
|
-
try {
|
|
2624
|
-
await rm(bundleRootPath, {
|
|
2625
|
-
recursive: true,
|
|
2626
|
-
force: true
|
|
2627
|
-
});
|
|
2628
|
-
await mkdir(bundleRootPath, { recursive: true });
|
|
2629
|
-
await cp(sourceDistRootPath, targetDistRootPath, {
|
|
2630
|
-
recursive: true,
|
|
2631
|
-
force: true,
|
|
2632
|
-
filter: (sourcePath) => isDaemonSourceDistPathIncluded(sourceDistRootPath, sourcePath)
|
|
2633
|
-
});
|
|
2634
|
-
await writeDaemonBundlePackageManifest({
|
|
2635
|
-
bundleRootPath,
|
|
2636
|
-
daemonVersion: input.daemonVersion
|
|
2637
|
-
});
|
|
2638
|
-
await copyDaemonBundleRuntimeDependencies({
|
|
2639
|
-
bundleRootPath,
|
|
2640
|
-
sourcePackageRootPath
|
|
2641
|
-
});
|
|
2642
|
-
} catch (error) {
|
|
2643
|
-
await rm(bundleRootPath, {
|
|
2644
|
-
recursive: true,
|
|
2645
|
-
force: true
|
|
2646
|
-
}).catch(() => void 0);
|
|
2647
|
-
throw error;
|
|
2648
|
-
}
|
|
2649
|
-
return {
|
|
2650
|
-
v: 2,
|
|
2651
|
-
schema: DAEMON_ACTIVE_BUNDLE_SCHEMA,
|
|
2652
|
-
bundleId,
|
|
2653
|
-
daemonVersion: input.daemonVersion,
|
|
2654
|
-
entryScriptRelativePath: join("dist", entryScriptRelativePath),
|
|
2655
|
-
bundleFormat: "self_contained_v1",
|
|
2656
|
-
sourceEntryScriptPath,
|
|
2657
|
-
sourcePackageRootPath,
|
|
2658
|
-
sourceDistRootPath,
|
|
2659
|
-
sourceDistFingerprint,
|
|
2660
|
-
sourceKind: sourceProvenance.sourceKind,
|
|
2661
|
-
createdAt: now,
|
|
2662
|
-
updatedAt: now
|
|
2663
|
-
};
|
|
2664
|
-
}
|
|
2665
|
-
async function prepareBinaryDaemonServiceBundle(input) {
|
|
2666
|
-
const { daemonVersion } = input;
|
|
2667
|
-
const bundledRelease = resolveBundledServiceRelease();
|
|
2668
|
-
const binaryRelease = input.binaryRelease ?? (bundledRelease?.version === daemonVersion ? bundledRelease : void 0);
|
|
2669
|
-
if (daemonVersion !== resolveCliSelfVersion()) {
|
|
2670
|
-
const active = await readDaemonActiveBundleState();
|
|
2671
|
-
if (active?.bundleFormat === "binary_v1" && active.daemonVersion === daemonVersion && active.sourceDistFingerprint && (!binaryRelease || binaryRelease.sha256 === active.sourceDistFingerprint) && await pathExists$4(active.sourceEntryScriptPath) && await hashDaemonBinaryFile(active.sourceEntryScriptPath) === active.sourceDistFingerprint) return active;
|
|
2672
|
-
}
|
|
2673
|
-
if (binaryRelease) return await prepareSelectedBinaryDaemonServiceBundle({
|
|
2674
|
-
daemonVersion,
|
|
2675
|
-
release: binaryRelease
|
|
2676
|
-
});
|
|
2677
|
-
if (daemonVersion !== resolveCliSelfVersion()) throw new Error(`Cannot prepare OpenMeld Service ${daemonVersion} from CLI ${resolveCliSelfVersion()}. Acquire the selected Service release before preparing the update.`);
|
|
2678
|
-
const outcome = await performManagedInstall();
|
|
2679
|
-
const managedBinaryPath = outcome.managedBinaryPath;
|
|
2680
|
-
if (!await pathExists$4(managedBinaryPath)) throw new Error(`OpenMeld managed binary is missing at ${managedBinaryPath}; cannot prepare binary OpenMeld Service.`);
|
|
2681
|
-
const managedVersionDir = dirname(managedBinaryPath);
|
|
2682
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2683
|
-
await Promise.all([
|
|
2684
|
-
mkdir(daemonRuntimeRootPath(), { recursive: true }),
|
|
2685
|
-
mkdir(daemonRuntimeStateRootPath(), { recursive: true }),
|
|
2686
|
-
mkdir(daemonRuntimeServiceManagerPath(), { recursive: true })
|
|
2687
|
-
]);
|
|
2688
|
-
return {
|
|
2689
|
-
v: 2,
|
|
2690
|
-
schema: DAEMON_ACTIVE_BUNDLE_SCHEMA,
|
|
2691
|
-
bundleId: createBundleId(outcome.version),
|
|
2692
|
-
daemonVersion: outcome.version,
|
|
2693
|
-
entryScriptRelativePath: "openmeld",
|
|
2694
|
-
bundleFormat: "binary_v1",
|
|
2695
|
-
sourceEntryScriptPath: managedBinaryPath,
|
|
2696
|
-
sourcePackageRootPath: managedVersionDir,
|
|
2697
|
-
sourceDistRootPath: managedVersionDir,
|
|
2698
|
-
sourceDistFingerprint: await hashDaemonBinaryFile(managedBinaryPath),
|
|
2699
|
-
sourceKind: DAEMON_BUNDLE_SOURCE_KIND_PACKAGE_INSTALL,
|
|
2700
|
-
createdAt: now,
|
|
2701
|
-
updatedAt: now
|
|
2702
|
-
};
|
|
2703
|
-
}
|
|
2704
|
-
async function prepareSelectedBinaryDaemonServiceBundle(input) {
|
|
2705
|
-
if (input.release.version !== input.daemonVersion) throw new Error("The selected Service artifact does not match the update target.");
|
|
2706
|
-
const bundleId = createBundleId(input.daemonVersion);
|
|
2707
|
-
const bundleRootPath = resolveDaemonBundleRootPath(bundleId);
|
|
2708
|
-
const executablePath = join(bundleRootPath, "openmeld");
|
|
2709
|
-
const onDeltaFallback = (error) => {
|
|
2710
|
-
console.warn("[openmeld.service.artifact_delta_fallback]", error.message);
|
|
2711
|
-
};
|
|
2712
|
-
const plan = await resolveCliBinaryUpdatePlan({
|
|
2713
|
-
baseBinaryPath: process$1.execPath,
|
|
2714
|
-
currentVersion: resolveCliSelfVersion(),
|
|
2715
|
-
onDeltaFallback,
|
|
2716
|
-
release: input.release
|
|
2717
|
-
});
|
|
2718
|
-
const bytes = await downloadCliBinaryUpdateArtifact({
|
|
2719
|
-
downloadTimeoutMs: 6e4,
|
|
2720
|
-
fetchImpl: fetch,
|
|
2721
|
-
onDeltaFallback,
|
|
2722
|
-
plan,
|
|
2723
|
-
release: input.release
|
|
2724
|
-
});
|
|
2725
|
-
await mkdir(bundleRootPath, { recursive: true });
|
|
2726
|
-
try {
|
|
2727
|
-
await writeFile(executablePath, bytes, { mode: 493 });
|
|
2728
|
-
await verifyCliBinaryCodeSignature({
|
|
2729
|
-
artifactPath: executablePath,
|
|
2730
|
-
release: input.release,
|
|
2731
|
-
runCommand: async (command, args) => {
|
|
2732
|
-
const result = await promisify(execFile)(command, args, { encoding: "utf8" });
|
|
2733
|
-
return {
|
|
2734
|
-
code: 0,
|
|
2735
|
-
stdout: result.stdout,
|
|
2736
|
-
stderr: result.stderr
|
|
2737
|
-
};
|
|
2738
|
-
}
|
|
2739
|
-
});
|
|
2740
|
-
} catch (error) {
|
|
2741
|
-
await rm(bundleRootPath, {
|
|
2742
|
-
recursive: true,
|
|
2743
|
-
force: true
|
|
2744
|
-
});
|
|
2745
|
-
throw error;
|
|
2746
|
-
}
|
|
2747
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
2748
|
-
return {
|
|
2749
|
-
v: 2,
|
|
2750
|
-
schema: DAEMON_ACTIVE_BUNDLE_SCHEMA,
|
|
2751
|
-
bundleId,
|
|
2752
|
-
daemonVersion: input.daemonVersion,
|
|
2753
|
-
entryScriptRelativePath: "openmeld",
|
|
2754
|
-
bundleFormat: "binary_v1",
|
|
2755
|
-
sourceEntryScriptPath: executablePath,
|
|
2756
|
-
sourcePackageRootPath: bundleRootPath,
|
|
2757
|
-
sourceDistRootPath: bundleRootPath,
|
|
2758
|
-
sourceDistFingerprint: input.release.sha256.toLowerCase(),
|
|
2759
|
-
sourceKind: DAEMON_BUNDLE_SOURCE_KIND_PACKAGE_INSTALL,
|
|
2760
|
-
createdAt: now,
|
|
2761
|
-
updatedAt: now
|
|
2762
|
-
};
|
|
2763
|
-
}
|
|
2764
|
-
async function activateDaemonServiceBundle(preparedBundle) {
|
|
2765
|
-
await mkdir(daemonRuntimeStateRootPath(), { recursive: true });
|
|
2766
|
-
await writeFile(daemonServiceActiveBundlePath(), `${JSON.stringify(preparedBundle, null, 2)}\n`, {
|
|
2767
|
-
encoding: "utf8",
|
|
2768
|
-
mode: 384
|
|
2769
|
-
});
|
|
2770
|
-
if (preparedBundle.bundleFormat !== "binary_v1") await ensureDaemonServiceManagerExecutables();
|
|
2771
|
-
}
|
|
2772
|
-
async function discardPreparedDaemonServiceBundle(preparedBundle) {
|
|
2773
|
-
if (preparedBundle.bundleFormat === "legacy_linked_v1") return;
|
|
2774
|
-
if ((await readDaemonActiveBundleState())?.bundleId === preparedBundle.bundleId) return;
|
|
2775
|
-
await rm(resolveDaemonBundleRootPath(preparedBundle.bundleId), {
|
|
2776
|
-
recursive: true,
|
|
2777
|
-
force: true
|
|
2778
|
-
});
|
|
2779
|
-
}
|
|
2780
|
-
async function hashDaemonBinaryFile(filePath) {
|
|
2781
|
-
const hash = createHash("sha256");
|
|
2782
|
-
hash.update(await readFile(filePath));
|
|
2783
|
-
return hash.digest("hex");
|
|
2784
|
-
}
|
|
2785
|
-
async function runAuditedServiceManagerCarrierMutation(input) {
|
|
2786
|
-
const pathInput = input.pathInput ?? {};
|
|
2787
|
-
const metadata = {
|
|
2788
|
-
distribution: input.distribution ?? resolveOpenMeldDistribution(),
|
|
2789
|
-
executable: process$1.execPath,
|
|
2790
|
-
operation: input.operation,
|
|
2791
|
-
preset: resolveOpenMeldEnvPreset(pathInput),
|
|
2792
|
-
targetPath: input.targetPath,
|
|
2793
|
-
targetCategory: classifyDiagnosticPath(input.targetPath),
|
|
2794
|
-
actorPid: process$1.pid,
|
|
2795
|
-
parentPid: process$1.ppid
|
|
2796
|
-
};
|
|
2797
|
-
await emitDaemonLifecycleEvent({
|
|
2798
|
-
command: "openmeld service carrier mutation",
|
|
2799
|
-
intent: "status_cleanup",
|
|
2800
|
-
metadata,
|
|
2801
|
-
pathInput,
|
|
2802
|
-
result: "attempted",
|
|
2803
|
-
type: "service_manager.registration_reconcile"
|
|
2804
|
-
});
|
|
2805
|
-
try {
|
|
2806
|
-
const result = await input.run();
|
|
2807
|
-
await emitDaemonLifecycleEvent({
|
|
2808
|
-
command: "openmeld service carrier mutation",
|
|
2809
|
-
intent: "status_cleanup",
|
|
2810
|
-
metadata,
|
|
2811
|
-
pathInput,
|
|
2812
|
-
result: "completed",
|
|
2813
|
-
type: "service_manager.registration_reconcile"
|
|
2814
|
-
});
|
|
2815
|
-
return result;
|
|
2816
|
-
} catch (error) {
|
|
2817
|
-
await emitDaemonLifecycleEvent({
|
|
2818
|
-
command: "openmeld service carrier mutation",
|
|
2819
|
-
intent: "status_cleanup",
|
|
2820
|
-
metadata: {
|
|
2821
|
-
...metadata,
|
|
2822
|
-
errorMessage: error instanceof Error ? error.message : String(error),
|
|
2823
|
-
operationFailure: collectLocalOperationFailure(error)
|
|
2824
|
-
},
|
|
2825
|
-
pathInput,
|
|
2826
|
-
result: "failed",
|
|
2827
|
-
type: "service_manager.registration_reconcile"
|
|
2828
|
-
});
|
|
2829
|
-
throw error;
|
|
2830
|
-
}
|
|
2831
|
-
}
|
|
2832
|
-
async function ensureDaemonServiceStableBinaryExecutable(pathInput = {}) {
|
|
2833
|
-
const activeBundle = await readDaemonActiveBundleState();
|
|
2834
|
-
if (activeBundle?.bundleFormat !== "binary_v1") throw new Error("OpenMeld cannot prepare the stable macOS Service executable without an active binary bundle.");
|
|
2835
|
-
return await ensureVerifiedBinaryCarrier({
|
|
2836
|
-
bundle: activeBundle,
|
|
2837
|
-
operationName: "stable_binary",
|
|
2838
|
-
pathInput,
|
|
2839
|
-
targetPath: daemonServiceBinaryExecutablePath(pathInput)
|
|
2840
|
-
});
|
|
2841
|
-
}
|
|
2842
|
-
async function ensureDaemonServiceUpdateWorkerBinaryExecutable(preparedBundle, pathInput = {}) {
|
|
2843
|
-
if (preparedBundle.bundleFormat !== "binary_v1") throw new Error("OpenMeld cannot prepare the update worker binary without a binary Service bundle.");
|
|
2844
|
-
return await ensureVerifiedBinaryCarrier({
|
|
2845
|
-
bundle: preparedBundle,
|
|
2846
|
-
operationName: "update_worker_binary",
|
|
2847
|
-
pathInput,
|
|
2848
|
-
targetPath: daemonServiceUpdateWorkerBinaryPath(pathInput)
|
|
2849
|
-
});
|
|
2850
|
-
}
|
|
2851
|
-
async function clearDaemonServiceUpdateWorkerBinaryExecutable(pathInput = {}) {
|
|
2852
|
-
const targetPath = daemonServiceUpdateWorkerBinaryPath(pathInput);
|
|
2853
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2854
|
-
distribution: "binary",
|
|
2855
|
-
operation: "remove_update_worker_binary",
|
|
2856
|
-
pathInput,
|
|
2857
|
-
targetPath,
|
|
2858
|
-
run: async () => await rm(targetPath, { force: true })
|
|
2859
|
-
});
|
|
2860
|
-
}
|
|
2861
|
-
async function ensureVerifiedBinaryCarrier(input) {
|
|
2862
|
-
const sourcePath = input.bundle.sourceEntryScriptPath;
|
|
2863
|
-
const expectedFingerprint = input.bundle.sourceDistFingerprint ?? await hashDaemonBinaryFile(sourcePath);
|
|
2864
|
-
const stableExecutablePath = input.targetPath;
|
|
2865
|
-
const stableExecutableStat = await lstat(stableExecutablePath).catch(() => null);
|
|
2866
|
-
if (stableExecutableStat?.isFile() === true && !stableExecutableStat.isSymbolicLink() && await hashDaemonBinaryFile(stableExecutablePath).catch(() => null) === expectedFingerprint) {
|
|
2867
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2868
|
-
distribution: "binary",
|
|
2869
|
-
operation: `refresh_${input.operationName}_permissions`,
|
|
2870
|
-
pathInput: input.pathInput,
|
|
2871
|
-
targetPath: stableExecutablePath,
|
|
2872
|
-
run: async () => await chmod(stableExecutablePath, 448)
|
|
2873
|
-
});
|
|
2874
|
-
return stableExecutablePath;
|
|
2875
|
-
}
|
|
2876
|
-
await mkdir(dirname(stableExecutablePath), { recursive: true });
|
|
2877
|
-
const preparedPath = `${stableExecutablePath}.next-${String(process$1.pid)}`;
|
|
2878
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2879
|
-
distribution: "binary",
|
|
2880
|
-
operation: `clear_prepared_${input.operationName}`,
|
|
2881
|
-
pathInput: input.pathInput,
|
|
2882
|
-
targetPath: preparedPath,
|
|
2883
|
-
run: async () => await rm(preparedPath, { force: true })
|
|
2884
|
-
});
|
|
2885
|
-
try {
|
|
2886
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2887
|
-
distribution: "binary",
|
|
2888
|
-
operation: `prepare_${input.operationName}`,
|
|
2889
|
-
pathInput: input.pathInput,
|
|
2890
|
-
targetPath: preparedPath,
|
|
2891
|
-
run: async () => {
|
|
2892
|
-
await copyFile(sourcePath, preparedPath);
|
|
2893
|
-
await chmod(preparedPath, 448);
|
|
2894
|
-
}
|
|
2895
|
-
});
|
|
2896
|
-
if (await hashDaemonBinaryFile(preparedPath) !== expectedFingerprint) throw new Error("OpenMeld could not verify the prepared Service carrier executable.");
|
|
2897
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2898
|
-
distribution: "binary",
|
|
2899
|
-
operation: `replace_${input.operationName}`,
|
|
2900
|
-
pathInput: input.pathInput,
|
|
2901
|
-
targetPath: stableExecutablePath,
|
|
2902
|
-
run: async () => await rename(preparedPath, stableExecutablePath)
|
|
2903
|
-
});
|
|
2904
|
-
return stableExecutablePath;
|
|
2905
|
-
} finally {
|
|
2906
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2907
|
-
distribution: "binary",
|
|
2908
|
-
operation: `clear_prepared_${input.operationName}`,
|
|
2909
|
-
pathInput: input.pathInput,
|
|
2910
|
-
targetPath: preparedPath,
|
|
2911
|
-
run: async () => await rm(preparedPath, { force: true })
|
|
2912
|
-
}).catch(() => void 0);
|
|
2913
|
-
}
|
|
2914
|
-
}
|
|
2915
|
-
async function verifyDaemonActiveBundleIntegrity(activeBundle) {
|
|
2916
|
-
const expectedFingerprint = activeBundle.sourceDistFingerprint?.trim();
|
|
2917
|
-
if (!expectedFingerprint || activeBundle.bundleFormat === "legacy_linked_v1") return false;
|
|
2918
|
-
if (!await resolveDaemonBundleEntryPathFromState(activeBundle)) return false;
|
|
2919
|
-
return await resolveInstalledDaemonBundleFingerprint(activeBundle) === expectedFingerprint;
|
|
2920
|
-
}
|
|
2921
|
-
async function writeDaemonBundlePackageManifest(input) {
|
|
2922
|
-
await writeFile(join(input.bundleRootPath, "package.json"), `${JSON.stringify({
|
|
2923
|
-
name: "openmeld-daemon-service-bundle",
|
|
2924
|
-
private: true,
|
|
2925
|
-
type: "module",
|
|
2926
|
-
version: input.daemonVersion
|
|
2927
|
-
}, null, 2)}\n`, {
|
|
2928
|
-
encoding: "utf8",
|
|
2929
|
-
mode: 384
|
|
2930
|
-
});
|
|
2931
|
-
}
|
|
2932
|
-
async function copyDaemonBundleRuntimeDependencies(input) {
|
|
2933
|
-
const runtimeDependencies = await collectDaemonBundleRuntimeDependencyClosure({ sourcePackageRootPath: input.sourcePackageRootPath });
|
|
2934
|
-
const targetNodeModulesPath = join(input.bundleRootPath, "node_modules");
|
|
2935
|
-
await rm(targetNodeModulesPath, {
|
|
2936
|
-
recursive: true,
|
|
2937
|
-
force: true
|
|
2938
|
-
});
|
|
2939
|
-
await mkdir(targetNodeModulesPath, { recursive: true });
|
|
2940
|
-
for (const runtimeDependency of runtimeDependencies) await copyDaemonBundleDependencyDirectory({
|
|
2941
|
-
dependencyName: runtimeDependency.dependencyName,
|
|
2942
|
-
sourceDependencyPath: runtimeDependency.packageRootPath,
|
|
2943
|
-
targetNodeModulesPath
|
|
2944
|
-
});
|
|
2945
|
-
}
|
|
2946
|
-
async function copyDaemonBundleDependencyDirectory(input) {
|
|
2947
|
-
if (!await pathExists$4(input.sourceDependencyPath)) throw new Error(`OpenMeld could not copy runtime dependency ${input.dependencyName} for background service bundling from ${input.sourceDependencyPath}. Run \`pnpm install\` and retry.`);
|
|
2948
|
-
const targetDependencyPath = join(input.targetNodeModulesPath, ...input.dependencyName.split("/"));
|
|
2949
|
-
await mkdir(dirname(targetDependencyPath), { recursive: true });
|
|
2950
|
-
await cp(input.sourceDependencyPath, targetDependencyPath, {
|
|
2951
|
-
recursive: true,
|
|
2952
|
-
force: true,
|
|
2953
|
-
dereference: true,
|
|
2954
|
-
preserveTimestamps: true
|
|
2955
|
-
});
|
|
2956
|
-
}
|
|
2957
|
-
async function writeDaemonServiceLauncher(pathInput = {}) {
|
|
2958
|
-
await mkdir(daemonRuntimeServiceManagerPath(pathInput), { recursive: true });
|
|
2959
|
-
const targetPath = daemonServiceLauncherPath(pathInput);
|
|
2960
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2961
|
-
distribution: "npm",
|
|
2962
|
-
operation: "write_launcher",
|
|
2963
|
-
pathInput,
|
|
2964
|
-
targetPath,
|
|
2965
|
-
run: async () => await writeFile(targetPath, `${buildDaemonServiceLauncherSource(pathInput)}\n`, {
|
|
2966
|
-
encoding: "utf8",
|
|
2967
|
-
mode: 448
|
|
2968
|
-
})
|
|
2969
|
-
});
|
|
2970
|
-
}
|
|
2971
|
-
async function writeDaemonServiceExecutableWrapper(pathInput = {}) {
|
|
2972
|
-
await mkdir(daemonRuntimeServiceManagerPath(pathInput), { recursive: true });
|
|
2973
|
-
await Promise.all(daemonServiceExecutableWrapperPaths(pathInput).map(async (wrapperPath) => {
|
|
2974
|
-
await runAuditedServiceManagerCarrierMutation({
|
|
2975
|
-
distribution: "npm",
|
|
2976
|
-
operation: "write_executable_wrapper",
|
|
2977
|
-
pathInput,
|
|
2978
|
-
targetPath: wrapperPath,
|
|
2979
|
-
run: async () => {
|
|
2980
|
-
await writeFile(wrapperPath, `${buildDaemonServiceExecutableWrapperSource(pathInput)}\n`, {
|
|
2981
|
-
encoding: "utf8",
|
|
2982
|
-
mode: 448
|
|
2983
|
-
});
|
|
2984
|
-
await chmod(wrapperPath, 448);
|
|
2985
|
-
}
|
|
2986
|
-
});
|
|
2987
|
-
}));
|
|
2988
|
-
}
|
|
2989
|
-
async function ensureDaemonServiceManagerExecutables(pathInput = {}) {
|
|
2990
|
-
await writeDaemonServiceLauncher(pathInput);
|
|
2991
|
-
await writeDaemonServiceExecutableWrapper(pathInput);
|
|
2992
|
-
}
|
|
2993
|
-
async function restoreDaemonActiveBundleStateSnapshot(snapshot, pathInput = {}) {
|
|
2994
|
-
if (!snapshot) {
|
|
2995
|
-
await rm(daemonServiceActiveBundlePath(pathInput), { force: true });
|
|
2996
|
-
return;
|
|
2997
|
-
}
|
|
2998
|
-
await mkdir(daemonRuntimeStateRootPath(pathInput), { recursive: true });
|
|
2999
|
-
await writeFile(daemonServiceActiveBundlePath(pathInput), `${JSON.stringify(snapshot, null, 2)}\n`, {
|
|
3000
|
-
encoding: "utf8",
|
|
3001
|
-
mode: 384
|
|
3002
|
-
});
|
|
3003
|
-
}
|
|
3004
|
-
async function cleanupInactiveDaemonServiceBundles(input = {}) {
|
|
3005
|
-
const [active, serviceContract, runtimeLease, registeredWorkerBundleIds, pendingUpdate] = await Promise.all([
|
|
3006
|
-
readDaemonActiveBundleState(),
|
|
3007
|
-
readDaemonServiceContract().catch(() => null),
|
|
3008
|
-
readDaemonRuntimeLease().catch(() => null),
|
|
3009
|
-
readDaemonServiceUpdateWorkerProtectedBundleIds(),
|
|
3010
|
-
readPendingDaemonServiceUpdate()
|
|
3011
|
-
]);
|
|
3012
|
-
const retain = /* @__PURE__ */ new Set([
|
|
3013
|
-
...active ? [active.bundleId] : [],
|
|
3014
|
-
...serviceContract?.bundleId ? [serviceContract.bundleId] : [],
|
|
3015
|
-
...runtimeLease?.bundleId ? [runtimeLease.bundleId] : [],
|
|
3016
|
-
...registeredWorkerBundleIds,
|
|
3017
|
-
...pendingUpdate?.preparedBundle.bundleFormat === "self_contained_v1" ? [pendingUpdate.preparedBundle.bundleId] : [],
|
|
3018
|
-
...input.retainBundleIds ?? []
|
|
3019
|
-
]);
|
|
3020
|
-
const bundleEntries = await readDirectoryNames(daemonRuntimeBundlesPath());
|
|
3021
|
-
await Promise.all(bundleEntries.filter((bundleId) => !retain.has(bundleId)).map(async (bundleId) => {
|
|
3022
|
-
await rm(resolveDaemonBundleRootPath(bundleId), {
|
|
3023
|
-
recursive: true,
|
|
3024
|
-
force: true
|
|
3025
|
-
});
|
|
3026
|
-
}));
|
|
3027
|
-
}
|
|
3028
|
-
async function resolveDaemonBundleSourceProvenance(explicitPath) {
|
|
3029
|
-
const sourceEntryScriptPath = await resolveCliScriptPath(explicitPath);
|
|
3030
|
-
const sourceDistRootPath = dirname(sourceEntryScriptPath);
|
|
3031
|
-
const sourcePackageRootPath = dirname(sourceDistRootPath);
|
|
3032
|
-
return {
|
|
3033
|
-
sourceEntryScriptPath,
|
|
3034
|
-
sourceDistRootPath,
|
|
3035
|
-
sourcePackageRootPath,
|
|
3036
|
-
sourceKind: inferDaemonBundleSourceKind(sourcePackageRootPath)
|
|
3037
|
-
};
|
|
3038
|
-
}
|
|
3039
|
-
async function resolveCliScriptPath(explicitPath) {
|
|
3040
|
-
const rawPath = explicitPath ?? process$1.argv[1];
|
|
3041
|
-
if (!rawPath) throw new Error("Cannot determine CLI script path for OpenMeld background service bundle.");
|
|
3042
|
-
const resolvedPath = await realpath(rawPath).catch(async () => {
|
|
3043
|
-
const fallbackPath = await resolvePreferredCliScriptPath(rawPath);
|
|
3044
|
-
if (fallbackPath) return fallbackPath;
|
|
3045
|
-
throw new Error(`OpenMeld could not resolve a CLI dist entry for service bundling from ${rawPath}.`);
|
|
3046
|
-
});
|
|
3047
|
-
const preferredPath = await resolvePreferredCliScriptPath(resolvedPath);
|
|
3048
|
-
if (preferredPath) return preferredPath;
|
|
3049
|
-
throw new Error(`OpenMeld could not find a supported CLI dist entry for service bundling from ${resolvedPath}.`);
|
|
3050
|
-
}
|
|
3051
|
-
function createBundleId(version) {
|
|
3052
|
-
return `${version.replace(/[^a-zA-Z0-9._-]+/g, "_")}-${Date.now()}`;
|
|
3053
|
-
}
|
|
3054
|
-
async function computeDaemonSourceDistFingerprint(sourceDistRootPath) {
|
|
3055
|
-
const filePaths = await listDaemonSourceDistFiles(sourceDistRootPath);
|
|
3056
|
-
const hash = createHash("sha256");
|
|
3057
|
-
for (const filePath of filePaths) {
|
|
3058
|
-
const relativePath = relative(sourceDistRootPath, filePath).replaceAll("\\", "/");
|
|
3059
|
-
hash.update(relativePath, "utf8");
|
|
3060
|
-
hash.update("\0", "utf8");
|
|
3061
|
-
hash.update(await readFile(filePath));
|
|
3062
|
-
hash.update("\0", "utf8");
|
|
3063
|
-
}
|
|
3064
|
-
return hash.digest("hex");
|
|
3065
|
-
}
|
|
3066
|
-
async function listDaemonSourceDistFiles(path) {
|
|
3067
|
-
return await listIncludedDaemonSourceDistFiles(path, path);
|
|
3068
|
-
}
|
|
3069
|
-
async function listIncludedDaemonSourceDistFiles(sourceDistRootPath, currentPath) {
|
|
3070
|
-
const entries = await readdir(currentPath, { withFileTypes: true });
|
|
3071
|
-
const filePaths = [];
|
|
3072
|
-
for (const entry of entries) {
|
|
3073
|
-
const entryPath = join(currentPath, entry.name);
|
|
3074
|
-
if (!isDaemonSourceDistPathIncluded(sourceDistRootPath, entryPath)) continue;
|
|
3075
|
-
if (entry.isDirectory()) {
|
|
3076
|
-
filePaths.push(...await listIncludedDaemonSourceDistFiles(sourceDistRootPath, entryPath));
|
|
3077
|
-
continue;
|
|
3078
|
-
}
|
|
3079
|
-
if (entry.isFile()) filePaths.push(entryPath);
|
|
3080
|
-
}
|
|
3081
|
-
return filePaths.sort((left, right) => {
|
|
3082
|
-
if (left === right) return 0;
|
|
3083
|
-
return left < right ? -1 : 1;
|
|
3084
|
-
});
|
|
3085
|
-
}
|
|
3086
|
-
function isDaemonSourceDistPathIncluded(sourceDistRootPath, candidatePath) {
|
|
3087
|
-
const relativePath = relative(sourceDistRootPath, candidatePath).replaceAll("\\", "/");
|
|
3088
|
-
if (!relativePath || relativePath.startsWith("..")) return true;
|
|
3089
|
-
const topLevelPathSegment = relativePath.split("/")[0] ?? "";
|
|
3090
|
-
return !DAEMON_SOURCE_DIST_IGNORED_TOP_LEVEL_DIRS.has(topLevelPathSegment);
|
|
3091
|
-
}
|
|
3092
|
-
async function collectDaemonBundleRuntimeDependencyClosure(input) {
|
|
3093
|
-
const packageManifestPath = join(input.sourcePackageRootPath, "package.json");
|
|
3094
|
-
const packageManifestRaw = await readFile(packageManifestPath, "utf8").catch((error) => {
|
|
3095
|
-
if (getErrorCode$1(error) === "ENOENT") throw new Error(`OpenMeld could not find the CLI package manifest for background service bundling at ${packageManifestPath}.`);
|
|
3096
|
-
throw error;
|
|
3097
|
-
});
|
|
3098
|
-
const packageManifest = JSON.parse(packageManifestRaw);
|
|
3099
|
-
const resolvedDependencies = /* @__PURE__ */ new Map();
|
|
3100
|
-
const queue = [...Object.keys(packageManifest.dependencies ?? {}).map((dependencyName) => ({
|
|
3101
|
-
dependencyName,
|
|
3102
|
-
required: true,
|
|
3103
|
-
resolverPackageRootPath: input.sourcePackageRootPath
|
|
3104
|
-
})), ...Object.keys(packageManifest.optionalDependencies ?? {}).map((dependencyName) => ({
|
|
3105
|
-
dependencyName,
|
|
3106
|
-
required: false,
|
|
3107
|
-
resolverPackageRootPath: input.sourcePackageRootPath
|
|
3108
|
-
}))];
|
|
3109
|
-
while (queue.length > 0) {
|
|
3110
|
-
const nextDependency = queue.shift();
|
|
3111
|
-
if (!nextDependency) continue;
|
|
3112
|
-
if (isTypeOnlyDependencyName(nextDependency.dependencyName)) continue;
|
|
3113
|
-
if (resolvedDependencies.has(nextDependency.dependencyName)) continue;
|
|
3114
|
-
const dependencyManifest = await readDaemonBundleDependencyManifest({
|
|
3115
|
-
dependencyName: nextDependency.dependencyName,
|
|
3116
|
-
required: nextDependency.required,
|
|
3117
|
-
resolverPackageRootPath: nextDependency.resolverPackageRootPath
|
|
3118
|
-
});
|
|
3119
|
-
if (!dependencyManifest) continue;
|
|
3120
|
-
resolvedDependencies.set(nextDependency.dependencyName, dependencyManifest.packageRootPath);
|
|
3121
|
-
const nestedRequiredDependencies = Object.keys(dependencyManifest.dependencies ?? {});
|
|
3122
|
-
const nestedOptionalDependencies = Object.keys(dependencyManifest.optionalDependencies ?? {});
|
|
3123
|
-
const nestedPeerDependencies = Object.keys(dependencyManifest.peerDependencies ?? {});
|
|
3124
|
-
for (const dependencyName of nestedRequiredDependencies) queue.push({
|
|
3125
|
-
dependencyName,
|
|
3126
|
-
required: true,
|
|
3127
|
-
resolverPackageRootPath: dependencyManifest.packageRootPath
|
|
3128
|
-
});
|
|
3129
|
-
for (const dependencyName of nestedOptionalDependencies) queue.push({
|
|
3130
|
-
dependencyName,
|
|
3131
|
-
required: false,
|
|
3132
|
-
resolverPackageRootPath: dependencyManifest.packageRootPath
|
|
3133
|
-
});
|
|
3134
|
-
for (const dependencyName of nestedPeerDependencies) queue.push({
|
|
3135
|
-
dependencyName,
|
|
3136
|
-
required: false,
|
|
3137
|
-
resolverPackageRootPath: dependencyManifest.packageRootPath
|
|
3138
|
-
});
|
|
3139
|
-
}
|
|
3140
|
-
return [...resolvedDependencies.entries()].map(([dependencyName, packageRootPath]) => ({
|
|
3141
|
-
dependencyName,
|
|
3142
|
-
packageRootPath
|
|
3143
|
-
})).sort((left, right) => left.dependencyName.localeCompare(right.dependencyName));
|
|
3144
|
-
}
|
|
3145
|
-
function isTypeOnlyDependencyName(dependencyName) {
|
|
3146
|
-
return dependencyName.startsWith("@types/");
|
|
3147
|
-
}
|
|
3148
|
-
async function readDaemonBundleDependencyManifest(input) {
|
|
3149
|
-
const dependencyPackageRootPath = await resolveDaemonDependencyPackageRoot({
|
|
3150
|
-
dependencyName: input.dependencyName,
|
|
3151
|
-
resolverPackageRootPath: input.resolverPackageRootPath,
|
|
3152
|
-
required: input.required
|
|
3153
|
-
});
|
|
3154
|
-
if (!dependencyPackageRootPath) return null;
|
|
3155
|
-
const dependencyManifestPath = join(dependencyPackageRootPath, "package.json");
|
|
3156
|
-
const dependencyManifestRaw = await readFile(dependencyManifestPath, "utf8").catch((error) => {
|
|
3157
|
-
if (getErrorCode$1(error) === "ENOENT") {
|
|
3158
|
-
if (!input.required) return null;
|
|
3159
|
-
throw new Error(`OpenMeld could not find runtime dependency ${input.dependencyName} for background service bundling at ${dependencyManifestPath}. Run \`pnpm install\` and retry.`);
|
|
3160
|
-
}
|
|
3161
|
-
throw error;
|
|
3162
|
-
});
|
|
3163
|
-
if (dependencyManifestRaw === null) return null;
|
|
3164
|
-
return {
|
|
3165
|
-
packageRootPath: dependencyPackageRootPath,
|
|
3166
|
-
...JSON.parse(dependencyManifestRaw)
|
|
3167
|
-
};
|
|
3168
|
-
}
|
|
3169
|
-
async function resolveDaemonDependencyPackageRoot(input) {
|
|
3170
|
-
const resolver = createRequire(join(input.resolverPackageRootPath, "package.json"));
|
|
3171
|
-
const dependencyPackageRootPath = await resolveDaemonDependencyPackageRootFromManifest({
|
|
3172
|
-
dependencyName: input.dependencyName,
|
|
3173
|
-
resolver
|
|
3174
|
-
});
|
|
3175
|
-
if (dependencyPackageRootPath) return dependencyPackageRootPath;
|
|
3176
|
-
try {
|
|
3177
|
-
return await findDaemonDependencyPackageRoot(await realpath(resolver.resolve(input.dependencyName)));
|
|
3178
|
-
} catch (error) {
|
|
3179
|
-
if (isPackageEntryResolutionError(error)) {
|
|
3180
|
-
const dependencyPackageRootPath = await findDaemonDependencyPackageRootFromResolutionPaths({
|
|
3181
|
-
dependencyName: input.dependencyName,
|
|
3182
|
-
resolver
|
|
3183
|
-
});
|
|
3184
|
-
if (dependencyPackageRootPath) return dependencyPackageRootPath;
|
|
3185
|
-
if (!input.required) return null;
|
|
3186
|
-
throw new Error(`OpenMeld could not find runtime dependency ${input.dependencyName} for background service bundling from ${input.resolverPackageRootPath}. Run \`pnpm install\` and retry.`);
|
|
3187
|
-
}
|
|
3188
|
-
throw error;
|
|
3189
|
-
}
|
|
3190
|
-
}
|
|
3191
|
-
async function resolveDaemonDependencyPackageRootFromManifest(input) {
|
|
3192
|
-
try {
|
|
3193
|
-
return await findDaemonDependencyPackageRootFromManifestPath({
|
|
3194
|
-
dependencyManifestPath: await realpath(input.resolver.resolve(`${input.dependencyName}/package.json`)),
|
|
3195
|
-
dependencyName: input.dependencyName
|
|
3196
|
-
});
|
|
3197
|
-
} catch (error) {
|
|
3198
|
-
if (isPackageEntryResolutionError(error)) return null;
|
|
3199
|
-
throw error;
|
|
3200
|
-
}
|
|
3201
|
-
}
|
|
3202
|
-
async function findDaemonDependencyPackageRootFromManifestPath(input) {
|
|
3203
|
-
let currentPath = dirname(input.dependencyManifestPath);
|
|
3204
|
-
while (true) {
|
|
3205
|
-
const packageManifestRaw = await readFile(join(currentPath, "package.json"), "utf8").catch((error) => {
|
|
3206
|
-
if (getErrorCode$1(error) === "ENOENT") return null;
|
|
3207
|
-
throw error;
|
|
3208
|
-
});
|
|
3209
|
-
if (packageManifestRaw !== null) {
|
|
3210
|
-
if (JSON.parse(packageManifestRaw).name === input.dependencyName) return currentPath;
|
|
3211
|
-
}
|
|
3212
|
-
const parentPath = dirname(currentPath);
|
|
3213
|
-
if (parentPath === currentPath) return null;
|
|
3214
|
-
currentPath = parentPath;
|
|
3215
|
-
}
|
|
3216
|
-
}
|
|
3217
|
-
async function findDaemonDependencyPackageRootFromResolutionPaths(input) {
|
|
3218
|
-
const resolutionPaths = input.resolver.resolve.paths(input.dependencyName);
|
|
3219
|
-
if (!resolutionPaths) return null;
|
|
3220
|
-
for (const nodeModulesPath of resolutionPaths) {
|
|
3221
|
-
const candidatePackageRootPath = join(nodeModulesPath, ...input.dependencyName.split("/"));
|
|
3222
|
-
if (await pathExists$4(join(candidatePackageRootPath, "package.json"))) return await realpath(candidatePackageRootPath);
|
|
3223
|
-
}
|
|
3224
|
-
return null;
|
|
3225
|
-
}
|
|
3226
|
-
async function findDaemonDependencyPackageRoot(resolvedEntryPath) {
|
|
3227
|
-
let currentPath = dirname(resolvedEntryPath);
|
|
3228
|
-
while (true) {
|
|
3229
|
-
if (await pathExists$4(join(currentPath, "package.json"))) return currentPath;
|
|
3230
|
-
const parentPath = dirname(currentPath);
|
|
3231
|
-
if (parentPath === currentPath) break;
|
|
3232
|
-
currentPath = parentPath;
|
|
3233
|
-
}
|
|
3234
|
-
throw new Error(`OpenMeld could not determine the package root for background service dependency entry ${resolvedEntryPath}.`);
|
|
3235
|
-
}
|
|
3236
|
-
function buildDaemonServiceLauncherSource(pathInput = {}) {
|
|
3237
|
-
return `import { access, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
3238
|
-
import { join } from "node:path";
|
|
3239
|
-
import process from "node:process";
|
|
3240
|
-
import { spawn } from "node:child_process";
|
|
3241
|
-
|
|
3242
|
-
const ACTIVE_BUNDLE_PATH = ${JSON.stringify(daemonServiceActiveBundlePath(pathInput))};
|
|
3243
|
-
const INSTALL_STATE_PATH = ${JSON.stringify(daemonStatePath(pathInput))};
|
|
3244
|
-
const BUNDLE_ROOT_PATH = ${JSON.stringify(daemonRuntimeBundlesPath(pathInput))};
|
|
3245
|
-
const ALLOW_WORKSPACE_BUNDLE_SOURCE = ${JSON.stringify(resolveOpenMeldEnvPreset(pathInput) === "dev-local")};
|
|
3246
|
-
|
|
3247
|
-
const ACTIVE_BUNDLE_SCHEMA = "openmeld-daemon-active-bundle-v2";
|
|
3248
|
-
const ACTIVE_BUNDLE_LEGACY_SCHEMA = "openmeld-daemon-active-bundle-v1";
|
|
3249
|
-
const INSTALL_STATE_SCHEMA = "openmeld-daemon-install-v1";
|
|
3250
|
-
|
|
3251
|
-
async function readJsonFile(path) {
|
|
3252
|
-
try {
|
|
3253
|
-
return JSON.parse(await readFile(path, "utf8"));
|
|
3254
|
-
} catch (error) {
|
|
3255
|
-
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
3256
|
-
return null;
|
|
3257
|
-
}
|
|
3258
|
-
throw error;
|
|
3259
|
-
}
|
|
3260
|
-
}
|
|
3261
|
-
|
|
3262
|
-
async function pathExists(path) {
|
|
3263
|
-
try {
|
|
3264
|
-
await access(path);
|
|
3265
|
-
return true;
|
|
3266
|
-
} catch (error) {
|
|
3267
|
-
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
3268
|
-
return false;
|
|
3269
|
-
}
|
|
3270
|
-
throw error;
|
|
3271
|
-
}
|
|
3272
|
-
}
|
|
3273
|
-
|
|
3274
|
-
function normalizeInstallState(parsed) {
|
|
3275
|
-
if (!parsed || parsed.schema !== INSTALL_STATE_SCHEMA || typeof parsed.daemonVersion !== "string" || parsed.daemonVersion.length === 0) {
|
|
3276
|
-
return null;
|
|
3277
|
-
}
|
|
3278
|
-
return {
|
|
3279
|
-
daemonVersion: parsed.daemonVersion,
|
|
3280
|
-
};
|
|
3281
|
-
}
|
|
3282
|
-
|
|
3283
|
-
function normalizeBundleState(parsed) {
|
|
3284
|
-
if (
|
|
3285
|
-
parsed &&
|
|
3286
|
-
parsed.v === 2 &&
|
|
3287
|
-
parsed.schema === ACTIVE_BUNDLE_SCHEMA &&
|
|
3288
|
-
typeof parsed.bundleId === "string" &&
|
|
3289
|
-
parsed.bundleId.length > 0 &&
|
|
3290
|
-
typeof parsed.daemonVersion === "string" &&
|
|
3291
|
-
parsed.daemonVersion.length > 0 &&
|
|
3292
|
-
typeof parsed.entryScriptRelativePath === "string" &&
|
|
3293
|
-
parsed.entryScriptRelativePath.length > 0 &&
|
|
3294
|
-
(parsed.bundleFormat === "self_contained_v1" || parsed.bundleFormat === "legacy_linked_v1")
|
|
3295
|
-
) {
|
|
3296
|
-
return parsed;
|
|
3297
|
-
}
|
|
3298
|
-
if (
|
|
3299
|
-
parsed &&
|
|
3300
|
-
parsed.v === 1 &&
|
|
3301
|
-
parsed.schema === ACTIVE_BUNDLE_LEGACY_SCHEMA &&
|
|
3302
|
-
typeof parsed.bundleId === "string" &&
|
|
3303
|
-
parsed.bundleId.length > 0 &&
|
|
3304
|
-
typeof parsed.daemonVersion === "string" &&
|
|
3305
|
-
parsed.daemonVersion.length > 0 &&
|
|
3306
|
-
typeof parsed.entryScriptRelativePath === "string" &&
|
|
3307
|
-
parsed.entryScriptRelativePath.length > 0
|
|
3308
|
-
) {
|
|
3309
|
-
return {
|
|
3310
|
-
...parsed,
|
|
3311
|
-
bundleFormat: "legacy_linked_v1",
|
|
3312
|
-
};
|
|
3313
|
-
}
|
|
3314
|
-
return null;
|
|
3315
|
-
}
|
|
3316
|
-
|
|
3317
|
-
function normalizeBundlePackageManifest(parsed) {
|
|
3318
|
-
if (!parsed || typeof parsed.version !== "string" || parsed.version.length === 0) {
|
|
3319
|
-
return null;
|
|
3320
|
-
}
|
|
3321
|
-
return {
|
|
3322
|
-
version: parsed.version,
|
|
3323
|
-
};
|
|
3324
|
-
}
|
|
3325
|
-
|
|
3326
|
-
function uniqueNonEmptyStrings(values) {
|
|
3327
|
-
return [...new Set(values.filter((value) => typeof value === "string" && value.length > 0))];
|
|
3328
|
-
}
|
|
3329
|
-
|
|
3330
|
-
async function findFallbackSelfContainedBundle(input) {
|
|
3331
|
-
const directories = await readdir(BUNDLE_ROOT_PATH, { withFileTypes: true }).catch((error) => {
|
|
3332
|
-
if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
|
|
3333
|
-
return [];
|
|
3334
|
-
}
|
|
3335
|
-
throw error;
|
|
3336
|
-
});
|
|
3337
|
-
const entryScriptRelativePaths = uniqueNonEmptyStrings([
|
|
3338
|
-
input.preferredEntryScriptRelativePath,
|
|
3339
|
-
"dist/openmeld.js",
|
|
3340
|
-
"dist/openmeld-dev.js",
|
|
3341
|
-
]);
|
|
3342
|
-
const candidates = [];
|
|
3343
|
-
for (const directory of directories) {
|
|
3344
|
-
if (!directory.isDirectory()) {
|
|
3345
|
-
continue;
|
|
3346
|
-
}
|
|
3347
|
-
const bundleId = directory.name;
|
|
3348
|
-
const bundlePath = join(BUNDLE_ROOT_PATH, bundleId);
|
|
3349
|
-
const manifest = normalizeBundlePackageManifest(
|
|
3350
|
-
await readJsonFile(join(bundlePath, "package.json"))
|
|
3351
|
-
);
|
|
3352
|
-
if (manifest?.version !== input.installState.daemonVersion) {
|
|
3353
|
-
continue;
|
|
3354
|
-
}
|
|
3355
|
-
for (const entryScriptRelativePath of entryScriptRelativePaths) {
|
|
3356
|
-
const entryPath = join(bundlePath, entryScriptRelativePath);
|
|
3357
|
-
if (!(await pathExists(entryPath))) {
|
|
3358
|
-
continue;
|
|
3359
|
-
}
|
|
3360
|
-
const entryStat = await stat(entryPath).catch(() => null);
|
|
3361
|
-
candidates.push({
|
|
3362
|
-
bundleId,
|
|
3363
|
-
entryPath,
|
|
3364
|
-
entryScriptRelativePath,
|
|
3365
|
-
mtimeMs: entryStat?.mtimeMs ?? 0,
|
|
3366
|
-
});
|
|
3367
|
-
break;
|
|
3368
|
-
}
|
|
3369
|
-
}
|
|
3370
|
-
candidates.sort((a, b) => {
|
|
3371
|
-
if (b.mtimeMs !== a.mtimeMs) {
|
|
3372
|
-
return b.mtimeMs - a.mtimeMs;
|
|
3373
|
-
}
|
|
3374
|
-
return b.bundleId.localeCompare(a.bundleId);
|
|
3375
|
-
});
|
|
3376
|
-
return candidates[0] ?? null;
|
|
3377
|
-
}
|
|
3378
|
-
|
|
3379
|
-
async function persistFallbackActiveBundleState(input) {
|
|
3380
|
-
const now = new Date().toISOString();
|
|
3381
|
-
const bundleRootPath = join(BUNDLE_ROOT_PATH, input.bundleId);
|
|
3382
|
-
const nextState = {
|
|
3383
|
-
v: 2,
|
|
3384
|
-
schema: ACTIVE_BUNDLE_SCHEMA,
|
|
3385
|
-
bundleId: input.bundleId,
|
|
3386
|
-
daemonVersion: input.installState.daemonVersion,
|
|
3387
|
-
entryScriptRelativePath: input.entryScriptRelativePath,
|
|
3388
|
-
bundleFormat: "self_contained_v1",
|
|
3389
|
-
sourceEntryScriptPath: input.entryPath,
|
|
3390
|
-
sourcePackageRootPath: bundleRootPath,
|
|
3391
|
-
sourceDistRootPath: join(bundleRootPath, "dist"),
|
|
3392
|
-
sourceDistFingerprint: null,
|
|
3393
|
-
sourceKind: "package_install",
|
|
3394
|
-
createdAt: input.previousBundleState?.createdAt ?? now,
|
|
3395
|
-
updatedAt: now,
|
|
3396
|
-
};
|
|
3397
|
-
await writeFile(ACTIVE_BUNDLE_PATH, \`\${JSON.stringify(nextState, null, 2)}\\n\`, {
|
|
3398
|
-
encoding: "utf8",
|
|
3399
|
-
mode: 0o600,
|
|
3400
|
-
}).catch((error) => {
|
|
3401
|
-
console.error(\`OpenMeld Service launcher recovered a matching bundle but could not update active bundle state: \${String(error)}\`);
|
|
3402
|
-
});
|
|
3403
|
-
}
|
|
3404
|
-
|
|
3405
|
-
async function resolveEntryPath() {
|
|
3406
|
-
const installState = normalizeInstallState(await readJsonFile(INSTALL_STATE_PATH));
|
|
3407
|
-
const bundleState = normalizeBundleState(await readJsonFile(ACTIVE_BUNDLE_PATH));
|
|
3408
|
-
if (!installState) {
|
|
3409
|
-
throw new Error("OpenMeld Service launcher could not read a valid install state.");
|
|
3410
|
-
}
|
|
3411
|
-
if (!bundleState) {
|
|
3412
|
-
const fallback = await findFallbackSelfContainedBundle({
|
|
3413
|
-
installState,
|
|
3414
|
-
preferredEntryScriptRelativePath: null,
|
|
3415
|
-
});
|
|
3416
|
-
if (!fallback) {
|
|
3417
|
-
throw new Error("OpenMeld Service launcher could not read a valid active bundle state.");
|
|
3418
|
-
}
|
|
3419
|
-
await persistFallbackActiveBundleState({
|
|
3420
|
-
...fallback,
|
|
3421
|
-
installState,
|
|
3422
|
-
previousBundleState: null,
|
|
3423
|
-
});
|
|
3424
|
-
console.error(\`OpenMeld Service launcher recovered bundle \${fallback.bundleId} because active bundle state was missing or invalid.\`);
|
|
3425
|
-
return fallback.entryPath;
|
|
3426
|
-
}
|
|
3427
|
-
if (bundleState.bundleFormat !== "self_contained_v1") {
|
|
3428
|
-
const fallback = await findFallbackSelfContainedBundle({
|
|
3429
|
-
installState,
|
|
3430
|
-
preferredEntryScriptRelativePath: bundleState.entryScriptRelativePath,
|
|
3431
|
-
});
|
|
3432
|
-
if (!fallback) {
|
|
3433
|
-
throw new Error(\`OpenMeld Service launcher refused to start legacy bundle format \${String(bundleState.bundleFormat)}.\`);
|
|
3434
|
-
}
|
|
3435
|
-
await persistFallbackActiveBundleState({
|
|
3436
|
-
...fallback,
|
|
3437
|
-
installState,
|
|
3438
|
-
previousBundleState: bundleState,
|
|
3439
|
-
});
|
|
3440
|
-
console.error(\`OpenMeld Service launcher recovered bundle \${fallback.bundleId} because active bundle state used legacy bundle format \${String(bundleState.bundleFormat)}.\`);
|
|
3441
|
-
return fallback.entryPath;
|
|
3442
|
-
}
|
|
3443
|
-
if (bundleState.sourceKind === "workspace" && !ALLOW_WORKSPACE_BUNDLE_SOURCE) {
|
|
3444
|
-
const fallback = await findFallbackSelfContainedBundle({
|
|
3445
|
-
installState,
|
|
3446
|
-
preferredEntryScriptRelativePath: bundleState.entryScriptRelativePath,
|
|
3447
|
-
});
|
|
3448
|
-
if (!fallback) {
|
|
3449
|
-
throw new Error("OpenMeld Service launcher refused to start repo-local workspace service files in this lane. Repo-local service files are only allowed through \`openmeld-dev\`.");
|
|
3450
|
-
}
|
|
3451
|
-
await persistFallbackActiveBundleState({
|
|
3452
|
-
...fallback,
|
|
3453
|
-
installState,
|
|
3454
|
-
previousBundleState: bundleState,
|
|
3455
|
-
});
|
|
3456
|
-
console.error(\`OpenMeld Service launcher recovered bundle \${fallback.bundleId} because active bundle state pointed at a repo-local workspace bundle in this lane.\`);
|
|
3457
|
-
return fallback.entryPath;
|
|
3458
|
-
}
|
|
3459
|
-
if (bundleState.daemonVersion !== installState.daemonVersion) {
|
|
3460
|
-
const fallback = await findFallbackSelfContainedBundle({
|
|
3461
|
-
installState,
|
|
3462
|
-
preferredEntryScriptRelativePath: bundleState.entryScriptRelativePath,
|
|
3463
|
-
});
|
|
3464
|
-
if (!fallback) {
|
|
3465
|
-
throw new Error(\`OpenMeld Service launcher detected bundle version drift: bundle v\${String(bundleState.daemonVersion)} != install v\${String(installState.daemonVersion)}.\`);
|
|
3466
|
-
}
|
|
3467
|
-
await persistFallbackActiveBundleState({
|
|
3468
|
-
...fallback,
|
|
3469
|
-
installState,
|
|
3470
|
-
previousBundleState: bundleState,
|
|
3471
|
-
});
|
|
3472
|
-
console.error(\`OpenMeld Service launcher recovered bundle \${fallback.bundleId} because active bundle state had version drift.\`);
|
|
3473
|
-
return fallback.entryPath;
|
|
3474
|
-
}
|
|
3475
|
-
const entryPath = join(BUNDLE_ROOT_PATH, bundleState.bundleId, bundleState.entryScriptRelativePath);
|
|
3476
|
-
if (await pathExists(entryPath)) {
|
|
3477
|
-
return entryPath;
|
|
3478
|
-
}
|
|
3479
|
-
const fallback = await findFallbackSelfContainedBundle({
|
|
3480
|
-
installState,
|
|
3481
|
-
preferredEntryScriptRelativePath: bundleState.entryScriptRelativePath,
|
|
3482
|
-
});
|
|
3483
|
-
if (!fallback) {
|
|
3484
|
-
throw new Error(\`OpenMeld Service launcher could not find active bundle entry \${entryPath}.\`);
|
|
3485
|
-
}
|
|
3486
|
-
await persistFallbackActiveBundleState({
|
|
3487
|
-
...fallback,
|
|
3488
|
-
installState,
|
|
3489
|
-
previousBundleState: bundleState,
|
|
3490
|
-
});
|
|
3491
|
-
console.error(\`OpenMeld Service launcher recovered bundle \${fallback.bundleId} because active bundle entry was missing.\`);
|
|
3492
|
-
return fallback.entryPath;
|
|
3493
|
-
}
|
|
3494
|
-
|
|
3495
|
-
async function main() {
|
|
3496
|
-
const entryPath = await resolveEntryPath();
|
|
3497
|
-
const child = spawn(process.execPath, [entryPath, ...process.argv.slice(2)], {
|
|
3498
|
-
stdio: "inherit",
|
|
3499
|
-
env: process.env,
|
|
3500
|
-
windowsHide: true,
|
|
3501
|
-
});
|
|
3502
|
-
|
|
3503
|
-
const forwardSignal = (signal) => {
|
|
3504
|
-
if (!child.killed) {
|
|
3505
|
-
child.kill(signal);
|
|
3506
|
-
}
|
|
3507
|
-
};
|
|
3508
|
-
|
|
3509
|
-
for (const signal of ["SIGINT", "SIGTERM"]) {
|
|
3510
|
-
process.on(signal, () => {
|
|
3511
|
-
forwardSignal(signal);
|
|
3512
|
-
});
|
|
3513
|
-
}
|
|
3514
|
-
|
|
3515
|
-
child.once("error", (error) => {
|
|
3516
|
-
console.error(String(error));
|
|
3517
|
-
process.exitCode = 1;
|
|
3518
|
-
});
|
|
3519
|
-
|
|
3520
|
-
child.once("close", (code, signal) => {
|
|
3521
|
-
if (typeof code === "number") {
|
|
3522
|
-
process.exitCode = code;
|
|
3523
|
-
return;
|
|
3524
|
-
}
|
|
3525
|
-
if (signal) {
|
|
3526
|
-
process.kill(process.pid, signal);
|
|
3527
|
-
return;
|
|
3528
|
-
}
|
|
3529
|
-
process.exitCode = 1;
|
|
3530
|
-
});
|
|
3531
|
-
}
|
|
3532
|
-
|
|
3533
|
-
await main();`;
|
|
3534
|
-
}
|
|
3535
|
-
function buildDaemonServiceExecutableWrapperSource(pathInput = {}) {
|
|
3536
|
-
return ["#!/bin/sh", `exec ${quoteShellSingle(process$1.execPath)} ${quoteShellSingle(daemonServiceLauncherPath(pathInput))} "$@"`].join("\n");
|
|
3537
|
-
}
|
|
3538
|
-
function quoteShellSingle(value) {
|
|
3539
|
-
return `'${value.replaceAll("'", "'\"'\"'")}'`;
|
|
3540
|
-
}
|
|
3541
|
-
async function readDirectoryNames(path) {
|
|
3542
|
-
return (await readdir(path, { withFileTypes: true }).catch((error) => {
|
|
3543
|
-
if (getErrorCode$1(error) === "ENOENT") return [];
|
|
3544
|
-
throw error;
|
|
3545
|
-
})).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
3546
|
-
}
|
|
3547
|
-
function inferDaemonBundleSourceKind(sourcePackageRootPath) {
|
|
3548
|
-
const normalized = sourcePackageRootPath.replaceAll("\\", "/").toLowerCase();
|
|
3549
|
-
if (normalized.includes("/.npm/") && normalized.includes("_npx")) return DAEMON_BUNDLE_SOURCE_KIND_NPX_CACHE;
|
|
3550
|
-
if (normalized.includes("/node_modules/")) return DAEMON_BUNDLE_SOURCE_KIND_PACKAGE_INSTALL;
|
|
3551
|
-
if (normalized.includes("/openmeld/")) return DAEMON_BUNDLE_SOURCE_KIND_WORKSPACE;
|
|
3552
|
-
return DAEMON_BUNDLE_SOURCE_KIND_UNKNOWN;
|
|
3553
|
-
}
|
|
3554
|
-
function isDaemonBundleFormat(value) {
|
|
3555
|
-
return value === "legacy_linked_v1" || value === "self_contained_v1" || value === "binary_v1";
|
|
3556
|
-
}
|
|
3557
|
-
function isDaemonBundleSourceKind(value) {
|
|
3558
|
-
return value === DAEMON_BUNDLE_SOURCE_KIND_WORKSPACE || value === DAEMON_BUNDLE_SOURCE_KIND_PACKAGE_INSTALL || value === DAEMON_BUNDLE_SOURCE_KIND_NPX_CACHE || value === DAEMON_BUNDLE_SOURCE_KIND_UNKNOWN;
|
|
3559
|
-
}
|
|
3560
|
-
function isPackageEntryResolutionError(error) {
|
|
3561
|
-
const code = getErrorCode$1(error);
|
|
3562
|
-
return code === "MODULE_NOT_FOUND" || code === "ERR_PACKAGE_PATH_NOT_EXPORTED";
|
|
3563
|
-
}
|
|
3564
|
-
function normalizeOptionalText$54(value) {
|
|
3565
|
-
const normalized = String(value ?? "").trim();
|
|
3566
|
-
return normalized.length > 0 ? normalized : null;
|
|
3567
|
-
}
|
|
3568
|
-
async function pathExists$4(path) {
|
|
3569
|
-
try {
|
|
3570
|
-
await stat(path);
|
|
3571
|
-
return true;
|
|
3572
|
-
} catch (error) {
|
|
3573
|
-
if (getErrorCode$1(error) === "ENOENT") return false;
|
|
3574
|
-
throw error;
|
|
3575
|
-
}
|
|
3576
|
-
}
|
|
3577
|
-
async function resolvePreferredCliScriptPath(rawPath) {
|
|
3578
|
-
const preferredScriptNames = buildPreferredCliScriptNames(rawPath);
|
|
3579
|
-
const candidateRoots = [
|
|
3580
|
-
dirname(rawPath),
|
|
3581
|
-
join(process$1.cwd(), "dist"),
|
|
3582
|
-
join(process$1.cwd(), "clients", "openmeld-cli", "dist"),
|
|
3583
|
-
dirname(fileURLToPath(import.meta.url)),
|
|
3584
|
-
join(dirname(fileURLToPath(import.meta.url)), "..", "dist")
|
|
3585
|
-
];
|
|
3586
|
-
for (const scriptName of preferredScriptNames) for (const candidateRoot of candidateRoots) {
|
|
3587
|
-
const candidatePath = join(candidateRoot, scriptName);
|
|
3588
|
-
if (await pathExists$4(candidatePath)) return candidatePath;
|
|
3589
|
-
}
|
|
3590
|
-
return null;
|
|
3591
|
-
}
|
|
3592
|
-
function buildPreferredCliScriptNames(rawPath) {
|
|
3593
|
-
const requestedScriptName = basename(rawPath).endsWith(".js") ? basename(rawPath) : `${basename(rawPath)}.js`;
|
|
3594
|
-
if (isSupportedDaemonCliEntryName(requestedScriptName)) return [requestedScriptName];
|
|
3595
|
-
if (String(process$1.env.OPENMELD_DEV_MODE ?? "").trim() === "1") return [...DAEMON_CLI_ENTRY_NAMES];
|
|
3596
|
-
return [...DAEMON_CLI_ENTRY_NAMES].reverse();
|
|
3597
|
-
}
|
|
3598
|
-
function isSupportedDaemonCliEntryName(value) {
|
|
3599
|
-
return DAEMON_CLI_ENTRY_NAMES.includes(value);
|
|
3600
|
-
}
|
|
3601
|
-
function getErrorCode$1(error) {
|
|
3602
|
-
if (!error || typeof error !== "object") return;
|
|
3603
|
-
const code = error.code;
|
|
3604
|
-
return typeof code === "string" ? code : void 0;
|
|
3605
|
-
}
|
|
3606
|
-
//#endregion
|
|
3607
|
-
//#region src/runtime/version.ts
|
|
3608
|
-
/**
|
|
3609
|
-
* The version of the running CLI and Service bundle.
|
|
3610
|
-
*
|
|
3611
|
-
* npm builds use package.json. Binary builds may inject an isolated staging
|
|
3612
|
-
* prerelease so the real update lifecycle can be exercised before a production
|
|
3613
|
-
* version exists.
|
|
3614
|
-
*/
|
|
3615
|
-
function resolveOpenMeldVersion() {
|
|
3616
|
-
return (typeof __OPENMELD_VERSION__ === "string" ? __OPENMELD_VERSION__.trim() : "") || package_default.version;
|
|
3617
|
-
}
|
|
3618
|
-
const OPENMELD_VERSION = resolveOpenMeldVersion();
|
|
3619
|
-
//#endregion
|
|
3620
|
-
//#region src/local-components/managed-version-pruning.ts
|
|
3621
|
-
const MANAGED_VERSION_DIRECTORY_PATTERN = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|\d*[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
3622
|
-
async function pruneManagedVersions(input) {
|
|
3623
|
-
const versionsDir = openMeldVersionsDir(input.pathInput);
|
|
3624
|
-
const managedVersions = (await readdir(versionsDir, { withFileTypes: true })).filter((entry) => entry.isDirectory() && MANAGED_VERSION_DIRECTORY_PATTERN.test(entry.name)).map((entry) => entry.name);
|
|
3625
|
-
const usableManagedVersions = new Set((await Promise.all(managedVersions.map(async (version) => ({
|
|
3626
|
-
usable: await isUsableManagedVersion(version, versionsDir),
|
|
3627
|
-
version
|
|
3628
|
-
})))).filter((entry) => entry.usable).map((entry) => entry.version));
|
|
3629
|
-
const retainedVersions = /* @__PURE__ */ new Set([input.currentVersion]);
|
|
3630
|
-
let rollbackVersion = null;
|
|
3631
|
-
if (input.preferredRollbackVersion && input.preferredRollbackVersion !== input.currentVersion && usableManagedVersions.has(input.preferredRollbackVersion)) rollbackVersion = input.preferredRollbackVersion;
|
|
3632
|
-
rollbackVersion ??= [...usableManagedVersions].filter((version) => compareSemver(version, input.currentVersion) < 0).sort((left, right) => compareSemver(right, left))[0] ?? null;
|
|
3633
|
-
if (rollbackVersion) retainedVersions.add(rollbackVersion);
|
|
3634
|
-
for (const protectedVersion of input.protectedVersions ?? []) if (usableManagedVersions.has(protectedVersion)) retainedVersions.add(protectedVersion);
|
|
3635
|
-
await Promise.all(managedVersions.filter((version) => !retainedVersions.has(version)).map((version) => rm(path.join(versionsDir, version), { recursive: true })));
|
|
3636
|
-
}
|
|
3637
|
-
async function isUsableManagedVersion(version, versionsDir) {
|
|
3638
|
-
const target = path.join(versionsDir, version, "openmeld");
|
|
3639
|
-
if (!(await stat(target).catch((error) => {
|
|
3640
|
-
if (getErrorCode(error) === "ENOENT") return null;
|
|
3641
|
-
throw error;
|
|
3642
|
-
}))?.isFile()) return false;
|
|
3643
|
-
return await access(target, constants.X_OK).then(() => true, (error) => {
|
|
3644
|
-
if (getErrorCode(error) === "EACCES" || getErrorCode(error) === "ENOENT") return false;
|
|
3645
|
-
throw error;
|
|
3646
|
-
});
|
|
3647
|
-
}
|
|
3648
|
-
function getErrorCode(error) {
|
|
3649
|
-
return error && typeof error === "object" && "code" in error ? String(error.code) : null;
|
|
3650
|
-
}
|
|
3651
|
-
//#endregion
|
|
3652
|
-
//#region src/local-components/managed-install.ts
|
|
3653
|
-
const MANAGED_INSTALL_LOCK_PROFILE = "managed-cli";
|
|
3654
|
-
const MANAGED_INSTALL_LOCK_KEY = "install";
|
|
3655
|
-
const MANAGED_INSTALL_LOCK_RETRY_DELAY_MS = 100;
|
|
3656
|
-
const MANAGED_INSTALL_LOCK_TIMEOUT_MS = 3e4;
|
|
3657
|
-
function resolveCliPlatformToken() {
|
|
3658
|
-
return `${process$1.platform}-${process$1.arch}`;
|
|
3659
|
-
}
|
|
3660
|
-
function resolveCliSelfVersion() {
|
|
3661
|
-
return OPENMELD_VERSION;
|
|
3662
|
-
}
|
|
3663
|
-
async function isUsableManagedBinary(target) {
|
|
3664
|
-
if (!(await stat(target).catch((error) => {
|
|
3665
|
-
if (isErrorWithCode(error, "ENOENT")) return null;
|
|
3666
|
-
throw error;
|
|
3667
|
-
}))?.isFile()) return false;
|
|
3668
|
-
return await access(target, constants.X_OK).then(() => true, (error) => {
|
|
3669
|
-
if (isErrorWithCode(error, "EACCES") || isErrorWithCode(error, "ENOENT")) return false;
|
|
3670
|
-
throw error;
|
|
3671
|
-
});
|
|
3672
|
-
}
|
|
3673
|
-
async function readCurrentPointerVersion(pathInput = {}) {
|
|
3674
|
-
const pointerPath = openMeldManagedBinaryPath(pathInput);
|
|
3675
|
-
const target = await readlink(pointerPath).catch((error) => {
|
|
3676
|
-
if (isErrorWithCode(error, "ENOENT") || isErrorWithCode(error, "EINVAL")) return null;
|
|
3677
|
-
throw error;
|
|
3678
|
-
});
|
|
3679
|
-
if (!target) return null;
|
|
3680
|
-
const resolved = path.isAbsolute(target) ? target : path.resolve(path.dirname(pointerPath), target);
|
|
3681
|
-
const version = path.basename(path.dirname(resolved));
|
|
3682
|
-
return version.length > 0 && path.resolve(resolved) === openMeldManagedVersionBinaryPath(version, pathInput) ? version : null;
|
|
3683
|
-
}
|
|
3684
|
-
async function readManagedCliInstallation() {
|
|
3685
|
-
const version = await readCurrentPointerVersion();
|
|
3686
|
-
if (!version) return null;
|
|
3687
|
-
const binaryPath = openMeldManagedVersionBinaryPath(version);
|
|
3688
|
-
if (!await isUsableManagedBinary(binaryPath)) return null;
|
|
3689
|
-
return {
|
|
3690
|
-
version,
|
|
3691
|
-
binaryPath
|
|
3692
|
-
};
|
|
3693
|
-
}
|
|
3694
|
-
/**
|
|
3695
|
-
* Install the currently-running binary (process.execPath) into the managed
|
|
3696
|
-
* layout and point bin/openmeld at it. Idempotent with semver arbitration:
|
|
3697
|
-
* a same-or-newer pointer is left in place (install only goes up), unless
|
|
3698
|
-
* `force` is set. Both the versioned binary and the pointer are swapped in
|
|
3699
|
-
* atomically via a temp name + rename.
|
|
3700
|
-
*/
|
|
3701
|
-
async function performManagedInstall(input) {
|
|
3702
|
-
return await withManagedInstallTransaction(async () => performManagedInstallLocked(input));
|
|
3703
|
-
}
|
|
3704
|
-
async function withManagedInstallTransaction(run, pathInput = {}) {
|
|
3705
|
-
const startedAtMs = Date.now();
|
|
3706
|
-
for (;;) try {
|
|
3707
|
-
return await runWithHeldLock({
|
|
3708
|
-
lock: await acquireLock({
|
|
3709
|
-
openMeldProfileId: MANAGED_INSTALL_LOCK_PROFILE,
|
|
3710
|
-
key: MANAGED_INSTALL_LOCK_KEY,
|
|
3711
|
-
meta: { component: "managed_cli.install" },
|
|
3712
|
-
pathResolution: pathInput
|
|
3713
|
-
}),
|
|
3714
|
-
run,
|
|
3715
|
-
releaseContext: {
|
|
3716
|
-
component: "managed_cli.install",
|
|
3717
|
-
lockKey: MANAGED_INSTALL_LOCK_KEY,
|
|
3718
|
-
openMeldProfileId: MANAGED_INSTALL_LOCK_PROFILE
|
|
3719
|
-
}
|
|
3720
|
-
});
|
|
3721
|
-
} catch (error) {
|
|
3722
|
-
if (!isOpenMeldLockError(error) || isOpenMeldOrphanedLockError(error) || Date.now() - startedAtMs >= MANAGED_INSTALL_LOCK_TIMEOUT_MS) throw error;
|
|
3723
|
-
await setTimeout$1(MANAGED_INSTALL_LOCK_RETRY_DELAY_MS);
|
|
3724
|
-
}
|
|
3725
|
-
}
|
|
3726
|
-
/**
|
|
3727
|
-
* Prune managed CLI versions only while holding the install transaction lock.
|
|
3728
|
-
* The current pointer and every durable Service update target are re-read in
|
|
3729
|
-
* the lock, so cleanup cannot race an install or use a stale pending snapshot.
|
|
3730
|
-
*/
|
|
3731
|
-
async function pruneManagedInstallVersions(input) {
|
|
3732
|
-
const pathInput = input.pathInput;
|
|
3733
|
-
assertNoPublishedProductionMutationDuringTests(pathInput, "managed CLI versions");
|
|
3734
|
-
await withManagedInstallTransaction(async () => {
|
|
3735
|
-
const currentVersion = await readCurrentPointerVersion(pathInput);
|
|
3736
|
-
if (currentVersion === null) return;
|
|
3737
|
-
const protectedVersions = await readManagedInstallProtectedVersions(pathInput);
|
|
3738
|
-
await pruneManagedVersions({
|
|
3739
|
-
currentVersion,
|
|
3740
|
-
pathInput,
|
|
3741
|
-
preferredRollbackVersion: input.preferredRollbackVersion,
|
|
3742
|
-
protectedVersions
|
|
3743
|
-
});
|
|
3744
|
-
}, pathInput);
|
|
3745
|
-
}
|
|
3746
|
-
async function performManagedInstallLocked(input) {
|
|
3747
|
-
const force = input?.force ?? false;
|
|
3748
|
-
const version = resolveCliSelfVersion();
|
|
3749
|
-
const platform = resolveCliPlatformToken();
|
|
3750
|
-
const currentPointerPath = openMeldManagedBinaryPath();
|
|
3751
|
-
const managedBinaryPath = openMeldManagedVersionBinaryPath(version);
|
|
3752
|
-
const previousVersion = await readCurrentPointerVersion();
|
|
3753
|
-
const protectedVersions = await readManagedInstallProtectedVersions();
|
|
3754
|
-
const baseOutcome = {
|
|
3755
|
-
version,
|
|
3756
|
-
platform,
|
|
3757
|
-
managedBinaryPath,
|
|
3758
|
-
currentPointerPath,
|
|
3759
|
-
previousVersion,
|
|
3760
|
-
forced: force
|
|
3761
|
-
};
|
|
3762
|
-
if (previousVersion !== null) {
|
|
3763
|
-
const comparison = compareSemver(version, previousVersion);
|
|
3764
|
-
if (!force && comparison === 0 && await isUsableManagedBinary(managedBinaryPath)) {
|
|
3765
|
-
await pruneManagedVersions({
|
|
3766
|
-
currentVersion: previousVersion,
|
|
3767
|
-
protectedVersions
|
|
3768
|
-
});
|
|
3769
|
-
return {
|
|
3770
|
-
...baseOutcome,
|
|
3771
|
-
result: "noop_same_version"
|
|
3772
|
-
};
|
|
3773
|
-
}
|
|
3774
|
-
if (comparison < 0 && !force) {
|
|
3775
|
-
if (!await isUsableManagedBinary(managedBinaryPath)) await placeVersionedBinary(input?.sourceBinaryPath ?? process$1.execPath, version, managedBinaryPath);
|
|
3776
|
-
await pruneManagedVersions({
|
|
3777
|
-
currentVersion: previousVersion,
|
|
3778
|
-
preferredRollbackVersion: version,
|
|
3779
|
-
protectedVersions
|
|
3780
|
-
});
|
|
3781
|
-
return {
|
|
3782
|
-
...baseOutcome,
|
|
3783
|
-
result: "noop_newer_present"
|
|
3784
|
-
};
|
|
3785
|
-
}
|
|
3786
|
-
}
|
|
3787
|
-
await placeVersionedBinary(input?.sourceBinaryPath ?? process$1.execPath, version, managedBinaryPath);
|
|
3788
|
-
await pruneManagedVersions({
|
|
3789
|
-
currentVersion: version,
|
|
3790
|
-
preferredRollbackVersion: previousVersion,
|
|
3791
|
-
protectedVersions
|
|
3792
|
-
});
|
|
3793
|
-
await swapCurrentPointer(currentPointerPath, managedBinaryPath);
|
|
3794
|
-
return {
|
|
3795
|
-
...baseOutcome,
|
|
3796
|
-
result: "installed"
|
|
3797
|
-
};
|
|
3798
|
-
}
|
|
3799
|
-
async function readManagedInstallProtectedVersions(pathInput = {}) {
|
|
3800
|
-
const [protectedVersions, pendingServiceUpdate, activeBundle] = await Promise.all([
|
|
3801
|
-
readDaemonServiceUpdateWorkerProtectedManagedVersions(pathInput),
|
|
3802
|
-
readPendingDaemonServiceUpdate(pathInput),
|
|
3803
|
-
readDaemonActiveBundleState(pathInput)
|
|
3804
|
-
]);
|
|
3805
|
-
if (activeBundle?.bundleFormat === "binary_v1") protectedVersions.add(activeBundle.daemonVersion);
|
|
3806
|
-
if (pendingServiceUpdate?.preparedBundle.bundleFormat === "binary_v1") protectedVersions.add(pendingServiceUpdate.preparedBundle.daemonVersion);
|
|
3807
|
-
return protectedVersions;
|
|
3808
|
-
}
|
|
3809
|
-
async function placeVersionedBinary(sourceBinary, version, managedBinaryPath) {
|
|
3810
|
-
await mkdir(openMeldManagedVersionDir(version), { recursive: true });
|
|
3811
|
-
const tmpPath = `${managedBinaryPath}.tmp-${process$1.pid}-${Date.now()}`;
|
|
3812
|
-
await rm(tmpPath, { force: true }).catch(() => void 0);
|
|
3813
|
-
await copyFile(sourceBinary, tmpPath);
|
|
3814
|
-
await chmod(tmpPath, 493);
|
|
3815
|
-
if ((await lstat(managedBinaryPath).catch((error) => {
|
|
3816
|
-
if (isErrorWithCode(error, "ENOENT")) return null;
|
|
3817
|
-
throw error;
|
|
3818
|
-
}))?.isDirectory()) await rm(managedBinaryPath, { recursive: true });
|
|
3819
|
-
await rename(tmpPath, managedBinaryPath);
|
|
3820
|
-
}
|
|
3821
|
-
async function swapCurrentPointer(currentPointerPath, managedBinaryPath) {
|
|
3822
|
-
await mkdir(openMeldBinDir(), { recursive: true });
|
|
3823
|
-
const relativeTarget = path.relative(path.dirname(currentPointerPath), managedBinaryPath);
|
|
3824
|
-
const tmpPath = `${currentPointerPath}.tmp-${process$1.pid}-${Date.now()}`;
|
|
3825
|
-
await rm(tmpPath, { force: true }).catch(() => void 0);
|
|
3826
|
-
await symlink(relativeTarget, tmpPath);
|
|
3827
|
-
await rename(tmpPath, currentPointerPath);
|
|
3828
|
-
}
|
|
3829
|
-
function buildInstallSelfJsonPayload(outcome) {
|
|
3830
|
-
return {
|
|
3831
|
-
schemaVersion: 1,
|
|
3832
|
-
type: "cli.install_self",
|
|
3833
|
-
result: outcome.result,
|
|
3834
|
-
version: outcome.version,
|
|
3835
|
-
platform: outcome.platform,
|
|
3836
|
-
managedBinaryPath: outcome.managedBinaryPath,
|
|
3837
|
-
currentPointerPath: outcome.currentPointerPath,
|
|
3838
|
-
previousVersion: outcome.previousVersion,
|
|
3839
|
-
forced: outcome.forced
|
|
3840
|
-
};
|
|
3841
|
-
}
|
|
3842
|
-
function isErrorWithCode(error, code) {
|
|
3843
|
-
return error instanceof Error && "code" in error && error.code === code;
|
|
3844
|
-
}
|
|
3845
|
-
//#endregion
|
|
3846
|
-
//#region src/local-service/control-plane/client.ts
|
|
3847
|
-
const DEFAULT_LOCAL_DAEMON_CONTROL_PLANE_TIMEOUT_MS = 5e3;
|
|
3848
|
-
var LocalDaemonControlPlaneClientError = class extends Error {
|
|
3849
|
-
code;
|
|
3850
|
-
constructor(code, message) {
|
|
3851
|
-
super(message);
|
|
3852
|
-
this.code = code;
|
|
3853
|
-
}
|
|
3854
|
-
};
|
|
3855
|
-
async function sendLocalDaemonControlPlaneRequest(input) {
|
|
3856
|
-
const endpoint = input.endpoint ?? resolveDaemonControlPlaneEndpoint();
|
|
3857
|
-
const authToken = await readDaemonControlPlaneToken();
|
|
3858
|
-
if (!authToken) throw new LocalDaemonControlPlaneClientError("daemon.control.auth_token_missing", "daemon control token is missing");
|
|
3859
|
-
const rawResponse = await writeControlPlaneRequest({
|
|
3860
|
-
endpoint,
|
|
3861
|
-
request: {
|
|
3862
|
-
...input.request,
|
|
3863
|
-
authToken
|
|
3864
|
-
},
|
|
3865
|
-
timeoutMs: input.timeoutMs ?? DEFAULT_LOCAL_DAEMON_CONTROL_PLANE_TIMEOUT_MS
|
|
3866
|
-
});
|
|
3867
|
-
const parsed = openMeldDaemonControlPlaneResponseSchema.safeParse(rawResponse);
|
|
3868
|
-
if (!parsed.success) throw new LocalDaemonControlPlaneClientError("daemon.control.invalid_response", "local daemon control returned an invalid response");
|
|
3869
|
-
if (parsed.data.code === "service.error") throw new LocalDaemonControlPlaneClientError(parsed.data.payload.errorCode, parsed.data.payload.errorMessage);
|
|
3870
|
-
return parsed.data;
|
|
3871
|
-
}
|
|
3872
|
-
async function requestLocalSyncRouteCatalog(input) {
|
|
3873
|
-
let response;
|
|
3874
|
-
try {
|
|
3875
|
-
response = await sendLocalDaemonControlPlaneRequest({
|
|
3876
|
-
endpoint: input.endpoint,
|
|
3877
|
-
timeoutMs: input.timeoutMs,
|
|
3878
|
-
request: {
|
|
3879
|
-
v: 1,
|
|
3880
|
-
command: "sync_route_catalog",
|
|
3881
|
-
payload: input.payload
|
|
3882
|
-
}
|
|
3883
|
-
});
|
|
3884
|
-
} catch (error) {
|
|
3885
|
-
throw rewriteDaemonControlPlaneContractMismatch(error);
|
|
3886
|
-
}
|
|
3887
|
-
if (response.code !== "service.sync_route_catalog") throw new LocalDaemonControlPlaneClientError("daemon.control.invalid_response", "local daemon control returned an unexpected response for route catalog sync");
|
|
3888
|
-
return response.payload;
|
|
3889
|
-
}
|
|
3890
|
-
async function requestLocalAgentActivitySync(input) {
|
|
3891
|
-
let response;
|
|
3892
|
-
try {
|
|
3893
|
-
response = await sendLocalDaemonControlPlaneRequest({
|
|
3894
|
-
endpoint: input.endpoint,
|
|
3895
|
-
timeoutMs: input.timeoutMs,
|
|
3896
|
-
request: {
|
|
3897
|
-
v: 1,
|
|
3898
|
-
command: "request_agent_activity_sync",
|
|
3899
|
-
payload: input.payload
|
|
3900
|
-
}
|
|
3901
|
-
});
|
|
3902
|
-
} catch (error) {
|
|
3903
|
-
throw rewriteDaemonControlPlaneContractMismatch(error);
|
|
3904
|
-
}
|
|
3905
|
-
if (response.code !== "service.agent_activity_sync_requested") throw new LocalDaemonControlPlaneClientError("daemon.control.invalid_response", "local daemon control returned an unexpected response for Agent Activity sync");
|
|
3906
|
-
return response.payload;
|
|
3907
|
-
}
|
|
3908
|
-
async function requestLocalDaemonShutdown(input) {
|
|
3909
|
-
let response;
|
|
3910
|
-
try {
|
|
3911
|
-
response = await sendLocalDaemonControlPlaneRequest({
|
|
3912
|
-
endpoint: input.endpoint,
|
|
3913
|
-
timeoutMs: input.timeoutMs,
|
|
3914
|
-
request: {
|
|
3915
|
-
v: 1,
|
|
3916
|
-
command: "shutdown",
|
|
3917
|
-
payload: input.payload
|
|
3918
|
-
}
|
|
3919
|
-
});
|
|
3920
|
-
} catch (error) {
|
|
3921
|
-
throw rewriteDaemonControlPlaneContractMismatch(error);
|
|
3922
|
-
}
|
|
3923
|
-
if (response.code !== "service.shutdown") throw new LocalDaemonControlPlaneClientError("daemon.control.invalid_response", "local daemon control returned an unexpected response for shutdown");
|
|
3924
|
-
return response.payload;
|
|
3925
|
-
}
|
|
3926
|
-
async function requestLocalDaemonServiceUpdateReadiness(input = {}) {
|
|
3927
|
-
let response;
|
|
3928
|
-
try {
|
|
3929
|
-
response = await sendLocalDaemonControlPlaneRequest({
|
|
3930
|
-
endpoint: input.endpoint,
|
|
3931
|
-
timeoutMs: input.timeoutMs,
|
|
3932
|
-
request: {
|
|
3933
|
-
v: 1,
|
|
3934
|
-
command: "service_update_readiness"
|
|
3935
|
-
}
|
|
3936
|
-
});
|
|
3937
|
-
} catch (error) {
|
|
3938
|
-
throw rewriteDaemonControlPlaneContractMismatch(error);
|
|
3939
|
-
}
|
|
3940
|
-
if (response.code !== "service.update_readiness") throw new LocalDaemonControlPlaneClientError("daemon.control.invalid_response", "local daemon control returned an unexpected response for service update readiness");
|
|
3941
|
-
return response.payload;
|
|
3942
|
-
}
|
|
3943
|
-
function rewriteDaemonControlPlaneContractMismatch(error) {
|
|
3944
|
-
if (error instanceof LocalDaemonControlPlaneClientError && error.code === "service.invalid_request") return new LocalDaemonControlPlaneClientError("daemon.control.contract_mismatch", "local OpenMeld Service must be restarted because the daemon control-plane contract changed on this device");
|
|
3945
|
-
return error;
|
|
3946
|
-
}
|
|
3947
|
-
async function writeControlPlaneRequest(input) {
|
|
3948
|
-
return await new Promise((resolve, reject) => {
|
|
3949
|
-
const socket = createConnection(input.endpoint);
|
|
3950
|
-
let responseBuffer = "";
|
|
3951
|
-
let settled = false;
|
|
3952
|
-
const cleanup = () => {
|
|
3953
|
-
socket.setTimeout(0);
|
|
3954
|
-
socket.off("connect", handleConnect);
|
|
3955
|
-
socket.off("data", handleData);
|
|
3956
|
-
socket.off("end", handleEnd);
|
|
3957
|
-
socket.off("error", handleError);
|
|
3958
|
-
socket.off("timeout", handleTimeout);
|
|
3959
|
-
};
|
|
3960
|
-
const settle = (action) => {
|
|
3961
|
-
if (settled) return;
|
|
3962
|
-
settled = true;
|
|
3963
|
-
cleanup();
|
|
3964
|
-
action();
|
|
3965
|
-
};
|
|
3966
|
-
const fail = (error) => {
|
|
3967
|
-
settle(() => {
|
|
3968
|
-
socket.destroy();
|
|
3969
|
-
reject(error);
|
|
3970
|
-
});
|
|
3971
|
-
};
|
|
3972
|
-
const handleConnect = () => {
|
|
3973
|
-
socket.write(`${JSON.stringify(input.request)}\n`);
|
|
3974
|
-
};
|
|
3975
|
-
const handleData = (chunk) => {
|
|
3976
|
-
responseBuffer += chunk;
|
|
3977
|
-
};
|
|
3978
|
-
const handleEnd = () => {
|
|
3979
|
-
settle(() => {
|
|
3980
|
-
const rawResponse = responseBuffer.trim();
|
|
3981
|
-
if (!rawResponse) {
|
|
3982
|
-
reject(new LocalDaemonControlPlaneClientError("daemon.control.empty_response", "local daemon control returned an empty response"));
|
|
3983
|
-
return;
|
|
3984
|
-
}
|
|
3985
|
-
try {
|
|
3986
|
-
resolve(JSON.parse(rawResponse));
|
|
3987
|
-
} catch {
|
|
3988
|
-
reject(new LocalDaemonControlPlaneClientError("daemon.control.invalid_json", "local daemon control returned malformed JSON"));
|
|
3989
|
-
}
|
|
3990
|
-
});
|
|
3991
|
-
};
|
|
3992
|
-
const handleError = (error) => {
|
|
3993
|
-
const code = error && typeof error === "object" && "code" in error ? String(error.code) : "daemon.control.connection_failed";
|
|
3994
|
-
fail(new LocalDaemonControlPlaneClientError(code === "ENOENT" || code === "ECONNREFUSED" ? "daemon.control.endpoint_missing" : code, error instanceof Error ? error.message : "failed to connect to local daemon control"));
|
|
3995
|
-
};
|
|
3996
|
-
const handleTimeout = () => {
|
|
3997
|
-
fail(new LocalDaemonControlPlaneClientError("daemon.control.timeout", `local daemon control timed out after ${String(input.timeoutMs)}ms`));
|
|
3998
|
-
};
|
|
3999
|
-
socket.setEncoding("utf8");
|
|
4000
|
-
socket.setTimeout(input.timeoutMs);
|
|
4001
|
-
socket.once("connect", handleConnect);
|
|
4002
|
-
socket.on("data", handleData);
|
|
4003
|
-
socket.once("end", handleEnd);
|
|
4004
|
-
socket.once("error", handleError);
|
|
4005
|
-
socket.once("timeout", handleTimeout);
|
|
4006
|
-
});
|
|
4007
|
-
}
|
|
4008
|
-
//#endregion
|
|
4009
|
-
//#region src/config/auth-url.ts
|
|
4010
|
-
const DEFAULT_AUTH_BASE_URL = "https://auth.openmeld.ai";
|
|
4011
|
-
const DEV_LOCAL_AUTH_BASE_URL = "http://localhost:8788";
|
|
4012
|
-
function resolveAuthBaseUrl(cliValue, input = {}) {
|
|
4013
|
-
const env = input.env ?? process.env;
|
|
4014
|
-
const fromCli = String(cliValue ?? "").trim();
|
|
4015
|
-
if (fromCli) return normalizeBaseUrl(fromCli);
|
|
4016
|
-
const fromEnv = String(env.OPENMELD_AUTH_URL ?? "").trim();
|
|
4017
|
-
if (fromEnv) return normalizeBaseUrl(fromEnv);
|
|
4018
|
-
return normalizeBaseUrl(resolveDefaultAuthBaseUrl(env));
|
|
4019
|
-
}
|
|
4020
|
-
function resolveDefaultAuthBaseUrl(env) {
|
|
4021
|
-
const preset = resolveOpenMeldEnvPreset({ env });
|
|
4022
|
-
if (preset === "dev-local" || preset === "canary") return DEV_LOCAL_AUTH_BASE_URL;
|
|
4023
|
-
return DEFAULT_AUTH_BASE_URL;
|
|
4024
|
-
}
|
|
4025
|
-
//#endregion
|
|
4026
|
-
//#region src/config/openmeld-environment-target.ts
|
|
4027
|
-
const OPENMELD_USER_FACING_CLI_COMMAND_ENV = "OPENMELD_USER_FACING_CLI_COMMAND";
|
|
4028
|
-
async function resolveOpenMeldEnvironmentTarget(input = {}) {
|
|
4029
|
-
const env = input.env ?? process$1.env;
|
|
4030
|
-
const preset = resolveOpenMeldEnvPreset({ env });
|
|
4031
|
-
return {
|
|
4032
|
-
preset,
|
|
4033
|
-
gatewayUrl: await resolveBaseUrl(input.gatewayUrl, { env }),
|
|
4034
|
-
authBaseUrl: resolveAuthBaseUrl(input.authUrl, { env }),
|
|
4035
|
-
userFacingCommand: resolveUserFacingCommandForPreset({
|
|
4036
|
-
env,
|
|
4037
|
-
preset
|
|
4038
|
-
})
|
|
4039
|
-
};
|
|
4040
|
-
}
|
|
4041
|
-
function resolveOpenMeldEnvironmentTargetFromEnv(input = {}) {
|
|
4042
|
-
const env = input.env ?? process$1.env;
|
|
4043
|
-
const preset = resolveOpenMeldEnvPreset({ env });
|
|
4044
|
-
return {
|
|
4045
|
-
preset,
|
|
4046
|
-
gatewayUrl: resolveGatewayUrlFromEnvOnly({
|
|
4047
|
-
env,
|
|
4048
|
-
gatewayUrl: input.gatewayUrl
|
|
4049
|
-
}),
|
|
4050
|
-
authBaseUrl: resolveAuthBaseUrl(input.authUrl, { env }),
|
|
4051
|
-
userFacingCommand: resolveUserFacingCommandForPreset({
|
|
4052
|
-
env,
|
|
4053
|
-
preset
|
|
4054
|
-
})
|
|
4055
|
-
};
|
|
4056
|
-
}
|
|
4057
|
-
function resolveUserFacingCommandForPreset(input) {
|
|
4058
|
-
const explicitCommand = normalizeOptionalText$53(input.env[OPENMELD_USER_FACING_CLI_COMMAND_ENV]);
|
|
4059
|
-
if (explicitCommand) return explicitCommand;
|
|
4060
|
-
if (input.preset === "dev-local") return "openmeld-dev";
|
|
4061
|
-
if (input.preset === "canary") return "openmeld-canary";
|
|
4062
|
-
return resolveUserFacingCliEntryCommand({ env: input.env });
|
|
4063
|
-
}
|
|
4064
|
-
function resolveGatewayUrlFromEnvOnly(input) {
|
|
4065
|
-
const fromInput = normalizeOptionalText$53(input.gatewayUrl);
|
|
4066
|
-
if (fromInput) return normalizeGatewayBaseUrl(fromInput);
|
|
4067
|
-
const fromEnv = normalizeOptionalText$53(input.env.OPENMELD_GATEWAY_URL);
|
|
4068
|
-
if (fromEnv) return normalizeGatewayBaseUrl(fromEnv);
|
|
4069
|
-
return normalizeGatewayBaseUrl(resolveDefaultGatewayBaseUrl({ env: input.env }));
|
|
4070
|
-
}
|
|
4071
|
-
function normalizeOptionalText$53(value) {
|
|
4072
|
-
const normalized = String(value ?? "").trim();
|
|
4073
|
-
return normalized.length > 0 ? normalized : null;
|
|
4074
|
-
}
|
|
4075
|
-
//#endregion
|
|
4076
875
|
//#region src/config/openmeld-profile-selection.ts
|
|
4077
876
|
const SESSION_FILE_HASH_LENGTH = 8;
|
|
4078
877
|
const SESSION_FILE_MAX_LENGTH = 128;
|
|
@@ -4484,7 +1283,7 @@ function warnDaemonEvent(eventName, fields) {
|
|
|
4484
1283
|
const definedFields = Object.fromEntries(Object.entries(fields).filter((entry) => entry[1] !== void 0));
|
|
4485
1284
|
console.warn(`${nowIsoString()} ${eventName} ${JSON.stringify(definedFields)}`);
|
|
4486
1285
|
}
|
|
4487
|
-
const toErrorMessage$23 = toErrorMessage$
|
|
1286
|
+
const toErrorMessage$23 = toErrorMessage$25;
|
|
4488
1287
|
function dirnamePath(path) {
|
|
4489
1288
|
const lastSlash = Math.max(path.lastIndexOf("/"), path.lastIndexOf("\\"));
|
|
4490
1289
|
if (lastSlash <= 0) return ".";
|
|
@@ -4877,188 +1676,6 @@ function collectReasonCodes(input) {
|
|
|
4877
1676
|
return reasonCodes;
|
|
4878
1677
|
}
|
|
4879
1678
|
//#endregion
|
|
4880
|
-
//#region src/local-service/lifecycle/daemon-managed-binary-path.ts
|
|
4881
|
-
const MANAGED_BINARY_NAME = "openmeld";
|
|
4882
|
-
const PATH_BOUNDARY_PATTERN = /[\s"'<>]/u;
|
|
4883
|
-
const TRAILING_SLASHES_PATTERN = /\/+$/u;
|
|
4884
|
-
const VERSION_SEGMENT_BOUNDARY_PATTERN = /[\s"'<>/]/u;
|
|
4885
|
-
function isOpenMeldManagedBinaryPath(value, pathInput = {}) {
|
|
4886
|
-
const normalizedPath = normalizeManagedBinaryPathText(value);
|
|
4887
|
-
if (normalizedPath === normalizeManagedBinaryPathText(openMeldManagedBinaryPath(pathInput))) return true;
|
|
4888
|
-
return isManagedVersionBinaryPath(normalizedPath, pathInput);
|
|
4889
|
-
}
|
|
4890
|
-
function containsOpenMeldManagedBinaryPath(value, pathInput = {}) {
|
|
4891
|
-
const normalizedValue = normalizeManagedBinaryPathText(value);
|
|
4892
|
-
return containsExactManagedPath(normalizedValue, normalizeManagedBinaryPathText(openMeldManagedBinaryPath(pathInput))) || containsManagedVersionBinaryPath(normalizedValue, pathInput);
|
|
4893
|
-
}
|
|
4894
|
-
function resolveOpenMeldManagedVersionBinaryRootPath(value) {
|
|
4895
|
-
const normalizedPath = normalizeManagedBinaryPathText(value);
|
|
4896
|
-
const segments = normalizedPath.split("/");
|
|
4897
|
-
const binaryName = segments.pop();
|
|
4898
|
-
const versionSegment = segments.pop();
|
|
4899
|
-
const versionsDirectory = segments.pop();
|
|
4900
|
-
if (binaryName !== MANAGED_BINARY_NAME || versionsDirectory !== "versions" || !versionSegment || !isValidManagedVersionSegment(versionSegment)) return null;
|
|
4901
|
-
const rootPath = segments.join("/");
|
|
4902
|
-
if (rootPath.length > 0) return rootPath;
|
|
4903
|
-
return normalizedPath.startsWith("/") ? "/" : null;
|
|
4904
|
-
}
|
|
4905
|
-
function isManagedVersionBinaryPath(normalizedPath, pathInput) {
|
|
4906
|
-
const versionsRoot = normalizeVersionsRoot(pathInput);
|
|
4907
|
-
if (!normalizedPath.startsWith(versionsRoot)) return false;
|
|
4908
|
-
const segments = normalizedPath.slice(versionsRoot.length).split("/");
|
|
4909
|
-
const versionSegment = segments[0] ?? "";
|
|
4910
|
-
const binaryName = segments[1] ?? "";
|
|
4911
|
-
return segments.length === 2 && versionSegment.length > 0 && binaryName === MANAGED_BINARY_NAME;
|
|
4912
|
-
}
|
|
4913
|
-
function containsManagedVersionBinaryPath(normalizedValue, pathInput) {
|
|
4914
|
-
const versionsRoot = normalizeVersionsRoot(pathInput);
|
|
4915
|
-
let index = normalizedValue.indexOf(versionsRoot);
|
|
4916
|
-
while (index >= 0) {
|
|
4917
|
-
const before = index > 0 ? normalizedValue[index - 1] ?? "" : "";
|
|
4918
|
-
const afterRoot = normalizedValue.slice(index + versionsRoot.length);
|
|
4919
|
-
const versionSeparatorIndex = afterRoot.indexOf("/");
|
|
4920
|
-
if (isPathBoundary(before) && versionSeparatorIndex > 0 && isValidManagedVersionSegment(afterRoot.slice(0, versionSeparatorIndex))) {
|
|
4921
|
-
const afterVersion = afterRoot.slice(versionSeparatorIndex + 1);
|
|
4922
|
-
if (afterVersion.startsWith(MANAGED_BINARY_NAME)) {
|
|
4923
|
-
if (isPathBoundary(afterVersion[8] ?? "")) return true;
|
|
4924
|
-
}
|
|
4925
|
-
}
|
|
4926
|
-
index = normalizedValue.indexOf(versionsRoot, index + 1);
|
|
4927
|
-
}
|
|
4928
|
-
return false;
|
|
4929
|
-
}
|
|
4930
|
-
function containsExactManagedPath(normalizedValue, normalizedPath) {
|
|
4931
|
-
let index = normalizedValue.indexOf(normalizedPath);
|
|
4932
|
-
while (index >= 0) {
|
|
4933
|
-
const before = index > 0 ? normalizedValue[index - 1] ?? "" : "";
|
|
4934
|
-
const after = normalizedValue[index + normalizedPath.length] ?? "";
|
|
4935
|
-
if (isPathBoundary(before) && isPathBoundary(after)) return true;
|
|
4936
|
-
index = normalizedValue.indexOf(normalizedPath, index + 1);
|
|
4937
|
-
}
|
|
4938
|
-
return false;
|
|
4939
|
-
}
|
|
4940
|
-
function normalizeVersionsRoot(pathInput) {
|
|
4941
|
-
return `${normalizeManagedBinaryPathText(openMeldVersionsDir(pathInput)).replace(TRAILING_SLASHES_PATTERN, "")}/`;
|
|
4942
|
-
}
|
|
4943
|
-
function normalizeManagedBinaryPathText(value) {
|
|
4944
|
-
return value.trim().replaceAll("\\", "/").toLowerCase();
|
|
4945
|
-
}
|
|
4946
|
-
function isPathBoundary(value) {
|
|
4947
|
-
return value === "" || PATH_BOUNDARY_PATTERN.test(value);
|
|
4948
|
-
}
|
|
4949
|
-
function isValidManagedVersionSegment(value) {
|
|
4950
|
-
return value.length > 0 && !VERSION_SEGMENT_BOUNDARY_PATTERN.test(value);
|
|
4951
|
-
}
|
|
4952
|
-
//#endregion
|
|
4953
|
-
//#region src/local-service/lifecycle/daemon-service-command-path.ts
|
|
4954
|
-
const COMMAND_TOKEN_PATTERN = /"([^"]*)"|'([^']*)'|(\S+)/g;
|
|
4955
|
-
const COMMAND_ARGUMENT_BOUNDARY_PATTERN = /\s/u;
|
|
4956
|
-
function tokenizeDaemonCommand(command) {
|
|
4957
|
-
const tokens = [];
|
|
4958
|
-
for (const match of command.matchAll(COMMAND_TOKEN_PATTERN)) {
|
|
4959
|
-
const token = match[1] ?? match[2] ?? match[3];
|
|
4960
|
-
if (token) tokens.push(token);
|
|
4961
|
-
}
|
|
4962
|
-
return tokens;
|
|
4963
|
-
}
|
|
4964
|
-
function normalizeDaemonCommandPath(path) {
|
|
4965
|
-
return path.trim().replaceAll("\\", "/").toLowerCase();
|
|
4966
|
-
}
|
|
4967
|
-
function daemonCommandContainsExactPath(command, path) {
|
|
4968
|
-
const normalizedCommand = normalizeDaemonCommandPath(command);
|
|
4969
|
-
const normalizedPath = normalizeDaemonCommandPath(path);
|
|
4970
|
-
let pathIndex = normalizedCommand.indexOf(normalizedPath);
|
|
4971
|
-
while (pathIndex >= 0) {
|
|
4972
|
-
const beforePath = normalizedCommand[pathIndex - 1];
|
|
4973
|
-
const afterPath = normalizedCommand[pathIndex + normalizedPath.length];
|
|
4974
|
-
if (isCommandArgumentBoundary(beforePath) && isCommandArgumentBoundary(afterPath)) return true;
|
|
4975
|
-
pathIndex = normalizedCommand.indexOf(normalizedPath, pathIndex + normalizedPath.length);
|
|
4976
|
-
}
|
|
4977
|
-
return false;
|
|
4978
|
-
}
|
|
4979
|
-
function extractDaemonCommandEntryPath(command, pathInput = {}) {
|
|
4980
|
-
const unquotedWrapperPath = extractUnquotedDaemonWrapperPath(command, pathInput);
|
|
4981
|
-
if (unquotedWrapperPath) return unquotedWrapperPath;
|
|
4982
|
-
const tokens = tokenizeDaemonCommand(command);
|
|
4983
|
-
if (tokens.length === 0) return null;
|
|
4984
|
-
const serviceRunIndex = findDaemonServiceCommandIndex(tokens);
|
|
4985
|
-
const candidateTokens = serviceRunIndex > 0 ? tokens.slice(0, serviceRunIndex) : tokens;
|
|
4986
|
-
for (let index = candidateTokens.length - 1; index >= 0; index -= 1) {
|
|
4987
|
-
const token = candidateTokens[index];
|
|
4988
|
-
if (!(token && looksLikeDaemonEntryPath(token, pathInput))) continue;
|
|
4989
|
-
return token;
|
|
4990
|
-
}
|
|
4991
|
-
return null;
|
|
4992
|
-
}
|
|
4993
|
-
function isDaemonRuntimeProcessCommand(command) {
|
|
4994
|
-
const serviceCommand = parseDaemonServiceProcessCommand(command);
|
|
4995
|
-
return serviceCommand?.action === "run" || serviceCommand?.action === "start" && serviceCommand.mode === "foreground";
|
|
4996
|
-
}
|
|
4997
|
-
function parseDaemonServiceProcessCommand(command) {
|
|
4998
|
-
const tokens = tokenizeDaemonCommand(command).map((token) => token.toLowerCase());
|
|
4999
|
-
const serviceCommandIndex = findDaemonServiceCommandIndex(tokens);
|
|
5000
|
-
if (serviceCommandIndex < 0) return null;
|
|
5001
|
-
const action = tokens[serviceCommandIndex + 1];
|
|
5002
|
-
if (action !== "run" && action !== "start") return null;
|
|
5003
|
-
return {
|
|
5004
|
-
action,
|
|
5005
|
-
mode: resolveDaemonServiceProcessMode(tokens.slice(serviceCommandIndex + 2))
|
|
5006
|
-
};
|
|
5007
|
-
}
|
|
5008
|
-
function resolveDaemonBundleIdFromEntryPath(entryPath, pathInput = {}) {
|
|
5009
|
-
const normalizedEntryPath = normalizeDaemonCommandPath(entryPath);
|
|
5010
|
-
const normalizedBundleRoot = `${normalizeDaemonCommandPath(daemonRuntimeBundlesPath(pathInput))}/`;
|
|
5011
|
-
if (!normalizedEntryPath.startsWith(normalizedBundleRoot)) return null;
|
|
5012
|
-
const bundleId = normalizedEntryPath.slice(normalizedBundleRoot.length).split("/")[0];
|
|
5013
|
-
return bundleId && bundleId.length > 0 ? bundleId : null;
|
|
5014
|
-
}
|
|
5015
|
-
function looksLikeDaemonEntryPath(token, pathInput) {
|
|
5016
|
-
return token.includes("/bundles/") || token.includes("openmeld/dist/openmeld.js") || token.endsWith("/openmeld.js") || token.endsWith("/openmeld-dev.js") || token.endsWith("/daemon-service-launcher.mjs") || isRecognizedDaemonServiceExecutableWrapperPath(token, pathInput) || isOpenMeldManagedBinaryPath(token, pathInput);
|
|
5017
|
-
}
|
|
5018
|
-
function findDaemonServiceCommandIndex(tokens) {
|
|
5019
|
-
return tokens.findIndex((token, index) => token === "service" && (tokens[index + 1] === "run" || tokens[index + 1] === "start"));
|
|
5020
|
-
}
|
|
5021
|
-
function resolveDaemonServiceProcessMode(serviceArguments) {
|
|
5022
|
-
let mode = null;
|
|
5023
|
-
for (let index = 0; index < serviceArguments.length; index += 1) {
|
|
5024
|
-
const argument = serviceArguments[index];
|
|
5025
|
-
let modeValue;
|
|
5026
|
-
if (argument === "--mode") modeValue = serviceArguments[index + 1];
|
|
5027
|
-
else if (argument?.startsWith("--mode=")) modeValue = argument.slice(7);
|
|
5028
|
-
if (modeValue === "foreground" || modeValue === "background") mode = modeValue;
|
|
5029
|
-
}
|
|
5030
|
-
return mode;
|
|
5031
|
-
}
|
|
5032
|
-
function isRecognizedDaemonServiceExecutableWrapperPath(token, pathInput) {
|
|
5033
|
-
const normalizedToken = normalizeDaemonCommandPath(token);
|
|
5034
|
-
return daemonServiceRecognizedExecutablePaths$1(pathInput).some((wrapperPath) => {
|
|
5035
|
-
const normalizedWrapperPath = normalizeDaemonCommandPath(wrapperPath);
|
|
5036
|
-
return normalizedToken === normalizedWrapperPath || normalizedToken.endsWith(`/${normalizeDaemonCommandPath(basename(wrapperPath))}`);
|
|
5037
|
-
});
|
|
5038
|
-
}
|
|
5039
|
-
function extractUnquotedDaemonWrapperPath(command, pathInput) {
|
|
5040
|
-
const normalizedCommand = normalizeDaemonCommandPath(command);
|
|
5041
|
-
const serviceRunIndex = normalizedCommand.indexOf(" service run");
|
|
5042
|
-
if (serviceRunIndex <= 0) return null;
|
|
5043
|
-
const commandPrefix = command.slice(0, serviceRunIndex);
|
|
5044
|
-
const normalizedPrefix = normalizedCommand.slice(0, serviceRunIndex);
|
|
5045
|
-
for (const wrapperPath of daemonServiceRecognizedExecutablePaths$1(pathInput)) {
|
|
5046
|
-
const normalizedWrapperPath = normalizeDaemonCommandPath(wrapperPath);
|
|
5047
|
-
const wrapperPathIndex = normalizedPrefix.lastIndexOf(normalizedWrapperPath);
|
|
5048
|
-
if (wrapperPathIndex >= 0 && daemonCommandContainsExactPath(commandPrefix, wrapperPath)) return commandPrefix.slice(wrapperPathIndex, wrapperPathIndex + normalizedWrapperPath.length);
|
|
5049
|
-
const wrapperName = basename(wrapperPath);
|
|
5050
|
-
if (!wrapperName.includes(" ")) continue;
|
|
5051
|
-
const normalizedSuffix = `/${normalizeDaemonCommandPath(wrapperName)}`;
|
|
5052
|
-
const wrapperNameIndex = normalizedPrefix.lastIndexOf(normalizedSuffix);
|
|
5053
|
-
if (wrapperNameIndex < 0 || wrapperNameIndex + normalizedSuffix.length !== normalizedPrefix.length) continue;
|
|
5054
|
-
return commandPrefix.slice(0, wrapperNameIndex + normalizedSuffix.length);
|
|
5055
|
-
}
|
|
5056
|
-
return null;
|
|
5057
|
-
}
|
|
5058
|
-
function isCommandArgumentBoundary(char) {
|
|
5059
|
-
return char === void 0 || char === "'" || char === "\"" || COMMAND_ARGUMENT_BOUNDARY_PATTERN.test(char);
|
|
5060
|
-
}
|
|
5061
|
-
//#endregion
|
|
5062
1679
|
//#region src/local-service/lifecycle/daemon-service-command-spec.ts
|
|
5063
1680
|
const DEFAULT_LAUNCHD_PATH = "/usr/bin:/bin:/usr/sbin:/sbin";
|
|
5064
1681
|
const MACOS_SYSTEM_SHELL = "/bin/sh";
|
|
@@ -5091,6 +1708,7 @@ function buildDaemonSystemServiceCommandSpec(input) {
|
|
|
5091
1708
|
"--mode",
|
|
5092
1709
|
"foreground"
|
|
5093
1710
|
];
|
|
1711
|
+
if (input.accountAdmissionId) args.push("--account-admission-id", input.accountAdmissionId);
|
|
5094
1712
|
const environmentTarget = input.environmentTarget ?? resolveOpenMeldEnvironmentTargetFromEnv();
|
|
5095
1713
|
const { executable, specArgs } = resolveDaemonServiceExecutable({
|
|
5096
1714
|
args,
|
|
@@ -5257,7 +1875,7 @@ function resolveOpenMeldAccountContext(input) {
|
|
|
5257
1875
|
};
|
|
5258
1876
|
}
|
|
5259
1877
|
async function resolveCurrentOpenMeldAccountContext() {
|
|
5260
|
-
const { getAuthSessionMetadata } = await import("./auth-session-
|
|
1878
|
+
const { getAuthSessionMetadata } = await import("./auth-session-B7QMhHwh.js");
|
|
5261
1879
|
return resolveOpenMeldAccountContext({ session: await getAuthSessionMetadata().catch(() => null) });
|
|
5262
1880
|
}
|
|
5263
1881
|
function resolveHostKey(baseUrl) {
|
|
@@ -6028,590 +2646,6 @@ function toStartBackgroundHelperExecutionCompatibility(input) {
|
|
|
6028
2646
|
};
|
|
6029
2647
|
}
|
|
6030
2648
|
//#endregion
|
|
6031
|
-
//#region src/local-service/lifecycle/daemon-service-manager-command-match.ts
|
|
6032
|
-
async function assertDaemonMaintenanceInstallationOwnership() {
|
|
6033
|
-
const manager = await resolveDaemonServiceManager();
|
|
6034
|
-
if (!manager) throw new Error("OpenMeld cannot verify the background service installation.");
|
|
6035
|
-
const status = await manager.status();
|
|
6036
|
-
if (!status.installed) return;
|
|
6037
|
-
if (!await matchesExpectedDaemonServiceManagerDefinition({
|
|
6038
|
-
controller: manager.controller,
|
|
6039
|
-
definitionPath: status.definitionPath ?? null,
|
|
6040
|
-
commandSpec: status.commandSpec
|
|
6041
|
-
})) throw new Error("OpenMeld background service belongs to a different installation. Automatic maintenance was stopped without changing it.");
|
|
6042
|
-
}
|
|
6043
|
-
function matchesExpectedDaemonServiceManagerCommand(input) {
|
|
6044
|
-
if (input.controller === "windows-service") {
|
|
6045
|
-
if (input.commandSpec) return matchesWindowsTaskInstallation(input.commandSpec, input.pathInput);
|
|
6046
|
-
return typeof input.definitionPath === "string" && input.definitionPath.length > 0 && input.commandSummary.includes(input.definitionPath);
|
|
6047
|
-
}
|
|
6048
|
-
if ((input.distribution ?? resolveOpenMeldDistribution()) === "binary") {
|
|
6049
|
-
if (input.controller === "launchd") {
|
|
6050
|
-
const stableExecutablePath = daemonServiceBinaryExecutablePath(input.pathInput);
|
|
6051
|
-
return [
|
|
6052
|
-
`${stableExecutablePath} service run`,
|
|
6053
|
-
`"${stableExecutablePath}" service run`,
|
|
6054
|
-
`'${stableExecutablePath}' service run`
|
|
6055
|
-
].some((expectedPrefix) => input.commandSummary.includes(expectedPrefix));
|
|
6056
|
-
}
|
|
6057
|
-
return containsOpenMeldManagedBinaryPath(input.commandSummary, input.pathInput);
|
|
6058
|
-
}
|
|
6059
|
-
return resolveExpectedDaemonServiceManagerCommandPaths({
|
|
6060
|
-
controller: input.controller,
|
|
6061
|
-
includeLegacyExecutableWrappers: input.includeLegacyExecutableWrappers === true,
|
|
6062
|
-
pathInput: input.pathInput
|
|
6063
|
-
}).some((path) => input.commandSummary.includes(path));
|
|
6064
|
-
}
|
|
6065
|
-
async function matchesExpectedDaemonServiceManagerDefinition(input) {
|
|
6066
|
-
if (input.controller === "windows-service" && input.commandSpec) return matchesWindowsTaskInstallation(input.commandSpec, input.pathInput);
|
|
6067
|
-
if (typeof input.definitionPath !== "string" || input.definitionPath.trim().length === 0) return false;
|
|
6068
|
-
const definition = await readFile(input.definitionPath, "utf8").catch(() => null);
|
|
6069
|
-
if (definition === null) return false;
|
|
6070
|
-
if ((input.distribution ?? resolveOpenMeldDistribution()) === "binary") {
|
|
6071
|
-
if (input.controller === "launchd") {
|
|
6072
|
-
const stableExecutablePath = daemonServiceBinaryExecutablePath(input.pathInput);
|
|
6073
|
-
return definition.includes(`<string>${stableExecutablePath}</string>`);
|
|
6074
|
-
}
|
|
6075
|
-
return containsOpenMeldManagedBinaryPath(definition, input.pathInput);
|
|
6076
|
-
}
|
|
6077
|
-
return resolveExpectedDaemonServiceManagerCommandPaths({
|
|
6078
|
-
controller: input.controller ?? null,
|
|
6079
|
-
pathInput: input.pathInput
|
|
6080
|
-
}).some((path) => definition.includes(path));
|
|
6081
|
-
}
|
|
6082
|
-
function matchesWindowsTaskInstallation(spec, pathInput = {}) {
|
|
6083
|
-
return spec.args[0] === daemonServiceLauncherPath(pathInput) && spec.args[1] === "service" && spec.args[2] === "run" && resolveOpenMeldRootDir({ env: spec.env }) === resolveOpenMeldRootDir(pathInput);
|
|
6084
|
-
}
|
|
6085
|
-
function resolveExpectedDaemonServiceManagerCommandPaths(input) {
|
|
6086
|
-
if (input.controller === "launchd") return [daemonServiceExecutableWrapperPath(input.pathInput), ...input.includeLegacyExecutableWrappers === true ? [daemonServiceLegacyWrapperPath(input.pathInput)] : []];
|
|
6087
|
-
return [daemonServiceLauncherPath(input.pathInput)];
|
|
6088
|
-
}
|
|
6089
|
-
//#endregion
|
|
6090
|
-
//#region src/local-service/lifecycle/daemon-service-process-inventory.ts
|
|
6091
|
-
const POSIX_PROCESS_LINE_PATTERN = /^(\d+)\s+(\d+)\s+(.+)$/;
|
|
6092
|
-
const TRAILING_PATH_SEPARATOR_PATTERN = /\/+$/u;
|
|
6093
|
-
const OPENMELD_PACKAGE_INSTALL_ENTRY_SEGMENT = "/node_modules/openmeld/dist/openmeld.js";
|
|
6094
|
-
const OPENMELD_DEV_LOCAL_ENTRY_SEGMENT = "/openmeld-dev.js";
|
|
6095
|
-
const ALL_OPENMELD_ENV_PRESETS = [
|
|
6096
|
-
"prod",
|
|
6097
|
-
"dev-local",
|
|
6098
|
-
"canary"
|
|
6099
|
-
];
|
|
6100
|
-
const DAEMON_BIN_COMMAND_PATTERN_BY_PRESET = {
|
|
6101
|
-
prod: buildOpenMeldBinCommandPatternForPreset("prod"),
|
|
6102
|
-
"dev-local": buildOpenMeldBinCommandPatternForPreset("dev-local"),
|
|
6103
|
-
canary: buildOpenMeldBinCommandPatternForPreset("canary")
|
|
6104
|
-
};
|
|
6105
|
-
async function listDaemonOwnedProcesses(overrides = {}) {
|
|
6106
|
-
const listProcesses = overrides.listProcesses ?? listProcessesForCurrentPlatform;
|
|
6107
|
-
const ignoredProcessIds = new Set(Array.from(overrides.ignoreProcessIds ?? []).filter((pid) => Number.isInteger(pid) && pid > 0));
|
|
6108
|
-
return collapseLauncherWrapperProcesses((await listProcesses()).map((processInfo) => classifyDaemonOwnedProcess(processInfo, ignoredProcessIds, overrides.pathInput)).filter((processInfo) => processInfo !== null));
|
|
6109
|
-
}
|
|
6110
|
-
function classifyDaemonOwnedProcess(processInfo, ignoredProcessIds, pathInput = {}) {
|
|
6111
|
-
if (ignoredProcessIds.has(processInfo.pid)) return null;
|
|
6112
|
-
const normalizedCommand = normalizeProcessCommand(processInfo.command);
|
|
6113
|
-
const isRuntimeProcess = isDaemonRuntimeProcessCommand(normalizedCommand);
|
|
6114
|
-
const isLegacyDetachedProcess = normalizedCommand.includes("legacy-detached");
|
|
6115
|
-
if (!(isRuntimeProcess || isLegacyDetachedProcess)) return null;
|
|
6116
|
-
const launcherPath = normalizeProcessCommand(daemonServiceLauncherPath(pathInput));
|
|
6117
|
-
const wrapperPaths = daemonServiceRecognizedExecutablePaths(pathInput).map(normalizeProcessCommand);
|
|
6118
|
-
if (wrapperPaths.some((wrapperPath) => normalizedCommand.includes(wrapperPath) && !daemonCommandContainsExactPath(normalizedCommand, wrapperPath))) return null;
|
|
6119
|
-
if (!looksLikeCurrentLaneDaemonCandidate({
|
|
6120
|
-
launcherPath,
|
|
6121
|
-
normalizedCommand,
|
|
6122
|
-
wrapperPaths
|
|
6123
|
-
})) return null;
|
|
6124
|
-
if (resolveDaemonCommandLaneScope({
|
|
6125
|
-
launcherPath,
|
|
6126
|
-
normalizedCommand,
|
|
6127
|
-
pathInput
|
|
6128
|
-
}) !== "current_lane") return null;
|
|
6129
|
-
const ownership = resolveDaemonProcessOwnership(normalizedCommand, launcherPath, wrapperPaths, pathInput);
|
|
6130
|
-
const mode = parseDaemonServiceProcessCommand(normalizedCommand)?.mode ?? null;
|
|
6131
|
-
return {
|
|
6132
|
-
pid: processInfo.pid,
|
|
6133
|
-
parentPid: processInfo.parentPid,
|
|
6134
|
-
command: processInfo.command,
|
|
6135
|
-
mode,
|
|
6136
|
-
ownership
|
|
6137
|
-
};
|
|
6138
|
-
}
|
|
6139
|
-
async function listProcessesForCurrentPlatform() {
|
|
6140
|
-
if (process$1.platform === "win32") return await listWindowsProcesses();
|
|
6141
|
-
return await listPosixProcesses();
|
|
6142
|
-
}
|
|
6143
|
-
async function listPosixProcesses() {
|
|
6144
|
-
const output = await runCommand$2("ps", ["-axo", "pid=,ppid=,command="]);
|
|
6145
|
-
const processes = [];
|
|
6146
|
-
for (const line of output.split("\n")) {
|
|
6147
|
-
const trimmed = line.trim();
|
|
6148
|
-
if (trimmed.length === 0) continue;
|
|
6149
|
-
const match = trimmed.match(POSIX_PROCESS_LINE_PATTERN);
|
|
6150
|
-
if (!(match?.[1] && match[2] && match[3])) continue;
|
|
6151
|
-
processes.push({
|
|
6152
|
-
pid: Number(match[1]),
|
|
6153
|
-
parentPid: Number(match[2]),
|
|
6154
|
-
command: match[3]
|
|
6155
|
-
});
|
|
6156
|
-
}
|
|
6157
|
-
return processes;
|
|
6158
|
-
}
|
|
6159
|
-
function resolveDaemonProcessOwnership(normalizedCommand, launcherPath, wrapperPaths, pathInput) {
|
|
6160
|
-
const isRuntimeProcess = isDaemonRuntimeProcessCommand(normalizedCommand);
|
|
6161
|
-
if (normalizedCommand.includes(launcherPath) || wrapperPaths.some((wrapperPath) => daemonCommandContainsExactPath(normalizedCommand, wrapperPath)) || isRuntimeProcess && containsOpenMeldManagedBinaryPath(normalizedCommand, pathInput)) return "stable_launcher";
|
|
6162
|
-
if (normalizedCommand.includes("legacy-detached")) return "legacy_detached";
|
|
6163
|
-
if (isRuntimeProcess) return "cli_direct";
|
|
6164
|
-
return "unknown";
|
|
6165
|
-
}
|
|
6166
|
-
function looksLikeCurrentLaneDaemonCandidate(input) {
|
|
6167
|
-
return isDaemonRuntimeProcessCommand(input.normalizedCommand) || input.normalizedCommand.includes(input.launcherPath) || input.wrapperPaths.some((wrapperPath) => daemonCommandContainsExactPath(input.normalizedCommand, wrapperPath)) || input.normalizedCommand.includes("legacy-detached");
|
|
6168
|
-
}
|
|
6169
|
-
function resolveDaemonCommandLaneScope(input) {
|
|
6170
|
-
const managedVersionRoot = resolveDaemonCommandManagedVersionRoot(input.normalizedCommand);
|
|
6171
|
-
if (managedVersionRoot) return managedVersionRoot === normalizeRootPath(resolveOpenMeldRootDir(input.pathInput)) ? "current_lane" : "other_lane";
|
|
6172
|
-
const currentLane = resolveOpenMeldEnvPreset(input.pathInput);
|
|
6173
|
-
const managedLane = resolveManagedDaemonPathLane({
|
|
6174
|
-
normalizedCommand: input.normalizedCommand,
|
|
6175
|
-
pathInput: input.pathInput
|
|
6176
|
-
});
|
|
6177
|
-
if (managedLane) return managedLane === currentLane ? "current_lane" : "other_lane";
|
|
6178
|
-
if (hasExplicitOpenMeldHome(input.pathInput)) return "not_openmeld";
|
|
6179
|
-
const detectedLane = resolveDaemonCliCommandLane(input.normalizedCommand, input.pathInput);
|
|
6180
|
-
if (!detectedLane) return "not_openmeld";
|
|
6181
|
-
return detectedLane === currentLane ? "current_lane" : "other_lane";
|
|
6182
|
-
}
|
|
6183
|
-
function hasExplicitOpenMeldHome(pathInput) {
|
|
6184
|
-
const value = (pathInput.env ?? process$1.env)[OPENMELD_HOME_ENV_KEY];
|
|
6185
|
-
return typeof value === "string" && value.trim().length > 0;
|
|
6186
|
-
}
|
|
6187
|
-
function resolveDaemonCommandManagedVersionRoot(normalizedCommand) {
|
|
6188
|
-
for (const token of tokenizeDaemonCommand(normalizedCommand)) {
|
|
6189
|
-
const rootPath = resolveOpenMeldManagedVersionBinaryRootPath(token);
|
|
6190
|
-
if (rootPath) return normalizeRootPath(rootPath);
|
|
6191
|
-
}
|
|
6192
|
-
return null;
|
|
6193
|
-
}
|
|
6194
|
-
function resolveManagedDaemonPathLane(input) {
|
|
6195
|
-
const currentPreset = resolveOpenMeldEnvPreset(input.pathInput);
|
|
6196
|
-
for (const preset of ALL_OPENMELD_ENV_PRESETS) {
|
|
6197
|
-
const lanePathInput = resolveLanePathInput(input.pathInput, preset);
|
|
6198
|
-
const laneLauncherPath = normalizeProcessCommand(daemonServiceLauncherPath(lanePathInput));
|
|
6199
|
-
const laneWrapperPaths = daemonServiceRecognizedExecutablePaths(lanePathInput).map(normalizeProcessCommand);
|
|
6200
|
-
const laneRuntimeRoot = normalizeProcessCommand(daemonRuntimeRootPath(lanePathInput));
|
|
6201
|
-
const laneEntryPath = extractDaemonCommandEntryPath(input.normalizedCommand, lanePathInput);
|
|
6202
|
-
const laneExecutableNames = laneWrapperPaths.map((candidatePath) => basename(candidatePath));
|
|
6203
|
-
if (input.normalizedCommand.includes(laneLauncherPath) || laneWrapperPaths.some((wrapperPath) => daemonCommandContainsExactPath(input.normalizedCommand, wrapperPath)) || preset !== currentPreset && laneEntryPath !== null && laneExecutableNames.includes(normalizeProcessCommand(basename(laneEntryPath))) || input.normalizedCommand.includes(laneRuntimeRoot) || containsOpenMeldManagedBinaryPath(input.normalizedCommand, lanePathInput)) return preset;
|
|
6204
|
-
}
|
|
6205
|
-
return null;
|
|
6206
|
-
}
|
|
6207
|
-
function resolveDaemonCliCommandLane(normalizedCommand, pathInput) {
|
|
6208
|
-
if (!isDaemonRuntimeProcessCommand(normalizedCommand)) return null;
|
|
6209
|
-
if (matchesDaemonCliLane(normalizedCommand, "dev-local", pathInput)) return "dev-local";
|
|
6210
|
-
if (matchesDaemonCliLane(normalizedCommand, "canary", pathInput)) return "canary";
|
|
6211
|
-
if (matchesDaemonCliLane(normalizedCommand, "prod", pathInput)) return "prod";
|
|
6212
|
-
return null;
|
|
6213
|
-
}
|
|
6214
|
-
function matchesDaemonCliLane(normalizedCommand, preset, pathInput) {
|
|
6215
|
-
if (DAEMON_BIN_COMMAND_PATTERN_BY_PRESET[preset].test(normalizedCommand)) return true;
|
|
6216
|
-
if (preset === "dev-local") return normalizedCommand.includes(OPENMELD_DEV_LOCAL_ENTRY_SEGMENT);
|
|
6217
|
-
const canaryPackageInstallRoot = resolveCanaryPackageInstallRoot(pathInput);
|
|
6218
|
-
if (preset === "canary") return normalizedCommand.includes(canaryPackageInstallRoot) || normalizedCommand.includes("/.local/share/openmeld-canary/package-install/");
|
|
6219
|
-
return normalizedCommand.includes(OPENMELD_PACKAGE_INSTALL_ENTRY_SEGMENT) && !normalizedCommand.includes(canaryPackageInstallRoot) && !normalizedCommand.includes("/.local/share/openmeld-canary/package-install/") && !normalizedCommand.includes(OPENMELD_DEV_LOCAL_ENTRY_SEGMENT);
|
|
6220
|
-
}
|
|
6221
|
-
function collapseLauncherWrapperProcesses(processes) {
|
|
6222
|
-
const launcherPidSet = /* @__PURE__ */ new Set();
|
|
6223
|
-
for (const processInfo of processes) if (processInfo.ownership === "stable_launcher") launcherPidSet.add(processInfo.pid);
|
|
6224
|
-
if (launcherPidSet.size === 0) return processes;
|
|
6225
|
-
const collapsedProcesses = [];
|
|
6226
|
-
for (const processInfo of processes) {
|
|
6227
|
-
if (processInfo.ownership === "stable_launcher") {
|
|
6228
|
-
if (processes.some((candidate) => candidate.pid !== processInfo.pid && candidate.parentPid === processInfo.pid && candidate.ownership !== "stable_launcher")) continue;
|
|
6229
|
-
collapsedProcesses.push(processInfo);
|
|
6230
|
-
continue;
|
|
6231
|
-
}
|
|
6232
|
-
if (processInfo.parentPid !== null && launcherPidSet.has(processInfo.parentPid)) {
|
|
6233
|
-
collapsedProcesses.push({
|
|
6234
|
-
...processInfo,
|
|
6235
|
-
ownership: processInfo.ownership === "unknown" ? processInfo.ownership : "stable_launcher"
|
|
6236
|
-
});
|
|
6237
|
-
continue;
|
|
6238
|
-
}
|
|
6239
|
-
collapsedProcesses.push(processInfo);
|
|
6240
|
-
}
|
|
6241
|
-
return collapsedProcesses;
|
|
6242
|
-
}
|
|
6243
|
-
async function listWindowsProcesses() {
|
|
6244
|
-
const output = await runCommand$2("powershell", [
|
|
6245
|
-
"-NoProfile",
|
|
6246
|
-
"-Command",
|
|
6247
|
-
"Get-CimInstance Win32_Process | Select-Object ProcessId,ParentProcessId,CommandLine | ConvertTo-Json -Compress"
|
|
6248
|
-
]);
|
|
6249
|
-
const parsed = JSON.parse(output);
|
|
6250
|
-
const rows = Array.isArray(parsed) ? parsed : [parsed];
|
|
6251
|
-
const processes = [];
|
|
6252
|
-
for (const row of rows) {
|
|
6253
|
-
if (typeof row.ProcessId !== "number" || typeof row.ParentProcessId !== "number" || typeof row.CommandLine !== "string" || row.CommandLine.trim().length === 0) continue;
|
|
6254
|
-
processes.push({
|
|
6255
|
-
pid: row.ProcessId,
|
|
6256
|
-
parentPid: row.ParentProcessId,
|
|
6257
|
-
command: row.CommandLine
|
|
6258
|
-
});
|
|
6259
|
-
}
|
|
6260
|
-
return processes;
|
|
6261
|
-
}
|
|
6262
|
-
async function runCommand$2(command, args) {
|
|
6263
|
-
return await new Promise((resolve, reject) => {
|
|
6264
|
-
const child = spawn(command, args, {
|
|
6265
|
-
stdio: [
|
|
6266
|
-
"ignore",
|
|
6267
|
-
"pipe",
|
|
6268
|
-
"pipe"
|
|
6269
|
-
],
|
|
6270
|
-
env: process$1.env,
|
|
6271
|
-
windowsHide: true
|
|
6272
|
-
});
|
|
6273
|
-
let stdout = "";
|
|
6274
|
-
let stderr = "";
|
|
6275
|
-
child.stdout?.on("data", (chunk) => {
|
|
6276
|
-
stdout += chunk.toString();
|
|
6277
|
-
});
|
|
6278
|
-
child.stderr?.on("data", (chunk) => {
|
|
6279
|
-
stderr += chunk.toString();
|
|
6280
|
-
});
|
|
6281
|
-
child.once("error", reject);
|
|
6282
|
-
child.once("close", (code) => {
|
|
6283
|
-
if (code !== 0) {
|
|
6284
|
-
reject(/* @__PURE__ */ new Error(`process inventory command failed: ${command} ${args.join(" ")} ${stderr.trim()}`));
|
|
6285
|
-
return;
|
|
6286
|
-
}
|
|
6287
|
-
resolve(stdout);
|
|
6288
|
-
});
|
|
6289
|
-
});
|
|
6290
|
-
}
|
|
6291
|
-
function buildOpenMeldBinCommandPatternForPreset(preset) {
|
|
6292
|
-
const aliases = resolveDaemonServiceIdentity({ env: { OPENMELD_ENV_PRESET: preset } }).cliEntryAliases.map(escapeRegex);
|
|
6293
|
-
return new RegExp(`(^|[\\s\\/])(${aliases.join("|")})(?:\\.cmd|\\.exe|\\.js)?(?=\\s|$)`, "u");
|
|
6294
|
-
}
|
|
6295
|
-
function escapeRegex(value) {
|
|
6296
|
-
return value.replaceAll(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
6297
|
-
}
|
|
6298
|
-
function resolveCanaryPackageInstallRoot(pathInput = {}) {
|
|
6299
|
-
return normalizeProcessCommand(join(pathInput.homeDir ?? homedir(), ".local", "share", "openmeld-canary", "package-install"));
|
|
6300
|
-
}
|
|
6301
|
-
function resolveLanePathInput(pathInput, preset) {
|
|
6302
|
-
const currentPreset = resolveOpenMeldEnvPreset(pathInput);
|
|
6303
|
-
const env = {
|
|
6304
|
-
...pathInput.env ?? process$1.env,
|
|
6305
|
-
OPENMELD_ENV_PRESET: preset
|
|
6306
|
-
};
|
|
6307
|
-
if (preset !== currentPreset && env["OPENMELD_HOME"]) delete env[OPENMELD_HOME_ENV_KEY];
|
|
6308
|
-
return {
|
|
6309
|
-
...pathInput,
|
|
6310
|
-
env
|
|
6311
|
-
};
|
|
6312
|
-
}
|
|
6313
|
-
function normalizeProcessCommand(command) {
|
|
6314
|
-
return command.trim().toLowerCase().replaceAll("\\", "/");
|
|
6315
|
-
}
|
|
6316
|
-
function normalizeRootPath(path) {
|
|
6317
|
-
const normalized = normalizeProcessCommand(path);
|
|
6318
|
-
return normalized === "/" ? normalized : normalized.replace(TRAILING_PATH_SEPARATOR_PATTERN, "");
|
|
6319
|
-
}
|
|
6320
|
-
//#endregion
|
|
6321
|
-
//#region src/local-service/lifecycle/daemon-service-legacy-shared.ts
|
|
6322
|
-
const PROD_ENV_PRESET = "prod";
|
|
6323
|
-
function shouldInspectLegacySharedDaemonService(input = {}) {
|
|
6324
|
-
const env = input.env ?? process.env;
|
|
6325
|
-
if (String(env["OPENMELD_HOME"] ?? "").trim()) return false;
|
|
6326
|
-
return resolveOpenMeldEnvPreset(input) === PROD_ENV_PRESET;
|
|
6327
|
-
}
|
|
6328
|
-
function resolveLegacySharedDaemonPathInput(input = {}) {
|
|
6329
|
-
if (!shouldInspectLegacySharedDaemonService(input)) return null;
|
|
6330
|
-
return {
|
|
6331
|
-
...input,
|
|
6332
|
-
env: {
|
|
6333
|
-
...input.env ?? process.env,
|
|
6334
|
-
OPENMELD_ENV_PRESET: PROD_ENV_PRESET
|
|
6335
|
-
}
|
|
6336
|
-
};
|
|
6337
|
-
}
|
|
6338
|
-
function requiresLegacySharedDaemonServiceMigration(input) {
|
|
6339
|
-
if (hasLegacySharedServiceManagerResidual(input)) return true;
|
|
6340
|
-
return hasLegacyDetachedResidual(input);
|
|
6341
|
-
}
|
|
6342
|
-
async function inspectLegacySharedDaemonService(input = {}) {
|
|
6343
|
-
const pathInput = resolveLegacySharedDaemonPathInput(input);
|
|
6344
|
-
if (!pathInput) return null;
|
|
6345
|
-
const [installStatus, runtimeStatus, serviceManager, ownedProcesses] = await Promise.all([
|
|
6346
|
-
getDaemonStatus(pathInput),
|
|
6347
|
-
getDaemonRuntimeStatus(pathInput),
|
|
6348
|
-
resolveDaemonServiceManager(void 0, pathInput).catch(() => null),
|
|
6349
|
-
listDaemonOwnedProcesses({ pathInput }).catch(() => [])
|
|
6350
|
-
]);
|
|
6351
|
-
const serviceManagerStatus = serviceManager ? await serviceManager.status().catch(() => null) : null;
|
|
6352
|
-
return {
|
|
6353
|
-
present: requiresLegacySharedDaemonServiceMigration({
|
|
6354
|
-
pathInput,
|
|
6355
|
-
runtimeStatus,
|
|
6356
|
-
serviceManager,
|
|
6357
|
-
serviceManagerStatus,
|
|
6358
|
-
ownedProcesses
|
|
6359
|
-
}),
|
|
6360
|
-
pathInput,
|
|
6361
|
-
installStatus,
|
|
6362
|
-
runtimeStatus,
|
|
6363
|
-
serviceManager,
|
|
6364
|
-
serviceManagerStatus,
|
|
6365
|
-
ownedProcesses
|
|
6366
|
-
};
|
|
6367
|
-
}
|
|
6368
|
-
function hasLegacySharedServiceManagerResidual(input) {
|
|
6369
|
-
if (!input.serviceManagerStatus?.installed) return false;
|
|
6370
|
-
if (!input.serviceManagerStatus.commandSummary) return true;
|
|
6371
|
-
return !matchesExpectedDaemonServiceManagerCommand({
|
|
6372
|
-
controller: input.serviceManager?.controller ?? null,
|
|
6373
|
-
commandSummary: input.serviceManagerStatus.commandSummary,
|
|
6374
|
-
commandSpec: input.serviceManagerStatus.commandSpec,
|
|
6375
|
-
definitionPath: input.serviceManagerStatus.definitionPath ?? null,
|
|
6376
|
-
includeLegacyExecutableWrappers: true,
|
|
6377
|
-
pathInput: input.pathInput
|
|
6378
|
-
});
|
|
6379
|
-
}
|
|
6380
|
-
function hasLegacyDetachedResidual(input) {
|
|
6381
|
-
if (input.runtimeStatus.serviceController === "legacy-detached") return true;
|
|
6382
|
-
return input.ownedProcesses.some((processInfo) => processInfo.ownership === "legacy_detached");
|
|
6383
|
-
}
|
|
6384
|
-
async function cleanupLegacySharedDaemonServiceState(input = {}) {
|
|
6385
|
-
const pathInput = resolveLegacySharedDaemonPathInput(input);
|
|
6386
|
-
if (!pathInput) return { removed: false };
|
|
6387
|
-
const legacySharedService = await inspectLegacySharedDaemonService(input);
|
|
6388
|
-
let removedServiceManager = false;
|
|
6389
|
-
if (legacySharedService?.present && legacySharedService.serviceManager && legacySharedService.serviceManagerStatus?.installed) {
|
|
6390
|
-
await legacySharedService.serviceManager.uninstall();
|
|
6391
|
-
await legacySharedService.serviceManager.waitUntilAbsent();
|
|
6392
|
-
removedServiceManager = true;
|
|
6393
|
-
}
|
|
6394
|
-
const uninstallResult = await uninstallDaemon(pathInput);
|
|
6395
|
-
return { removed: removedServiceManager || uninstallResult.removed };
|
|
6396
|
-
}
|
|
6397
|
-
//#endregion
|
|
6398
|
-
//#region src/local-service/lifecycle/daemon-service-runtime-observer.ts
|
|
6399
|
-
function resolveObservedDaemonRuntimeStatus(input) {
|
|
6400
|
-
const runtimeLeaseIssue = resolveRuntimeLeaseIssue(input.runtimeLease);
|
|
6401
|
-
const observedProcess = selectObservedRuntimeProcess(input.ownedProcesses);
|
|
6402
|
-
if (!runtimeLeaseIssue && input.runtimeLease) return {
|
|
6403
|
-
status: "running",
|
|
6404
|
-
mode: input.runtimeLease.mode,
|
|
6405
|
-
pid: input.runtimeLease.pid,
|
|
6406
|
-
startedAt: input.runtimeLease.startedAt,
|
|
6407
|
-
updatedAt: input.runtimeLease.updatedAt,
|
|
6408
|
-
managedBySystemService: input.runtimeLease.managedBySystemService,
|
|
6409
|
-
serviceController: input.runtimeLease.serviceController,
|
|
6410
|
-
autoStart: input.runtimeLease.managedBySystemService
|
|
6411
|
-
};
|
|
6412
|
-
if (observedProcess) return {
|
|
6413
|
-
status: "stale",
|
|
6414
|
-
mode: observedProcess.mode,
|
|
6415
|
-
pid: observedProcess.pid,
|
|
6416
|
-
startedAt: input.runtimeLease?.startedAt ?? null,
|
|
6417
|
-
updatedAt: input.runtimeLease?.updatedAt ?? null,
|
|
6418
|
-
managedBySystemService: observedProcess.ownership === "stable_launcher",
|
|
6419
|
-
serviceController: observedProcess.ownership === "legacy_detached" ? "legacy-detached" : "unknown",
|
|
6420
|
-
autoStart: observedProcess.ownership === "stable_launcher",
|
|
6421
|
-
reason: runtimeLeaseIssue ?? "runtime_lease_missing"
|
|
6422
|
-
};
|
|
6423
|
-
if (!input.runtimeLease) return {
|
|
6424
|
-
status: "not_running",
|
|
6425
|
-
mode: null,
|
|
6426
|
-
pid: null,
|
|
6427
|
-
startedAt: null,
|
|
6428
|
-
updatedAt: null,
|
|
6429
|
-
managedBySystemService: false,
|
|
6430
|
-
serviceController: "unknown",
|
|
6431
|
-
autoStart: false
|
|
6432
|
-
};
|
|
6433
|
-
return {
|
|
6434
|
-
status: "stale",
|
|
6435
|
-
mode: input.runtimeLease.mode,
|
|
6436
|
-
pid: input.runtimeLease.pid,
|
|
6437
|
-
startedAt: input.runtimeLease.startedAt,
|
|
6438
|
-
updatedAt: input.runtimeLease.updatedAt,
|
|
6439
|
-
managedBySystemService: input.runtimeLease.managedBySystemService,
|
|
6440
|
-
serviceController: input.runtimeLease.serviceController,
|
|
6441
|
-
autoStart: input.runtimeLease.managedBySystemService,
|
|
6442
|
-
reason: runtimeLeaseIssue ?? "runtime_lease_missing"
|
|
6443
|
-
};
|
|
6444
|
-
}
|
|
6445
|
-
function resolveObservedRuntimeCommandEntryPath(input) {
|
|
6446
|
-
const runtimePid = typeof input.runtimeStatus.pid === "number" ? input.runtimeStatus.pid : null;
|
|
6447
|
-
if (!runtimePid) return null;
|
|
6448
|
-
const runtimeProcess = input.ownedProcesses.find((processInfo) => processInfo.pid === runtimePid);
|
|
6449
|
-
if (!runtimeProcess) return null;
|
|
6450
|
-
return extractDaemonCommandEntryPath(runtimeProcess.command);
|
|
6451
|
-
}
|
|
6452
|
-
function resolveRuntimeLeaseIssue(runtimeLease) {
|
|
6453
|
-
if (!runtimeLease) return "runtime_lease_missing";
|
|
6454
|
-
if (!Number.isInteger(runtimeLease.pid) || runtimeLease.pid <= 0) return "invalid_pid";
|
|
6455
|
-
if (!isPidAlive$2(runtimeLease.pid)) return "process_not_alive";
|
|
6456
|
-
if (isRuntimeLeaseHeartbeatStale(runtimeLease)) return "heartbeat_stale";
|
|
6457
|
-
return null;
|
|
6458
|
-
}
|
|
6459
|
-
function selectObservedRuntimeProcess(ownedProcesses) {
|
|
6460
|
-
return [...ownedProcesses].sort((left, right) => {
|
|
6461
|
-
const priorityDifference = resolveOwnershipPriority(left.ownership) - resolveOwnershipPriority(right.ownership);
|
|
6462
|
-
if (priorityDifference !== 0) return priorityDifference;
|
|
6463
|
-
const modeDifference = resolveModePriority(left.mode) - resolveModePriority(right.mode);
|
|
6464
|
-
if (modeDifference !== 0) return modeDifference;
|
|
6465
|
-
return left.pid - right.pid;
|
|
6466
|
-
})[0] ?? null;
|
|
6467
|
-
}
|
|
6468
|
-
function resolveOwnershipPriority(ownership) {
|
|
6469
|
-
switch (ownership) {
|
|
6470
|
-
case "stable_launcher": return 0;
|
|
6471
|
-
case "legacy_detached": return 1;
|
|
6472
|
-
case "cli_direct": return 2;
|
|
6473
|
-
default: return 3;
|
|
6474
|
-
}
|
|
6475
|
-
}
|
|
6476
|
-
function resolveModePriority(mode) {
|
|
6477
|
-
switch (mode) {
|
|
6478
|
-
case "background": return 0;
|
|
6479
|
-
case "foreground": return 1;
|
|
6480
|
-
default: return 2;
|
|
6481
|
-
}
|
|
6482
|
-
}
|
|
6483
|
-
function isPidAlive$2(pid) {
|
|
6484
|
-
try {
|
|
6485
|
-
process$1.kill(pid, 0);
|
|
6486
|
-
return true;
|
|
6487
|
-
} catch {
|
|
6488
|
-
return false;
|
|
6489
|
-
}
|
|
6490
|
-
}
|
|
6491
|
-
function isRuntimeLeaseHeartbeatStale(runtimeLease) {
|
|
6492
|
-
const freshnessTimestamp = runtimeLease.heartbeatAt ?? runtimeLease.updatedAt;
|
|
6493
|
-
const heartbeatMs = Date.parse(freshnessTimestamp);
|
|
6494
|
-
if (Number.isNaN(heartbeatMs)) return true;
|
|
6495
|
-
return Date.now() - heartbeatMs > DAEMON_HEARTBEAT_STALE_MS;
|
|
6496
|
-
}
|
|
6497
|
-
//#endregion
|
|
6498
|
-
//#region src/local-service/lifecycle/daemon-service-runtime.ts
|
|
6499
|
-
const DEFAULT_SYSTEM_SERVICE_STOP_WAIT_MS = 3e3;
|
|
6500
|
-
const DEFAULT_SYSTEM_SERVICE_STOP_POLL_MS = 200;
|
|
6501
|
-
async function readCurrentObservedDaemonRuntimeStatus() {
|
|
6502
|
-
return await readObservedRuntimeState();
|
|
6503
|
-
}
|
|
6504
|
-
async function clearDaemonRuntimeStateIfDefinitelyStopped() {
|
|
6505
|
-
const context = await readCurrentDaemonRuntimeContext();
|
|
6506
|
-
if (!(context.effectiveRuntimeStatus === "not_running" || await isStoppedSystemServiceSnapshot(context))) return {
|
|
6507
|
-
context,
|
|
6508
|
-
cleared: false
|
|
6509
|
-
};
|
|
6510
|
-
await clearDaemonServiceRuntimeState();
|
|
6511
|
-
return {
|
|
6512
|
-
context,
|
|
6513
|
-
cleared: true
|
|
6514
|
-
};
|
|
6515
|
-
}
|
|
6516
|
-
async function isStoppedSystemServiceSnapshot(context) {
|
|
6517
|
-
if (context.runtimeStatus.status !== "stale" || !context.runtimeStatus.managedBySystemService || context.serviceManagerStatus?.running !== false) return false;
|
|
6518
|
-
return (await listDaemonOwnedProcesses({ ignoreProcessIds: [process$1.pid, process$1.ppid] })).length === 0;
|
|
6519
|
-
}
|
|
6520
|
-
async function readCurrentDaemonRuntimeContext(input = {}) {
|
|
6521
|
-
const status = input.status ?? await getDaemonStatus();
|
|
6522
|
-
const runtimeStatus = await readCurrentObservedDaemonRuntimeStatus();
|
|
6523
|
-
const { serviceManager, serviceManagerStatus, legacySharedService } = await resolveDaemonServiceManagerForRuntimeState({
|
|
6524
|
-
status,
|
|
6525
|
-
runtimeState: runtimeStatus
|
|
6526
|
-
});
|
|
6527
|
-
return {
|
|
6528
|
-
status,
|
|
6529
|
-
runtimeStatus,
|
|
6530
|
-
serviceManager,
|
|
6531
|
-
serviceManagerStatus,
|
|
6532
|
-
legacySharedService,
|
|
6533
|
-
effectiveRuntimeStatus: getEffectiveDaemonRuntimeStatus({
|
|
6534
|
-
runtimeState: runtimeStatus,
|
|
6535
|
-
serviceManagerStatus
|
|
6536
|
-
})
|
|
6537
|
-
};
|
|
6538
|
-
}
|
|
6539
|
-
async function resolveDaemonRuntimeState(status) {
|
|
6540
|
-
if (!status.installed) return null;
|
|
6541
|
-
return await readCurrentObservedDaemonRuntimeStatus();
|
|
6542
|
-
}
|
|
6543
|
-
async function resolveDaemonServiceManagerFromRuntimeState(runtimeState) {
|
|
6544
|
-
if (!runtimeState?.managedBySystemService) return null;
|
|
6545
|
-
if (runtimeState.serviceController === "legacy-detached") return null;
|
|
6546
|
-
return await resolveDaemonServiceManager(runtimeState.serviceController);
|
|
6547
|
-
}
|
|
6548
|
-
async function resolveDaemonServiceManagerForRuntimeState(input) {
|
|
6549
|
-
const initialManager = await resolveDaemonServiceManagerFromRuntimeState(input.runtimeState);
|
|
6550
|
-
const initialManagerStatus = initialManager ? await initialManager.status().catch(() => null) : null;
|
|
6551
|
-
if (input.status.installed && input.runtimeState?.managedBySystemService !== true && !initialManagerStatus?.installed) {
|
|
6552
|
-
const detectedManager = await resolveDaemonServiceManager().catch(() => null);
|
|
6553
|
-
if (detectedManager) {
|
|
6554
|
-
const detectedManagerStatus = await detectedManager.status().catch(() => null);
|
|
6555
|
-
if (detectedManagerStatus?.installed) return {
|
|
6556
|
-
serviceManager: detectedManager,
|
|
6557
|
-
serviceManagerStatus: detectedManagerStatus,
|
|
6558
|
-
legacySharedService: null
|
|
6559
|
-
};
|
|
6560
|
-
}
|
|
6561
|
-
}
|
|
6562
|
-
const legacySharedService = await inspectLegacySharedDaemonService().catch(() => null);
|
|
6563
|
-
if (legacySharedService?.present && legacySharedService.serviceManagerStatus?.installed) {
|
|
6564
|
-
const legacyManager = legacySharedService.serviceManager ?? await resolveDaemonServiceManager(legacySharedService.runtimeStatus.serviceController === "unknown" ? void 0 : legacySharedService.runtimeStatus.serviceController, legacySharedService.pathInput).catch(() => null);
|
|
6565
|
-
if (legacyManager) return {
|
|
6566
|
-
serviceManager: legacyManager,
|
|
6567
|
-
serviceManagerStatus: legacySharedService.serviceManagerStatus,
|
|
6568
|
-
legacySharedService
|
|
6569
|
-
};
|
|
6570
|
-
}
|
|
6571
|
-
return {
|
|
6572
|
-
serviceManager: initialManager,
|
|
6573
|
-
serviceManagerStatus: initialManagerStatus,
|
|
6574
|
-
legacySharedService
|
|
6575
|
-
};
|
|
6576
|
-
}
|
|
6577
|
-
function getEffectiveDaemonRuntimeStatus(input) {
|
|
6578
|
-
if (input.runtimeState.status === "running") return "running";
|
|
6579
|
-
if (!(input.runtimeState.managedBySystemService && input.serviceManagerStatus)) return input.runtimeState.status;
|
|
6580
|
-
if (input.runtimeState.status === "stale") {
|
|
6581
|
-
if (input.runtimeState.reason === "heartbeat_stale") return "stale";
|
|
6582
|
-
if (input.serviceManagerStatus.running) return "running";
|
|
6583
|
-
if (!input.serviceManagerStatus.enabled) return "not_running";
|
|
6584
|
-
}
|
|
6585
|
-
if (!input.serviceManagerStatus.running) return "not_running";
|
|
6586
|
-
return input.runtimeState.status;
|
|
6587
|
-
}
|
|
6588
|
-
async function waitForDaemonSystemServiceToStop(input) {
|
|
6589
|
-
const waitMs = input.waitMs ?? DEFAULT_SYSTEM_SERVICE_STOP_WAIT_MS;
|
|
6590
|
-
const pollMs = input.pollMs ?? DEFAULT_SYSTEM_SERVICE_STOP_POLL_MS;
|
|
6591
|
-
const deadlineMs = Date.now() + waitMs;
|
|
6592
|
-
while (Date.now() < deadlineMs) {
|
|
6593
|
-
const currentRuntime = await readCurrentObservedDaemonRuntimeStatus().catch(() => null);
|
|
6594
|
-
if ((await input.manager.status().catch(() => null))?.running === false && currentRuntime !== null && currentRuntime.status !== "running") return true;
|
|
6595
|
-
if (currentRuntime?.status === "stale" && !currentRuntime.managedBySystemService) return true;
|
|
6596
|
-
if (currentRuntime?.status === "not_running") return true;
|
|
6597
|
-
await sleep(pollMs);
|
|
6598
|
-
}
|
|
6599
|
-
const finalRuntime = await readCurrentObservedDaemonRuntimeStatus().catch(() => null);
|
|
6600
|
-
if (finalRuntime?.status === "not_running") return true;
|
|
6601
|
-
if (finalRuntime?.status === "stale" && !finalRuntime.managedBySystemService) return true;
|
|
6602
|
-
if (finalRuntime?.status === "running") return false;
|
|
6603
|
-
if (finalRuntime === null) return false;
|
|
6604
|
-
return (await input.manager.status().catch(() => null))?.running === false;
|
|
6605
|
-
}
|
|
6606
|
-
async function readObservedRuntimeState() {
|
|
6607
|
-
const ignoredProcessIds = [process$1.pid, process$1.ppid].filter((pid) => Number.isInteger(pid) && pid > 0);
|
|
6608
|
-
const [runtimeLease, ownedProcesses] = await Promise.all([readDaemonRuntimeLease().catch(() => null), listDaemonOwnedProcesses({ ignoreProcessIds: ignoredProcessIds })]);
|
|
6609
|
-
return resolveObservedDaemonRuntimeStatus({
|
|
6610
|
-
runtimeLease,
|
|
6611
|
-
ownedProcesses
|
|
6612
|
-
});
|
|
6613
|
-
}
|
|
6614
|
-
//#endregion
|
|
6615
2649
|
//#region src/local-service/lifecycle/daemon-service-owner-snapshot.ts
|
|
6616
2650
|
async function readCurrentDaemonOwnerSnapshot(input = {}) {
|
|
6617
2651
|
const listOwnedProcesses = input.listOwnedProcesses ?? listDaemonOwnedProcesses;
|
|
@@ -25097,6 +21131,11 @@ async function buildControlPlaneResponse(input) {
|
|
|
25097
21131
|
payload: request.payload,
|
|
25098
21132
|
requestMeta
|
|
25099
21133
|
});
|
|
21134
|
+
case "account_control_capabilities": return openMeldDaemonControlPlaneResponseSchema.parse({
|
|
21135
|
+
...requestMeta,
|
|
21136
|
+
code: "service.account_control_capabilities",
|
|
21137
|
+
payload: { supported: input.context.accountCheckedServiceControl === true }
|
|
21138
|
+
});
|
|
25100
21139
|
case "service_update_readiness": return await buildServiceUpdateReadinessControlPlaneResponse({
|
|
25101
21140
|
context: input.context,
|
|
25102
21141
|
requestMeta
|
|
@@ -33512,9 +29551,9 @@ function createModelCatalogReadSession(input) {
|
|
|
33512
29551
|
async function readModelCatalogOnce(baseUrl) {
|
|
33513
29552
|
try {
|
|
33514
29553
|
const [apiClient, baseUrlModule, clientFoundationModule] = await Promise.all([
|
|
33515
|
-
import("./dist-
|
|
33516
|
-
import("./base-url-
|
|
33517
|
-
import("./api-client-foundation-
|
|
29554
|
+
import("./dist-DTG_Vqc7.js"),
|
|
29555
|
+
import("./base-url-BE3pFiOZ.js"),
|
|
29556
|
+
import("./api-client-foundation-D6_NXHPV.js")
|
|
33518
29557
|
]);
|
|
33519
29558
|
if (typeof apiClient.createConfigApi !== "function") throw new Error("config api client is unavailable");
|
|
33520
29559
|
const resolvedBaseUrl = baseUrl ?? await baseUrlModule.resolveBaseUrl();
|
|
@@ -36062,9 +32101,9 @@ async function resolveGatewayChainReadiness(input = {}) {
|
|
|
36062
32101
|
applicable: true,
|
|
36063
32102
|
baseUrl: fallbackBaseUrl,
|
|
36064
32103
|
checkedAt,
|
|
36065
|
-
details: toErrorMessage$
|
|
32104
|
+
details: toErrorMessage$24(error),
|
|
36066
32105
|
errorCode: null,
|
|
36067
|
-
errorMessage: toErrorMessage$
|
|
32106
|
+
errorMessage: toErrorMessage$24(error),
|
|
36068
32107
|
failureKind: "gateway_unreachable",
|
|
36069
32108
|
ready: false,
|
|
36070
32109
|
status: null,
|
|
@@ -39220,7 +35259,7 @@ var DaemonServiceLifecycleDrainTimeoutError = class extends Error {
|
|
|
39220
35259
|
var DaemonServiceLifecycleControlledDrainError = class extends Error {
|
|
39221
35260
|
cause;
|
|
39222
35261
|
constructor(cause) {
|
|
39223
|
-
super(`controlled service drain failed: ${toErrorMessage$
|
|
35262
|
+
super(`controlled service drain failed: ${toErrorMessage$25(cause)}`);
|
|
39224
35263
|
this.name = "DaemonServiceLifecycleControlledDrainError";
|
|
39225
35264
|
this.cause = cause;
|
|
39226
35265
|
}
|
|
@@ -39383,7 +35422,7 @@ async function runDaemonServiceLifecycle(input) {
|
|
|
39383
35422
|
evidencePath: state.evidencePath,
|
|
39384
35423
|
recoveryStatus: "failed_before_safe_state",
|
|
39385
35424
|
errorCode: resolveLifecycleFailureErrorCode(error),
|
|
39386
|
-
errorMessage: toErrorMessage$
|
|
35425
|
+
errorMessage: toErrorMessage$25(error)
|
|
39387
35426
|
};
|
|
39388
35427
|
} finally {
|
|
39389
35428
|
await cleanupPreparedBundleAfterLifecycle({
|
|
@@ -39419,7 +35458,7 @@ async function cleanupPreparedBundleAfterLifecycle(input) {
|
|
|
39419
35458
|
} catch (error) {
|
|
39420
35459
|
console.warn("[openmeld.daemon_bundle.cleanup_warning]", {
|
|
39421
35460
|
bundleId: input.preparedBundle.bundleId,
|
|
39422
|
-
errorMessage: toErrorMessage$
|
|
35461
|
+
errorMessage: toErrorMessage$25(error),
|
|
39423
35462
|
operation: input.operation
|
|
39424
35463
|
});
|
|
39425
35464
|
}
|
|
@@ -39578,7 +35617,7 @@ async function executeDaemonServiceLifecycle(input) {
|
|
|
39578
35617
|
}
|
|
39579
35618
|
}
|
|
39580
35619
|
async function recoverLifecycleFailure(input) {
|
|
39581
|
-
const originalErrorMessage = toErrorMessage$
|
|
35620
|
+
const originalErrorMessage = toErrorMessage$25(input.error);
|
|
39582
35621
|
const originalErrorCode = resolveLifecycleFailureErrorCode(input.error);
|
|
39583
35622
|
const originalFailureStage = resolveLifecycleFailureStage(input.error, input.state.failureStage);
|
|
39584
35623
|
const originalReasonCodes = resolveLifecycleFailureReasonCodes(input.error);
|
|
@@ -39590,7 +35629,7 @@ async function recoverLifecycleFailure(input) {
|
|
|
39590
35629
|
}).catch((error) => {
|
|
39591
35630
|
verifiedRollbackError = error;
|
|
39592
35631
|
console.warn("[openmeld.daemon_service.verified_rollback_failed]", {
|
|
39593
|
-
errorMessage: toErrorMessage$
|
|
35632
|
+
errorMessage: toErrorMessage$25(error),
|
|
39594
35633
|
failureStage: originalFailureStage,
|
|
39595
35634
|
operation: input.operation,
|
|
39596
35635
|
previousVersion: input.restorePoint.previousInstallState?.daemonVersion ?? null,
|
|
@@ -39615,7 +35654,7 @@ async function recoverLifecycleFailure(input) {
|
|
|
39615
35654
|
errorMessage: originalErrorMessage
|
|
39616
35655
|
};
|
|
39617
35656
|
}
|
|
39618
|
-
const recoveryErrorMessage = verifiedRollbackError ? `${originalErrorMessage}; verified previous Service recovery failed: ${toErrorMessage$
|
|
35657
|
+
const recoveryErrorMessage = verifiedRollbackError ? `${originalErrorMessage}; verified previous Service recovery failed: ${toErrorMessage$25(verifiedRollbackError)}` : originalErrorMessage;
|
|
39619
35658
|
const stoppedSafe = await transitionLifecycleToStoppedSafeCurrentVersion({
|
|
39620
35659
|
commandOptions: input.commandOptions,
|
|
39621
35660
|
currentContract: input.currentContract,
|
|
@@ -39643,7 +35682,7 @@ async function recoverLifecycleFailure(input) {
|
|
|
39643
35682
|
evidencePath: input.state.evidencePath,
|
|
39644
35683
|
recoveryStatus: "failed_before_safe_state",
|
|
39645
35684
|
errorCode: originalErrorCode,
|
|
39646
|
-
errorMessage: `${recoveryErrorMessage}; stopped-safe recovery failed: ${toErrorMessage$
|
|
35685
|
+
errorMessage: `${recoveryErrorMessage}; stopped-safe recovery failed: ${toErrorMessage$25(stoppedSafe.safeStopError)}`
|
|
39647
35686
|
};
|
|
39648
35687
|
}
|
|
39649
35688
|
input.state.runtimeDataBackup = null;
|
|
@@ -39838,7 +35877,7 @@ async function stopLifecycleSystemServiceRuntime(input) {
|
|
|
39838
35877
|
} catch (restoreError) {
|
|
39839
35878
|
throw new DaemonServiceLifecycleStageError({
|
|
39840
35879
|
cause: restoreError,
|
|
39841
|
-
message: `${toErrorMessage$
|
|
35880
|
+
message: `${toErrorMessage$25(drainError)}; failed to restore service autostart: ${toErrorMessage$25(restoreError)}`,
|
|
39842
35881
|
stage: "stop_or_drain"
|
|
39843
35882
|
});
|
|
39844
35883
|
}
|
|
@@ -39902,7 +35941,7 @@ async function requestControlledSystemServiceDrain(input) {
|
|
|
39902
35941
|
reasonCode: "socket_close_timeout"
|
|
39903
35942
|
} : {},
|
|
39904
35943
|
...isManagerRunningWithoutRuntime ? { compatibilityReason: "manager_running_without_runtime" } : {},
|
|
39905
|
-
errorMessage: toErrorMessage$
|
|
35944
|
+
errorMessage: toErrorMessage$25(error)
|
|
39906
35945
|
},
|
|
39907
35946
|
result: isCompatibilityFallback ? "fallback" : "failed",
|
|
39908
35947
|
stopCause: "controlled_service_update",
|
|
@@ -39987,7 +36026,7 @@ async function waitForLifecycleRuntimeAbsentWithRetry(serviceManager) {
|
|
|
39987
36026
|
} catch (retryError) {
|
|
39988
36027
|
throw new DaemonServiceLifecycleStageError({
|
|
39989
36028
|
cause: retryError,
|
|
39990
|
-
message: `${toErrorMessage$
|
|
36029
|
+
message: `${toErrorMessage$25(retryError)}; initial absence verification failed: ${toErrorMessage$25(initialError)}`,
|
|
39991
36030
|
stage: "wait_absent"
|
|
39992
36031
|
});
|
|
39993
36032
|
}
|
|
@@ -39997,7 +36036,7 @@ async function cleanupStaleDaemonRuntimeDataBackupsAfterHealthyLifecycle(operati
|
|
|
39997
36036
|
await cleanupStaleDaemonRuntimeDataBackups();
|
|
39998
36037
|
} catch (error) {
|
|
39999
36038
|
console.warn("[openmeld.daemon_runtime_data.cleanup_warning]", {
|
|
40000
|
-
errorMessage: toErrorMessage$
|
|
36039
|
+
errorMessage: toErrorMessage$25(error),
|
|
40001
36040
|
operation
|
|
40002
36041
|
});
|
|
40003
36042
|
}
|
|
@@ -40420,7 +36459,7 @@ async function stopDaemonProcess(pid, signal) {
|
|
|
40420
36459
|
process$1.kill(pid, signal);
|
|
40421
36460
|
} catch (error) {
|
|
40422
36461
|
if (error instanceof Error && error.code === "ESRCH") return true;
|
|
40423
|
-
throw new Error(`Failed to send ${signal} to pid ${String(pid)}: ${toErrorMessage$
|
|
36462
|
+
throw new Error(`Failed to send ${signal} to pid ${String(pid)}: ${toErrorMessage$25(error)}`);
|
|
40424
36463
|
}
|
|
40425
36464
|
if (signal === "SIGKILL") return true;
|
|
40426
36465
|
return await waitForProcessToExit(pid, PROCESS_STOP_WAIT_MS);
|
|
@@ -40430,7 +36469,7 @@ async function stopDaemonProcessWithTimeout(pid, signal, timeoutMs) {
|
|
|
40430
36469
|
process$1.kill(pid, signal);
|
|
40431
36470
|
} catch (error) {
|
|
40432
36471
|
if (error instanceof Error && error.code === "ESRCH") return true;
|
|
40433
|
-
throw new Error(`Failed to send ${signal} to pid ${String(pid)}: ${toErrorMessage$
|
|
36472
|
+
throw new Error(`Failed to send ${signal} to pid ${String(pid)}: ${toErrorMessage$25(error)}`);
|
|
40434
36473
|
}
|
|
40435
36474
|
return await waitForProcessToExit(pid, timeoutMs);
|
|
40436
36475
|
}
|
|
@@ -40542,7 +36581,7 @@ async function reschedulePendingDaemonServiceUpdate(input) {
|
|
|
40542
36581
|
async function pruneWorkerVersionsBestEffort(input) {
|
|
40543
36582
|
await input.dependencies.pruneWorkerVersions(input.job).catch((error) => {
|
|
40544
36583
|
console.warn("[openmeld.daemon_service.update_worker_prune_failed]", {
|
|
40545
|
-
errorMessage: toErrorMessage$
|
|
36584
|
+
errorMessage: toErrorMessage$25(error),
|
|
40546
36585
|
operationId: input.job.jobId,
|
|
40547
36586
|
targetVersion: input.job.targetVersion
|
|
40548
36587
|
});
|
|
@@ -40586,7 +36625,7 @@ async function recordSafeSwitchWaitFailure(deps, waiting, error) {
|
|
|
40586
36625
|
if (!(current && isSameWaitingUpdate(current, waiting))) return;
|
|
40587
36626
|
await deps.persistPendingJob({
|
|
40588
36627
|
...current,
|
|
40589
|
-
errorMessage: toErrorMessage$
|
|
36628
|
+
errorMessage: toErrorMessage$25(error),
|
|
40590
36629
|
updatedAt: deps.now()
|
|
40591
36630
|
});
|
|
40592
36631
|
}
|
|
@@ -40633,7 +36672,7 @@ async function runPreparedPendingUpdate(deps) {
|
|
|
40633
36672
|
await deps.completePendingJob(completed);
|
|
40634
36673
|
return completed;
|
|
40635
36674
|
} catch (error) {
|
|
40636
|
-
const errorMessage = toErrorMessage$
|
|
36675
|
+
const errorMessage = toErrorMessage$25(error);
|
|
40637
36676
|
if (running.attempts < MAX_BACKGROUND_UPDATE_ATTEMPTS) {
|
|
40638
36677
|
const retry = {
|
|
40639
36678
|
...running,
|
|
@@ -41264,7 +37303,7 @@ async function runAttempt(attempt, deps) {
|
|
|
41264
37303
|
} catch (error) {
|
|
41265
37304
|
await deps.completeAttempt({
|
|
41266
37305
|
...running,
|
|
41267
|
-
errorMessage: toErrorMessage$
|
|
37306
|
+
errorMessage: toErrorMessage$25(error),
|
|
41268
37307
|
operation: {
|
|
41269
37308
|
...running.operation,
|
|
41270
37309
|
phase: "needs_help",
|
|
@@ -41321,6 +37360,6 @@ function projectServiceJob(job) {
|
|
|
41321
37360
|
};
|
|
41322
37361
|
}
|
|
41323
37362
|
//#endregion
|
|
41324
|
-
export { formatDeviceReplyReadinessLabel as $, RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS as $a, getSetupFlowCopy as $i, resolveRouteRegistrationReconcileDecision as $n, createOpenMeldHumanProfile as $o, resolveAgentControllerPermissionModeForController as $r, resolveProjectBindingForPath as $t, resolveDaemonStatusSnapshot as A, normalizeNonNegativeInteger as Aa, readCurrentDaemonOwnerSnapshot as Ai, resolveSkillsAgentRegistry as An, readRecentDaemonLifecycleEvents as Ao, seedLegacyAgentContext as Ar, createModelCatalogReadSession as At, formatDaemonServiceRefreshReliabilityMessage as B, CONTROLLED_SHUTDOWN_SOCKET_CLOSE_TIMEOUT_MS as Ba, waitForDaemonSystemServiceToStop as Bi, repairBuiltinControllerInstall as Bn, hasIndependentMaintenanceRegistration as Bo, buildWorkingLanguagePromptPlan as Br, setOpenMeldManagedProfileWorkspace as Bt, isSystemServiceStartupTimeoutError as C, ensureDaemonRuntimePaths as Ca, buildCliLaunchInvocation as Ci, removeAgentCustomTarget as Cn, completePendingDaemonServiceUpdate as Co, buildRuntimeWorkspaceFingerprint as Cr, formatProfileAwareOpenMeldCliCommand as Cs, summarizeSkippedDaemonProfiles as Ct, captureDaemonServiceEvidence as D, dirnamePath as Da, buildDaemonOwnerSnapshotFromObservedState as Di, updateAgentRegistrations as Dn, formatDaemonLifecycleOriginSummary as Do, loadLedgerState as Dr, compareAgentControllerRefsForDisplay as Ds, resolveLocalController as Dt, startDaemonSystemServiceWithAutoRepair as E, asRecord as Ea, inspectDaemonServiceInventory as Ei, updateAgentCustomTarget as En, emitDaemonLifecycleEvent as Eo, commitResolvedAgentContext as Er, resolveUserFacingCliEntryCommand as Es, readLocalEnabledControllers as Et, buildDaemonServiceRefreshNextStep as F, warnDaemonEvent as Fa, getEffectiveDaemonRuntimeStatus as Fi, notifyDaemonRouteCatalogChanged as Fn, downloadCliBinaryUpdateArtifact as Fo, buildAgentContextLookupKey as Fr, readProfileWorkspaceConfig as Ft, buildDaemonServiceDependencyDetails as G, DEFAULT_RECONNECT_DELAY_MS as Ga, toStartBackgroundHelperExecutionCompatibility as Gi, isNpmGlobalCommandPath as Gn, buildNextVersionState as Go, getAgentControllerPermissionModeFieldLabel as Gr, bindProject as Gt, resolveDaemonServiceFreshnessWarning as H, DAEMON_STREAM_CONNECT_TIMEOUT_MS as Ha, listDaemonOwnedProcesses as Hi, resolveBuiltinAgentControllerDefinition as Hn, isDaemonServiceContractIdentityReusable as Ho, createAgentExecutionStatusDisplayRows as Hr, describeProfileWorkspacePathValidationFailure as Ht, buildDaemonServiceRefreshPromptMessage as I, CATALOG_SYNC_RETRY_INTERVAL_MS as Ia, readCurrentDaemonRuntimeContext as Ii, normalizeAgentId as In, resolveCliBinaryUpdatePlan as Io, DEFAULT_TASK_LIFECYCLE_HEARTBEAT_INTERVAL_MS as Ir, readProfileWorkspaceConfigForAccount as It, buildDaemonServiceDependencySummary as J, PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS as Ja, DaemonServiceRunError as Ji, normalizeDispatchThreadAction as Jn, fetchLatestCliBinaryRelease as Jo, parseAgentControllerRef as Jr, listProjectConnectionsWithStatus as Jt, buildDaemonServiceDependencyMeaning as K, HEARTBEAT_RESPONSE_TIMEOUT_MS as Ka, ensureDaemonRuntimeContractState as Ki, isPnpmGlobalCommandPath as Kn, compareSemver as Ko, isAgentExecutionReadyOrConnecting as Kr, isProjectBound as Kt, buildDaemonServiceRepairGuidance as L, CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS as La, readCurrentObservedDaemonRuntimeStatus as Li, normalizeAgentIds as Ln, verifyCliBinaryCodeSignature as Lo, areAgentControllerInterfaceAccountsSame as Lr, resolveConfiguredProfileWorkspacePath as Lt, resolveDaemonStatusAuthenticationAttention as M, normalizeText$11 as Ma, resolveStoppedContractWriteBlockedReason as Mi, resolveRegistryOriginLaunchCommand as Mn, runDaemonServiceManagerAction as Mo, upsertConversationExecutionState as Mr, resolveProfileWorkspaceRuntime as Mt, resolveServiceReadiness as N, nowIsoString as Na, summarizeDaemonOwnerSnapshot as Ni, resolveRegistryRuntimeAdapterCapabilitySnapshot as Nn, runWithDaemonLifecycleCommandJournal as No, withLedgerStateTransaction as Nr, ensureOpenMeldManagedProfileWorkspace as Nt, captureDaemonServiceEvidenceBestEffort as O, emitRunLine as Oa, formatDaemonOwnerSummaryLabel as Oi, canManageRegistryAgentSkillTargets as On, readLatestDaemonLifecycleConnectionStateEvent as Oo, removeConversationExecutionState as Or, resolveBuiltinAgentControllerBrand as Os, resolveLocalRuntimeControllerSupport as Ot, resolveServiceReadinessFromServiceStatus as P, toErrorMessage$23 as Pa, clearDaemonRuntimeStateIfDefinitelyStopped as Pi, resolveRegistryRuntimeAdapterContractByAgentControllerRef as Pn, collectLocalOperationFailure as Po, buildAuthenticatedControlPlaneResponse as Pr, normalizeCustomProfileWorkspacePath as Pt, formatAgentReplyReadinessLabel as Q, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS as Qa, buildOnboardingPlan as Qi, isDaemonReconcileInProgressError as Qn, createOpenMeldAgentProfile as Qo, renderWorkingLanguagePrompt as Qr, removeProjectConnection as Qt, buildDaemonServiceStatusReadOnlyDetail as R, CONTROLLED_SHUTDOWN_REQUEST_TIMEOUT_MS as Ra, resolveDaemonRuntimeState as Ri, parseAgentEnabledOption as Rn, package_default as Ro, buildAgentControllerRef as Rr, resolveConfiguredProfileWorkspacePathForAccount as Rt, isDaemonInventoryRunningAndStartReady as S, buildLedgerPaths as Sa, resolveDispatchSpaceActionMcpServer as Si, reconcileNewRunnableBuiltinAgentsForSetup as Sn, resolveDaemonBundleEntryPathFromState as So, runRuntimeTask as Sr, formatOpenMeldCliTextBlock as Ss, loadDaemonRouteCatalog as St, waitForSystemServiceStartup as T, resolvePreferredDaemonDeviceId as Ta, createProviderOriginalError as Ti, setAgentRegistrationEnabled as Tn, readPendingDaemonServiceUpdate as To, appendLedgerHistoryEntry as Tr, resolveSetupFollowUpCliEntryCommand as Ts, buildRuntimeRouteTargets as Tt, clearDaemonStartFailureState as U, DAEMON_STREAM_KEEPALIVE_INTERVAL_MS as Ua, assertDaemonMaintenanceInstallationOwnership as Ui, isBunGlobalCommandPath as Un, readDaemonServiceContract as Uo, createAuthorityOpenMeldServiceRuntimeId as Ur, ProjectBindingOperationError as Ut, formatDaemonServiceUpdateRequiredMessage as V, DAEMON_RUNTIME_CONTRACT_EPOCH as Va, cleanupLegacySharedDaemonServiceState as Vi, EMPTY_AGENT_CONTROLLER_INTERFACE_CAPABILITIES as Vn, clearDaemonServiceContract as Vo, createAgentControllerInterfaceDisplayRows as Vr, validateCustomProfileWorkspacePath as Vt, writeDaemonStartFailureState as W, DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS as Wa, resolveDaemonRuntimeContractCompatibility as Wi, isHomebrewCommandPath as Wn, upsertDaemonServiceContract as Wo, getAgentControllerPermissionModeDisplayMetadata as Wr, ProjectBindingStoreUpdateRequiredError as Wt, resolveDaemonServiceDependencyDiagnostics as X, REGISTER_RESPONSE_TIMEOUT_MS as Xa, PREPARE_SESSION_RECONNECT_GRACE_MS as Xi, SPACE_ACTION_CONTEXT_GUIDANCE_LINES as Xn, readVersionState as Xo, projectPeopleComputersToLegacyLocalRuntimes as Xr, removeAgentActivityBindingsWhileDeliveryLocked as Xt, buildDaemonServiceDependencyTitle as Y, PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS as Ya, resolveCurrentDaemonExpectedVersion as Yi, syncRuntimeEventToInflightTaskControlRegistry as Yn, fetchLatestPackageInfo as Yo, peopleComputerContainsDevice as Yr, migrateProjectBindingStore as Yt, resolveCurrentReplyReadinessSnapshot as Z, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS as Za, buildDaemonRouteObservationPresentation as Zi, SPACE_ACTION_TARGET_GUIDANCE_LINES as Zn, writeVersionState as Zo, renderInformationProtectionPrompt as Zr, removeMissingProjectConnections as Zt, DaemonServiceLifecycleDrainTimeoutError as _, DAEMON_SERVICE_FULL_ALIGNMENT_ANOMALIES as _a, forkCodexAppServerThread as _i, listAgentRegistrations as _n, OPENMELD_VERSION as _o, resolveDispatchQueueLogMeta as _r, resolveAuthenticationReasonFromState as _s, readDaemonRouteCatalogCache as _t, resolveServiceUpdateUrgency as a, resolveCurrentOpenMeldAccountContext as aa, resolveCatalogSyncSkippedProfilesLogState as ai, withAgentActivityDeliveryLock as an, clearSelectedOpenMeldProfileId as ao, createLocalTaskInterruptSender as ar, updateOpenMeldProfile as as, resolveReplyReadinessAvailabilityReasonCopy as at, prepareDaemonServiceUpdateWorkerCarrier as b, classifyDaemonServiceRunStartability as ba, createUnavailableProviderUsageLimits as bi, readAgentRuntimeConfigHealth as bn, readDaemonActiveBundleState as bo, resolveCompatibleConversationExecutionState as br, formatOpenMeldCliCommands as bs, createMutableRouteCatalogState as bt, buildLocalAgentCatalogFromReadiness as c, ensureDaemonSystemServiceCommandFiles as ca, parseOpenCodeGoUsageResponse as ci, syncDeviceRuntimeStateProjection as cn, resolveOpenMeldEnvironmentTarget as co, createInflightTaskControlRegistry as cr, buildAgentAuthenticationGuide as cs, classifyGatewayChainFailure as ct, isCliUpdateCheckApplicable as d, isOpenMeldManagedBinaryPath as da, GrokBuildAcpTransportError as di, emitReconcileStartedEvidence as dn, requestLocalAgentActivitySync as do, MIN_HEARTBEAT_INTERVAL_MS as dr, buildHumanAuthenticationCard as ds, resolveGatewayChainRetryGuidance as dt, parseCliViewMode as ea, resolveAgentExecutionStatus as ei, runIfAgentActivityBindingGenerationIsCurrent as en, isSelectedOpenMeldProfileRequiredError as eo, createSerialAgentInteractionCallback as er, deleteOpenMeldProfile as es, formatHumanReplyReadinessReason as et, readLastOpenMeldToolsUpdateAttempt as f, buildDaemonServiceTargetSpec as fa, probeGrokBuildAcpInterface as fi, createPrimaryBindingReadSession as fn, requestLocalDaemonShutdown as fo, applyAcceptedLeases as fr, createAuthenticationError as fs, resolveOpenClawLocalDiagnosticsValue as ft, scheduleDaemonServiceUpdate as g, DAEMON_SERVICE_AUTO_HEAL_ANOMALIES as ga, resolveInstalledCodexLaunchCandidates as gi, listAgentCustomTargets as gn, readManagedCliInstallation as go, resolveCatalogSyncIntervalMs as gr, resolveAuthenticationGuidanceFromMessage as gs, slugifyOpenClawNamePart as gt, runPendingDaemonServiceUpdate as h, resolveVersionChangeDirection as ha, resolveCodexTimeoutMs as hi, createRegistrationFromCatalogTarget as hn, performManagedInstall as ho, resolveAdaptiveHeartbeatIntervalMs as hr, resolveAuthenticationGuidanceFromError as hs, normalizeOpenClawSpaceIdPrefix as ht, writeOpenMeldToolsMaintenancePolicy as i, setProfileDefaultView as ia, resolveSelectableCandidates as ii, resolveLocalProjectConnectionForPath as in, clearAllSelectedOpenMeldProfileIds as io, mergeOpenClawGatewayVisibility as ir, resolveOpenMeldProfile as is, formatSpaceMemberCommandRecoveryCopy as it, resolveDaemonStatusAttention as j, normalizeOptionalText$52 as ja, resolveDaemonStopStrategy as ji, listBuiltinAgentsRegistryEntries as jn, resolveRecentDaemonSignalStopCause as jo, settleInflightTask as jr, resolveCurrentEffectiveProfileWorkingFolderRuntime as jt, formatDaemonFailureContextText as k, normalizeHeartbeatIntervalMs as ka, hasActiveDaemonOwners as ki, detectInstalledSkillsAgents as kn, readLatestDaemonLifecycleOriginEvent as ko, resolveConversationExecutionStateByLookupKey as kr, syncProfileWorkspaceState as kt, readCurrentLocalDeviceId as l, extractDaemonCommandEntryPath as la, forkOpenCodeServerSession as li, emitDriftDetectedEvidence as ln, resolveAuthBaseUrl as lo, ADAPTIVE_HEARTBEAT_JITTER_RATIO as lr, buildAuthenticationStatusLabel as ls, resolveGatewayChainReadiness as lt, readOpenMeldToolsUpdateContextFromEnv as m, isVersionDowngrade as ma, projectCodexUsageLimits as mi, addAgentCustomTarget as mn, buildInstallSelfJsonPayload as mo, pruneStaleLeases as mr, resolveAuthenticationGuidance as ms, buildOpenClawSpaceSessionKey as mt, readOpenMeldToolsMaintenancePolicy as n, resolveViewProfileKey as na, resolveEvidenceSyncHealth as ni, unbindProject as nn, resolveOpenMeldProfileOrNull as no, normalizeDispatchPostMessageAction as nr, listOpenMeldProfiles as ns, mapAgentReplyReadinessToLegacyAutoReply as nt, assessServerRequiredVersion as o, writeDaemonServiceContract as oa, createLocalAdapterContainer as oi, withAgentActivityLocalStateLock as on, getSelectedOpenMeldProfileId as oo, buildLocalServiceDiagnosticsPayload as or, assertAdditionalHumanProfileCreationEnabled as os, resolveReplyReadinessGuidanceSummaryCopy as ot, readPendingOpenMeldToolsUpdateAttempt as p, resolveDaemonServiceAlignmentDecision as pa, resolveInstalledGrokBuildLaunchCandidates as pi, resolveAgentProfilePrimaryAgentControllerReport as pn, sendLocalDaemonControlPlaneRequest as po, applyIntervalJitterMs as pr, extractAuthenticationPromptAction as ps, prepareProviderRuntime as pt, buildDaemonServiceDependencyNextStep as q, MAX_RECONNECT_DELAY_MS as qa, readDaemonRuntimeContractRepairReport as qi, resolveLocalRegistryAgentIdFromAgentControllerRef as qn, ensureVersionStateReady as qo, listAgentControllerPermissionModeOptions as qr, listProjectBindings as qt, resolveOpenMeldToolsMaintenanceProjection as r, getProfileDefaultView as ra, resolveNativeAgentControllerPermissionModeForController as ri, canonicalizeLocalProjectPath as rn, alignSelectedOpenMeldProfileStorage as ro, createPendingAgentInteractionRegistry as rr, primeOpenMeldProfilesSessionCache as rs, REPLY_READINESS_COPY as rt, describeServerRequiredVersionUnavailableReason as s, buildDaemonSystemServiceCommandSpec as sa, createLocalAdapterEntries as si, NO_LOCAL_AGENTS_NEED_OPENMELD_SERVICE_REASON as sn, setSelectedOpenMeldProfileId as so, createLocalExecutionSlots as sr, readDaemonCatalogSyncSignal as ss, resolveOpenClawDiagnosticsGuidance as st, createOpenMeldToolsUpdateCoordinator as t, resolveRuntimeContext as ta, resolveAgentProfileEditCapabilities as ti, setDefaultProjectConnection as tn, requireOpenMeldProfile as to, buildDispatchReplyContextSummary as tr, getOpenMeldProfileCapabilities as ts, formatReplyReadinessSummary as tt, assessCliUpdate as u, resolveDaemonBundleIdFromEntryPath as ua, resolveInstalledOpenCodeLaunchCandidates as ui, emitReconcileCompletedEvidence as un, LocalDaemonControlPlaneClientError as uo, MAX_HEARTBEAT_INTERVAL_MS as ur, buildCommandAuthenticationPromptMessage as us, resolveGatewayChainRepairGuidance as ut, runDaemonServiceLifecycle as v, DAEMON_SERVICE_REPAIR_ANOMALIES as va, verifyCodexAppServerThread as vi, listAgentTargetStates as vn, cleanupInactiveDaemonServiceBundles as vo, resolveDispatchContinuityObservation as vr, formatInlineOpenMeldCliCommands as vs, writeDaemonRouteCatalogCache as vt, resolveSystemServiceStartupWaitMs as w, resolveDaemonDeviceId as wa, materializeCliLaunchCommand as wi, resolveAgentTargetState as wn, readLastDaemonServiceUpdate as wo, buildTaskResultEnvelope as wr, formatProfileAwareOpenMeldCliCommands as ws, syncDaemonRouteCatalogState as wt, uninstallDaemonServiceUpdateWorker as x, classifyDaemonServiceWakeability as xa, createUnsupportedProviderUsageLimits as xi, reconcileNewRunnableBuiltinAgentRegistrations as xn, resolveAlignedDaemonActiveBundleEntryPath as xo, resolveLatestScopedConversationExecutionState as xr, formatOpenMeldCliLine as xs, createRouteCatalogFromMutableState as xt, ensureDaemonServiceMaintenanceInstalled as y, DAEMON_SERVICE_WAKEABILITY_ADVISORY_ANOMALIES as ya, resolveInstalledClaudeCodeLaunchCandidates as yi, manageAgentRegistrationInstallation as yn, prepareDaemonServiceBundle as yo, resolveCompatibleAgentContextMatch as yr, formatOpenMeldCliCommand as ys, resolveLocalServiceDemand as yt, buildDaemonServiceUpdateRequiredNextStep as z, CONTROLLED_SHUTDOWN_RESULT_ACK_TIMEOUT_MS as za, resolveDaemonServiceManagerForRuntimeState as zi, sortAgentRegistrations as zn, configureDaemonMaintenanceEnvironment as zo, buildInformationProtectionPromptPlan as zr, setCustomProfileWorkspace as zt };
|
|
37363
|
+
export { formatDeviceReplyReadinessLabel as $, listOpenMeldProfiles as $a, buildDaemonServiceTargetSpec as $i, resolveRouteRegistrationReconcileDecision as $n, resolveAgentControllerPermissionModeForController as $r, resolveProjectBindingForPath as $t, resolveDaemonStatusSnapshot as A, DAEMON_STREAM_KEEPALIVE_INTERVAL_MS as Aa, readCurrentDaemonOwnerSnapshot as Ai, resolveSkillsAgentRegistry as An, seedLegacyAgentContext as Ar, createModelCatalogReadSession as At, formatDaemonServiceRefreshReliabilityMessage as B, RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS as Ba, PREPARE_SESSION_RECONNECT_GRACE_MS as Bi, repairBuiltinControllerInstall as Bn, buildWorkingLanguagePromptPlan as Br, setOpenMeldManagedProfileWorkspace as Bt, isSystemServiceStartupTimeoutError as C, CATALOG_SYNC_RETRY_INTERVAL_MS as Ca, buildCliLaunchInvocation as Ci, removeAgentCustomTarget as Cn, buildRuntimeWorkspaceFingerprint as Cr, summarizeSkippedDaemonProfiles as Ct, captureDaemonServiceEvidence as D, CONTROLLED_SHUTDOWN_SOCKET_CLOSE_TIMEOUT_MS as Da, buildDaemonOwnerSnapshotFromObservedState as Di, updateAgentRegistrations as Dn, loadLedgerState as Dr, resolveLocalController as Dt, startDaemonSystemServiceWithAutoRepair as E, CONTROLLED_SHUTDOWN_RESULT_ACK_TIMEOUT_MS as Ea, inspectDaemonServiceInventory as Ei, updateAgentCustomTarget as En, commitResolvedAgentContext as Er, readLocalEnabledControllers as Et, buildDaemonServiceRefreshNextStep as F, PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS as Fa, toStartBackgroundHelperExecutionCompatibility as Fi, notifyDaemonRouteCatalogChanged as Fn, buildAgentContextLookupKey as Fr, readProfileWorkspaceConfig as Ft, buildDaemonServiceDependencyDetails as G, clearAllSelectedOpenMeldProfileIds as Ga, resolveRuntimeContext as Gi, isNpmGlobalCommandPath as Gn, getAgentControllerPermissionModeFieldLabel as Gr, bindProject as Gt, resolveDaemonServiceFreshnessWarning as H, requireOpenMeldProfile as Ha, buildOnboardingPlan as Hi, resolveBuiltinAgentControllerDefinition as Hn, createAgentExecutionStatusDisplayRows as Hr, describeProfileWorkspacePathValidationFailure as Ht, buildDaemonServiceRefreshPromptMessage as I, PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS as Ia, ensureDaemonRuntimeContractState as Ii, normalizeAgentId as In, DEFAULT_TASK_LIFECYCLE_HEARTBEAT_INTERVAL_MS as Ir, readProfileWorkspaceConfigForAccount as It, buildDaemonServiceDependencySummary as J, setSelectedOpenMeldProfileId as Ja, setProfileDefaultView as Ji, normalizeDispatchThreadAction as Jn, parseAgentControllerRef as Jr, listProjectConnectionsWithStatus as Jt, buildDaemonServiceDependencyMeaning as K, clearSelectedOpenMeldProfileId as Ka, resolveViewProfileKey as Ki, isPnpmGlobalCommandPath as Kn, isAgentExecutionReadyOrConnecting as Kr, isProjectBound as Kt, buildDaemonServiceRepairGuidance as L, REGISTER_RESPONSE_TIMEOUT_MS as La, readDaemonRuntimeContractRepairReport as Li, normalizeAgentIds as Ln, areAgentControllerInterfaceAccountsSame as Lr, resolveConfiguredProfileWorkspacePath as Lt, resolveDaemonStatusAuthenticationAttention as M, DEFAULT_RECONNECT_DELAY_MS as Ma, resolveStoppedContractWriteBlockedReason as Mi, resolveRegistryOriginLaunchCommand as Mn, upsertConversationExecutionState as Mr, resolveProfileWorkspaceRuntime as Mt, resolveServiceReadiness as N, HEARTBEAT_RESPONSE_TIMEOUT_MS as Na, summarizeDaemonOwnerSnapshot as Ni, resolveRegistryRuntimeAdapterCapabilitySnapshot as Nn, withLedgerStateTransaction as Nr, ensureOpenMeldManagedProfileWorkspace as Nt, captureDaemonServiceEvidenceBestEffort as O, DAEMON_RUNTIME_CONTRACT_EPOCH as Oa, formatDaemonOwnerSummaryLabel as Oi, canManageRegistryAgentSkillTargets as On, removeConversationExecutionState as Or, resolveLocalRuntimeControllerSupport as Ot, resolveServiceReadinessFromServiceStatus as P, MAX_RECONNECT_DELAY_MS as Pa, resolveDaemonRuntimeContractCompatibility as Pi, resolveRegistryRuntimeAdapterContractByAgentControllerRef as Pn, buildAuthenticatedControlPlaneResponse as Pr, normalizeCustomProfileWorkspacePath as Pt, formatAgentReplyReadinessLabel as Q, getOpenMeldProfileCapabilities as Qa, ensureDaemonSystemServiceCommandFiles as Qi, isDaemonReconcileInProgressError as Qn, renderWorkingLanguagePrompt as Qr, removeProjectConnection as Qt, buildDaemonServiceStatusReadOnlyDetail as R, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS as Ra, DaemonServiceRunError as Ri, parseAgentEnabledOption as Rn, buildAgentControllerRef as Rr, resolveConfiguredProfileWorkspacePathForAccount as Rt, isDaemonInventoryRunningAndStartReady as S, warnDaemonEvent as Sa, resolveDispatchSpaceActionMcpServer as Si, reconcileNewRunnableBuiltinAgentsForSetup as Sn, runRuntimeTask as Sr, loadDaemonRouteCatalog as St, waitForSystemServiceStartup as T, CONTROLLED_SHUTDOWN_REQUEST_TIMEOUT_MS as Ta, createProviderOriginalError as Ti, setAgentRegistrationEnabled as Tn, appendLedgerHistoryEntry as Tr, buildRuntimeRouteTargets as Tt, clearDaemonStartFailureState as U, resolveOpenMeldProfileOrNull as Ua, getSetupFlowCopy as Ui, isBunGlobalCommandPath as Un, createAuthorityOpenMeldServiceRuntimeId as Ur, ProjectBindingOperationError as Ut, formatDaemonServiceUpdateRequiredMessage as V, isSelectedOpenMeldProfileRequiredError as Va, buildDaemonRouteObservationPresentation as Vi, EMPTY_AGENT_CONTROLLER_INTERFACE_CAPABILITIES as Vn, createAgentControllerInterfaceDisplayRows as Vr, validateCustomProfileWorkspacePath as Vt, writeDaemonStartFailureState as W, alignSelectedOpenMeldProfileStorage as Wa, parseCliViewMode as Wi, isHomebrewCommandPath as Wn, getAgentControllerPermissionModeDisplayMetadata as Wr, ProjectBindingStoreUpdateRequiredError as Wt, resolveDaemonServiceDependencyDiagnostics as X, createOpenMeldHumanProfile as Xa, writeDaemonServiceContract as Xi, SPACE_ACTION_CONTEXT_GUIDANCE_LINES as Xn, projectPeopleComputersToLegacyLocalRuntimes as Xr, removeAgentActivityBindingsWhileDeliveryLocked as Xt, buildDaemonServiceDependencyTitle as Y, createOpenMeldAgentProfile as Ya, resolveCurrentOpenMeldAccountContext as Yi, syncRuntimeEventToInflightTaskControlRegistry as Yn, peopleComputerContainsDevice as Yr, migrateProjectBindingStore as Yt, resolveCurrentReplyReadinessSnapshot as Z, deleteOpenMeldProfile as Za, buildDaemonSystemServiceCommandSpec as Zi, SPACE_ACTION_TARGET_GUIDANCE_LINES as Zn, renderInformationProtectionPrompt as Zr, removeMissingProjectConnections as Zt, DaemonServiceLifecycleDrainTimeoutError as _, normalizeNonNegativeInteger as _a, forkCodexAppServerThread as _i, listAgentRegistrations as _n, resolveDispatchQueueLogMeta as _r, readDaemonRouteCatalogCache as _t, resolveServiceUpdateUrgency as a, DAEMON_SERVICE_REPAIR_ANOMALIES as aa, resolveCatalogSyncSkippedProfilesLogState as ai, withAgentActivityDeliveryLock as an, buildAgentAuthenticationGuide as ao, createLocalTaskInterruptSender as ar, resolveReplyReadinessAvailabilityReasonCopy as at, prepareDaemonServiceUpdateWorkerCarrier as b, nowIsoString as ba, createUnavailableProviderUsageLimits as bi, readAgentRuntimeConfigHealth as bn, resolveCompatibleConversationExecutionState as br, createMutableRouteCatalogState as bt, buildLocalAgentCatalogFromReadiness as c, classifyDaemonServiceWakeability as ca, parseOpenCodeGoUsageResponse as ci, syncDeviceRuntimeStateProjection as cn, buildHumanAuthenticationCard as co, createInflightTaskControlRegistry as cr, classifyGatewayChainFailure as ct, isCliUpdateCheckApplicable as d, resolveDaemonDeviceId as da, GrokBuildAcpTransportError as di, emitReconcileStartedEvidence as dn, resolveAuthenticationGuidance as do, MIN_HEARTBEAT_INTERVAL_MS as dr, resolveGatewayChainRetryGuidance as dt, resolveDaemonServiceAlignmentDecision as ea, resolveAgentExecutionStatus as ei, runIfAgentActivityBindingGenerationIsCurrent as en, primeOpenMeldProfilesSessionCache as eo, createSerialAgentInteractionCallback as er, formatHumanReplyReadinessReason as et, readLastOpenMeldToolsUpdateAttempt as f, resolvePreferredDaemonDeviceId as fa, probeGrokBuildAcpInterface as fi, createPrimaryBindingReadSession as fn, resolveAuthenticationGuidanceFromError as fo, applyAcceptedLeases as fr, resolveOpenClawLocalDiagnosticsValue as ft, scheduleDaemonServiceUpdate as g, normalizeHeartbeatIntervalMs as ga, resolveInstalledCodexLaunchCandidates as gi, listAgentCustomTargets as gn, resolveBuiltinAgentControllerBrand as go, resolveCatalogSyncIntervalMs as gr, slugifyOpenClawNamePart as gt, runPendingDaemonServiceUpdate as h, emitRunLine as ha, resolveCodexTimeoutMs as hi, createRegistrationFromCatalogTarget as hn, compareAgentControllerRefsForDisplay as ho, resolveAdaptiveHeartbeatIntervalMs as hr, normalizeOpenClawSpaceIdPrefix as ht, writeOpenMeldToolsMaintenancePolicy as i, DAEMON_SERVICE_FULL_ALIGNMENT_ANOMALIES as ia, resolveSelectableCandidates as ii, resolveLocalProjectConnectionForPath as in, readDaemonCatalogSyncSignal as io, mergeOpenClawGatewayVisibility as ir, formatSpaceMemberCommandRecoveryCopy as it, resolveDaemonStatusAttention as j, DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS as ja, resolveDaemonStopStrategy as ji, listBuiltinAgentsRegistryEntries as jn, settleInflightTask as jr, resolveCurrentEffectiveProfileWorkingFolderRuntime as jt, formatDaemonFailureContextText as k, DAEMON_STREAM_CONNECT_TIMEOUT_MS as ka, hasActiveDaemonOwners as ki, detectInstalledSkillsAgents as kn, resolveConversationExecutionStateByLookupKey as kr, syncProfileWorkspaceState as kt, readCurrentLocalDeviceId as l, buildLedgerPaths as la, forkOpenCodeServerSession as li, emitDriftDetectedEvidence as ln, createAuthenticationError as lo, ADAPTIVE_HEARTBEAT_JITTER_RATIO as lr, resolveGatewayChainReadiness as lt, readOpenMeldToolsUpdateContextFromEnv as m, dirnamePath as ma, projectCodexUsageLimits as mi, addAgentCustomTarget as mn, resolveAuthenticationReasonFromState as mo, pruneStaleLeases as mr, buildOpenClawSpaceSessionKey as mt, readOpenMeldToolsMaintenancePolicy as n, resolveVersionChangeDirection as na, resolveEvidenceSyncHealth as ni, unbindProject as nn, updateOpenMeldProfile as no, normalizeDispatchPostMessageAction as nr, mapAgentReplyReadinessToLegacyAutoReply as nt, assessServerRequiredVersion as o, DAEMON_SERVICE_WAKEABILITY_ADVISORY_ANOMALIES as oa, createLocalAdapterContainer as oi, withAgentActivityLocalStateLock as on, buildAuthenticationStatusLabel as oo, buildLocalServiceDiagnosticsPayload as or, resolveReplyReadinessGuidanceSummaryCopy as ot, readPendingOpenMeldToolsUpdateAttempt as p, asRecord as pa, resolveInstalledGrokBuildLaunchCandidates as pi, resolveAgentProfilePrimaryAgentControllerReport as pn, resolveAuthenticationGuidanceFromMessage as po, applyIntervalJitterMs as pr, prepareProviderRuntime as pt, buildDaemonServiceDependencyNextStep as q, getSelectedOpenMeldProfileId as qa, getProfileDefaultView as qi, resolveLocalRegistryAgentIdFromAgentControllerRef as qn, listAgentControllerPermissionModeOptions as qr, listProjectBindings as qt, resolveOpenMeldToolsMaintenanceProjection as r, DAEMON_SERVICE_AUTO_HEAL_ANOMALIES as ra, resolveNativeAgentControllerPermissionModeForController as ri, canonicalizeLocalProjectPath as rn, assertAdditionalHumanProfileCreationEnabled as ro, createPendingAgentInteractionRegistry as rr, REPLY_READINESS_COPY as rt, describeServerRequiredVersionUnavailableReason as s, classifyDaemonServiceRunStartability as sa, createLocalAdapterEntries as si, NO_LOCAL_AGENTS_NEED_OPENMELD_SERVICE_REASON as sn, buildCommandAuthenticationPromptMessage as so, createLocalExecutionSlots as sr, resolveOpenClawDiagnosticsGuidance as st, createOpenMeldToolsUpdateCoordinator as t, isVersionDowngrade as ta, resolveAgentProfileEditCapabilities as ti, setDefaultProjectConnection as tn, resolveOpenMeldProfile as to, buildDispatchReplyContextSummary as tr, formatReplyReadinessSummary as tt, assessCliUpdate as u, ensureDaemonRuntimePaths as ua, resolveInstalledOpenCodeLaunchCandidates as ui, emitReconcileCompletedEvidence as un, extractAuthenticationPromptAction as uo, MAX_HEARTBEAT_INTERVAL_MS as ur, resolveGatewayChainRepairGuidance as ut, runDaemonServiceLifecycle as v, normalizeOptionalText$52 as va, verifyCodexAppServerThread as vi, listAgentTargetStates as vn, resolveDispatchContinuityObservation as vr, writeDaemonRouteCatalogCache as vt, resolveSystemServiceStartupWaitMs as w, CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS as wa, materializeCliLaunchCommand as wi, resolveAgentTargetState as wn, buildTaskResultEnvelope as wr, syncDaemonRouteCatalogState as wt, uninstallDaemonServiceUpdateWorker as x, toErrorMessage$23 as xa, createUnsupportedProviderUsageLimits as xi, reconcileNewRunnableBuiltinAgentRegistrations as xn, resolveLatestScopedConversationExecutionState as xr, createRouteCatalogFromMutableState as xt, ensureDaemonServiceMaintenanceInstalled as y, normalizeText$11 as ya, resolveInstalledClaudeCodeLaunchCandidates as yi, manageAgentRegistrationInstallation as yn, resolveCompatibleAgentContextMatch as yr, resolveLocalServiceDemand as yt, buildDaemonServiceUpdateRequiredNextStep as z, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS as za, resolveCurrentDaemonExpectedVersion as zi, sortAgentRegistrations as zn, buildInformationProtectionPromptPlan as zr, setCustomProfileWorkspace as zt };
|
|
41325
37364
|
|
|
41326
|
-
//# sourceMappingURL=openmeld-tools-update-coordinator-
|
|
37365
|
+
//# sourceMappingURL=openmeld-tools-update-coordinator-D9Skj8IE.js.map
|