mcoda 0.1.9 → 0.1.12
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/README.md +4 -4
- package/dist/bin/McodaEntrypoint.d.ts.map +1 -1
- package/dist/bin/McodaEntrypoint.js +40 -3
- package/dist/commands/agents/AgentRunCommand.d.ts.map +1 -1
- package/dist/commands/agents/AgentRunCommand.js +16 -2
- package/dist/commands/agents/AgentsCommands.d.ts.map +1 -1
- package/dist/commands/agents/AgentsCommands.js +209 -6
- package/dist/commands/agents/GatewayAgentCommand.js +1 -1
- package/dist/commands/agents/TestAgentCommand.d.ts.map +1 -1
- package/dist/commands/agents/TestAgentCommand.js +3 -0
- package/dist/commands/backlog/BacklogCommands.d.ts +5 -0
- package/dist/commands/backlog/BacklogCommands.d.ts.map +1 -1
- package/dist/commands/backlog/BacklogCommands.js +155 -34
- package/dist/commands/backlog/OrderTasksCommand.d.ts +3 -1
- package/dist/commands/backlog/OrderTasksCommand.d.ts.map +1 -1
- package/dist/commands/backlog/OrderTasksCommand.js +71 -31
- package/dist/commands/docs/DocsCommands.d.ts +14 -0
- package/dist/commands/docs/DocsCommands.d.ts.map +1 -1
- package/dist/commands/docs/DocsCommands.js +252 -4
- package/dist/commands/estimate/EstimateCommands.d.ts +1 -0
- package/dist/commands/estimate/EstimateCommands.d.ts.map +1 -1
- package/dist/commands/estimate/EstimateCommands.js +85 -7
- package/dist/commands/jobs/JobsCommands.d.ts +4 -0
- package/dist/commands/jobs/JobsCommands.d.ts.map +1 -1
- package/dist/commands/jobs/JobsCommands.js +117 -16
- package/dist/commands/openapi/OpenapiCommands.d.ts +1 -0
- package/dist/commands/openapi/OpenapiCommands.d.ts.map +1 -1
- package/dist/commands/openapi/OpenapiCommands.js +39 -5
- package/dist/commands/planning/CreateTasksCommand.d.ts +4 -0
- package/dist/commands/planning/CreateTasksCommand.d.ts.map +1 -1
- package/dist/commands/planning/CreateTasksCommand.js +43 -5
- package/dist/commands/planning/MigrateTasksCommand.js +1 -1
- package/dist/commands/planning/QaTasksCommand.d.ts +3 -1
- package/dist/commands/planning/QaTasksCommand.d.ts.map +1 -1
- package/dist/commands/planning/QaTasksCommand.js +28 -4
- package/dist/commands/planning/RefineTasksCommand.d.ts.map +1 -1
- package/dist/commands/planning/RefineTasksCommand.js +6 -1
- package/dist/commands/review/CodeReviewCommand.d.ts +1 -0
- package/dist/commands/review/CodeReviewCommand.d.ts.map +1 -1
- package/dist/commands/review/CodeReviewCommand.js +29 -6
- package/dist/commands/routing/RoutingCommands.d.ts.map +1 -1
- package/dist/commands/routing/RoutingCommands.js +48 -6
- package/dist/commands/telemetry/TelemetryCommands.d.ts +2 -0
- package/dist/commands/telemetry/TelemetryCommands.d.ts.map +1 -1
- package/dist/commands/telemetry/TelemetryCommands.js +3 -3
- package/dist/commands/work/GatewayTrioCommand.d.ts +4 -0
- package/dist/commands/work/GatewayTrioCommand.d.ts.map +1 -1
- package/dist/commands/work/GatewayTrioCommand.js +264 -19
- package/dist/commands/work/WorkOnTasksCommand.d.ts +3 -0
- package/dist/commands/work/WorkOnTasksCommand.d.ts.map +1 -1
- package/dist/commands/work/WorkOnTasksCommand.js +101 -12
- package/dist/commands/workspace/SetWorkspaceCommand.d.ts +64 -0
- package/dist/commands/workspace/SetWorkspaceCommand.d.ts.map +1 -1
- package/dist/commands/workspace/SetWorkspaceCommand.js +1377 -3
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -15,14 +15,14 @@ mcoda docs pdr generate --workspace-root . --project WEB --rfp-path docs/rfp/web
|
|
|
15
15
|
|
|
16
16
|
## Docdex & QA
|
|
17
17
|
- mcoda depends on the `docdex` CLI for doc search and context stitching.
|
|
18
|
-
- Run `docdex setup`
|
|
18
|
+
- Run `docdex setup` (or `docdexd browser install`) to install the headless Chromium browser used for web enrichment.
|
|
19
19
|
- Docdex stores state under `~/.docdex`; mcoda does not create repo-local `.docdex` folders.
|
|
20
20
|
- If `~/.docdex/agents.md` exists, it is prepended to every agent run.
|
|
21
21
|
|
|
22
22
|
## Workspace layout
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
-
|
|
23
|
+
- `~/.mcoda/workspaces/<fingerprint>/config.json` for defaults (docdex URL, branch metadata, telemetry preferences).
|
|
24
|
+
- `~/.mcoda/workspaces/<fingerprint>/mcoda.db` for backlog, jobs, and telemetry.
|
|
25
|
+
- `~/.mcoda/workspaces/<fingerprint>/docs/` for generated artifacts.
|
|
26
26
|
|
|
27
27
|
## Common commands
|
|
28
28
|
- Docs: `mcoda docs pdr generate`, `mcoda docs sds generate`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";AA2BA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";AA2BA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CAkLxE"}
|
|
@@ -26,14 +26,51 @@ import { AgentRunCommand } from "../commands/agents/AgentRunCommand.js";
|
|
|
26
26
|
import { SetWorkspaceCommand } from "../commands/workspace/SetWorkspaceCommand.js";
|
|
27
27
|
export class McodaEntrypoint {
|
|
28
28
|
static async run(argv = process.argv.slice(2)) {
|
|
29
|
-
const
|
|
29
|
+
const applyCodexNoSandboxFlag = (value) => {
|
|
30
|
+
if (value === undefined || value === "") {
|
|
31
|
+
process.env.MCODA_CODEX_NO_SANDBOX = "1";
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
const normalized = value.trim().toLowerCase();
|
|
35
|
+
if (["0", "false", "off", "no"].includes(normalized)) {
|
|
36
|
+
process.env.MCODA_CODEX_NO_SANDBOX = "0";
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
process.env.MCODA_CODEX_NO_SANDBOX = "1";
|
|
40
|
+
};
|
|
41
|
+
const filteredArgs = [];
|
|
42
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
43
|
+
const arg = argv[i];
|
|
44
|
+
if (arg === "--codex-no-sandbox") {
|
|
45
|
+
const next = argv[i + 1];
|
|
46
|
+
if (next && !next.startsWith("--")) {
|
|
47
|
+
applyCodexNoSandboxFlag(next);
|
|
48
|
+
i += 1;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
applyCodexNoSandboxFlag(undefined);
|
|
52
|
+
}
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (arg.startsWith("--codex-no-sandbox=")) {
|
|
56
|
+
const [, raw] = arg.split("=", 2);
|
|
57
|
+
applyCodexNoSandboxFlag(raw);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
filteredArgs.push(arg);
|
|
61
|
+
}
|
|
62
|
+
const [command, ...rest] = filteredArgs;
|
|
30
63
|
const wantsJson = argv.some((arg) => arg === "--json" || arg.startsWith("--json="));
|
|
31
64
|
const wantsQuiet = argv.some((arg) => arg === "--quiet" || arg.startsWith("--quiet="));
|
|
32
65
|
if (wantsJson || wantsQuiet) {
|
|
33
66
|
process.env.MCODA_STREAM_IO = "0";
|
|
67
|
+
process.env.MCODA_STREAM_IO_PROMPT = "0";
|
|
34
68
|
}
|
|
35
69
|
else if (process.env.MCODA_STREAM_IO === undefined) {
|
|
36
|
-
process.env.MCODA_STREAM_IO = "
|
|
70
|
+
process.env.MCODA_STREAM_IO = "0";
|
|
71
|
+
if (process.env.MCODA_STREAM_IO_PROMPT === undefined) {
|
|
72
|
+
process.env.MCODA_STREAM_IO_PROMPT = "0";
|
|
73
|
+
}
|
|
37
74
|
}
|
|
38
75
|
if (command === "--version" || command === "-v" || command === "version") {
|
|
39
76
|
// Keep this simple so `mcoda --version` works even in thin installs.
|
|
@@ -111,7 +148,7 @@ export class McodaEntrypoint {
|
|
|
111
148
|
if (command === "qa-tasks") {
|
|
112
149
|
if (rest.includes("--help") || rest.includes("-h")) {
|
|
113
150
|
// eslint-disable-next-line no-console
|
|
114
|
-
console.log("Usage: mcoda qa-tasks [--workspace-root <path>] --project <PROJECT_KEY> [--task <TASK_KEY> ... | --epic <EPIC_KEY> | --story <STORY_KEY>] [--status <STATUS_FILTER>] [--mode auto|manual] [--profile <PROFILE_NAME>] [--level unit|integration|acceptance] [--test-command \"<CMD>\"] [--agent <NAME>] [--agent-stream true|false] [--resume <JOB_ID>] [--create-followup-tasks auto|none|prompt] [--result pass|fail
|
|
151
|
+
console.log("Usage: mcoda qa-tasks [--workspace-root <path>] --project <PROJECT_KEY> [--task <TASK_KEY> ... | --epic <EPIC_KEY> | --story <STORY_KEY>] [--status <STATUS_FILTER>] [--limit N] [--mode auto|manual] [--profile <PROFILE_NAME>] [--level unit|integration|acceptance] [--test-command \"<CMD>\"] [--agent <NAME>] [--agent-stream true|false] [--resume <JOB_ID>] [--create-followup-tasks auto|none|prompt] [--result pass|fail] [--notes \"<text>\"] [--evidence-url \"<url>\"] [--dry-run] [--json]");
|
|
115
152
|
return;
|
|
116
153
|
}
|
|
117
154
|
await QaTasksCommand.run(rest);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentRunCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/AgentRunCommand.ts"],"names":[],"mappings":"AAyDA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"AgentRunCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/AgentRunCommand.ts"],"names":[],"mappings":"AAyDA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAsFhD"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import { AgentsApi } from "@mcoda/core";
|
|
3
|
-
const USAGE = "Usage: mcoda agent-run <NAME> [--prompt \"<text>\"] [--prompt-file <PATH>] [--task-file <PATH>] [--json]";
|
|
3
|
+
const USAGE = "Usage: mcoda agent-run <NAME> [--prompt \"<text>\"] [--prompt-file <PATH>] [--task-file <PATH>] [--stdin] [--json]";
|
|
4
4
|
const parseArgs = (argv) => {
|
|
5
5
|
const flags = {};
|
|
6
6
|
const positionals = [];
|
|
@@ -61,6 +61,15 @@ export class AgentRunCommand {
|
|
|
61
61
|
if (!name || parsed.flags.help) {
|
|
62
62
|
throw new Error(USAGE);
|
|
63
63
|
}
|
|
64
|
+
if (parsed.flags.prompt === true) {
|
|
65
|
+
throw new Error("agent-run: missing value for --prompt");
|
|
66
|
+
}
|
|
67
|
+
if (parsed.flags["prompt-file"] === true) {
|
|
68
|
+
throw new Error("agent-run: missing value for --prompt-file");
|
|
69
|
+
}
|
|
70
|
+
if (parsed.flags["task-file"] === true) {
|
|
71
|
+
throw new Error("agent-run: missing value for --task-file");
|
|
72
|
+
}
|
|
64
73
|
const prompts = [];
|
|
65
74
|
const inlinePrompts = toArray(parsed.flags.prompt);
|
|
66
75
|
for (const prompt of inlinePrompts) {
|
|
@@ -83,7 +92,12 @@ export class AgentRunCommand {
|
|
|
83
92
|
prompts.push(entry);
|
|
84
93
|
}
|
|
85
94
|
}
|
|
86
|
-
if (
|
|
95
|
+
if (parsed.flags.stdin) {
|
|
96
|
+
const stdinPrompt = await readStdinIfProvided();
|
|
97
|
+
if (stdinPrompt)
|
|
98
|
+
prompts.push(stdinPrompt);
|
|
99
|
+
}
|
|
100
|
+
else if (prompts.length === 0) {
|
|
87
101
|
const stdinPrompt = await readStdinIfProvided();
|
|
88
102
|
if (stdinPrompt)
|
|
89
103
|
prompts.push(stdinPrompt);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentsCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/AgentsCommands.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AgentsCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/AgentsCommands.ts"],"names":[],"mappings":"AA2TA,qBAAa,cAAc;WACZ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAuThD"}
|
|
@@ -38,15 +38,21 @@ const readSecret = async (promptText) => new Promise((resolve) => {
|
|
|
38
38
|
});
|
|
39
39
|
});
|
|
40
40
|
const USAGE = `
|
|
41
|
-
Usage: mcoda agent <list|add|update|delete|remove|auth|auth-status|set-default|use|ratings> ...
|
|
41
|
+
Usage: mcoda agent <list|details|add|update|delete|remove|auth|auth-status|set-default|use|ratings> ...
|
|
42
42
|
|
|
43
43
|
Subcommands:
|
|
44
44
|
list List agents (supports --json)
|
|
45
|
+
details <NAME> Show agent details (supports --json)
|
|
45
46
|
add <NAME> Create a global agent
|
|
46
47
|
--adapter <TYPE> Adapter slug (openai-api|zhipu-api|codex-cli|gemini-cli|local-model|qa-cli|ollama-remote)
|
|
47
48
|
--model <MODEL> Default model name
|
|
48
49
|
--rating <N> Relative capability rating (higher is stronger)
|
|
49
50
|
--reasoning-rating <N> Relative reasoning strength rating (higher is stronger)
|
|
51
|
+
--max-complexity <N> Max task complexity the agent should handle (1-10)
|
|
52
|
+
--openai-compatible <B> OpenAI-compatible API support (true/false)
|
|
53
|
+
--context-window <N> Context window size (tokens)
|
|
54
|
+
--max-output-tokens <N> Max output tokens per response
|
|
55
|
+
--supports-tools <B> Tool-calling support (true/false)
|
|
50
56
|
--best-usage <TEXT> Primary usage area (e.g., code_write, ui_ux_docs)
|
|
51
57
|
--cost-per-million <N> Cost per 1M tokens (0 for local models)
|
|
52
58
|
--capability <CAP> Repeatable capabilities to attach
|
|
@@ -56,6 +62,11 @@ Subcommands:
|
|
|
56
62
|
--config-temperature <N> Temperature override for supported adapters
|
|
57
63
|
--config-thinking <BOOL> Enable thinking mode for supported adapters
|
|
58
64
|
update <NAME> Update adapter/model/capabilities/prompts for an agent
|
|
65
|
+
--max-complexity <N> Max task complexity the agent should handle (1-10)
|
|
66
|
+
--openai-compatible <B> OpenAI-compatible API support (true/false)
|
|
67
|
+
--context-window <N> Context window size (tokens)
|
|
68
|
+
--max-output-tokens <N> Max output tokens per response
|
|
69
|
+
--supports-tools <B> Tool-calling support (true/false)
|
|
59
70
|
delete|remove <NAME> Remove an agent (use --force to ignore routing/default references)
|
|
60
71
|
--force Force deletion even if referenced
|
|
61
72
|
auth set <NAME> Store credentials (use --api-key or interactive prompt)
|
|
@@ -107,6 +118,44 @@ const parseReasoningRating = (value) => {
|
|
|
107
118
|
}
|
|
108
119
|
return parsed;
|
|
109
120
|
};
|
|
121
|
+
const parseMaxComplexity = (value) => {
|
|
122
|
+
if (value === undefined)
|
|
123
|
+
return undefined;
|
|
124
|
+
const raw = Array.isArray(value) ? value[value.length - 1] : value;
|
|
125
|
+
if (typeof raw === "boolean")
|
|
126
|
+
return undefined;
|
|
127
|
+
const parsed = Number.parseInt(String(raw), 10);
|
|
128
|
+
if (!Number.isFinite(parsed) || parsed < 1 || parsed > 10) {
|
|
129
|
+
throw new Error("Invalid --max-complexity; expected an integer 1-10");
|
|
130
|
+
}
|
|
131
|
+
return parsed;
|
|
132
|
+
};
|
|
133
|
+
const parsePositiveInt = (value, label) => {
|
|
134
|
+
if (value === undefined)
|
|
135
|
+
return undefined;
|
|
136
|
+
const raw = Array.isArray(value) ? value[value.length - 1] : value;
|
|
137
|
+
if (typeof raw === "boolean") {
|
|
138
|
+
throw new Error(`Invalid ${label}; expected a number`);
|
|
139
|
+
}
|
|
140
|
+
const parsed = Number.parseInt(String(raw), 10);
|
|
141
|
+
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
142
|
+
throw new Error(`Invalid ${label}; expected a positive integer`);
|
|
143
|
+
}
|
|
144
|
+
return parsed;
|
|
145
|
+
};
|
|
146
|
+
const parseBooleanFlag = (value, label) => {
|
|
147
|
+
if (value === undefined)
|
|
148
|
+
return undefined;
|
|
149
|
+
const raw = Array.isArray(value) ? value[value.length - 1] : value;
|
|
150
|
+
if (typeof raw === "boolean")
|
|
151
|
+
return raw;
|
|
152
|
+
const normalized = String(raw).trim().toLowerCase();
|
|
153
|
+
if (["true", "1", "yes", "y"].includes(normalized))
|
|
154
|
+
return true;
|
|
155
|
+
if (["false", "0", "no", "n"].includes(normalized))
|
|
156
|
+
return false;
|
|
157
|
+
throw new Error(`Invalid ${label}; expected true/false`);
|
|
158
|
+
};
|
|
110
159
|
const parseCostPerMillion = (value) => {
|
|
111
160
|
if (value === undefined)
|
|
112
161
|
return undefined;
|
|
@@ -178,6 +227,28 @@ const formatNumber = (value) => {
|
|
|
178
227
|
return "-";
|
|
179
228
|
return `${value}`;
|
|
180
229
|
};
|
|
230
|
+
const formatCompactNumber = (value) => {
|
|
231
|
+
if (value === undefined || value === null || Number.isNaN(value))
|
|
232
|
+
return "-";
|
|
233
|
+
const abs = Math.abs(value);
|
|
234
|
+
const format = (num, suffix, digits) => {
|
|
235
|
+
const raw = num.toFixed(digits);
|
|
236
|
+
const trimmed = raw.replace(/\.0+$/, "").replace(/(\.\d*[1-9])0+$/, "$1");
|
|
237
|
+
return `${trimmed}${suffix}`;
|
|
238
|
+
};
|
|
239
|
+
if (abs < 1000)
|
|
240
|
+
return `${value}`;
|
|
241
|
+
if (abs < 1000000) {
|
|
242
|
+
const digits = abs >= 10000 ? 0 : 1;
|
|
243
|
+
return format(value / 1000, "k", digits);
|
|
244
|
+
}
|
|
245
|
+
if (abs < 1000000000) {
|
|
246
|
+
const digits = abs >= 10000000 ? 0 : 2;
|
|
247
|
+
return format(value / 1000000, "M", digits);
|
|
248
|
+
}
|
|
249
|
+
const digits = abs >= 10000000000 ? 0 : 2;
|
|
250
|
+
return format(value / 1000000000, "B", digits);
|
|
251
|
+
};
|
|
181
252
|
const formatDuration = (value) => {
|
|
182
253
|
if (value === undefined || value === null || Number.isNaN(value))
|
|
183
254
|
return "-";
|
|
@@ -204,12 +275,51 @@ const formatBoxTable = (headers, rows, maxWidths) => {
|
|
|
204
275
|
const body = rows.map((row) => `│ ${row.map((val, idx) => cell(val ?? "", idx)).join(" │ ")} │`).join("\n");
|
|
205
276
|
return [top, headerLine, mid, body, bottom].join("\n");
|
|
206
277
|
};
|
|
278
|
+
const formatCapabilitiesFull = (caps) => {
|
|
279
|
+
const list = (caps ?? []).slice().sort();
|
|
280
|
+
return list.length === 0 ? "none" : list.join(", ");
|
|
281
|
+
};
|
|
282
|
+
const formatModels = (models) => {
|
|
283
|
+
if (!models || models.length === 0)
|
|
284
|
+
return "-";
|
|
285
|
+
const names = models
|
|
286
|
+
.map((model) => (model.isDefault ? `${model.modelName}*` : model.modelName))
|
|
287
|
+
.sort();
|
|
288
|
+
return names.join(", ");
|
|
289
|
+
};
|
|
290
|
+
const formatCommandPrompts = (prompts) => {
|
|
291
|
+
if (!prompts || Object.keys(prompts).length === 0)
|
|
292
|
+
return "-";
|
|
293
|
+
return Object.entries(prompts)
|
|
294
|
+
.sort(([left], [right]) => left.localeCompare(right))
|
|
295
|
+
.map(([key, value]) => `${key}=${value}`)
|
|
296
|
+
.join("; ");
|
|
297
|
+
};
|
|
298
|
+
const formatLatency = (value) => {
|
|
299
|
+
if (value === undefined || value === null || Number.isNaN(value))
|
|
300
|
+
return "-";
|
|
301
|
+
return `${Math.round(value)}ms`;
|
|
302
|
+
};
|
|
303
|
+
const renderKeyValues = (entries) => {
|
|
304
|
+
const width = entries.reduce((max, [label]) => Math.max(max, label.length), 0);
|
|
305
|
+
const lines = entries.map(([label, value]) => `${pad(label, width)} : ${value}`);
|
|
306
|
+
// eslint-disable-next-line no-console
|
|
307
|
+
console.log(lines.join("\n"));
|
|
308
|
+
};
|
|
207
309
|
export class AgentsCommands {
|
|
208
310
|
static async run(argv) {
|
|
209
311
|
const [rawSubcommand, ...rest] = argv;
|
|
210
|
-
const subcommand = rawSubcommand === "use"
|
|
211
|
-
|
|
212
|
-
|
|
312
|
+
const subcommand = rawSubcommand === "use"
|
|
313
|
+
? "set-default"
|
|
314
|
+
: rawSubcommand === "remove"
|
|
315
|
+
? "delete"
|
|
316
|
+
: rawSubcommand === "detail" || rawSubcommand === "show"
|
|
317
|
+
? "details"
|
|
318
|
+
: rawSubcommand;
|
|
319
|
+
if (!subcommand || argv.includes("--help") || argv.includes("-h")) {
|
|
320
|
+
// eslint-disable-next-line no-console
|
|
321
|
+
console.log(USAGE);
|
|
322
|
+
return;
|
|
213
323
|
}
|
|
214
324
|
const api = await AgentsApi.create();
|
|
215
325
|
const parsed = parseArgs(rest);
|
|
@@ -218,8 +328,9 @@ export class AgentsCommands {
|
|
|
218
328
|
case "list": {
|
|
219
329
|
const agents = await api.listAgents();
|
|
220
330
|
if (parsed.flags.json) {
|
|
331
|
+
const detailed = await Promise.all(agents.map((agent) => api.getAgent(agent.id ?? agent.slug)));
|
|
221
332
|
// eslint-disable-next-line no-console
|
|
222
|
-
console.log(JSON.stringify(
|
|
333
|
+
console.log(JSON.stringify(detailed, null, 2));
|
|
223
334
|
}
|
|
224
335
|
else {
|
|
225
336
|
if (agents.length === 0) {
|
|
@@ -233,19 +344,45 @@ export class AgentsCommands {
|
|
|
233
344
|
"MODEL",
|
|
234
345
|
"RATING",
|
|
235
346
|
"REASON",
|
|
347
|
+
"MAX CPLX",
|
|
348
|
+
"OAI",
|
|
349
|
+
"CTX",
|
|
350
|
+
"OUT",
|
|
351
|
+
"TOOLS",
|
|
236
352
|
"USAGE",
|
|
237
353
|
"COST/1M",
|
|
238
354
|
"HEALTH",
|
|
239
355
|
"LAST CHECK",
|
|
240
356
|
"CAPABILITIES",
|
|
241
357
|
];
|
|
242
|
-
const maxWidths = [
|
|
358
|
+
const maxWidths = [
|
|
359
|
+
undefined,
|
|
360
|
+
14,
|
|
361
|
+
24,
|
|
362
|
+
6,
|
|
363
|
+
9,
|
|
364
|
+
8,
|
|
365
|
+
4,
|
|
366
|
+
7,
|
|
367
|
+
7,
|
|
368
|
+
6,
|
|
369
|
+
10,
|
|
370
|
+
12,
|
|
371
|
+
10,
|
|
372
|
+
16,
|
|
373
|
+
36,
|
|
374
|
+
];
|
|
243
375
|
const rows = agents.map((agent) => [
|
|
244
376
|
agent.slug,
|
|
245
377
|
agent.adapter,
|
|
246
378
|
agent.defaultModel ?? "-",
|
|
247
379
|
agent.rating !== undefined ? String(agent.rating) : "-",
|
|
248
380
|
agent.reasoningRating !== undefined ? String(agent.reasoningRating) : "-",
|
|
381
|
+
formatNumber(agent.maxComplexity),
|
|
382
|
+
agent.openaiCompatible === undefined ? "-" : agent.openaiCompatible ? "yes" : "no",
|
|
383
|
+
formatCompactNumber(agent.contextWindow),
|
|
384
|
+
formatCompactNumber(agent.maxOutputTokens),
|
|
385
|
+
agent.supportsTools === undefined ? "-" : agent.supportsTools ? "yes" : "no",
|
|
249
386
|
agent.bestUsage ?? "-",
|
|
250
387
|
formatCost(agent.costPerMillion),
|
|
251
388
|
agent.health?.status ?? "unknown",
|
|
@@ -258,6 +395,52 @@ export class AgentsCommands {
|
|
|
258
395
|
}
|
|
259
396
|
break;
|
|
260
397
|
}
|
|
398
|
+
case "details": {
|
|
399
|
+
const name = parsed.positionals[0];
|
|
400
|
+
if (!name)
|
|
401
|
+
throw new Error("Usage: mcoda agent details <NAME> [--json]");
|
|
402
|
+
const agent = await api.getAgent(name);
|
|
403
|
+
if (parsed.flags.json) {
|
|
404
|
+
// eslint-disable-next-line no-console
|
|
405
|
+
console.log(JSON.stringify(agent, null, 2));
|
|
406
|
+
}
|
|
407
|
+
else {
|
|
408
|
+
renderKeyValues([
|
|
409
|
+
["Slug", agent.slug],
|
|
410
|
+
["Adapter", agent.adapter],
|
|
411
|
+
["Default model", agent.defaultModel ?? "-"],
|
|
412
|
+
["Rating", formatNumber(agent.rating)],
|
|
413
|
+
["Reasoning rating", formatNumber(agent.reasoningRating)],
|
|
414
|
+
["Max complexity", formatNumber(agent.maxComplexity)],
|
|
415
|
+
["OpenAI compatible", agent.openaiCompatible === undefined ? "-" : agent.openaiCompatible ? "yes" : "no"],
|
|
416
|
+
["Context window", formatNumber(agent.contextWindow)],
|
|
417
|
+
["Max output tokens", formatNumber(agent.maxOutputTokens)],
|
|
418
|
+
["Supports tools", agent.supportsTools === undefined ? "-" : agent.supportsTools ? "yes" : "no"],
|
|
419
|
+
["Best usage", agent.bestUsage ?? "-"],
|
|
420
|
+
["Cost per 1M", formatCost(agent.costPerMillion)],
|
|
421
|
+
["Rating samples", formatNumber(agent.ratingSamples)],
|
|
422
|
+
["Rating last score", formatNumber(agent.ratingLastScore)],
|
|
423
|
+
["Rating updated", formatDate(agent.ratingUpdatedAt)],
|
|
424
|
+
["Complexity samples", formatNumber(agent.complexitySamples)],
|
|
425
|
+
["Complexity updated", formatDate(agent.complexityUpdatedAt)],
|
|
426
|
+
["Capabilities", formatCapabilitiesFull(agent.capabilities)],
|
|
427
|
+
["Models", formatModels(agent.models)],
|
|
428
|
+
["Health status", agent.health?.status ?? "unknown"],
|
|
429
|
+
["Health last checked", formatDate(agent.health?.lastCheckedAt)],
|
|
430
|
+
["Health latency", formatLatency(agent.health?.latencyMs)],
|
|
431
|
+
["Auth configured", agent.auth?.configured ? "yes" : "no"],
|
|
432
|
+
["Auth last updated", formatDate(agent.auth?.lastUpdatedAt)],
|
|
433
|
+
["Auth last verified", formatDate(agent.auth?.lastVerifiedAt)],
|
|
434
|
+
["Command prompts", formatCommandPrompts(agent.prompts?.commandPrompts)],
|
|
435
|
+
["Job prompt path", agent.prompts?.jobPath ?? "-"],
|
|
436
|
+
["Character prompt path", agent.prompts?.characterPath ?? "-"],
|
|
437
|
+
["Config", agent.config ? JSON.stringify(agent.config) : "-"],
|
|
438
|
+
["Created", formatDate(agent.createdAt)],
|
|
439
|
+
["Updated", formatDate(agent.updatedAt)],
|
|
440
|
+
]);
|
|
441
|
+
}
|
|
442
|
+
break;
|
|
443
|
+
}
|
|
261
444
|
case "add": {
|
|
262
445
|
const name = parsed.positionals[0];
|
|
263
446
|
if (!name)
|
|
@@ -268,6 +451,11 @@ export class AgentsCommands {
|
|
|
268
451
|
const config = parseConfig(parsed.flags);
|
|
269
452
|
const rating = parseRating(parsed.flags.rating);
|
|
270
453
|
const reasoningRating = parseReasoningRating(parsed.flags["reasoning-rating"]);
|
|
454
|
+
const maxComplexity = parseMaxComplexity(parsed.flags["max-complexity"]);
|
|
455
|
+
const openaiCompatible = parseBooleanFlag(parsed.flags["openai-compatible"], "--openai-compatible");
|
|
456
|
+
const contextWindow = parsePositiveInt(parsed.flags["context-window"], "--context-window");
|
|
457
|
+
const maxOutputTokens = parsePositiveInt(parsed.flags["max-output-tokens"], "--max-output-tokens");
|
|
458
|
+
const supportsTools = parseBooleanFlag(parsed.flags["supports-tools"], "--supports-tools");
|
|
271
459
|
const bestUsage = parsed.flags["best-usage"] ? String(parsed.flags["best-usage"]) : undefined;
|
|
272
460
|
const costPerMillion = parseCostPerMillion(parsed.flags["cost-per-million"]);
|
|
273
461
|
const agent = await api.createAgent({
|
|
@@ -276,6 +464,11 @@ export class AgentsCommands {
|
|
|
276
464
|
defaultModel: parsed.flags.model ? String(parsed.flags.model) : undefined,
|
|
277
465
|
rating,
|
|
278
466
|
reasoningRating,
|
|
467
|
+
maxComplexity,
|
|
468
|
+
openaiCompatible,
|
|
469
|
+
contextWindow,
|
|
470
|
+
maxOutputTokens,
|
|
471
|
+
supportsTools,
|
|
279
472
|
bestUsage,
|
|
280
473
|
costPerMillion,
|
|
281
474
|
capabilities,
|
|
@@ -295,6 +488,11 @@ export class AgentsCommands {
|
|
|
295
488
|
const config = parseConfig(parsed.flags);
|
|
296
489
|
const rating = parseRating(parsed.flags.rating);
|
|
297
490
|
const reasoningRating = parseReasoningRating(parsed.flags["reasoning-rating"]);
|
|
491
|
+
const maxComplexity = parseMaxComplexity(parsed.flags["max-complexity"]);
|
|
492
|
+
const openaiCompatible = parseBooleanFlag(parsed.flags["openai-compatible"], "--openai-compatible");
|
|
493
|
+
const contextWindow = parsePositiveInt(parsed.flags["context-window"], "--context-window");
|
|
494
|
+
const maxOutputTokens = parsePositiveInt(parsed.flags["max-output-tokens"], "--max-output-tokens");
|
|
495
|
+
const supportsTools = parseBooleanFlag(parsed.flags["supports-tools"], "--supports-tools");
|
|
298
496
|
const bestUsage = parsed.flags["best-usage"] ? String(parsed.flags["best-usage"]) : undefined;
|
|
299
497
|
const costPerMillion = parseCostPerMillion(parsed.flags["cost-per-million"]);
|
|
300
498
|
const agent = await api.updateAgent(name, {
|
|
@@ -302,6 +500,11 @@ export class AgentsCommands {
|
|
|
302
500
|
defaultModel: parsed.flags.model ? String(parsed.flags.model) : undefined,
|
|
303
501
|
rating,
|
|
304
502
|
reasoningRating,
|
|
503
|
+
maxComplexity,
|
|
504
|
+
openaiCompatible,
|
|
505
|
+
contextWindow,
|
|
506
|
+
maxOutputTokens,
|
|
507
|
+
supportsTools,
|
|
305
508
|
bestUsage,
|
|
306
509
|
costPerMillion,
|
|
307
510
|
capabilities,
|
|
@@ -392,7 +392,7 @@ export class GatewayAgentCommand {
|
|
|
392
392
|
}
|
|
393
393
|
const service = await GatewayAgentService.create(workspace);
|
|
394
394
|
try {
|
|
395
|
-
const streamEnabled = (gatewayArgs.agentStream ??
|
|
395
|
+
const streamEnabled = (gatewayArgs.agentStream ?? false) && !gatewayArgs.json;
|
|
396
396
|
const ioEnabled = isIoEnabled();
|
|
397
397
|
const shouldPrintStream = streamEnabled && !ioEnabled;
|
|
398
398
|
let streamStarted = false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TestAgentCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/TestAgentCommand.ts"],"names":[],"mappings":"AAyBA,qBAAa,gBAAgB;WACd,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"TestAgentCommand.d.ts","sourceRoot":"","sources":["../../../src/commands/agents/TestAgentCommand.ts"],"names":[],"mappings":"AAyBA,qBAAa,gBAAgB;WACd,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAuChD"}
|
|
@@ -29,6 +29,9 @@ export class TestAgentCommand {
|
|
|
29
29
|
if (!name || parsed.flags.help) {
|
|
30
30
|
throw new Error(USAGE);
|
|
31
31
|
}
|
|
32
|
+
if (parsed.flags.prompt === true) {
|
|
33
|
+
throw new Error("test-agent: missing value for --prompt");
|
|
34
|
+
}
|
|
32
35
|
const prompt = typeof parsed.flags.prompt === "string" ? parsed.flags.prompt : undefined;
|
|
33
36
|
const api = await AgentsApi.create();
|
|
34
37
|
try {
|
|
@@ -5,7 +5,12 @@ interface ParsedArgs {
|
|
|
5
5
|
story?: string;
|
|
6
6
|
assignee?: string;
|
|
7
7
|
statuses?: string[];
|
|
8
|
+
statusAll?: boolean;
|
|
9
|
+
includeDone: boolean;
|
|
10
|
+
includeCancelled: boolean;
|
|
8
11
|
orderDependencies: boolean;
|
|
12
|
+
view?: "summary" | "epics" | "stories" | "tasks";
|
|
13
|
+
limit?: number;
|
|
9
14
|
json: boolean;
|
|
10
15
|
verbose: boolean;
|
|
11
16
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BacklogCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/BacklogCommands.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"BacklogCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/backlog/BacklogCommands.ts"],"names":[],"mappings":"AAIA,UAAU,UAAU;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AA6BD,eAAO,MAAM,gBAAgB,GAAI,MAAM,MAAM,EAAE,KAAG,UAsHjD,CAAC;AAgLF,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA4DhD"}
|