@timurproko/a1 0.2.7-dev.792 → 0.2.7-dev.806
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/app/session-shell/clipboard-diagnostics.js +1 -1
- package/dist/app/session-shell/response-copy-helper.js +21 -6
- package/dist/app/session-shell/response-copy-protocol.d.ts +1 -1
- package/dist/app/session-shell/response-copy-transport.d.ts +3 -6
- package/dist/app/session-shell/response-copy-transport.js +60 -17
- package/dist/app/session-shell/session-shell-root.d.ts +2 -0
- package/dist/app/session-shell/session-shell-root.js +6 -1
- package/dist/app/session-shell/session-shell.d.ts +1 -0
- package/dist/app/session-shell/session-shell.js +22 -19
- package/dist/cli/tabs.js +1 -1
- package/dist/composition/owned-ui.d.ts +1 -0
- package/dist/composition/owned-ui.js +16 -3
- package/dist/features/resident-tab/shortcut-declarations.d.ts +1 -1
- package/dist/features/resident-tab/shortcut-declarations.js +1 -0
- package/dist/foundation/launch-guardian/exit-watcher.d.ts +14 -0
- package/dist/foundation/launch-guardian/exit-watcher.js +94 -0
- package/dist/foundation/launch-guardian/main.d.ts +2 -1
- package/dist/foundation/launch-guardian/main.js +58 -6
- package/dist/foundation/process-containment/{native-guardian-containment.d.ts → addon-containment.d.ts} +7 -5
- package/dist/foundation/process-containment/addon-containment.js +139 -0
- package/dist/foundation/process-containment/addon-process-inspector.d.ts +11 -0
- package/dist/foundation/process-containment/addon-process-inspector.js +36 -0
- package/dist/foundation/process-containment/addon.d.ts +42 -0
- package/dist/foundation/process-containment/addon.js +57 -0
- package/dist/foundation/process-containment/artifact.d.ts +1 -1
- package/dist/foundation/process-containment/artifact.js +6 -5
- package/dist/foundation/process-containment/contracts.d.ts +2 -0
- package/dist/foundation/process-containment/index.d.ts +4 -4
- package/dist/foundation/process-containment/index.js +3 -3
- package/dist/foundation/process-containment/native-process-inspector.d.ts +2 -1
- package/dist/foundation/process-containment/native-process-inspector.js +10 -10
- package/dist/foundation/release/bootstrap.js +53 -16
- package/dist/foundation/release/index.d.ts +1 -1
- package/dist/foundation/release/index.js +1 -1
- package/dist/foundation/release/release-store.d.ts +12 -0
- package/dist/foundation/release/release-store.js +124 -2
- package/dist/foundation/resident-tabs/bounded-host-command.d.ts +3 -1
- package/dist/foundation/resident-tabs/bounded-host-command.js +6 -2
- package/dist/foundation/resident-tabs/bridge-client.d.ts +2 -0
- package/dist/foundation/resident-tabs/bridge-client.js +13 -0
- package/dist/foundation/resident-tabs/doctor.d.ts +0 -1
- package/dist/foundation/resident-tabs/doctor.js +4 -4
- package/dist/foundation/resident-tabs/ensure-terminal-host.d.ts +7 -2
- package/dist/foundation/resident-tabs/ensure-terminal-host.js +15 -11
- package/dist/foundation/resident-tabs/host-entry.d.ts +1 -0
- package/dist/foundation/resident-tabs/host-entry.js +17 -0
- package/dist/foundation/resident-tabs/index.d.ts +2 -2
- package/dist/foundation/resident-tabs/index.js +1 -1
- package/dist/foundation/resident-tabs/maintenance.d.ts +5 -4
- package/dist/foundation/resident-tabs/maintenance.js +32 -17
- package/dist/foundation/resident-tabs/release-holds.d.ts +3 -2
- package/dist/foundation/resident-tabs/release-holds.js +16 -7
- package/dist/foundation/resident-tabs/settings.d.ts +0 -1
- package/dist/foundation/resident-tabs/settings.js +1 -7
- package/dist/foundation/resident-tabs/terminal-host-artifact.d.ts +11 -15
- package/dist/foundation/resident-tabs/terminal-host-artifact.js +57 -32
- package/dist/foundation/session-writer-lock/index.d.ts +1 -3
- package/dist/foundation/session-writer-lock/index.js +8 -6
- package/dist/integrations/pi/components/shell-editor-autocomplete.js +2 -1
- package/dist/integrations/pi/components/shell-shared-facade.d.ts +2 -0
- package/dist/native/darwin-arm64/manifest.json +8 -6
- package/dist/native/darwin-arm64/process-guardian.node +0 -0
- package/dist/native/darwin-arm64/terminal-host-THIRD-PARTY-NOTICES.txt +1 -1
- package/dist/native/darwin-arm64/terminal-host.manifest.json +14 -13
- package/dist/native/darwin-arm64/terminal-host.node +0 -0
- package/dist/native/darwin-x64/manifest.json +9 -7
- package/dist/native/darwin-x64/process-guardian.node +0 -0
- package/dist/native/darwin-x64/terminal-host-THIRD-PARTY-NOTICES.txt +1 -1
- package/dist/native/darwin-x64/terminal-host.manifest.json +15 -14
- package/dist/native/darwin-x64/terminal-host.node +0 -0
- package/dist/native/linux-x64/manifest.json +8 -6
- package/dist/native/linux-x64/process-guardian.node +0 -0
- package/dist/native/linux-x64/terminal-host-THIRD-PARTY-NOTICES.txt +1 -1
- package/dist/native/linux-x64/terminal-host.manifest.json +14 -13
- package/dist/native/linux-x64/{terminal-host → terminal-host.node} +0 -0
- package/dist/native/win32-x64/manifest.json +8 -6
- package/dist/native/win32-x64/process-guardian.node +0 -0
- package/dist/native/win32-x64/terminal-host-THIRD-PARTY-NOTICES.txt +1 -1
- package/dist/native/win32-x64/terminal-host.manifest.json +14 -13
- package/dist/native/win32-x64/{terminal-host.exe → terminal-host.node} +0 -0
- package/dist/product-identity.d.ts +1 -1
- package/dist/product-identity.js +1 -1
- package/dist/product-identity.json +3 -2
- package/dist/runtime-payload-inventory.json +1 -0
- package/dist/ui/settings/declarations.d.ts +0 -12
- package/dist/ui/settings/declarations.js +0 -10
- package/docs/architecture/boundaries.md +10 -9
- package/docs/architecture/process-guardian-provenance.md +17 -11
- package/docs/architecture/resident-tabs.md +36 -34
- package/docs/architecture/terminal-host-provenance.md +5 -3
- package/docs/architecture/toolchain.md +8 -6
- package/docs/ci-release-runbook.md +1 -1
- package/docs/openspec-archive-automation.md +23 -9
- package/docs/validation.md +6 -2
- package/package.json +5 -3
- package/dist/foundation/process-containment/darwin-process-inspector.d.ts +0 -5
- package/dist/foundation/process-containment/darwin-process-inspector.js +0 -7
- package/dist/foundation/process-containment/native-guardian-containment.js +0 -152
- package/dist/foundation/process-containment/windows-process-inspector.d.ts +0 -19
- package/dist/foundation/process-containment/windows-process-inspector.js +0 -56
- package/dist/native/darwin-arm64/a1_session_lock.node +0 -0
- package/dist/native/darwin-arm64/process-guardian +0 -0
- package/dist/native/darwin-arm64/terminal-host +0 -0
- package/dist/native/darwin-x64/a1_session_lock.node +0 -0
- package/dist/native/darwin-x64/process-guardian +0 -0
- package/dist/native/darwin-x64/terminal-host +0 -0
- package/dist/native/linux-x64/a1_session_lock.node +0 -0
- package/dist/native/linux-x64/process-guardian +0 -0
- package/dist/native/win32-x64/a1_session_lock.node +0 -0
- package/dist/native/win32-x64/process-guardian.exe +0 -0
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { WindowsNativeProcessInspector } from "./windows-process-inspector.js";
|
|
2
|
-
/** Verifies Darwin process identity through the bounded native guardian inspection command. */
|
|
3
|
-
export class DarwinNativeProcessInspector extends WindowsNativeProcessInspector {
|
|
4
|
-
constructor(helperPath, runner) {
|
|
5
|
-
super(helperPath, runner, "darwin-proc-start:");
|
|
6
|
-
}
|
|
7
|
-
}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { spawn } from "node:child_process";
|
|
2
|
-
import { mkdir, readFile, rm } from "node:fs/promises";
|
|
3
|
-
import { dirname, resolve } from "node:path";
|
|
4
|
-
import { PRODUCT_IDENTITY } from "../../product-identity.js";
|
|
5
|
-
/** Delegates one root runtime to the native guardian and exposes its verified containment identity. */
|
|
6
|
-
export class NativeGuardianContainment {
|
|
7
|
-
#identity;
|
|
8
|
-
#helper = null;
|
|
9
|
-
#rootIdentity = null;
|
|
10
|
-
#outcome = null;
|
|
11
|
-
instanceId;
|
|
12
|
-
helperPath;
|
|
13
|
-
statusPath;
|
|
14
|
-
exitNoticePath;
|
|
15
|
-
constructor(instanceId, helperPath, statusPath, exitNoticePath = null) {
|
|
16
|
-
this.instanceId = instanceId;
|
|
17
|
-
this.helperPath = helperPath;
|
|
18
|
-
this.statusPath = statusPath;
|
|
19
|
-
this.exitNoticePath = exitNoticePath;
|
|
20
|
-
this.#identity = { provider: "native-guardian-pending", token: instanceId };
|
|
21
|
-
}
|
|
22
|
-
get identity() {
|
|
23
|
-
return this.#identity;
|
|
24
|
-
}
|
|
25
|
-
async spawn(executable, arguments_, options) {
|
|
26
|
-
if (this.#helper)
|
|
27
|
-
throw new Error("process containment already has a root runtime");
|
|
28
|
-
await mkdir(dirname(this.statusPath), { recursive: true, mode: 0o700 });
|
|
29
|
-
await rm(this.statusPath, { force: true });
|
|
30
|
-
if (this.exitNoticePath)
|
|
31
|
-
await rm(this.exitNoticePath, { force: true });
|
|
32
|
-
const helper = spawn(this.helperPath, [
|
|
33
|
-
"--parent-pid", String(process.pid),
|
|
34
|
-
"--instance", this.instanceId,
|
|
35
|
-
"--status-file", this.statusPath,
|
|
36
|
-
...(this.exitNoticePath ? ["--exit-notice", this.exitNoticePath] : []),
|
|
37
|
-
"--", executable, ...arguments_,
|
|
38
|
-
], {
|
|
39
|
-
cwd: options.cwd,
|
|
40
|
-
env: {
|
|
41
|
-
...options.environment,
|
|
42
|
-
...(options.terminalType ? { TERM: options.terminalType } : {}),
|
|
43
|
-
// Protocol: the runtime arms this notice and the guardian prints it if the runtime dies unclean.
|
|
44
|
-
...(this.exitNoticePath ? { [PRODUCT_IDENTITY.environment.exitNoticePath]: this.exitNoticePath } : {}),
|
|
45
|
-
},
|
|
46
|
-
shell: false,
|
|
47
|
-
stdio: "inherit",
|
|
48
|
-
windowsHide: false,
|
|
49
|
-
});
|
|
50
|
-
this.#helper = helper;
|
|
51
|
-
this.#outcome = helperOutcome(helper);
|
|
52
|
-
const status = await waitForReadyStatus(this.statusPath, this.#outcome, 5_000);
|
|
53
|
-
this.#rootIdentity = { pid: status.pid, startIdentity: status.startIdentity };
|
|
54
|
-
this.#identity = { provider: status.containmentProvider, token: status.containmentToken };
|
|
55
|
-
return { identity: this.#rootIdentity, outcome: this.#outcome };
|
|
56
|
-
}
|
|
57
|
-
async contains(identity) {
|
|
58
|
-
return this.#rootIdentity !== null
|
|
59
|
-
&& identity.pid === this.#rootIdentity.pid
|
|
60
|
-
&& identity.startIdentity === this.#rootIdentity.startIdentity;
|
|
61
|
-
}
|
|
62
|
-
async stop(force) {
|
|
63
|
-
const root = this.#rootIdentity;
|
|
64
|
-
if (!root)
|
|
65
|
-
return;
|
|
66
|
-
try {
|
|
67
|
-
process.kill(root.pid, force ? "SIGKILL" : "SIGTERM");
|
|
68
|
-
}
|
|
69
|
-
catch { }
|
|
70
|
-
}
|
|
71
|
-
async waitForEmpty(timeoutMs) {
|
|
72
|
-
if (!this.#helper || this.#helper.exitCode !== null || this.#helper.signalCode !== null)
|
|
73
|
-
return true;
|
|
74
|
-
return await new Promise(resolvePromise => {
|
|
75
|
-
const timer = setTimeout(() => finish(false), timeoutMs);
|
|
76
|
-
timer.unref();
|
|
77
|
-
const finish = (empty) => {
|
|
78
|
-
clearTimeout(timer);
|
|
79
|
-
this.#helper?.off("close", onClose);
|
|
80
|
-
resolvePromise(empty);
|
|
81
|
-
};
|
|
82
|
-
const onClose = () => finish(true);
|
|
83
|
-
this.#helper?.once("close", onClose);
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
async close() {
|
|
87
|
-
const helper = this.#helper;
|
|
88
|
-
if (helper && helper.exitCode === null && helper.signalCode === null)
|
|
89
|
-
helper.kill("SIGKILL");
|
|
90
|
-
await this.waitForEmpty(1_500);
|
|
91
|
-
await rm(this.statusPath, { force: true });
|
|
92
|
-
if (this.exitNoticePath)
|
|
93
|
-
await rm(this.exitNoticePath, { force: true });
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
export function resolveProcessGuardianPath(releaseRoot, environment = process.env, platform = process.platform, architecture = process.arch) {
|
|
97
|
-
const override = environment[PRODUCT_IDENTITY.environment.processGuardianPath]?.trim();
|
|
98
|
-
if (override)
|
|
99
|
-
return resolve(override);
|
|
100
|
-
const executable = platform === "win32"
|
|
101
|
-
? `${PRODUCT_IDENTITY.artifacts.processGuardianExecutable}.exe`
|
|
102
|
-
: PRODUCT_IDENTITY.artifacts.processGuardianExecutable;
|
|
103
|
-
return resolve(releaseRoot, "dist", "native", `${platform}-${architecture}`, executable);
|
|
104
|
-
}
|
|
105
|
-
function helperOutcome(helper) {
|
|
106
|
-
return new Promise(resolvePromise => {
|
|
107
|
-
let settled = false;
|
|
108
|
-
const settle = (outcome) => {
|
|
109
|
-
if (settled)
|
|
110
|
-
return;
|
|
111
|
-
settled = true;
|
|
112
|
-
resolvePromise(outcome);
|
|
113
|
-
};
|
|
114
|
-
helper.once("error", error => settle({ kind: "guardian-error", message: error.message, code: errorCode(error) }));
|
|
115
|
-
helper.once("close", (code, signal) => {
|
|
116
|
-
if (signal)
|
|
117
|
-
settle({ kind: "signaled", signal });
|
|
118
|
-
else
|
|
119
|
-
settle({ kind: "exited", exitCode: code ?? 1 });
|
|
120
|
-
});
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
async function waitForReadyStatus(path, outcome, timeoutMs) {
|
|
124
|
-
const deadline = Date.now() + timeoutMs;
|
|
125
|
-
let terminalOutcome = null;
|
|
126
|
-
void outcome.then(value => { terminalOutcome = value; });
|
|
127
|
-
while (Date.now() < deadline) {
|
|
128
|
-
try {
|
|
129
|
-
const value = JSON.parse(await readFile(path, "utf8"));
|
|
130
|
-
if (isReadyStatus(value))
|
|
131
|
-
return value;
|
|
132
|
-
throw new Error("process guardian published invalid ready status");
|
|
133
|
-
}
|
|
134
|
-
catch (error) {
|
|
135
|
-
if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
|
|
136
|
-
throw error;
|
|
137
|
-
}
|
|
138
|
-
if (terminalOutcome)
|
|
139
|
-
throw new Error(`process guardian exited before readiness: ${JSON.stringify(terminalOutcome)}`);
|
|
140
|
-
await new Promise(resolvePromise => setTimeout(resolvePromise, 20));
|
|
141
|
-
}
|
|
142
|
-
throw new Error(`process guardian did not publish readiness within ${timeoutMs}ms`);
|
|
143
|
-
}
|
|
144
|
-
function isReadyStatus(value) {
|
|
145
|
-
return Number.isSafeInteger(value.pid) && Number(value.pid) > 0
|
|
146
|
-
&& typeof value.startIdentity === "string" && value.startIdentity.length > 0
|
|
147
|
-
&& typeof value.containmentProvider === "string" && value.containmentProvider.length > 0
|
|
148
|
-
&& typeof value.containmentToken === "string" && value.containmentToken.length > 0;
|
|
149
|
-
}
|
|
150
|
-
function errorCode(error) {
|
|
151
|
-
return "code" in error && typeof error.code === "string" ? error.code : null;
|
|
152
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import type { NativeProcessIdentity } from "../lifecycle/index.js";
|
|
2
|
-
import type { NativeProcessInspector } from "./contracts.js";
|
|
3
|
-
export interface InspectorCommandResult {
|
|
4
|
-
readonly exitCode: number;
|
|
5
|
-
readonly stdout: string;
|
|
6
|
-
readonly stderr: string;
|
|
7
|
-
}
|
|
8
|
-
export interface InspectorCommandRunner {
|
|
9
|
-
run(executable: string, arguments_: readonly string[]): Promise<InspectorCommandResult>;
|
|
10
|
-
}
|
|
11
|
-
/** Verifies Windows process identity through the bounded process-guardian inspection command. */
|
|
12
|
-
export declare class WindowsNativeProcessInspector implements NativeProcessInspector {
|
|
13
|
-
readonly helperPath: string;
|
|
14
|
-
private readonly runner;
|
|
15
|
-
private readonly identityPrefix;
|
|
16
|
-
constructor(helperPath: string, runner?: InspectorCommandRunner, identityPrefix?: string);
|
|
17
|
-
observe(pid: number): Promise<NativeProcessIdentity | null>;
|
|
18
|
-
matches(identity: NativeProcessIdentity): Promise<boolean>;
|
|
19
|
-
}
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
|
-
/** Verifies Windows process identity through the bounded process-guardian inspection command. */
|
|
3
|
-
export class WindowsNativeProcessInspector {
|
|
4
|
-
helperPath;
|
|
5
|
-
runner;
|
|
6
|
-
identityPrefix;
|
|
7
|
-
constructor(helperPath, runner = defaultRunner, identityPrefix = "windows-filetime:") {
|
|
8
|
-
this.helperPath = helperPath;
|
|
9
|
-
this.runner = runner;
|
|
10
|
-
this.identityPrefix = identityPrefix;
|
|
11
|
-
if (!helperPath || helperPath.includes("\0"))
|
|
12
|
-
throw new TypeError("process guardian helper path is invalid");
|
|
13
|
-
}
|
|
14
|
-
async observe(pid) {
|
|
15
|
-
if (!Number.isSafeInteger(pid) || pid <= 0)
|
|
16
|
-
throw new TypeError("inspected PID must be a positive safe integer");
|
|
17
|
-
const result = await this.runner.run(this.helperPath, ["--inspect-pid", String(pid)]);
|
|
18
|
-
if (result.exitCode === 3)
|
|
19
|
-
return null;
|
|
20
|
-
if (result.exitCode !== 0) {
|
|
21
|
-
const detail = result.stderr.trim() || `helper exited ${result.exitCode}`;
|
|
22
|
-
throw Object.assign(new Error(`cannot inspect native process identity: ${detail}`), { code: "PROCESS_INSPECTION_FAILED" });
|
|
23
|
-
}
|
|
24
|
-
let value;
|
|
25
|
-
try {
|
|
26
|
-
value = JSON.parse(result.stdout);
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
throw Object.assign(new Error("process guardian returned malformed identity data"), { code: "PROCESS_INSPECTION_INVALID" });
|
|
30
|
-
}
|
|
31
|
-
if (!isIdentity(value) || value.pid !== pid || !value.startIdentity.startsWith(this.identityPrefix)) {
|
|
32
|
-
throw Object.assign(new Error("process guardian returned mismatched identity data"), { code: "PROCESS_INSPECTION_INVALID" });
|
|
33
|
-
}
|
|
34
|
-
return value;
|
|
35
|
-
}
|
|
36
|
-
async matches(identity) {
|
|
37
|
-
const observed = await this.observe(identity.pid);
|
|
38
|
-
return observed !== null && observed.startIdentity === identity.startIdentity;
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
const defaultRunner = {
|
|
42
|
-
async run(executable, arguments_) {
|
|
43
|
-
return await new Promise(resolvePromise => {
|
|
44
|
-
execFile(executable, [...arguments_], { windowsHide: true, timeout: 2_000, maxBuffer: 8 * 1_024 }, (error, stdout, stderr) => {
|
|
45
|
-
const exitCode = error && "code" in error && typeof error.code === "number" ? error.code : error ? 1 : 0;
|
|
46
|
-
resolvePromise({ exitCode, stdout, stderr });
|
|
47
|
-
});
|
|
48
|
-
});
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
function isIdentity(value) {
|
|
52
|
-
return typeof value === "object" && value !== null
|
|
53
|
-
&& "pid" in value && Number.isSafeInteger(value.pid) && Number(value.pid) > 0
|
|
54
|
-
&& "startIdentity" in value && typeof value.startIdentity === "string"
|
|
55
|
-
&& value.startIdentity.length > 0 && value.startIdentity.length <= 512 && !value.startIdentity.includes("\0");
|
|
56
|
-
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|