@timurproko/a1 0.1.8-dev.134 → 0.1.8-dev.136

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/bin/cli.js CHANGED
@@ -11,12 +11,23 @@ const capabilities = cliCapabilities(JSON.parse(await readFile(new URL("package.
11
11
 
12
12
  process.exitCode = await dispatchCli(process.argv.slice(2), {
13
13
  launch: async intent => {
14
- const [{ prepareInteractiveLaunch }, { runBootstrap }] = await Promise.all([
14
+ const [{ prepareInteractiveLaunch }, { runBootstrap }, { healModuleIdentityAtLaunch, releaseCopyIsLaunchable }] = await Promise.all([
15
15
  import("../dist/features/launch/index.js"),
16
16
  import("../dist/foundation/release/index.js"),
17
+ import("./module-identity.js"),
17
18
  ]);
19
+ // Self-heal the installed tree before the release store copies it: npm 12
20
+ // blocks install scripts by default, so the postinstall that normally
21
+ // repairs module identity may never have run (see bin/module-identity.js).
22
+ const packageRootPath = fileURLToPath(packageRoot);
23
+ await healModuleIdentityAtLaunch(packageRootPath, message => process.stderr.write(message));
18
24
  const prepared = await prepareInteractiveLaunch(intent);
19
- return await runBootstrap({ packageRoot: fileURLToPath(packageRoot), launchIntent: intent, environment: prepared.environment });
25
+ return await runBootstrap({
26
+ packageRoot: packageRootPath,
27
+ launchIntent: intent,
28
+ environment: prepared.environment,
29
+ releaseIsLaunchable: releaseCopyIsLaunchable,
30
+ });
20
31
  },
21
32
  version: async () => {
22
33
  const { runVersionStats } = await import("../dist/cli/index.js");
@@ -132,6 +132,29 @@ function message(error) {
132
132
  return error instanceof Error ? error.message : String(error);
133
133
  }
134
134
 
135
+ /**
136
+ * Launch-entry self-heal: when A1 and pinned Pi disagree on the terminal
137
+ * module, rewrite the proxy to the copy Pi resolves before anything copies
138
+ * this tree. npm 12 blocks install scripts unless allowScripts covers the
139
+ * package, so the postinstall that normally rewrites the proxy may never
140
+ * have run and the installed tree may still carry the published placeholder
141
+ * path. Named neutrally so the launch entries that call it stay free of
142
+ * terminal implementation identifiers, as the bootstrap boundary requires.
143
+ */
144
+ export async function healModuleIdentityAtLaunch(packageRoot, warn) {
145
+ if (inspectPiTuiModuleIdentity(packageRoot).kind === "unified") return;
146
+ const { syncPiTuiProxy } = await import("./sync-pi-tui-proxy.js");
147
+ const outcome = syncPiTuiProxy(packageRoot);
148
+ if (outcome.kind === "unresolved") {
149
+ warn(`a1: could not point the terminal module proxy at pinned Pi's copy (${outcome.message}); extension UI may not render.\n`);
150
+ }
151
+ }
152
+
153
+ /** Whether a materialized release copy resolves one terminal module for both A1 and Pi. */
154
+ export function releaseCopyIsLaunchable(releaseRoot) {
155
+ return inspectPiTuiModuleIdentity(releaseRoot).kind === "unified";
156
+ }
157
+
135
158
  /** Launch-entry wrapper: warn on stderr when the two sides disagree. */
136
159
  export function assertSinglePiTuiModuleAtLaunch(packageRoot, warn) {
137
160
  const outcome = inspectPiTuiModuleIdentity(packageRoot);
@@ -13,6 +13,16 @@ export interface BootstrapOptions {
13
13
  };
14
14
  readonly environment?: NodeJS.ProcessEnv;
15
15
  readonly output?: Pick<NodeJS.WriteStream, "write">;
16
+ /**
17
+ * Whether a materialized release copy is fit to launch. The active release
18
+ * is normally reused while its version matches the installation, but a copy
19
+ * can be broken in ways a version cannot see — materialized from a tree a
20
+ * blocked postinstall never finished repairing. The probe is injected from
21
+ * the bin entry because deciding it requires inspecting dependency
22
+ * resolution, which stays out of production code. Absent means every
23
+ * release is fit.
24
+ */
25
+ readonly releaseIsLaunchable?: (releaseRoot: string) => boolean;
16
26
  }
17
27
  export declare function runBootstrap(options: BootstrapOptions): Promise<number>;
18
28
  export declare function certifyMaterializedRelease(release: MaterializedRelease, dataDir: string, verification?: VerifyMaterializedReleaseOptions): Promise<string>;
@@ -46,7 +46,11 @@ export async function runBootstrap(options) {
46
46
  const installedVersion = await readInstalledVersion(options.packageRoot);
47
47
  const activeId = state.references.active;
48
48
  const active = activeId === null ? undefined : state.releases[activeId];
49
- if (active?.approval === "approved" && active.packageVersion === installedVersion) {
49
+ const activeIsLaunchable = active === undefined || (options.releaseIsLaunchable?.(active.releaseRoot) ?? true);
50
+ if (active !== undefined && !activeIsLaunchable) {
51
+ output.write(`${PRODUCT_TEXT.diagnostic(`retired release ${active.releaseId} because its copy is not launchable; rebuilding from the installed package.`)}\n`);
52
+ }
53
+ if (activeIsLaunchable && active?.approval === "approved" && active.packageVersion === installedVersion) {
50
54
  const endpointMatches = endpoint?.releaseId === active.releaseId
51
55
  && endpoint.releaseRoot === active.releaseRoot
52
56
  && endpoint.contentDigest === active.contentDigest;
@@ -403,6 +403,19 @@ export async function runSelfUpdate(options) {
403
403
  }
404
404
  transaction = await transactionStore.advance("package-installed");
405
405
  }
406
+ // npm 12 blocks install scripts unless allowScripts covers the package, so
407
+ // the postinstall that points the #pi-tui proxy at the tree npm just built
408
+ // may never have run. Run the shipped script directly: the proxy must be
409
+ // correct before the release store copies this tree. A failure is reported
410
+ // and left to the launch-time self-heal rather than failing the update.
411
+ try {
412
+ const proxySync = await runner(process.execPath, [resolve(packageRoot, "bin", "sync-pi-tui-proxy.js")], { captureStdout: true });
413
+ if (proxySync.code !== 0)
414
+ output.stderr(`${PRODUCT_TEXT.diagnostic(`could not point the #pi-tui proxy at the installed tree (exited ${formatExitCode(proxySync.code)}).`)}\n`);
415
+ }
416
+ catch (error) {
417
+ output.stderr(`${PRODUCT_TEXT.diagnostic(`could not point the #pi-tui proxy at the installed tree: ${errorMessage(error)}`)}\n`);
418
+ }
406
419
  progress.set(70, 75);
407
420
  // Ownership can be reacquired after an interrupted installation (for
408
421
  // example, if bare A1 is launched before the update is resumed). Recheck
@@ -5,7 +5,7 @@
5
5
  "platform": "darwin",
6
6
  "architecture": "arm64",
7
7
  "capability": "unsupported",
8
- "builtAt": "2026-08-25T18:22:19.065Z",
8
+ "builtAt": "2026-08-26T05:59:16.405Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian",
11
11
  "sha256": "7524bf568992517f50ed53196c861c5edeba0d7275633bb4735ab45bd5963a28",
@@ -5,11 +5,11 @@
5
5
  "platform": "linux",
6
6
  "architecture": "x64",
7
7
  "capability": "supported",
8
- "builtAt": "2026-08-25T18:22:33.863Z",
8
+ "builtAt": "2026-08-26T05:59:26.040Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian",
11
- "sha256": "ee8a00eaaf79c707459bbbfb52518e9739314967049fbe5fa625f36ce33db9ee",
12
- "size": 414568
11
+ "sha256": "29e22fe29de2828982bc67ef418c4adcaab1490281477b7bea592ec6fe621bcd",
12
+ "size": 415696
13
13
  },
14
14
  "provenance": {
15
15
  "language": "Rust",
@@ -5,10 +5,10 @@
5
5
  "platform": "win32",
6
6
  "architecture": "x64",
7
7
  "capability": "supported",
8
- "builtAt": "2026-08-25T18:23:18.046Z",
8
+ "builtAt": "2026-08-26T05:59:44.317Z",
9
9
  "artifact": {
10
10
  "filename": "process-guardian.exe",
11
- "sha256": "2f13a4c73ed082a13cf9947be6f363c3c800eaf40e22ea9ae4674299d7f51cdd",
11
+ "sha256": "f36f8c76d82ce8e3d163c7671868bd0ab8b7bc1e14a190714aaeb304b2116a5b",
12
12
  "size": 172544
13
13
  },
14
14
  "provenance": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@timurproko/a1",
3
- "version": "0.1.8-dev.134",
3
+ "version": "0.1.8-dev.136",
4
4
  "description": "Standalone terminal workspace for supervised native and managed agents",
5
5
  "type": "module",
6
6
  "packageManager": "npm@11.13.0",