@agent-relay/factory 0.1.50 → 0.1.51

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 (173) hide show
  1. package/README.md +93 -11
  2. package/dist/cli/fleet.d.ts +4 -1
  3. package/dist/cli/fleet.d.ts.map +1 -1
  4. package/dist/cli/fleet.js +87 -42
  5. package/dist/cli/fleet.js.map +1 -1
  6. package/dist/config/schema.d.ts +1671 -10
  7. package/dist/config/schema.d.ts.map +1 -1
  8. package/dist/config/schema.js +83 -0
  9. package/dist/config/schema.js.map +1 -1
  10. package/dist/dispatch/templates.d.ts +6 -0
  11. package/dist/dispatch/templates.d.ts.map +1 -1
  12. package/dist/dispatch/templates.js +16 -0
  13. package/dist/dispatch/templates.js.map +1 -1
  14. package/dist/environments/connection-registry.d.ts +617 -0
  15. package/dist/environments/connection-registry.d.ts.map +1 -0
  16. package/dist/environments/connection-registry.js +174 -0
  17. package/dist/environments/connection-registry.js.map +1 -0
  18. package/dist/environments/index.d.ts +21 -0
  19. package/dist/environments/index.d.ts.map +1 -0
  20. package/dist/environments/index.js +11 -0
  21. package/dist/environments/index.js.map +1 -0
  22. package/dist/environments/k6-job.d.ts +64 -0
  23. package/dist/environments/k6-job.d.ts.map +1 -0
  24. package/dist/environments/k6-job.js +376 -0
  25. package/dist/environments/k6-job.js.map +1 -0
  26. package/dist/environments/kubernetes-client.d.ts +72 -0
  27. package/dist/environments/kubernetes-client.d.ts.map +1 -0
  28. package/dist/environments/kubernetes-client.js +337 -0
  29. package/dist/environments/kubernetes-client.js.map +1 -0
  30. package/dist/environments/kubernetes-command.d.ts +30 -0
  31. package/dist/environments/kubernetes-command.d.ts.map +1 -0
  32. package/dist/environments/kubernetes-command.js +108 -0
  33. package/dist/environments/kubernetes-command.js.map +1 -0
  34. package/dist/environments/kubernetes-environment.d.ts +38 -0
  35. package/dist/environments/kubernetes-environment.d.ts.map +1 -0
  36. package/dist/environments/kubernetes-environment.js +333 -0
  37. package/dist/environments/kubernetes-environment.js.map +1 -0
  38. package/dist/environments/kubernetes-provider.d.ts +83 -0
  39. package/dist/environments/kubernetes-provider.d.ts.map +1 -0
  40. package/dist/environments/kubernetes-provider.js +956 -0
  41. package/dist/environments/kubernetes-provider.js.map +1 -0
  42. package/dist/environments/load-harness.d.ts +199 -0
  43. package/dist/environments/load-harness.d.ts.map +1 -0
  44. package/dist/environments/load-harness.js +259 -0
  45. package/dist/environments/load-harness.js.map +1 -0
  46. package/dist/environments/load-profile.d.ts +294 -0
  47. package/dist/environments/load-profile.d.ts.map +1 -0
  48. package/dist/environments/load-profile.js +125 -0
  49. package/dist/environments/load-profile.js.map +1 -0
  50. package/dist/environments/stack-deployer.d.ts +22 -0
  51. package/dist/environments/stack-deployer.d.ts.map +1 -0
  52. package/dist/environments/stack-deployer.js +27 -0
  53. package/dist/environments/stack-deployer.js.map +1 -0
  54. package/dist/environments/stack-descriptor.d.ts +243 -0
  55. package/dist/environments/stack-descriptor.d.ts.map +1 -0
  56. package/dist/environments/stack-descriptor.js +88 -0
  57. package/dist/environments/stack-descriptor.js.map +1 -0
  58. package/dist/environments/verification-pipeline.d.ts +117 -0
  59. package/dist/environments/verification-pipeline.d.ts.map +1 -0
  60. package/dist/environments/verification-pipeline.js +643 -0
  61. package/dist/environments/verification-pipeline.js.map +1 -0
  62. package/dist/environments/verification-stack-deployer.d.ts +73 -0
  63. package/dist/environments/verification-stack-deployer.d.ts.map +1 -0
  64. package/dist/environments/verification-stack-deployer.js +484 -0
  65. package/dist/environments/verification-stack-deployer.js.map +1 -0
  66. package/dist/environments/verification-stack-descriptor.d.ts +1134 -0
  67. package/dist/environments/verification-stack-descriptor.d.ts.map +1 -0
  68. package/dist/environments/verification-stack-descriptor.js +275 -0
  69. package/dist/environments/verification-stack-descriptor.js.map +1 -0
  70. package/dist/environments/verification-stack.d.ts +29 -0
  71. package/dist/environments/verification-stack.d.ts.map +1 -0
  72. package/dist/environments/verification-stack.js +43 -0
  73. package/dist/environments/verification-stack.js.map +1 -0
  74. package/dist/featuremap/generate.d.ts +72 -0
  75. package/dist/featuremap/generate.d.ts.map +1 -0
  76. package/dist/featuremap/generate.js +854 -0
  77. package/dist/featuremap/generate.js.map +1 -0
  78. package/dist/featuremap/index.d.ts +2 -0
  79. package/dist/featuremap/index.d.ts.map +1 -1
  80. package/dist/featuremap/index.js +1 -0
  81. package/dist/featuremap/index.js.map +1 -1
  82. package/dist/featuremap/validate.d.ts +6 -0
  83. package/dist/featuremap/validate.d.ts.map +1 -1
  84. package/dist/featuremap/validate.js +95 -13
  85. package/dist/featuremap/validate.js.map +1 -1
  86. package/dist/fleet/create-fleet.d.ts +2 -0
  87. package/dist/fleet/create-fleet.d.ts.map +1 -1
  88. package/dist/fleet/create-fleet.js +1 -0
  89. package/dist/fleet/create-fleet.js.map +1 -1
  90. package/dist/fleet/internal-fleet-client.d.ts +8 -1
  91. package/dist/fleet/internal-fleet-client.d.ts.map +1 -1
  92. package/dist/fleet/internal-fleet-client.js +31 -6
  93. package/dist/fleet/internal-fleet-client.js.map +1 -1
  94. package/dist/fleet/relay-fleet-client.d.ts +4 -1
  95. package/dist/fleet/relay-fleet-client.d.ts.map +1 -1
  96. package/dist/fleet/relay-fleet-client.js +142 -1
  97. package/dist/fleet/relay-fleet-client.js.map +1 -1
  98. package/dist/git/agent-worktree.d.ts +4 -1
  99. package/dist/git/agent-worktree.d.ts.map +1 -1
  100. package/dist/git/agent-worktree.js +151 -8
  101. package/dist/git/agent-worktree.js.map +1 -1
  102. package/dist/index.d.ts +32 -8
  103. package/dist/index.d.ts.map +1 -1
  104. package/dist/index.js +15 -3
  105. package/dist/index.js.map +1 -1
  106. package/dist/mount/local-mount-preflight.d.ts.map +1 -1
  107. package/dist/mount/local-mount-preflight.js +6 -2
  108. package/dist/mount/local-mount-preflight.js.map +1 -1
  109. package/dist/mount/relayfile-cloud-mount-client.d.ts +8 -2
  110. package/dist/mount/relayfile-cloud-mount-client.d.ts.map +1 -1
  111. package/dist/mount/relayfile-cloud-mount-client.js +11 -1
  112. package/dist/mount/relayfile-cloud-mount-client.js.map +1 -1
  113. package/dist/node/factory-node.d.ts +2 -0
  114. package/dist/node/factory-node.d.ts.map +1 -1
  115. package/dist/node/factory-node.js +107 -2
  116. package/dist/node/factory-node.js.map +1 -1
  117. package/dist/node/preview-process.d.ts +65 -0
  118. package/dist/node/preview-process.d.ts.map +1 -0
  119. package/dist/node/preview-process.js +431 -0
  120. package/dist/node/preview-process.js.map +1 -0
  121. package/dist/node/tailscale-preview.d.ts +45 -0
  122. package/dist/node/tailscale-preview.d.ts.map +1 -0
  123. package/dist/node/tailscale-preview.js +748 -0
  124. package/dist/node/tailscale-preview.js.map +1 -0
  125. package/dist/observability/events.d.ts +1838 -28
  126. package/dist/observability/events.d.ts.map +1 -1
  127. package/dist/observability/events.js +52 -0
  128. package/dist/observability/events.js.map +1 -1
  129. package/dist/orchestrator/factory.d.ts.map +1 -1
  130. package/dist/orchestrator/factory.js +1317 -61
  131. package/dist/orchestrator/factory.js.map +1 -1
  132. package/dist/orchestrator/index.d.ts +2 -1
  133. package/dist/orchestrator/index.d.ts.map +1 -1
  134. package/dist/orchestrator/index.js +1 -1
  135. package/dist/orchestrator/index.js.map +1 -1
  136. package/dist/orchestrator/reaper.d.ts +24 -0
  137. package/dist/orchestrator/reaper.d.ts.map +1 -1
  138. package/dist/orchestrator/reaper.js +117 -0
  139. package/dist/orchestrator/reaper.js.map +1 -1
  140. package/dist/ports/environment.d.ts +83 -0
  141. package/dist/ports/environment.d.ts.map +1 -0
  142. package/dist/ports/environment.js +2 -0
  143. package/dist/ports/environment.js.map +1 -0
  144. package/dist/ports/fleet.d.ts +68 -1
  145. package/dist/ports/fleet.d.ts.map +1 -1
  146. package/dist/ports/index.d.ts +3 -2
  147. package/dist/ports/index.d.ts.map +1 -1
  148. package/dist/ports/mount.d.ts +9 -0
  149. package/dist/ports/mount.d.ts.map +1 -1
  150. package/dist/ports/state.d.ts +17 -1
  151. package/dist/ports/state.d.ts.map +1 -1
  152. package/dist/ports/worktree.d.ts +14 -0
  153. package/dist/ports/worktree.d.ts.map +1 -1
  154. package/dist/state/file-state-store.js +28 -1
  155. package/dist/state/file-state-store.js.map +1 -1
  156. package/dist/subscriptions/index.d.ts +2 -0
  157. package/dist/subscriptions/index.d.ts.map +1 -1
  158. package/dist/subscriptions/index.js +1 -0
  159. package/dist/subscriptions/index.js.map +1 -1
  160. package/dist/subscriptions/resource-subscriptions.d.ts +77 -0
  161. package/dist/subscriptions/resource-subscriptions.d.ts.map +1 -0
  162. package/dist/subscriptions/resource-subscriptions.js +91 -0
  163. package/dist/subscriptions/resource-subscriptions.js.map +1 -0
  164. package/dist/testing/fakes.d.ts +9 -1
  165. package/dist/testing/fakes.d.ts.map +1 -1
  166. package/dist/testing/fakes.js +40 -0
  167. package/dist/testing/fakes.js.map +1 -1
  168. package/dist/triage/schema.d.ts +32 -32
  169. package/dist/types.d.ts +4 -1
  170. package/dist/types.d.ts.map +1 -1
  171. package/package.json +18 -4
  172. package/schemas/kubernetes-environment-stack.schema.json +86 -0
  173. package/schemas/verification-stack.schema.json +292 -0
