@timurproko/a1 0.1.1-dev.7 → 0.1.1-dev.9

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.
Files changed (49) hide show
  1. package/README.md +11 -74
  2. package/bin/{a1-guardian.js → guardian.js} +1 -1
  3. package/bin/{a1-ui.js → ui.js} +1 -8
  4. package/dist/native/darwin-arm64/manifest.json +3 -3
  5. package/dist/native/darwin-arm64/{a1-process-guardian → process-guardian} +0 -0
  6. package/dist/native/linux-x64/manifest.json +3 -3
  7. package/dist/native/linux-x64/{a1-process-guardian → process-guardian} +0 -0
  8. package/dist/native/win32-x64/manifest.json +3 -3
  9. package/dist/native/win32-x64/process-guardian.exe +0 -0
  10. package/dist/src/composition/index.js +7 -1
  11. package/dist/src/features/launch/initialize-profile.js +23 -2
  12. package/dist/src/features/launch/profiles.d.ts +1 -1
  13. package/dist/src/features/launch/profiles.js +2 -2
  14. package/dist/src/features/launch/runtime-selection.d.ts +13 -9
  15. package/dist/src/features/launch/runtime-selection.js +6 -6
  16. package/dist/src/features/owned-ui/settings-app.js +6 -4
  17. package/dist/src/foundation/pi-component-adapter/index.d.ts +1 -1
  18. package/dist/src/foundation/pi-component-adapter/index.js +1 -1
  19. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.d.ts +8 -0
  20. package/dist/src/foundation/pi-component-adapter/upstream/theme/theme.js +12 -0
  21. package/dist/src/foundation/pi-engine-adapter/adapter.d.ts +5 -0
  22. package/dist/src/foundation/pi-engine-adapter/adapter.js +7 -0
  23. package/dist/src/foundation/pi-engine-adapter/settings-integration.d.ts +0 -2
  24. package/dist/src/foundation/pi-engine-adapter/settings-integration.js +24 -37
  25. package/dist/src/foundation/release/bootstrap.js +2 -2
  26. package/dist/src/foundation/ui-components/list-view.js +4 -4
  27. package/dist/src/foundation/ui-components/theme.d.ts +6 -0
  28. package/dist/src/foundation/ui-components/theme.js +1 -0
  29. package/dist/src/product-identity.json +7 -7
  30. package/docs/architecture/process-guardian-provenance.md +5 -5
  31. package/docs/architecture/toolchain.md +3 -3
  32. package/docs/ci-release-runbook.md +10 -2
  33. package/docs/manual-terminal-colour-check.md +55 -0
  34. package/package.json +9 -7
  35. package/dist/native/win32-x64/a1-process-guardian.exe +0 -0
  36. package/dist/src/composition/transparent-runtime.d.ts +0 -6
  37. package/dist/src/composition/transparent-runtime.js +0 -19
  38. package/dist/src/foundation/transparent-terminal/command-resolution.d.ts +0 -13
  39. package/dist/src/foundation/transparent-terminal/command-resolution.js +0 -72
  40. package/dist/src/foundation/transparent-terminal/foreground-broker.d.ts +0 -24
  41. package/dist/src/foundation/transparent-terminal/foreground-broker.js +0 -30
  42. package/dist/src/foundation/transparent-terminal/index.d.ts +0 -4
  43. package/dist/src/foundation/transparent-terminal/index.js +0 -4
  44. package/dist/src/foundation/transparent-terminal/main.d.ts +0 -9
  45. package/dist/src/foundation/transparent-terminal/main.js +0 -87
  46. package/dist/src/foundation/transparent-terminal/native-launcher.d.ts +0 -25
  47. package/dist/src/foundation/transparent-terminal/native-launcher.js +0 -146
  48. /package/bin/{a1.js → cli.js} +0 -0
  49. /package/bin/{a1-supervisor.js → supervisor.js} +0 -0
