kimaki 1.2.0 → 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.
Files changed (63) hide show
  1. package/dist/bot.d.ts +4 -2
  2. package/dist/bot.js.map +1 -1
  3. package/dist/builtin-skills.d.ts +3 -0
  4. package/dist/builtin-skills.js +29 -0
  5. package/dist/builtin-skills.js.map +1 -1
  6. package/dist/builtin-skills.test.js +73 -1
  7. package/dist/builtin-skills.test.js.map +1 -1
  8. package/dist/cli/bot.d.ts +1 -1
  9. package/dist/cli/bot.js +15 -6
  10. package/dist/cli/bot.js.map +1 -1
  11. package/dist/cli-lock.e2e.test.js +3 -2
  12. package/dist/cli-lock.e2e.test.js.map +1 -1
  13. package/dist/commands/login-commands.d.ts +1 -1
  14. package/dist/commands/preference-commands.d.ts +1 -1
  15. package/dist/commands/worktree-commands.d.ts +1 -1
  16. package/dist/hello-thread.e2e.test.js +31 -0
  17. package/dist/hello-thread.e2e.test.js.map +1 -1
  18. package/dist/ingress.js +11 -6
  19. package/dist/ingress.js.map +1 -1
  20. package/dist/lock-routes.d.ts +14 -14
  21. package/dist/main.d.ts +2 -0
  22. package/dist/main.js +1 -0
  23. package/dist/main.js.map +1 -1
  24. package/dist/markdown/markdown.test.js +10 -0
  25. package/dist/markdown/markdown.test.js.map +1 -1
  26. package/dist/markdown/render-markdown.js +3 -1
  27. package/dist/markdown/render-markdown.js.map +1 -1
  28. package/dist/plugin/index.js +8 -2
  29. package/dist/plugin/index.js.map +1 -1
  30. package/dist/prompt.d.ts +6 -6
  31. package/dist/scheduler.d.ts +1 -1
  32. package/dist/session-events.js +9 -5
  33. package/dist/session-events.js.map +1 -1
  34. package/dist/sessions.d.ts +10 -10
  35. package/dist/sessions.js +1 -0
  36. package/dist/sessions.js.map +1 -1
  37. package/dist/system-prompt.d.ts +3 -1
  38. package/dist/system-prompt.js +52 -43
  39. package/dist/system-prompt.js.map +1 -1
  40. package/dist/tunnel.d.ts +21 -0
  41. package/dist/tunnel.js +296 -0
  42. package/dist/tunnel.js.map +1 -0
  43. package/dist/tunnel.test.d.ts +1 -0
  44. package/dist/tunnel.test.js +114 -0
  45. package/dist/tunnel.test.js.map +1 -0
  46. package/package.json +3 -3
  47. package/skills/kimaki-tunnel/SKILL.md +16 -11
  48. package/src/bot.ts +3 -0
  49. package/src/builtin-skills.test.ts +74 -1
  50. package/src/builtin-skills.ts +33 -0
  51. package/src/cli/bot.ts +13 -7
  52. package/src/cli-lock.e2e.test.ts +3 -2
  53. package/src/hello-thread.e2e.test.ts +35 -0
  54. package/src/ingress.ts +9 -5
  55. package/src/main.ts +4 -0
  56. package/src/markdown/markdown.test.ts +11 -0
  57. package/src/markdown/render-markdown.ts +3 -1
  58. package/src/plugin/index.ts +9 -2
  59. package/src/session-events.ts +8 -4
  60. package/src/sessions.ts +1 -0
  61. package/src/system-prompt.ts +56 -42
  62. package/src/tunnel.test.ts +115 -0
  63. package/src/tunnel.ts +308 -0
