roughbook 0.0.0-stage → 0.1.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/LICENSE +201 -0
- package/README.md +166 -2
- package/dist/agents/claude.js +214 -0
- package/dist/agents/claude.js.map +1 -0
- package/dist/agents/codex.js +179 -0
- package/dist/agents/codex.js.map +1 -0
- package/dist/agents/command.js +47 -0
- package/dist/agents/command.js.map +1 -0
- package/dist/agents/index.js +21 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/process.js +76 -0
- package/dist/agents/process.js.map +1 -0
- package/dist/agents/session.js +26 -0
- package/dist/agents/session.js.map +1 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/api/client.js +138 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/errors.js +40 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/outbox.js +105 -0
- package/dist/api/outbox.js.map +1 -0
- package/dist/api/types.js +4 -0
- package/dist/api/types.js.map +1 -0
- package/dist/cli.js +10 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agents.js +39 -0
- package/dist/commands/agents.js.map +1 -0
- package/dist/commands/context.js +27 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/done.js +125 -0
- package/dist/commands/done.js.map +1 -0
- package/dist/commands/index.js +101 -0
- package/dist/commands/index.js.map +1 -0
- package/dist/commands/init.js +203 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/login.js +93 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.js +34 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/promote.js +105 -0
- package/dist/commands/promote.js.map +1 -0
- package/dist/commands/pull.js +45 -0
- package/dist/commands/pull.js.map +1 -0
- package/dist/commands/revert.js +39 -0
- package/dist/commands/revert.js.map +1 -0
- package/dist/commands/review.js +73 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/run.js +147 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/shared.js +81 -0
- package/dist/commands/shared.js.map +1 -0
- package/dist/commands/start.js +119 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.js +62 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/config/credentials.js +17 -0
- package/dist/config/credentials.js.map +1 -0
- package/dist/config/server.js +29 -0
- package/dist/config/server.js.map +1 -0
- package/dist/config/settings.js +21 -0
- package/dist/config/settings.js.map +1 -0
- package/dist/config/userDir.js +18 -0
- package/dist/config/userDir.js.map +1 -0
- package/dist/fs/json.js +44 -0
- package/dist/fs/json.js.map +1 -0
- package/dist/fs/lock.js +38 -0
- package/dist/fs/lock.js.map +1 -0
- package/dist/io.js +26 -0
- package/dist/io.js.map +1 -0
- package/dist/launch/open.js +48 -0
- package/dist/launch/open.js.map +1 -0
- package/dist/launch/platform.js +38 -0
- package/dist/launch/platform.js.map +1 -0
- package/dist/launch/pty.js +61 -0
- package/dist/launch/pty.js.map +1 -0
- package/dist/launch/terminal.js +194 -0
- package/dist/launch/terminal.js.map +1 -0
- package/dist/launch/which.js +59 -0
- package/dist/launch/which.js.map +1 -0
- package/dist/repo/diff.js +26 -0
- package/dist/repo/diff.js.map +1 -0
- package/dist/repo/framework.js +41 -0
- package/dist/repo/framework.js.map +1 -0
- package/dist/repo/link.js +28 -0
- package/dist/repo/link.js.map +1 -0
- package/dist/repo/prep.js +447 -0
- package/dist/repo/prep.js.map +1 -0
- package/dist/repo/preview.js +144 -0
- package/dist/repo/preview.js.map +1 -0
- package/dist/repo/root.js +48 -0
- package/dist/repo/root.js.map +1 -0
- package/dist/repo/scratch.js +111 -0
- package/dist/repo/scratch.js.map +1 -0
- package/dist/runs/checks.js +160 -0
- package/dist/runs/checks.js.map +1 -0
- package/dist/runs/lifecycle.js +142 -0
- package/dist/runs/lifecycle.js.map +1 -0
- package/dist/runs/promote.js +185 -0
- package/dist/runs/promote.js.map +1 -0
- package/dist/runs/pull.js +182 -0
- package/dist/runs/pull.js.map +1 -0
- package/dist/runs/reviews.js +34 -0
- package/dist/runs/reviews.js.map +1 -0
- package/dist/runs/slots.js +96 -0
- package/dist/runs/slots.js.map +1 -0
- package/dist/runs/snapshot.js +265 -0
- package/dist/runs/snapshot.js.map +1 -0
- package/dist/runs/store.js +38 -0
- package/dist/runs/store.js.map +1 -0
- package/dist/runs/types.js +3 -0
- package/dist/runs/types.js.map +1 -0
- package/dist/runs/watch.js +42 -0
- package/dist/runs/watch.js.map +1 -0
- package/dist/screenshot/browser.js +163 -0
- package/dist/screenshot/browser.js.map +1 -0
- package/dist/screenshot/iteration.js +37 -0
- package/dist/screenshot/iteration.js.map +1 -0
- package/dist/server/app.js +321 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/security.js +44 -0
- package/dist/server/security.js.map +1 -0
- package/dist/server/studio.js +618 -0
- package/dist/server/studio.js.map +1 -0
- package/dist/server/terminals.js +142 -0
- package/dist/server/terminals.js.map +1 -0
- package/dist/ui/assets/ibm-plex-mono-latin-400-normal-CvHOgSBP.woff +0 -0
- package/dist/ui/assets/ibm-plex-mono-latin-400-normal-DMJ8VG8y.woff2 +0 -0
- package/dist/ui/assets/ibm-plex-mono-latin-500-normal-CB9ihrfo.woff +0 -0
- package/dist/ui/assets/ibm-plex-mono-latin-500-normal-DSY6xOcd.woff2 +0 -0
- package/dist/ui/assets/index-D-TSXfvz.css +1 -0
- package/dist/ui/assets/index-HGV8FKwI.js +27 -0
- package/dist/ui/assets/inter-latin-400-normal-C38fXH4l.woff2 +0 -0
- package/dist/ui/assets/inter-latin-400-normal-CyCys3Eg.woff +0 -0
- package/dist/ui/assets/inter-latin-500-normal-BL9OpVg8.woff +0 -0
- package/dist/ui/assets/inter-latin-500-normal-Cerq10X2.woff2 +0 -0
- package/dist/ui/assets/space-grotesk-latin-400-normal-BnQMeOim.woff +0 -0
- package/dist/ui/assets/space-grotesk-latin-400-normal-CJ-V5oYT.woff2 +0 -0
- package/dist/ui/assets/space-grotesk-latin-500-normal-CNSSEhBt.woff +0 -0
- package/dist/ui/assets/space-grotesk-latin-500-normal-lFbtlQH6.woff2 +0 -0
- package/dist/ui/index.html +14 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/package.json +68 -4
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
// OpenAI's Codex CLI. `codex exec` flags checked against OpenAI's CLI reference (2026-10-05):
|
|
2
|
+
// --json, --sandbox workspace-write, --cd, --model, --skip-git-repo-check, and "-" for a prompt
|
|
3
|
+
// on standard input. The sandbox confines writes to the working directory, so a headless run
|
|
4
|
+
// works in the run's folder and is told where the repo root is. Unattended runs use the
|
|
5
|
+
// designer's own API key (CODEX_API_KEY or OPENAI_API_KEY), never a ChatGPT login. No Codex CLI
|
|
6
|
+
// was installed where this was written: check the event names against the first real run.
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
import { diskProbe } from '../launch/platform.js';
|
|
9
|
+
import { findNpmScript, findOnPath, fromEnv } from '../launch/which.js';
|
|
10
|
+
import { count, record, runCommand } from './command.js';
|
|
11
|
+
const NOT_FOUND = 'Codex was not found. Install it (npm install -g @openai/codex), or set ROUGHBOOK_CODEX_BIN to the full path of codex.';
|
|
12
|
+
function apiKey(env) {
|
|
13
|
+
return env.CODEX_API_KEY?.trim() || env.OPENAI_API_KEY?.trim() || null;
|
|
14
|
+
}
|
|
15
|
+
export function parseCodexLine(line) {
|
|
16
|
+
let parsed;
|
|
17
|
+
try {
|
|
18
|
+
parsed = record(JSON.parse(line.trim()));
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return {};
|
|
22
|
+
}
|
|
23
|
+
const item = record(parsed.item);
|
|
24
|
+
switch (parsed.type) {
|
|
25
|
+
case 'thread.started':
|
|
26
|
+
return typeof parsed.thread_id === 'string'
|
|
27
|
+
? { event: { kind: 'session', id: parsed.thread_id } }
|
|
28
|
+
: {};
|
|
29
|
+
case 'item.started':
|
|
30
|
+
if (item.type === 'command_execution')
|
|
31
|
+
return { event: { kind: 'tool', name: 'Shell' } };
|
|
32
|
+
if (item.type === 'file_change')
|
|
33
|
+
return { event: { kind: 'tool', name: 'Write' } };
|
|
34
|
+
return {};
|
|
35
|
+
case 'item.completed': {
|
|
36
|
+
if (item.type === 'agent_message' && typeof item.text === 'string' && item.text.trim()) {
|
|
37
|
+
return { event: { kind: 'message', text: item.text } };
|
|
38
|
+
}
|
|
39
|
+
if (item.type === 'file_change') {
|
|
40
|
+
const first = record(Array.isArray(item.changes) ? item.changes[0] : null).path;
|
|
41
|
+
return {
|
|
42
|
+
event: { kind: 'file', name: typeof first === 'string' ? path.basename(first) : 'files' }
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
case 'turn.completed': {
|
|
48
|
+
const usage = record(parsed.usage);
|
|
49
|
+
const input = count(usage.input_tokens);
|
|
50
|
+
const cached = count(usage.cached_input_tokens);
|
|
51
|
+
return {
|
|
52
|
+
event: { kind: 'result', ok: true, text: null },
|
|
53
|
+
usage: {
|
|
54
|
+
// Codex does not say which model ran; the run fills it in.
|
|
55
|
+
model: '',
|
|
56
|
+
// As the backend counts them: input without the cached part.
|
|
57
|
+
inputTokens: input === null ? null : Math.max(0, input - (cached ?? 0)),
|
|
58
|
+
outputTokens: count(usage.output_tokens),
|
|
59
|
+
cacheReadTokens: cached,
|
|
60
|
+
cacheWriteTokens: null
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
case 'turn.failed':
|
|
65
|
+
case 'error': {
|
|
66
|
+
const message = record(parsed.error).message ?? parsed.message;
|
|
67
|
+
return {
|
|
68
|
+
event: {
|
|
69
|
+
kind: 'result',
|
|
70
|
+
ok: false,
|
|
71
|
+
text: typeof message === 'string' ? message.slice(0, 300) : null
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
default:
|
|
76
|
+
return {};
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export const codex = {
|
|
80
|
+
id: 'codex',
|
|
81
|
+
name: 'Codex',
|
|
82
|
+
kind: 'terminal',
|
|
83
|
+
capabilities: { interactive: true, headless: true, permissions: true, usage: true },
|
|
84
|
+
notFound: NOT_FOUND,
|
|
85
|
+
find(lookup) {
|
|
86
|
+
const p = lookup.platform === 'win32' ? path.win32 : path.posix;
|
|
87
|
+
const probe = lookup.probe ?? diskProbe;
|
|
88
|
+
const explicit = fromEnv('ROUGHBOOK_CODEX_BIN', lookup);
|
|
89
|
+
if (explicit)
|
|
90
|
+
return explicit;
|
|
91
|
+
const onPath = findOnPath('codex', lookup);
|
|
92
|
+
if (onPath)
|
|
93
|
+
return { command: onPath, prefixArgs: [], source: 'PATH' };
|
|
94
|
+
const npm = findNpmScript('codex', '@openai/codex', 'bin/codex.js', lookup);
|
|
95
|
+
if (npm)
|
|
96
|
+
return npm;
|
|
97
|
+
const native = p.join(lookup.home, '.local', 'bin', lookup.platform === 'win32' ? 'codex.exe' : 'codex');
|
|
98
|
+
return probe.exists(native)
|
|
99
|
+
? { command: native, prefixArgs: [], source: 'native install' }
|
|
100
|
+
: null;
|
|
101
|
+
},
|
|
102
|
+
async detect(lookup) {
|
|
103
|
+
const base = {
|
|
104
|
+
id: this.id,
|
|
105
|
+
name: this.name,
|
|
106
|
+
kind: this.kind,
|
|
107
|
+
capabilities: this.capabilities
|
|
108
|
+
};
|
|
109
|
+
const executable = this.find(lookup);
|
|
110
|
+
if (!executable) {
|
|
111
|
+
return {
|
|
112
|
+
...base,
|
|
113
|
+
found: false,
|
|
114
|
+
executable: null,
|
|
115
|
+
version: null,
|
|
116
|
+
signedIn: null,
|
|
117
|
+
signIn: null,
|
|
118
|
+
headless: { ready: false, reason: NOT_FOUND }
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
const version = await runCommand(executable, ['--version']);
|
|
122
|
+
const status = await runCommand(executable, ['login', 'status']);
|
|
123
|
+
const said = (status.stdout || status.stderr).trim().split('\n')[0]?.slice(0, 80) || null;
|
|
124
|
+
return {
|
|
125
|
+
...base,
|
|
126
|
+
found: version.ok,
|
|
127
|
+
executable,
|
|
128
|
+
version: (version.stdout || version.stderr).trim().split(/\s+/).pop() || null,
|
|
129
|
+
signedIn: status.ok,
|
|
130
|
+
signIn: status.ok ? said : 'not signed in',
|
|
131
|
+
headless: !version.ok
|
|
132
|
+
? { ready: false, reason: 'Codex could not be run.' }
|
|
133
|
+
: apiKey(lookup.env)
|
|
134
|
+
? { ready: true }
|
|
135
|
+
: {
|
|
136
|
+
ready: false,
|
|
137
|
+
reason: 'Unattended runs use your own OpenAI API key: set CODEX_API_KEY or OPENAI_API_KEY. A ChatGPT login works for terminal sessions.'
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
},
|
|
141
|
+
interactiveArgs(run) {
|
|
142
|
+
return [...(run.model ? ['--model', run.model] : []), run.instruction];
|
|
143
|
+
},
|
|
144
|
+
headless(run, executable, env) {
|
|
145
|
+
const key = apiKey(env);
|
|
146
|
+
if (!key) {
|
|
147
|
+
return {
|
|
148
|
+
refused: 'Unattended runs use your own OpenAI API key: set CODEX_API_KEY or OPENAI_API_KEY, or run it in a terminal session.'
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
const folder = path.join(run.repoRoot, ...run.targetFolder.split('/'));
|
|
152
|
+
return {
|
|
153
|
+
command: executable.command,
|
|
154
|
+
args: [
|
|
155
|
+
...executable.prefixArgs,
|
|
156
|
+
'exec',
|
|
157
|
+
'--json',
|
|
158
|
+
'--sandbox',
|
|
159
|
+
'workspace-write',
|
|
160
|
+
'--cd',
|
|
161
|
+
folder,
|
|
162
|
+
'--skip-git-repo-check',
|
|
163
|
+
...(run.model ? ['--model', run.model] : []),
|
|
164
|
+
'-'
|
|
165
|
+
],
|
|
166
|
+
cwd: folder,
|
|
167
|
+
stdin: [
|
|
168
|
+
`Your working directory is ${run.targetFolder}, the one folder you may write to.`,
|
|
169
|
+
`The repository root is ${run.repoRoot}. Every path in your instructions is relative to it: read from there, write only in your working directory.`,
|
|
170
|
+
'',
|
|
171
|
+
run.instruction,
|
|
172
|
+
''
|
|
173
|
+
].join('\n'),
|
|
174
|
+
env: { CODEX_API_KEY: key }
|
|
175
|
+
};
|
|
176
|
+
},
|
|
177
|
+
parseLine: parseCodexLine
|
|
178
|
+
};
|
|
179
|
+
//# sourceMappingURL=codex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/agents/codex.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,gGAAgG;AAChG,6FAA6F;AAC7F,wFAAwF;AACxF,gGAAgG;AAChG,0FAA0F;AAC1F,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAGzD,MAAM,SAAS,GACb,uHAAuH,CAAC;AAE1H,SAAS,MAAM,CAAC,GAAsB;IACpC,OAAO,GAAG,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,GAAG,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,MAA+B,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACjC,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,gBAAgB;YACnB,OAAO,OAAO,MAAM,CAAC,SAAS,KAAK,QAAQ;gBACzC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,SAAS,EAAE,EAAE;gBACtD,CAAC,CAAC,EAAE,CAAC;QACT,KAAK,cAAc;YACjB,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB;gBAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;YACzF,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa;gBAAE,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC;YACnF,OAAO,EAAE,CAAC;QACZ,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvF,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACzD,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;gBAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;gBAChF,OAAO;oBACL,KAAK,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE;iBAC1F,CAAC;YACJ,CAAC;YACD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,KAAK,gBAAgB,CAAC,CAAC,CAAC;YACtB,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACnC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACxC,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC;YAChD,OAAO;gBACL,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;gBAC/C,KAAK,EAAE;oBACL,2DAA2D;oBAC3D,KAAK,EAAE,EAAE;oBACT,6DAA6D;oBAC7D,WAAW,EAAE,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;oBACvE,YAAY,EAAE,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC;oBACxC,eAAe,EAAE,MAAM;oBACvB,gBAAgB,EAAE,IAAI;iBACvB;aACF,CAAC;QACJ,CAAC;QACD,KAAK,aAAa,CAAC;QACnB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC;YAC/D,OAAO;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,EAAE,EAAE,KAAK;oBACT,IAAI,EAAE,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI;iBACjE;aACF,CAAC;QACJ,CAAC;QACD;YACE,OAAO,EAAE,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,KAAK,GAAoB;IACpC,EAAE,EAAE,OAAO;IACX,IAAI,EAAE,OAAO;IACb,IAAI,EAAE,UAAU;IAChB,YAAY,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;IACnF,QAAQ,EAAE,SAAS;IAEnB,IAAI,CAAC,MAAM;QACT,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC;QAChE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,SAAS,CAAC;QACxC,MAAM,QAAQ,GAAG,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACxD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAC;QAC9B,MAAM,MAAM,GAAG,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC3C,IAAI,MAAM;YAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QACvE,MAAM,GAAG,GAAG,aAAa,CAAC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;QAC5E,IAAI,GAAG;YAAE,OAAO,GAAG,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CACnB,MAAM,CAAC,IAAI,EACX,QAAQ,EACR,KAAK,EACL,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CACpD,CAAC;QACF,OAAO,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC;YACzB,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE;YAC/D,CAAC,CAAC,IAAI,CAAC;IACX,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,MAAM;QACjB,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,YAAY,EAAE,IAAI,CAAC,YAAY;SACvB,CAAC;QACX,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACrC,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO;gBACL,GAAG,IAAI;gBACP,KAAK,EAAE,KAAK;gBACZ,UAAU,EAAE,IAAI;gBAChB,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,IAAI;gBACd,MAAM,EAAE,IAAI;gBACZ,QAAQ,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE;aAC9C,CAAC;QACJ,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;QACjE,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;QAC1F,OAAO;YACL,GAAG,IAAI;YACP,KAAK,EAAE,OAAO,CAAC,EAAE;YACjB,UAAU;YACV,OAAO,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI;YAC7E,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe;YAC1C,QAAQ,EAAE,CAAC,OAAO,CAAC,EAAE;gBACnB,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE;gBACrD,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;oBAClB,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE;oBACjB,CAAC,CAAC;wBACE,KAAK,EAAE,KAAK;wBACZ,MAAM,EACJ,gIAAgI;qBACnI;SACR,CAAC;IACJ,CAAC;IAED,eAAe,CAAC,GAAG;QACjB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;IACzE,CAAC;IAED,QAAQ,CAAC,GAAG,EAAE,UAAU,EAAE,GAAG;QAC3B,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACxB,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO;gBACL,OAAO,EACL,oHAAoH;aACvH,CAAC;QACJ,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,YAAY,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;QACvE,OAAO;YACL,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,IAAI,EAAE;gBACJ,GAAG,UAAU,CAAC,UAAU;gBACxB,MAAM;gBACN,QAAQ;gBACR,WAAW;gBACX,iBAAiB;gBACjB,MAAM;gBACN,MAAM;gBACN,uBAAuB;gBACvB,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5C,GAAG;aACJ;YACD,GAAG,EAAE,MAAM;YACX,KAAK,EAAE;gBACL,6BAA6B,GAAG,CAAC,YAAY,oCAAoC;gBACjF,0BAA0B,GAAG,CAAC,QAAQ,6GAA6G;gBACnJ,EAAE;gBACF,GAAG,CAAC,WAAW;gBACf,EAAE;aACH,CAAC,IAAI,CAAC,IAAI,CAAC;YACZ,GAAG,EAAE,EAAE,aAAa,EAAE,GAAG,EAAE;SAC5B,CAAC;IACJ,CAAC;IAED,SAAS,EAAE,cAAc;CAC1B,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
/** Runs a short command and collects its output. Never through a shell. */
|
|
3
|
+
export function runCommand(executable, args, timeoutMs = 10_000) {
|
|
4
|
+
return new Promise(resolve => {
|
|
5
|
+
let settled = false;
|
|
6
|
+
let stdout = '';
|
|
7
|
+
let stderr = '';
|
|
8
|
+
const child = spawn(executable.command, [...executable.prefixArgs, ...args], {
|
|
9
|
+
windowsHide: true,
|
|
10
|
+
stdio: ['ignore', 'pipe', 'pipe']
|
|
11
|
+
});
|
|
12
|
+
const timer = setTimeout(() => {
|
|
13
|
+
if (settled)
|
|
14
|
+
return;
|
|
15
|
+
settled = true;
|
|
16
|
+
child.kill();
|
|
17
|
+
resolve({ ok: false, stdout, stderr: `${stderr}\n(timed out)`.trim(), code: null });
|
|
18
|
+
}, timeoutMs);
|
|
19
|
+
child.stdout.on('data', chunk => (stdout += String(chunk)));
|
|
20
|
+
child.stderr.on('data', chunk => (stderr += String(chunk)));
|
|
21
|
+
child.on('error', error => {
|
|
22
|
+
if (settled)
|
|
23
|
+
return;
|
|
24
|
+
settled = true;
|
|
25
|
+
clearTimeout(timer);
|
|
26
|
+
resolve({ ok: false, stdout, stderr: error.message, code: null });
|
|
27
|
+
});
|
|
28
|
+
child.on('close', code => {
|
|
29
|
+
if (settled)
|
|
30
|
+
return;
|
|
31
|
+
settled = true;
|
|
32
|
+
clearTimeout(timer);
|
|
33
|
+
resolve({ ok: code === 0, stdout, stderr, code });
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export function record(value) {
|
|
38
|
+
return value && typeof value === 'object' && !Array.isArray(value)
|
|
39
|
+
? value
|
|
40
|
+
: {};
|
|
41
|
+
}
|
|
42
|
+
export function count(value) {
|
|
43
|
+
return typeof value === 'number' && Number.isFinite(value) && value >= 0
|
|
44
|
+
? Math.round(value)
|
|
45
|
+
: null;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/agents/command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAK3C,2EAA2E;AAC3E,MAAM,UAAU,UAAU,CACxB,UAAsB,EACtB,IAAc,EACd,SAAS,GAAG,MAAM;IAElB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,EAAE;YAC3E,WAAW,EAAE,IAAI;YACjB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC;SAClC,CAAC,CAAC;QACH,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,KAAK,CAAC,IAAI,EAAE,CAAC;YACb,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACtF,CAAC,EAAE,SAAS,CAAC,CAAC;QACd,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5D,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC5D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;YACxB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE;YACvB,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAc;IACnC,OAAO,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAChE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,KAAc;IAClC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;QACtE,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;QACnB,CAAC,CAAC,IAAI,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import os from 'node:os';
|
|
2
|
+
import { hostPlatform } from '../launch/platform.js';
|
|
3
|
+
import { claudeCode } from './claude.js';
|
|
4
|
+
import { codex } from './codex.js';
|
|
5
|
+
/** The terminal agents this version ships. Editor agents and more CLIs come with S2. */
|
|
6
|
+
export const ADAPTERS = [claudeCode, codex];
|
|
7
|
+
export function adapterFor(id) {
|
|
8
|
+
const adapter = ADAPTERS.find(item => item.id === id);
|
|
9
|
+
if (!adapter)
|
|
10
|
+
throw new Error(`${id} is not supported in this version of the studio.`);
|
|
11
|
+
return adapter;
|
|
12
|
+
}
|
|
13
|
+
/** Where to look for agents on this machine. */
|
|
14
|
+
export function hostLookup(env) {
|
|
15
|
+
return { env, platform: hostPlatform(), home: os.homedir(), node: process.execPath };
|
|
16
|
+
}
|
|
17
|
+
/** What each agent is on this machine: found or not, its version, sign-in, and headless rule. */
|
|
18
|
+
export async function detectAgents(lookup) {
|
|
19
|
+
return Promise.all(ADAPTERS.map(adapter => adapter.detect(lookup)));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAGrD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGnC,wFAAwF;AACxF,MAAM,CAAC,MAAM,QAAQ,GAAsB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAE/D,MAAM,UAAU,UAAU,CAAC,EAAY;IACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACtD,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,GAAG,EAAE,kDAAkD,CAAC,CAAC;IACvF,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,gDAAgD;AAChD,MAAM,UAAU,UAAU,CAAC,GAAsB;IAC/C,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,OAAO,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC;AACvF,CAAC;AAED,iGAAiG;AACjG,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc;IAC/C,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { createInterface } from 'node:readline';
|
|
3
|
+
/**
|
|
4
|
+
* Runs an agent unattended: never through a shell, every argument separate. Each line of its
|
|
5
|
+
* output is parsed by the adapter into events for the local UI and, at the end, token counts.
|
|
6
|
+
* Aborting stops the process, and then kills it if it lingers.
|
|
7
|
+
*/
|
|
8
|
+
export function runHeadless(adapter, invocation, options) {
|
|
9
|
+
return new Promise(resolve => {
|
|
10
|
+
let settled = false;
|
|
11
|
+
let usage = null;
|
|
12
|
+
let reportedFailure = null;
|
|
13
|
+
const finish = (result) => {
|
|
14
|
+
if (settled)
|
|
15
|
+
return;
|
|
16
|
+
settled = true;
|
|
17
|
+
resolve(result);
|
|
18
|
+
};
|
|
19
|
+
const child = spawn(invocation.command, invocation.args, {
|
|
20
|
+
cwd: invocation.cwd,
|
|
21
|
+
env: { ...options.env, ...invocation.env },
|
|
22
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
23
|
+
windowsHide: true
|
|
24
|
+
});
|
|
25
|
+
const abort = () => {
|
|
26
|
+
child.kill('SIGTERM');
|
|
27
|
+
setTimeout(() => {
|
|
28
|
+
if (child.exitCode === null)
|
|
29
|
+
child.kill('SIGKILL');
|
|
30
|
+
}, 5000).unref();
|
|
31
|
+
};
|
|
32
|
+
options.signal?.addEventListener('abort', abort, { once: true });
|
|
33
|
+
child.on('error', error => finish({
|
|
34
|
+
ok: false,
|
|
35
|
+
exitCode: null,
|
|
36
|
+
cancelled: false,
|
|
37
|
+
error: `${adapter.name} could not be started: ${error.message}`,
|
|
38
|
+
usage
|
|
39
|
+
}));
|
|
40
|
+
createInterface({ input: child.stdout }).on('line', line => {
|
|
41
|
+
options.onOutput?.(line);
|
|
42
|
+
const parsed = adapter.parseLine(line);
|
|
43
|
+
if (parsed.usage) {
|
|
44
|
+
usage = { ...parsed.usage, model: parsed.usage.model || options.model || adapter.id };
|
|
45
|
+
}
|
|
46
|
+
if (parsed.event) {
|
|
47
|
+
if (parsed.event.kind === 'result' && !parsed.event.ok) {
|
|
48
|
+
reportedFailure = parsed.event.text ?? `${adapter.name} reported a failure.`;
|
|
49
|
+
}
|
|
50
|
+
options.onEvent?.(parsed.event);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
child.stderr.on('data', () => { });
|
|
54
|
+
child.on('close', code => {
|
|
55
|
+
options.signal?.removeEventListener('abort', abort);
|
|
56
|
+
const cancelled = options.signal?.aborted ?? false;
|
|
57
|
+
const ok = !cancelled && code === 0 && !reportedFailure;
|
|
58
|
+
finish({
|
|
59
|
+
ok,
|
|
60
|
+
exitCode: code,
|
|
61
|
+
cancelled,
|
|
62
|
+
error: ok
|
|
63
|
+
? null
|
|
64
|
+
: cancelled
|
|
65
|
+
? 'Cancelled.'
|
|
66
|
+
: (reportedFailure ?? `${adapter.name} exited with code ${code}.`),
|
|
67
|
+
usage
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
child.stdin.on('error', () => { });
|
|
71
|
+
if (invocation.stdin !== null)
|
|
72
|
+
child.stdin.write(invocation.stdin);
|
|
73
|
+
child.stdin.end();
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=process.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/agents/process.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { sessionTitle } from '../launch/terminal.js';
|
|
2
|
+
import { handoffLine } from '../runs/slots.js';
|
|
3
|
+
/** A run as an adapter sees it. The run id doubles as the agent's session id, so it can resume. */
|
|
4
|
+
export function runTarget(repoRoot, run, model) {
|
|
5
|
+
return {
|
|
6
|
+
repoRoot,
|
|
7
|
+
targetFolder: run.targetFolder,
|
|
8
|
+
promptFile: run.promptFile,
|
|
9
|
+
instruction: handoffLine(run.promptFile),
|
|
10
|
+
sessionId: run.runId,
|
|
11
|
+
model,
|
|
12
|
+
title: sessionTitle(`${run.component} ${run.iteration}`)
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** One terminal session per run, each started with its one-line instruction. */
|
|
16
|
+
export function terminalSessions(adapter, executable, repoRoot, runs, model) {
|
|
17
|
+
return runs.map(run => {
|
|
18
|
+
const target = runTarget(repoRoot, run, model);
|
|
19
|
+
return {
|
|
20
|
+
title: target.title,
|
|
21
|
+
command: executable.command,
|
|
22
|
+
args: [...executable.prefixArgs, ...adapter.interactiveArgs(target)]
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/agents/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAErD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAI/C,mGAAmG;AACnG,MAAM,UAAU,SAAS,CAAC,QAAgB,EAAE,GAAc,EAAE,KAAoB;IAC9E,OAAO;QACL,QAAQ;QACR,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,WAAW,EAAE,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC;QACxC,SAAS,EAAE,GAAG,CAAC,KAAK;QACpB,KAAK;QACL,KAAK,EAAE,YAAY,CAAC,GAAG,GAAG,CAAC,SAAS,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,gBAAgB,CAC9B,OAAwB,EACxB,UAAsB,EACtB,QAAgB,EAChB,IAAiB,EACjB,KAAoB;IAEpB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE;QACpB,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;QAC/C,OAAO;YACL,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,OAAO,EAAE,UAAU,CAAC,OAAO;YAC3B,IAAI,EAAE,CAAC,GAAG,UAAU,CAAC,UAAU,EAAE,GAAG,OAAO,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;SACrE,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { ApiError, OfflineError } from './errors.js';
|
|
2
|
+
/** Where the backend serves the studio's routes. */
|
|
3
|
+
export const STUDIO_BASE = '/v1/api/studio';
|
|
4
|
+
/** The typed client for `/studio`. Every route the studio calls goes through `request`. */
|
|
5
|
+
export class StudioApi {
|
|
6
|
+
config;
|
|
7
|
+
constructor(config) {
|
|
8
|
+
this.config = config;
|
|
9
|
+
}
|
|
10
|
+
get server() {
|
|
11
|
+
return this.config.server;
|
|
12
|
+
}
|
|
13
|
+
get signedIn() {
|
|
14
|
+
return this.config.token !== null;
|
|
15
|
+
}
|
|
16
|
+
/** The same server, without the token: for signing in. */
|
|
17
|
+
signedOut() {
|
|
18
|
+
return new StudioApi({ ...this.config, token: null });
|
|
19
|
+
}
|
|
20
|
+
/** The same server with a newly issued token. */
|
|
21
|
+
withToken(token) {
|
|
22
|
+
return new StudioApi({ ...this.config, token });
|
|
23
|
+
}
|
|
24
|
+
startDeviceLogin(body) {
|
|
25
|
+
return this.request('POST', '/auth/device', body);
|
|
26
|
+
}
|
|
27
|
+
pollDeviceLogin(deviceCode) {
|
|
28
|
+
return this.request('POST', '/auth/token', { deviceCode });
|
|
29
|
+
}
|
|
30
|
+
me() {
|
|
31
|
+
return this.request('GET', '/me');
|
|
32
|
+
}
|
|
33
|
+
logout() {
|
|
34
|
+
return this.request('POST', '/auth/logout', {});
|
|
35
|
+
}
|
|
36
|
+
projects() {
|
|
37
|
+
return this.request('GET', '/projects');
|
|
38
|
+
}
|
|
39
|
+
createProject(orgId, name) {
|
|
40
|
+
return this.request('POST', `/orgs/${encodeURIComponent(orgId)}/projects`, { name });
|
|
41
|
+
}
|
|
42
|
+
/** Allocates the iterations and compiles their prompts for this repo. */
|
|
43
|
+
startRuns(orgId, project, request) {
|
|
44
|
+
return this.request('POST', `${projectPath(orgId, project)}/runs`, request);
|
|
45
|
+
}
|
|
46
|
+
/** The project with its brief and the server's records of its iterations. */
|
|
47
|
+
project(orgId, project) {
|
|
48
|
+
return this.request('GET', projectPath(orgId, project));
|
|
49
|
+
}
|
|
50
|
+
/** Renders the promote prompt; the assets are the server file names the iteration uses. */
|
|
51
|
+
promote(orgId, project, body) {
|
|
52
|
+
return this.request('POST', `${projectPath(orgId, project)}/promotions`, body);
|
|
53
|
+
}
|
|
54
|
+
/** A local iteration's reviews, oldest first. */
|
|
55
|
+
reviews(orgId, project, page, component, iteration) {
|
|
56
|
+
return this.request('GET', `${iterationPath(orgId, project, page, component, iteration)}/reviews`);
|
|
57
|
+
}
|
|
58
|
+
/** The component's web sketches that can be pulled, newest first. */
|
|
59
|
+
sketches(orgId, project, page, component) {
|
|
60
|
+
return this.request('GET', `${componentPath(orgId, project, page, component)}/sketches`);
|
|
61
|
+
}
|
|
62
|
+
/** Allocates the next local iteration as a fork of the sketch, with the sketch's files. */
|
|
63
|
+
pullSketch(orgId, project, page, component, sketch) {
|
|
64
|
+
return this.request('POST', `${componentPath(orgId, project, page, component)}/sketches/${encodeURIComponent(sketch)}/pull`, {});
|
|
65
|
+
}
|
|
66
|
+
heartbeat(body) {
|
|
67
|
+
return this.request('POST', '/heartbeat', body);
|
|
68
|
+
}
|
|
69
|
+
/** An asset file's bytes, to copy into the repo when promoting. */
|
|
70
|
+
async file(orgId, project, scope, file) {
|
|
71
|
+
const response = await this.send('GET', `${projectPath(orgId, project)}/files/${scope}/${encodeURIComponent(file)}`, undefined, {}, '*/*');
|
|
72
|
+
if (response.ok)
|
|
73
|
+
return Buffer.from(await response.arrayBuffer());
|
|
74
|
+
throw await readError(response);
|
|
75
|
+
}
|
|
76
|
+
link(orgId, body) {
|
|
77
|
+
return this.request('POST', `/orgs/${encodeURIComponent(orgId)}/links`, body);
|
|
78
|
+
}
|
|
79
|
+
async request(method, path, body, options = {}) {
|
|
80
|
+
const response = await this.send(method, path, body, options);
|
|
81
|
+
const envelope = await readEnvelope(response);
|
|
82
|
+
if (envelope.success && response.ok)
|
|
83
|
+
return envelope.data;
|
|
84
|
+
throw toApiError(response.status, envelope);
|
|
85
|
+
}
|
|
86
|
+
async send(method, path, body, options, accept = 'application/json') {
|
|
87
|
+
const headers = {
|
|
88
|
+
accept,
|
|
89
|
+
'user-agent': this.config.userAgent
|
|
90
|
+
};
|
|
91
|
+
if (body !== undefined)
|
|
92
|
+
headers['content-type'] = 'application/json';
|
|
93
|
+
if (this.config.token)
|
|
94
|
+
headers.authorization = `Bearer ${this.config.token}`;
|
|
95
|
+
if (options.idempotencyKey)
|
|
96
|
+
headers['idempotency-key'] = options.idempotencyKey;
|
|
97
|
+
try {
|
|
98
|
+
return await (this.config.fetch ?? fetch)(`${this.config.server}${STUDIO_BASE}${path}`, {
|
|
99
|
+
method,
|
|
100
|
+
headers,
|
|
101
|
+
body: body === undefined ? undefined : JSON.stringify(body),
|
|
102
|
+
signal: AbortSignal.timeout(this.config.timeoutMs ?? 30_000)
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
throw new OfflineError(this.config.server, error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
function projectPath(orgId, project) {
|
|
111
|
+
return `/orgs/${encodeURIComponent(orgId)}/projects/${encodeURIComponent(project)}`;
|
|
112
|
+
}
|
|
113
|
+
function componentPath(orgId, project, page, component) {
|
|
114
|
+
return `${projectPath(orgId, project)}/pages/${encodeURIComponent(page)}/components/${encodeURIComponent(component)}`;
|
|
115
|
+
}
|
|
116
|
+
/** The path of one iteration's review routes. */
|
|
117
|
+
export function iterationPath(orgId, project, page, component, iteration) {
|
|
118
|
+
return `${componentPath(orgId, project, page, component)}/iterations/${encodeURIComponent(iteration)}`;
|
|
119
|
+
}
|
|
120
|
+
async function readEnvelope(response) {
|
|
121
|
+
const envelope = (await response.json().catch(() => null));
|
|
122
|
+
if (!envelope || typeof envelope !== 'object' || typeof envelope.success !== 'boolean') {
|
|
123
|
+
throw new ApiError(response.ok ? 'BAD_RESPONSE' : `HTTP_${response.status}`, response.status, `The server answered ${response.status} with something the studio cannot read.`);
|
|
124
|
+
}
|
|
125
|
+
return envelope;
|
|
126
|
+
}
|
|
127
|
+
async function readError(response) {
|
|
128
|
+
return toApiError(response.status, await readEnvelope(response));
|
|
129
|
+
}
|
|
130
|
+
function toApiError(status, envelope) {
|
|
131
|
+
const message = typeof envelope.message === 'string' ? envelope.message : undefined;
|
|
132
|
+
if (Array.isArray(envelope.error)) {
|
|
133
|
+
return new ApiError('INVALID_REQUEST', status, message, envelope.error);
|
|
134
|
+
}
|
|
135
|
+
const code = typeof envelope.error === 'string' ? envelope.error : `HTTP_${status}`;
|
|
136
|
+
return new ApiError(code, status, message);
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/api/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** The backend answered and refused: a code such as `RUN_NOT_FOUND`, and a message when it has one. */
|
|
2
|
+
export class ApiError extends Error {
|
|
3
|
+
code;
|
|
4
|
+
status;
|
|
5
|
+
/** Field errors from the backend's validation, when the request was malformed. */
|
|
6
|
+
issues;
|
|
7
|
+
constructor(code, status, message, issues = null) {
|
|
8
|
+
super(message || code);
|
|
9
|
+
this.name = 'ApiError';
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.status = status;
|
|
12
|
+
this.issues = issues;
|
|
13
|
+
}
|
|
14
|
+
/** Worth sending again later: the server failed or asked us to slow down. */
|
|
15
|
+
get retryable() {
|
|
16
|
+
return this.status >= 500 || this.status === 429 || this.status === 408;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/** The backend could not be reached at all: no network, a timeout, or nothing listening. */
|
|
20
|
+
export class OfflineError extends Error {
|
|
21
|
+
server;
|
|
22
|
+
constructor(server, cause) {
|
|
23
|
+
super(`Could not reach ${server}.`, { cause });
|
|
24
|
+
this.name = 'OfflineError';
|
|
25
|
+
this.server = server;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** One line for the terminal or the local UI, never a stack. */
|
|
29
|
+
export function describeError(error) {
|
|
30
|
+
if (error instanceof OfflineError) {
|
|
31
|
+
return `${error.message} Check your connection, or set ROUGHBOOK_SERVER.`;
|
|
32
|
+
}
|
|
33
|
+
if (error instanceof ApiError) {
|
|
34
|
+
if (error.code === 'INVALID_REQUEST')
|
|
35
|
+
return 'The server did not accept that request.';
|
|
36
|
+
return error.message;
|
|
37
|
+
}
|
|
38
|
+
return error instanceof Error ? error.message : String(error);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/api/errors.ts"],"names":[],"mappings":"AAAA,uGAAuG;AACvG,MAAM,OAAO,QAAS,SAAQ,KAAK;IACxB,IAAI,CAAS;IACb,MAAM,CAAS;IACxB,kFAAkF;IACzE,MAAM,CAAmB;IAElC,YAAY,IAAY,EAAE,MAAc,EAAE,OAAgB,EAAE,SAA2B,IAAI;QACzF,KAAK,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,6EAA6E;IAC7E,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,GAAG,CAAC;IAC1E,CAAC;CACF;AAED,4FAA4F;AAC5F,MAAM,OAAO,YAAa,SAAQ,KAAK;IAC5B,MAAM,CAAS;IAExB,YAAY,MAAc,EAAE,KAAe;QACzC,KAAK,CAAC,mBAAmB,MAAM,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;QAC3B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAED,gEAAgE;AAChE,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,YAAY,YAAY,EAAE,CAAC;QAClC,OAAO,GAAG,KAAK,CAAC,OAAO,kDAAkD,CAAC;IAC5E,CAAC;IACD,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB;YAAE,OAAO,yCAAyC,CAAC;QACvF,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|