@kodycodes/cli 1.2.1 → 1.4.0
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 +41 -1
- package/dist/capability-proxy.d.ts +46 -0
- package/dist/capability-proxy.js +151 -0
- package/dist/capability-proxy.js.map +1 -0
- package/dist/cli.d.ts +28 -0
- package/dist/cli.js +98 -18
- package/dist/cli.js.map +1 -1
- package/dist/defaults.d.ts +3 -0
- package/dist/defaults.js +3 -0
- package/dist/defaults.js.map +1 -1
- package/dist/help.js +12 -3
- package/dist/help.js.map +1 -1
- package/dist/local-execute.d.ts +28 -0
- package/dist/local-execute.js +286 -0
- package/dist/local-execute.js.map +1 -0
- package/dist/local-runtime-source.d.ts +32 -0
- package/dist/local-runtime-source.js +199 -0
- package/dist/local-runtime-source.js.map +1 -0
- package/dist/network-error.d.ts +2 -0
- package/dist/network-error.js +11 -0
- package/dist/network-error.js.map +1 -0
- package/dist/workerd-binary.d.ts +31 -0
- package/dist/workerd-binary.js +98 -0
- package/dist/workerd-binary.js.map +1 -0
- package/package.json +1 -1
- package/skills/kody/SKILL.md +10 -0
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { randomBytes } from 'node:crypto';
|
|
3
|
+
import { rmSync } from 'node:fs';
|
|
4
|
+
import { mkdtemp, rm, writeFile } from 'node:fs/promises';
|
|
5
|
+
import { createServer, request as httpRequest, } from 'node:http';
|
|
6
|
+
import { tmpdir } from 'node:os';
|
|
7
|
+
import { join } from 'node:path';
|
|
8
|
+
import { setTimeout as delay } from 'node:timers/promises';
|
|
9
|
+
import { assertTokenSafeApiUrl, callCapabilityProxy, openCapabilityProxySession, } from './capability-proxy.js';
|
|
10
|
+
import { apiTokenEnvVar } from './defaults.js';
|
|
11
|
+
import { createLocalEntrySource, createLocalRuntimeModuleSource, createWorkerdConfig, runSecretEnvVar, runSecretHeader, } from './local-runtime-source.js';
|
|
12
|
+
import { redact } from './redact.js';
|
|
13
|
+
import { ensureWorkerdBinary } from './workerd-binary.js';
|
|
14
|
+
const workerdStartTimeoutMs = 30_000;
|
|
15
|
+
const workerdExitGraceMs = 1_000;
|
|
16
|
+
export function assertNoStaticPackageImports(code) {
|
|
17
|
+
if (/(?:\bfrom\s*|\bimport\s*\(?\s*)["']kody:@/.test(code)) {
|
|
18
|
+
throw new Error('execute --local does not resolve saved-package imports (kody:@…) yet. Call the export with packages.invoke(specifier, options) from kody:runtime, or run execute without --local.');
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function runLocalExecute(input) {
|
|
22
|
+
assertNoStaticPackageImports(input.code);
|
|
23
|
+
assertTokenSafeApiUrl(input.apiUrl);
|
|
24
|
+
const client = { apiUrl: input.apiUrl, token: input.token, fetchFn: input.fetchFn };
|
|
25
|
+
await openCapabilityProxySession(client);
|
|
26
|
+
const workerdPath = input.workerdPath ??
|
|
27
|
+
(await ensureWorkerdBinary({
|
|
28
|
+
onDownload: (url) => input.onStatus?.(`Downloading workerd for local execute from ${url}…`),
|
|
29
|
+
}));
|
|
30
|
+
const runSecret = randomBytes(32).toString('hex');
|
|
31
|
+
const workDir = await mkdtemp(join(tmpdir(), 'kody-local-'));
|
|
32
|
+
let child;
|
|
33
|
+
let bridge;
|
|
34
|
+
// SIGTERM makes workerd drain in-flight requests, which a hung module never finishes.
|
|
35
|
+
const stopWorkerd = () => child?.kill('SIGKILL');
|
|
36
|
+
const releaseSignals = cleanupOnSignal(() => {
|
|
37
|
+
stopWorkerd();
|
|
38
|
+
rmSync(workDir, { recursive: true, force: true });
|
|
39
|
+
});
|
|
40
|
+
const startedAt = new Date();
|
|
41
|
+
const finish = (sandbox) => buildLocalExecuteResult({
|
|
42
|
+
sandbox,
|
|
43
|
+
startedAt,
|
|
44
|
+
endedAt: new Date(),
|
|
45
|
+
conversationId: input.conversationId,
|
|
46
|
+
});
|
|
47
|
+
try {
|
|
48
|
+
bridge = await startBridge({
|
|
49
|
+
runSecret,
|
|
50
|
+
forward: (call, signal) => callCapabilityProxy({
|
|
51
|
+
...client,
|
|
52
|
+
...call,
|
|
53
|
+
conversationId: input.conversationId,
|
|
54
|
+
signal,
|
|
55
|
+
}),
|
|
56
|
+
});
|
|
57
|
+
const files = { entry: 'entry.js', user: 'main.js', runtime: 'runtime.js' };
|
|
58
|
+
await writeFile(join(workDir, files.entry), createLocalEntrySource());
|
|
59
|
+
await writeFile(join(workDir, files.user), input.code);
|
|
60
|
+
await writeFile(join(workDir, files.runtime), createLocalRuntimeModuleSource());
|
|
61
|
+
const configPath = join(workDir, 'config.capnp');
|
|
62
|
+
await writeFile(configPath, createWorkerdConfig({ bridgePort: bridge.port, files }));
|
|
63
|
+
const env = { ...process.env, [runSecretEnvVar]: runSecret };
|
|
64
|
+
delete env[apiTokenEnvVar];
|
|
65
|
+
child = spawn(workerdPath, ['serve', configPath, '--control-fd=3'], {
|
|
66
|
+
cwd: workDir,
|
|
67
|
+
env,
|
|
68
|
+
stdio: ['ignore', 'pipe', 'pipe', 'pipe'],
|
|
69
|
+
});
|
|
70
|
+
const workerd = watchWorkerd(child);
|
|
71
|
+
const started = await workerd.listening;
|
|
72
|
+
if ('exitDetail' in started) {
|
|
73
|
+
return finish({ error: `Local execute could not load the module${started.exitDetail}` });
|
|
74
|
+
}
|
|
75
|
+
let response;
|
|
76
|
+
try {
|
|
77
|
+
response = await postToWorkerd({
|
|
78
|
+
port: started.port,
|
|
79
|
+
runSecret,
|
|
80
|
+
body: JSON.stringify({ params: input.params ?? {} }),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
catch (error) {
|
|
84
|
+
const exitDetail = await Promise.race([workerd.exited, delay(workerdExitGraceMs, null)]);
|
|
85
|
+
if (exitDetail !== null)
|
|
86
|
+
throw new Error(`workerd exited during the run${exitDetail}`);
|
|
87
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
88
|
+
throw new Error(`Local execute run failed (${reason}).${workerd.stderr()}`);
|
|
89
|
+
}
|
|
90
|
+
if (response.status !== 200) {
|
|
91
|
+
throw new Error(`Local execute runtime returned HTTP ${response.status}.${workerd.stderr()}`);
|
|
92
|
+
}
|
|
93
|
+
return finish(JSON.parse(response.body));
|
|
94
|
+
}
|
|
95
|
+
finally {
|
|
96
|
+
releaseSignals();
|
|
97
|
+
stopWorkerd();
|
|
98
|
+
await bridge?.close();
|
|
99
|
+
await rm(workDir, { recursive: true, force: true });
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/** Same envelope as cloud execute so `formatToolResult` and `--json` behave identically. */
|
|
103
|
+
export function buildLocalExecuteResult(input) {
|
|
104
|
+
const { sandbox } = input;
|
|
105
|
+
const logs = sandbox.logs ?? [];
|
|
106
|
+
const base = {
|
|
107
|
+
...(input.conversationId !== undefined ? { conversationId: input.conversationId } : {}),
|
|
108
|
+
timing: {
|
|
109
|
+
startedAt: input.startedAt.toISOString(),
|
|
110
|
+
endedAt: input.endedAt.toISOString(),
|
|
111
|
+
durationMs: input.endedAt.getTime() - input.startedAt.getTime(),
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
if (typeof sandbox.error === 'string') {
|
|
115
|
+
return {
|
|
116
|
+
content: [{ type: 'text', text: `Error: ${sandbox.error}` }],
|
|
117
|
+
structuredContent: { ...base, returnedBytes: 0, error: sandbox.error, logs },
|
|
118
|
+
isError: true,
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const text = typeof sandbox.result === 'string'
|
|
122
|
+
? sandbox.result
|
|
123
|
+
: (JSON.stringify(sandbox.result, null, 2) ?? 'undefined');
|
|
124
|
+
const serialized = typeof sandbox.result === 'string'
|
|
125
|
+
? sandbox.result
|
|
126
|
+
: (JSON.stringify(sandbox.result) ?? 'undefined');
|
|
127
|
+
return {
|
|
128
|
+
content: [{ type: 'text', text }],
|
|
129
|
+
structuredContent: {
|
|
130
|
+
...base,
|
|
131
|
+
returnedBytes: Buffer.byteLength(serialized),
|
|
132
|
+
result: sandbox.result,
|
|
133
|
+
logs,
|
|
134
|
+
},
|
|
135
|
+
isError: false,
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* `finally` does not run when the CLI is killed by a signal; without this,
|
|
140
|
+
* workerd is orphaned and the user's module stays in the temp dir.
|
|
141
|
+
*/
|
|
142
|
+
function cleanupOnSignal(cleanup) {
|
|
143
|
+
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
144
|
+
const release = () => {
|
|
145
|
+
for (const signal of signals)
|
|
146
|
+
process.off(signal, handler);
|
|
147
|
+
};
|
|
148
|
+
const handler = (signal) => {
|
|
149
|
+
release();
|
|
150
|
+
cleanup();
|
|
151
|
+
process.kill(process.pid, signal);
|
|
152
|
+
};
|
|
153
|
+
for (const signal of signals)
|
|
154
|
+
process.once(signal, handler);
|
|
155
|
+
return release;
|
|
156
|
+
}
|
|
157
|
+
function watchWorkerd(child) {
|
|
158
|
+
let stderrText = '';
|
|
159
|
+
child.stderr?.on('data', (chunk) => {
|
|
160
|
+
stderrText += chunk.toString('utf8');
|
|
161
|
+
});
|
|
162
|
+
child.stdout?.resume();
|
|
163
|
+
const stderr = () => {
|
|
164
|
+
const trimmed = redact(stderrText.trim());
|
|
165
|
+
return trimmed ? `\n${trimmed}` : '';
|
|
166
|
+
};
|
|
167
|
+
const exited = new Promise((resolve) => {
|
|
168
|
+
child.once('exit', (code, signal) => {
|
|
169
|
+
resolve(` (workerd exit ${signal ?? code})${stderr()}`);
|
|
170
|
+
});
|
|
171
|
+
});
|
|
172
|
+
const listening = new Promise((resolve, reject) => {
|
|
173
|
+
const control = child.stdio[3];
|
|
174
|
+
let buffered = '';
|
|
175
|
+
const timer = setTimeout(() => {
|
|
176
|
+
reject(new Error(`workerd did not start within ${workerdStartTimeoutMs / 1000}s.${stderr()}`));
|
|
177
|
+
}, workerdStartTimeoutMs);
|
|
178
|
+
control?.on('data', (chunk) => {
|
|
179
|
+
buffered += chunk.toString('utf8');
|
|
180
|
+
for (const line of buffered.split('\n')) {
|
|
181
|
+
const port = parseListenPort(line);
|
|
182
|
+
if (port !== null) {
|
|
183
|
+
clearTimeout(timer);
|
|
184
|
+
resolve({ port });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
child.once('error', (error) => {
|
|
189
|
+
clearTimeout(timer);
|
|
190
|
+
reject(new Error(`Could not start workerd: ${error.message}`));
|
|
191
|
+
});
|
|
192
|
+
void exited.then((exitDetail) => {
|
|
193
|
+
clearTimeout(timer);
|
|
194
|
+
resolve({ exitDetail });
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
return { listening, exited, stderr };
|
|
198
|
+
}
|
|
199
|
+
function parseListenPort(line) {
|
|
200
|
+
if (!line.trim())
|
|
201
|
+
return null;
|
|
202
|
+
try {
|
|
203
|
+
const event = JSON.parse(line);
|
|
204
|
+
return event.event === 'listen' && event.socket === 'http' && typeof event.port === 'number'
|
|
205
|
+
? event.port
|
|
206
|
+
: null;
|
|
207
|
+
}
|
|
208
|
+
catch {
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/** node:http rather than fetch: local runs have no time limit, and fetch gives up after 300s. */
|
|
213
|
+
function postToWorkerd(input) {
|
|
214
|
+
return new Promise((resolve, reject) => {
|
|
215
|
+
const request = httpRequest({
|
|
216
|
+
host: '127.0.0.1',
|
|
217
|
+
port: input.port,
|
|
218
|
+
method: 'POST',
|
|
219
|
+
path: '/',
|
|
220
|
+
headers: {
|
|
221
|
+
'content-type': 'application/json',
|
|
222
|
+
'content-length': Buffer.byteLength(input.body),
|
|
223
|
+
[runSecretHeader]: input.runSecret,
|
|
224
|
+
},
|
|
225
|
+
}, (response) => {
|
|
226
|
+
readBody(response).then((body) => resolve({ status: response.statusCode ?? 0, body }), reject);
|
|
227
|
+
});
|
|
228
|
+
request.on('error', reject);
|
|
229
|
+
request.end(input.body);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
async function startBridge(input) {
|
|
233
|
+
const inFlight = new AbortController();
|
|
234
|
+
const server = createServer(async (request, response) => {
|
|
235
|
+
const reply = (status, body) => {
|
|
236
|
+
response.writeHead(status, { 'content-type': 'application/json' });
|
|
237
|
+
response.end(JSON.stringify(body));
|
|
238
|
+
};
|
|
239
|
+
if (request.method !== 'POST' ||
|
|
240
|
+
request.url !== '/call' ||
|
|
241
|
+
request.headers[runSecretHeader] !== input.runSecret) {
|
|
242
|
+
reply(403, { error: 'Forbidden' });
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
try {
|
|
246
|
+
const call = parseBridgeCall(await readBody(request));
|
|
247
|
+
const result = await input.forward(call, inFlight.signal);
|
|
248
|
+
reply(200, { result });
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
reply(200, { error: redact(error instanceof Error ? error.message : String(error)) });
|
|
252
|
+
}
|
|
253
|
+
});
|
|
254
|
+
await new Promise((resolve, reject) => {
|
|
255
|
+
server.once('error', reject);
|
|
256
|
+
server.listen(0, '127.0.0.1', () => resolve());
|
|
257
|
+
});
|
|
258
|
+
return {
|
|
259
|
+
port: server.address().port,
|
|
260
|
+
close: () => new Promise((resolve) => {
|
|
261
|
+
inFlight.abort();
|
|
262
|
+
server.closeAllConnections();
|
|
263
|
+
server.close(() => resolve());
|
|
264
|
+
}),
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function parseBridgeCall(body) {
|
|
268
|
+
const parsed = JSON.parse(body);
|
|
269
|
+
if (!Array.isArray(parsed.path) ||
|
|
270
|
+
parsed.path.length === 0 ||
|
|
271
|
+
!parsed.path.every((segment) => typeof segment === 'string')) {
|
|
272
|
+
throw new Error('Invalid kody:runtime call path.');
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
path: parsed.path,
|
|
276
|
+
args: Array.isArray(parsed.args) ? parsed.args : [],
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
async function readBody(stream) {
|
|
280
|
+
const chunks = [];
|
|
281
|
+
for await (const chunk of stream) {
|
|
282
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
283
|
+
}
|
|
284
|
+
return Buffer.concat(chunks).toString('utf8');
|
|
285
|
+
}
|
|
286
|
+
//# sourceMappingURL=local-execute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-execute.js","sourceRoot":"","sources":["../src/local-execute.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sources for the workerd process behind `execute --local`. User code sees the
|
|
3
|
+
* same `kody:runtime` surface as ad hoc cloud execute; every call becomes a
|
|
4
|
+
* `{ path, args }` hop to the CLI's loopback bridge, which adds the API token
|
|
5
|
+
* and forwards it to CapabilityProxy. The token never enters workerd.
|
|
6
|
+
*/
|
|
7
|
+
export declare const localExecuteCompatibilityDate = "2026-04-16";
|
|
8
|
+
export declare const localExecuteCompatibilityFlags: readonly ["nodejs_compat"];
|
|
9
|
+
export declare const localWorkerModuleNames: {
|
|
10
|
+
readonly entry: "__kody_local_entry.js";
|
|
11
|
+
readonly user: "main.js";
|
|
12
|
+
readonly runtime: "kody:runtime";
|
|
13
|
+
};
|
|
14
|
+
/** Header carrying the per-run secret on workerd → bridge and CLI → workerd hops. */
|
|
15
|
+
export declare const runSecretHeader = "x-kody-run-secret";
|
|
16
|
+
export declare const runSecretEnvVar = "KODY_RUN_SECRET";
|
|
17
|
+
export declare function createLocalRuntimeModuleSource(): string;
|
|
18
|
+
export declare function createLocalEntrySource(): string;
|
|
19
|
+
/**
|
|
20
|
+
* workerd text config. `files` are embedded relative to the config file.
|
|
21
|
+
* Outbound fetch reaches public and private networks: local execute runs as
|
|
22
|
+
* the user on their own machine, and reaching local services is part of why
|
|
23
|
+
* one would run locally.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createWorkerdConfig(input: {
|
|
26
|
+
bridgePort: number;
|
|
27
|
+
files: {
|
|
28
|
+
entry: string;
|
|
29
|
+
user: string;
|
|
30
|
+
runtime: string;
|
|
31
|
+
};
|
|
32
|
+
}): string;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sources for the workerd process behind `execute --local`. User code sees the
|
|
3
|
+
* same `kody:runtime` surface as ad hoc cloud execute; every call becomes a
|
|
4
|
+
* `{ path, args }` hop to the CLI's loopback bridge, which adds the API token
|
|
5
|
+
* and forwards it to CapabilityProxy. The token never enters workerd.
|
|
6
|
+
*/
|
|
7
|
+
export const localExecuteCompatibilityDate = '2026-04-16';
|
|
8
|
+
export const localExecuteCompatibilityFlags = ['nodejs_compat'];
|
|
9
|
+
export const localWorkerModuleNames = {
|
|
10
|
+
entry: '__kody_local_entry.js',
|
|
11
|
+
user: 'main.js',
|
|
12
|
+
runtime: 'kody:runtime',
|
|
13
|
+
};
|
|
14
|
+
/** Header carrying the per-run secret on workerd → bridge and CLI → workerd hops. */
|
|
15
|
+
export const runSecretHeader = 'x-kody-run-secret';
|
|
16
|
+
export const runSecretEnvVar = 'KODY_RUN_SECRET';
|
|
17
|
+
export function createLocalRuntimeModuleSource() {
|
|
18
|
+
return `
|
|
19
|
+
let __kodyBridge = null;
|
|
20
|
+
|
|
21
|
+
export function __kodyInstallLocalBridge(bridge) {
|
|
22
|
+
__kodyBridge = bridge;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function __kodyCall(path, args) {
|
|
26
|
+
if (__kodyBridge === null) {
|
|
27
|
+
throw new Error('kody:runtime is only available while an execute --local run is in progress.');
|
|
28
|
+
}
|
|
29
|
+
return __kodyBridge(path, args);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function __kodyNamespace(path) {
|
|
33
|
+
const label = '[KodyRuntime:' + path.join('.') + ']';
|
|
34
|
+
return new Proxy(function () {}, {
|
|
35
|
+
get(_target, property) {
|
|
36
|
+
if (typeof property === 'symbol' || property === 'then' || property === 'toJSON') {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
if (property === 'toString' || property === 'inspect') return () => label;
|
|
40
|
+
return __kodyNamespace([...path, property]);
|
|
41
|
+
},
|
|
42
|
+
apply(_target, _thisArg, args) {
|
|
43
|
+
return __kodyCall(path, args);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export const kody = __kodyNamespace(['kody']);
|
|
49
|
+
|
|
50
|
+
export const workflows = {
|
|
51
|
+
create: async (input) => await __kodyCall(['workflows', 'create'], [input ?? {}]),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export const packages = {
|
|
55
|
+
invoke: async (specifier, options) => {
|
|
56
|
+
if (typeof specifier !== 'string') {
|
|
57
|
+
throw new Error(
|
|
58
|
+
'Object-only packages.invoke was removed. Use a static import (import fn from "kody:@owner/package/export") when the name is known, or import(specifier) when the name is data.',
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
return await __kodyCall(['packages', 'invoke'], [specifier, options ?? {}]);
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export function packageStorage() {
|
|
66
|
+
throw new Error(
|
|
67
|
+
'packageStorage() requires package provenance: this module was not bundled from a saved package and the run has no package context. ' +
|
|
68
|
+
'Ad hoc execute has no scratch SQLite helper. Persist durable state from a saved package with packageStorage().',
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function __kodyPackageSecretsUnavailable() {
|
|
73
|
+
throw new Error(
|
|
74
|
+
'packageSecrets is not available in this execution context. It is bound for stamped saved-package modules and saved-package runtime contexts.',
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
export const packageSecrets = {
|
|
79
|
+
get: async () => __kodyPackageSecretsUnavailable(),
|
|
80
|
+
has: async () => __kodyPackageSecretsUnavailable(),
|
|
81
|
+
};
|
|
82
|
+
export const packageContext = Object.freeze({});
|
|
83
|
+
export const email = null;
|
|
84
|
+
export const events = null;
|
|
85
|
+
export const createAuthenticatedFetch = undefined;
|
|
86
|
+
export const secretHeaders = undefined;
|
|
87
|
+
export const oauthClientCredentials = undefined;
|
|
88
|
+
|
|
89
|
+
const __kodyRuntimeDefault = Object.freeze({
|
|
90
|
+
kody,
|
|
91
|
+
packageStorage,
|
|
92
|
+
createAuthenticatedFetch,
|
|
93
|
+
secretHeaders,
|
|
94
|
+
oauthClientCredentials,
|
|
95
|
+
packageContext,
|
|
96
|
+
packageSecrets,
|
|
97
|
+
email,
|
|
98
|
+
workflows,
|
|
99
|
+
packages,
|
|
100
|
+
events,
|
|
101
|
+
});
|
|
102
|
+
export default __kodyRuntimeDefault;
|
|
103
|
+
export const KodyRuntime = Object.freeze({ defaultValue: __kodyRuntimeDefault });
|
|
104
|
+
`.trimStart();
|
|
105
|
+
}
|
|
106
|
+
export function createLocalEntrySource() {
|
|
107
|
+
return `
|
|
108
|
+
import { __kodyInstallLocalBridge } from ${JSON.stringify(localWorkerModuleNames.runtime)};
|
|
109
|
+
|
|
110
|
+
const __kodyRunSecretHeader = ${JSON.stringify(runSecretHeader)};
|
|
111
|
+
let __kodyClaimed = false;
|
|
112
|
+
|
|
113
|
+
function __kodyFormatLogArgs(args) {
|
|
114
|
+
return args.map(String).join(' ');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export default {
|
|
118
|
+
async fetch(request, env) {
|
|
119
|
+
const secret = env.${runSecretEnvVar};
|
|
120
|
+
if (__kodyClaimed || !secret || request.headers.get(__kodyRunSecretHeader) !== secret) {
|
|
121
|
+
return new Response('Forbidden', { status: 403 });
|
|
122
|
+
}
|
|
123
|
+
__kodyClaimed = true;
|
|
124
|
+
const { params } = await request.json();
|
|
125
|
+
__kodyInstallLocalBridge(async (path, args) => {
|
|
126
|
+
const response = await env.KODY_BRIDGE.fetch('http://kody-bridge/call', {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: { 'content-type': 'application/json', [__kodyRunSecretHeader]: secret },
|
|
129
|
+
body: JSON.stringify({ path, args }),
|
|
130
|
+
});
|
|
131
|
+
const data = await response.json();
|
|
132
|
+
if (data.error) throw new Error(data.error);
|
|
133
|
+
return data.result;
|
|
134
|
+
});
|
|
135
|
+
const logs = [];
|
|
136
|
+
const nativeConsole = globalThis.console;
|
|
137
|
+
globalThis.console = {
|
|
138
|
+
...nativeConsole,
|
|
139
|
+
log: (...a) => { logs.push(__kodyFormatLogArgs(a)); },
|
|
140
|
+
info: (...a) => { logs.push('[info] ' + __kodyFormatLogArgs(a)); },
|
|
141
|
+
debug: (...a) => { logs.push('[debug] ' + __kodyFormatLogArgs(a)); },
|
|
142
|
+
warn: (...a) => { logs.push('[warn] ' + __kodyFormatLogArgs(a)); },
|
|
143
|
+
error: (...a) => { logs.push('[error] ' + __kodyFormatLogArgs(a)); },
|
|
144
|
+
};
|
|
145
|
+
try {
|
|
146
|
+
const module = await import(${JSON.stringify(`./${localWorkerModuleNames.user}`)});
|
|
147
|
+
if (typeof module?.default !== 'function') {
|
|
148
|
+
throw new Error('Kody execute modules must default export a function.');
|
|
149
|
+
}
|
|
150
|
+
const result = await module.default(params);
|
|
151
|
+
return new Response(JSON.stringify({ result, logs }), {
|
|
152
|
+
headers: { 'content-type': 'application/json' },
|
|
153
|
+
});
|
|
154
|
+
} catch (error) {
|
|
155
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
156
|
+
return Response.json({ error: message, logs });
|
|
157
|
+
} finally {
|
|
158
|
+
globalThis.console = nativeConsole;
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
};
|
|
162
|
+
`.trimStart();
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* workerd text config. `files` are embedded relative to the config file.
|
|
166
|
+
* Outbound fetch reaches public and private networks: local execute runs as
|
|
167
|
+
* the user on their own machine, and reaching local services is part of why
|
|
168
|
+
* one would run locally.
|
|
169
|
+
*/
|
|
170
|
+
export function createWorkerdConfig(input) {
|
|
171
|
+
const flags = localExecuteCompatibilityFlags.map((flag) => JSON.stringify(flag)).join(', ');
|
|
172
|
+
return `using Workerd = import "/workerd/workerd.capnp";
|
|
173
|
+
|
|
174
|
+
const config :Workerd.Config = (
|
|
175
|
+
services = [
|
|
176
|
+
(name = "main", worker = .kodyWorker),
|
|
177
|
+
(name = "kody-bridge", external = (address = "127.0.0.1:${input.bridgePort}", http = ())),
|
|
178
|
+
(name = "internet", network = (allow = ["public", "private", "local"], tlsOptions = (trustBrowserCas = true))),
|
|
179
|
+
],
|
|
180
|
+
sockets = [ (name = "http", address = "127.0.0.1:0", http = (), service = "main") ],
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const kodyWorker :Workerd.Worker = (
|
|
184
|
+
modules = [
|
|
185
|
+
(name = ${JSON.stringify(localWorkerModuleNames.entry)}, esModule = embed ${JSON.stringify(input.files.entry)}),
|
|
186
|
+
(name = ${JSON.stringify(localWorkerModuleNames.user)}, esModule = embed ${JSON.stringify(input.files.user)}),
|
|
187
|
+
(name = ${JSON.stringify(localWorkerModuleNames.runtime)}, esModule = embed ${JSON.stringify(input.files.runtime)}),
|
|
188
|
+
],
|
|
189
|
+
compatibilityDate = ${JSON.stringify(localExecuteCompatibilityDate)},
|
|
190
|
+
compatibilityFlags = [${flags}],
|
|
191
|
+
globalOutbound = "internet",
|
|
192
|
+
bindings = [
|
|
193
|
+
(name = "KODY_BRIDGE", service = "kody-bridge"),
|
|
194
|
+
(name = ${JSON.stringify(runSecretEnvVar)}, fromEnvironment = ${JSON.stringify(runSecretEnvVar)}),
|
|
195
|
+
],
|
|
196
|
+
);
|
|
197
|
+
`;
|
|
198
|
+
}
|
|
199
|
+
//# sourceMappingURL=local-runtime-source.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-runtime-source.js","sourceRoot":"","sources":["../src/local-runtime-source.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,6BAA6B,GAAG,YAAY,CAAA;AACzD,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAAC,eAAe,CAAU,CAAA;AAExE,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACrC,KAAK,EAAE,uBAAuB;IAC9B,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,cAAc;CACd,CAAA;AAEV,qFAAqF;AACrF,MAAM,CAAC,MAAM,eAAe,GAAG,mBAAmB,CAAA;AAClD,MAAM,CAAC,MAAM,eAAe,GAAG,iBAAiB,CAAA;AAEhD,MAAM,UAAU,8BAA8B;IAC7C,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAsFP,CAAC,SAAS,EAAE,CAAA;AACb,CAAC;AAED,MAAM,UAAU,sBAAsB;IACrC,OAAO;2CACmC,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,OAAO,CAAC;;gCAEzD,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;;;;;;;;;uBASxC,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;iCA2BL,IAAI,CAAC,SAAS,CAAC,KAAK,sBAAsB,CAAC,IAAI,EAAE,CAAC;;;;;;;;;;;;;;;;CAgBlF,CAAC,SAAS,EAAE,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAGnC;IACA,MAAM,KAAK,GAAG,8BAA8B,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC3F,OAAO;;;;;8DAKsD,KAAK,CAAC,UAAU;;;;;;;;cAQhE,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC;cACnG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,IAAI,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC;cACjG,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,OAAO,CAAC,sBAAsB,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;;wBAE7F,IAAI,CAAC,SAAS,CAAC,6BAA6B,CAAC;0BAC3C,KAAK;;;;cAIjB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC;;;CAGlG,CAAA;AACD,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** `fetch failed` alone hides why; undici puts ECONNREFUSED / ENOTFOUND on `cause.code`. */
|
|
2
|
+
export function describeNetworkError(error) {
|
|
3
|
+
if (!(error instanceof Error))
|
|
4
|
+
return String(error);
|
|
5
|
+
const cause = error.cause;
|
|
6
|
+
const causeCode = cause && typeof cause === 'object' && 'code' in cause && typeof cause.code === 'string'
|
|
7
|
+
? cause.code
|
|
8
|
+
: null;
|
|
9
|
+
return causeCode ? `${error.message}: ${causeCode}` : error.message;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=network-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network-error.js","sourceRoot":"","sources":["../src/network-error.ts"],"names":[],"mappings":"AAAA,4FAA4F;AAC5F,MAAM,UAAU,oBAAoB,CAAC,KAAc;IAClD,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAA;IACzB,MAAM,SAAS,GACd,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;QACtF,CAAC,CAAC,KAAK,CAAC,IAAI;QACZ,CAAC,CAAC,IAAI,CAAA;IACR,OAAO,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAA;AACpE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** Matches the workerd the Kody platform runs; bump together with the digests. */
|
|
2
|
+
export declare const workerdVersion = "1.20260815.1";
|
|
3
|
+
/** sha256 of each gzipped release asset on github.com/cloudflare/workerd. */
|
|
4
|
+
export declare const workerdAssetDigests: {
|
|
5
|
+
readonly 'linux-64': "05099ec6f50832fcbc327490e5a971d682c97231fb01943b61726db07677e559";
|
|
6
|
+
readonly 'linux-arm64': "0331597b53771170df2ab8344d9ae81d38bad4959e47152dd86592eedd9264c7";
|
|
7
|
+
readonly 'darwin-64': "752ec91c01dfc44d660de6e3a654879cfc1277caa7f3c5312871c608c4c2d6df";
|
|
8
|
+
readonly 'darwin-arm64': "c189fc08f691739c37d8784945e943e33b66cbd4e14635a061fe516dc95f2b39";
|
|
9
|
+
};
|
|
10
|
+
export type WorkerdTarget = keyof typeof workerdAssetDigests;
|
|
11
|
+
export declare function workerdTargetFor(platform?: NodeJS.Platform, arch?: string): WorkerdTarget;
|
|
12
|
+
export declare function workerdAssetUrl(target: WorkerdTarget, version?: string): string;
|
|
13
|
+
export declare function userCacheDir(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform, home?: string): string;
|
|
14
|
+
export declare function cachedWorkerdPath(cacheDir: string, target: WorkerdTarget): string;
|
|
15
|
+
/**
|
|
16
|
+
* Returns a runnable workerd path: `KODY_WORKERD_PATH` when set, otherwise the
|
|
17
|
+
* pinned release under the user cache dir (downloaded and verified on first use).
|
|
18
|
+
*/
|
|
19
|
+
export declare function ensureWorkerdBinary(input?: {
|
|
20
|
+
env?: NodeJS.ProcessEnv;
|
|
21
|
+
cacheDir?: string;
|
|
22
|
+
target?: WorkerdTarget;
|
|
23
|
+
fetchFn?: typeof fetch;
|
|
24
|
+
onDownload?: (url: string) => void;
|
|
25
|
+
}): Promise<string>;
|
|
26
|
+
export declare function downloadVerifiedGzip(input: {
|
|
27
|
+
url: string;
|
|
28
|
+
sha256: string;
|
|
29
|
+
destination: string;
|
|
30
|
+
fetchFn: typeof fetch;
|
|
31
|
+
}): Promise<void>;
|