@@ -1 +1 @@
1
- {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../src/system-prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import http from 'node:http';
2
+ export declare function detectPortFromText(text: string): number | null;
3
+ export declare function routeName({ name, tuistorySessionId }: {
4
+ name?: string;
5
+ tuistorySessionId?: string;
6
+ }): string | Error;
7
+ export declare function parseNetstatListeningPids({ stdout, port }: {
8
+ stdout: string;
9
+ port: number;
10
+ }): number[];
11
+ export declare function startHostProxy({ host, port }: {
12
+ host: string;
13
+ port: number;
14
+ }): Promise<http.Server | Error>;
15
+ export declare function runTunnel(options: {
16
+ port?: number;
17
+ command?: string[];
18
+ name?: string;
19
+ host?: string;
20
+ kill?: boolean;
21
+ }): Promise<void | Error>;
package/dist/tunnel.js ADDED
@@ -0,0 +1,296 @@
1
+ // `kimaki tunnel`: run a command, find the local port it listens on, and expose
2
+ // it at https://<route>.<id>.opentunnel.xyz. TLS ends in this process, so the
3
+ // relay never sees plaintext. The tunnel identity is the default opentunnel
4
+ // profile in $XDG_DATA_HOME/opentunnel, shared with the opentunnel CLI.
5
+ import crypto from 'node:crypto';
6
+ import { execFile, spawn } from 'node:child_process';
7
+ import http from 'node:http';
8
+ import net from 'node:net';
9
+ import { setTimeout as sleep } from 'node:timers/promises';
10
+ import { promisify, stripVTControlCharacters } from 'node:util';
11
+ import { create as createOpenTunnel, isValidRouteName, OpenTunnelClientError, publicUrl, } from '@opentunnel/client';
12
+ const execFileAsync = promisify(execFile);
13
+ const PORT_WAIT_MS = 30_000;
14
+ const CHILD_KILL_GRACE_MS = 5_000;
15
+ // Only lines with host:port, so "Port 5173 is in use" does not match.
16
+ const LOCAL_PORT_PATTERN = /(?:https?:\/\/)?(?:localhost|127\.0\.0\.1|0\.0\.0\.0|\[::\]):(\d{1,5})/i;
17
+ const IGNORED_LINE_PATTERNS = [/\bdebugger (?:listening|attached)\b/i, /\bdevtools listening\b/i];
18
+ export function detectPortFromText(text) {
19
+ // Vite colors the port separately, so strip ANSI before matching.
20
+ for (const line of stripVTControlCharacters(text).split('\n')) {
21
+ if (IGNORED_LINE_PATTERNS.some((pattern) => pattern.test(line)))
22
+ continue;
23
+ const port = Number(line.match(LOCAL_PORT_PATTERN)?.[1]);
24
+ if (port >= 1 && port <= 65_535)
25
+ return port;
26
+ }
27
+ return null;
28
+ }
29
+ // Traforo accepted any tunnel ID, so map it to a DNS label instead of failing: `My_App` becomes `my-app`.
30
+ function toRouteLabel(raw) {
31
+ const label = raw.toLowerCase().replace(/[^a-z0-9-]+/g, '-').replace(/^-+|-+$/g, '').slice(0, 63).replace(/-+$/, '');
32
+ return isValidRouteName(label) ? label : '';
33
+ }
34
+ // Explicit name, then the tuistory session ID (stable URL across restarts of one session), then random.
35
+ export function routeName({ name, tuistorySessionId }) {
36
+ if (name)
37
+ return toRouteLabel(name) || new Error(`Invalid tunnel ID ${JSON.stringify(name)}: use letters, digits and dashes`);
38
+ return toRouteLabel(tuistorySessionId ?? '') || crypto.randomBytes(8).toString('hex');
39
+ }
40
+ // Parses `netstat -ano` output on Windows: `TCP 0.0.0.0:5173 0.0.0.0:0 LISTENING 1234`.
41
+ export function parseNetstatListeningPids({ stdout, port }) {
42
+ const pids = new Set();
43
+ for (const line of stdout.split('\n')) {
44
+ const [protocol, local, , state, pid] = line.trim().split(/\s+/);
45
+ if (protocol !== 'TCP' || state !== 'LISTENING' || !local?.endsWith(`:${port}`))
46
+ continue;
47
+ const parsed = Number(pid);
48
+ if (Number.isInteger(parsed) && parsed > 0)
49
+ pids.add(parsed);
50
+ }
51
+ return [...pids];
52
+ }
53
+ function isPortInUse({ port, host }) {
54
+ return new Promise((resolve) => {
55
+ const socket = net.connect({ port, host });
56
+ socket.once('connect', () => { socket.destroy(); resolve(true); });
57
+ socket.once('error', () => { socket.destroy(); resolve(false); });
58
+ });
59
+ }
60
+ async function waitForPort({ port, host, signal }) {
61
+ while (!(await isPortInUse({ port, host }))) {
62
+ if (signal.aborted)
63
+ return new Error(`Timed out waiting for ${host}:${port} to accept connections`);
64
+ await sleep(300);
65
+ }
66
+ }
67
+ async function listeningPids(port) {
68
+ if (process.platform === 'win32') {
69
+ const { stdout } = await execFileAsync('netstat', ['-ano'], { timeout: 5_000 }).catch(() => ({ stdout: '' }));
70
+ return parseNetstatListeningPids({ stdout, port });
71
+ }
72
+ const { stdout } = await execFileAsync('lsof', ['-ti', `tcp:${port}`, '-sTCP:LISTEN'], { timeout: 5_000 }).catch(() => ({ stdout: '' }));
73
+ return stdout.split('\n').map(Number).filter((pid) => Number.isInteger(pid) && pid > 0);
74
+ }
75
+ async function killProcessOnPort({ port, host }) {
76
+ for (const signal of ['SIGTERM', 'SIGKILL']) {
77
+ for (const pid of await listeningPids(port)) {
78
+ try {
79
+ process.kill(pid, signal);
80
+ }
81
+ catch { }
82
+ }
83
+ for (let waited = 0; waited < 3_000; waited += 200) {
84
+ if (!(await isPortInUse({ port, host })))
85
+ return;
86
+ await sleep(200);
87
+ }
88
+ }
89
+ return new Error(`Port ${port} is still in use after --kill`);
90
+ }
91
+ function detectPortFromOutput({ child, signal }) {
92
+ return new Promise((resolve) => {
93
+ let buffer = '';
94
+ const finish = (result) => {
95
+ child.stdout?.off('data', onData);
96
+ child.stderr?.off('data', onData);
97
+ child.off('exit', onExit);
98
+ signal.removeEventListener('abort', onAbort);
99
+ resolve(result);
100
+ };
101
+ const onData = (chunk) => {
102
+ buffer = (buffer + chunk.toString()).slice(-8_000);
103
+ const port = detectPortFromText(buffer);
104
+ if (port)
105
+ finish(port);
106
+ };
107
+ const onExit = (code) => finish(new Error(`Command exited with code ${code} before printing a localhost URL. Pass --port`));
108
+ const onAbort = () => finish(new Error(`No localhost URL in the command output after ${PORT_WAIT_MS / 1000}s. Pass --port`));
109
+ child.stdout?.on('data', onData);
110
+ child.stderr?.on('data', onData);
111
+ child.once('exit', onExit);
112
+ signal.addEventListener('abort', onAbort, { once: true });
113
+ });
114
+ }
115
+ function killChild(child, signal = 'SIGTERM') {
116
+ if (!child || child.exitCode !== null || child.signalCode !== null)
117
+ return Promise.resolve();
118
+ return new Promise((resolve) => {
119
+ const timer = setTimeout(() => { child.kill('SIGKILL'); resolve(); }, CHILD_KILL_GRACE_MS);
120
+ child.once('exit', () => { clearTimeout(timer); resolve(); });
121
+ child.kill(signal);
122
+ });
123
+ }
124
+ const log = (line) => process.stderr.write(`${line}\n`);
125
+ function logTunnelEvent(event) {
126
+ if (event.type === 'disconnected')
127
+ log(`Tunnel disconnected: ${event.reason}`);
128
+ if (event.type === 'connected')
129
+ log('Tunnel connected');
130
+ }
131
+ function forwardedHeaders({ headers, target }) {
132
+ return {
133
+ ...headers,
134
+ host: target,
135
+ 'x-forwarded-host': headers['x-forwarded-host'] ?? headers.host,
136
+ 'x-forwarded-proto': headers['x-forwarded-proto'] ?? 'https',
137
+ };
138
+ }
139
+ function rawResponseHead(response) {
140
+ let head = `HTTP/1.1 ${response.statusCode} ${response.statusMessage}\r\n`;
141
+ for (let i = 0; i < response.rawHeaders.length; i += 2)
142
+ head += `${response.rawHeaders[i]}: ${response.rawHeaders[i + 1]}\r\n`;
143
+ return `${head}\r\n`;
144
+ }
145
+ // opentunnel forwards the raw bytes, so the app would see the public Host header. Vite and other dev
146
+ // servers reject unknown hosts (DNS rebinding protection) with 403. This loopback proxy sends
147
+ // Host: localhost:<port> and keeps the public host in X-Forwarded-Host, like traforo did.
148
+ export function startHostProxy({ host, port }) {
149
+ const target = `${host}:${port}`;
150
+ const server = http.createServer((req, res) => {
151
+ const upstream = http.request({ host, port, method: req.method, path: req.url, headers: forwardedHeaders({ headers: req.headers, target }) }, (response) => {
152
+ res.writeHead(response.statusCode ?? 502, response.statusMessage, response.rawHeaders);
153
+ response.pipe(res);
154
+ });
155
+ upstream.on('error', () => {
156
+ if (!res.headersSent)
157
+ res.writeHead(502);
158
+ res.end();
159
+ });
160
+ req.pipe(upstream);
161
+ });
162
+ // WebSocket upgrades (Vite HMR): replay the handshake upstream, then pipe both sockets.
163
+ server.on('upgrade', (req, socket, head) => {
164
+ const upstream = http.request({ host, port, method: req.method, path: req.url, headers: forwardedHeaders({ headers: req.headers, target }) });
165
+ upstream.on('upgrade', (response, upstreamSocket, upstreamHead) => {
166
+ socket.write(rawResponseHead(response));
167
+ if (upstreamHead.length > 0)
168
+ socket.write(upstreamHead);
169
+ if (head.length > 0)
170
+ upstreamSocket.write(head);
171
+ upstreamSocket.on('error', () => socket.destroy());
172
+ socket.on('error', () => upstreamSocket.destroy());
173
+ upstreamSocket.pipe(socket).pipe(upstreamSocket);
174
+ });
175
+ upstream.on('response', (response) => {
176
+ socket.write(rawResponseHead(response));
177
+ response.pipe(socket);
178
+ });
179
+ upstream.on('error', () => socket.destroy());
180
+ socket.on('error', () => upstream.destroy());
181
+ upstream.end();
182
+ });
183
+ return new Promise((resolve) => {
184
+ server.once('error', (cause) => resolve(new Error('Could not start the tunnel proxy', { cause })));
185
+ server.listen(0, '127.0.0.1', () => resolve(server));
186
+ });
187
+ }
188
+ export async function runTunnel(options) {
189
+ const host = options.host ?? 'localhost';
190
+ const route = routeName({ name: options.name, tuistorySessionId: process.env['TUISTORY_SESSION_ID'] });
191
+ if (route instanceof Error)
192
+ return route;
193
+ if (options.kill && !options.port)
194
+ return new Error('--kill needs --port');
195
+ if (options.port && options.kill) {
196
+ const killed = await killProcessOnPort({ port: options.port, host });
197
+ if (killed instanceof Error)
198
+ return killed;
199
+ }
200
+ else if (options.port && options.command && (await isPortInUse({ port: options.port, host }))) {
201
+ return new Error(`Port ${options.port} is already in use. Pass --kill to stop the process on it first`);
202
+ }
203
+ const client = createOpenTunnel();
204
+ let waitLogged = false;
205
+ const identity = await client.tunnel
206
+ .ensure({
207
+ onProgress: (stage) => {
208
+ if (waitLogged || stage === 'checking-certificate' || stage === 'ready')
209
+ return;
210
+ waitLogged = true;
211
+ log('Getting a certificate for the opentunnel.xyz tunnel of this machine (up to a minute)...');
212
+ },
213
+ })
214
+ .catch((cause) => new Error('Could not create the opentunnel tunnel', { cause }));
215
+ if (identity instanceof Error)
216
+ return identity;
217
+ const url = publicUrl(route, identity.hostname);
218
+ let child;
219
+ let connection;
220
+ // Set before we kill the child ourselves, so its exit does not end the process first.
221
+ let stopping = false;
222
+ const shutdown = async (signal) => {
223
+ if (stopping)
224
+ return;
225
+ stopping = true;
226
+ log('Shutting down...');
227
+ await connection?.close().catch(() => undefined);
228
+ await killChild(child, signal);
229
+ process.exit(0);
230
+ };
231
+ for (const signal of ['SIGINT', 'SIGTERM', 'SIGHUP'])
232
+ process.once(signal, () => void shutdown(signal));
233
+ if (options.command) {
234
+ const [cmd, ...args] = options.command;
235
+ child = spawn(cmd, args, {
236
+ stdio: ['inherit', 'pipe', 'pipe'],
237
+ env: {
238
+ ...process.env,
239
+ ...(options.port && { PORT: String(options.port) }),
240
+ KIMAKI_TUNNEL_URL: url,
241
+ // Old name from traforo, kept so existing app configs still work.
242
+ TRAFORO_URL: url,
243
+ // wrangler dev passes parent env vars as worker bindings, so workers can read KIMAKI_TUNNEL_URL.
244
+ CLOUDFLARE_INCLUDE_PROCESS_ENV: 'true',
245
+ FORCE_COLOR: '1',
246
+ VITE_CLS: 'false',
247
+ NEXT_TELEMETRY_DISABLED: '1',
248
+ },
249
+ });
250
+ child.stdout?.pipe(process.stdout);
251
+ child.stderr?.pipe(process.stderr);
252
+ child.on('error', (error) => { log(`Failed to start command: ${error.message}`); process.exit(1); });
253
+ child.on('exit', (code, signal) => {
254
+ if (stopping)
255
+ return;
256
+ log(`Command exited with ${signal ?? `code ${code}`}`);
257
+ process.exit(code ?? 1);
258
+ });
259
+ }
260
+ const fail = async (error) => { stopping = true; await killChild(child); return error; };
261
+ let port = options.port;
262
+ const portSignal = AbortSignal.timeout(PORT_WAIT_MS);
263
+ if (!port && child) {
264
+ const detected = await detectPortFromOutput({ child, signal: portSignal });
265
+ if (detected instanceof Error)
266
+ return fail(detected);
267
+ port = detected;
268
+ }
269
+ if (!port)
270
+ return fail(new Error('Could not find the local port. Pass --port'));
271
+ const ready = await waitForPort({ port, host, signal: portSignal });
272
+ if (ready instanceof Error)
273
+ return fail(ready);
274
+ const proxy = await startHostProxy({ host, port });
275
+ if (proxy instanceof Error)
276
+ return fail(proxy);
277
+ const proxyAddress = proxy.address();
278
+ if (!proxyAddress || typeof proxyAddress === 'string')
279
+ return fail(new Error('Tunnel proxy has no TCP address'));
280
+ const attached = await client.tunnel
281
+ .connect({ routes: { [route]: `127.0.0.1:${proxyAddress.port}` }, onRouteConflict: 'fail', onEvent: logTunnelEvent })
282
+ .catch((cause) => {
283
+ if (cause instanceof OpenTunnelClientError && cause.code === 'route_conflict') {
284
+ return new Error(`Tunnel ID ${route} is already used by another process. Pass a different -t`, { cause });
285
+ }
286
+ return new Error('Could not connect the tunnel', { cause });
287
+ });
288
+ if (attached instanceof Error)
289
+ return fail(attached);
290
+ connection = attached;
291
+ process.stdout.write(`\nLocal: http://${host}:${port}\nTunnel: ${url}\n` +
292
+ `Agents: validate with the Local URL (playwriter, curl), it is much faster. The Tunnel URL is for the user.\n\n`);
293
+ const closed = await attached.closed.then(() => undefined, (cause) => new Error('Tunnel stopped', { cause }));
294
+ return fail(closed ?? new Error('Tunnel stopped'));
295
+ }
296
+ //# sourceMappingURL=tunnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,114 @@
1
+ import fs from 'node:fs';
2
+ import http from 'node:http';
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ import { createServer } from 'vite';
6
+ import { expect, test } from 'vitest';
7
+ import { detectPortFromText, parseNetstatListeningPids, routeName, startHostProxy } from "./tunnel.js";
8
+ test('detects the dev server port and skips noise lines', () => {
9
+ const vite = '\u001b[33mPort 5173 is in use, trying another one...\u001b[39m\n ➜ Local: \u001b[36mhttp://localhost:\u001b[1m5174\u001b[22m/\u001b[39m\n';
10
+ expect({
11
+ vite: detectPortFromText(vite),
12
+ next: detectPortFromText(' - Local: http://127.0.0.1:3000'),
13
+ bare: detectPortFromText('Server running at 0.0.0.0:4321'),
14
+ inspector: detectPortFromText('Debugger listening on ws://127.0.0.1:9229/abc\nready on http://localhost:4173'),
15
+ outOfRange: detectPortFromText('listening on localhost:70000'),
16
+ portOnly: detectPortFromText('Port 5173 is in use'),
17
+ }).toMatchInlineSnapshot(`
18
+ {
19
+ "bare": 4321,
20
+ "inspector": 4173,
21
+ "next": 3000,
22
+ "outOfRange": null,
23
+ "portOnly": null,
24
+ "vite": 5174,
25
+ }
26
+ `);
27
+ });
28
+ test('route name: explicit, then tuistory session, then random', () => {
29
+ expect({
30
+ explicit: routeName({ name: 'docs', tuistorySessionId: 'abc123' }),
31
+ normalized: routeName({ name: '_My_App.dev_' }),
32
+ invalid: String(routeName({ name: '___' })),
33
+ tuistory: routeName({ tuistorySessionId: 'Holocron_Dev' }),
34
+ tuistoryInvalid: String(routeName({ tuistorySessionId: '___' })).length,
35
+ random: String(routeName({})).length,
36
+ }).toMatchInlineSnapshot(`
37
+ {
38
+ "explicit": "docs",
39
+ "invalid": "Error: Invalid tunnel ID "___": use letters, digits and dashes",
40
+ "normalized": "my-app-dev",
41
+ "random": 16,
42
+ "tuistory": "holocron-dev",
43
+ "tuistoryInvalid": 16,
44
+ }
45
+ `);
46
+ });
47
+ test('netstat listening pids on Windows', () => {
48
+ const stdout = [
49
+ 'Active Connections',
50
+ ' Proto Local Address Foreign Address State PID',
51
+ ' TCP 0.0.0.0:5173 0.0.0.0:0 LISTENING 1234',
52
+ ' TCP [::]:5173 [::]:0 LISTENING 1234',
53
+ ' TCP 127.0.0.1:51730 0.0.0.0:0 LISTENING 999',
54
+ ' TCP 127.0.0.1:5173 127.0.0.1:60000 ESTABLISHED 777',
55
+ ' UDP 0.0.0.0:5173 *:* 555',
56
+ ].join('\r\n');
57
+ expect(parseNetstatListeningPids({ stdout, port: 5173 })).toMatchInlineSnapshot(`
58
+ [
59
+ 1234,
60
+ ]
61
+ `);
62
+ });
63
+ function request({ port, headers }) {
64
+ return new Promise((resolve, reject) => {
65
+ const req = http.request({ host: '127.0.0.1', port, path: '/', headers });
66
+ req.on('response', (res) => {
67
+ res.resume();
68
+ resolve(String(res.statusCode));
69
+ req.destroy();
70
+ });
71
+ req.on('upgrade', (res, socket) => {
72
+ resolve(`${res.statusCode} ${res.headers['sec-websocket-protocol']}`);
73
+ socket.destroy();
74
+ });
75
+ req.on('error', reject);
76
+ req.end();
77
+ });
78
+ }
79
+ test('host proxy lets the public tunnel host through Vite host check, HMR included', async () => {
80
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'kimaki-tunnel-'));
81
+ fs.writeFileSync(path.join(root, 'index.html'), '<p>hi</p>');
82
+ const vite = await createServer({ root, configFile: false, logLevel: 'silent', server: { host: '127.0.0.1', port: 0 } });
83
+ await vite.listen();
84
+ const address = vite.httpServer.address();
85
+ if (!address || typeof address === 'string')
86
+ throw new Error('no vite address');
87
+ const proxy = await startHostProxy({ host: '127.0.0.1', port: address.port });
88
+ if (proxy instanceof Error)
89
+ throw proxy;
90
+ const proxyAddress = proxy.address();
91
+ if (!proxyAddress || typeof proxyAddress === 'string')
92
+ throw new Error('no proxy address');
93
+ const publicHost = { host: 'docs.abc.opentunnel.xyz' };
94
+ const hmr = { ...publicHost, connection: 'Upgrade', upgrade: 'websocket', 'sec-websocket-version': '13', 'sec-websocket-key': 'dGhlIHNhbXBsZSBub25jZQ==', 'sec-websocket-protocol': 'vite-hmr' };
95
+ try {
96
+ expect({
97
+ direct: await request({ port: address.port, headers: publicHost }),
98
+ proxied: await request({ port: proxyAddress.port, headers: publicHost }),
99
+ proxiedHmr: await request({ port: proxyAddress.port, headers: hmr }),
100
+ }).toMatchInlineSnapshot(`
101
+ {
102
+ "direct": "403",
103
+ "proxied": "200",
104
+ "proxiedHmr": "101 vite-hmr",
105
+ }
106
+ `);
107
+ }
108
+ finally {
109
+ proxy.close();
110
+ await vite.close();
111
+ fs.rmSync(root, { recursive: true, force: true });
112
+ }
113
+ });
114
+ //# sourceMappingURL=tunnel.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.test.js","sourceRoot":"","sources":["../src/tunnel.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kimaki",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "description": "A collaborative agent orchestrator for OpenCode, inside Discord",
5
5
  "repository": "https://github.com/remorses/kimaki",
