@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.
@@ -5,7 +5,7 @@
5
5
  "platform": "darwin",
6
6
  "architecture": "arm64",
7
7
  "capability": "unsupported",
8
- "builtAt": "2026-08-23T14:26:10.351Z",
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:26:49.615Z",
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:26:50.453Z",
8
+ "builtAt": "2026-08-23T14:55:13.661Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian.exe",
11
- "sha256": "1073746062839c69cc4de5df47cc2eecc9211f26e80518395b2987f958c86a02",
11
+ "sha256": "068b70d85658579b34c845f742cd9e209239f4b93fcfb4d39962fd1d4d19d226",
12
12
  "size": 172544
13
13
  },
14
14
  "provenance": {
@@ -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>): 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
- const candidate = await materializeRelease(packageRoot, paths.dataDir);
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: 85, creepTo: 90 },
128
- certified: { at: 90, creepTo: 95 },
129
- "active-reference-committed": { at: 95, creepTo: 99 },
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 - 0.5, current + (creepTo - current) * 0.04);
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, 85);
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();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurproko/a1",
3
- "version": "0.1.1-dev.13",
3
+ "version": "0.1.1-dev.14",
4
4
  "description": "Standalone terminal workspace for supervised native and managed agents",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.13.0",