@executablemd/cli 0.4.1 → 0.5.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/esm/deno.js +18 -14
- package/esm/src/agent-config.js +45 -0
- package/esm/src/cli.js +183 -8
- package/package.json +7 -4
- package/types/deno.d.ts +10 -6
- package/types/src/agent-config.d.ts +33 -0
- package/types/src/cli.d.ts +3 -3
package/esm/deno.js
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
export default {
|
|
2
2
|
"name": "@executablemd/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"exports": "./src/cli.ts",
|
|
5
5
|
"imports": {
|
|
6
6
|
"@types/node": "npm:@types/node@^24.5.2",
|
|
7
7
|
"@durable-streams/client": "npm:@durable-streams/client@^0.2.2",
|
|
8
|
-
"@
|
|
9
|
-
"@effectionx/bdd/
|
|
8
|
+
"@durable-streams/server": "npm:@durable-streams/server@^0.3.8",
|
|
9
|
+
"@effectionx/bdd/node": "file:///home/runner/work/executable.md/executable.md/packages/test-support/bdd.ts",
|
|
10
|
+
"@effectionx/bdd/expect": "file:///home/runner/work/executable.md/executable.md/packages/test-support/expect.ts",
|
|
10
11
|
"@effectionx/test-adapter": "npm:@effectionx/test-adapter@0.7.4",
|
|
11
12
|
"effection": "npm:effection@4.1.0-alpha.7",
|
|
12
13
|
"effection/experimental": "npm:effection@4.1.0-alpha.7/experimental",
|
|
13
|
-
"@executablemd/durable-streams": "npm:@executablemd/durable-streams@^0.4.1",
|
|
14
|
-
"@executablemd/runtime": "npm:@executablemd/runtime@^0.4.1",
|
|
15
|
-
"@executablemd/testing": "npm:@executablemd/testing@^0.4.1",
|
|
16
14
|
"@std/assert": "jsr:@std/assert@^1.0.17",
|
|
17
15
|
"ajv": "npm:ajv@^8.17.1",
|
|
18
|
-
"@executablemd/runtime/test": "file:///home/runner/work/executable.md/executable.md/runtime/test/mod.ts",
|
|
19
|
-
"@executablemd/code-review-agent": "npm:@executablemd/code-review-agent@^0.4.1",
|
|
20
16
|
"@effectionx/context-api": "npm:@effectionx/context-api@0.6.0",
|
|
21
17
|
"@effectionx/converge": "npm:@effectionx/converge@0.1.4",
|
|
22
18
|
"@effectionx/fetch": "npm:@effectionx/fetch@0.2.0",
|
|
@@ -35,11 +31,19 @@ export default {
|
|
|
35
31
|
"oxlint-tsgolint": "npm:oxlint-tsgolint@^0.17",
|
|
36
32
|
"unist-util-select": "npm:unist-util-select@^5",
|
|
37
33
|
"mdast-util-to-string": "npm:mdast-util-to-string@^4",
|
|
38
|
-
"@executablemd/
|
|
39
|
-
"@executablemd/
|
|
40
|
-
"@executablemd/
|
|
41
|
-
"@executablemd/
|
|
42
|
-
"@executablemd/
|
|
43
|
-
"@executablemd/
|
|
34
|
+
"@executablemd/acp": "npm:@executablemd/acp@^0.5.1",
|
|
35
|
+
"@executablemd/acp/": "npm:@executablemd/acp@^0.5.1/",
|
|
36
|
+
"@executablemd/code-review-agent": "npm:@executablemd/code-review-agent@^0.5.1",
|
|
37
|
+
"@executablemd/code-review-agent/": "npm:@executablemd/code-review-agent@^0.5.1/",
|
|
38
|
+
"@executablemd/core": "npm:@executablemd/core@^0.5.1",
|
|
39
|
+
"@executablemd/core/": "npm:@executablemd/core@^0.5.1/",
|
|
40
|
+
"@executablemd/durable-streams": "npm:@executablemd/durable-streams@^0.5.1",
|
|
41
|
+
"@executablemd/durable-streams/": "npm:@executablemd/durable-streams@^0.5.1/",
|
|
42
|
+
"@executablemd/runtime": "npm:@executablemd/runtime@^0.5.1",
|
|
43
|
+
"@executablemd/runtime/": "npm:@executablemd/runtime@^0.5.1/",
|
|
44
|
+
"@executablemd/test-agent": "npm:@executablemd/test-agent@^0.5.1",
|
|
45
|
+
"@executablemd/test-agent/": "npm:@executablemd/test-agent@^0.5.1/",
|
|
46
|
+
"@executablemd/testing": "npm:@executablemd/testing@^0.5.1",
|
|
47
|
+
"@executablemd/testing/": "npm:@executablemd/testing@^0.5.1/"
|
|
44
48
|
}
|
|
45
49
|
};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent flag parsing for `xmd run` (specs/acp-client-spec.md
|
|
3
|
+
* §Command-line configuration).
|
|
4
|
+
*
|
|
5
|
+
* A pure function over the parsed flags: it reads no Context Apis, no
|
|
6
|
+
* environment, and no configuration. The `DEFAULT_AGENT_NAME` lookup and
|
|
7
|
+
* every install step stay in the CLI, so the flag-to-configuration
|
|
8
|
+
* mapping can be asserted on its own.
|
|
9
|
+
*/
|
|
10
|
+
/** `digits` or `digits "." digits` — nothing else is a number of seconds. */
|
|
11
|
+
const SECONDS = /^\d+(\.\d+)?$/;
|
|
12
|
+
function parseTimeout(value) {
|
|
13
|
+
const invalid = {
|
|
14
|
+
error: `--timeout must be a positive number of seconds, got "${value}"`,
|
|
15
|
+
};
|
|
16
|
+
const trimmed = value.trim();
|
|
17
|
+
if (!SECONDS.test(trimmed)) {
|
|
18
|
+
return invalid;
|
|
19
|
+
}
|
|
20
|
+
const seconds = Number(trimmed);
|
|
21
|
+
if (!Number.isFinite(seconds) || seconds <= 0) {
|
|
22
|
+
return invalid;
|
|
23
|
+
}
|
|
24
|
+
return seconds * 1000;
|
|
25
|
+
}
|
|
26
|
+
export function resolveAgentConfig(flags) {
|
|
27
|
+
const selected = [flags.approveAll, flags.approveReads, flags.denyAll].filter(Boolean);
|
|
28
|
+
if (selected.length > 1) {
|
|
29
|
+
return { error: "--approve-all, --approve-reads, and --deny-all are mutually exclusive" };
|
|
30
|
+
}
|
|
31
|
+
const permissionMode = flags.approveAll
|
|
32
|
+
? "approve-all"
|
|
33
|
+
: flags.denyAll
|
|
34
|
+
? "deny-all"
|
|
35
|
+
: "approve-reads";
|
|
36
|
+
let timeoutMs;
|
|
37
|
+
if (flags.timeout !== undefined) {
|
|
38
|
+
const parsed = parseTimeout(flags.timeout);
|
|
39
|
+
if (typeof parsed !== "number") {
|
|
40
|
+
return parsed;
|
|
41
|
+
}
|
|
42
|
+
timeoutMs = parsed;
|
|
43
|
+
}
|
|
44
|
+
return { permissionMode, defaultAgent: flags.defaultAgent, timeoutMs };
|
|
45
|
+
}
|
package/esm/src/cli.js
CHANGED
|
@@ -7,20 +7,25 @@
|
|
|
7
7
|
* xmd <document.md> [options] (run is the default command)
|
|
8
8
|
*
|
|
9
9
|
* Examples:
|
|
10
|
-
* xmd run core/examples/hello-world.md
|
|
11
|
-
* xmd core/examples/hello-world.md --verbose
|
|
12
|
-
* xmd run core/examples/hello-world.md --journal events.jsonl
|
|
10
|
+
* xmd run packages/core/examples/hello-world.md
|
|
11
|
+
* xmd packages/core/examples/hello-world.md --verbose
|
|
12
|
+
* xmd run packages/core/examples/hello-world.md --journal events.jsonl
|
|
13
13
|
*/
|
|
14
14
|
import { main, exit, spawn, each, createSignal, until } from "effection";
|
|
15
15
|
import { InMemoryStream, } from "@executablemd/durable-streams";
|
|
16
16
|
import { forEach } from "@effectionx/stream-helpers";
|
|
17
17
|
import { open } from "node:fs/promises";
|
|
18
|
+
import { basename, extname } from "node:path";
|
|
18
19
|
import { inspect } from "node:util";
|
|
19
20
|
import process from "node:process";
|
|
20
21
|
import { program, object, field, cli, commands } from "configliere";
|
|
21
22
|
import { z } from "zod";
|
|
22
|
-
import { execute, useNormalizedOutput, useTerminalOutput } from "@executablemd/core";
|
|
23
|
+
import { AgentProviders, Config, execute, installAgentVocabulary, installPermissionMode, registerAgentProvider, useNormalizedOutput, useTerminalOutput, } from "@executablemd/core";
|
|
24
|
+
import { env as readEnv } from "@executablemd/runtime";
|
|
25
|
+
import { createAcpxProvider, DEFAULT_AGENT_NAME } from "@executablemd/acp";
|
|
23
26
|
import { installTestingVocabulary, TestFailureError, useTesting } from "@executablemd/testing";
|
|
27
|
+
import { installTestAgentVocabulary, runTestAgentWorker } from "@executablemd/test-agent";
|
|
28
|
+
import { resolveAgentConfig } from "./agent-config.js";
|
|
24
29
|
import { FileStream } from "./file-stream.js";
|
|
25
30
|
import denoJson from "../deno.js";
|
|
26
31
|
const defaults = (value) => (mods) => ({ ...mods, default: value });
|
|
@@ -47,6 +52,30 @@ const runConfig = object({
|
|
|
47
52
|
description: "output raw markdown without normalization or terminal formatting",
|
|
48
53
|
...field(z.boolean(), defaults(false)),
|
|
49
54
|
},
|
|
55
|
+
agentProvider: {
|
|
56
|
+
description: "agent provider for agent components",
|
|
57
|
+
...field(z.string(), defaults("acpx")),
|
|
58
|
+
},
|
|
59
|
+
defaultAgent: {
|
|
60
|
+
description: "default agent name (overrides DEFAULT_AGENT_NAME)",
|
|
61
|
+
...field(z.string().optional()),
|
|
62
|
+
},
|
|
63
|
+
timeout: {
|
|
64
|
+
description: "shared timeout in seconds for process, fetch, and agent operations",
|
|
65
|
+
...field(z.union([z.string(), z.number()]).optional()),
|
|
66
|
+
},
|
|
67
|
+
approveAll: {
|
|
68
|
+
description: "approve every agent permission request",
|
|
69
|
+
...field(z.boolean(), defaults(false)),
|
|
70
|
+
},
|
|
71
|
+
approveReads: {
|
|
72
|
+
description: "approve read and search agent permissions, ask for the rest (default)",
|
|
73
|
+
...field(z.boolean(), defaults(false)),
|
|
74
|
+
},
|
|
75
|
+
denyAll: {
|
|
76
|
+
description: "deny every agent permission request",
|
|
77
|
+
...field(z.boolean(), defaults(false)),
|
|
78
|
+
},
|
|
50
79
|
});
|
|
51
80
|
const testConfig = object({
|
|
52
81
|
docPath: {
|
|
@@ -72,10 +101,16 @@ const testConfig = object({
|
|
|
72
101
|
...field(z.boolean(), defaults(false)),
|
|
73
102
|
},
|
|
74
103
|
});
|
|
104
|
+
const testAgentConfig = object({
|
|
105
|
+
connect: {
|
|
106
|
+
description: "opaque controller route (controller-launched workers only)",
|
|
107
|
+
...field(z.string()),
|
|
108
|
+
},
|
|
109
|
+
});
|
|
75
110
|
const xmd = program({
|
|
76
111
|
name: "xmd",
|
|
77
112
|
version: denoJson.version,
|
|
78
|
-
config: commands({ run: runConfig, test: testConfig }, { default: "run" }),
|
|
113
|
+
config: commands({ run: runConfig, test: testConfig, "test-agent": testAgentConfig }, { default: "run" }),
|
|
79
114
|
});
|
|
80
115
|
const pretty = (value) => inspect(value, {
|
|
81
116
|
colors: true,
|
|
@@ -129,6 +164,115 @@ function* createJournalFile(filePath) {
|
|
|
129
164
|
}
|
|
130
165
|
yield* until(handle.close());
|
|
131
166
|
}
|
|
167
|
+
/**
|
|
168
|
+
* The CLI entry script to hand back to a relaunched runtime. Deno and
|
|
169
|
+
* Node both report the module they started as `process.argv[1]`: the
|
|
170
|
+
* source `cli.ts` under `deno run`, the generated bin under npm. Only
|
|
171
|
+
* the compiled binary carries no entry script, and it never asks.
|
|
172
|
+
*/
|
|
173
|
+
function cliEntrypoint() {
|
|
174
|
+
const entrypoint = process.argv[1];
|
|
175
|
+
if (!entrypoint) {
|
|
176
|
+
throw new Error("cannot start the test-agent worker: this xmd was launched without a CLI entry script, so there is nothing for the worker process to run");
|
|
177
|
+
}
|
|
178
|
+
return entrypoint;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* A worker inheriting the parent's `--inspect` would exit immediately on
|
|
182
|
+
* the debug port the parent already holds, so those options do not carry
|
|
183
|
+
* across the relaunch. Everything else the parent runs under does.
|
|
184
|
+
*/
|
|
185
|
+
function workerExecArgv() {
|
|
186
|
+
return process.execArgv.filter((option) => !option.startsWith("--inspect"));
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* The command that relaunches this xmd as a test-agent worker. Three
|
|
190
|
+
* builds reach this: the compiled binary invokes itself, the Deno source
|
|
191
|
+
* CLI reconstructs `deno run`, and the npm package reconstructs `node`.
|
|
192
|
+
* `process.execPath` names the running executable under both runtimes —
|
|
193
|
+
* `Deno.execPath()` exists in neither the Node build nor Node itself.
|
|
194
|
+
*/
|
|
195
|
+
function resolveWorkerCommand() {
|
|
196
|
+
const execPath = process.execPath;
|
|
197
|
+
const runtime = basename(execPath, extname(execPath));
|
|
198
|
+
if (runtime === "deno") {
|
|
199
|
+
return [execPath, "run", "--allow-all", cliEntrypoint(), "test-agent"];
|
|
200
|
+
}
|
|
201
|
+
if (runtime === "node") {
|
|
202
|
+
return [execPath, ...workerExecArgv(), cliEntrypoint(), "test-agent"];
|
|
203
|
+
}
|
|
204
|
+
return [execPath, "test-agent"];
|
|
205
|
+
}
|
|
206
|
+
const AGENT_ONLY_FLAGS = [
|
|
207
|
+
"--agent-provider",
|
|
208
|
+
"--default-agent",
|
|
209
|
+
"--timeout",
|
|
210
|
+
"--approve-all",
|
|
211
|
+
"--approve-reads",
|
|
212
|
+
"--deny-all",
|
|
213
|
+
];
|
|
214
|
+
/**
|
|
215
|
+
* Agent options belong to `xmd run`. The argument parser ignores options
|
|
216
|
+
* it does not define rather than rejecting them, so `xmd test` has to
|
|
217
|
+
* reject these itself instead of silently running without them.
|
|
218
|
+
*/
|
|
219
|
+
function findAgentOnlyFlag(args) {
|
|
220
|
+
return args.find((arg) => AGENT_ONLY_FLAGS.some((flag) => arg === flag || arg.startsWith(`${flag}=`)));
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The text an option carried on the command line. `--timeout` validates
|
|
224
|
+
* this rather than the parsed value: the parser coerces `1e3` and `0x10`
|
|
225
|
+
* into numbers and drops `.5`, `+1` and `Infinity`, so forms the grammar
|
|
226
|
+
* rejects would otherwise reach the stack as valid seconds.
|
|
227
|
+
*/
|
|
228
|
+
function findFlagText(args, flag) {
|
|
229
|
+
for (const [index, arg] of args.entries()) {
|
|
230
|
+
if (arg === flag) {
|
|
231
|
+
return args[index + 1] ?? "";
|
|
232
|
+
}
|
|
233
|
+
if (arg.startsWith(`${flag}=`)) {
|
|
234
|
+
return arg.slice(flag.length + 1);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return undefined;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Install the agent stack for `xmd run`: permission mode, contextual
|
|
241
|
+
* timeout, the ACPX registration, and the vocabulary with the resolved
|
|
242
|
+
* root provider. Invalid flags and an unknown --agent-provider fail here
|
|
243
|
+
* — before any document executes. Nothing starts an agent: the provider
|
|
244
|
+
* validates availability on first use.
|
|
245
|
+
*/
|
|
246
|
+
function* installAgentStack(flags) {
|
|
247
|
+
const config = resolveAgentConfig(flags);
|
|
248
|
+
if ("error" in config) {
|
|
249
|
+
console.error(config.error);
|
|
250
|
+
yield* exit(1);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
if (config.timeoutMs !== undefined) {
|
|
254
|
+
const ms = config.timeoutMs;
|
|
255
|
+
yield* Config.around({ timeout: () => ms }, { at: "min" });
|
|
256
|
+
}
|
|
257
|
+
yield* registerAgentProvider("acpx", createAcpxProvider());
|
|
258
|
+
const defaultAgent = config.defaultAgent ?? (yield* readEnv("DEFAULT_AGENT_NAME")) ?? DEFAULT_AGENT_NAME;
|
|
259
|
+
let factory;
|
|
260
|
+
try {
|
|
261
|
+
factory = yield* AgentProviders.operations.resolve(flags.agentProvider);
|
|
262
|
+
}
|
|
263
|
+
catch (error) {
|
|
264
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
265
|
+
yield* exit(1);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
const permissionMode = config.permissionMode;
|
|
269
|
+
yield* installAgentVocabulary({
|
|
270
|
+
defaultAgent,
|
|
271
|
+
permissionMode,
|
|
272
|
+
rootProvider: { factory, options: { defaultAgent, permissionMode } },
|
|
273
|
+
});
|
|
274
|
+
yield* installPermissionMode(permissionMode);
|
|
275
|
+
}
|
|
132
276
|
function* run(config, mode) {
|
|
133
277
|
const { docPath, componentDir, verbose, journal, raw } = config;
|
|
134
278
|
// Every CLI invocation starts from an empty stream. --journal writes
|
|
@@ -173,10 +317,19 @@ function* run(config, mode) {
|
|
|
173
317
|
// additionally activates root testing through a useTesting() session.
|
|
174
318
|
if (mode.testing) {
|
|
175
319
|
yield* useTesting({ verbose });
|
|
320
|
+
// TestAgent installs before the agent vocabulary so its <Prompt>
|
|
321
|
+
// interceptor runs first.
|
|
322
|
+
yield* installTestAgentVocabulary({ workerCommand: resolveWorkerCommand() });
|
|
323
|
+
yield* installAgentVocabulary();
|
|
176
324
|
}
|
|
177
325
|
else {
|
|
178
326
|
yield* installTestingVocabulary({ verbose });
|
|
179
327
|
}
|
|
328
|
+
// Agent flags are exclusive to `xmd run` — `xmd test` drives agents
|
|
329
|
+
// through the deterministic TestAgent stack instead.
|
|
330
|
+
if (mode.agent) {
|
|
331
|
+
yield* installAgentStack(mode.agent);
|
|
332
|
+
}
|
|
180
333
|
const execution = yield* execute({
|
|
181
334
|
docPath,
|
|
182
335
|
stream,
|
|
@@ -231,12 +384,34 @@ await main(function* (args) {
|
|
|
231
384
|
break;
|
|
232
385
|
}
|
|
233
386
|
switch (parsed.value.name) {
|
|
234
|
-
case "run":
|
|
235
|
-
|
|
387
|
+
case "run": {
|
|
388
|
+
const config = parsed.value.config;
|
|
389
|
+
yield* run(config, {
|
|
390
|
+
testing: false,
|
|
391
|
+
agent: {
|
|
392
|
+
agentProvider: config.agentProvider,
|
|
393
|
+
defaultAgent: config.defaultAgent,
|
|
394
|
+
timeout: findFlagText(args, "--timeout"),
|
|
395
|
+
approveAll: config.approveAll,
|
|
396
|
+
approveReads: config.approveReads,
|
|
397
|
+
denyAll: config.denyAll,
|
|
398
|
+
},
|
|
399
|
+
});
|
|
236
400
|
break;
|
|
237
|
-
|
|
401
|
+
}
|
|
402
|
+
case "test": {
|
|
403
|
+
const agentFlag = findAgentOnlyFlag(args);
|
|
404
|
+
if (agentFlag) {
|
|
405
|
+
console.error(`unrecognized option for xmd test: ${agentFlag} — agent options are exclusive to xmd run`);
|
|
406
|
+
yield* exit(1);
|
|
407
|
+
break;
|
|
408
|
+
}
|
|
238
409
|
yield* run(parsed.value.config, { testing: true });
|
|
239
410
|
break;
|
|
411
|
+
}
|
|
412
|
+
case "test-agent":
|
|
413
|
+
yield* runTestAgentWorker({ connect: parsed.value.config.connect });
|
|
414
|
+
break;
|
|
240
415
|
}
|
|
241
416
|
}
|
|
242
417
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@executablemd/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "The xmd command-line interface for executable.md.",
|
|
5
5
|
"homepage": "https://executable.md",
|
|
6
6
|
"repository": {
|
|
@@ -17,9 +17,12 @@
|
|
|
17
17
|
},
|
|
18
18
|
"dependencies": {
|
|
19
19
|
"@effectionx/stream-helpers": "0.8.3",
|
|
20
|
-
"@executablemd/
|
|
21
|
-
"@executablemd/
|
|
22
|
-
"@executablemd/
|
|
20
|
+
"@executablemd/acp": "^0.5.1",
|
|
21
|
+
"@executablemd/core": "^0.5.1",
|
|
22
|
+
"@executablemd/durable-streams": "^0.5.1",
|
|
23
|
+
"@executablemd/runtime": "^0.5.1",
|
|
24
|
+
"@executablemd/test-agent": "^0.5.1",
|
|
25
|
+
"@executablemd/testing": "^0.5.1",
|
|
23
26
|
"configliere": "^0.2.3",
|
|
24
27
|
"effection": "4.1.0-alpha.7",
|
|
25
28
|
"zod": "^4.3.6"
|
package/types/deno.d.ts
CHANGED
|
@@ -5,18 +5,14 @@ declare namespace _default {
|
|
|
5
5
|
let imports: {
|
|
6
6
|
"@types/node": string;
|
|
7
7
|
"@durable-streams/client": string;
|
|
8
|
+
"@durable-streams/server": string;
|
|
8
9
|
"@effectionx/bdd/node": string;
|
|
9
10
|
"@effectionx/bdd/expect": string;
|
|
10
11
|
"@effectionx/test-adapter": string;
|
|
11
12
|
effection: string;
|
|
12
13
|
"effection/experimental": string;
|
|
13
|
-
"@executablemd/durable-streams": string;
|
|
14
|
-
"@executablemd/runtime": string;
|
|
15
|
-
"@executablemd/testing": string;
|
|
16
14
|
"@std/assert": string;
|
|
17
15
|
ajv: string;
|
|
18
|
-
"@executablemd/runtime/test": string;
|
|
19
|
-
"@executablemd/code-review-agent": string;
|
|
20
16
|
"@effectionx/context-api": string;
|
|
21
17
|
"@effectionx/converge": string;
|
|
22
18
|
"@effectionx/fetch": string;
|
|
@@ -35,12 +31,20 @@ declare namespace _default {
|
|
|
35
31
|
"oxlint-tsgolint": string;
|
|
36
32
|
"unist-util-select": string;
|
|
37
33
|
"mdast-util-to-string": string;
|
|
34
|
+
"@executablemd/acp": string;
|
|
35
|
+
"@executablemd/acp/": string;
|
|
36
|
+
"@executablemd/code-review-agent": string;
|
|
37
|
+
"@executablemd/code-review-agent/": string;
|
|
38
38
|
"@executablemd/core": string;
|
|
39
39
|
"@executablemd/core/": string;
|
|
40
|
+
"@executablemd/durable-streams": string;
|
|
40
41
|
"@executablemd/durable-streams/": string;
|
|
42
|
+
"@executablemd/runtime": string;
|
|
41
43
|
"@executablemd/runtime/": string;
|
|
44
|
+
"@executablemd/test-agent": string;
|
|
45
|
+
"@executablemd/test-agent/": string;
|
|
46
|
+
"@executablemd/testing": string;
|
|
42
47
|
"@executablemd/testing/": string;
|
|
43
|
-
"@executablemd/code-review-agent/": string;
|
|
44
48
|
};
|
|
45
49
|
}
|
|
46
50
|
export default _default;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent flag parsing for `xmd run` (specs/acp-client-spec.md
|
|
3
|
+
* §Command-line configuration).
|
|
4
|
+
*
|
|
5
|
+
* A pure function over the parsed flags: it reads no Context Apis, no
|
|
6
|
+
* environment, and no configuration. The `DEFAULT_AGENT_NAME` lookup and
|
|
7
|
+
* every install step stay in the CLI, so the flag-to-configuration
|
|
8
|
+
* mapping can be asserted on its own.
|
|
9
|
+
*/
|
|
10
|
+
import type { PermissionMode } from "@executablemd/core";
|
|
11
|
+
export interface AgentFlags {
|
|
12
|
+
agentProvider: string;
|
|
13
|
+
defaultAgent: string | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* The raw `--timeout` text. The argument parser coerces or drops
|
|
16
|
+
* lexical forms — `1e3`, `0x10`, `.5`, `+1` and `Infinity` all reach a
|
|
17
|
+
* number-typed field as something this grammar would have rejected —
|
|
18
|
+
* so the untransformed text is what gets validated.
|
|
19
|
+
*/
|
|
20
|
+
timeout: string | undefined;
|
|
21
|
+
approveAll: boolean;
|
|
22
|
+
approveReads: boolean;
|
|
23
|
+
denyAll: boolean;
|
|
24
|
+
}
|
|
25
|
+
export interface AgentConfig {
|
|
26
|
+
permissionMode: PermissionMode;
|
|
27
|
+
/** The `--default-agent` value; the environment fallback is applied by the caller. */
|
|
28
|
+
defaultAgent: string | undefined;
|
|
29
|
+
timeoutMs: number | undefined;
|
|
30
|
+
}
|
|
31
|
+
export declare function resolveAgentConfig(flags: AgentFlags): AgentConfig | {
|
|
32
|
+
error: string;
|
|
33
|
+
};
|
package/types/src/cli.d.ts
CHANGED
|
@@ -7,8 +7,8 @@
|
|
|
7
7
|
* xmd <document.md> [options] (run is the default command)
|
|
8
8
|
*
|
|
9
9
|
* Examples:
|
|
10
|
-
* xmd run core/examples/hello-world.md
|
|
11
|
-
* xmd core/examples/hello-world.md --verbose
|
|
12
|
-
* xmd run core/examples/hello-world.md --journal events.jsonl
|
|
10
|
+
* xmd run packages/core/examples/hello-world.md
|
|
11
|
+
* xmd packages/core/examples/hello-world.md --verbose
|
|
12
|
+
* xmd run packages/core/examples/hello-world.md --journal events.jsonl
|
|
13
13
|
*/
|
|
14
14
|
export {};
|