@wjarka/cezarion 0.14.8-pr498.749 → 0.14.8-pr501.753
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/README.md +13 -0
- package/dist/application-update/discovery.d.ts +22 -0
- package/dist/application-update/discovery.js +91 -0
- package/dist/application-update/discovery.js.map +1 -0
- package/dist/application-update/helper.d.ts +56 -0
- package/dist/application-update/helper.js +360 -0
- package/dist/application-update/helper.js.map +1 -0
- package/dist/application-update/launcher.d.ts +8 -0
- package/dist/application-update/launcher.js +52 -0
- package/dist/application-update/launcher.js.map +1 -0
- package/dist/application-update/lock.d.ts +4 -0
- package/dist/application-update/lock.js +70 -0
- package/dist/application-update/lock.js.map +1 -0
- package/dist/application-update/npm-process.d.ts +2 -0
- package/dist/application-update/npm-process.js +45 -0
- package/dist/application-update/npm-process.js.map +1 -0
- package/dist/application-update/service.d.ts +67 -0
- package/dist/application-update/service.js +432 -0
- package/dist/application-update/service.js.map +1 -0
- package/dist/contract/application-update.d.ts +32 -0
- package/dist/contract/health.d.ts +12 -0
- package/dist/contract/index.d.ts +1 -0
- package/dist/contract/index.js +1010 -993
- package/dist/delegation/transport.d.ts +4 -4
- package/dist/index.js +46 -7
- package/dist/index.js.map +1 -1
- package/dist/server/server.d.ts +102 -37
- package/dist/server/server.js +70 -2
- package/dist/server/server.js.map +1 -1
- package/package.json +3 -3
- package/web/dist/assets/agent-accounts-Dr2XFOSn.js +1 -0
- package/web/dist/assets/centered-state-60qUpq__.js +43 -0
- package/web/dist/assets/collapsible-BB9LgiQ9.js +1 -0
- package/web/dist/assets/commit-list-D3iigBKo.js +1 -0
- package/web/dist/assets/compare-variants-CS4wuELE.js +1 -0
- package/web/dist/assets/{diff-BvZErqfg2.js → diff-C2LyKTLL2.js} +2 -2
- package/web/dist/assets/diff-controls-BSftCFtS.js +1 -0
- package/web/dist/assets/{diff-stat-CVFxf2Ar.js → diff-stat-3hao9x1N.js} +1 -1
- package/web/dist/assets/{diff-view-B35r8kQK.js → diff-view-CtHqs45o.js} +1 -1
- package/web/dist/assets/dropdown-menu-CXN61qNS.js +1 -0
- package/web/dist/assets/git-toolbar-DGblYrBc.js +1 -0
- package/web/dist/assets/github-C-4NvSIF.js +1 -0
- package/web/dist/assets/{image-preview-BBqbaKaq.js → image-preview-BCMDBICt.js} +1 -1
- package/web/dist/assets/index-CcsZWnre.js +7 -0
- package/web/dist/assets/{index-D85fJxcf.css → index-DB_CKw76.css} +1 -1
- package/web/dist/assets/markdown-Cny_myUJ.js +2 -0
- package/web/dist/assets/pill-B9wMVRMC.js +1 -0
- package/web/dist/assets/project-router-DPkv2zTq.js +1 -0
- package/web/dist/assets/prompt-templates-nVw2unr_.js +15 -0
- package/web/dist/assets/repo-git-tnRhIvra.js +1 -0
- package/web/dist/assets/{run-diff-CXbgbsh9.js → run-diff-0j0NnTUT.js} +1 -1
- package/web/dist/assets/run-header-CmqicxQv.js +1 -0
- package/web/dist/assets/skills-B2DRiPAU.js +1 -0
- package/web/dist/assets/{tab-link-DC0UURrc.js → tab-link-DZRYo5NJ.js} +1 -1
- package/web/dist/assets/task-changes-YjEXRpBP.js +1 -0
- package/web/dist/assets/task-commits-BQIKe4uN.js +1 -0
- package/web/dist/assets/task-files-DOSQNS0t.js +2 -0
- package/web/dist/assets/task-thread-C8TwzpGz.js +9 -0
- package/web/dist/assets/textarea-Bg4jkhb4.js +1 -0
- package/web/dist/assets/thread-loading-BMq0pukO.js +1 -0
- package/web/dist/assets/{token-metrics-BVEbZnKW.js → token-metrics-B-z2SQQK.js} +1 -1
- package/web/dist/assets/utils-DwoxKYqB.js +64 -0
- package/web/dist/assets/workflows-xRY-AsMQ.js +11 -0
- package/web/dist/assets/{zoomable-image-DpL5gtv4.js → zoomable-image-CcgehL57.js} +1 -1
- package/web/dist/index.html +14 -14
- package/web/dist/assets/agent-accounts-BJDmhSDn.js +0 -1
- package/web/dist/assets/alert-dialog-DX4yEDYu.js +0 -43
- package/web/dist/assets/collapsible-BCJ0khvt.js +0 -1
- package/web/dist/assets/commit-list-D-16D4zZ.js +0 -1
- package/web/dist/assets/compare-variants-DRDigWJL.js +0 -1
- package/web/dist/assets/diff-controls-CnjM1p8Z.js +0 -1
- package/web/dist/assets/dropdown-menu-D0oVIuoD.js +0 -1
- package/web/dist/assets/git-toolbar-CewGX75-.js +0 -1
- package/web/dist/assets/github-C8ELncEJ.js +0 -1
- package/web/dist/assets/index-BmS3kflA.js +0 -7
- package/web/dist/assets/markdown-ckAEf3Je.js +0 -2
- package/web/dist/assets/pill-CxoPpiR8.js +0 -1
- package/web/dist/assets/project-router-p3S2kIpb.js +0 -1
- package/web/dist/assets/prompt-templates-Bz9Ni_N6.js +0 -15
- package/web/dist/assets/repo-git-D84wWmC3.js +0 -1
- package/web/dist/assets/run-header-C4l5XH56.js +0 -1
- package/web/dist/assets/skills-GyRyvSGk.js +0 -1
- package/web/dist/assets/task-changes-CikB7d7m.js +0 -1
- package/web/dist/assets/task-commits-4hwswJ6r.js +0 -1
- package/web/dist/assets/task-files-BabK4MnP.js +0 -2
- package/web/dist/assets/task-thread-ByhYz5SB.js +0 -9
- package/web/dist/assets/textarea-Bk2Mu1z_.js +0 -1
- package/web/dist/assets/thread-loading-CykR9TaJ.js +0 -1
- package/web/dist/assets/utils-VFstALJW.js +0 -64
- package/web/dist/assets/workflows-C2LvI3eZ.js +0 -11
package/README.md
CHANGED
|
@@ -38,6 +38,19 @@ That's the whole setup. If your `claude` CLI is logged in (Pro/Max) and `gh` is
|
|
|
38
38
|
authenticated, there is nothing else to configure. State lives in `.ai/cezar/`
|
|
39
39
|
inside your repo — plain JSON, NDJSON and Markdown you can `cat` and fix by hand.
|
|
40
40
|
|
|
41
|
+
Local npm installations have a workspace update API. `POST
|
|
42
|
+
/api/v1/workspace/application-update/apply` with `{}` prepares the release
|
|
43
|
+
advertised by health while the current server keeps running; `POST
|
|
44
|
+
/api/v1/workspace/application-update/restart` with `{}` then restarts it. A
|
|
45
|
+
successful restart updates the original global installation or ordinary npx
|
|
46
|
+
cache entry, so the same command uses the new version on its next launch.
|
|
47
|
+
Update preparation and recovery state is generated under
|
|
48
|
+
`~/.cezar/application-updates/` (or `CEZ_HOME`).
|
|
49
|
+
Pinned npx invocations, source checkouts, npm links, and hosted deployments use
|
|
50
|
+
their existing manual update paths. Cezar holds its own installation lock and
|
|
51
|
+
npm's npx lock during promotion; a separate manual `npm install` does not honor
|
|
52
|
+
those locks, so avoid one while an update is preparing or restarting.
|
|
53
|
+
|
|
41
54
|
## A look inside
|
|
42
55
|
|
|
43
56
|
Click any thumbnail for the full-size screenshot.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type Installation = {
|
|
2
|
+
kind: 'unsupported';
|
|
3
|
+
reason: string;
|
|
4
|
+
} | {
|
|
5
|
+
kind: 'global' | 'npx';
|
|
6
|
+
prefix: string;
|
|
7
|
+
cache: string;
|
|
8
|
+
installRoot: string;
|
|
9
|
+
packageRoot: string;
|
|
10
|
+
outerRoot: string;
|
|
11
|
+
launchEntry: string;
|
|
12
|
+
outerPackage: '@wjarka/cezarion' | 'cezarion';
|
|
13
|
+
request: string;
|
|
14
|
+
};
|
|
15
|
+
export interface DiscoveryInput {
|
|
16
|
+
prefix: string;
|
|
17
|
+
cache: string;
|
|
18
|
+
packageRoot: string;
|
|
19
|
+
launchEntry: string;
|
|
20
|
+
}
|
|
21
|
+
/** Match only npm-owned, canonical layouts. A matched but unsafe layout is explicit. */
|
|
22
|
+
export declare function discoverInstallation(input: DiscoveryInput): Installation;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { realpathSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join, relative, resolve, sep } from 'node:path';
|
|
3
|
+
function inside(path, root) {
|
|
4
|
+
const rel = relative(root, path);
|
|
5
|
+
return rel === '' || (rel !== '..' && !rel.startsWith(`..${sep}`) && !rel.startsWith(sep));
|
|
6
|
+
}
|
|
7
|
+
function json(path) {
|
|
8
|
+
return JSON.parse(readFileSync(path, 'utf8'));
|
|
9
|
+
}
|
|
10
|
+
/** Match only npm-owned, canonical layouts. A matched but unsafe layout is explicit. */
|
|
11
|
+
export function discoverInstallation(input) {
|
|
12
|
+
const unsupported = (reason) => ({ kind: 'unsupported', reason });
|
|
13
|
+
try {
|
|
14
|
+
let prefix;
|
|
15
|
+
try {
|
|
16
|
+
prefix = realpathSync(input.prefix);
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
prefix = resolve(input.prefix);
|
|
20
|
+
}
|
|
21
|
+
// A fresh global npm install need not have created its cache yet.
|
|
22
|
+
let cache;
|
|
23
|
+
try {
|
|
24
|
+
cache = realpathSync(input.cache);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
cache = resolve(input.cache);
|
|
28
|
+
}
|
|
29
|
+
const packageRoot = realpathSync(input.packageRoot);
|
|
30
|
+
const launchEntry = realpathSync(input.launchEntry);
|
|
31
|
+
const manifest = json(join(packageRoot, 'package.json'));
|
|
32
|
+
if (manifest.name !== '@wjarka/cezarion' || typeof manifest.version !== 'string') {
|
|
33
|
+
return unsupported('running package is not @wjarka/cezarion');
|
|
34
|
+
}
|
|
35
|
+
let kind;
|
|
36
|
+
let installRoot;
|
|
37
|
+
let modules;
|
|
38
|
+
if (inside(packageRoot, join(prefix, 'lib/node_modules')) || inside(packageRoot, join(prefix, 'node_modules'))) {
|
|
39
|
+
kind = 'global';
|
|
40
|
+
installRoot = prefix;
|
|
41
|
+
modules = inside(packageRoot, join(prefix, 'lib/node_modules')) ? join(prefix, 'lib/node_modules') : join(prefix, 'node_modules');
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
const parts = relative(cache, packageRoot).split(sep);
|
|
45
|
+
if (parts[0] !== '_npx' || !/^[a-z0-9]+$/i.test(parts[1] ?? '') || parts[2] !== 'node_modules') {
|
|
46
|
+
return unsupported('not an npm global or npx cache installation');
|
|
47
|
+
}
|
|
48
|
+
kind = 'npx';
|
|
49
|
+
installRoot = join(cache, '_npx', parts[1]);
|
|
50
|
+
modules = join(installRoot, 'node_modules');
|
|
51
|
+
}
|
|
52
|
+
const direct = join(modules, '@wjarka/cezarion');
|
|
53
|
+
const alias = join(modules, 'cezarion');
|
|
54
|
+
let outerPackage;
|
|
55
|
+
if (packageRoot !== direct && packageRoot !== join(alias, 'node_modules/@wjarka/cezarion')) {
|
|
56
|
+
return unsupported('linked or mixed package layout');
|
|
57
|
+
}
|
|
58
|
+
outerPackage = inside(launchEntry, alias) ? 'cezarion' : '@wjarka/cezarion';
|
|
59
|
+
let request = outerPackage;
|
|
60
|
+
if (kind === 'npx') {
|
|
61
|
+
const root = json(join(installRoot, 'package.json'));
|
|
62
|
+
const requests = root._npx?.packages;
|
|
63
|
+
if (!Array.isArray(requests) || requests.length !== 1 ||
|
|
64
|
+
!['cezarion', '@wjarka/cezarion'].includes(requests[0])) {
|
|
65
|
+
return unsupported('pinned or mixed npx request');
|
|
66
|
+
}
|
|
67
|
+
request = requests[0];
|
|
68
|
+
// npm may link .bin/cezarion to the scoped dependency even when the _npx
|
|
69
|
+
// request and root dependency are the alias. Metadata owns this choice.
|
|
70
|
+
outerPackage = request;
|
|
71
|
+
}
|
|
72
|
+
if (outerPackage === '@wjarka/cezarion' && packageRoot !== direct)
|
|
73
|
+
return unsupported('mixed launch layout');
|
|
74
|
+
const outerPath = outerPackage === 'cezarion' ? alias : direct;
|
|
75
|
+
if (!inside(launchEntry, outerPath) && !(kind === 'npx' && inside(launchEntry, packageRoot))) {
|
|
76
|
+
return unsupported('launch entry does not belong to installation');
|
|
77
|
+
}
|
|
78
|
+
if (outerPackage === 'cezarion') {
|
|
79
|
+
const outer = json(join(alias, 'package.json'));
|
|
80
|
+
const deps = outer.dependencies;
|
|
81
|
+
if (outer.name !== 'cezarion' || typeof deps?.['@wjarka/cezarion'] !== 'string')
|
|
82
|
+
return unsupported('alias is not linked to scoped package');
|
|
83
|
+
}
|
|
84
|
+
return { kind, prefix, cache, installRoot, packageRoot, outerRoot: outerPath,
|
|
85
|
+
launchEntry: resolve(input.launchEntry), outerPackage, request };
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return unsupported('installation metadata is unavailable');
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../../src/application-update/discovery.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { type AddressInfo } from 'node:net';
|
|
2
|
+
export interface HelperPlan {
|
|
3
|
+
installation: {
|
|
4
|
+
kind: 'global' | 'npx';
|
|
5
|
+
prefix: string;
|
|
6
|
+
cache: string;
|
|
7
|
+
installRoot: string;
|
|
8
|
+
packageRoot: string;
|
|
9
|
+
outerRoot: string;
|
|
10
|
+
launchEntry: string;
|
|
11
|
+
outerPackage: '@wjarka/cezarion' | 'cezarion';
|
|
12
|
+
request: string;
|
|
13
|
+
};
|
|
14
|
+
targetVersion: string;
|
|
15
|
+
oldVersion: string;
|
|
16
|
+
recovery: string;
|
|
17
|
+
binLinks?: string;
|
|
18
|
+
recordPath: string;
|
|
19
|
+
oldPid: number;
|
|
20
|
+
nodeExecutable: string;
|
|
21
|
+
nodeArgs: string[];
|
|
22
|
+
cliArgs: string[];
|
|
23
|
+
cwd: string;
|
|
24
|
+
repoRoot: string;
|
|
25
|
+
host: string;
|
|
26
|
+
port: number;
|
|
27
|
+
npmBin: string;
|
|
28
|
+
claimId: string;
|
|
29
|
+
}
|
|
30
|
+
/** Only a listening TCP server can supply the private restart destination. */
|
|
31
|
+
export declare function restartEndpoint(address: AddressInfo | string | null): Pick<HelperPlan, 'host' | 'port'>;
|
|
32
|
+
export declare function restartHealthUrl(endpoint: Pick<HelperPlan, 'host' | 'port'>): string;
|
|
33
|
+
/** A private loopback probe must not use Node's environment-proxied global agent. */
|
|
34
|
+
export declare function requestRestartHealth(endpoint: Pick<HelperPlan, 'host' | 'port'>, signal: AbortSignal): Promise<{
|
|
35
|
+
version?: string;
|
|
36
|
+
repoRoot?: string;
|
|
37
|
+
} | undefined>;
|
|
38
|
+
export interface RestartIO {
|
|
39
|
+
waitForOldExit(): Promise<void>;
|
|
40
|
+
promote(): Promise<void>;
|
|
41
|
+
validateOriginal(): Promise<void>;
|
|
42
|
+
launch(): Promise<void>;
|
|
43
|
+
verifyHealth(): Promise<void>;
|
|
44
|
+
reapReplacement(): Promise<void>;
|
|
45
|
+
restore(): Promise<void>;
|
|
46
|
+
launchPrevious(): Promise<void>;
|
|
47
|
+
reportSuccess(): Promise<void>;
|
|
48
|
+
reportFailure(rollbackFailed: boolean): Promise<void>;
|
|
49
|
+
assertOwned?(): Promise<void>;
|
|
50
|
+
}
|
|
51
|
+
/** Only the helper owns the promotion transaction. Rollback waits for its child to exit. */
|
|
52
|
+
export declare function runRestartWorkflow(io: RestartIO): Promise<void>;
|
|
53
|
+
export declare function manualRepairCommand(installation: Pick<HelperPlan['installation'], 'kind' | 'prefix' | 'installRoot' | 'outerPackage'>, version: string): string;
|
|
54
|
+
export declare function promoteOriginal(plan: HelperPlan, npxLockAlreadyHeld?: boolean, signal?: AbortSignal): Promise<void>;
|
|
55
|
+
export declare function restoreOriginal(plan: HelperPlan, assertOwned?: () => Promise<void>): Promise<void>;
|
|
56
|
+
export declare function runHelper(plan: HelperPlan, onArmed?: () => void): Promise<void>;
|
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { cp, readFile, readdir, rename, rm, symlink, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
4
|
+
import { dirname, join } from 'node:path';
|
|
5
|
+
import { isIP } from 'node:net';
|
|
6
|
+
import { Agent, get } from 'node:http';
|
|
7
|
+
import { withDirectoryLock } from './lock.js';
|
|
8
|
+
import { runOwnedNpm } from './npm-process.js';
|
|
9
|
+
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
/** Only a listening TCP server can supply the private restart destination. */
|
|
11
|
+
export function restartEndpoint(address) {
|
|
12
|
+
if (!address || typeof address === 'string' || !Number.isInteger(address.port) || address.port < 1 || address.port > 65535
|
|
13
|
+
|| !(isIP(address.address) === 4 && address.address.split('.')[0] === '127' || address.address === '::1')) {
|
|
14
|
+
throw new Error('restart requires a bound loopback endpoint');
|
|
15
|
+
}
|
|
16
|
+
return { host: address.address, port: address.port };
|
|
17
|
+
}
|
|
18
|
+
export function restartHealthUrl(endpoint) {
|
|
19
|
+
const { host, port } = restartEndpoint({ address: endpoint.host, port: endpoint.port, family: '' });
|
|
20
|
+
return `http://${host.includes(':') ? `[${host}]` : host}:${port}/api/v1/health`;
|
|
21
|
+
}
|
|
22
|
+
/** A private loopback probe must not use Node's environment-proxied global agent. */
|
|
23
|
+
export async function requestRestartHealth(endpoint, signal) {
|
|
24
|
+
const agent = new Agent();
|
|
25
|
+
try {
|
|
26
|
+
return await new Promise((resolve, reject) => {
|
|
27
|
+
const request = get(restartHealthUrl(endpoint), { agent, signal }, (response) => {
|
|
28
|
+
response.once('error', reject);
|
|
29
|
+
if (!response.statusCode || response.statusCode < 200 || response.statusCode >= 300) {
|
|
30
|
+
response.resume();
|
|
31
|
+
resolve(undefined);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
let body = '';
|
|
35
|
+
response.setEncoding('utf8');
|
|
36
|
+
response.on('data', (chunk) => { body += chunk; });
|
|
37
|
+
response.once('end', () => {
|
|
38
|
+
try {
|
|
39
|
+
resolve(JSON.parse(body));
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
reject(error);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
request.once('error', reject);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
agent.destroy();
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/** Only the helper owns the promotion transaction. Rollback waits for its child to exit. */
|
|
54
|
+
export async function runRestartWorkflow(io) {
|
|
55
|
+
await io.waitForOldExit();
|
|
56
|
+
await io.assertOwned?.();
|
|
57
|
+
let replacementLaunched = false;
|
|
58
|
+
try {
|
|
59
|
+
await io.assertOwned?.();
|
|
60
|
+
await io.promote();
|
|
61
|
+
await io.assertOwned?.();
|
|
62
|
+
await io.validateOriginal();
|
|
63
|
+
await io.assertOwned?.();
|
|
64
|
+
await io.launch();
|
|
65
|
+
replacementLaunched = true;
|
|
66
|
+
await io.assertOwned?.();
|
|
67
|
+
await io.verifyHealth();
|
|
68
|
+
await io.assertOwned?.();
|
|
69
|
+
await io.reportSuccess();
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
if (replacementLaunched) {
|
|
73
|
+
try {
|
|
74
|
+
await io.reapReplacement();
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Never mutate the installation or launch another process until the
|
|
78
|
+
// helper has confirmed its replacement is gone.
|
|
79
|
+
await io.assertOwned?.();
|
|
80
|
+
await io.reportFailure(true);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// A foreign owner may now be installing into the same tree. Preserve the
|
|
85
|
+
// recovery copy and leave the stale claim for the next boot to salvage.
|
|
86
|
+
await io.assertOwned?.();
|
|
87
|
+
let rollbackFailed = false;
|
|
88
|
+
try {
|
|
89
|
+
await io.assertOwned?.();
|
|
90
|
+
await io.restore();
|
|
91
|
+
await io.assertOwned?.();
|
|
92
|
+
await io.launchPrevious();
|
|
93
|
+
await io.assertOwned?.();
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
await io.reapReplacement().catch(() => undefined);
|
|
97
|
+
await io.assertOwned?.();
|
|
98
|
+
rollbackFailed = true;
|
|
99
|
+
}
|
|
100
|
+
await io.assertOwned?.();
|
|
101
|
+
await io.reportFailure(rollbackFailed);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
function scopedPath(plan) {
|
|
105
|
+
if (plan.installation.outerPackage === '@wjarka/cezarion')
|
|
106
|
+
return plan.installation.packageRoot;
|
|
107
|
+
const nested = join(plan.installation.outerRoot, 'node_modules/@wjarka/cezarion');
|
|
108
|
+
if (existsSync(nested))
|
|
109
|
+
return nested;
|
|
110
|
+
const modules = plan.installation.kind === 'npx' ? join(plan.installation.installRoot, 'node_modules')
|
|
111
|
+
: dirname(plan.installation.outerRoot);
|
|
112
|
+
return join(modules, '@wjarka/cezarion');
|
|
113
|
+
}
|
|
114
|
+
function validateOriginal(plan, expected) {
|
|
115
|
+
const pkg = JSON.parse(readFileSync(join(scopedPath(plan), 'package.json'), 'utf8'));
|
|
116
|
+
if (pkg.name !== '@wjarka/cezarion' || pkg.version !== expected || !existsSync(join(scopedPath(plan), 'dist/index.js')) || !existsSync(join(scopedPath(plan), 'web/dist/index.html'))) {
|
|
117
|
+
throw new Error('promoted installation did not validate');
|
|
118
|
+
}
|
|
119
|
+
if (!existsSync(plan.installation.launchEntry))
|
|
120
|
+
throw new Error('original launch entry missing');
|
|
121
|
+
if (plan.installation.kind === 'npx') {
|
|
122
|
+
const root = JSON.parse(readFileSync(join(plan.installation.installRoot, 'package.json'), 'utf8'));
|
|
123
|
+
if (root._npx?.packages?.[0] !== plan.installation.request || root._npx.packages.length !== 1)
|
|
124
|
+
throw new Error('npx request metadata changed');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
export function manualRepairCommand(installation, version) {
|
|
128
|
+
if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(version))
|
|
129
|
+
throw new Error('invalid repair version');
|
|
130
|
+
const quote = (value) => `'${value.replaceAll("'", "'\\''")}'`;
|
|
131
|
+
const prefix = installation.kind === 'global' ? installation.prefix : installation.installRoot;
|
|
132
|
+
return `npm install ${installation.kind === 'global' ? '--global ' : ''}--prefix ${quote(prefix)} ${installation.outerPackage}@${version}`;
|
|
133
|
+
}
|
|
134
|
+
async function writeState(plan, state, repairCommand) {
|
|
135
|
+
const current = JSON.parse(await readFile(plan.recordPath, 'utf8'));
|
|
136
|
+
const temp = `${plan.recordPath}.${process.pid}.tmp`;
|
|
137
|
+
await writeFile(temp, JSON.stringify({ ...current, state, ownerPid: undefined, claimId: undefined,
|
|
138
|
+
startedAt: undefined, repairCommand }), { mode: 0o600 });
|
|
139
|
+
await rename(temp, plan.recordPath);
|
|
140
|
+
}
|
|
141
|
+
function alive(pid) {
|
|
142
|
+
try {
|
|
143
|
+
process.kill(pid, 0);
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
return false;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
async function waitExit(pid, timeoutMs) {
|
|
151
|
+
const until = Date.now() + timeoutMs;
|
|
152
|
+
while (alive(pid) && Date.now() < until)
|
|
153
|
+
await delay(100);
|
|
154
|
+
if (alive(pid))
|
|
155
|
+
throw new Error('old server did not exit');
|
|
156
|
+
}
|
|
157
|
+
export async function promoteOriginal(plan, npxLockAlreadyHeld = false, signal) {
|
|
158
|
+
const { installation } = plan;
|
|
159
|
+
const args = installation.kind === 'global'
|
|
160
|
+
? ['install', '--global', '--prefix', installation.prefix]
|
|
161
|
+
: ['install', '--prefix', installation.installRoot];
|
|
162
|
+
args.push('--engine-strict', '--no-audit', '--no-fund', '--ignore-scripts', '--prefer-online', '--fetch-retries=1', `${installation.outerPackage}@${plan.targetVersion}`);
|
|
163
|
+
const run = async () => {
|
|
164
|
+
await runOwnedNpm(plan.npmBin, args, { ...process.env, npm_config_cache: installation.cache }, signal);
|
|
165
|
+
};
|
|
166
|
+
if (installation.kind === 'npx' && !npxLockAlreadyHeld) {
|
|
167
|
+
await withDirectoryLock(join(installation.installRoot, 'concurrency.lock'), async (assertOwned, lockSignal) => { await promoteOriginal(plan, true, lockSignal); await assertOwned(); }, 30_000);
|
|
168
|
+
}
|
|
169
|
+
else
|
|
170
|
+
await run();
|
|
171
|
+
}
|
|
172
|
+
function launch(plan) {
|
|
173
|
+
const args = [...plan.nodeArgs, plan.installation.launchEntry, ...plan.cliArgs,
|
|
174
|
+
'--bind-host', plan.host, '--port', String(plan.port), '--repo', plan.repoRoot, '--no-open', '--restart-exact'];
|
|
175
|
+
return spawn(plan.nodeExecutable, args, { cwd: plan.cwd, env: process.env,
|
|
176
|
+
stdio: ['ignore', 'ignore', 'ignore', 'ipc'], detached: true });
|
|
177
|
+
}
|
|
178
|
+
async function verifyHealth(plan, expectedVersion, child, signal) {
|
|
179
|
+
// The private IPC channel belongs to this exact child. An unrelated healthy
|
|
180
|
+
// server on the port cannot send this acknowledgement.
|
|
181
|
+
await new Promise((resolve, reject) => {
|
|
182
|
+
let finished = false;
|
|
183
|
+
const timer = setTimeout(() => finish(new Error('replacement listener acknowledgement timed out')), 20_000);
|
|
184
|
+
const finish = (error) => {
|
|
185
|
+
if (finished)
|
|
186
|
+
return;
|
|
187
|
+
finished = true;
|
|
188
|
+
clearTimeout(timer);
|
|
189
|
+
child.off('message', onMessage);
|
|
190
|
+
child.off('exit', onExit);
|
|
191
|
+
child.off('error', onExit);
|
|
192
|
+
signal?.removeEventListener('abort', onAbort);
|
|
193
|
+
if (error)
|
|
194
|
+
reject(error);
|
|
195
|
+
else
|
|
196
|
+
resolve();
|
|
197
|
+
};
|
|
198
|
+
const onExit = () => finish(new Error('replacement exited before listener acknowledgement'));
|
|
199
|
+
const onAbort = () => finish(new Error('update lock ownership changed'));
|
|
200
|
+
const onMessage = (value) => {
|
|
201
|
+
const message = value;
|
|
202
|
+
if (message?.type !== 'application-update-listening')
|
|
203
|
+
return;
|
|
204
|
+
if (message.host !== plan.host || message.port !== plan.port || message.repoRoot !== plan.repoRoot || message.version !== expectedVersion) {
|
|
205
|
+
finish(new Error('replacement listener identity mismatch'));
|
|
206
|
+
return;
|
|
207
|
+
}
|
|
208
|
+
finish();
|
|
209
|
+
};
|
|
210
|
+
child.on('message', onMessage);
|
|
211
|
+
child.once('exit', onExit);
|
|
212
|
+
child.once('error', onExit);
|
|
213
|
+
signal?.addEventListener('abort', onAbort, { once: true });
|
|
214
|
+
if (signal?.aborted)
|
|
215
|
+
onAbort();
|
|
216
|
+
if (child.exitCode !== null)
|
|
217
|
+
onExit();
|
|
218
|
+
});
|
|
219
|
+
const until = Date.now() + 20_000;
|
|
220
|
+
while (Date.now() < until) {
|
|
221
|
+
if (signal?.aborted)
|
|
222
|
+
throw new Error('update lock ownership changed');
|
|
223
|
+
if (child.exitCode !== null)
|
|
224
|
+
throw new Error('replacement exited before health');
|
|
225
|
+
try {
|
|
226
|
+
const health = await requestRestartHealth(plan, signal ? AbortSignal.any([signal, AbortSignal.timeout(1000)]) : AbortSignal.timeout(1000));
|
|
227
|
+
if (health) {
|
|
228
|
+
if (health.version === expectedVersion && health.repoRoot === plan.repoRoot) {
|
|
229
|
+
if (child.connected)
|
|
230
|
+
child.disconnect();
|
|
231
|
+
child.unref();
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
throw new Error('health identity mismatch');
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
catch (error) {
|
|
238
|
+
if (error instanceof Error && error.message === 'health identity mismatch')
|
|
239
|
+
throw error;
|
|
240
|
+
}
|
|
241
|
+
await delay(150);
|
|
242
|
+
}
|
|
243
|
+
throw new Error('replacement health timed out');
|
|
244
|
+
}
|
|
245
|
+
async function reap(child) {
|
|
246
|
+
if (!child?.pid || child.exitCode !== null)
|
|
247
|
+
return;
|
|
248
|
+
process.kill(child.pid, 'SIGTERM');
|
|
249
|
+
try {
|
|
250
|
+
await waitExit(child.pid, 3000);
|
|
251
|
+
}
|
|
252
|
+
catch {
|
|
253
|
+
process.kill(child.pid, 'SIGKILL');
|
|
254
|
+
await waitExit(child.pid, 3000);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
export async function restoreOriginal(plan, assertOwned = async () => { }) {
|
|
258
|
+
const { installation } = plan;
|
|
259
|
+
const copy = async (from, to) => cp(from, to, { recursive: true, dereference: false,
|
|
260
|
+
filter: async () => { await assertOwned(); return true; } });
|
|
261
|
+
await assertOwned();
|
|
262
|
+
if (installation.kind === 'npx') {
|
|
263
|
+
// Preserve the live concurrency.lock directory while restoring the rest of
|
|
264
|
+
// the npx root. Removing the root would compromise our own npm lock.
|
|
265
|
+
for (const name of await readdir(installation.installRoot)) {
|
|
266
|
+
await assertOwned();
|
|
267
|
+
if (name !== 'concurrency.lock')
|
|
268
|
+
await rm(join(installation.installRoot, name), { recursive: true, force: true });
|
|
269
|
+
}
|
|
270
|
+
for (const name of await readdir(plan.recovery)) {
|
|
271
|
+
await assertOwned();
|
|
272
|
+
if (name !== 'concurrency.lock')
|
|
273
|
+
await copy(join(plan.recovery, name), join(installation.installRoot, name));
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else {
|
|
277
|
+
const outer = installation.outerRoot;
|
|
278
|
+
await assertOwned();
|
|
279
|
+
await rm(outer, { recursive: true, force: true });
|
|
280
|
+
await assertOwned();
|
|
281
|
+
await copy(plan.recovery, outer);
|
|
282
|
+
if (plan.binLinks) {
|
|
283
|
+
const links = JSON.parse(await readFile(plan.binLinks, 'utf8'));
|
|
284
|
+
for (const link of links) {
|
|
285
|
+
await assertOwned();
|
|
286
|
+
if (!/^[a-zA-Z0-9-]+$/.test(link.name))
|
|
287
|
+
throw new Error('invalid recovery bin name');
|
|
288
|
+
const path = join(installation.prefix, 'bin', link.name);
|
|
289
|
+
await rm(path, { force: true });
|
|
290
|
+
await symlink(link.target, path);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
await assertOwned();
|
|
295
|
+
validateOriginal(plan, plan.oldVersion);
|
|
296
|
+
}
|
|
297
|
+
export async function runHelper(plan, onArmed) {
|
|
298
|
+
restartHealthUrl(plan); // Reject an invalid destination before claiming or mutating the installation.
|
|
299
|
+
let replacement;
|
|
300
|
+
let transactionSignal;
|
|
301
|
+
const assertClaim = async () => {
|
|
302
|
+
const record = JSON.parse(await readFile(plan.recordPath, 'utf8'));
|
|
303
|
+
if (record?.state?.status !== 'restarting' || record.state.targetVersion !== plan.targetVersion || record.claimId !== plan.claimId) {
|
|
304
|
+
throw new Error('stale application update claim');
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
const io = {
|
|
308
|
+
waitForOldExit: () => waitExit(plan.oldPid, 20_000),
|
|
309
|
+
promote: () => promoteOriginal(plan, plan.installation.kind === 'npx', transactionSignal),
|
|
310
|
+
validateOriginal: async () => validateOriginal(plan, plan.targetVersion),
|
|
311
|
+
launch: async () => { replacement = launch(plan); },
|
|
312
|
+
verifyHealth: () => verifyHealth(plan, plan.targetVersion, replacement, transactionSignal),
|
|
313
|
+
reapReplacement: () => reap(replacement),
|
|
314
|
+
restore: () => restoreOriginal(plan, io.assertOwned),
|
|
315
|
+
launchPrevious: async () => { replacement = launch(plan); await verifyHealth(plan, plan.oldVersion, replacement, transactionSignal); },
|
|
316
|
+
reportSuccess: async () => {
|
|
317
|
+
await writeState(plan, { status: 'idle', supported: true });
|
|
318
|
+
// Keep the recovery copy until a later preparation has the lock. This
|
|
319
|
+
// avoids a crash gap between committing success and deleting recovery.
|
|
320
|
+
},
|
|
321
|
+
reportFailure: (rollbackFailed) => writeState(plan, {
|
|
322
|
+
status: 'error', supported: true, targetVersion: plan.targetVersion,
|
|
323
|
+
message: rollbackFailed ? 'Update and recovery failed. Reinstall cezarion manually.' : 'Update failed; previous release was restored. Retry Update.',
|
|
324
|
+
}, rollbackFailed ? manualRepairCommand(plan.installation, plan.oldVersion) : undefined),
|
|
325
|
+
};
|
|
326
|
+
await withDirectoryLock(join(dirname(plan.recordPath), 'operation.lock'), async (assertInstallationOwned, installationSignal) => {
|
|
327
|
+
const run = async (assertNpxOwned, npxSignal) => {
|
|
328
|
+
transactionSignal = npxSignal ? AbortSignal.any([installationSignal, npxSignal]) : installationSignal;
|
|
329
|
+
io.assertOwned = async () => {
|
|
330
|
+
await assertInstallationOwned();
|
|
331
|
+
await assertNpxOwned?.();
|
|
332
|
+
if (transactionSignal?.aborted)
|
|
333
|
+
throw new Error('update lock ownership changed');
|
|
334
|
+
await assertClaim();
|
|
335
|
+
};
|
|
336
|
+
await io.assertOwned();
|
|
337
|
+
const record = JSON.parse(await readFile(plan.recordPath, 'utf8'));
|
|
338
|
+
const ownerTemp = `${plan.recordPath}.${process.pid}.owner.tmp`;
|
|
339
|
+
await writeFile(ownerTemp, JSON.stringify({ ...record, ownerPid: process.pid }), { mode: 0o600 });
|
|
340
|
+
await io.assertOwned();
|
|
341
|
+
await rename(ownerTemp, plan.recordPath);
|
|
342
|
+
await io.assertOwned();
|
|
343
|
+
onArmed?.();
|
|
344
|
+
await runRestartWorkflow(io);
|
|
345
|
+
};
|
|
346
|
+
if (plan.installation.kind === 'npx') {
|
|
347
|
+
await withDirectoryLock(join(plan.installation.installRoot, 'concurrency.lock'), run, 30_000);
|
|
348
|
+
}
|
|
349
|
+
else
|
|
350
|
+
await run();
|
|
351
|
+
}, 30_000);
|
|
352
|
+
}
|
|
353
|
+
if (process.send && process.argv[2] === '--application-update-helper') {
|
|
354
|
+
process.once('message', (message) => {
|
|
355
|
+
const plan = message;
|
|
356
|
+
void runHelper(plan, () => process.send?.({ type: 'armed' }, () => process.disconnect?.()))
|
|
357
|
+
.catch(() => process.exit(1));
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
//# sourceMappingURL=helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helper.js","sourceRoot":"","sources":["../../src/application-update/helper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,IAAI,EAAoB,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,KAAK,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAwBtF,8EAA8E;AAC9E,MAAM,UAAU,eAAe,CAAC,OAAoC;IAClE,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,GAAG,CAAC,IAAI,OAAO,CAAC,IAAI,GAAG,KAAK;WACrH,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,CAAC,EAAE,CAAC;QAC5G,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAA2C;IAC1E,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;IACpG,OAAO,UAAU,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,IAAI,gBAAgB,CAAC;AACnF,CAAC;AAED,qFAAqF;AACrF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,QAA2C,EAAE,MAAmB;IACzG,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;IAC1B,IAAI,CAAC;QACH,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,MAAM,OAAO,GAAG,GAAG,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,QAAQ,EAAE,EAAE;gBAC9E,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC/B,IAAI,CAAC,QAAQ,CAAC,UAAU,IAAI,QAAQ,CAAC,UAAU,GAAG,GAAG,IAAI,QAAQ,CAAC,UAAU,IAAI,GAAG,EAAE,CAAC;oBACpF,QAAQ,CAAC,MAAM,EAAE,CAAC;oBAAC,OAAO,CAAC,SAAS,CAAC,CAAC;oBAAC,OAAO;gBAChD,CAAC;gBACD,IAAI,IAAI,GAAG,EAAE,CAAC;gBACd,QAAQ,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;gBAC7B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE,GAAG,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3D,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE;oBACxB,IAAI,CAAC;wBAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4C,CAAC,CAAC;oBAAC,CAAC;oBAC7E,OAAO,KAAK,EAAE,CAAC;wBAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBAAC,CAAC;gBAClC,CAAC,CAAC,CAAC;YACL,CAAC,CAAC,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;IACL,CAAC;YAAS,CAAC;QAAC,KAAK,CAAC,OAAO,EAAE,CAAC;IAAC,CAAC;AAChC,CAAC;AAgBD,4FAA4F;AAC5F,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,EAAa;IACpD,MAAM,EAAE,CAAC,cAAc,EAAE,CAAC;IAC1B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;IACzB,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;QACnB,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,EAAE,CAAC,gBAAgB,EAAE,CAAC;QAC5B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC;QAClB,mBAAmB,GAAG,IAAI,CAAC;QAC3B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,EAAE,CAAC,YAAY,EAAE,CAAC;QACxB,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,EAAE,CAAC,aAAa,EAAE,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,mBAAmB,EAAE,CAAC;YACxB,IAAI,CAAC;gBAAC,MAAM,EAAE,CAAC,eAAe,EAAE,CAAC;YAAC,CAAC;YACnC,MAAM,CAAC;gBACL,oEAAoE;gBACpE,gDAAgD;gBAChD,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;gBACzB,MAAM,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;gBAC7B,OAAO;YACT,CAAC;QACH,CAAC;QACD,yEAAyE;QACzE,wEAAwE;QACxE,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,IAAI,cAAc,GAAG,KAAK,CAAC;QAC3B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,EAAE,CAAC,OAAO,EAAE,CAAC;YACnB,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,MAAM,EAAE,CAAC,cAAc,EAAE,CAAC;YAC1B,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAClD,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACzB,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;QACD,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;QACzB,MAAM,EAAE,CAAC,aAAa,CAAC,cAAc,CAAC,CAAC;IACzC,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAAgB;IAClC,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,KAAK,kBAAkB;QAAE,OAAO,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;IAChG,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,+BAA+B,CAAC,CAAC;IAClF,IAAI,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,cAAc,CAAC;QACpG,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;IACzC,OAAO,IAAI,CAAC,OAAO,EAAE,kBAAkB,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAgB,EAAE,QAAgB;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAsE,CAAC;IAC1J,IAAI,GAAG,CAAC,IAAI,KAAK,kBAAkB,IAAI,GAAG,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,qBAAqB,CAAC,CAAC,EAAE,CAAC;QACtL,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;IAC5D,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;IACjG,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACrC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAuC,CAAC;QACzI,IAAI,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,YAAY,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACjJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,YAAkG,EAAE,OAAe;IACrJ,IAAI,CAAC,qCAAqC,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IACpG,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,OAAO,CAAC,GAAG,CAAC;IACvE,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,WAAW,CAAC;IAC/F,OAAO,eAAe,YAAY,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,YAAY,KAAK,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC,YAAY,IAAI,OAAO,EAAE,CAAC;AAC7I,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAgB,EAAE,KAAuF,EAAE,aAAsB;IACzJ,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAA4B,CAAC;IAC/F,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,MAAM,CAAC;IACrD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS;QAC/F,SAAS,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,MAAM,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,KAAK,CAAC,GAAW;IACxB,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,KAAK,CAAC;IAAC,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,QAAQ,CAAC,GAAW,EAAE,SAAiB;IACpD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACrC,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;QAAE,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1D,IAAI,KAAK,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAgB,EAAE,kBAAkB,GAAG,KAAK,EAAE,MAAoB;IACtG,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC9B,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,KAAK,QAAQ;QACzC,CAAC,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,CAAC,MAAM,CAAC;QAC1D,CAAC,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,WAAW,CAAC,CAAC;IACtD,IAAI,CAAC,IAAI,CAAC,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,GAAG,YAAY,CAAC,YAAY,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1K,MAAM,GAAG,GAAG,KAAK,IAAI,EAAE;QACrB,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,gBAAgB,EAAE,YAAY,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;IACzG,CAAC,CAAC;IACF,IAAI,YAAY,CAAC,IAAI,KAAK,KAAK,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACvD,MAAM,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,EAAE,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,MAAM,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;IAClM,CAAC;;QAAM,MAAM,GAAG,EAAE,CAAC;AACrB,CAAC;AAED,SAAS,MAAM,CAAC,IAAgB;IAC9B,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,OAAO;QAC5E,aAAa,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC;IAClH,OAAO,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG;QACvE,KAAK,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,IAAgB,EAAE,eAAuB,EAAE,KAA+B,EAAE,MAAoB;IAC1H,4EAA4E;IAC5E,uDAAuD;IACvD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5G,MAAM,MAAM,GAAG,CAAC,KAAa,EAAE,EAAE;YAC/B,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,KAAK,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACvF,MAAM,EAAE,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC9C,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;gBAAM,OAAO,EAAE,CAAC;QAC3C,CAAC,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC,CAAC;QAC7F,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAC;QACzE,MAAM,SAAS,GAAG,CAAC,KAAc,EAAE,EAAE;YACnC,MAAM,OAAO,GAAG,KAA6F,CAAC;YAC9G,IAAI,OAAO,EAAE,IAAI,KAAK,8BAA8B;gBAAE,OAAO;YAC7D,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,IAAI,OAAO,CAAC,OAAO,KAAK,eAAe,EAAE,CAAC;gBAC1I,MAAM,CAAC,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC,CAAC;gBAAC,OAAO;YACtE,CAAC;YACD,MAAM,EAAE,CAAC;QACX,CAAC,CAAC;QACF,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QACxF,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,IAAI,MAAM,EAAE,OAAO;YAAE,OAAO,EAAE,CAAC;QAC/B,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;YAAE,MAAM,EAAE,CAAC;IACxC,CAAC,CAAC,CAAC;IACH,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC;IAClC,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,CAAC;QAC1B,IAAI,MAAM,EAAE,OAAO;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACtE,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;QACjF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;YAC3I,IAAI,MAAM,EAAE,CAAC;gBACX,IAAI,MAAM,CAAC,OAAO,KAAK,eAAe,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,EAAE,CAAC;oBAC5E,IAAI,KAAK,CAAC,SAAS;wBAAE,KAAK,CAAC,UAAU,EAAE,CAAC;oBACxC,KAAK,CAAC,KAAK,EAAE,CAAC;oBAAC,OAAO;gBACxB,CAAC;gBACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,0BAA0B;gBAAE,MAAM,KAAK,CAAC;QAC1F,CAAC;QACD,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;AAClD,CAAC;AAED,KAAK,UAAU,IAAI,CAAC,KAA2C;IAC7D,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,KAAK,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO;IACnD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACnC,IAAI,CAAC;QAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAAC,CAAC;IACxC,MAAM,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAAC,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAAC,CAAC;AAChF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAgB,EAAE,WAAW,GAAwB,KAAK,IAAI,EAAE,GAAE,CAAC;IACvG,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAC9B,MAAM,IAAI,GAAG,KAAK,EAAE,IAAY,EAAE,EAAU,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK;QACjG,MAAM,EAAE,KAAK,IAAI,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/D,MAAM,WAAW,EAAE,CAAC;IACpB,IAAI,YAAY,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QAChC,2EAA2E;QAC3E,qEAAqE;QACrE,KAAK,MAAM,IAAI,IAAI,MAAM,OAAO,CAAC,YAAY,CAAC,WAAW,CAAC,EAAE,CAAC;YAC3D,MAAM,WAAW,EAAE,CAAC;YACpB,IAAI,IAAI,KAAK,kBAAkB;gBAAE,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpH,CAAC;QACD,KAAK,MAAM,IAAI,IAAI,MAAM,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChD,MAAM,WAAW,EAAE,CAAC;YACpB,IAAI,IAAI,KAAK,kBAAkB;gBAAE,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;QAC/G,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,YAAY,CAAC,SAAS,CAAC;QACrC,MAAM,WAAW,EAAE,CAAC;QACpB,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,WAAW,EAAE,CAAC;QACpB,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACjC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAA4C,CAAC;YAC3G,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,WAAW,EAAE,CAAC;gBACpB,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;gBACrF,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBACzD,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAChC,MAAM,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,WAAW,EAAE,CAAC;IACpB,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAgB,EAAE,OAAoB;IACpE,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,8EAA8E;IACtG,IAAI,WAAiD,CAAC;IACtD,IAAI,iBAA0C,CAAC;IAC/C,MAAM,WAAW,GAAG,KAAK,IAAmB,EAAE;QAC5C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAA8E,CAAC;QAChJ,IAAI,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,YAAY,IAAI,MAAM,CAAC,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC,aAAa,IAAI,MAAM,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YACnI,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IACF,MAAM,EAAE,GAAc;QACpB,cAAc,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;QACnD,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,KAAK,EAAE,iBAAiB,CAAC;QACzF,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,CAAC;QACxE,MAAM,EAAE,KAAK,IAAI,EAAE,GAAG,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACnD,YAAY,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,aAAa,EAAE,WAAY,EAAE,iBAAiB,CAAC;QAC3F,eAAe,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC;QACxC,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC;QACpD,cAAc,EAAE,KAAK,IAAI,EAAE,GAAG,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,IAAI,CAAC,UAAU,EAAE,WAAW,EAAE,iBAAiB,CAAC,CAAC,CAAC,CAAC;QACtI,aAAa,EAAE,KAAK,IAAI,EAAE;YACxB,MAAM,UAAU,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC5D,sEAAsE;YACtE,uEAAuE;QACzE,CAAC;QACD,aAAa,EAAE,CAAC,cAAc,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,EAAE;YAClD,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,CAAC,aAAa;YACnE,OAAO,EAAE,cAAc,CAAC,CAAC,CAAC,0DAA0D,CAAC,CAAC,CAAC,6DAA6D;SACrJ,EAAE,cAAc,CAAC,CAAC,CAAC,mBAAmB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;KACzF,CAAC;IACF,MAAM,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,gBAAgB,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,EAAE;QAC9H,MAAM,GAAG,GAAG,KAAK,EAAE,cAAoC,EAAE,SAAuB,EAAE,EAAE;YAClF,iBAAiB,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,kBAAkB,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC;YACtG,EAAE,CAAC,WAAW,GAAG,KAAK,IAAI,EAAE;gBAC1B,MAAM,uBAAuB,EAAE,CAAC;gBAChC,MAAM,cAAc,EAAE,EAAE,CAAC;gBACzB,IAAI,iBAAiB,EAAE,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;gBACjF,MAAM,WAAW,EAAE,CAAC;YACtB,CAAC,CAAC;YACF,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAA4B,CAAC;YAC9F,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,YAAY,CAAC;YAChE,MAAM,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;YAClG,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;YACvB,MAAM,MAAM,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;YACzC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC;YACvB,OAAO,EAAE,EAAE,CAAC;YACZ,MAAM,kBAAkB,CAAC,EAAE,CAAC,CAAC;QAC/B,CAAC,CAAC;QACF,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACrC,MAAM,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAChG,CAAC;;YAAM,MAAM,GAAG,EAAE,CAAC;IACrB,CAAC,EAAE,MAAM,CAAC,CAAC;AACb,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,6BAA6B,EAAE,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;QAClC,MAAM,IAAI,GAAG,OAAqB,CAAC;QACnC,KAAK,SAAS,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;aACxF,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { RestartPlan } from './service.ts';
|
|
2
|
+
/** Copy the helper out of the package npm will replace; pass credentials only via inherited env. */
|
|
3
|
+
export declare function armRestartHelper(plan: RestartPlan, launch: {
|
|
4
|
+
repoRoot: string;
|
|
5
|
+
host: string;
|
|
6
|
+
port: number;
|
|
7
|
+
npmBin: string;
|
|
8
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { copyFile, mkdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { assertCezarHomeWriteIsSandboxed } from '../paths.js';
|
|
6
|
+
/** Copy the helper out of the package npm will replace; pass credentials only via inherited env. */
|
|
7
|
+
export async function armRestartHelper(plan, launch) {
|
|
8
|
+
const source = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const target = join(dirname(plan.recordPath), 'helper');
|
|
10
|
+
assertCezarHomeWriteIsSandboxed(target);
|
|
11
|
+
await mkdir(target, { recursive: true, mode: 0o700 });
|
|
12
|
+
await copyFile(join(source, 'helper.js'), join(target, 'helper.js'));
|
|
13
|
+
await copyFile(join(source, 'lock.js'), join(target, 'lock.js'));
|
|
14
|
+
await copyFile(join(source, 'npm-process.js'), join(target, 'npm-process.js'));
|
|
15
|
+
await writeFile(join(target, 'package.json'), '{"type":"module"}', { mode: 0o600 });
|
|
16
|
+
const child = spawn(process.execPath, [join(target, 'helper.js'), '--application-update-helper'], {
|
|
17
|
+
cwd: process.cwd(), env: process.env, detached: true, stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
|
|
18
|
+
});
|
|
19
|
+
if (!child.pid)
|
|
20
|
+
throw new Error('restart helper did not start');
|
|
21
|
+
const message = {
|
|
22
|
+
...plan, oldPid: process.pid, nodeExecutable: process.execPath, nodeArgs: process.execArgv,
|
|
23
|
+
cliArgs: process.argv.slice(2), cwd: process.cwd(), repoRoot: launch.repoRoot,
|
|
24
|
+
host: launch.host, port: launch.port, npmBin: launch.npmBin,
|
|
25
|
+
};
|
|
26
|
+
await new Promise((resolve, reject) => {
|
|
27
|
+
let settled = false;
|
|
28
|
+
const fail = (error) => {
|
|
29
|
+
if (settled)
|
|
30
|
+
return;
|
|
31
|
+
settled = true;
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
child.kill('SIGTERM');
|
|
34
|
+
reject(error);
|
|
35
|
+
};
|
|
36
|
+
const timer = setTimeout(() => fail(new Error('restart helper did not acknowledge')), 35_000);
|
|
37
|
+
child.once('error', (error) => fail(error));
|
|
38
|
+
child.once('exit', () => fail(new Error('restart helper exited before acknowledgement')));
|
|
39
|
+
child.on('message', (response) => {
|
|
40
|
+
if (response?.type !== 'armed' || settled)
|
|
41
|
+
return;
|
|
42
|
+
settled = true;
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
child.unref();
|
|
45
|
+
resolve();
|
|
46
|
+
});
|
|
47
|
+
child.send(message, (error) => { if (error)
|
|
48
|
+
fail(error); });
|
|
49
|
+
});
|
|
50
|
+
return child.pid;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=launcher.js.map
|