@@ -1,146 +0,0 @@
1
- import { spawn } from "node:child_process";
2
- import { randomUUID } from "node:crypto";
3
- import { resolveTransparentCommand } from "./command-resolution.js";
4
- export function createPlatformTransparentLauncher(platform = process.platform, adapter = defaultSpawnAdapter) {
5
- if (platform === "win32")
6
- return new WindowsTransparentLauncher(adapter);
7
- if (platform === "linux" || platform === "darwin")
8
- return new UnixTransparentLauncher(adapter);
9
- throw new Error(`transparent terminal attachment is unsupported on ${platform}`);
10
- }
11
- export class WindowsTransparentLauncher {
12
- adapter;
13
- constructor(adapter = defaultSpawnAdapter) {
14
- this.adapter = adapter;
15
- }
16
- async launch(profile) {
17
- return await launchInherited(profile, this.adapter, {
18
- windowsHide: true,
19
- windowsVerbatimArguments: false,
20
- detached: false,
21
- });
22
- }
23
- }
24
- export class UnixTransparentLauncher {
25
- adapter;
26
- constructor(adapter = defaultSpawnAdapter) {
27
- this.adapter = adapter;
28
- }
29
- async launch(profile) {
30
- // Staying in the foreground process group preserves the inherited controlling
31
- // terminal without an intermediary or synthetic terminal restoration.
32
- return await launchInherited(profile, this.adapter, {
33
- detached: false,
34
- });
35
- }
36
- }
37
- async function launchInherited(profile, adapter, platformOptions) {
38
- const command = await adapter.resolveCommand(profile);
39
- const child = adapter.spawn(command.executable, command.arguments, {
40
- ...platformOptions,
41
- cwd: profile.cwd,
42
- env: { ...profile.environment, TERM: profile.terminalType },
43
- shell: false,
44
- stdio: "inherit",
45
- });
46
- await spawned(child);
47
- if (!child.pid)
48
- throw Object.assign(new Error("transparent child has no process identity"), { code: "NO_PROCESS_ID" });
49
- const outcome = childOutcome(child);
50
- const startIdentity = await adapter.observeStartIdentity(child);
51
- const processIdentity = { pid: child.pid, startIdentity };
52
- let stopOutcome = null;
53
- return {
54
- processIdentity,
55
- outcome,
56
- stop(reason) {
57
- stopOutcome ??= stopOwnedChild(child, adapter, processIdentity.startIdentity, reason);
58
- return stopOutcome;
59
- },
60
- };
61
- }
62
- function spawned(child) {
63
- return new Promise((resolve, reject) => {
64
- if (child.pid) {
65
- resolve();
66
- return;
67
- }
68
- child.once("spawn", resolve);
69
- child.once("error", reject);
70
- });
71
- }
72
- function childOutcome(child) {
73
- return new Promise(resolve => {
74
- child.once("error", error => resolve({ kind: "broker-error", message: error.message, code: errorCode(error) }));
75
- child.once("close", (exitCode, signal) => {
76
- if (signal)
77
- resolve({ kind: "signaled", signal });
78
- else
79
- resolve({ kind: "exited", exitCode: exitCode ?? 1 });
80
- });
81
- });
82
- }
83
- async function stopOwnedChild(child, adapter, expectedStartIdentity, reason) {
84
- if (!await adapter.identityMatches(child, expectedStartIdentity)) {
85
- return { kind: "broker-error", message: "refusing cleanup because transparent child ownership changed", code: "PROCESS_IDENTITY_MISMATCH" };
86
- }
87
- await adapter.stop(child, false);
88
- if (!await adapter.waitForExit(child, 1_500)) {
89
- if (!await adapter.identityMatches(child, expectedStartIdentity)) {
90
- return { kind: "broker-error", message: "refusing forced cleanup because transparent child ownership changed", code: "PROCESS_IDENTITY_MISMATCH" };
91
- }
92
- await adapter.stop(child, true);
93
- if (!await adapter.waitForExit(child, 1_500)) {
94
- return { kind: "broker-error", message: "transparent child did not exit within the bounded cleanup deadline", code: "CLEANUP_TIMEOUT" };
95
- }
96
- }
97
- return { kind: "stopped", reason };
98
- }
99
- function errorCode(error) {
100
- return "code" in error && typeof error.code === "string" ? error.code : null;
101
- }
102
- const observedStartIdentities = new WeakMap();
103
- const defaultSpawnAdapter = {
104
- async resolveCommand(profile) {
105
- return await resolveTransparentCommand(profile.executable, profile.arguments, {
106
- cwd: profile.cwd,
107
- environment: profile.environment,
108
- });
109
- },
110
- spawn(executable, arguments_, options) {
111
- return spawn(executable, [...arguments_], options);
112
- },
113
- async observeStartIdentity(child) {
114
- if (!child.pid)
115
- throw new Error("transparent child has no PID");
116
- const identity = `${child.pid}:${randomUUID()}`;
117
- observedStartIdentities.set(child, identity);
118
- return identity;
119
- },
120
- async identityMatches(child, expectedStartIdentity) {
121
- return child.pid !== undefined
122
- && child.exitCode === null
123
- && child.signalCode === null
124
- && observedStartIdentities.get(child) === expectedStartIdentity;
125
- },
126
- async stop(child, force) {
127
- if (child.exitCode !== null || child.signalCode !== null)
128
- return;
129
- child.kill(force ? "SIGKILL" : "SIGTERM");
130
- },
131
- async waitForExit(child, timeoutMs) {
132
- if (child.exitCode !== null || child.signalCode !== null)
133
- return true;
134
- return await new Promise(resolve => {
135
- const timer = setTimeout(() => finish(false), timeoutMs);
136
- timer.unref();
137
- const finish = (exited) => {
138
- clearTimeout(timer);
139
- child.off("close", onClose);
140
- resolve(exited);
141
- };
142
- const onClose = () => finish(true);
143
- child.once("close", onClose);
144
- });
145
- },
146
- };
File without changes
File without changes