@timurproko/a1 0.1.8-dev.132 → 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 +13 -2
- package/bin/module-identity.js +24 -1
- package/bin/pi-tui.d.ts +1 -1
- package/bin/pi-tui.js +8 -4
- package/bin/sync-pi-tui-proxy.js +97 -0
- package/dist/cli/version-stats.d.ts +6 -0
- package/dist/cli/version-stats.js +38 -6
- package/dist/foundation/release/bootstrap.d.ts +10 -0
- package/dist/foundation/release/bootstrap.js +5 -1
- package/dist/foundation/release/update.js +13 -0
- 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/package.json +2 -1
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({
|
|
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");
|
package/bin/module-identity.js
CHANGED
|
@@ -87,7 +87,7 @@ function followProxyReExport(resolvedPath) {
|
|
|
87
87
|
* no CommonJS condition, so an ordinary require cannot name it. From there a
|
|
88
88
|
* require resolves pi-tui, which publishes no `exports` map at all.
|
|
89
89
|
*/
|
|
90
|
-
function resolvePinnedPiTui(packageRoot) {
|
|
90
|
+
export function resolvePinnedPiTui(packageRoot) {
|
|
91
91
|
let directory = packageRoot;
|
|
92
92
|
while (true) {
|
|
93
93
|
const candidate = join(directory, "node_modules", "@earendil-works", "pi-coding-agent");
|
|
@@ -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);
|
package/bin/pi-tui.d.ts
CHANGED
|
@@ -3,4 +3,4 @@
|
|
|
3
3
|
* file, so TypeScript reads this declaration and follows it to pinned Pi's
|
|
4
4
|
* nested pi-tui copy — the same module the proxy re-exports at runtime.
|
|
5
5
|
*/
|
|
6
|
-
export * from "../node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui/dist/index.
|
|
6
|
+
export * from "../node_modules/@earendil-works/pi-coding-agent/node_modules/@earendil-works/pi-tui/dist/index.d.ts";
|
package/bin/pi-tui.js
CHANGED
|
@@ -12,10 +12,14 @@
|
|
|
12
12
|
* plain import specifier in a module carries no such restriction, so the hop
|
|
13
13
|
* through this file is what makes the nested copy nameable from the manifest.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
15
|
+
* npm does not materialize one layout: `npm ci` keeps pinned Pi's shrinkwrapped
|
|
16
|
+
* nested copy, while a global install hoists pi-tui to the root and produces no
|
|
17
|
+
* nested copy. bin/sync-pi-tui-proxy.js therefore rewrites this file's one
|
|
18
|
+
* re-export on postinstall to whatever pinned Pi resolves in the tree npm
|
|
19
|
+
* actually built; the path below is the dev-checkout (`npm ci`) shape. When the
|
|
20
|
+
* target is missing anyway, this import fails loudly at launch instead of
|
|
21
|
+
* silently rendering without extension chrome, and bin/module-identity.js
|
|
22
|
+
* reports the same condition before the composition loads.
|
|
19
23
|
*
|
|
20
24
|
* This lives in bin/ (shipped, plain JS) because it names a path inside
|
|
21
25
|
* node_modules, which the Pi API boundary policy rightly forbids ordinary
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Point the `#pi-tui` proxy at the copy pinned Pi actually resolves.
|
|
3
|
+
*
|
|
4
|
+
* The proxy (bin/pi-tui.js) re-exports one static path, but npm does not
|
|
5
|
+
* materialize one layout: `npm ci` against A1's lockfile keeps pinned Pi's
|
|
6
|
+
* shrinkwrapped nested pi-tui copy, while a global `npm install -g` of the
|
|
7
|
+
* published tarball hoists pi-tui to A1's node_modules root and materializes
|
|
8
|
+
* no nested copy at all. A static path can only name one of those layouts —
|
|
9
|
+
* whichever the other layout lacks, the proxy's import fails at launch and
|
|
10
|
+
* extension UI never renders.
|
|
11
|
+
*
|
|
12
|
+
* This script runs on postinstall, asks Node what pinned Pi resolves
|
|
13
|
+
* `@earendil-works/pi-tui` to — the copy Pi's extension loader hands to
|
|
14
|
+
* extensions — and rewrites the proxy's single re-export (and its declaration
|
|
15
|
+
* twin) to that file. Whatever tree npm built, the proxy names the module Pi
|
|
16
|
+
* uses, so A1's renderer and Pi's extensions share one class identity.
|
|
17
|
+
*
|
|
18
|
+
* It never fails an install: a tree in which pinned Pi or its pi-tui cannot
|
|
19
|
+
* be resolved is reported on stderr and left untouched, and launch's
|
|
20
|
+
* module-identity check names the same condition to the user.
|
|
21
|
+
*
|
|
22
|
+
* This lives in bin/ (shipped, plain JS) because it inspects and names
|
|
23
|
+
* dependency resolution, which the Pi API boundary policy rightly forbids
|
|
24
|
+
* ordinary production code from touching.
|
|
25
|
+
*/
|
|
26
|
+
import { readFileSync, realpathSync, writeFileSync } from "node:fs";
|
|
27
|
+
import { dirname, join, relative } from "node:path";
|
|
28
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
29
|
+
import { resolvePinnedPiTui } from "./module-identity.js";
|
|
30
|
+
|
|
31
|
+
const RE_EXPORT_LINE = /^export \* from "[^"]+";$/m;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Rewrite the proxy pair under packageRoot/bin to re-export the pi-tui module
|
|
35
|
+
* pinned Pi resolves. Returns a discriminated outcome; never throws.
|
|
36
|
+
*/
|
|
37
|
+
export function syncPiTuiProxy(packageRoot) {
|
|
38
|
+
// resolvePinnedPiTui answers with a canonical real path, so the directory the
|
|
39
|
+
// relative specifier is computed from must be canonical too (Windows short
|
|
40
|
+
// names, symlinked installs).
|
|
41
|
+
const canonicalRoot = canonical(packageRoot);
|
|
42
|
+
let target;
|
|
43
|
+
try {
|
|
44
|
+
target = resolvePinnedPiTui(canonicalRoot);
|
|
45
|
+
} catch (error) {
|
|
46
|
+
return { kind: "unresolved", message: error instanceof Error ? error.message : String(error) };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const binDirectory = join(canonicalRoot, "bin");
|
|
50
|
+
const runtimeSpecifier = relativeSpecifier(binDirectory, target);
|
|
51
|
+
const declarationSpecifier = runtimeSpecifier.replace(/\.js$/, ".d.ts").replace(/\.d\.d\.ts$/, ".d.ts");
|
|
52
|
+
const changed = [];
|
|
53
|
+
for (const [file, specifier] of [
|
|
54
|
+
["pi-tui.js", runtimeSpecifier],
|
|
55
|
+
["pi-tui.d.ts", declarationSpecifier],
|
|
56
|
+
]) {
|
|
57
|
+
if (rewriteReExport(join(binDirectory, file), specifier)) changed.push(file);
|
|
58
|
+
}
|
|
59
|
+
return { kind: "synced", target, changed };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function canonical(path) {
|
|
63
|
+
try {
|
|
64
|
+
return realpathSync.native(path);
|
|
65
|
+
} catch {
|
|
66
|
+
return path;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function relativeSpecifier(fromDirectory, toFile) {
|
|
71
|
+
const specifier = relative(fromDirectory, toFile).split("\\").join("/");
|
|
72
|
+
return specifier.startsWith(".") ? specifier : `./${specifier}`;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Replace the file's single re-export line; returns whether the file changed. */
|
|
76
|
+
function rewriteReExport(file, specifier) {
|
|
77
|
+
let source;
|
|
78
|
+
try {
|
|
79
|
+
source = readFileSync(file, "utf8");
|
|
80
|
+
} catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
const line = `export * from "${specifier}";`;
|
|
84
|
+
if (source.includes(line) || !RE_EXPORT_LINE.test(source)) return false;
|
|
85
|
+
writeFileSync(file, source.replace(RE_EXPORT_LINE, line));
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const invokedDirectly = process.argv[1] !== undefined
|
|
90
|
+
&& import.meta.url === pathToFileURL(process.argv[1]).href;
|
|
91
|
+
if (invokedDirectly) {
|
|
92
|
+
const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
93
|
+
const outcome = syncPiTuiProxy(packageRoot);
|
|
94
|
+
if (outcome.kind === "unresolved") {
|
|
95
|
+
process.stderr.write(`a1: could not point #pi-tui at pinned Pi's copy (${outcome.message}); extension UI may not render.\n`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -3,6 +3,11 @@ interface VersionProcessResult {
|
|
|
3
3
|
readonly stdout: string;
|
|
4
4
|
}
|
|
5
5
|
type VersionProcessRunner = (command: string, arguments_: readonly string[]) => Promise<VersionProcessResult>;
|
|
6
|
+
type RegistryFetcher = (url: string) => Promise<{
|
|
7
|
+
readonly ok: boolean;
|
|
8
|
+
readonly status: number;
|
|
9
|
+
text(): Promise<string>;
|
|
10
|
+
}>;
|
|
6
11
|
interface VersionOutput {
|
|
7
12
|
stdout(message: string): void;
|
|
8
13
|
stderr(message: string): void;
|
|
@@ -11,6 +16,7 @@ export interface VersionStatsOptions {
|
|
|
11
16
|
readonly packageRoot: string;
|
|
12
17
|
readonly output?: VersionOutput;
|
|
13
18
|
readonly runner?: VersionProcessRunner;
|
|
19
|
+
readonly fetcher?: RegistryFetcher;
|
|
14
20
|
}
|
|
15
21
|
export declare function runVersionStats(options: VersionStatsOptions): Promise<number>;
|
|
16
22
|
export {};
|
|
@@ -20,13 +20,24 @@ export async function runVersionStats(options) {
|
|
|
20
20
|
output.stderr(`${PRODUCT_TEXT.diagnostic(`could not read its installed version: ${message(error)}`)}\n`);
|
|
21
21
|
return 1;
|
|
22
22
|
}
|
|
23
|
-
const remote = await queryDistTags(runner);
|
|
23
|
+
const remote = await queryDistTags(runner, options.fetcher ?? defaultRegistryFetcher);
|
|
24
24
|
output.stdout(`Current: ${installed}\nDevelop: ${remote.develop ?? "unavailable"}\nRelease: ${remote.release ?? "unavailable"}\n`);
|
|
25
25
|
if (remote.error)
|
|
26
26
|
output.stderr(`${PRODUCT_TEXT.diagnostic(`could not resolve npm dist-tags: ${remote.error}`)}\n`);
|
|
27
27
|
return 0;
|
|
28
28
|
}
|
|
29
|
-
|
|
29
|
+
// npm view respects the user's .npmrc registry and proxy, so it stays primary; the direct
|
|
30
|
+
// registry fetch below covers npm CLI versions whose --json output shape we cannot parse.
|
|
31
|
+
async function queryDistTags(runner, fetcher) {
|
|
32
|
+
const fromNpm = await queryDistTagsViaNpm(runner);
|
|
33
|
+
if (fromNpm.error === null)
|
|
34
|
+
return fromNpm;
|
|
35
|
+
const fromRegistry = await queryDistTagsViaRegistry(fetcher);
|
|
36
|
+
if (fromRegistry.error === null)
|
|
37
|
+
return fromRegistry;
|
|
38
|
+
return unavailable(`${fromNpm.error}; registry fallback failed: ${fromRegistry.error}`);
|
|
39
|
+
}
|
|
40
|
+
async function queryDistTagsViaNpm(runner) {
|
|
30
41
|
let result;
|
|
31
42
|
try {
|
|
32
43
|
result = await runner("npm", ["view", PRODUCT_TEXT.packageName, "dist-tags", "--json"]);
|
|
@@ -40,11 +51,31 @@ async function queryDistTags(runner) {
|
|
|
40
51
|
const parsed = JSON.parse(result.stdout);
|
|
41
52
|
// npm 12 wraps `npm view <pkg> dist-tags --json` output in a one-element array; older npm returns the bare object.
|
|
42
53
|
const metadata = Array.isArray(parsed) && parsed.length === 1 ? parsed[0] : parsed;
|
|
43
|
-
|
|
44
|
-
|
|
54
|
+
return parseDistTags(metadata, "npm");
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
return unavailable(message(error));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
async function queryDistTagsViaRegistry(fetcher) {
|
|
61
|
+
try {
|
|
62
|
+
const response = await fetcher(`https://registry.npmjs.org/-/package/${encodeURIComponent(PRODUCT_TEXT.packageName)}/dist-tags`);
|
|
63
|
+
if (!response.ok)
|
|
64
|
+
return unavailable(`registry responded with status ${response.status}`);
|
|
65
|
+
return parseDistTags(JSON.parse(await response.text()), "registry");
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
return unavailable(message(error));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function parseDistTags(metadata, source) {
|
|
72
|
+
if (typeof metadata !== "object" || metadata === null || Array.isArray(metadata)) {
|
|
73
|
+
return unavailable(`${source} returned a non-object dist-tags value`);
|
|
74
|
+
}
|
|
75
|
+
try {
|
|
45
76
|
const tags = metadata;
|
|
46
|
-
const release = parseVersion(tags.latest,
|
|
47
|
-
const develop = tags.next === undefined ? null : parseVersion(tags.next,
|
|
77
|
+
const release = parseVersion(tags.latest, `${source} latest`);
|
|
78
|
+
const develop = tags.next === undefined ? null : parseVersion(tags.next, `${source} development channel`);
|
|
48
79
|
return { release, develop, error: null };
|
|
49
80
|
}
|
|
50
81
|
catch (error) {
|
|
@@ -54,6 +85,7 @@ async function queryDistTags(runner) {
|
|
|
54
85
|
function unavailable(error) {
|
|
55
86
|
return { release: null, develop: null, error };
|
|
56
87
|
}
|
|
88
|
+
const defaultRegistryFetcher = async (url) => await fetch(url, { headers: { accept: "application/json" }, signal: AbortSignal.timeout(10_000) });
|
|
57
89
|
function createVersionProcessRunner() {
|
|
58
90
|
return async (command, arguments_) => await new Promise((resolvePromise, rejectPromise) => {
|
|
59
91
|
const child = process.platform === "win32"
|
|
@@ -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
|
-
|
|
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-
|
|
8
|
+
"builtAt": "2026-08-26T05:59:16.405Z",
|
|
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-
|
|
8
|
+
"builtAt": "2026-08-26T05:59:26.040Z",
|
|
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-
|
|
8
|
+
"builtAt": "2026-08-26T05:59:44.317Z",
|
|
9
9
|
"artifact": {
|
|
10
10
|
"filename": "process-guardian.exe",
|
|
11
|
-
"sha256": "
|
|
11
|
+
"sha256": "f36f8c76d82ce8e3d163c7671868bd0ab8b7bc1e14a190714aaeb304b2116a5b",
|
|
12
12
|
"size": 172544
|
|
13
13
|
},
|
|
14
14
|
"provenance": {
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@timurproko/a1",
|
|
3
|
-
"version": "0.1.8-dev.
|
|
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",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"node": ">=22.19.0 <25"
|
|
22
22
|
},
|
|
23
23
|
"scripts": {
|
|
24
|
+
"postinstall": "node bin/sync-pi-tui-proxy.js",
|
|
24
25
|
"clean": "node scripts/clean.mjs",
|
|
25
26
|
"build": "npm run clean && tsc -p tsconfig.build.json && node scripts/development/build-process-guardian.mjs",
|
|
26
27
|
"build:process-guardian": "node scripts/development/build-process-guardian.mjs",
|