6
6
  "type": "module",
@@ -20,6 +20,7 @@
20
20
  "@libsql/client": "^0.17.2",
21
21
  "@opencode/client": "2.0.29",
22
22
  "@opencode/plugin": "2.0.29",
23
+ "@opentunnel/client": "0.6.0",
23
24
  "@strada.sh/sdk": "^0.8.0",
24
25
  "cron-parser": "^5.5.0",
25
26
  "discord-api-types": "^0.38.40",
@@ -39,8 +40,7 @@
39
40
  "werift": "^0.25.0",
40
41
  "zod": "^4.4.3",
41
42
  "zustand": "^5.0.14",
42
- "errore": "^0.14.1",
43
- "traforo": "^0.7.2"
43
+ "errore": "^0.14.1"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@opencode/cli": "2.0.29",
@@ -1,30 +1,35 @@
1
1
  ---
2
2
  name: kimaki-tunnel
3
- description: Share a local dev server with the user through a public URL. Use when the user should open a localhost app in a browser, test a webhook or OAuth callback against a local server, or preview a dev server from Discord. Runs `kimaki tunnel` in a named background tuistory session. ALWAYS load before starting a dev server the user must open. Only for Kimaki Discord sessions.
3
+ description: Share a local dev server with the user through a public URL. Localhost URLs are useless from Discord. Use when the user should open a localhost app in a browser, test a webhook or OAuth callback against a local server, or preview a dev server from Discord. Runs `kimaki tunnel` in a named background tuistory session. ALWAYS load before starting a dev server the user must open. Only for Kimaki Discord sessions.
4
4
  ---
