tinyrelayfile
tinyrelay/scripts/qa/buzz-runner-acp.mjs/

scripts/qa/buzz-runner-acp.mjs raw
1#!/usr/bin/env node
2// Small ACP peer used by buzz-runner-integration.mjs. It is intentionally
3// disposable: it never connects to a relay and only speaks JSON-RPC on stdio.
4let buffer = '';
5let permissionID = 40;
6let sessionID = 'qa-session';
7let awaitingPermission = false;
8if (process.env.FAKE_ACP_MODE === 'crash-once') {
9 const fs = await import('node:fs');
10 if (!fs.existsSync(process.env.FAKE_ACP_MARKER)) fs.writeFileSync(process.env.FAKE_ACP_MARKER, 'crashed');
11 else process.env.FAKE_ACP_MODE = '';
12}
13process.stdin.setEncoding('utf8');
14process.stdin.on('data', chunk => {
15 buffer += chunk;
16 while (buffer.includes('\n')) {
17 const newline = buffer.indexOf('\n');
18 const line = buffer.slice(0, newline);
19 buffer = buffer.slice(newline + 1);
20 if (!line.trim()) continue;
21 let frame;
22 try { frame = JSON.parse(line); } catch { continue; }
23 handle(frame);
24 }
25});
26function send(frame) { process.stdout.write(JSON.stringify(frame) + '\n'); }
27function handle(frame) {
28 if (frame.method === 'initialize') {
29 send({jsonrpc: '2.0', id: frame.id, result: {protocolVersion: 1}});
30 return;
31 }
32 if (frame.method === 'session/new') {
33 send({jsonrpc: '2.0', id: frame.id, result: {sessionId: sessionID}});
34 return;
35 }
36 if (frame.method === 'session/cancel') {
37 send({jsonrpc: '2.0', id: frame.id, result: {}});
38 return;
39 }
40 if (frame.method === 'session/prompt') {
41 if (process.env.FAKE_ACP_MODE === 'crash-once') process.exit(23);
42 send({jsonrpc: '2.0', method: 'session/update', params: {sessionId: sessionID, update: {sessionUpdate: 'tool_call', title: 'publish preview', status: 'running'}}});
43 awaitingPermission = true;
44 send({jsonrpc: '2.0', id: ++permissionID, method: 'session/request_permission', params: {sessionId: sessionID, toolCall: {title: 'Publish preview', rawInput: {path: 'public/preview.html'}}, options: [{optionId: 'allow', name: 'Allow once', kind: 'allow_once'}, {optionId: 'deny', name: 'Deny once', kind: 'reject_once'}]}});
45 return;
46 }
47 if (frame.id === permissionID && awaitingPermission) {
48 awaitingPermission = false;
49 const outcome = frame.result?.outcome;
50 if (outcome?.outcome !== 'selected' || outcome.optionId !== 'allow') {
51 send({jsonrpc: '2.0', id: 3, result: {stopReason: 'cancelled'}});
52 return;
53 }
54 send({jsonrpc: '2.0', method: 'session/update', params: {sessionId: sessionID, update: {sessionUpdate: 'agent_message_chunk', content: {type: 'text', text: 'Preview published.'}}}});
55 send({jsonrpc: '2.0', id: 3, result: {stopReason: 'end_turn'}});
56 }
57}

About

ownerc01503e8035f
visibilitypublic
headd730679639bf

Maintainers

  • c01503e8035f owner
  • ba1b5beed5b5 agent hermes

Clone

  • https://012.run/npub1cq2s86qrtadf36eqq3epm38wmhdynrrcwxf84eldk3f94dkv7ttsrulrz5/tinyrelay.git

Refs