@nowcrew/daemon 0.6.89 → 0.6.91-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +64 -3
  2. package/dist/agent-ability/materializer.js +21 -10
  3. package/dist/agent-environment-contract.js +55 -0
  4. package/dist/agent-environment-control.js +24 -0
  5. package/dist/agent-environment-execution.js +98 -0
  6. package/dist/agent-environments.js +275 -0
  7. package/dist/automatic-daemon-installer.js +49 -1
  8. package/dist/computer-main.js +18 -0
  9. package/dist/computer-profile.js +17 -4
  10. package/dist/computer-setup-client.js +318 -0
  11. package/dist/computer-setup-orchestration.js +203 -0
  12. package/dist/computer-setup.js +244 -0
  13. package/dist/config.js +30 -12
  14. package/dist/console-formatter.js +3 -3
  15. package/dist/console.js +15 -2
  16. package/dist/daemon-update-eligibility.js +1 -1
  17. package/dist/daemon-updater.js +2 -12
  18. package/dist/execution-journal.js +9 -6
  19. package/dist/execution-protocol.js +1 -0
  20. package/dist/execution-runner.js +13 -8
  21. package/dist/i18n.js +19 -0
  22. package/dist/list-models.js +12 -12
  23. package/dist/local-execution-lease.js +22 -0
  24. package/dist/local-executor.js +57 -84
  25. package/dist/local-memory/candidate.js +43 -0
  26. package/dist/local-memory/index-budget.js +8 -0
  27. package/dist/local-memory/inventory-cli.js +61 -0
  28. package/dist/local-memory/inventory-preview.js +159 -0
  29. package/dist/local-memory/inventory-source.js +159 -0
  30. package/dist/local-memory/pending-match.js +29 -0
  31. package/dist/local-memory/pending-query.js +100 -0
  32. package/dist/local-memory/pending-schema.js +29 -0
  33. package/dist/local-memory/pending-source.js +126 -0
  34. package/dist/local-memory/pending.js +34 -84
  35. package/dist/local-memory/prompt.js +19 -12
  36. package/dist/local-memory/read-cli.js +97 -12
  37. package/dist/local-memory/rollout.js +82 -0
  38. package/dist/local-memory/runtime.js +23 -17
  39. package/dist/local-memory/work-log-execution.js +31 -0
  40. package/dist/local-memory/work-log.js +58 -0
  41. package/dist/local-memory/write.js +27 -58
  42. package/dist/local-runtime-environment.js +50 -0
  43. package/dist/machine-environment-cache.js +147 -0
  44. package/dist/machine-environment-contract.js +10 -0
  45. package/dist/machine-environment-control.js +27 -0
  46. package/dist/machine-environment-policy.js +75 -0
  47. package/dist/machine-environment-process.js +110 -0
  48. package/dist/machine-info.js +70 -25
  49. package/dist/machine-runtime-environment.js +189 -0
  50. package/dist/machine-shell-environment-capture.js +135 -0
  51. package/dist/machine-windows-environment-capture.js +215 -0
  52. package/dist/machine-windows-environment-script.js +158 -0
  53. package/dist/main.js +4 -69
  54. package/dist/marketplace-command.js +21 -0
  55. package/dist/marketplace-controller.js +80 -0
  56. package/dist/marketplace-protocol.js +38 -0
  57. package/dist/marketplace-remote.js +48 -0
  58. package/dist/marketplace-runner.js +235 -0
  59. package/dist/marketplace-serve.js +41 -0
  60. package/dist/marketplace-source.js +103 -0
  61. package/dist/message-file-preview.js +246 -0
  62. package/dist/pre-admission-rejection.js +64 -0
  63. package/dist/project-skills/execution-adapter.js +3 -2
  64. package/dist/project-skills/runtime-launch.js +14 -0
  65. package/dist/provider-env.js +26 -15
  66. package/dist/runner.js +17 -4
  67. package/dist/runtime-environment-merge.js +16 -0
  68. package/dist/runtime-health-handler.js +10 -0
  69. package/dist/runtime-health.js +3 -1
  70. package/dist/runtime-path.js +22 -12
  71. package/dist/runtime-probe.js +35 -6
  72. package/dist/runtimes/acp-probe-transport.js +69 -0
  73. package/dist/runtimes/claude-models.js +20 -9
  74. package/dist/runtimes/deepseek-harness-launch.js +10 -0
  75. package/dist/runtimes/deepseek-harness-profile.js +92 -0
  76. package/dist/runtimes/deepseek-harness-runner.js +226 -0
  77. package/dist/runtimes/deepseek-harness.js +76 -15
  78. package/dist/runtimes/harness-probe-retry.js +42 -0
  79. package/dist/runtimes/hermes-models.js +2 -1
  80. package/dist/runtimes/kimi-acp-runner.js +78 -13
  81. package/dist/runtimes/opencode.js +2 -2
  82. package/dist/serve.js +88 -178
  83. package/dist/storage-identity.js +0 -3
  84. package/dist/storage-serve-adapter.js +6 -72
  85. package/dist/supervised-runtime.js +17 -2
  86. package/dist/token.js +0 -1
  87. package/dist/workspace-control-handler.js +27 -0
  88. package/dist/workspace-fs.js +66 -15
  89. package/dist/workspace.js +1 -1
  90. package/package.json +13 -12
  91. package/dist/codex-home-launch.js +0 -7
  92. package/dist/codex-home-mode-controller.js +0 -68
  93. package/dist/daemon-migration-controller.js +0 -211
  94. package/dist/daemon-migration-wiring.js +0 -22
  95. package/dist/runtimes/codex-home-migration-cli.js +0 -26
  96. package/dist/runtimes/codex-home-migration.js +0 -112
  97. package/dist/runtimes/codex-home.js +0 -236
  98. package/dist/storage-control.js +0 -212
  99. package/dist/storage-copy.js +0 -628
  100. package/dist/storage-credential-guard.js +0 -21
  101. package/dist/storage-doctor.js +0 -228
  102. package/dist/storage-manifest.js +0 -1027
  103. package/dist/storage-migration-controller.js +0 -440
  104. package/dist/storage-migration-manifest.js +0 -105
  105. package/dist/storage-migration-policy.js +0 -100
  106. package/dist/storage-runtime-controller.js +0 -381
  107. package/dist/storage-runtime-readiness.js +0 -241
  108. package/dist/storage-safe-fs.js +0 -302
  109. package/dist/storage-status-delivery.js +0 -224
  110. package/dist/storage-status-replay.js +0 -140
  111. package/dist/storage-target-confirmation.js +0 -129
  112. package/dist/storage-worker-command.js +0 -37
  113. package/dist/storage-worker-executor.js +0 -447
  114. package/dist/storage-worker-handoff.js +0 -151
  115. package/dist/storage-worker-operation.js +0 -294
  116. package/dist/storage-worker-status.js +0 -259