5
5
 
6
6
  # Dev servers with tunnel access
7
7
 
8
- Localhost URLs are useless from Discord. Wrap the dev server in `kimaki tunnel` to get a public URL, and run it in a named background `tuistory` session so you can wait for output, read logs and stop it later. Name the session descriptively (e.g. `projectname-dev`) and reuse it. Run `tuistory --help` first (or `bunx tuistory` when it is not installed). Invoke `kimaki` directly, not via `npx` or `bunx`.
8
+ Localhost URLs are useless from Discord. Wrap the dev server in `kimaki tunnel` to get a public `https://<name>.<id>.opentunnel.xyz` URL, and run it in a named background `tuistory` session so you can wait for output, read logs and stop it later. Name the session descriptively (e.g. `projectname-dev`) and reuse it. Run `tuistory --help` first (or `bunx tuistory` when it is not installed). Invoke `kimaki` directly, not via `npx` or `bunx`.
9
9
 
10
- - Use random tunnel IDs by default. Pass `-t <id>` only for services that are safe to be publicly discoverable.
11
- - `kimaki tunnel` detects the local port from the child output. Pass `--port` only when the server prints no detectable localhost URL or port line.
12
- - `kimaki tunnel` injects `TRAFORO_URL` into the child process. Wire the app to it so OAuth callbacks, webhook URLs and absolute links use the public URL.
10
+ - **Validate on localhost.** The agent runs on the same machine as the server, so playwriter, curl and tests must use the `Local:` URL. It is much faster. The tunnel URL is only for the user.
11
+ - Use random names by default. Pass `-t <name>` only for services that are safe to be publicly discoverable.
12
+ - `kimaki tunnel` detects the local port from the child output. Pass `--port` only when the server prints no detectable localhost URL.
13
+ - `kimaki tunnel` injects `KIMAKI_TUNNEL_URL` into the child process. Wire the app to it so OAuth callbacks, webhook URLs and absolute links use the public URL.
14
+ - The app gets `Host: localhost:<port>` and the public host in `X-Forwarded-Host`, so Vite needs no `allowedHosts` config.
15
+ - The first run on a machine creates the tunnel and waits up to a minute for its certificate.
13
16
 
