@agent-link/agent 0.1.296 → 0.1.297

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 (39) hide show
  1. package/dist/cli.js +55 -1
  2. package/dist/cli.js.map +1 -1
  3. package/dist/config.d.ts +2 -0
  4. package/dist/config.js.map +1 -1
  5. package/dist/daemon.js +1 -1
  6. package/dist/daemon.js.map +1 -1
  7. package/dist/external-upgrade.d.ts +22 -0
  8. package/dist/external-upgrade.js +186 -0
  9. package/dist/external-upgrade.js.map +1 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.js +7 -2
  12. package/dist/index.js.map +1 -1
  13. package/dist/local-control-client.d.ts +4 -0
  14. package/dist/local-control-client.js.map +1 -1
  15. package/dist/local-control-http.js +28 -4
  16. package/dist/local-control-http.js.map +1 -1
  17. package/dist/local-control.d.ts +7 -2
  18. package/dist/local-control.js +12 -0
  19. package/dist/local-control.js.map +1 -1
  20. package/dist/process-identity.d.ts +30 -0
  21. package/dist/process-identity.js +99 -0
  22. package/dist/process-identity.js.map +1 -0
  23. package/dist/upgrade-job.d.ts +51 -0
  24. package/dist/upgrade-job.js +233 -20
  25. package/dist/upgrade-job.js.map +1 -1
  26. package/dist/upgrade-lock.d.ts +25 -0
  27. package/dist/upgrade-lock.js +207 -0
  28. package/dist/upgrade-lock.js.map +1 -0
  29. package/dist/upgrade-persistence.d.ts +1 -0
  30. package/dist/upgrade-persistence.js +25 -0
  31. package/dist/upgrade-persistence.js.map +1 -0
  32. package/dist/worker-host.d.ts +38 -0
  33. package/dist/worker-host.js +172 -0
  34. package/dist/worker-host.js.map +1 -0
  35. package/dist/worker-shutdown-authorization.d.ts +7 -0
  36. package/dist/worker-shutdown-authorization.js +71 -0
  37. package/dist/worker-shutdown-authorization.js.map +1 -0
  38. package/package.json +3 -2
  39. package/worker/worker.cjs +612 -0
@@ -1,24 +1,65 @@
1
- import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'fs';
2
- import { join } from 'path';
1
+ import { appendFileSync, chmodSync, closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeFileSync, } from 'fs';
2
+ import { dirname, join, resolve } from 'path';
3
3
  import { randomUUID } from 'crypto';
4
4
  import { CONFIG_DIR } from './config.js';
5
+ import { validateVersionPointer, } from './version-store.js';
6
+ export const EXTERNAL_UPGRADE_PROTOCOL_VERSION = 1;
5
7
  const UPGRADE_DIR = join(CONFIG_DIR, 'upgrades');
