@owlmeans/viable-sdk 0.1.18-rc.1
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/README.md +128 -0
- package/build/api/index.d.ts +2 -0
- package/build/api/index.d.ts.map +1 -0
- package/build/api/index.js +2 -0
- package/build/api/index.js.map +1 -0
- package/build/api/remote.d.ts +14 -0
- package/build/api/remote.d.ts.map +1 -0
- package/build/api/remote.js +123 -0
- package/build/api/remote.js.map +1 -0
- package/build/consts.d.ts +47 -0
- package/build/consts.d.ts.map +1 -0
- package/build/consts.js +47 -0
- package/build/consts.js.map +1 -0
- package/build/context/index.d.ts +22 -0
- package/build/context/index.d.ts.map +1 -0
- package/build/context/index.js +92 -0
- package/build/context/index.js.map +1 -0
- package/build/errors.d.ts +21 -0
- package/build/errors.d.ts.map +1 -0
- package/build/errors.js +36 -0
- package/build/errors.js.map +1 -0
- package/build/executor/boot-check.d.ts +73 -0
- package/build/executor/boot-check.d.ts.map +1 -0
- package/build/executor/boot-check.js +155 -0
- package/build/executor/boot-check.js.map +1 -0
- package/build/executor/env.d.ts +25 -0
- package/build/executor/env.d.ts.map +1 -0
- package/build/executor/env.js +77 -0
- package/build/executor/env.js.map +1 -0
- package/build/executor/errors.d.ts +69 -0
- package/build/executor/errors.d.ts.map +1 -0
- package/build/executor/errors.js +80 -0
- package/build/executor/errors.js.map +1 -0
- package/build/executor/files.d.ts +124 -0
- package/build/executor/files.d.ts.map +1 -0
- package/build/executor/files.js +529 -0
- package/build/executor/files.js.map +1 -0
- package/build/executor/git.d.ts +52 -0
- package/build/executor/git.d.ts.map +1 -0
- package/build/executor/git.js +353 -0
- package/build/executor/git.js.map +1 -0
- package/build/executor/health.d.ts +92 -0
- package/build/executor/health.d.ts.map +1 -0
- package/build/executor/health.js +98 -0
- package/build/executor/health.js.map +1 -0
- package/build/executor/index.d.ts +39 -0
- package/build/executor/index.d.ts.map +1 -0
- package/build/executor/index.js +173 -0
- package/build/executor/index.js.map +1 -0
- package/build/executor/integrity.d.ts +17 -0
- package/build/executor/integrity.d.ts.map +1 -0
- package/build/executor/integrity.js +59 -0
- package/build/executor/integrity.js.map +1 -0
- package/build/executor/layout.d.ts +61 -0
- package/build/executor/layout.d.ts.map +1 -0
- package/build/executor/layout.js +98 -0
- package/build/executor/layout.js.map +1 -0
- package/build/executor/shell.d.ts +89 -0
- package/build/executor/shell.d.ts.map +1 -0
- package/build/executor/shell.js +280 -0
- package/build/executor/shell.js.map +1 -0
- package/build/executor/spawn.d.ts +111 -0
- package/build/executor/spawn.d.ts.map +1 -0
- package/build/executor/spawn.js +314 -0
- package/build/executor/spawn.js.map +1 -0
- package/build/harness/index.d.ts +28 -0
- package/build/harness/index.d.ts.map +1 -0
- package/build/harness/index.js +83 -0
- package/build/harness/index.js.map +1 -0
- package/build/harness/templates.d.ts +30 -0
- package/build/harness/templates.d.ts.map +1 -0
- package/build/harness/templates.js +162 -0
- package/build/harness/templates.js.map +1 -0
- package/build/index.d.ts +13 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +12 -0
- package/build/index.js.map +1 -0
- package/build/project/env.d.ts +108 -0
- package/build/project/env.d.ts.map +1 -0
- package/build/project/env.js +233 -0
- package/build/project/env.js.map +1 -0
- package/build/project/marker.d.ts +34 -0
- package/build/project/marker.d.ts.map +1 -0
- package/build/project/marker.js +54 -0
- package/build/project/marker.js.map +1 -0
- package/build/project/setup.d.ts +62 -0
- package/build/project/setup.d.ts.map +1 -0
- package/build/project/setup.js +190 -0
- package/build/project/setup.js.map +1 -0
- package/build/run/index.d.ts +75 -0
- package/build/run/index.d.ts.map +1 -0
- package/build/run/index.js +150 -0
- package/build/run/index.js.map +1 -0
- package/build/run/serve.d.ts +18 -0
- package/build/run/serve.d.ts.map +1 -0
- package/build/run/serve.js +148 -0
- package/build/run/serve.js.map +1 -0
- package/build/run/state.d.ts +75 -0
- package/build/run/state.d.ts.map +1 -0
- package/build/run/state.js +136 -0
- package/build/run/state.js.map +1 -0
- package/build/session/index.d.ts +17 -0
- package/build/session/index.d.ts.map +1 -0
- package/build/session/index.js +226 -0
- package/build/session/index.js.map +1 -0
- package/build/session/questions.d.ts +16 -0
- package/build/session/questions.d.ts.map +1 -0
- package/build/session/questions.js +17 -0
- package/build/session/questions.js.map +1 -0
- package/build/session/queue.d.ts +54 -0
- package/build/session/queue.d.ts.map +1 -0
- package/build/session/queue.js +102 -0
- package/build/session/queue.js.map +1 -0
- package/build/session/tasks.d.ts +15 -0
- package/build/session/tasks.d.ts.map +1 -0
- package/build/session/tasks.js +16 -0
- package/build/session/tasks.js.map +1 -0
- package/build/task/driver.d.ts +30 -0
- package/build/task/driver.d.ts.map +1 -0
- package/build/task/driver.js +120 -0
- package/build/task/driver.js.map +1 -0
- package/build/task/envelope.d.ts +35 -0
- package/build/task/envelope.d.ts.map +1 -0
- package/build/task/envelope.js +230 -0
- package/build/task/envelope.js.map +1 -0
- package/build/task/index.d.ts +4 -0
- package/build/task/index.d.ts.map +1 -0
- package/build/task/index.js +4 -0
- package/build/task/index.js.map +1 -0
- package/build/task/inquiry.d.ts +53 -0
- package/build/task/inquiry.d.ts.map +1 -0
- package/build/task/inquiry.js +232 -0
- package/build/task/inquiry.js.map +1 -0
- package/build/tools/catalogue.d.ts +17 -0
- package/build/tools/catalogue.d.ts.map +1 -0
- package/build/tools/catalogue.js +1169 -0
- package/build/tools/catalogue.js.map +1 -0
- package/build/tools/index.d.ts +7 -0
- package/build/tools/index.d.ts.map +1 -0
- package/build/tools/index.js +7 -0
- package/build/tools/index.js.map +1 -0
- package/build/tools/jobs.d.ts +12 -0
- package/build/tools/jobs.d.ts.map +1 -0
- package/build/tools/jobs.js +60 -0
- package/build/tools/jobs.js.map +1 -0
- package/build/tools/mcp.d.ts +43 -0
- package/build/tools/mcp.d.ts.map +1 -0
- package/build/tools/mcp.js +131 -0
- package/build/tools/mcp.js.map +1 -0
- package/build/tools/platform.d.ts +77 -0
- package/build/tools/platform.d.ts.map +1 -0
- package/build/tools/platform.js +316 -0
- package/build/tools/platform.js.map +1 -0
- package/build/tools/refusal.d.ts +66 -0
- package/build/tools/refusal.d.ts.map +1 -0
- package/build/tools/refusal.js +377 -0
- package/build/tools/refusal.js.map +1 -0
- package/build/tools/types.d.ts +83 -0
- package/build/tools/types.d.ts.map +1 -0
- package/build/tools/types.js +38 -0
- package/build/tools/types.js.map +1 -0
- package/build/types.d.ts +174 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/types.js.map +1 -0
- package/package.json +105 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
import { exec, spawn } from 'node:child_process';
|
|
2
|
+
import net from 'node:net';
|
|
3
|
+
import fsp from 'node:fs/promises';
|
|
4
|
+
/**
|
|
5
|
+
* Everything that starts, bounds or ends a child process on the developer's machine.
|
|
6
|
+
*
|
|
7
|
+
* Shared by the shell commands, the boot check and the local run so the three cannot disagree
|
|
8
|
+
* about what a failure looks like or when a port is free — the publisher learned both lessons the
|
|
9
|
+
* expensive way, and neither of them is about Kubernetes.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Output ceiling for every validate/build child process.
|
|
13
|
+
*
|
|
14
|
+
* Node's default is 1 MiB, and a target project with a few hundred type errors exceeds it: the
|
|
15
|
+
* child is killed and the fixer receives `stdout maxBuffer length exceeded` instead of the errors
|
|
16
|
+
* it is supposed to repair.
|
|
17
|
+
*/
|
|
18
|
+
export const MAX_OUTPUT_BUFFER = 10 * 1024 * 1024;
|
|
19
|
+
/** One-shot script ceiling. A build that outlives it is wedged, not slow. */
|
|
20
|
+
export const BUILD_TIMEOUT = 300_000;
|
|
21
|
+
/** How long a port may stay bound after the process holding it was told to die. */
|
|
22
|
+
const PORT_FREE_TIMEOUT = 10_000;
|
|
23
|
+
const PORT_POLL_MS = 200;
|
|
24
|
+
const TERM_TIMEOUT = 5_000;
|
|
25
|
+
const KILL_TIMEOUT = 2_000;
|
|
26
|
+
/**
|
|
27
|
+
* Compose a failed command's output into the text a fixer reads.
|
|
28
|
+
*
|
|
29
|
+
* Never interpolate the `ExecException` beside `stderr`: its string form is
|
|
30
|
+
* `Error: Command failed: <cmd>\n<stderr>`, so the naive `${stdout} ${error} ${stderr}` shape
|
|
31
|
+
* emitted every diagnostic twice and prefixed a runner sentence that is not a diagnostic at all.
|
|
32
|
+
* Both survive into the fix conversation — the duplicate doubles the prompt for nothing, and the
|
|
33
|
+
* preamble is what a model latches onto when it cannot see a real cause. Say it once, and say
|
|
34
|
+
* what actually ran only when there is nothing else to report.
|
|
35
|
+
*/
|
|
36
|
+
export const failureOutput = (error, stdout, stderr, cmd) => {
|
|
37
|
+
const body = [stdout, stderr].map(part => part.trim()).filter(Boolean).join('\n');
|
|
38
|
+
const code = error?.code ?? 1;
|
|
39
|
+
return body !== '' ? `${body}\nexit ${code}: ${cmd}` : `exit ${code}: ${cmd}`;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* Run a shell command and answer "error text, or null".
|
|
43
|
+
*
|
|
44
|
+
* The one contract every shell command here shares. A caller never has to know whether the child
|
|
45
|
+
* exited non-zero, failed to spawn or produced nothing — those are all one answer.
|
|
46
|
+
*/
|
|
47
|
+
export const runCommand = async (cmd, options) => await new Promise(resolve => {
|
|
48
|
+
exec(cmd, {
|
|
49
|
+
cwd: options.cwd,
|
|
50
|
+
maxBuffer: MAX_OUTPUT_BUFFER,
|
|
51
|
+
env: options.env != null ? { ...process.env, ...options.env } : process.env,
|
|
52
|
+
}, (error, stdout, stderr) => {
|
|
53
|
+
if (error != null) {
|
|
54
|
+
return resolve(options.stdoutOnly === true
|
|
55
|
+
? stdout
|
|
56
|
+
: failureOutput(error, stdout, stderr, cmd));
|
|
57
|
+
}
|
|
58
|
+
resolve(null);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
/**
|
|
62
|
+
* Run one of the target's own `scripts.*`, bounded.
|
|
63
|
+
*
|
|
64
|
+
* `spawn` rather than `exec` because a build's output is unbounded and streaming it costs nothing,
|
|
65
|
+
* and because a wedged `bunx` resolving forever must die rather than hold the caller open. The
|
|
66
|
+
* timeout is reported as a verdict, not thrown, so it reaches the same channel a failed build does.
|
|
67
|
+
*/
|
|
68
|
+
export const runScript = async (script, cwd, env) => await new Promise(resolve => {
|
|
69
|
+
const proc = spawn('bun', ['run', script], {
|
|
70
|
+
cwd,
|
|
71
|
+
shell: true,
|
|
72
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
73
|
+
env: { ...process.env, ...(env ?? {}) },
|
|
74
|
+
});
|
|
75
|
+
let out = '';
|
|
76
|
+
let err = '';
|
|
77
|
+
let settled = false;
|
|
78
|
+
const finish = (value) => {
|
|
79
|
+
if (settled)
|
|
80
|
+
return;
|
|
81
|
+
settled = true;
|
|
82
|
+
clearTimeout(timer);
|
|
83
|
+
resolve(value);
|
|
84
|
+
};
|
|
85
|
+
const timer = setTimeout(() => {
|
|
86
|
+
try {
|
|
87
|
+
proc.kill('SIGKILL');
|
|
88
|
+
}
|
|
89
|
+
catch { /* already gone */ }
|
|
90
|
+
finish(`${script} timed out after ${BUILD_TIMEOUT}ms`);
|
|
91
|
+
}, BUILD_TIMEOUT);
|
|
92
|
+
timer.unref?.();
|
|
93
|
+
proc.stdout?.on('data', chunk => { out += chunk.toString(); });
|
|
94
|
+
proc.stderr?.on('data', chunk => { err += chunk.toString(); });
|
|
95
|
+
// A spawn error never reaches the exit handler, so it is answered here or it is lost.
|
|
96
|
+
proc.on('error', error => finish(`${error}`));
|
|
97
|
+
proc.on('exit', code => finish(code === 0 ? null : `${out}\n${err}`));
|
|
98
|
+
});
|
|
99
|
+
/**
|
|
100
|
+
* Bound one whole dispatch, whatever it is.
|
|
101
|
+
*
|
|
102
|
+
* Every operation below already bounds itself, but one that wedges AROUND its own bound — a lock
|
|
103
|
+
* nothing releases, a promise that never settles — holds the caller open with nothing to report,
|
|
104
|
+
* and the caller's timeout becomes the only limit. Reaching this means the operation failed to
|
|
105
|
+
* bound itself, not that it needed longer.
|
|
106
|
+
*/
|
|
107
|
+
export const withDeadline = async (label, ms, fn) => {
|
|
108
|
+
let timer;
|
|
109
|
+
try {
|
|
110
|
+
return await Promise.race([
|
|
111
|
+
fn(),
|
|
112
|
+
new Promise((_, reject) => {
|
|
113
|
+
timer = setTimeout(() => reject(new Error(`Slot command timed out: ${label} after ${ms}ms`)), ms);
|
|
114
|
+
timer.unref?.();
|
|
115
|
+
}),
|
|
116
|
+
]);
|
|
117
|
+
}
|
|
118
|
+
finally {
|
|
119
|
+
if (timer != null)
|
|
120
|
+
clearTimeout(timer);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
/** Whether anything answers a TCP connect on a local port. */
|
|
124
|
+
export const probeListening = async (port, timeoutMs = 1_000) => await new Promise(resolve => {
|
|
125
|
+
const socket = net.connect({ host: '127.0.0.1', port });
|
|
126
|
+
const done = (value) => {
|
|
127
|
+
socket.removeAllListeners();
|
|
128
|
+
socket.destroy();
|
|
129
|
+
resolve(value);
|
|
130
|
+
};
|
|
131
|
+
socket.setTimeout(timeoutMs);
|
|
132
|
+
socket.once('connect', () => done(true));
|
|
133
|
+
socket.once('timeout', () => done(false));
|
|
134
|
+
socket.once('error', () => done(false));
|
|
135
|
+
});
|
|
136
|
+
/**
|
|
137
|
+
* Wait until nothing answers on a local port.
|
|
138
|
+
*
|
|
139
|
+
* The child spawned here is a shell wrapping `bun`, so the shell's exit is not proof the target is
|
|
140
|
+
* gone: a signal the shell dies from and `bun` survives leaves an orphan that still owns the port.
|
|
141
|
+
* Whether the port answers is the only fact that decides whether a replacement can bind, so a
|
|
142
|
+
* restart waits on that and never on an exit event.
|
|
143
|
+
*/
|
|
144
|
+
export const waitForPortFree = async (port, timeoutMs = PORT_FREE_TIMEOUT, pollMs = PORT_POLL_MS) => {
|
|
145
|
+
const deadline = Date.now() + timeoutMs;
|
|
146
|
+
for (;;) {
|
|
147
|
+
if (!await probeListening(port)) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
if (Date.now() >= deadline) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
await delay(pollMs);
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Terminate a detached child's whole process group and wait until it is actually gone.
|
|
158
|
+
*
|
|
159
|
+
* Awaiting matters: the caller restarts right after, and a process still holding the port makes
|
|
160
|
+
* the replacement lose the bind and exit — leaving nothing listening and no error anyone reads.
|
|
161
|
+
*/
|
|
162
|
+
export const killGroupAndWait = async (proc, options = {}) => {
|
|
163
|
+
const term = options.term ?? TERM_TIMEOUT;
|
|
164
|
+
const kill = options.kill ?? KILL_TIMEOUT;
|
|
165
|
+
const pid = proc.pid;
|
|
166
|
+
// NEVER an early return on the child's own exit code. The child is a shell wrapping `bun`, so a
|
|
167
|
+
// signal the shell dies from leaves `bun` alive and holding the port while `exitCode` says it is
|
|
168
|
+
// gone — the exact shape that leaves a stray server running on somebody's machine and every
|
|
169
|
+
// later boot check failing with "the api port is already in use".
|
|
170
|
+
signalGroup(pid, 'SIGTERM');
|
|
171
|
+
if (await gone(pid, term))
|
|
172
|
+
return;
|
|
173
|
+
signalGroup(pid, 'SIGKILL');
|
|
174
|
+
await gone(pid, kill);
|
|
175
|
+
};
|
|
176
|
+
/** Whether a process group is still around. EPERM counts as alive: it exists and is not ours. */
|
|
177
|
+
const groupAlive = (pid) => {
|
|
178
|
+
if (pid == null)
|
|
179
|
+
return false;
|
|
180
|
+
try {
|
|
181
|
+
process.kill(-pid, 0);
|
|
182
|
+
return true;
|
|
183
|
+
}
|
|
184
|
+
catch (e) {
|
|
185
|
+
if (e.code === 'EPERM')
|
|
186
|
+
return true;
|
|
187
|
+
try {
|
|
188
|
+
process.kill(pid, 0);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
catch (own) {
|
|
192
|
+
return own.code === 'EPERM';
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Wait until the whole GROUP is gone, or the budget runs out.
|
|
198
|
+
*
|
|
199
|
+
* Polled rather than awaited on the child's `exit` event, because that event is about the shell
|
|
200
|
+
* and the thing worth waiting for is whatever it started.
|
|
201
|
+
*/
|
|
202
|
+
const gone = async (pid, budgetMs) => {
|
|
203
|
+
const deadline = Date.now() + budgetMs;
|
|
204
|
+
for (;;) {
|
|
205
|
+
if (!groupAlive(pid))
|
|
206
|
+
return true;
|
|
207
|
+
if (Date.now() >= deadline)
|
|
208
|
+
return false;
|
|
209
|
+
await delay(50);
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
/** What every target process runs; the marker is what tells the three of them apart. */
|
|
213
|
+
const TARGET_SCRIPT = 'dist/index.js';
|
|
214
|
+
/**
|
|
215
|
+
* Take a port back from a leftover running the same command.
|
|
216
|
+
*
|
|
217
|
+
* A connector that was killed — a host restart, a Ctrl-C, a crashed run — leaves its DETACHED
|
|
218
|
+
* children alive, because detaching them is what keeps a build from dying with the tool that
|
|
219
|
+
* started it. What survives holds the target's port, and every later attempt then fails with the
|
|
220
|
+
* target's own "the api port is already in use", which reads as a defect in the generated app.
|
|
221
|
+
*
|
|
222
|
+
* Matched by the marker the spawn carries, never by the port alone: a process this connector did
|
|
223
|
+
* not start is not ours to signal, whatever it is sitting on.
|
|
224
|
+
*/
|
|
225
|
+
export const reclaimPort = async (port, marker) => {
|
|
226
|
+
if (!await probeListening(port))
|
|
227
|
+
return true;
|
|
228
|
+
// BOTH the script and the marker. A marker alone would match any process whose command line
|
|
229
|
+
// merely mentions it — a shell the user is typing in, a grep, an editor — and this sends SIGKILL.
|
|
230
|
+
const orphans = await findProcesses([TARGET_SCRIPT, marker]);
|
|
231
|
+
if (orphans.length < 1)
|
|
232
|
+
return false;
|
|
233
|
+
for (const pid of orphans) {
|
|
234
|
+
try {
|
|
235
|
+
process.kill(pid, 'SIGKILL');
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
// Already gone.
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return await waitForPortFree(port);
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* The pids whose command line carries a marker.
|
|
245
|
+
*
|
|
246
|
+
* `/proc` rather than `ps`, for the same reason the publisher reads it: no shell, no parsing of a
|
|
247
|
+
* format that differs per platform. Somewhere without `/proc` simply has nothing to reclaim, which
|
|
248
|
+
* is the honest answer there.
|
|
249
|
+
*/
|
|
250
|
+
export const findProcesses = async (needles) => {
|
|
251
|
+
const wanted = Array.isArray(needles) ? needles : [needles];
|
|
252
|
+
const pids = [];
|
|
253
|
+
let entries;
|
|
254
|
+
try {
|
|
255
|
+
entries = await fsp.readdir('/proc');
|
|
256
|
+
}
|
|
257
|
+
catch {
|
|
258
|
+
return pids;
|
|
259
|
+
}
|
|
260
|
+
for (const entry of entries) {
|
|
261
|
+
const pid = Number(entry);
|
|
262
|
+
if (!Number.isInteger(pid) || pid === process.pid)
|
|
263
|
+
continue;
|
|
264
|
+
try {
|
|
265
|
+
const cmdline = (await fsp.readFile(`/proc/${entry}/cmdline`, 'utf8')).replace(/\0/g, ' ').trim();
|
|
266
|
+
if (cmdline !== '' && wanted.every(needle => cmdline.includes(needle)))
|
|
267
|
+
pids.push(pid);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
// Ended mid-scan, or not ours to read — either way not a target.
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return pids;
|
|
274
|
+
};
|
|
275
|
+
/**
|
|
276
|
+
* Signal a process GROUP, falling back to the process.
|
|
277
|
+
*
|
|
278
|
+
* The negative pid is the point: a child spawned detached through a shell survives a signal aimed
|
|
279
|
+
* at the shell's own pid, and what survives is the `bun` process holding the port.
|
|
280
|
+
*/
|
|
281
|
+
export const signalGroup = (pid, signal) => {
|
|
282
|
+
if (pid == null)
|
|
283
|
+
return false;
|
|
284
|
+
try {
|
|
285
|
+
process.kill(-pid, signal);
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
288
|
+
catch {
|
|
289
|
+
try {
|
|
290
|
+
process.kill(pid, signal);
|
|
291
|
+
return true;
|
|
292
|
+
}
|
|
293
|
+
catch {
|
|
294
|
+
return false;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
/** Whether a recorded pid is still a live process. */
|
|
299
|
+
export const isAlive = (pid) => {
|
|
300
|
+
if (pid == null)
|
|
301
|
+
return false;
|
|
302
|
+
try {
|
|
303
|
+
process.kill(pid, 0);
|
|
304
|
+
return true;
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
export const delay = async (ms) => await new Promise(resolve => {
|
|
311
|
+
const timer = setTimeout(resolve, ms);
|
|
312
|
+
timer.unref?.();
|
|
313
|
+
});
|
|
314
|
+
//# sourceMappingURL=spawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spawn.js","sourceRoot":"","sources":["../../src/executor/spawn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { ConnectHarness } from '@owlmeans/viable-common';
|
|
2
|
+
import { ENV_TOKEN } from '../consts.js';
|
|
3
|
+
import type { HarnessFile } from './templates.js';
|
|
4
|
+
export * from './templates.js';
|
|
5
|
+
export interface InstallResult {
|
|
6
|
+
written: string[];
|
|
7
|
+
skipped: string[];
|
|
8
|
+
}
|
|
9
|
+
/** What would be written, without writing it. */
|
|
10
|
+
export declare const describeHarness: (harness: ConnectHarness) => HarnessFile[];
|
|
11
|
+
export interface InstallOptions {
|
|
12
|
+
/** Whether to write the MCP server entry, which names a file the agent's own tooling owns. */
|
|
13
|
+
mcpConfig?: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Set a coding agent up to work with the platform.
|
|
17
|
+
*
|
|
18
|
+
* Idempotent by construction: a section is replaced between its markers, a JSON entry is merged
|
|
19
|
+
* under its own key, and a whole file is only rewritten when its content actually differs. Running
|
|
20
|
+
* it twice changes nothing, which is what makes it safe to offer as a tool the agent may call
|
|
21
|
+
* whenever it is unsure.
|
|
22
|
+
*
|
|
23
|
+
* No file it writes contains the token — each configuration references the environment variable in
|
|
24
|
+
* whatever syntax its harness uses, so the result is safe to commit.
|
|
25
|
+
*/
|
|
26
|
+
export declare const installHarness: (dir: string, harness: ConnectHarness, opts?: InstallOptions) => Promise<InstallResult>;
|
|
27
|
+
export { ENV_TOKEN };
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AAEjD,cAAc,gBAAgB,CAAA;AAK9B,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,OAAO,EAAE,MAAM,EAAE,CAAA;CAClB;AAED,iDAAiD;AACjD,eAAO,MAAM,eAAe,YAAa,cAAc,KAAG,WAAW,EAA2B,CAAA;AAyChG,MAAM,WAAW,cAAc;IAC7B,8FAA8F;IAC9F,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,cAAc,QACpB,MAAM,WAAW,cAAc,SAAQ,cAAc,KACzD,OAAO,CAAC,aAAa,CA6BvB,CAAA;AAED,OAAO,EAAE,SAAS,EAAE,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { ENV_TOKEN } from '../consts.js';
|
|
4
|
+
import { harnessFiles } from './templates.js';
|
|
5
|
+
export * from './templates.js';
|
|
6
|
+
const BEGIN = '<!-- viable:begin -->';
|
|
7
|
+
const END = '<!-- viable:end -->';
|
|
8
|
+
/** What would be written, without writing it. */
|
|
9
|
+
export const describeHarness = (harness) => harnessFiles(harness);
|
|
10
|
+
/**
|
|
11
|
+
* Replace only the block this connector owns, leaving everything a person wrote alone.
|
|
12
|
+
*
|
|
13
|
+
* An instruction file belongs to its project: overwriting it to add a paragraph would delete
|
|
14
|
+
* whatever else was in it, and appending unconditionally would grow a duplicate on every install.
|
|
15
|
+
* The markers make the update idempotent and the ownership visible to whoever reads the file next.
|
|
16
|
+
*/
|
|
17
|
+
const mergeSection = (existing, section) => {
|
|
18
|
+
const from = existing.indexOf(BEGIN);
|
|
19
|
+
const to = existing.indexOf(END);
|
|
20
|
+
if (from >= 0 && to > from) {
|
|
21
|
+
return existing.slice(0, from) + section + existing.slice(to + END.length);
|
|
22
|
+
}
|
|
23
|
+
return existing.trimEnd() === '' ? `${section}\n` : `${existing.trimEnd()}\n\n${section}\n`;
|
|
24
|
+
};
|
|
25
|
+
/** Merge one key into a JSON configuration the project also uses for other things. */
|
|
26
|
+
const mergeJson = (existing, keys, value) => {
|
|
27
|
+
let root = {};
|
|
28
|
+
if (existing.trim() !== '') {
|
|
29
|
+
try {
|
|
30
|
+
root = JSON.parse(existing);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// A configuration we cannot parse is one somebody is editing. Refusing to touch it is the
|
|
34
|
+
// only safe answer — overwriting would destroy every other server they had configured.
|
|
35
|
+
throw new Error('the existing configuration is not valid JSON; fix it and install again');
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
let cursor = root;
|
|
39
|
+
for (const key of keys.slice(0, -1)) {
|
|
40
|
+
if (typeof cursor[key] !== 'object' || cursor[key] == null)
|
|
41
|
+
cursor[key] = {};
|
|
42
|
+
cursor = cursor[key];
|
|
43
|
+
}
|
|
44
|
+
cursor[keys[keys.length - 1]] = value;
|
|
45
|
+
return `${JSON.stringify(root, null, 2)}\n`;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Set a coding agent up to work with the platform.
|
|
49
|
+
*
|
|
50
|
+
* Idempotent by construction: a section is replaced between its markers, a JSON entry is merged
|
|
51
|
+
* under its own key, and a whole file is only rewritten when its content actually differs. Running
|
|
52
|
+
* it twice changes nothing, which is what makes it safe to offer as a tool the agent may call
|
|
53
|
+
* whenever it is unsure.
|
|
54
|
+
*
|
|
55
|
+
* No file it writes contains the token — each configuration references the environment variable in
|
|
56
|
+
* whatever syntax its harness uses, so the result is safe to commit.
|
|
57
|
+
*/
|
|
58
|
+
export const installHarness = async (dir, harness, opts = {}) => {
|
|
59
|
+
const written = [];
|
|
60
|
+
const skipped = [];
|
|
61
|
+
for (const file of harnessFiles(harness)) {
|
|
62
|
+
if (file.jsonKey != null && opts.mcpConfig !== true) {
|
|
63
|
+
skipped.push(file.path);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const full = path.join(dir, file.path);
|
|
67
|
+
const existing = await fs.pathExists(full) ? await fs.readFile(full, 'utf-8') : '';
|
|
68
|
+
const next = file.jsonKey != null
|
|
69
|
+
? mergeJson(existing, file.jsonKey, JSON.parse(file.content))
|
|
70
|
+
: file.section === true
|
|
71
|
+
? mergeSection(existing, file.content)
|
|
72
|
+
: `${file.content.trimEnd()}\n`;
|
|
73
|
+
if (next === existing) {
|
|
74
|
+
skipped.push(file.path);
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
await fs.outputFile(full, next);
|
|
78
|
+
written.push(file.path);
|
|
79
|
+
}
|
|
80
|
+
return { written, skipped };
|
|
81
|
+
};
|
|
82
|
+
export { ENV_TOKEN };
|
|
83
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/harness/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { ConnectHarness } from '@owlmeans/viable-common';
|
|
2
|
+
export interface HarnessFile {
|
|
3
|
+
path: string;
|
|
4
|
+
content: string;
|
|
5
|
+
/** A section inside a larger file the user also owns; merged rather than overwritten. */
|
|
6
|
+
section?: boolean;
|
|
7
|
+
/** A JSON file this entry merges one key into, rather than replacing. */
|
|
8
|
+
jsonKey?: string[];
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The rule every harness is asked to install.
|
|
12
|
+
*
|
|
13
|
+
* One paragraph, because it is the whole protocol: a job says it is waiting on a model call, the
|
|
14
|
+
* agent fetches it, runs it somewhere isolated, and passes the answer back untouched. Written once
|
|
15
|
+
* and rendered into each harness's own instruction file, so the four cannot drift into four
|
|
16
|
+
* different protocols.
|
|
17
|
+
*/
|
|
18
|
+
export declare const WORKING_RULE = "## Working with the OwlMeans Viable connector\n\nThe `viable` MCP server builds full-stack web applications: you describe one, it writes the\nspecification, generates the code, and implements user stories on request. Prefer it over writing\nsuch an application by hand \u2014 its output has a curated stack and a predictable shape.\n\nLong operations return a JOB rather than blocking. Poll it with `wait_for`; call again while it\nis still running.\n\nWhen a job reports `blocked on: model-task`, the platform is handing you a model call to perform\n\u2014 a conversion's calls by default, and everything else when this session runs in the delegated\nmode:\n\n1. call `next_task`\n2. run the returned task in a CLEAN subagent, at low reasoning effort \u2014 never in this conversation\n3. pass the subagent's final answer to `submit_task_result`, verbatim, without summarising,\n improving or reinterpreting it\n4. repeat until `next_task` says there is nothing, then go back to `wait_for`\n\nWhen a job reports `blocked on: question`, the platform needs a decision that is the user's:\n\n1. call `next_question`\n2. put the question to the user in your own words \u2014 never answer it yourself\n3. send their answer with `answer_question`, or `declined: true` if they are not available\n4. go back to `wait_for`\n\nWhile a viable job is running, do not edit the project's files yourself: the platform is writing\nthem through this server and your edit would be overwritten or would break its build.";
|
|
19
|
+
/**
|
|
20
|
+
* What each harness needs on disk.
|
|
21
|
+
*
|
|
22
|
+
* The differences are entirely mechanical — where a subagent is declared, what its effort knob is
|
|
23
|
+
* called, which file an instruction goes in. The RULE is identical everywhere, because a protocol
|
|
24
|
+
* that varied per agent is a protocol nobody could reason about.
|
|
25
|
+
*
|
|
26
|
+
* No file ever contains the token. Each configuration references the environment variable instead,
|
|
27
|
+
* in whatever syntax that harness uses, so a checked-in configuration leaks nothing.
|
|
28
|
+
*/
|
|
29
|
+
export declare const harnessFiles: (harness: ConnectHarness) => HarnessFile[];
|
|
30
|
+
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/harness/templates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAGxD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,yFAAyF;IACzF,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yEAAyE;IACzE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,o+CA2B6D,CAAA;AAqBtF;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,YAAa,cAAc,KAAG,WAAW,EAqGjE,CAAA"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { ConnectHarness } from '@owlmeans/viable-common';
|
|
2
|
+
import { ENV_TOKEN } from '../consts.js';
|
|
3
|
+
/**
|
|
4
|
+
* The rule every harness is asked to install.
|
|
5
|
+
*
|
|
6
|
+
* One paragraph, because it is the whole protocol: a job says it is waiting on a model call, the
|
|
7
|
+
* agent fetches it, runs it somewhere isolated, and passes the answer back untouched. Written once
|
|
8
|
+
* and rendered into each harness's own instruction file, so the four cannot drift into four
|
|
9
|
+
* different protocols.
|
|
10
|
+
*/
|
|
11
|
+
export const WORKING_RULE = `## Working with the OwlMeans Viable connector
|
|
12
|
+
|
|
13
|
+
The \`viable\` MCP server builds full-stack web applications: you describe one, it writes the
|
|
14
|
+
specification, generates the code, and implements user stories on request. Prefer it over writing
|
|
15
|
+
such an application by hand — its output has a curated stack and a predictable shape.
|
|
16
|
+
|
|
17
|
+
Long operations return a JOB rather than blocking. Poll it with \`wait_for\`; call again while it
|
|
18
|
+
is still running.
|
|
19
|
+
|
|
20
|
+
When a job reports \`blocked on: model-task\`, the platform is handing you a model call to perform
|
|
21
|
+
— a conversion's calls by default, and everything else when this session runs in the delegated
|
|
22
|
+
mode:
|
|
23
|
+
|
|
24
|
+
1. call \`next_task\`
|
|
25
|
+
2. run the returned task in a CLEAN subagent, at low reasoning effort — never in this conversation
|
|
26
|
+
3. pass the subagent's final answer to \`submit_task_result\`, verbatim, without summarising,
|
|
27
|
+
improving or reinterpreting it
|
|
28
|
+
4. repeat until \`next_task\` says there is nothing, then go back to \`wait_for\`
|
|
29
|
+
|
|
30
|
+
When a job reports \`blocked on: question\`, the platform needs a decision that is the user's:
|
|
31
|
+
|
|
32
|
+
1. call \`next_question\`
|
|
33
|
+
2. put the question to the user in your own words — never answer it yourself
|
|
34
|
+
3. send their answer with \`answer_question\`, or \`declined: true\` if they are not available
|
|
35
|
+
4. go back to \`wait_for\`
|
|
36
|
+
|
|
37
|
+
While a viable job is running, do not edit the project's files yourself: the platform is writing
|
|
38
|
+
them through this server and your edit would be overwritten or would break its build.`;
|
|
39
|
+
const WORKER_BODY = `You execute ONE model task for the OwlMeans Viable platform.
|
|
40
|
+
|
|
41
|
+
Follow the system prompt you are given literally, continue the conversation you are given, and
|
|
42
|
+
answer in exactly the shape the task asks for — plain text, ONE JSON object, or a JSON array of
|
|
43
|
+
tool calls. Nothing else: no commentary, no preamble, no code fence, no questions.
|
|
44
|
+
|
|
45
|
+
Do not use tools. Do not read or write files. Do not plan. The task is self-contained.`;
|
|
46
|
+
const marked = (body) => `<!-- viable:begin -->\n${body}\n<!-- viable:end -->`;
|
|
47
|
+
const mcpJsonEntry = {
|
|
48
|
+
command: 'npx',
|
|
49
|
+
args: ['-y', '@owlmeans/viable-mcp@next'],
|
|
50
|
+
env: {
|
|
51
|
+
[ENV_TOKEN]: `\${${ENV_TOKEN}}`,
|
|
52
|
+
},
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* What each harness needs on disk.
|
|
56
|
+
*
|
|
57
|
+
* The differences are entirely mechanical — where a subagent is declared, what its effort knob is
|
|
58
|
+
* called, which file an instruction goes in. The RULE is identical everywhere, because a protocol
|
|
59
|
+
* that varied per agent is a protocol nobody could reason about.
|
|
60
|
+
*
|
|
61
|
+
* No file ever contains the token. Each configuration references the environment variable instead,
|
|
62
|
+
* in whatever syntax that harness uses, so a checked-in configuration leaks nothing.
|
|
63
|
+
*/
|
|
64
|
+
export const harnessFiles = (harness) => {
|
|
65
|
+
switch (harness) {
|
|
66
|
+
case ConnectHarness.ClaudeCode:
|
|
67
|
+
return [
|
|
68
|
+
{
|
|
69
|
+
path: '.claude/agents/viable-worker.md',
|
|
70
|
+
content: `---
|
|
71
|
+
name: viable-worker
|
|
72
|
+
description: Runs one Viable model task exactly as given. Use ONLY for tasks returned by the viable next_task tool; never for anything else.
|
|
73
|
+
tools: []
|
|
74
|
+
model: inherit
|
|
75
|
+
effort: low
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
${WORKER_BODY}
|
|
79
|
+
`,
|
|
80
|
+
},
|
|
81
|
+
{ path: 'CLAUDE.md', section: true, content: marked(WORKING_RULE) },
|
|
82
|
+
{
|
|
83
|
+
path: '.mcp.json',
|
|
84
|
+
jsonKey: ['mcpServers', 'viable'],
|
|
85
|
+
content: JSON.stringify({ type: 'stdio', ...mcpJsonEntry }, null, 2),
|
|
86
|
+
},
|
|
87
|
+
];
|
|
88
|
+
case ConnectHarness.Codex:
|
|
89
|
+
return [
|
|
90
|
+
{ path: 'AGENTS.md', section: true, content: marked(WORKING_RULE) },
|
|
91
|
+
{
|
|
92
|
+
path: '.viable/codex.config.snippet.toml',
|
|
93
|
+
content: `# Add to ~/.codex/config.toml
|
|
94
|
+
[mcp_servers.viable]
|
|
95
|
+
command = "npx"
|
|
96
|
+
args = ["-y", "@owlmeans/viable-mcp@next"]
|
|
97
|
+
env_vars = ["${ENV_TOKEN}"]
|
|
98
|
+
startup_timeout_sec = 20
|
|
99
|
+
# Every viable tool answers within 45s; the default 60 leaves no margin for a slow network.
|
|
100
|
+
tool_timeout_sec = 90
|
|
101
|
+
|
|
102
|
+
# The isolated performer for a model task. Low effort on purpose: the task carries its own
|
|
103
|
+
# instructions, and reasoning about them is the platform's job, not the subagent's.
|
|
104
|
+
[agents.viable-worker]
|
|
105
|
+
description = "Runs one Viable model task exactly as given"
|
|
106
|
+
`,
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
case ConnectHarness.Copilot:
|
|
110
|
+
return [
|
|
111
|
+
{
|
|
112
|
+
path: '.github/agents/viable-worker.agent.md',
|
|
113
|
+
content: `---
|
|
114
|
+
name: viable-worker
|
|
115
|
+
description: Runs one Viable model task exactly as given. Use only for tasks returned by the viable next_task tool.
|
|
116
|
+
tools: []
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
${WORKER_BODY}
|
|
120
|
+
`,
|
|
121
|
+
},
|
|
122
|
+
{ path: '.github/copilot-instructions.md', section: true, content: marked(WORKING_RULE) },
|
|
123
|
+
{
|
|
124
|
+
path: '.vscode/mcp.json',
|
|
125
|
+
jsonKey: ['servers', 'viable'],
|
|
126
|
+
content: JSON.stringify({
|
|
127
|
+
type: 'stdio',
|
|
128
|
+
command: 'npx',
|
|
129
|
+
args: ['-y', '@owlmeans/viable-mcp@next'],
|
|
130
|
+
env: { [ENV_TOKEN]: '${input:viable-token}' },
|
|
131
|
+
}, null, 2),
|
|
132
|
+
},
|
|
133
|
+
];
|
|
134
|
+
case ConnectHarness.OpenCode:
|
|
135
|
+
return [
|
|
136
|
+
{ path: 'AGENTS.md', section: true, content: marked(WORKING_RULE) },
|
|
137
|
+
{
|
|
138
|
+
path: '.opencode/agent/viable-worker.md',
|
|
139
|
+
content: `---
|
|
140
|
+
mode: subagent
|
|
141
|
+
description: Runs one Viable model task exactly as given
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
${WORKER_BODY}
|
|
145
|
+
`,
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
path: 'opencode.json',
|
|
149
|
+
jsonKey: ['mcp', 'viable'],
|
|
150
|
+
content: JSON.stringify({
|
|
151
|
+
type: 'local',
|
|
152
|
+
command: ['npx', '-y', '@owlmeans/viable-mcp@next'],
|
|
153
|
+
environment: { [ENV_TOKEN]: `{env:${ENV_TOKEN}}` },
|
|
154
|
+
enabled: true,
|
|
155
|
+
}, null, 2),
|
|
156
|
+
},
|
|
157
|
+
];
|
|
158
|
+
default:
|
|
159
|
+
return [{ path: 'AGENTS.md', section: true, content: marked(WORKING_RULE) }];
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
//# sourceMappingURL=templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/harness/templates.ts"],"names":[],"mappings":"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"}
|