@timurproko/a1 0.1.1-dev.13 → 0.1.1-dev.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/native/darwin-arm64/manifest.json +1 -1
- package/dist/native/linux-x64/manifest.json +1 -1
- package/dist/native/win32-x64/manifest.json +2 -2
- package/dist/native/win32-x64/process-guardian.exe +0 -0
- package/dist/src/foundation/release/update.d.ts +10 -1
- package/dist/src/foundation/release/update.js +34 -8
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"platform": "darwin",
|
|
6
6
|
"architecture": "arm64",
|
|
7
7
|
"capability": "unsupported",
|
|
8
|
-
"builtAt": "2026-08-23T14:
|
|
8
|
+
"builtAt": "2026-08-23T14:54:52.984Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian",
|
|
11
11
|
"sha256": "7524bf568992517f50ed53196c861c5edeba0d7275633bb4735ab45bd5963a28",
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"platform": "linux",
|
|
6
6
|
"architecture": "x64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-08-23T14:
|
|
8
|
+
"builtAt": "2026-08-23T14:54:49.534Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian",
|
|
11
11
|
"sha256": "29e22fe29de2828982bc67ef418c4adcaab1490281477b7bea592ec6fe621bcd",
|
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
"platform": "win32",
|
|
6
6
|
"architecture": "x64",
|
|
7
7
|
"capability": "supported",
|
|
8
|
-
"builtAt": "2026-08-23T14:
|
|
8
|
+
"builtAt": "2026-08-23T14:55:13.661Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian.exe",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "068b70d85658579b34c845f742cd9e209239f4b93fcfb4d39962fd1d4d19d226",
|
|
12
12
|
"size": 172544
|
|
13
13
|
},
|
|
14
14
|
"provenance": {
|
|
Binary file
|
|
@@ -44,13 +44,22 @@ export interface SelfUpdateOptions {
|
|
|
44
44
|
now?: () => number;
|
|
45
45
|
}
|
|
46
46
|
export type UpdateActivationPhase = Extract<UpdateTransactionPhase, "materialized" | "certified" | "active-reference-committed">;
|
|
47
|
+
/**
|
|
48
|
+
* Copying the release is the longest step with nothing to say for itself, so it
|
|
49
|
+
* reports the files it has written against the files it must write. A caller that
|
|
50
|
+
* shows progress can then move with the work instead of guessing at it.
|
|
51
|
+
*/
|
|
52
|
+
export interface UpdateMaterializationProgress {
|
|
53
|
+
readonly completed: number;
|
|
54
|
+
readonly total: number;
|
|
55
|
+
}
|
|
47
56
|
export interface UpdateLifecycleCoordinator {
|
|
48
57
|
targetIsActive(targetVersion: string): Promise<boolean>;
|
|
49
58
|
shutdownVerifiedOwners(targetVersion: string): Promise<{
|
|
50
59
|
priorActiveVersion: string | null;
|
|
51
60
|
}>;
|
|
52
61
|
verifyPackageUnlocked(packageRoot: string): Promise<void>;
|
|
53
|
-
activateInstalled(packageRoot: string, targetVersion: string, phase: (phase: UpdateActivationPhase) => Promise<void
|
|
62
|
+
activateInstalled(packageRoot: string, targetVersion: string, phase: (phase: UpdateActivationPhase) => Promise<void>, onMaterializing?: (progress: UpdateMaterializationProgress) => void): Promise<void>;
|
|
54
63
|
}
|
|
55
64
|
export interface UpdateTransactionJournal {
|
|
56
65
|
readonly path: string;
|
|
@@ -105,8 +105,21 @@ export function createUpdateLifecycleCoordinator(environment = process.env, file
|
|
|
105
105
|
throw new Error(PRODUCT_TEXT.diagnostic(`package remains locked after verified shutdown: ${errorMessage(error)}`));
|
|
106
106
|
}
|
|
107
107
|
},
|
|
108
|
-
async activateInstalled(packageRoot, targetVersion, phase) {
|
|
109
|
-
|
|
108
|
+
async activateInstalled(packageRoot, targetVersion, phase, onMaterializing) {
|
|
109
|
+
let total = 0;
|
|
110
|
+
let completed = 0;
|
|
111
|
+
const candidate = await materializeRelease(packageRoot, paths.dataDir, {
|
|
112
|
+
onProgress: event => {
|
|
113
|
+
total = event.fileCount;
|
|
114
|
+
onMaterializing?.({ completed, total });
|
|
115
|
+
},
|
|
116
|
+
onOperation: event => {
|
|
117
|
+
if (event.operation !== "candidate-write")
|
|
118
|
+
return;
|
|
119
|
+
completed += 1;
|
|
120
|
+
onMaterializing?.({ completed, total });
|
|
121
|
+
},
|
|
122
|
+
});
|
|
110
123
|
if (candidate.packageVersion !== targetVersion)
|
|
111
124
|
throw new Error(`installed ${PRODUCT_TEXT.displayName} version ${candidate.packageVersion} does not match target ${targetVersion}`);
|
|
112
125
|
await stateStore.recordCandidate(candidate);
|
|
@@ -123,10 +136,16 @@ export function createUpdateLifecycleCoordinator(environment = process.env, file
|
|
|
123
136
|
}
|
|
124
137
|
const PROGRESS_BAR_WIDTH = 39;
|
|
125
138
|
const PROGRESS_TICK_MS = 200;
|
|
139
|
+
/**
|
|
140
|
+
* Copying the release owns 78–92 and is reported file by file, so the bar crosses
|
|
141
|
+
* that span with the work rather than parking at its start. What follows is short,
|
|
142
|
+
* which is why the remaining milestones sit close together.
|
|
143
|
+
*/
|
|
144
|
+
const MATERIALIZE_PROGRESS = Object.freeze({ from: 78, to: 92 });
|
|
126
145
|
const ACTIVATION_PROGRESS = {
|
|
127
|
-
materialized: { at:
|
|
128
|
-
certified: { at:
|
|
129
|
-
"active-reference-committed": { at:
|
|
146
|
+
materialized: { at: 92, creepTo: 94 },
|
|
147
|
+
certified: { at: 94, creepTo: 96 },
|
|
148
|
+
"active-reference-committed": { at: 96, creepTo: 99 },
|
|
130
149
|
};
|
|
131
150
|
function renderProgressBar(percent) {
|
|
132
151
|
const bounded = Math.min(100, Math.max(0, Math.round(percent)));
|
|
@@ -163,9 +182,12 @@ function createUpdateProgress(output, enabled) {
|
|
|
163
182
|
if (creepTo <= current)
|
|
164
183
|
return;
|
|
165
184
|
// Creep asymptotically toward (but never reach) the next milestone so
|
|
166
|
-
// long opaque phases such as npm install still show visible motion.
|
|
185
|
+
// long opaque phases such as npm install still show visible motion. The
|
|
186
|
+
// ceiling stays a whole point below the milestone: settling on `creepTo`
|
|
187
|
+
// itself would render as that milestone and make arriving at it invisible,
|
|
188
|
+
// which is what a stalled bar looks like.
|
|
167
189
|
timer = setInterval(() => {
|
|
168
|
-
current = Math.min(creepTo -
|
|
190
|
+
current = Math.min(creepTo - 1, current + (creepTo - current) * 0.04);
|
|
169
191
|
draw();
|
|
170
192
|
}, PROGRESS_TICK_MS);
|
|
171
193
|
timer.unref?.();
|
|
@@ -293,13 +315,17 @@ export async function runSelfUpdate(options) {
|
|
|
293
315
|
// example, if bare A1 is launched before the update is resumed). Recheck
|
|
294
316
|
// immediately before activation so recovery cannot start a second cohort.
|
|
295
317
|
await measure("ownership-release", async () => { await lifecycle.shutdownVerifiedOwners(targetVersion); });
|
|
296
|
-
progress.set(75,
|
|
318
|
+
progress.set(75, MATERIALIZE_PROGRESS.from);
|
|
297
319
|
let activationPhaseStartedAt = now();
|
|
298
320
|
await lifecycle.activateInstalled(packageRoot, targetVersion, async (phase) => {
|
|
299
321
|
options.onPhaseTiming?.({ phase, durationMs: Math.max(0, now() - activationPhaseStartedAt) });
|
|
300
322
|
transaction = await transactionStore.advance(phase);
|
|
301
323
|
progress.set(ACTIVATION_PROGRESS[phase].at, ACTIVATION_PROGRESS[phase].creepTo);
|
|
302
324
|
activationPhaseStartedAt = now();
|
|
325
|
+
}, ({ completed, total }) => {
|
|
326
|
+
const span = MATERIALIZE_PROGRESS.to - MATERIALIZE_PROGRESS.from;
|
|
327
|
+
const done = total > 0 ? Math.min(1, completed / total) : 0;
|
|
328
|
+
progress.set(MATERIALIZE_PROGRESS.from + span * done);
|
|
303
329
|
});
|
|
304
330
|
options.onPhaseTiming?.({ phase: "supervisor-verified", durationMs: Math.max(0, now() - activationPhaseStartedAt) });
|
|
305
331
|
const transactionStartedAt = now();
|