6
- function jobPath(jobId) {
7
- if (!/^[a-zA-Z0-9-]{1,128}$/.test(jobId)) {
8
+ const JOB_ID = /^[a-zA-Z0-9-]{1,128}$/;
9
+ const TRANSITIONS = {
10
+ created: ['worker-starting', 'failed'],
11
+ 'worker-starting': ['worker-ready', 'failed'],
12
+ 'worker-ready': ['shutdown-requested', 'failed'],
13
+ 'shutdown-requested': ['old-agent-stopped', 'failed'],
14
+ 'old-agent-stopped': ['switching', 'failed'],
15
+ switching: ['target-starting', 'failed'],
16
+ 'target-starting': ['target-started', 'failed'],
17
+ 'target-started': [],
18
+ failed: [],
19
+ };
20
+ function requireJobId(jobId) {
21
+ if (!JOB_ID.test(jobId))
8
22
  throw new Error(`Invalid upgrade job ID: ${jobId}`);
9
- }
10
- return join(UPGRADE_DIR, `${jobId}.json`);
23
+ return jobId;
24
+ }
25
+ function legacyJobPath(jobId) {
26
+ return join(UPGRADE_DIR, `${requireJobId(jobId)}.json`);
27
+ }
28
+ export function getUpgradeRoot() {
29
+ return UPGRADE_DIR;
30
+ }
31
+ export function getExternalUpgradeJobDirectory(jobId) {
32
+ return join(UPGRADE_DIR, requireJobId(jobId));
11
33
  }
12
- function writeJob(path, job) {
13
- mkdirSync(UPGRADE_DIR, { recursive: true });
34
+ export function getExternalUpgradeJobPath(jobId) {
35
+ return join(getExternalUpgradeJobDirectory(jobId), 'job.json');
36
+ }
37
+ export function getExternalUpgradeEventsPath(jobId) {
38
+ return join(getExternalUpgradeJobDirectory(jobId), 'events.jsonl');
39
+ }
40
+ function atomicWriteJson(path, value) {
41
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
14
42
  const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
15
- writeFileSync(temporaryPath, JSON.stringify(job, null, 2) + '\n', {
16
- encoding: 'utf8',
17
- mode: 0o600,
18
- });
19
- renameSync(temporaryPath, path);
20
- if (process.platform !== 'win32')
21
- chmodSync(path, 0o600);
43
+ const handle = openSync(temporaryPath, 'wx', 0o600);
44
+ try {
45
+ writeFileSync(handle, JSON.stringify(value, null, 2) + '\n', 'utf8');
46
+ fsyncSync(handle);
47
+ }
48
+ finally {
49
+ closeSync(handle);
50
+ }
51
+ try {
52
+ renameSync(temporaryPath, path);
53
+ if (process.platform !== 'win32')
54
+ chmodSync(path, 0o600);
55
+ }
56
+ catch (error) {
57
+ rmSync(temporaryPath, { force: true });
58
+ throw error;
59
+ }
60
+ }
61
+ function writeLegacyJob(path, job) {
62
+ atomicWriteJson(path, job);
22
63
  }
23
64
  export function createUpgradeJob(input) {
24
65
  const timestamp = (input.now ?? new Date()).toISOString();
@@ -33,12 +74,12 @@ export function createUpgradeJob(input) {
33
74
  updatedAt: timestamp,
34
75
  launchSpecPath: input.launchSpecPath,
35
76
  };
36
- writeJob(jobPath(job.jobId), job);
37
- writeJob(join(UPGRADE_DIR, 'latest.json'), job);
77
+ writeLegacyJob(legacyJobPath(job.jobId), job);
78
+ writeLegacyJob(join(UPGRADE_DIR, 'latest.json'), job);
38
79
  return job;
39
80
  }
40
81
  export function updateUpgradeJob(jobId, phase, options = {}) {
41
- const path = jobPath(jobId);
82
+ const path = legacyJobPath(jobId);
42
83
  const existing = JSON.parse(readFileSync(path, 'utf8'));
43
84
  if (existing.schemaVersion !== 1 || existing.jobId !== jobId) {
44
85
  throw new Error(`Invalid upgrade job file: ${path}`);
@@ -52,8 +93,180 @@ export function updateUpgradeJob(jobId, phase, options = {}) {
52
93
  updated.error = options.error;
53
94
  else
54
95
  delete updated.error;
55
- writeJob(path, updated);
56
- writeJob(join(UPGRADE_DIR, 'latest.json'), updated);
96
+ writeLegacyJob(path, updated);
97
+ writeLegacyJob(join(UPGRADE_DIR, 'latest.json'), updated);
57
98
  return updated;
58
99
  }
100
+ function requireString(value, field) {
101
+ if (typeof value !== 'string' || value.length === 0) {
102
+ throw new Error(`External upgrade job ${field} must be a non-empty string`);
103
+ }
104
+ return value;
105
+ }
106
+ function requireTimestamp(value, field) {
107
+ const timestamp = requireString(value, field);
108
+ if (!Number.isFinite(Date.parse(timestamp))) {
109
+ throw new Error(`External upgrade job ${field} must be an ISO timestamp`);
110
+ }
111
+ return timestamp;
112
+ }
113
+ function validateProcessIdentity(value, field) {
114
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
115
+ throw new Error(`External upgrade job ${field} must be an object`);
116
+ }
117
+ const identity = value;
118
+ if (!Number.isSafeInteger(identity.pid) || identity.pid <= 0) {
119
+ throw new Error(`External upgrade job ${field}.pid must be a positive integer`);
120
+ }
121
+ return {
122
+ pid: identity.pid,
123
+ processStartIdentity: requireString(identity.processStartIdentity, `${field}.processStartIdentity`),
124
+ };
125
+ }
126
+ export function validateExternalUpgradeJob(value) {
127
+ if (!value || typeof value !== 'object' || Array.isArray(value)) {
128
+ throw new Error('External upgrade job must be an object');
129
+ }
130
+ const job = value;
131
+ if (job.schemaVersion !== 2)
132
+ throw new Error('External upgrade job schemaVersion is unsupported');
133
+ const jobId = requireJobId(requireString(job.jobId, 'jobId'));
134
+ if (!Object.prototype.hasOwnProperty.call(TRANSITIONS, String(job.phase))) {
135
+ throw new Error('External upgrade job phase is unsupported');
136
+ }
137
+ if (job.channel !== 'latest' && job.channel !== 'beta') {
138
+ throw new Error('External upgrade job channel is unsupported');
139
+ }
140
+ if (job.restartOwner !== 'worker') {
141
+ throw new Error('External upgrade job restartOwner must be worker');
142
+ }
143
+ const oldRuntime = validateProcessIdentity(job.oldRuntime, 'oldRuntime');
144
+ const oldRuntimeValue = job.oldRuntime;
145
+ const worker = job.worker === undefined
146
+ ? undefined
147
+ : {
148
+ ...validateProcessIdentity(job.worker, 'worker'),
149
+ protocolVersion: job.worker.protocolVersion,
150
+ };
151
+ if (worker && worker.protocolVersion !== EXTERNAL_UPGRADE_PROTOCOL_VERSION) {
152
+ throw new Error('External upgrade worker protocolVersion is unsupported');
153
+ }
154
+ const error = job.error;
155
+ if (error !== null && typeof error !== 'string') {
156
+ throw new Error('External upgrade job error must be null or a string');
157
+ }
158
+ const validated = {
159
+ schemaVersion: 2,
160
+ jobId,
161
+ requestId: requireString(job.requestId, 'requestId'),
162
+ channel: job.channel,
163
+ sourceVersion: requireString(job.sourceVersion, 'sourceVersion'),
164
+ targetVersion: requireString(job.targetVersion, 'targetVersion'),
165
+ phase: job.phase,
166
+ dataRoot: resolve(requireString(job.dataRoot, 'dataRoot')),
167
+ launchSpecPath: resolve(requireString(job.launchSpecPath, 'launchSpecPath')),
168
+ launchSpecDigest: requireString(job.launchSpecDigest, 'launchSpecDigest'),
169
+ oldRuntime: {
170
+ ...oldRuntime,
171
+ processInstanceId: requireString(oldRuntimeValue.processInstanceId, 'oldRuntime.processInstanceId'),
172
+ sessionId: requireString(oldRuntimeValue.sessionId, 'oldRuntime.sessionId'),
173
+ sessionUrlHash: requireString(oldRuntimeValue.sessionUrlHash, 'oldRuntime.sessionUrlHash'),
174
+ },
175
+ ...(worker ? {
176
+ worker: {
177
+ pid: worker.pid,
178
+ processStartIdentity: worker.processStartIdentity,
179
+ protocolVersion: 1,
180
+ },
181
+ } : {}),
182
+ restartOwner: 'worker',
183
+ sourceSelection: validateVersionPointer(job.sourceSelection),
184
+ targetSelection: validateVersionPointer(job.targetSelection),
185
+ lastKnownGoodSelection: validateVersionPointer(job.lastKnownGoodSelection),
186
+ lockNonce: requireString(job.lockNonce, 'lockNonce'),
187
+ handoffExpiresAt: requireTimestamp(job.handoffExpiresAt, 'handoffExpiresAt'),
188
+ createdAt: requireTimestamp(job.createdAt, 'createdAt'),
189
+ updatedAt: requireTimestamp(job.updatedAt, 'updatedAt'),
190
+ error: error,
191
+ };
192
+ if (validated.sourceSelection.version !== validated.sourceVersion
193
+ || validated.targetSelection.version !== validated.targetVersion) {
194
+ throw new Error('External upgrade job selections do not match source/target versions');
195
+ }
196
+ return validated;
197
+ }
198
+ export function createExternalUpgradeJob(input) {
199
+ const timestamp = (input.now ?? new Date()).toISOString();
200
+ const job = validateExternalUpgradeJob({
201
+ ...input,
202
+ now: undefined,
203
+ schemaVersion: 2,
204
+ phase: 'created',
205
+ createdAt: timestamp,
206
+ updatedAt: timestamp,
207
+ error: null,
208
+ });
209
+ const path = getExternalUpgradeJobPath(job.jobId);
210
+ if (existsSync(path))
211
+ throw new Error(`External upgrade job already exists: ${job.jobId}`);
212
+ atomicWriteJson(path, job);
213
+ atomicWriteJson(join(UPGRADE_DIR, 'latest.json'), job);
214
+ appendExternalUpgradeEvent(job, 'job-created');
215
+ return job;
216
+ }
217
+ export function loadExternalUpgradeJob(jobId) {
218
+ const path = getExternalUpgradeJobPath(jobId);
219
+ let value;
220
+ try {
221
+ value = JSON.parse(readFileSync(path, 'utf8'));
222
+ }
223
+ catch (error) {
224
+ throw new Error(`Failed to load external upgrade job ${jobId}: ${error.message}`);
225
+ }
226
+ const job = validateExternalUpgradeJob(value);
227
+ if (job.jobId !== jobId)
228
+ throw new Error('External upgrade job identity does not match its path');
229
+ return job;
230
+ }
231
+ export function transitionExternalUpgradeJob(jobId, phase, options = {}) {
232
+ const existing = loadExternalUpgradeJob(jobId);
233
+ if (existing.phase !== phase && !TRANSITIONS[existing.phase].includes(phase)) {
234
+ throw new Error(`Invalid external upgrade transition: ${existing.phase} -> ${phase}`);
235
+ }
236
+ const updated = validateExternalUpgradeJob({
237
+ ...existing,
238
+ phase,
239
+ ...(options.worker ? { worker: options.worker } : {}),
240
+ ...(options.error !== undefined ? { error: options.error } : {}),
241
+ updatedAt: (options.now ?? new Date()).toISOString(),
242
+ });
243
+ atomicWriteJson(getExternalUpgradeJobPath(jobId), updated);
244
+ atomicWriteJson(join(UPGRADE_DIR, 'latest.json'), updated);
245
+ appendExternalUpgradeEvent(updated, `phase-${phase}`);
246
+ return updated;
247
+ }
248
+ export function appendExternalUpgradeEvent(job, code, detail) {
249
+ const event = {
250
+ timestamp: new Date().toISOString(),
251
+ jobId: job.jobId,
252
+ phase: job.phase,
253
+ code,
254
+ ...(detail ? { detail: detail.slice(0, 512) } : {}),
255
+ oldRuntime: {
256
+ pid: job.oldRuntime.pid,
257
+ processStartIdentity: job.oldRuntime.processStartIdentity,
258
+ },
259
+ ...(job.worker ? {
260
+ worker: {
261
+ pid: job.worker.pid,
262
+ processStartIdentity: job.worker.processStartIdentity,
263
+ },
264
+ } : {}),
265
+ };
266
+ mkdirSync(getExternalUpgradeJobDirectory(job.jobId), { recursive: true, mode: 0o700 });
267
+ appendFileSync(getExternalUpgradeEventsPath(job.jobId), `${JSON.stringify(event)}\n`, {
268
+ encoding: 'utf8',
269
+ mode: 0o600,
270
+ });
271
+ }
59
272
  //# sourceMappingURL=upgrade-job.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade-job.js","sourceRoot":"","sources":["../src/upgrade-job.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"upgrade-job.js","sourceRoot":"","sources":["../src/upgrade-job.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { ProcessIdentity } from './upgrade-job.js';
2
+ export interface UpgradeLockOwner {
3
+ schemaVersion: 1;
4
+ jobId: string;
5
+ nonce: string;
6
+ dataRoot: string;
7
+ controller: ProcessIdentity;
8
+ worker?: ProcessIdentity;
9
+ createdAt: string;
10
+ }
11
+ export interface UpgradeLock {
12
+ path: string;
13
+ owner: UpgradeLockOwner;
14
+ tryClaimControllerCleanup(): boolean;
15
+ tryReclaimDeadWorkerCleanup(worker: ProcessIdentity): boolean;
16
+ abandonControllerCleanup(): void;
17
+ release(): void;
18
+ }
19
+ export declare function getUpgradeLockPath(): string;
20
+ export declare function loadUpgradeLockOwner(): UpgradeLockOwner;
21
+ export declare function acquireUpgradeLock(jobId: string): UpgradeLock;
22
+ export declare function assignUpgradeLockWorker(jobId: string, nonce: string, worker: ProcessIdentity): UpgradeLockOwner;
23
+ export declare function releaseUpgradeLockForWorker(jobId: string, nonce: string, worker: ProcessIdentity): void;
24
+ export declare function hasUpgradeLock(): boolean;
25
+ export declare function loadUpgradeLockWorkerClaim(): ProcessIdentity | null;
@@ -0,0 +1,207 @@
1
+ import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeFileSync, } from 'fs';
2
+ import { join, resolve } from 'path';
3
+ import { randomUUID } from 'crypto';
4
+ import { CONFIG_DIR } from './config.js';
5
+ import { getProcessStartIdentity } from './process-identity.js';
6
+ import { writePrivateJsonAtomic } from './upgrade-persistence.js';
7
+ export function getUpgradeLockPath() {
8
+ return join(CONFIG_DIR, 'upgrades', 'active.lock');
9
+ }
10
+ export function loadUpgradeLockOwner() {
11
+ const value = JSON.parse(readFileSync(join(getUpgradeLockPath(), 'owner.json'), 'utf8'));
12
+ if (value.schemaVersion !== 1
13
+ || typeof value.jobId !== 'string'
14
+ || typeof value.nonce !== 'string'
15
+ || resolve(value.dataRoot) !== resolve(CONFIG_DIR)
16
+ || !Number.isSafeInteger(value.controller?.pid)
17
+ || typeof value.controller?.processStartIdentity !== 'string') {
18
+ throw new Error('Upgrade lock owner is invalid');
19
+ }
20
+ return value;
21
+ }
22
+ function getHandoffClaimPath() {
23
+ return join(getUpgradeLockPath(), 'handoff.claim');
24
+ }
25
+ function loadHandoffClaim() {
26
+ try {
27
+ const value = JSON.parse(readFileSync(getHandoffClaimPath(), 'utf8'));
28
+ if (value.schemaVersion !== 1
29
+ || (value.role !== 'controller' && value.role !== 'worker')
30
+ || typeof value.jobId !== 'string'
31
+ || typeof value.nonce !== 'string'
32
+ || (value.role === 'worker'
33
+ && (!Number.isSafeInteger(value.worker?.pid)
34
+ || typeof value.worker?.processStartIdentity !== 'string'))) {
35
+ throw new Error('Upgrade handoff claim is invalid');
36
+ }
37
+ return value;
38
+ }
39
+ catch (error) {
40
+ if (error.code === 'ENOENT')
41
+ return null;
42
+ throw error;
43
+ }
44
+ }
45
+ function tryCreateHandoffClaim(claim) {
46
+ let handle;
47
+ try {
48
+ handle = openSync(getHandoffClaimPath(), 'wx', 0o600);
49
+ }
50
+ catch (error) {
51
+ if (error.code === 'EEXIST')
52
+ return false;
53
+ throw error;
54
+ }
55
+ try {
56
+ writeFileSync(handle, JSON.stringify(claim, null, 2) + '\n', 'utf8');
57
+ fsyncSync(handle);
58
+ }
59
+ finally {
60
+ closeSync(handle);
61
+ }
62
+ return true;
63
+ }
64
+ function releaseClaimedLock(jobId, nonce, role) {
65
+ const owner = loadUpgradeLockOwner();
66
+ const claim = loadHandoffClaim();
67
+ if (owner.jobId !== jobId
68
+ || owner.nonce !== nonce
69
+ || claim?.jobId !== jobId
70
+ || claim.nonce !== nonce
71
+ || claim.role !== role) {
72
+ throw new Error('Upgrade lock ownership changed unexpectedly');
73
+ }
74
+ const lockPath = getUpgradeLockPath();
75
+ const tombstone = `${lockPath}.released-${nonce}`;
76
+ renameSync(lockPath, tombstone);
77
+ rmSync(tombstone, { recursive: true, force: true });
78
+ }
79
+ export function acquireUpgradeLock(jobId) {
80
+ const lockPath = getUpgradeLockPath();
81
+ mkdirSync(join(CONFIG_DIR, 'upgrades'), { recursive: true, mode: 0o700 });
82
+ try {
83
+ mkdirSync(lockPath, { mode: 0o700 });
84
+ }
85
+ catch (error) {
86
+ if (error.code === 'EEXIST') {
87
+ throw new Error('Another external upgrade owns the active upgrade lock');
88
+ }
89
+ throw error;
90
+ }
91
+ const processStartIdentity = getProcessStartIdentity(process.pid);
92
+ if (!processStartIdentity) {
93
+ rmSync(lockPath, { recursive: true, force: true });
94
+ throw new Error('Cannot acquire upgrade lock without an exact controller process identity');
95
+ }
96
+ const owner = {
97
+ schemaVersion: 1,
98
+ jobId,
99
+ nonce: randomUUID(),
100
+ dataRoot: resolve(CONFIG_DIR),
101
+ controller: { pid: process.pid, processStartIdentity },
102
+ createdAt: new Date().toISOString(),
103
+ };
104
+ try {
105
+ writePrivateJsonAtomic(join(lockPath, 'owner.json'), owner);
106
+ }
107
+ catch (error) {
108
+ rmSync(lockPath, { recursive: true, force: true });
109
+ throw error;
110
+ }
111
+ let released = false;
112
+ let controllerClaimed = false;
113
+ return {
114
+ path: lockPath,
115
+ owner,
116
+ tryClaimControllerCleanup() {
117
+ if (released)
118
+ return false;
119
+ if (controllerClaimed)
120
+ return true;
121
+ controllerClaimed = tryCreateHandoffClaim({
122
+ schemaVersion: 1,
123
+ role: 'controller',
124
+ jobId: owner.jobId,
125
+ nonce: owner.nonce,
126
+ });
127
+ return controllerClaimed;
128
+ },
129
+ tryReclaimDeadWorkerCleanup(worker) {
130
+ if (released || controllerClaimed)
131
+ return false;
132
+ const claim = loadHandoffClaim();
133
+ if (claim?.role !== 'worker'
134
+ || claim.jobId !== owner.jobId
135
+ || claim.nonce !== owner.nonce
136
+ || claim.worker?.pid !== worker.pid
137
+ || claim.worker.processStartIdentity !== worker.processStartIdentity) {
138
+ return false;
139
+ }
140
+ rmSync(getHandoffClaimPath());
141
+ return this.tryClaimControllerCleanup();
142
+ },
143
+ abandonControllerCleanup() {
144
+ if (!controllerClaimed || released)
145
+ return;
146
+ const claim = loadHandoffClaim();
147
+ if (claim?.role !== 'controller'
148
+ || claim.jobId !== owner.jobId
149
+ || claim.nonce !== owner.nonce) {
150
+ throw new Error('Upgrade controller cleanup claim changed unexpectedly');
151
+ }
152
+ rmSync(getHandoffClaimPath());
153
+ controllerClaimed = false;
154
+ },
155
+ release() {
156
+ if (released)
157
+ return;
158
+ if (!controllerClaimed && !this.tryClaimControllerCleanup()) {
159
+ throw new Error('Upgrade lock ownership transferred to the worker');
160
+ }
161
+ releaseClaimedLock(owner.jobId, owner.nonce, 'controller');
162
+ released = true;
163
+ },
164
+ };
165
+ }
166
+ export function assignUpgradeLockWorker(jobId, nonce, worker) {
167
+ const owner = loadUpgradeLockOwner();
168
+ if (owner.jobId !== jobId || owner.nonce !== nonce) {
169
+ throw new Error('Upgrade worker does not own the active lock');
170
+ }
171
+ if (!tryCreateHandoffClaim({
172
+ schemaVersion: 1,
173
+ role: 'worker',
174
+ jobId,
175
+ nonce,
176
+ worker,
177
+ })) {
178
+ throw new Error('Upgrade lock handoff was already claimed');
179
+ }
180
+ const current = loadUpgradeLockOwner();
181
+ if (current.jobId !== jobId || current.nonce !== nonce) {
182
+ throw new Error('Upgrade lock changed during worker handoff');
183
+ }
184
+ const updated = { ...owner, worker };
185
+ writePrivateJsonAtomic(join(getUpgradeLockPath(), 'owner.json'), updated);
186
+ return updated;
187
+ }
188
+ export function releaseUpgradeLockForWorker(jobId, nonce, worker) {
189
+ const owner = loadUpgradeLockOwner();
190
+ const claim = loadHandoffClaim();
191
+ if (owner.worker?.pid !== worker.pid
192
+ || owner.worker?.processStartIdentity !== worker.processStartIdentity
193
+ || claim?.role !== 'worker'
194
+ || claim.worker?.pid !== worker.pid
195
+ || claim.worker.processStartIdentity !== worker.processStartIdentity) {
196
+ throw new Error('Upgrade lock is not owned by this worker');
197
+ }
198
+ releaseClaimedLock(jobId, nonce, 'worker');
199
+ }
200
+ export function hasUpgradeLock() {
201
+ return existsSync(getUpgradeLockPath());
202
+ }
203
+ export function loadUpgradeLockWorkerClaim() {
204
+ const claim = loadHandoffClaim();
205
+ return claim?.role === 'worker' ? claim.worker ?? null : null;
206
+ }
207
+ //# sourceMappingURL=upgrade-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-lock.js","sourceRoot":"","sources":["../src/upgrade-lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function writePrivateJsonAtomic(path: string, value: unknown): void;
@@ -0,0 +1,25 @@
1
+ import { chmodSync, closeSync, fsyncSync, mkdirSync, openSync, renameSync, rmSync, writeFileSync, } from 'fs';
2
+ import { dirname } from 'path';
3
+ import { randomUUID } from 'crypto';
4
+ export function writePrivateJsonAtomic(path, value) {
5
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
6
+ const temporaryPath = `${path}.${process.pid}.${randomUUID()}.tmp`;
7
+ const handle = openSync(temporaryPath, 'wx', 0o600);
8
+ try {
9
+ writeFileSync(handle, JSON.stringify(value, null, 2) + '\n', 'utf8');
10
+ fsyncSync(handle);
11
+ }
12
+ finally {
13
+ closeSync(handle);
14
+ }
15
+ try {
16
+ renameSync(temporaryPath, path);
17
+ if (process.platform !== 'win32')
18
+ chmodSync(path, 0o600);
19
+ }
20
+ catch (error) {
21
+ rmSync(temporaryPath, { force: true });
22
+ throw error;
23
+ }
24
+ }
25
+ //# sourceMappingURL=upgrade-persistence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade-persistence.js","sourceRoot":"","sources":["../src/upgrade-persistence.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,SAAS,EACT,SAAS,EACT,SAAS,EACT,QAAQ,EACR,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,MAAM,UAAU,sBAAsB,CAAC,IAAY,EAAE,KAAc;IACjE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,GAAG,IAAI,IAAI,OAAO,CAAC,GAAG,IAAI,UAAU,EAAE,MAAM,CAAC;IACnE,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IACpD,IAAI,CAAC;QACH,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;QACrE,SAAS,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;YAAS,CAAC;QACT,SAAS,CAAC,MAAM,CAAC,CAAC;IACpB,CAAC;IACD,IAAI,CAAC;QACH,UAAU,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;QAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;YAAE,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACvC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,38 @@
1
+ import { type ChildProcess } from 'child_process';
2
+ import type { LaunchHostType } from './launch-spec.js';
3
+ export interface WorkerHostCommand {
4
+ executable: string;
5
+ args: string[];
6
+ options: {
7
+ cwd: string;
8
+ env: NodeJS.ProcessEnv;
9
+ detached?: boolean;
10
+ stdio?: ['ignore', number, number] | 'ignore';
11
+ windowsHide: true;
12
+ };
13
+ }
14
+ export interface WorkerHostDeps {
15
+ platform?: NodeJS.Platform;
16
+ nodePath?: string;
17
+ spawnProcess?: (command: WorkerHostCommand) => ChildProcess | {
18
+ pid?: number;
19
+ unref?: () => void;
20
+ };
21
+ uid?: number;
22
+ }
23
+ export interface WorkerHostResult {
24
+ kind: 'detached' | 'systemd-transient' | 'launchd-temporary';
25
+ pid?: number;
26
+ command: WorkerHostCommand;
27
+ artifactPath?: string;
28
+ serviceIdentifier?: string;
29
+ started: Promise<void>;
30
+ }
31
+ export declare function getPackagedWorkerPath(): string;
32
+ export declare function startUpgradeWorker(input: {
33
+ jobId: string;
34
+ jobPath: string;
35
+ workerPath: string;
36
+ hostType: LaunchHostType;
37
+ }, deps?: WorkerHostDeps): WorkerHostResult;
38
+ export declare function cleanupUpgradeWorkerHost(result: WorkerHostResult, deps?: WorkerHostDeps): void;