14
17
  ```bash
15
18
  # start in a named background session, wait for output, then read the tunnel URL
16
19
  tuistory launch "kimaki tunnel -- pnpm dev" -s myapp-dev
17
- tuistory -s myapp-dev wait "/ready|local|tunnel/i" --timeout 30000
20
+ tuistory -s myapp-dev wait "/Tunnel: https/" --timeout 90000
18
21
  tuistory read -s myapp-dev
19
22
 
20
- # pass the public URL to the app (better-auth, Next.js, Vite; node reads process.env.TRAFORO_URL)
21
- tuistory launch "kimaki tunnel -- sh -c 'BETTER_AUTH_URL=$TRAFORO_URL exec pnpm dev'" -s myapp-dev
22
- tuistory launch "kimaki tunnel -- sh -c 'APP_URL=$TRAFORO_URL exec pnpm dev'" -s myapp-dev
23
- tuistory launch "kimaki tunnel -- sh -c 'VITE_BASE_URL=$TRAFORO_URL exec pnpm dev'" -s myapp-dev
23
+ # pass the public URL to the app (better-auth, Next.js, Vite; node reads process.env.KIMAKI_TUNNEL_URL)
24
+ tuistory launch "kimaki tunnel -- sh -c 'BETTER_AUTH_URL=\$KIMAKI_TUNNEL_URL exec pnpm dev'" -s myapp-dev
25
+ tuistory launch "kimaki tunnel -- sh -c 'APP_URL=\$KIMAKI_TUNNEL_URL exec pnpm dev'" -s myapp-dev
24
26
 
25
- # custom tunnel ID (only for intentionally public-safe services)
27
+ # fixed name (only for intentionally public-safe services)
26
28
  tuistory launch "kimaki tunnel -t holocron -- pnpm dev" -s holocron-dev
27
29
 
30
+ # restart the server on a known port and keep the URL
31
+ tuistory launch "kimaki tunnel -t holocron -p 5173 --kill -- pnpm dev --port 5173" -s holocron-dev
32
+
28
33
  # list sessions; stop with Ctrl+C, then close
29
34
  tuistory sessions
30
35
  tuistory -s myapp-dev press ctrl c
package/src/bot.ts CHANGED
@@ -11,6 +11,7 @@ import { ChannelType, type Client, type TextChannel, type ThreadChannel } from '
11
11
 
12
12
  import type { AgentUi } from './agent-ui.ts'
13
13
  import type { Analytics } from './analytics.ts'
14
+ import type { PromptSection } from './builtin-skills.ts'
14
15
  import type { KimakiDb } from './db.ts'
15
16
  import type { EffectsRunner } from './effects.ts'
16
17
  import { ConfigError, DbError, DiscordError, OpenCodeError, OpenCodeUnavailableError } from './errors.ts'
@@ -69,6 +70,8 @@ export type Bot = {
69
70
  allowAllUsers: boolean
70
71
  // Built-in skill ids (builtin-skills.ts) denied through the permissions of new sessions.
71
72
  disabledSkills: readonly string[]
73
+ // `kimaki --disable-prompt`: static instruction parts left out of new sessions.
74
+ disabledPrompt: readonly PromptSection[]
72
75
  features: BotFeatures
73
76
  }
74
77