@openagt/agent-runner 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/bin/agent-runner +11 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +208 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +62 -0
- package/dist/config.js.map +1 -0
- package/dist/ended.d.ts +66 -0
- package/dist/ended.d.ts.map +1 -0
- package/dist/ended.js +114 -0
- package/dist/ended.js.map +1 -0
- package/dist/git-host.d.ts +31 -0
- package/dist/git-host.d.ts.map +1 -0
- package/dist/git-host.js +26 -0
- package/dist/git-host.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/init.d.ts +39 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +104 -0
- package/dist/init.js.map +1 -0
- package/dist/live-card.d.ts +27 -0
- package/dist/live-card.d.ts.map +1 -0
- package/dist/live-card.js +56 -0
- package/dist/live-card.js.map +1 -0
- package/dist/names.d.ts +12 -0
- package/dist/names.d.ts.map +1 -0
- package/dist/names.js +12 -0
- package/dist/names.js.map +1 -0
- package/dist/parent.d.ts +47 -0
- package/dist/parent.d.ts.map +1 -0
- package/dist/parent.js +52 -0
- package/dist/parent.js.map +1 -0
- package/dist/records.d.ts +81 -0
- package/dist/records.d.ts.map +1 -0
- package/dist/records.js +89 -0
- package/dist/records.js.map +1 -0
- package/dist/run-lock.d.ts +29 -0
- package/dist/run-lock.d.ts.map +1 -0
- package/dist/run-lock.js +80 -0
- package/dist/run-lock.js.map +1 -0
- package/dist/run.d.ts +169 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/run.js +462 -0
- package/dist/run.js.map +1 -0
- package/dist/runner.d.ts +148 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +208 -0
- package/dist/runner.js.map +1 -0
- package/dist/sweep.d.ts +46 -0
- package/dist/sweep.d.ts.map +1 -0
- package/dist/sweep.js +83 -0
- package/dist/sweep.js.map +1 -0
- package/dist/test-repo.d.ts +18 -0
- package/dist/test-repo.d.ts.map +1 -0
- package/dist/test-repo.js +49 -0
- package/dist/test-repo.js.map +1 -0
- package/package.json +54 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Suleiman Shahbari
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/bin/agent-runner
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { runCli } from '../dist/cli.js'
|
|
3
|
+
|
|
4
|
+
runCli(process.argv.slice(2), { cwd: process.cwd(), stdout: line => console.log(line), stderr: line => console.error(line) })
|
|
5
|
+
.then(code => {
|
|
6
|
+
process.exitCode = code
|
|
7
|
+
})
|
|
8
|
+
.catch(err => {
|
|
9
|
+
console.error(err)
|
|
10
|
+
process.exitCode = 1
|
|
11
|
+
})
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type GitRunner } from '@openagt/agent-data';
|
|
2
|
+
/**
|
|
3
|
+
* The command line: JSON on stdout, one line for a person on stderr, and the exit code says how
|
|
4
|
+
* it went — 0 for a result, 1 for a refusal or a failure, 2 for a command that could not be read.
|
|
5
|
+
* The same contract as the skills' commands, so a person and a dashboard read it the same way.
|
|
6
|
+
*/
|
|
7
|
+
export declare const USAGE = "usage: agent-runner <command>\n\n run <prompt> [--model <id>] [--driver <claude-code|codex>] [--then <prompt>] [--publish <commit|branch|pr|merge>] [--parent <id>] [--base <ref>]\n one run of <prompt> in its own checkout, now, recorded; on Claude Code unless --driver says Codex,\n on the coding agent's own default model unless --model names one;\n with --then, once it ends done with a pull request, a fresh agent on its branch gets that prompt and the run's id, and the merge waits for it;\n with --publish, the agent is told, in one sentence after the prompt, how far to take its work when it finishes: commit it, and from there push its branch,\n open its pull request, or set the request to merge once its checks pass; without it the prompt goes as written, and nothing is committed or published unless the prompt asks;\n with --parent, the run <id> is told when this one ends: which run, how it ended, its last words, as its next prompt;\n with --base, the run's branch starts from <ref> instead of origin's default branch\n run --detach <prompt> the same run in its own process, answered at once with its id: what a dashboard's start hook runs\n run --resume <id> [<text>] [--answer <label>]\n continue an ended run: the same record, its session resumed; the text as the next prompt, or the answer to the question it ended on\n run --detach --resume <id> \u2026 the same continuing in its own process, answered at once: what a dashboard's resume hook runs\n check [--driver <claude-code|codex>]\n whether a run can start here: the coding agent's CLI installed and logged in, and its warnings; what a dashboard's check hook runs\n init this tool's lines in the dashboard's .the-framework/hooks.yml, so its Start works; a line already there is kept\n\nWhen a run ends waiting on a question, or ends done with a pull request it did not have, the `ended:` line in the\nproject's .agent-runner/config.yml runs, if there is one, in the project's root, with MESSAGE (one line for a person),\nRUN_ID, STATUS, QUESTION and PR_URL in its environment. The file is this machine's: keep it out of git (this tool hides\n.agent-runner/ from git once a run has started here). A run's coding agent loads the person's own setup, as when\nstarted by hand; in the same file, each part is left out with its own line under `personal:`, so a run does the same\njob on every machine:\n personal:\n memory: off Claude Code's auto-memory; Codex's memories\n connectors: off your claude.ai connectors; Codex's apps and plugins\n skills: off Claude Code: your user settings (effort, model, hooks, a login through apiKeyHelper or env), the skills\n synced from your claude.ai account, ~/.claude/CLAUDE.md, ~/.claude/skills.\n Codex: ~/.codex/AGENTS.md, ~/.codex/skills, ~/.codex/config.toml (with a model provider or\n login set there) and its memories, so Codex's memory stays on only with skills on too (`check` warns).\n Codex loads skills in ~/.agents/skills either way; with skills off, `check --driver codex` warns about them.\n\nJSON on stdout. Exit code 1 for a refusal or a failure (the reason on stderr), 2 for a usage error.";
|
|
8
|
+
export interface CliIo {
|
|
9
|
+
cwd: string;
|
|
10
|
+
stdout: (line: string) => void;
|
|
11
|
+
stderr: (line: string) => void;
|
|
12
|
+
}
|
|
13
|
+
export type CliRefusal = {
|
|
14
|
+
ok: false;
|
|
15
|
+
reason: string;
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
};
|
|
18
|
+
export declare function runCli(argv: string[], io: CliIo, git?: GitRunner): Promise<number>;
|
|
19
|
+
//# sourceMappingURL=cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAOnE;;;;GAIG;AAEH,eAAO,MAAM,KAAK,09GAiCkF,CAAA;AAEpG,MAAM,WAAW,KAAK;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAC/B;AAED,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CAAE,CAAA;AAU9E,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,GAAE,SAA2B,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BzG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { parseArgs } from 'node:util';
|
|
2
|
+
import { nodeGitRunner } from '@openagt/agent-data';
|
|
3
|
+
import { projectRoot } from '@openagt/skill-branches';
|
|
4
|
+
import { findRun } from '@openagt/skill-logs';
|
|
5
|
+
import { DRIVER_NAMES, detachResume, detachRun, isDriverName, readyToRun, resumeProject, runProject } from './runner.js';
|
|
6
|
+
import { initHooks } from './init.js';
|
|
7
|
+
import { isPublish, PUBLISH_LEVELS } from './records.js';
|
|
8
|
+
/**
|
|
9
|
+
* The command line: JSON on stdout, one line for a person on stderr, and the exit code says how
|
|
10
|
+
* it went — 0 for a result, 1 for a refusal or a failure, 2 for a command that could not be read.
|
|
11
|
+
* The same contract as the skills' commands, so a person and a dashboard read it the same way.
|
|
12
|
+
*/
|
|
13
|
+
export const USAGE = `usage: agent-runner <command>
|
|
14
|
+
|
|
15
|
+
run <prompt> [--model <id>] [--driver <claude-code|codex>] [--then <prompt>] [--publish <commit|branch|pr|merge>] [--parent <id>] [--base <ref>]
|
|
16
|
+
one run of <prompt> in its own checkout, now, recorded; on Claude Code unless --driver says Codex,
|
|
17
|
+
on the coding agent's own default model unless --model names one;
|
|
18
|
+
with --then, once it ends done with a pull request, a fresh agent on its branch gets that prompt and the run's id, and the merge waits for it;
|
|
19
|
+
with --publish, the agent is told, in one sentence after the prompt, how far to take its work when it finishes: commit it, and from there push its branch,
|
|
20
|
+
open its pull request, or set the request to merge once its checks pass; without it the prompt goes as written, and nothing is committed or published unless the prompt asks;
|
|
21
|
+
with --parent, the run <id> is told when this one ends: which run, how it ended, its last words, as its next prompt;
|
|
22
|
+
with --base, the run's branch starts from <ref> instead of origin's default branch
|
|
23
|
+
run --detach <prompt> the same run in its own process, answered at once with its id: what a dashboard's start hook runs
|
|
24
|
+
run --resume <id> [<text>] [--answer <label>]
|
|
25
|
+
continue an ended run: the same record, its session resumed; the text as the next prompt, or the answer to the question it ended on
|
|
26
|
+
run --detach --resume <id> … the same continuing in its own process, answered at once: what a dashboard's resume hook runs
|
|
27
|
+
check [--driver <claude-code|codex>]
|
|
28
|
+
whether a run can start here: the coding agent's CLI installed and logged in, and its warnings; what a dashboard's check hook runs
|
|
29
|
+
init this tool's lines in the dashboard's .the-framework/hooks.yml, so its Start works; a line already there is kept
|
|
30
|
+
|
|
31
|
+
When a run ends waiting on a question, or ends done with a pull request it did not have, the \`ended:\` line in the
|
|
32
|
+
project's .agent-runner/config.yml runs, if there is one, in the project's root, with MESSAGE (one line for a person),
|
|
33
|
+
RUN_ID, STATUS, QUESTION and PR_URL in its environment. The file is this machine's: keep it out of git (this tool hides
|
|
34
|
+
.agent-runner/ from git once a run has started here). A run's coding agent loads the person's own setup, as when
|
|
35
|
+
started by hand; in the same file, each part is left out with its own line under \`personal:\`, so a run does the same
|
|
36
|
+
job on every machine:
|
|
37
|
+
personal:
|
|
38
|
+
memory: off Claude Code's auto-memory; Codex's memories
|
|
39
|
+
connectors: off your claude.ai connectors; Codex's apps and plugins
|
|
40
|
+
skills: off Claude Code: your user settings (effort, model, hooks, a login through apiKeyHelper or env), the skills
|
|
41
|
+
synced from your claude.ai account, ~/.claude/CLAUDE.md, ~/.claude/skills.
|
|
42
|
+
Codex: ~/.codex/AGENTS.md, ~/.codex/skills, ~/.codex/config.toml (with a model provider or
|
|
43
|
+
login set there) and its memories, so Codex's memory stays on only with skills on too (\`check\` warns).
|
|
44
|
+
Codex loads skills in ~/.agents/skills either way; with skills off, \`check --driver codex\` warns about them.
|
|
45
|
+
|
|
46
|
+
JSON on stdout. Exit code 1 for a refusal or a failure (the reason on stderr), 2 for a usage error.`;
|
|
47
|
+
class Refused extends Error {
|
|
48
|
+
outcome;
|
|
49
|
+
line;
|
|
50
|
+
constructor(outcome, line) {
|
|
51
|
+
super(line);
|
|
52
|
+
this.outcome = outcome;
|
|
53
|
+
this.line = line;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
class Usage extends Error {
|
|
57
|
+
}
|
|
58
|
+
export async function runCli(argv, io, git = nodeGitRunner()) {
|
|
59
|
+
const [command, ...rest] = argv;
|
|
60
|
+
const run = command && Object.hasOwn(COMMANDS, command) ? COMMANDS[command] : undefined;
|
|
61
|
+
if (!run) {
|
|
62
|
+
io.stderr(USAGE);
|
|
63
|
+
return 2;
|
|
64
|
+
}
|
|
65
|
+
try {
|
|
66
|
+
const result = await run(rest, io, git);
|
|
67
|
+
io.stdout(JSON.stringify(result));
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
catch (err) {
|
|
71
|
+
if (err instanceof Usage) {
|
|
72
|
+
io.stderr(`${err.message}\n\n${USAGE}`);
|
|
73
|
+
return 2;
|
|
74
|
+
}
|
|
75
|
+
if (err instanceof Refused) {
|
|
76
|
+
io.stdout(JSON.stringify(err.outcome));
|
|
77
|
+
io.stderr(err.line);
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
81
|
+
io.stdout(JSON.stringify({ ok: false, reason: 'failed', detail }));
|
|
82
|
+
io.stderr(detail);
|
|
83
|
+
return 1;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
const COMMANDS = {
|
|
87
|
+
async run(args, io, git) {
|
|
88
|
+
const { positionals, values } = parse(args, { id: { type: 'string' }, model: { type: 'string' }, resume: { type: 'string' }, answer: { type: 'string' }, detach: { type: 'boolean' }, mark: { type: 'boolean' }, driver: { type: 'string' }, then: { type: 'string' }, publish: { type: 'string' }, parent: { type: 'string' }, base: { type: 'string' } }, 0, 1);
|
|
89
|
+
const repo = await project(io.cwd, git);
|
|
90
|
+
const driver = values.driver;
|
|
91
|
+
if (driver !== undefined && !isDriverName(driver))
|
|
92
|
+
throw new Usage(`unknown driver "${driver}"; the drivers are ${DRIVER_NAMES.join(' and ')}`);
|
|
93
|
+
const publish = values.publish;
|
|
94
|
+
if (publish !== undefined && !isPublish(publish))
|
|
95
|
+
throw new Usage(`unknown publish level "${publish}"; the levels are ${PUBLISH_LEVELS.join(', ')}`);
|
|
96
|
+
if (values.resume !== undefined) {
|
|
97
|
+
if (driver !== undefined)
|
|
98
|
+
throw new Usage('--resume takes no --driver: a run continues on the coding agent its record names');
|
|
99
|
+
if (values.id !== undefined)
|
|
100
|
+
throw new Usage('--resume takes no --id: a run continues under its own');
|
|
101
|
+
if (values.then !== undefined)
|
|
102
|
+
throw new Usage('--resume takes no --then: a run continues with the follow-up its record names');
|
|
103
|
+
if (publish !== undefined)
|
|
104
|
+
throw new Usage('--resume takes no --publish: a run continues at the publish level its record names');
|
|
105
|
+
if (values.parent !== undefined)
|
|
106
|
+
throw new Usage('--resume takes no --parent: a run continues for the parent its record names');
|
|
107
|
+
if (values.base !== undefined)
|
|
108
|
+
throw new Usage('--resume takes no --base: a run continues on its own branch');
|
|
109
|
+
if (positionals[0] === undefined && values.answer === undefined)
|
|
110
|
+
throw new Usage('a text or --answer is needed to resume a run');
|
|
111
|
+
}
|
|
112
|
+
if (values.then !== undefined && !values.then.trim())
|
|
113
|
+
throw new Usage('--then needs a prompt');
|
|
114
|
+
// A parent this project has no record of is refused while someone is still listening; a run
|
|
115
|
+
// spawned with its id was asked about already.
|
|
116
|
+
if (values.parent !== undefined && values.id === undefined && !(await findRun(repo, values.parent))) {
|
|
117
|
+
throw new Refused({ ok: false, reason: 'no-parent', parent: values.parent }, `no run ${values.parent} in this project`);
|
|
118
|
+
}
|
|
119
|
+
// A person's run is refused before it spends a checkout when its coding agent cannot start;
|
|
120
|
+
// a scheduler asks the same before it marks, and a resumed run's agent already ran once here.
|
|
121
|
+
if (values.resume === undefined && values.id === undefined) {
|
|
122
|
+
const ready = await readyToRun(repo, driver ?? 'claude-code');
|
|
123
|
+
if (ready.problems.length > 0)
|
|
124
|
+
throw new Refused({ ok: false, reason: 'not-ready', ...ready }, ready.problems.join(' '));
|
|
125
|
+
}
|
|
126
|
+
const named = { ...(values.then !== undefined ? { then: values.then.trim() } : {}), ...(publish !== undefined ? { publish } : {}), ...(values.parent !== undefined ? { parent: values.parent } : {}), ...(values.base !== undefined ? { base: values.base } : {}) };
|
|
127
|
+
if (values.detach && values.resume !== undefined) {
|
|
128
|
+
const resumed = await detachResume(repo, {
|
|
129
|
+
id: values.resume,
|
|
130
|
+
...(positionals[0] !== undefined ? { text: positionals[0] } : {}),
|
|
131
|
+
...(values.answer !== undefined ? { answer: values.answer } : {}),
|
|
132
|
+
...(values.model !== undefined ? { model: values.model } : {}),
|
|
133
|
+
});
|
|
134
|
+
return { ok: true, detached: true, ...resumed };
|
|
135
|
+
}
|
|
136
|
+
if (values.detach) {
|
|
137
|
+
if (positionals[0] === undefined)
|
|
138
|
+
throw new Usage('expected 1 argument(s), got 0');
|
|
139
|
+
if (values.id !== undefined)
|
|
140
|
+
throw new Usage('--detach takes no --id: the run\'s id is minted and answered');
|
|
141
|
+
const started = await detachRun(repo, { prompt: positionals[0], ...(values.model !== undefined ? { model: values.model } : {}), ...(driver !== undefined ? { driver } : {}), ...named });
|
|
142
|
+
return { ok: true, detached: true, ...started };
|
|
143
|
+
}
|
|
144
|
+
if (values.resume !== undefined) {
|
|
145
|
+
const outcome = await resumeProject(repo, {
|
|
146
|
+
id: values.resume,
|
|
147
|
+
...(positionals[0] !== undefined ? { text: positionals[0] } : {}),
|
|
148
|
+
...(values.answer !== undefined ? { answer: values.answer } : {}),
|
|
149
|
+
...(values.model !== undefined ? { model: values.model } : {}),
|
|
150
|
+
log: io.stderr,
|
|
151
|
+
});
|
|
152
|
+
return { ok: outcome.status === 'done' || outcome.status === 'waiting', ...outcome };
|
|
153
|
+
}
|
|
154
|
+
if (positionals[0] === undefined)
|
|
155
|
+
throw new Usage('expected 1 argument(s), got 0');
|
|
156
|
+
const outcome = await runProject(repo, {
|
|
157
|
+
prompt: positionals[0],
|
|
158
|
+
...(values.id !== undefined ? { id: values.id } : {}),
|
|
159
|
+
...(values.mark ? { mark: true } : {}),
|
|
160
|
+
...(values.model !== undefined ? { model: values.model } : {}),
|
|
161
|
+
...(driver !== undefined ? { driver } : {}),
|
|
162
|
+
...named,
|
|
163
|
+
log: io.stderr,
|
|
164
|
+
});
|
|
165
|
+
return { ok: outcome.status === 'done' || outcome.status === 'waiting', ...outcome };
|
|
166
|
+
},
|
|
167
|
+
async check(args, io, git) {
|
|
168
|
+
const { values } = parse(args, { driver: { type: 'string' } }, 0);
|
|
169
|
+
const driver = values.driver ?? 'claude-code';
|
|
170
|
+
if (!isDriverName(driver))
|
|
171
|
+
throw new Usage(`unknown driver "${driver}"; the drivers are ${DRIVER_NAMES.join(' and ')}`);
|
|
172
|
+
const repo = await project(io.cwd, git);
|
|
173
|
+
return { ok: true, ...(await readyToRun(repo, driver)) };
|
|
174
|
+
},
|
|
175
|
+
async init(args, io, git) {
|
|
176
|
+
parse(args, {}, 0);
|
|
177
|
+
const repo = await project(io.cwd, git);
|
|
178
|
+
const outcome = await initHooks(repo);
|
|
179
|
+
if (outcome.ok)
|
|
180
|
+
return outcome;
|
|
181
|
+
const line = outcome.reason === 'no-dashboard' ? 'no .the-framework/ here: add the project in the dashboard first' : `${outcome.file}: ${outcome.detail ?? 'unreadable'}`;
|
|
182
|
+
throw new Refused(outcome, line);
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
/** The project the working directory belongs to, even from inside a checkout under `.branches/`. */
|
|
186
|
+
async function project(cwd, git) {
|
|
187
|
+
try {
|
|
188
|
+
return await projectRoot(cwd, git);
|
|
189
|
+
}
|
|
190
|
+
catch (err) {
|
|
191
|
+
if (!/not a git repository/i.test(err instanceof Error ? err.message : String(err)))
|
|
192
|
+
throw err;
|
|
193
|
+
throw new Refused({ ok: false, reason: 'not-a-repo' }, 'not inside a git repository');
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
function parse(args, options, min, max = min) {
|
|
197
|
+
try {
|
|
198
|
+
const parsed = parseArgs({ args, options, allowPositionals: true, strict: true });
|
|
199
|
+
if (parsed.positionals.length < min || parsed.positionals.length > max) {
|
|
200
|
+
throw new Usage(`expected ${max === min ? min : `${min} to ${max}`} argument(s), got ${parsed.positionals.length}`);
|
|
201
|
+
}
|
|
202
|
+
return parsed;
|
|
203
|
+
}
|
|
204
|
+
catch (err) {
|
|
205
|
+
throw err instanceof Usage ? err : new Usage(err instanceof Error ? err.message : String(err));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,aAAa,EAAkB,MAAM,qBAAqB,CAAA;AACnE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAC7C,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAExD;;;;GAIG;AAEH,MAAM,CAAC,MAAM,KAAK,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oGAiC+E,CAAA;AAUpG,MAAM,OAAQ,SAAQ,KAAK;IACJ,OAAO;IAAuB,IAAI;IAAvD,YAAqB,OAAmB,EAAW,IAAY;QAC7D,KAAK,CAAC,IAAI,CAAC,CAAA;uBADQ,OAAO;oBAAuB,IAAI;IAEvD,CAAC;CACF;AAED,MAAM,KAAM,SAAQ,KAAK;CAAG;AAE5B,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,IAAc,EAAE,EAAS,EAAE,GAAG,GAAc,aAAa,EAAE;IACtF,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAC/B,MAAM,GAAG,GAAG,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;IACvF,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QAChB,OAAO,CAAC,CAAA;IACV,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,CAAA;QACvC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAA;QACjC,OAAO,CAAC,CAAA;IACV,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;YACzB,EAAE,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,OAAO,KAAK,EAAE,CAAC,CAAA;YACvC,OAAO,CAAC,CAAA;QACV,CAAC;QACD,IAAI,GAAG,YAAY,OAAO,EAAE,CAAC;YAC3B,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;YACtC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACnB,OAAO,CAAC,CAAA;QACV,CAAC;QACD,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAA;QAC/D,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;QAClE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QACjB,OAAO,CAAC,CAAA;IACV,CAAC;AACH,CAAC;AAID,MAAM,QAAQ,GAA4B;IACxC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG;QACrB,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QACjW,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACvC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAA;QAC5B,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,sBAAsB,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QAC/I,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAA;QAC9B,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,OAAO,qBAAqB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACpJ,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,kFAAkF,CAAC,CAAA;YAC7H,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;YACrG,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,+EAA+E,CAAC,CAAA;YAC/H,IAAI,OAAO,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,oFAAoF,CAAC,CAAA;YAChI,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,6EAA6E,CAAC,CAAA;YAC/H,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAA;YAC7G,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;QAClI,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAA;QAC9F,4FAA4F;QAC5F,+CAA+C;QAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;YACpG,MAAM,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,EAAE,UAAU,MAAM,CAAC,MAAM,kBAAkB,CAAC,CAAA;QACzH,CAAC;QACD,4FAA4F;QAC5F,8FAA8F;QAC9F,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC3D,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,IAAI,aAAa,CAAC,CAAA;YAC7D,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC;gBAAE,MAAM,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,EAAE,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1H,CAAC;QACD,MAAM,KAAK,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAA;QACnQ,IAAI,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjD,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,IAAI,EAAE;gBACvC,EAAE,EAAE,MAAM,CAAC,MAAM;gBACjB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/D,CAAC,CAAA;YACF,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAA;QACjD,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;YAClF,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,8DAA8D,CAAC,CAAA;YAC5G,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,GAAG,KAAK,EAAE,CAAC,CAAA;YACxL,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAA;QACjD,CAAC;QACD,IAAI,MAAM,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,IAAI,EAAE;gBACxC,EAAE,EAAE,MAAM,CAAC,MAAM;gBACjB,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjE,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9D,GAAG,EAAE,EAAE,CAAC,MAAM;aACf,CAAC,CAAA;YACF,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,GAAG,OAAO,EAAE,CAAA;QACtF,CAAC;QACD,IAAI,WAAW,CAAC,CAAC,CAAC,KAAK,SAAS;YAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;QAClF,MAAM,OAAO,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE;YACrC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;YACtB,GAAG,CAAC,MAAM,CAAC,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACrD,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtC,GAAG,CAAC,MAAM,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,KAAK;YACR,GAAG,EAAE,EAAE,CAAC,MAAM;SACf,CAAC,CAAA;QACF,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,KAAK,MAAM,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,GAAG,OAAO,EAAE,CAAA;IACtF,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG;QACvB,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QACjE,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,aAAa,CAAA;QAC7C,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,MAAM,sBAAsB,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;QACvH,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACvC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE,CAAA;IAC1D,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,GAAG;QACtB,KAAK,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;QAClB,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QACvC,MAAM,OAAO,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,OAAO,CAAC,EAAE;YAAE,OAAO,OAAO,CAAA;QAC9B,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC,CAAC,iEAAiE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC,MAAM,IAAI,YAAY,EAAE,CAAA;QACzK,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;IAClC,CAAC;CACF,CAAA;AAED,oGAAoG;AACpG,KAAK,UAAU,OAAO,CAAC,GAAW,EAAE,GAAc;IAChD,IAAI,CAAC;QACH,OAAO,MAAM,WAAW,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;IACpC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,uBAAuB,CAAC,IAAI,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAAE,MAAM,GAAG,CAAA;QAC9F,MAAM,IAAI,OAAO,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,6BAA6B,CAAC,CAAA;IACvF,CAAC;AACH,CAAC;AAID,SAAS,KAAK,CAAoB,IAAc,EAAE,OAAU,EAAE,GAAW,EAAE,GAAG,GAAW,GAAG;IAC1F,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QACjF,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,GAAG,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;YACvE,MAAM,IAAI,KAAK,CAAC,YAAY,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,OAAO,GAAG,EAAE,qBAAqB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAA;QACrH,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAA;IAChG,CAAC;AACH,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type PersonalSetup } from '@openagt/agent-driver';
|
|
2
|
+
/**
|
|
3
|
+
* This machine's settings for the tool: `.agent-runner/config.yml` in the project, hidden from git
|
|
4
|
+
* with the rest of the directory. A missing file is no settings; a file that cannot be read as a
|
|
5
|
+
* YAML map is one line on `log` and no settings either, so a broken file never stops a run.
|
|
6
|
+
*/
|
|
7
|
+
export declare function readConfig(repo: string, log: (line: string) => void): Promise<Record<string, unknown>>;
|
|
8
|
+
/** Where this machine's settings file is in the project, for the lines that name it. */
|
|
9
|
+
export declare function configFile(repo: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Which parts of the person's own setup this machine's runs load: the `personal:` map in the
|
|
12
|
+
* config, one line per part (`memory: off`). A part is on unless its line says off, so a run
|
|
13
|
+
* loads what the coding agent loads when started by hand; anything else in the map is said on
|
|
14
|
+
* `log` and changes nothing.
|
|
15
|
+
*/
|
|
16
|
+
export declare function readPersonal(repo: string, log: (line: string) => void): Promise<PersonalSetup>;
|
|
17
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAA;AAI1E;;;;GAIG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAmB5G;AAED,wFAAwF;AACxF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,CAepG"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { readFile } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { PERSONAL_PARTS } from '@openagt/agent-driver';
|
|
4
|
+
import { parseDocument } from 'yaml';
|
|
5
|
+
import { RUNNER_CONFIG, RUNNER_DIR } from './names.js';
|
|
6
|
+
/**
|
|
7
|
+
* This machine's settings for the tool: `.agent-runner/config.yml` in the project, hidden from git
|
|
8
|
+
* with the rest of the directory. A missing file is no settings; a file that cannot be read as a
|
|
9
|
+
* YAML map is one line on `log` and no settings either, so a broken file never stops a run.
|
|
10
|
+
*/
|
|
11
|
+
export async function readConfig(repo, log) {
|
|
12
|
+
const file = configFile(repo);
|
|
13
|
+
let raw;
|
|
14
|
+
try {
|
|
15
|
+
raw = await readFile(file, 'utf8');
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
const doc = parseDocument(raw);
|
|
21
|
+
if (doc.errors.length > 0) {
|
|
22
|
+
log(`[agent-runner] ${file}: ${doc.errors[0].message.split('\n')[0]}`);
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
const top = doc.toJS();
|
|
26
|
+
if (top !== null && (typeof top !== 'object' || Array.isArray(top))) {
|
|
27
|
+
log(`[agent-runner] ${file}: the file is not a YAML map`);
|
|
28
|
+
return {};
|
|
29
|
+
}
|
|
30
|
+
return top ?? {};
|
|
31
|
+
}
|
|
32
|
+
/** Where this machine's settings file is in the project, for the lines that name it. */
|
|
33
|
+
export function configFile(repo) {
|
|
34
|
+
return join(repo, RUNNER_DIR, RUNNER_CONFIG);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Which parts of the person's own setup this machine's runs load: the `personal:` map in the
|
|
38
|
+
* config, one line per part (`memory: off`). A part is on unless its line says off, so a run
|
|
39
|
+
* loads what the coding agent loads when started by hand; anything else in the map is said on
|
|
40
|
+
* `log` and changes nothing.
|
|
41
|
+
*/
|
|
42
|
+
export async function readPersonal(repo, log) {
|
|
43
|
+
const setup = { memory: true, connectors: true, skills: true };
|
|
44
|
+
const value = (await readConfig(repo, log))['personal'];
|
|
45
|
+
if (value === undefined || value === null)
|
|
46
|
+
return setup;
|
|
47
|
+
const file = configFile(repo);
|
|
48
|
+
if (typeof value !== 'object' || Array.isArray(value)) {
|
|
49
|
+
log(`[agent-runner] ${file}: \`personal\` is not a map of ${PERSONAL_PARTS.join(', ')}`);
|
|
50
|
+
return setup;
|
|
51
|
+
}
|
|
52
|
+
for (const [part, on] of Object.entries(value)) {
|
|
53
|
+
if (!PERSONAL_PARTS.includes(part))
|
|
54
|
+
log(`[agent-runner] ${file}: \`personal\` has no part \`${part}\`; the parts are ${PERSONAL_PARTS.join(', ')}`);
|
|
55
|
+
else if (on === 'off' || on === false)
|
|
56
|
+
setup[part] = false;
|
|
57
|
+
else if (on !== null && on !== 'on' && on !== true)
|
|
58
|
+
log(`[agent-runner] ${file}: \`personal.${part}\` is not on or off`);
|
|
59
|
+
}
|
|
60
|
+
return setup;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/ended.d.ts
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The line a person wrote to run when a run needs them: `ended:` in the project's
|
|
3
|
+
* `.agent-runner/config.yml`, on this machine only, hidden from git with the rest of the
|
|
4
|
+
* directory. It runs when a run ends waiting on a question, and when a run ends done with a pull
|
|
5
|
+
* request its branch did not have before; never on any other end. The line is a shell line of
|
|
6
|
+
* the person's: this tool names no service it posts to.
|
|
7
|
+
*
|
|
8
|
+
* It runs in the project's root with the run's facts in its environment (`MESSAGE`, one line for
|
|
9
|
+
* a person; `RUN_ID`, `STATUS`, `QUESTION`, `PR_URL`), after the run's record is written. What it
|
|
10
|
+
* prints and how it exits never change the run: a failure is one line on this process's stderr.
|
|
11
|
+
*/
|
|
12
|
+
/** How long the line may take before it is ended. */
|
|
13
|
+
export declare const ENDED_TIMEOUT_MS = 60000;
|
|
14
|
+
/** Why a run's end is worth a person's attention, or nothing when it is not. */
|
|
15
|
+
export type EndedNews = {
|
|
16
|
+
status: 'waiting';
|
|
17
|
+
question: string;
|
|
18
|
+
pr?: {
|
|
19
|
+
url: string;
|
|
20
|
+
};
|
|
21
|
+
} | {
|
|
22
|
+
status: 'done';
|
|
23
|
+
pr: {
|
|
24
|
+
url: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Whether a run's end is one the line runs for: it ended waiting, or it ended done with a pull
|
|
29
|
+
* request it did not have when this session started. A failed or stopped run is left to whoever
|
|
30
|
+
* is looking at the runs.
|
|
31
|
+
*/
|
|
32
|
+
export declare function endedNews(end: {
|
|
33
|
+
status: string;
|
|
34
|
+
question?: string;
|
|
35
|
+
pr?: {
|
|
36
|
+
url: string;
|
|
37
|
+
};
|
|
38
|
+
prBefore?: {
|
|
39
|
+
url: string;
|
|
40
|
+
};
|
|
41
|
+
}): EndedNews | undefined;
|
|
42
|
+
/** The one line for a person: the project, the run's prompt, and what it needs or did. */
|
|
43
|
+
export declare function endedMessage(project: string, prompt: string, news: EndedNews): string;
|
|
44
|
+
/** The `ended:` line of this machine, or none. A file that cannot be read is said on `log`. */
|
|
45
|
+
export declare function readEndedLine(repo: string, log: (line: string) => void): Promise<string | undefined>;
|
|
46
|
+
/**
|
|
47
|
+
* Run the `ended:` line for a run's end when it is news, and wait for it (bounded): the run's
|
|
48
|
+
* process should not exit while the line posts. Nothing when there is no line or no news. Never
|
|
49
|
+
* throws: whatever goes wrong is one line on `log`, and the run ends as it ended.
|
|
50
|
+
*/
|
|
51
|
+
export declare function runEndedLine(repo: string, end: {
|
|
52
|
+
id: string;
|
|
53
|
+
prompt: string;
|
|
54
|
+
status: string;
|
|
55
|
+
question?: string;
|
|
56
|
+
pr?: {
|
|
57
|
+
url: string;
|
|
58
|
+
};
|
|
59
|
+
prBefore?: {
|
|
60
|
+
url: string;
|
|
61
|
+
};
|
|
62
|
+
}, deps: {
|
|
63
|
+
log: (line: string) => void;
|
|
64
|
+
timeoutMs?: number;
|
|
65
|
+
}): Promise<void>;
|
|
66
|
+
//# sourceMappingURL=ended.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ended.d.ts","sourceRoot":"","sources":["../src/ended.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,qDAAqD;AACrD,eAAO,MAAM,gBAAgB,QAAS,CAAA;AAEtC,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG;IAAE,MAAM,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,CAAA;AAE/H;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,GAAG,SAAS,CAK7I;AAQD,0FAA0F;AAC1F,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,MAAM,CAIrF;AAED,+FAA+F;AAC/F,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAI1G;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,QAAQ,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EACxH,IAAI,EAAE;IAAE,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
package/dist/ended.js
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { basename } from 'node:path';
|
|
3
|
+
import { configFile, readConfig } from './config.js';
|
|
4
|
+
/**
|
|
5
|
+
* The line a person wrote to run when a run needs them: `ended:` in the project's
|
|
6
|
+
* `.agent-runner/config.yml`, on this machine only, hidden from git with the rest of the
|
|
7
|
+
* directory. It runs when a run ends waiting on a question, and when a run ends done with a pull
|
|
8
|
+
* request its branch did not have before; never on any other end. The line is a shell line of
|
|
9
|
+
* the person's: this tool names no service it posts to.
|
|
10
|
+
*
|
|
11
|
+
* It runs in the project's root with the run's facts in its environment (`MESSAGE`, one line for
|
|
12
|
+
* a person; `RUN_ID`, `STATUS`, `QUESTION`, `PR_URL`), after the run's record is written. What it
|
|
13
|
+
* prints and how it exits never change the run: a failure is one line on this process's stderr.
|
|
14
|
+
*/
|
|
15
|
+
/** How long the line may take before it is ended. */
|
|
16
|
+
export const ENDED_TIMEOUT_MS = 60_000;
|
|
17
|
+
/**
|
|
18
|
+
* Whether a run's end is one the line runs for: it ended waiting, or it ended done with a pull
|
|
19
|
+
* request it did not have when this session started. A failed or stopped run is left to whoever
|
|
20
|
+
* is looking at the runs.
|
|
21
|
+
*/
|
|
22
|
+
export function endedNews(end) {
|
|
23
|
+
const newPr = end.pr && end.pr.url !== end.prBefore?.url ? { pr: { url: end.pr.url } } : {};
|
|
24
|
+
if (end.status === 'waiting')
|
|
25
|
+
return { status: 'waiting', question: end.question ?? 'a question', ...newPr };
|
|
26
|
+
if (end.status === 'done' && newPr.pr)
|
|
27
|
+
return { status: 'done', pr: newPr.pr };
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
/** The prompt as a message names it: its first line, cut short. */
|
|
31
|
+
function promptLabel(prompt) {
|
|
32
|
+
const first = prompt.trim().split('\n')[0] ?? '';
|
|
33
|
+
return first.length > 80 ? `${first.slice(0, 79)}…` : first;
|
|
34
|
+
}
|
|
35
|
+
/** The one line for a person: the project, the run's prompt, and what it needs or did. */
|
|
36
|
+
export function endedMessage(project, prompt, news) {
|
|
37
|
+
const head = `${project}: "${promptLabel(prompt)}"`;
|
|
38
|
+
if (news.status === 'waiting')
|
|
39
|
+
return `${head} is waiting for you: ${news.question.replace(/\s+/g, ' ').trim()}${news.pr ? ` (pull request: ${news.pr.url})` : ''}`;
|
|
40
|
+
return `${head} opened a pull request: ${news.pr.url}`;
|
|
41
|
+
}
|
|
42
|
+
/** The `ended:` line of this machine, or none. A file that cannot be read is said on `log`. */
|
|
43
|
+
export async function readEndedLine(repo, log) {
|
|
44
|
+
const value = (await readConfig(repo, log))['ended'];
|
|
45
|
+
if (value !== undefined && value !== null && typeof value !== 'string')
|
|
46
|
+
log(`[agent-runner] ${configFile(repo)}: \`ended\` is not a string`);
|
|
47
|
+
return typeof value === 'string' && value.trim() ? value.trim() : undefined;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Run the `ended:` line for a run's end when it is news, and wait for it (bounded): the run's
|
|
51
|
+
* process should not exit while the line posts. Nothing when there is no line or no news. Never
|
|
52
|
+
* throws: whatever goes wrong is one line on `log`, and the run ends as it ended.
|
|
53
|
+
*/
|
|
54
|
+
export async function runEndedLine(repo, end, deps) {
|
|
55
|
+
try {
|
|
56
|
+
await runLine(repo, end, deps);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
deps.log(`[agent-runner] the ended line could not run: ${err instanceof Error ? err.message : String(err)}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
async function runLine(repo, end, deps) {
|
|
63
|
+
const news = endedNews(end);
|
|
64
|
+
if (!news)
|
|
65
|
+
return;
|
|
66
|
+
const line = await readEndedLine(repo, deps.log);
|
|
67
|
+
if (!line)
|
|
68
|
+
return;
|
|
69
|
+
const env = {
|
|
70
|
+
...process.env,
|
|
71
|
+
MESSAGE: endedMessage(basename(repo), end.prompt, news),
|
|
72
|
+
RUN_ID: end.id,
|
|
73
|
+
STATUS: news.status,
|
|
74
|
+
QUESTION: news.status === 'waiting' ? news.question : '',
|
|
75
|
+
PR_URL: news.pr?.url ?? '',
|
|
76
|
+
};
|
|
77
|
+
// Its own process group, so the time limit ends whatever the line started (`npx` and its node),
|
|
78
|
+
// and the wait is for the line's exit, not for a pipe a leftover child still holds. Once the
|
|
79
|
+
// shell has exited, what it left running in the background is its own.
|
|
80
|
+
const limit = deps.timeoutMs ?? ENDED_TIMEOUT_MS;
|
|
81
|
+
await new Promise(resolve => {
|
|
82
|
+
// Only the last line is said: the tail is kept, bounded.
|
|
83
|
+
let stderr = '';
|
|
84
|
+
let timedOut = false;
|
|
85
|
+
const child = spawn('sh', ['-c', line], { cwd: repo, env, stdio: ['ignore', 'ignore', 'pipe'], detached: true });
|
|
86
|
+
const timer = setTimeout(() => {
|
|
87
|
+
timedOut = true;
|
|
88
|
+
try {
|
|
89
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// Already gone.
|
|
93
|
+
}
|
|
94
|
+
}, limit);
|
|
95
|
+
child.stderr.on('data', chunk => (stderr = (stderr + chunk).slice(-4096)));
|
|
96
|
+
child.on('error', err => {
|
|
97
|
+
clearTimeout(timer);
|
|
98
|
+
deps.log(`[agent-runner] the ended line could not start: ${err.message}`);
|
|
99
|
+
resolve();
|
|
100
|
+
});
|
|
101
|
+
child.on('exit', (code, signal) => {
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
child.stderr.destroy();
|
|
104
|
+
if (timedOut)
|
|
105
|
+
deps.log(`[agent-runner] the ended line took longer than ${limit >= 1000 ? `${Math.round(limit / 1000)}s` : `${limit}ms`} and was ended`);
|
|
106
|
+
else if (signal)
|
|
107
|
+
deps.log(`[agent-runner] the ended line was ended by ${signal}`);
|
|
108
|
+
else if (code !== 0)
|
|
109
|
+
deps.log(`[agent-runner] the ended line exited ${code}${stderr.trim() ? `: ${stderr.trim().split('\n').slice(-1)[0]}` : ''}`);
|
|
110
|
+
resolve();
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=ended.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ended.js","sourceRoot":"","sources":["../src/ended.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The project's git host (#1820), reached by declaration: whichever of the project's packages
|
|
3
|
+
* declares `"framework": { "git-host": "<command>" }` answers the pull requests, and this tool runs
|
|
4
|
+
* that command the way the dashboard runs any provided command. The tool names no git host and no
|
|
5
|
+
* package: a project with none has no pull requests to read back and nothing to merge.
|
|
6
|
+
*
|
|
7
|
+
* Two questions this tool asks of it: which pull request a branch has, for the run's record, and
|
|
8
|
+
* the merge of one, once a follow-up is done (`run.ts`).
|
|
9
|
+
*/
|
|
10
|
+
/** The pull request a branch has, as the record keeps it. */
|
|
11
|
+
export interface BranchRequest {
|
|
12
|
+
number: number;
|
|
13
|
+
url: string;
|
|
14
|
+
}
|
|
15
|
+
/** How merging a pull request went: armed on green, merged at once, watched by the git host package, or not at all. */
|
|
16
|
+
export type MergeOutcome = {
|
|
17
|
+
outcome: 'auto-armed' | 'merged' | 'watching';
|
|
18
|
+
} | {
|
|
19
|
+
outcome: 'failed';
|
|
20
|
+
error: string;
|
|
21
|
+
};
|
|
22
|
+
/** What a run asks of the git host; a test may hand in its own. */
|
|
23
|
+
export interface GitHost {
|
|
24
|
+
/** The newest pull request whose head is `branch`, open or closed; none when there is none, no git host, or the git host could not tell. */
|
|
25
|
+
requestOfBranch(repo: string, branch: string): Promise<BranchRequest | undefined>;
|
|
26
|
+
/** Land pull request `number`: armed to merge on green, or merged at once. */
|
|
27
|
+
mergeRequest(repo: string, number: number): Promise<MergeOutcome>;
|
|
28
|
+
}
|
|
29
|
+
/** The git host the project declares, run as a command. */
|
|
30
|
+
export declare const projectGitHost: GitHost;
|
|
31
|
+
//# sourceMappingURL=git-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-host.d.ts","sourceRoot":"","sources":["../src/git-host.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AAEH,6DAA6D;AAC7D,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,uHAAuH;AACvH,MAAM,MAAM,YAAY,GAAG;IAAE,OAAO,EAAE,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAA;CAAE,GAAG;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAA;AAEnH,mEAAmE;AACnE,MAAM,WAAW,OAAO;IACtB,4IAA4I;IAC5I,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAA;IACjF,8EAA8E;IAC9E,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CAClE;AAID,2DAA2D;AAC3D,eAAO,MAAM,cAAc,EAAE,OAkB5B,CAAA"}
|