@@ -0,0 +1,431 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { execFile, spawn } from 'node:child_process';
3
+ import { readdir, readFile, readlink } from 'node:fs/promises';
4
+ import { promisify } from 'node:util';
5
+ import { findAgentProcessByName, readProcessIdentity, } from '../orchestrator/process-identity.js';
6
+ import { terminatePids, } from '../orchestrator/reaper.js';
7
+ const DEFAULT_IDENTITY_TIMEOUT_MS = 5_000;
8
+ const DEFAULT_IDENTITY_POLL_INTERVAL_MS = 25;
9
+ const PREVIEW_CWD_ARGUMENT = '--factory-preview-cwd';
10
+ const PREVIEW_COMMAND_ARGUMENT = '--factory-preview-command';
11
+ const execFileAsync = promisify(execFile);
12
+ const PREVIEW_ENVIRONMENT_KEYS = new Set([
13
+ 'HOME',
14
+ 'LANG',
15
+ 'LOGNAME',
16
+ 'PATH',
17
+ 'SHELL',
18
+ 'TEMP',
19
+ 'TERM',
20
+ 'TMP',
21
+ 'TMPDIR',
22
+ 'USER',
23
+ ]);
24
+ // Keep the wrapper process alive while its configured command runs so the
25
+ // stable, Factory-owned marker remains visible in the wrapper's command line.
26
+ // The command itself runs in a child shell and receives termination through the
27
+ // ordinary process-tree teardown as well as this forwarding trap.
28
+ const PREVIEW_PROCESS_WRAPPER = [
29
+ 'child=',
30
+ 'forward_signal() {',
31
+ ' if [ -n "$child" ]; then',
32
+ ' kill -TERM "$child" 2>/dev/null || true',
33
+ ' fi',
34
+ '}',
35
+ 'trap forward_signal TERM INT HUP',
36
+ '/bin/sh -c "$6" &',
37
+ 'child=$!',
38
+ 'wait "$child"',
39
+ 'status=$?',
40
+ 'exit "$status"',
41
+ ].join('\n');
42
+ /**
43
+ * Owns repository preview commands independently of an agent PTY or Factory
44
+ * process. The persisted identity is exact enough to refuse recycled PIDs, and
45
+ * its deterministic marker lets startup recovery find the wrapper after a
46
+ * spawn/persist crash gap.
47
+ */
48
+ export class PreviewProcessSupervisor {
49
+ #shell;
50
+ #spawn;
51
+ #findProcess;
52
+ #readProcessIdentity;
53
+ #terminatePids;
54
+ #terminateOptions;
55
+ #sleep;
56
+ #identityTimeoutMs;
57
+ #identityPollIntervalMs;
58
+ #env;
59
+ #resolveListenerPids;
60
+ #readParentPid;
61
+ constructor(options = {}) {
62
+ this.#shell = options.shell ?? '/bin/sh';
63
+ this.#spawn = options.spawn ?? ((file, args, spawnOptions) => spawn(file, args, spawnOptions));
64
+ this.#readProcessIdentity = options.readProcessIdentity ?? readProcessIdentity;
65
+ this.#findProcess = options.findProcess ?? ((marker, findOptions) => findAgentProcessByName(marker, {
66
+ ...findOptions,
67
+ readProcessIdentity: this.#readProcessIdentity,
68
+ }));
69
+ this.#terminatePids = options.terminatePids ?? terminatePids;
70
+ this.#terminateOptions = options.terminateOptions ?? {};
71
+ this.#sleep = options.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
72
+ this.#identityTimeoutMs = options.identityTimeoutMs ?? DEFAULT_IDENTITY_TIMEOUT_MS;
73
+ this.#identityPollIntervalMs = options.identityPollIntervalMs ?? DEFAULT_IDENTITY_POLL_INTERVAL_MS;
74
+ this.#env = options.env ?? process.env;
75
+ const platform = options.platform ?? process.platform;
76
+ const procRoot = options.procRoot ?? '/proc';
77
+ const runListenerCommand = options.runListenerCommand ?? runCommand;
78
+ this.#resolveListenerPids = options.resolveListenerPids ?? (async (port) => await resolveListeningPids(port, platform, procRoot, runListenerCommand));
79
+ this.#readParentPid = options.readParentPid ?? (async (pid) => await readParentPid(pid, platform, procRoot, runListenerCommand));
80
+ }
81
+ async start(input) {
82
+ validateStartInput(input);
83
+ const marker = previewProcessMarker(input.id);
84
+ const cwdToken = encodeArgument(input.cwd);
85
+ const commandToken = digest(input.command);
86
+ const existing = await this.find(input.id);
87
+ if (existing) {
88
+ if (existing.cwd !== input.cwd ||
89
+ !commandTokenMatches(existing.cmdline, commandToken)) {
90
+ throw new Error(`Preview process marker ${marker} is already owned by a different command or checkout`);
91
+ }
92
+ return existing;
93
+ }
94
+ const child = this.#spawn(this.#shell, [
95
+ '-c',
96
+ PREVIEW_PROCESS_WRAPPER,
97
+ '--agent-name',
98
+ marker,
99
+ PREVIEW_CWD_ARGUMENT,
100
+ cwdToken,
101
+ PREVIEW_COMMAND_ARGUMENT,
102
+ commandToken,
103
+ input.command,
104
+ ], {
105
+ cwd: input.cwd,
106
+ detached: true,
107
+ env: previewEnvironment(this.#env, input.port),
108
+ stdio: 'ignore',
109
+ });
110
+ const pid = child.pid;
111
+ if (!Number.isInteger(pid) || (pid ?? 0) <= 0) {
112
+ throw new Error(`Unable to start preview process ${marker}: detached shell returned no PID`);
113
+ }
114
+ child.unref();
115
+ const identity = await this.#awaitIdentity(pid, marker, input.cwd, commandToken);
116
+ if (!identity) {
117
+ try {
118
+ // The PID came directly from this spawn call. Do not leave that known
119
+ // detached process behind merely because the platform identity lookup
120
+ // did not become observable before the deadline.
121
+ const report = await this.#terminatePids([pid], this.#terminateOptions);
122
+ const cleanupConfirmed = report.terminated.some((entry) => entry.pid === pid) ||
123
+ report.skipped.some((entry) => entry.pid === pid && entry.reason === 'pid not running');
124
+ if (!cleanupConfirmed) {
125
+ throw new Error(report.skipped.find((entry) => entry.pid === pid)?.reason ?? 'termination was not confirmed');
126
+ }
127
+ }
128
+ catch (cleanupError) {
129
+ throw new Error(`Preview process ${marker} started as PID ${pid} but its exact identity was not observable and the spawned process could not be terminated`, { cause: cleanupError });
130
+ }
131
+ throw new Error(`Preview process ${marker} started as PID ${pid} but its exact identity was not observable and was terminated`);
132
+ }
133
+ return identity;
134
+ }
135
+ async isRunning(identity) {
136
+ if (!validPersistedIdentity(identity))
137
+ return false;
138
+ const current = await this.#readProcessIdentity(identity.pid);
139
+ return Boolean(current && processIdentityMatches(identity, current));
140
+ }
141
+ async listenerOwnership(identity, port) {
142
+ // This is deliberately a point-in-time guard. Arbitrary development
143
+ // servers cannot inherit a reserved Factory socket, so eliminating the
144
+ // final check/use race would require socket activation or an intermediary
145
+ // proxy. Callers repeat this check during active reconciliation.
146
+ if (!validPersistedIdentity(identity) || !validPort(port) || !await this.isRunning(identity)) {
147
+ return 'indeterminate';
148
+ }
149
+ let listenerPids;
150
+ try {
151
+ listenerPids = await this.#resolveListenerPids(port);
152
+ }
153
+ catch {
154
+ return 'indeterminate';
155
+ }
156
+ if (!listenerPids || listenerPids.length === 0)
157
+ return 'indeterminate';
158
+ let indeterminate = false;
159
+ for (const pid of new Set(listenerPids)) {
160
+ const belongs = await this.#belongsToProcessTree(pid, identity.pid);
161
+ if (belongs === false)
162
+ return 'unrelated';
163
+ if (belongs === undefined)
164
+ indeterminate = true;
165
+ }
166
+ return indeterminate ? 'indeterminate' : 'owned';
167
+ }
168
+ async find(id) {
169
+ const marker = previewProcessMarker(id);
170
+ const resolution = await this.#findProcess(marker);
171
+ if (resolution.status === 'missing')
172
+ return undefined;
173
+ if (resolution.status === 'ambiguous') {
174
+ throw new Error(`Preview process marker ${marker} matched multiple process trees`);
175
+ }
176
+ const cwd = cwdFromCommandLine(resolution.identity.cmdline);
177
+ if (!cwd || !markerMatches(resolution.identity.cmdline, marker)) {
178
+ throw new Error(`Preview process marker ${marker} resolved to an invalid wrapper identity`);
179
+ }
180
+ return {
181
+ ...resolution.identity,
182
+ cwd,
183
+ marker,
184
+ };
185
+ }
186
+ async stop(identity) {
187
+ if (!validPersistedIdentity(identity))
188
+ return false;
189
+ const current = await this.#readProcessIdentity(identity.pid);
190
+ // Already absent is an idempotent success. A live but changed identity is
191
+ // a recycled PID and must never be signalled.
192
+ if (!current)
193
+ return true;
194
+ if (!processIdentityMatches(identity, current)) {
195
+ return false;
196
+ }
197
+ const report = await this.#terminatePids([identity.pid], this.#terminateOptions);
198
+ if (report.terminated.some((entry) => entry.pid === identity.pid)) {
199
+ return true;
200
+ }
201
+ // The wrapper can exit naturally between the identity check and the tree
202
+ // terminator's liveness probe. Count only confirmed absence as success; a
203
+ // recycled or changed identity remains a fail-closed false result.
204
+ return (await this.#readProcessIdentity(identity.pid)) === undefined;
205
+ }
206
+ async #awaitIdentity(pid, marker, cwd, commandToken) {
207
+ const interval = Math.max(1, this.#identityPollIntervalMs);
208
+ const attempts = Math.max(1, Math.ceil(Math.max(0, this.#identityTimeoutMs) / interval) + 1);
209
+ for (let attempt = 0; attempt < attempts; attempt += 1) {
210
+ const current = await this.#readProcessIdentity(pid);
211
+ if (current &&
212
+ markerMatches(current.cmdline, marker) &&
213
+ cwdFromCommandLine(current.cmdline) === cwd &&
214
+ commandTokenMatches(current.cmdline, commandToken)) {
215
+ return { ...current, cwd, marker };
216
+ }
217
+ if (attempt + 1 < attempts)
218
+ await this.#sleep(interval);
219
+ }
220
+ return undefined;
221
+ }
222
+ async #belongsToProcessTree(pid, rootPid) {
223
+ let current = pid;
224
+ const seen = new Set();
225
+ for (let depth = 0; depth < 256; depth += 1) {
226
+ if (current === rootPid)
227
+ return true;
228
+ if (!Number.isInteger(current) || current <= 1 || seen.has(current))
229
+ return false;
230
+ seen.add(current);
231
+ try {
232
+ const parent = await this.#readParentPid(current);
233
+ if (parent === undefined)
234
+ return undefined;
235
+ current = parent;
236
+ }
237
+ catch {
238
+ return undefined;
239
+ }
240
+ }
241
+ return undefined;
242
+ }
243
+ }
244
+ export function previewProcessMarker(id) {
245
+ const normalized = id.trim();
246
+ if (!normalized)
247
+ throw new Error('Preview process id must be non-empty');
248
+ return `factory-preview-${digest(normalized).slice(0, 32)}`;
249
+ }
250
+ function validateStartInput(input) {
251
+ previewProcessMarker(input.id);
252
+ if (!input.command.trim())
253
+ throw new Error('Preview process command must be non-empty');
254
+ if (!input.cwd.trim())
255
+ throw new Error('Preview process cwd must be non-empty');
256
+ if (!validPort(input.port)) {
257
+ throw new Error('Preview process port must be an integer between 1 and 65535');
258
+ }
259
+ }
260
+ const validPort = (port) => Number.isInteger(port) && port >= 1 && port <= 65_535;
261
+ function previewEnvironment(source, port) {
262
+ const environment = { PORT: String(port) };
263
+ for (const [key, value] of Object.entries(source)) {
264
+ if (value === undefined)
265
+ continue;
266
+ if (PREVIEW_ENVIRONMENT_KEYS.has(key) || key.startsWith('LC_')) {
267
+ environment[key] = value;
268
+ }
269
+ }
270
+ return environment;
271
+ }
272
+ function validPersistedIdentity(identity) {
273
+ return Number.isInteger(identity.pid) &&
274
+ identity.pid > 0 &&
275
+ Boolean(identity.startTime) &&
276
+ Boolean(identity.cmdline) &&
277
+ Boolean(identity.cwd) &&
278
+ /^factory-preview-[a-f0-9]{32}$/u.test(identity.marker) &&
279
+ markerMatches(identity.cmdline, identity.marker) &&
280
+ cwdFromCommandLine(identity.cmdline) === identity.cwd;
281
+ }
282
+ function processIdentityMatches(expected, current) {
283
+ return current.pid === expected.pid &&
284
+ current.startTime === expected.startTime &&
285
+ current.cmdline === expected.cmdline &&
286
+ markerMatches(current.cmdline, expected.marker) &&
287
+ cwdFromCommandLine(current.cmdline) === expected.cwd;
288
+ }
289
+ function markerMatches(cmdline, marker) {
290
+ const escaped = escapeRegExp(marker);
291
+ return new RegExp(`(^|\\s)--agent-name(\\s+|=)${escaped}(\\s|$)`, 'u').test(cmdline);
292
+ }
293
+ function commandTokenMatches(cmdline, token) {
294
+ return commandLineArgument(cmdline, PREVIEW_COMMAND_ARGUMENT) === token;
295
+ }
296
+ function cwdFromCommandLine(cmdline) {
297
+ const encoded = commandLineArgument(cmdline, PREVIEW_CWD_ARGUMENT);
298
+ if (!encoded)
299
+ return undefined;
300
+ try {
301
+ return Buffer.from(encoded, 'base64url').toString('utf8') || undefined;
302
+ }
303
+ catch {
304
+ return undefined;
305
+ }
306
+ }
307
+ function commandLineArgument(cmdline, name) {
308
+ const escaped = escapeRegExp(name);
309
+ return new RegExp(`(?:^|\\s)${escaped}(?:\\s+|=)([^\\s]+)(?:\\s|$)`, 'u').exec(cmdline)?.[1];
310
+ }
311
+ function encodeArgument(value) {
312
+ return Buffer.from(value, 'utf8').toString('base64url');
313
+ }
314
+ function digest(value) {
315
+ return createHash('sha256').update(value).digest('hex');
316
+ }
317
+ function escapeRegExp(value) {
318
+ return value.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&');
319
+ }
320
+ async function resolveListeningPids(port, platform, procRoot, run) {
321
+ if (!validPort(port))
322
+ return undefined;
323
+ if (platform === 'linux')
324
+ return await resolveLinuxListeningPids(port, procRoot);
325
+ if (platform === 'darwin')
326
+ return await resolveDarwinListeningPids(port, run);
327
+ return undefined;
328
+ }
329
+ async function resolveLinuxListeningPids(port, procRoot) {
330
+ const tables = await Promise.allSettled([
331
+ readFile(`${procRoot}/net/tcp`, 'utf8'),
332
+ readFile(`${procRoot}/net/tcp6`, 'utf8'),
333
+ ]);
334
+ const readableTables = tables.flatMap((result) => result.status === 'fulfilled' ? [result.value] : []);
335
+ if (readableTables.length === 0)
336
+ return undefined;
337
+ const socketInodes = new Set(readableTables.flatMap((table) => listeningSocketInodes(table, port)));
338
+ if (socketInodes.size === 0)
339
+ return [];
340
+ let processEntries;
341
+ try {
342
+ processEntries = await readdir(procRoot);
343
+ }
344
+ catch {
345
+ return undefined;
346
+ }
347
+ const owners = new Set();
348
+ await Promise.all(processEntries.filter((entry) => /^\d+$/u.test(entry)).map(async (entry) => {
349
+ let descriptors;
350
+ try {
351
+ descriptors = await readdir(`${procRoot}/${entry}/fd`);
352
+ }
353
+ catch {
354
+ return;
355
+ }
356
+ for (const descriptor of descriptors) {
357
+ try {
358
+ const target = await readlink(`${procRoot}/${entry}/fd/${descriptor}`);
359
+ const inode = /^socket:\[(\d+)\]$/u.exec(target)?.[1];
360
+ if (inode && socketInodes.has(inode)) {
361
+ owners.add(Number(entry));
362
+ return;
363
+ }
364
+ }
365
+ catch {
366
+ // Processes and descriptors can disappear during the scan.
367
+ }
368
+ }
369
+ }));
370
+ return [...owners];
371
+ }
372
+ function listeningSocketInodes(table, port) {
373
+ const expectedPort = port.toString(16).toUpperCase().padStart(4, '0');
374
+ const inodes = [];
375
+ for (const line of table.split(/\r?\n/u).slice(1)) {
376
+ const fields = line.trim().split(/\s+/u);
377
+ if (fields.length < 10)
378
+ continue;
379
+ const localPort = fields[1]?.split(':').at(-1)?.toUpperCase();
380
+ const state = fields[3]?.toUpperCase();
381
+ const inode = fields[9];
382
+ if (localPort === expectedPort && state === '0A' && /^\d+$/u.test(inode ?? '')) {
383
+ inodes.push(inode);
384
+ }
385
+ }
386
+ return inodes;
387
+ }
388
+ async function resolveDarwinListeningPids(port, run) {
389
+ try {
390
+ const output = await run('/usr/sbin/lsof', [
391
+ '-nP',
392
+ '-a',
393
+ `-iTCP:${port}`,
394
+ '-sTCP:LISTEN',
395
+ '-Fp',
396
+ ]);
397
+ return [...new Set(output.split(/\r?\n/u)
398
+ .filter((line) => /^p\d+$/u.test(line))
399
+ .map((line) => Number(line.slice(1))))];
400
+ }
401
+ catch {
402
+ return undefined;
403
+ }
404
+ }
405
+ async function readParentPid(pid, platform, procRoot, run) {
406
+ if (platform === 'linux') {
407
+ try {
408
+ const status = await readFile(`${procRoot}/${pid}/status`, 'utf8');
409
+ const parent = Number(/^PPid:\s+(\d+)$/mu.exec(status)?.[1]);
410
+ return Number.isInteger(parent) && parent >= 0 ? parent : undefined;
411
+ }
412
+ catch {
413
+ return undefined;
414
+ }
415
+ }
416
+ if (platform === 'darwin') {
417
+ try {
418
+ const parent = Number((await run('/bin/ps', ['-o', 'ppid=', '-p', String(pid)])).trim());
419
+ return Number.isInteger(parent) && parent >= 0 ? parent : undefined;
420
+ }
421
+ catch {
422
+ return undefined;
423
+ }
424
+ }
425
+ return undefined;
426
+ }
427
+ const runCommand = async (file, args) => {
428
+ const result = await execFileAsync(file, args, { encoding: 'utf8' });
429
+ return result.stdout;
430
+ };
431
+ //# sourceMappingURL=preview-process.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preview-process.js","sourceRoot":"","sources":["../../src/node/preview-process.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { PreviewConfig } from '../config/schema.js';
2
+ import type { PreviewReference, PreviewStartInput, PreviewSweepInput, PreviewSweepResult } from '../ports/fleet.js';
3
+ import { PreviewProcessSupervisor } from './preview-process.js';
4
+ type CommandResult = {
5
+ stdout: string;
6
+ stderr: string;
7
+ };
8
+ export type PreviewCommandRunner = (file: string, args: string[]) => Promise<CommandResult>;
9
+ export type PreviewPortProbe = (port: number) => Promise<boolean>;
10
+ export type PreviewReadyProbe = (port: number) => Promise<boolean>;
11
+ export type PreviewPublishedProbe = (url: string) => Promise<boolean>;
12
+ type PreviewProcessController = Pick<PreviewProcessSupervisor, 'start' | 'isRunning' | 'find' | 'stop'> & Partial<Pick<PreviewProcessSupervisor, 'listenerOwnership'>>;
13
+ export interface PreviewManager {
14
+ start(input: PreviewStartInput): Promise<PreviewReference>;
15
+ remove(preview: PreviewReference): Promise<boolean>;
16
+ sweep(input: PreviewSweepInput): Promise<PreviewSweepResult>;
17
+ }
18
+ export interface TailscalePreviewManagerOptions {
19
+ config: PreviewConfig;
20
+ run?: PreviewCommandRunner;
21
+ isPortAvailable?: PreviewPortProbe;
22
+ isReady?: PreviewReadyProbe;
23
+ isPublishedReady?: PreviewPublishedProbe;
24
+ processSupervisor?: PreviewProcessController;
25
+ sleep?: (ms: number) => Promise<void>;
26
+ readyTimeoutMs?: number;
27
+ publishedReadyTimeoutMs?: number;
28
+ readyPollIntervalMs?: number;
29
+ now?: () => Date;
30
+ }
31
+ /**
32
+ * Thin lifecycle adapter around Tailscale Serve. `tailscaled` owns background
33
+ * proxying, while this registry records the exact routes Factory may remove.
34
+ * Every destructive operation checks the live Serve target before issuing
35
+ * `off`, so a stale registry can never turn off a port repurposed by a human.
36
+ */
37
+ export declare class TailscalePreviewManager implements PreviewManager {
38
+ #private;
39
+ constructor(options: TailscalePreviewManagerOptions);
40
+ start(input: PreviewStartInput): Promise<PreviewReference>;
41
+ remove(reference: PreviewReference): Promise<boolean>;
42
+ sweep(input: PreviewSweepInput): Promise<PreviewSweepResult>;
43
+ }
44
+ export {};
45
+ //# sourceMappingURL=tailscale-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tailscale-preview.d.ts","sourceRoot":"","sources":["../../src/node/tailscale-preview.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACrD,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EACL,wBAAwB,EAEzB,MAAM,mBAAmB,CAAA;AAwB1B,KAAK,aAAa,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AACvD,MAAM,MAAM,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;AAC3F,MAAM,MAAM,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AACjE,MAAM,MAAM,iBAAiB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAClE,MAAM,MAAM,qBAAqB,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AACrE,KAAK,wBAAwB,GAC3B,IAAI,CAAC,wBAAwB,EAAE,OAAO,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC,GACvE,OAAO,CAAC,IAAI,CAAC,wBAAwB,EAAE,mBAAmB,CAAC,CAAC,CAAA;AAE9D,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAA;IAC1D,MAAM,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IACnD,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAA;CAC7D;AAED,MAAM,WAAW,8BAA8B;IAC7C,MAAM,EAAE,aAAa,CAAA;IACrB,GAAG,CAAC,EAAE,oBAAoB,CAAA;IAC1B,eAAe,CAAC,EAAE,gBAAgB,CAAA;IAClC,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,gBAAgB,CAAC,EAAE,qBAAqB,CAAA;IACxC,iBAAiB,CAAC,EAAE,wBAAwB,CAAA;IAC5C,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACrC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,GAAG,CAAC,EAAE,MAAM,IAAI,CAAA;CACjB;AAED;;;;;GAKG;AACH,qBAAa,uBAAwB,YAAW,cAAc;;gBAchD,OAAO,EAAE,8BAA8B;IAoB7C,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4L1D,MAAM,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiDrD,KAAK,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CAmTnE"}