@@ -1,236 +0,0 @@
1
- import { chmod, copyFile, lstat, mkdir, open, readdir, readlink, rename, rm, symlink, unlink, link, writeFile, } from "node:fs/promises";
2
- import { constants } from "node:fs";
3
- import { dirname, join, relative, resolve, sep } from "node:path";
4
- const PRIVATE_CODEX_HOME = ".codex";
5
- export function defaultCodexHome(homeDir) {
6
- return resolve(homeDir, PRIVATE_CODEX_HOME);
7
- }
8
- async function linkIfMissing(source, target) {
9
- try {
10
- await lstat(target);
11
- return;
12
- }
13
- catch (error) {
14
- if (error.code !== "ENOENT")
15
- throw error;
16
- }
17
- try {
18
- await lstat(source);
19
- }
20
- catch (error) {
21
- if (error.code === "ENOENT")
22
- return;
23
- throw error;
24
- }
25
- try {
26
- await symlink(source, target, "file");
27
- }
28
- catch (error) {
29
- if (error.code !== "EEXIST")
30
- throw error;
31
- }
32
- }
33
- function isBelow(root, candidate) {
34
- const child = relative(root, candidate);
35
- return child !== "" && child !== ".." && !child.startsWith(`..${sep}`) && !child.startsWith(sep);
36
- }
37
- async function isExactSymlink(target, expectedSource) {
38
- const linkTarget = await readlink(target);
39
- return resolve(dirname(target), linkTarget) === resolve(expectedSource);
40
- }
41
- async function ensurePrivateSessions(target, legacySource) {
42
- try {
43
- const current = await lstat(target);
44
- if (current.isSymbolicLink()) {
45
- if (legacySource === undefined || !(await isExactSymlink(target, legacySource))) {
46
- throw new Error(`Refusing to replace unexpected Codex sessions symlink: ${target}`);
47
- }
48
- const replacement = `${target}.private-${process.pid}-${Math.random().toString(36).slice(2)}`;
49
- const legacyBackup = `${target}.legacy-${process.pid}-${Math.random().toString(36).slice(2)}`;
50
- try {
51
- await mkdir(replacement, { mode: 0o700 });
52
- await rename(target, legacyBackup);
53
- try {
54
- await rename(replacement, target);
55
- }
56
- catch (error) {
57
- await rename(legacyBackup, target).catch(() => undefined);
58
- throw error;
59
- }
60
- }
61
- finally {
62
- await rm(replacement, { recursive: true, force: true }).catch(() => undefined);
63
- await rm(legacyBackup, { recursive: true, force: true }).catch(() => undefined);
64
- }
65
- }
66
- else if (!current.isDirectory()) {
67
- throw new Error(`Codex sessions target is not a directory: ${target}`);
68
- }
69
- }
70
- catch (error) {
71
- if (error.code !== "ENOENT")
72
- throw error;
73
- await mkdir(target, { mode: 0o700 });
74
- }
75
- await chmod(target, 0o700);
76
- }
77
- async function atomicCopyFile(source, target, mode) {
78
- const parent = dirname(target);
79
- await mkdir(parent, { recursive: true, mode: 0o700 });
80
- const temporary = `${target}.tmp-${process.pid}-${Math.random().toString(36).slice(2)}`;
81
- try {
82
- await copyFile(source, temporary, constants.COPYFILE_EXCL);
83
- await chmod(temporary, mode);
84
- try {
85
- await link(temporary, target);
86
- return true;
87
- }
88
- catch (error) {
89
- if (error.code !== "EEXIST")
90
- throw error;
91
- return false;
92
- }
93
- }
94
- finally {
95
- await unlink(temporary).catch(() => undefined);
96
- }
97
- }
98
- async function ensurePrivateIndex(target, source) {
99
- let current;
100
- try {
101
- current = await lstat(target);
102
- }
103
- catch (error) {
104
- if (error.code !== "ENOENT")
105
- throw error;
106
- }
107
- if (current?.isSymbolicLink()) {
108
- if (source === undefined || !(await isExactSymlink(target, source))) {
109
- throw new Error(`Refusing to replace unexpected Codex session index symlink: ${target}`);
110
- }
111
- const replacement = `${target}.private-${process.pid}-${Math.random().toString(36).slice(2)}`;
112
- const legacyBackup = `${target}.legacy-${process.pid}-${Math.random().toString(36).slice(2)}`;
113
- try {
114
- try {
115
- await lstat(source);
116
- await copyFile(source, replacement, constants.COPYFILE_EXCL);
117
- }
118
- catch (error) {
119
- if (error.code !== "ENOENT")
120
- throw error;
121
- await writeFile(replacement, "", { encoding: "utf8", flag: "wx" });
122
- }
123
- await chmod(replacement, 0o600);
124
- await rename(target, legacyBackup);
125
- try {
126
- await rename(replacement, target);
127
- }
128
- catch (error) {
129
- await rename(legacyBackup, target).catch(() => undefined);
130
- throw error;
131
- }
132
- }
133
- finally {
134
- await rm(replacement, { force: true }).catch(() => undefined);
135
- await rm(legacyBackup, { force: true }).catch(() => undefined);
136
- }
137
- current = undefined;
138
- }
139
- if (current !== undefined && !current.isFile()) {
140
- throw new Error(`Codex session index target is not a regular file: ${target}`);
141
- }
142
- if (current !== undefined) {
143
- await chmod(target, 0o600);
144
- return;
145
- }
146
- if (source !== undefined) {
147
- try {
148
- await lstat(source);
149
- if (await atomicCopyFile(source, target, 0o600))
150
- return;
151
- return;
152
- }
153
- catch (error) {
154
- if (error.code !== "ENOENT")
155
- throw error;
156
- }
157
- }
158
- const handle = await open(target, "wx", 0o600).catch((error) => {
159
- if (error.code === "EEXIST")
160
- return null;
161
- throw error;
162
- });
163
- await handle?.close();
164
- }
165
- async function findRollout(root, sessionId) {
166
- const entries = await readdir(root, { withFileTypes: true }).catch((error) => {
167
- if (error.code === "ENOENT")
168
- return [];
169
- throw error;
170
- });
171
- const matches = [];
172
- for (const entry of entries) {
173
- const path = join(root, entry.name);
174
- if (entry.isDirectory()) {
175
- const nested = await findRollout(path, sessionId);
176
- if (nested !== null)
177
- matches.push(nested);
178
- }
179
- else if (entry.isFile() && entry.name.includes(sessionId)) {
180
- matches.push(path);
181
- }
182
- }
183
- if (matches.length > 1)
184
- throw new Error(`Multiple Codex rollout files match session ${sessionId}`);
185
- return matches[0] ?? null;
186
- }
187
- async function hydrateResumeRollout(sourceSessions, privateSessions, sessionId) {
188
- if (sessionId.includes("/") || sessionId.includes("\\") || sessionId.includes("..")) {
189
- throw new Error("Invalid Codex resume session id");
190
- }
191
- const sourcePath = await findRollout(sourceSessions, sessionId);
192
- if (sourcePath === null)
193
- return;
194
- const relativePath = relative(sourceSessions, sourcePath);
195
- const destination = resolve(privateSessions, relativePath);
196
- if (!isBelow(resolve(privateSessions), destination)) {
197
- throw new Error("Codex resume rollout escaped the private sessions directory");
198
- }
199
- let existing;
200
- try {
201
- existing = await lstat(destination);
202
- }
203
- catch (error) {
204
- if (error.code !== "ENOENT")
205
- throw error;
206
- }
207
- if (existing !== undefined) {
208
- if (!existing.isFile() || existing.isSymbolicLink()) {
209
- throw new Error(`Refusing to replace existing Codex rollout: ${destination}`);
210
- }
211
- return;
212
- }
213
- const mode = (await lstat(sourcePath)).mode & 0o777;
214
- await atomicCopyFile(sourcePath, destination, mode);
215
- }
216
- /** Isolate Codex high-volume state per Agent while preserving auth and exact resume. */
217
- export async function materializeDefaultCodexHome(agentHome, sourceHome, resumeSessionId) {
218
- const codexHome = defaultCodexHome(agentHome);
219
- await mkdir(codexHome, { recursive: true, mode: 0o700 });
220
- await chmod(codexHome, 0o700);
221
- const source = sourceHome === undefined ? null : resolve(sourceHome);
222
- if (source !== null && source !== codexHome) {
223
- await Promise.all([
224
- linkIfMissing(join(source, "auth.json"), join(codexHome, "auth.json")),
225
- linkIfMissing(join(source, "config.toml"), join(codexHome, "config.toml")),
226
- ]);
227
- }
228
- const sourceSessions = source === null || source === codexHome ? undefined : join(source, "sessions");
229
- await ensurePrivateSessions(join(codexHome, "sessions"), sourceSessions);
230
- const sourceIndex = source === null || source === codexHome ? undefined : join(source, "session_index.jsonl");
231
- await ensurePrivateIndex(join(codexHome, "session_index.jsonl"), sourceIndex);
232
- if (sourceSessions !== undefined && resumeSessionId) {
233
- await hydrateResumeRollout(sourceSessions, join(codexHome, "sessions"), resumeSessionId);
234
- }
235
- return codexHome;
236
- }
@@ -1,212 +0,0 @@
1
- import { z } from "zod";
2
- export const STORAGE_MIGRATION_CAPABILITY = "storage_migration_v1";
3
- export const STORAGE_MIGRATION_STATUS_CAPABILITY = "storage_migration_status_v1";
4
- const IdentitySchema = z.object({
5
- migrationId: z.string().uuid(),
6
- environment: z.string().regex(/^[a-z0-9][a-z0-9_-]{0,31}$/u),
7
- workspaceId: z.string().uuid(),
8
- ownerEpoch: z.number().int().positive().safe().optional(),
9
- ownershipClaimFingerprint: z.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
10
- });
11
- const DoctorRequestSchema = IdentitySchema.extend({ type: z.literal("daemon:storage-doctor") }).strict();
12
- const MigrateRequestSchema = IdentitySchema.extend({
13
- type: z.literal("daemon:storage-migrate"),
14
- manifestDigest: z.string().regex(/^[0-9a-f]{64}$/u),
15
- }).strict();
16
- const StatusSchema = z.enum([
17
- "preflight_running", "preflight_passed", "backing_up", "initial_sync", "quiescing", "final_sync", "verified",
18
- "service_switched", "hello_confirmed", "completed", "failed", "rollback_pending", "rolled_back",
19
- "rollback_failed",
20
- ]);
21
- const TOKEN = /(?:\bsk_(?:machine|user|agent)_[A-Za-z0-9_-]{4,}\b|\bbearer\s+[^\s]+|(?:password|secret|token)\s*[:=]\s*[^\s]+)/giu;
22
- const safeError = (error) => (error instanceof Error ? error.message : String(error))
23
- .replaceAll(TOKEN, "<redacted>").slice(0, 500) || "storage migration failed";
24
- const stableErrorCode = (candidate, fallback) => typeof candidate === "string" && /^[a-z0-9._-]{1,128}$/u.test(candidate) ? candidate : fallback;
25
- export function createStorageControlController(input) {
26
- const environment = z.string().regex(/^[a-z0-9][a-z0-9_-]{0,31}$/u).parse(input.environment);
27
- const workspaceId = z.string().uuid().parse(input.workspaceId);
28
- const profile = z.string().regex(/^[a-z0-9][a-z0-9_-]{0,47}$/u).parse(input.profile);
29
- const sourceStorageFingerprint = z.string().regex(/^sha256:[0-9a-f]{64}$/u).parse(input.sourceStorageFingerprint);
30
- const targetStorageFingerprint = z.string().regex(/^sha256:[0-9a-f]{64}$/u).parse(input.targetStorageFingerprint);
31
- const ownership = input.ownership === undefined ? undefined : Object.freeze({
32
- ownerEpoch: z.number().int().positive().safe().parse(input.ownership.ownerEpoch),
33
- ownershipClaimFingerprint: z.string().regex(/^sha256:[0-9a-f]{64}$/u)
34
- .parse(input.ownership.ownershipClaimFingerprint),
35
- });
36
- const preflights = new Map();
37
- const preflightRuns = new Map();
38
- const appliedMigrationIds = new Set();
39
- let runningMigrationId = null;
40
- const preflightTimeoutMs = z.number().int().positive().max(24 * 60 * 60 * 1000)
41
- .parse(input.preflightTimeoutMs ?? 30 * 60 * 1000);
42
- const frame = (identity, status, extra = {}) => ({
43
- type: "daemon:storage-migration-status",
44
- migrationId: identity.migrationId,
45
- status,
46
- environment,
47
- workspaceId,
48
- profile,
49
- ...(ownership === undefined ? {} : ownership),
50
- ...extra,
51
- });
52
- const failure = (identity, errorCode, error, reopenAdmission = false, extra = {}) => {
53
- reportStatus(frame(identity, "failed", {
54
- errorCode,
55
- ...extra,
56
- ...(error === undefined ? {} : { errorMessage: safeError(error) }),
57
- ...(reopenAdmission || error?.reopenAdmission === true
58
- ? { reopenAdmission: true }
59
- : {}),
60
- }));
61
- };
62
- const reportStatus = (statusFrame) => {
63
- try {
64
- input.sendStatus(statusFrame);
65
- }
66
- catch (error) {
67
- input.onStatusError?.(error, statusFrame);
68
- }
69
- };
70
- const matchesIdentity = (identity) => identity.environment === environment && identity.workspaceId === workspaceId
71
- && (ownership === undefined
72
- || (identity.ownerEpoch === ownership.ownerEpoch
73
- && identity.ownershipClaimFingerprint === ownership.ownershipClaimFingerprint));
74
- const preflightKey = (identity) => `${identity.migrationId}\0${identity.environment}\0${identity.workspaceId}`;
75
- const runPreflight = (identity, failureFallback = "doctor_failed") => {
76
- const key = preflightKey(identity);
77
- const existing = preflightRuns.get(key);
78
- if (existing !== undefined)
79
- return existing;
80
- const controller = new AbortController();
81
- let scannedEntries = 0;
82
- let timedOut = false;
83
- reportStatus(frame(identity, "preflight_running", {
84
- progress: { state: "running", scannedEntries: 0 },
85
- }));
86
- const doctorPromise = Promise.resolve().then(() => input.runDoctor(identity.migrationId, {
87
- signal: controller.signal,
88
- onProgress: (progress) => {
89
- if (timedOut)
90
- return;
91
- scannedEntries = progress.scannedEntries;
92
- reportStatus(frame(identity, "preflight_running", {
93
- progress: { state: "running", scannedEntries },
94
- }));
95
- },
96
- }));
97
- let timeoutHandle;
98
- const timeout = new Promise((_, reject) => {
99
- timeoutHandle = setTimeout(() => {
100
- timedOut = true;
101
- controller.abort();
102
- reject(Object.assign(new Error("storage doctor preflight timed out"), {
103
- code: "preflight_stale",
104
- scannedEntries,
105
- }));
106
- }, preflightTimeoutMs);
107
- timeoutHandle.unref?.();
108
- });
109
- void doctorPromise.catch(() => undefined);
110
- let outcome;
111
- outcome = Promise.race([doctorPromise, timeout]).then((doctor) => {
112
- if (doctor.manifest.migrationId !== identity.migrationId
113
- || doctor.environment !== environment || doctor.workspaceId !== workspaceId
114
- || doctor.profile !== profile) {
115
- failure(identity, "storage_identity_mismatch", undefined, true);
116
- return null;
117
- }
118
- if (!doctor.applyAllowed) {
119
- failure(identity, doctor.blockers[0]?.code ?? "doctor_blocked", undefined, true);
120
- return null;
121
- }
122
- preflights.set(identity.migrationId, doctor);
123
- reportStatus(frame(identity, "preflight_passed", {
124
- sourceStorageFingerprint,
125
- targetStorageFingerprint,
126
- manifestDigest: doctor.manifestDigest,
127
- }));
128
- return doctor;
129
- }).catch((error) => {
130
- const code = error.code;
131
- if (code === "preflight_stale") {
132
- failure(identity, "preflight_stale", undefined, true, {
133
- retryable: true,
134
- progress: { state: "stale", scannedEntries: Number(error.scannedEntries) || scannedEntries },
135
- });
136
- }
137
- else if (code === "preflight_aborted") {
138
- failure(identity, "preflight_aborted", error, true, {
139
- retryable: true,
140
- progress: { state: "stale", scannedEntries },
141
- });
142
- }
143
- else {
144
- failure(identity, stableErrorCode(code, failureFallback), error, true);
145
- }
146
- return null;
147
- }).finally(() => {
148
- if (timeoutHandle !== undefined)
149
- clearTimeout(timeoutHandle);
150
- if (preflightRuns.get(key) === outcome)
151
- preflightRuns.delete(key);
152
- });
153
- preflightRuns.set(key, outcome);
154
- return outcome;
155
- };
156
- const handle = async (raw) => {
157
- const type = typeof raw === "object" && raw !== null && "type" in raw ? raw.type : null;
158
- if (type !== "daemon:storage-doctor" && type !== "daemon:storage-migrate")
159
- return false;
160
- const schema = type === "daemon:storage-doctor" ? DoctorRequestSchema : MigrateRequestSchema;
161
- const parsed = schema.safeParse(raw);
162
- if (!parsed.success)
163
- return true;
164
- const identity = parsed.data;
165
- if (!matchesIdentity(identity)) {
166
- failure(identity, "storage_identity_mismatch", undefined, true);
167
- return true;
168
- }
169
- if (type === "daemon:storage-doctor") {
170
- await runPreflight(identity);
171
- return true;
172
- }
173
- if (runningMigrationId !== null) {
174
- if (runningMigrationId !== identity.migrationId)
175
- failure(identity, "migration_active");
176
- return true;
177
- }
178
- const migrate = MigrateRequestSchema.parse(identity);
179
- if (appliedMigrationIds.has(identity.migrationId))
180
- return true;
181
- let doctor = preflights.get(identity.migrationId);
182
- if (doctor === undefined) {
183
- const rebuilt = await runPreflight(identity, "preflight_rebuild_failed");
184
- if (rebuilt === null)
185
- return true;
186
- doctor = rebuilt;
187
- }
188
- if (!doctor.applyAllowed || doctor.manifestDigest !== migrate.manifestDigest
189
- || doctor.manifest.migrationId !== identity.migrationId
190
- || doctor.environment !== environment || doctor.workspaceId !== workspaceId || doctor.profile !== profile) {
191
- failure(identity, "preflight_digest_mismatch", undefined, true);
192
- return true;
193
- }
194
- preflights.delete(identity.migrationId);
195
- runningMigrationId = identity.migrationId;
196
- try {
197
- await input.runMigration(doctor, (status) => {
198
- if (StatusSchema.safeParse(status).success)
199
- reportStatus(frame(identity, status));
200
- });
201
- appliedMigrationIds.add(identity.migrationId);
202
- }
203
- catch (error) {
204
- failure(identity, stableErrorCode(error.code, "storage_migration_failed"), error);
205
- }
206
- finally {
207
- runningMigrationId = null;
208
- }
209
- return true;
210
- };
211
- return Object.freeze({ handle });
212
- }