mcoda 0.1.38 → 0.1.40

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/CHANGELOG.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  ## Unreleased
4
4
  - Initial npm packaging scaffold for the mcoda CLI.
5
+ - Added bundled mswarm consent terms plus guided `mcoda setup`/postinstall consent bootstrap for installed CLI packages.
5
6
 
6
7
  ## 0.1.9
7
8
  - Release v0.1.9.
@@ -0,0 +1,65 @@
1
+ Mswarm Data Collection Terms And Consent
2
+
3
+ Version: 2026-03-18
4
+
5
+ By using Docdex or mcoda with mswarm-backed services, you agree to the following terms.
6
+
7
+ ## What We Collect
8
+
9
+ We may collect and process:
10
+
11
+ - product installation and client identity metadata
12
+ - consent records, including acceptance time, source IP address, and user agent
13
+ - web search queries and web search results generated by the product
14
+ - fetched webpage content and ai-digested summaries generated from that content
15
+ - local delegation failures and related error diagnostics
16
+ - mcoda local and cloud agent ratings, evaluations, and performance signals
17
+ - package integrity metadata such as signatures, checksums, and upload timestamps
18
+
19
+ ## Why We Collect It
20
+
21
+ We use this data to:
22
+
23
+ - operate and improve mswarm-backed search, cache, and cloud features
24
+ - measure quality, reliability, performance, and cost
25
+ - detect abuse, fraud, tampering, or manipulated uploads
26
+ - validate user consent and maintain compliance records
27
+ - improve model ratings and answer-cache quality across the product ecosystem
28
+
29
+ ## Required Consent
30
+
31
+ - Consent is required to use the product.
32
+ - If you do not accept these terms, installation and setup cannot continue.
33
+ - Your consent is recorded server-side together with the acceptance timestamp and source IP address.
34
+
35
+ ## Local Storage
36
+
37
+ Before upload, the product stores telemetry locally under `~/.docdex` or `~/.mcoda`.
38
+ Local packages may include search, fetch, answer, error, and rating data until they are uploaded or purged.
39
+
40
+ ## Upload And Retention
41
+
42
+ - Telemetry packages are compressed, checksummed, and signed before upload.
43
+ - The product retries failed uploads automatically.
44
+ - Uploaded packages are deleted locally after successful transfer.
45
+ - Unsent local packages older than 30 days are deleted.
46
+
47
+ ## Security And Integrity
48
+
49
+ - Packages are signed to reduce the risk of tampering or malware injection.
50
+ - Checksums are verified before ingestion.
51
+ - mswarm may reject packages that fail integrity or policy checks.
52
+
53
+ ## Your Rights
54
+
55
+ Subject to applicable law, you may:
56
+
57
+ - withdraw consent for future collection
58
+ - request deletion of your stored data
59
+ - ask for a summary of data associated with your client identity
60
+
61
+ Withdrawing consent stops future uploads but may also limit or disable product functionality that depends on mswarm.
62
+
63
+ ## Contact And Updates
64
+
65
+ These terms may be updated. The product may require renewed acceptance when the policy version changes.
package/README.md CHANGED
@@ -5,10 +5,13 @@ mcoda is a local-first CLI for planning, documentation, and execution workflows
5
5
  ## Install
6
6
  - Requires Node.js >= 20.
7
7
  - Global install: `npm i -g mcoda`
8
+ - Interactive installs show the bundled mswarm data collection terms and require acceptance before setup can continue.
9
+ - If install cannot prompt, complete the same mandatory consent flow with `mcoda setup` before other commands.
8
10
  - Verify: `mcoda --version`
9
11
 
10
12
  ## Quick start
11
13
  ```sh
14
+ mcoda setup
12
15
  mcoda set-workspace --workspace-root .
13
16
  mcoda docs pdr generate --workspace-root . --project WEB --rfp-path docs/rfp/web.md --agent codex
14
17
  ```
@@ -1 +1 @@
1
- {"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";AAiCA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CAqNxE"}
1
+ {"version":3,"file":"McodaEntrypoint.d.ts","sourceRoot":"","sources":["../../src/bin/McodaEntrypoint.ts"],"names":[],"mappings":";AAoCA,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,GAAE,MAAM,EAA0B,GAAG,OAAO,CAAC,IAAI,CAAC;CA6OxE"}
@@ -1,55 +1,58 @@
1
1
  #!/usr/bin/env node
2
- import { realpathSync } from "node:fs";
3
- import { fileURLToPath } from "node:url";
4
- import packageJson from "../../package.json" with { type: "json" };
5
- import { AgentsCommands } from "../commands/agents/AgentsCommands.js";
6
- import { CloudCommands } from "../commands/cloud/CloudCommands.js";
7
- import { ConfigCommands } from "../commands/config/ConfigCommands.js";
8
- import { GatewayAgentCommand } from "../commands/agents/GatewayAgentCommand.js";
9
- import { DocsCommands } from "../commands/docs/DocsCommands.js";
10
- import { JobsCommands } from "../commands/jobs/JobsCommands.js";
11
- import { OpenapiCommands } from "../commands/openapi/OpenapiCommands.js";
12
- import { CreateTasksCommand } from "../commands/planning/CreateTasksCommand.js";
13
- import { RefineTasksCommand } from "../commands/planning/RefineTasksCommand.js";
14
- import { TaskSufficiencyAuditCommand } from "../commands/planning/TaskSufficiencyAuditCommand.js";
15
- import { SdsPreflightCommand } from "../commands/planning/SdsPreflightCommand.js";
16
- import { BacklogCommands } from "../commands/backlog/BacklogCommands.js";
17
- import { TaskShowCommands } from "../commands/backlog/TaskShowCommands.js";
18
- import { OrderTasksCommand } from "../commands/backlog/OrderTasksCommand.js";
19
- import { EstimateCommands } from "../commands/estimate/EstimateCommands.js";
20
- import { TelemetryCommands } from "../commands/telemetry/TelemetryCommands.js";
21
- import { WorkOnTasksCommand } from "../commands/work/WorkOnTasksCommand.js";
22
- import { GatewayTrioCommand } from "../commands/work/GatewayTrioCommand.js";
23
- import { AddTestsCommand } from "../commands/work/AddTestsCommand.js";
24
- import { CodeReviewCommand } from "../commands/review/CodeReviewCommand.js";
25
- import { QaTasksCommand } from "../commands/planning/QaTasksCommand.js";
26
- import { MigrateTasksCommand } from "../commands/planning/MigrateTasksCommand.js";
27
- import { UpdateCommands } from "../commands/update/UpdateCommands.js";
28
- import { RoutingCommands } from "../commands/routing/RoutingCommands.js";
29
- import { TestAgentCommand } from "../commands/agents/TestAgentCommand.js";
30
- import { AgentRunCommand } from "../commands/agents/AgentRunCommand.js";
31
- import { SetWorkspaceCommand } from "../commands/workspace/SetWorkspaceCommand.js";
32
- import { ProjectGuidanceCommand } from "../commands/workspace/ProjectGuidanceCommand.js";
2
+ import { realpathSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import packageJson from '../../package.json' with { type: 'json' };
5
+ import { AgentsCommands } from '../commands/agents/AgentsCommands.js';
6
+ import { CloudCommands } from '../commands/cloud/CloudCommands.js';
7
+ import { ConfigCommands } from '../commands/config/ConfigCommands.js';
8
+ import { ConsentCommands } from '../commands/consent/ConsentCommands.js';
9
+ import { GatewayAgentCommand } from '../commands/agents/GatewayAgentCommand.js';
10
+ import { DocsCommands } from '../commands/docs/DocsCommands.js';
11
+ import { JobsCommands } from '../commands/jobs/JobsCommands.js';
12
+ import { OpenapiCommands } from '../commands/openapi/OpenapiCommands.js';
13
+ import { CreateTasksCommand } from '../commands/planning/CreateTasksCommand.js';
14
+ import { RefineTasksCommand } from '../commands/planning/RefineTasksCommand.js';
15
+ import { TaskSufficiencyAuditCommand } from '../commands/planning/TaskSufficiencyAuditCommand.js';
16
+ import { SdsPreflightCommand } from '../commands/planning/SdsPreflightCommand.js';
17
+ import { BacklogCommands } from '../commands/backlog/BacklogCommands.js';
18
+ import { TaskShowCommands } from '../commands/backlog/TaskShowCommands.js';
19
+ import { OrderTasksCommand } from '../commands/backlog/OrderTasksCommand.js';
20
+ import { EstimateCommands } from '../commands/estimate/EstimateCommands.js';
21
+ import { TelemetryCommands } from '../commands/telemetry/TelemetryCommands.js';
22
+ import { WorkOnTasksCommand } from '../commands/work/WorkOnTasksCommand.js';
23
+ import { GatewayTrioCommand } from '../commands/work/GatewayTrioCommand.js';
24
+ import { AddTestsCommand } from '../commands/work/AddTestsCommand.js';
25
+ import { CodeReviewCommand } from '../commands/review/CodeReviewCommand.js';
26
+ import { QaTasksCommand } from '../commands/planning/QaTasksCommand.js';
27
+ import { MigrateTasksCommand } from '../commands/planning/MigrateTasksCommand.js';
28
+ import { UpdateCommands } from '../commands/update/UpdateCommands.js';
29
+ import { RoutingCommands } from '../commands/routing/RoutingCommands.js';
30
+ import { SetupCommand } from '../commands/setup/SetupCommand.js';
31
+ import { TestAgentCommand } from '../commands/agents/TestAgentCommand.js';
32
+ import { AgentRunCommand } from '../commands/agents/AgentRunCommand.js';
33
+ import { SetWorkspaceCommand } from '../commands/workspace/SetWorkspaceCommand.js';
34
+ import { ProjectGuidanceCommand } from '../commands/workspace/ProjectGuidanceCommand.js';
35
+ import { MswarmConfigStore } from '@mcoda/core';
33
36
  export class McodaEntrypoint {
34
37
  static async run(argv = process.argv.slice(2)) {
35
38
  const applyCodexNoSandboxFlag = (value) => {
36
- if (value === undefined || value === "") {
37
- process.env.MCODA_CODEX_NO_SANDBOX = "1";
39
+ if (value === undefined || value === '') {
40
+ process.env.MCODA_CODEX_NO_SANDBOX = '1';
38
41
  return;
39
42
  }
40
43
  const normalized = value.trim().toLowerCase();
41
- if (["0", "false", "off", "no"].includes(normalized)) {
42
- process.env.MCODA_CODEX_NO_SANDBOX = "0";
44
+ if (['0', 'false', 'off', 'no'].includes(normalized)) {
45
+ process.env.MCODA_CODEX_NO_SANDBOX = '0';
43
46
  return;
44
47
  }
45
- process.env.MCODA_CODEX_NO_SANDBOX = "1";
48
+ process.env.MCODA_CODEX_NO_SANDBOX = '1';
46
49
  };
47
50
  const filteredArgs = [];
48
51
  for (let i = 0; i < argv.length; i += 1) {
49
52
  const arg = argv[i];
50
- if (arg === "--codex-no-sandbox") {
53
+ if (arg === '--codex-no-sandbox') {
51
54
  const next = argv[i + 1];
52
- if (next && !next.startsWith("--")) {
55
+ if (next && !next.startsWith('--')) {
53
56
  applyCodexNoSandboxFlag(next);
54
57
  i += 1;
55
58
  }
@@ -58,184 +61,202 @@ export class McodaEntrypoint {
58
61
  }
59
62
  continue;
60
63
  }
61
- if (arg.startsWith("--codex-no-sandbox=")) {
62
- const [, raw] = arg.split("=", 2);
64
+ if (arg.startsWith('--codex-no-sandbox=')) {
65
+ const [, raw] = arg.split('=', 2);
63
66
  applyCodexNoSandboxFlag(raw);
64
67
  continue;
65
68
  }
66
69
  filteredArgs.push(arg);
67
70
  }
68
71
  const [command, ...rest] = filteredArgs;
69
- const wantsJson = argv.some((arg) => arg === "--json" || arg.startsWith("--json="));
70
- const wantsQuiet = argv.some((arg) => arg === "--quiet" || arg.startsWith("--quiet="));
72
+ const wantsJson = argv.some((arg) => arg === '--json' || arg.startsWith('--json='));
73
+ const wantsQuiet = argv.some((arg) => arg === '--quiet' || arg.startsWith('--quiet='));
71
74
  if (wantsJson || wantsQuiet) {
72
- process.env.MCODA_STREAM_IO = "0";
73
- process.env.MCODA_STREAM_IO_PROMPT = "0";
75
+ process.env.MCODA_STREAM_IO = '0';
76
+ process.env.MCODA_STREAM_IO_PROMPT = '0';
74
77
  }
75
78
  else if (process.env.MCODA_STREAM_IO === undefined) {
76
- process.env.MCODA_STREAM_IO = "0";
79
+ process.env.MCODA_STREAM_IO = '0';
77
80
  if (process.env.MCODA_STREAM_IO_PROMPT === undefined) {
78
- process.env.MCODA_STREAM_IO_PROMPT = "0";
81
+ process.env.MCODA_STREAM_IO_PROMPT = '0';
79
82
  }
80
83
  }
81
- if (command === "--version" || command === "-v" || command === "version") {
84
+ if (command === '--version' || command === '-v' || command === 'version') {
82
85
  // Keep this simple so `mcoda --version` works even in thin installs.
83
86
  // eslint-disable-next-line no-console
84
- console.log(packageJson.version ?? "dev");
87
+ console.log(packageJson.version ?? 'dev');
85
88
  return;
86
89
  }
87
90
  if (!command) {
88
- throw new Error("Usage: mcoda <agent|cloud|cloud-agent|config|gateway-agent|test-agent|agent-run|routing|docs|openapi|job|jobs|tokens|telemetry|create-tasks|migrate-tasks|refine-tasks|task-sufficiency-audit|sds-preflight|order-tasks|tasks|add-tests|work-on-tasks|gateway-trio|code-review|qa-tasks|backlog|task|task-detail|estimate|update|set-workspace|project-guidance|pdr|sds> [...args]\n" +
89
- "Config: use `mcoda config set mswarm-api-key <KEY>` to persist an encrypted mswarm API key in the resolved global mcoda config file.\n" +
90
- "Routing: use `mcoda routing defaults` to view/update workspace/global defaults, `mcoda routing preview|explain` to inspect agent selection/provenance (override workspace_default global_default).\n" +
91
- "Cloud agents: use `mcoda cloud agent list|details|sync` to discover and materialize mswarm-managed remote agents.\n" +
92
- "Aliases: `tasks order-by-deps` forwards to `order-tasks` (dependency-aware ordering), `task`/`task-detail` show a single task.\n" +
93
- "Job commands (mcoda job --help for details): list|status|watch|logs|inspect|resume|cancel|tokens\n" +
94
- "Jobs API required for job commands (set MCODA_API_BASE_URL/MCODA_JOBS_API_URL or workspace api.baseUrl). status/watch/logs exit non-zero on failed/cancelled jobs per SDS.");
95
- }
96
- if (command === "agent") {
91
+ throw new Error('Usage: mcoda <agent|cloud|cloud-agent|config|consent|setup|gateway-agent|test-agent|agent-run|routing|docs|openapi|job|jobs|tokens|telemetry|create-tasks|migrate-tasks|refine-tasks|task-sufficiency-audit|sds-preflight|order-tasks|tasks|add-tests|work-on-tasks|gateway-trio|code-review|qa-tasks|backlog|task|task-detail|estimate|update|set-workspace|project-guidance|pdr|sds> [...args]\n' +
92
+ 'Setup: use `mcoda setup` after installation (or accept the postinstall prompt) to complete the mandatory mswarm telemetry consent flow.\n' +
93
+ 'Config: use `mcoda config set mswarm-api-key <KEY>` to persist an encrypted mswarm API key in the resolved global mcoda config file.\n' +
94
+ 'Consent: use `mcoda consent accept` before other commands if you need to complete consent outside the guided setup flow.\n' +
95
+ 'Routing: use `mcoda routing defaults` to view/update workspace/global defaults, `mcoda routing preview|explain` to inspect agent selection/provenance (override → workspace_default → global_default).\n' +
96
+ 'Cloud agents: use `mcoda cloud agent list|details|sync` to discover and materialize mswarm-managed remote agents.\n' +
97
+ 'Aliases: `tasks order-by-deps` forwards to `order-tasks` (dependency-aware ordering), `task`/`task-detail` show a single task.\n' +
98
+ 'Job commands (mcoda job --help for details): list|status|watch|logs|inspect|resume|cancel|tokens\n' +
99
+ 'Jobs API required for job commands (set MCODA_API_BASE_URL/MCODA_JOBS_API_URL or workspace api.baseUrl). status/watch/logs exit non-zero on failed/cancelled jobs per SDS.');
100
+ }
101
+ if (!['config', 'consent', 'setup'].includes(command)) {
102
+ const consentState = await new MswarmConfigStore().readState();
103
+ const consentAccepted = Boolean(consentState.consentAccepted);
104
+ const consentTokenSet = Boolean(consentState.consentToken?.trim());
105
+ if (!consentAccepted || !consentTokenSet) {
106
+ throw new Error('Telemetry consent is required before using mcoda. Review the mswarm data collection terms and run `mcoda setup` or `mcoda consent accept`.');
107
+ }
108
+ }
109
+ if (command === 'agent') {
97
110
  await AgentsCommands.run(rest);
98
111
  return;
99
112
  }
100
- if (command === "cloud") {
113
+ if (command === 'cloud') {
101
114
  await CloudCommands.run(rest);
102
115
  return;
103
116
  }
104
- if (command === "config") {
117
+ if (command === 'config') {
105
118
  await ConfigCommands.run(rest);
106
119
  return;
107
120
  }
108
- if (command === "cloud-agent") {
109
- await CloudCommands.run(["agent", ...rest]);
121
+ if (command === 'consent') {
122
+ await ConsentCommands.run(rest);
123
+ return;
124
+ }
125
+ if (command === 'setup') {
126
+ await SetupCommand.run(rest);
127
+ return;
128
+ }
129
+ if (command === 'cloud-agent') {
130
+ await CloudCommands.run(['agent', ...rest]);
110
131
  return;
111
132
  }
112
- if (command === "gateway-agent") {
133
+ if (command === 'gateway-agent') {
113
134
  await GatewayAgentCommand.run(rest);
114
135
  return;
115
136
  }
116
- if (command === "test-agent") {
137
+ if (command === 'test-agent') {
117
138
  await TestAgentCommand.run(rest);
118
139
  return;
119
140
  }
120
- if (command === "agent-run") {
141
+ if (command === 'agent-run') {
121
142
  await AgentRunCommand.run(rest);
122
143
  return;
123
144
  }
124
- if (command === "routing") {
145
+ if (command === 'routing') {
125
146
  await RoutingCommands.run(rest);
126
147
  return;
127
148
  }
128
- if (command === "docs") {
149
+ if (command === 'docs') {
129
150
  await DocsCommands.run(rest);
130
151
  return;
131
152
  }
132
- if (command === "openapi-from-docs" || command === "openapi") {
153
+ if (command === 'openapi-from-docs' || command === 'openapi') {
133
154
  await OpenapiCommands.run(rest);
134
155
  return;
135
156
  }
136
- if (command === "job" || command === "jobs") {
157
+ if (command === 'job' || command === 'jobs') {
137
158
  await JobsCommands.run(rest);
138
159
  return;
139
160
  }
140
- if (command === "tokens") {
161
+ if (command === 'tokens') {
141
162
  await TelemetryCommands.runTokens(rest);
142
163
  return;
143
164
  }
144
- if (command === "telemetry") {
165
+ if (command === 'telemetry') {
145
166
  await TelemetryCommands.runTelemetry(rest);
146
167
  return;
147
168
  }
148
- if (command === "pdr" || command === "mcoda:pdr") {
149
- await DocsCommands.run(["pdr", "generate", ...rest]);
169
+ if (command === 'pdr' || command === 'mcoda:pdr') {
170
+ await DocsCommands.run(['pdr', 'generate', ...rest]);
150
171
  return;
151
172
  }
152
- if (command === "sds" || command === "mcoda:sds") {
173
+ if (command === 'sds' || command === 'mcoda:sds') {
153
174
  const [subcommand, ...tail] = rest;
154
- if (subcommand === "generate" || subcommand === "suggestions") {
155
- await DocsCommands.run(["sds", subcommand, ...tail]);
175
+ if (subcommand === 'generate' || subcommand === 'suggestions') {
176
+ await DocsCommands.run(['sds', subcommand, ...tail]);
156
177
  }
157
178
  else {
158
- await DocsCommands.run(["sds", "generate", ...rest]);
179
+ await DocsCommands.run(['sds', 'generate', ...rest]);
159
180
  }
160
181
  return;
161
182
  }
162
- if (command === "create-tasks") {
183
+ if (command === 'create-tasks') {
163
184
  await CreateTasksCommand.run(rest);
164
185
  return;
165
186
  }
166
- if (command === "migrate-tasks") {
187
+ if (command === 'migrate-tasks') {
167
188
  await MigrateTasksCommand.run(rest);
168
189
  return;
169
190
  }
170
- if (command === "refine-tasks") {
191
+ if (command === 'refine-tasks') {
171
192
  await RefineTasksCommand.run(rest);
172
193
  return;
173
194
  }
174
- if (command === "task-sufficiency-audit") {
195
+ if (command === 'task-sufficiency-audit') {
175
196
  await TaskSufficiencyAuditCommand.run(rest);
176
197
  return;
177
198
  }
178
- if (command === "sds-preflight") {
199
+ if (command === 'sds-preflight') {
179
200
  await SdsPreflightCommand.run(rest);
180
201
  return;
181
202
  }
182
- if (command === "qa-tasks") {
183
- if (rest.includes("--help") || rest.includes("-h")) {
203
+ if (command === 'qa-tasks') {
204
+ if (rest.includes('--help') || rest.includes('-h')) {
184
205
  // eslint-disable-next-line no-console
185
- 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]");
206
+ 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]');
186
207
  return;
187
208
  }
188
209
  await QaTasksCommand.run(rest);
189
210
  return;
190
211
  }
191
- if (command === "order-tasks") {
212
+ if (command === 'order-tasks') {
192
213
  await OrderTasksCommand.run(rest);
193
214
  return;
194
215
  }
195
- if (command === "tasks") {
216
+ if (command === 'tasks') {
196
217
  const [sub, ...tail] = rest;
197
- if (sub === "order-by-deps" || sub === "order-by-dependencies") {
218
+ if (sub === 'order-by-deps' || sub === 'order-by-dependencies') {
198
219
  await OrderTasksCommand.run(tail);
199
220
  return;
200
221
  }
201
222
  }
202
- if (command === "work-on-tasks") {
223
+ if (command === 'work-on-tasks') {
203
224
  await WorkOnTasksCommand.run(rest);
204
225
  return;
205
226
  }
206
- if (command === "add-tests") {
227
+ if (command === 'add-tests') {
207
228
  await AddTestsCommand.run(rest);
208
229
  return;
209
230
  }
210
- if (command === "gateway-trio") {
231
+ if (command === 'gateway-trio') {
211
232
  await GatewayTrioCommand.run(rest);
212
233
  return;
213
234
  }
214
- if (command === "code-review") {
235
+ if (command === 'code-review') {
215
236
  await CodeReviewCommand.run(rest);
216
237
  return;
217
238
  }
218
- if (command === "backlog") {
239
+ if (command === 'backlog') {
219
240
  await BacklogCommands.run(rest);
220
241
  return;
221
242
  }
222
- if (command === "task" || command === "task-detail") {
243
+ if (command === 'task' || command === 'task-detail') {
223
244
  await TaskShowCommands.run(rest);
224
245
  return;
225
246
  }
226
- if (command === "estimate") {
247
+ if (command === 'estimate') {
227
248
  await EstimateCommands.run(rest);
228
249
  return;
229
250
  }
230
- if (command === "update") {
251
+ if (command === 'update') {
231
252
  await UpdateCommands.run(rest);
232
253
  return;
233
254
  }
234
- if (command === "set-workspace") {
255
+ if (command === 'set-workspace') {
235
256
  await SetWorkspaceCommand.run(rest);
236
257
  return;
237
258
  }
238
- if (command === "project-guidance") {
259
+ if (command === 'project-guidance') {
239
260
  await ProjectGuidanceCommand.run(rest);
240
261
  return;
241
262
  }
@@ -243,7 +264,7 @@ export class McodaEntrypoint {
243
264
  }
244
265
  }
245
266
  const isDirectRun = (() => {
246
- if (typeof process.argv[1] !== "string") {
267
+ if (typeof process.argv[1] !== 'string') {
247
268
  return false;
248
269
  }
249
270
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"CloudCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/cloud/CloudCommands.ts"],"names":[],"mappings":"AAyLA,qBAAa,aAAa;WACX,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA+EhD"}
1
+ {"version":3,"file":"CloudCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/cloud/CloudCommands.ts"],"names":[],"mappings":"AAkNA,qBAAa,aAAa;WACX,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA4FhD"}
@@ -6,10 +6,17 @@ Subcommands:
6
6
  agent list List mswarm cloud agents (supports --json)
7
7
  --provider <NAME> Filter by provider
8
8
  --limit <N> Limit returned agents
9
+ --max-cost-per-1m-token <N>
10
+ Exclude agents above the given cost_per_million
11
+ --sorted-by-catalog-rating
12
+ Sort results by the catalog rating field (descending)
13
+ --min-context <N> Require at least this context window
14
+ --min-reasoning <N> Require at least this reasoning rating
9
15
  agent details <SLUG> Show a single mswarm cloud agent (supports --json)
10
16
  agent sync Sync mswarm cloud agents into the local mcoda registry
11
17
  --provider <NAME> Filter by provider before syncing
12
18
  --limit <N> Limit synced agents
19
+ --prune Remove previously synced managed agents missing from the current catalog result
13
20
  --agent-slug-prefix <P> Override the local managed-agent slug prefix
14
21
 
15
22
  Connection options:
@@ -78,6 +85,16 @@ const resolvePositiveInt = (value, label) => {
78
85
  }
79
86
  return parsed;
80
87
  };
88
+ const resolveNonNegativeNumber = (value, label) => {
89
+ const raw = resolveString(value);
90
+ if (raw === undefined)
91
+ return undefined;
92
+ const parsed = Number(raw);
93
+ if (!Number.isFinite(parsed) || parsed < 0) {
94
+ throw new Error(`Invalid ${label}; expected a non-negative number`);
95
+ }
96
+ return parsed;
97
+ };
81
98
  const formatNumber = (value) => value === undefined || Number.isNaN(value) ? "-" : String(value);
82
99
  const formatCapabilities = (capabilities) => capabilities && capabilities.length > 0 ? capabilities.join(",") : "-";
83
100
  const formatBoolean = (value) => value === undefined ? "-" : value ? "yes" : "no";
@@ -104,9 +121,10 @@ const printAgentList = (agents) => {
104
121
  "RATING",
105
122
  "REASON",
106
123
  "MAX CPLX",
124
+ "CTX",
125
+ "COST/$1M",
107
126
  "TOOLS",
108
127
  "HEALTH",
109
- "PRICING",
110
128
  "CAPABILITIES",
111
129
  ];
112
130
  const rows = agents.map((agent) => [
@@ -116,9 +134,10 @@ const printAgentList = (agents) => {
116
134
  formatNumber(agent.rating),
117
135
  formatNumber(agent.reasoning_rating),
118
136
  formatNumber(agent.max_complexity),
137
+ formatNumber(agent.context_window),
138
+ formatNumber(agent.cost_per_million),
119
139
  formatBoolean(agent.supports_tools),
120
140
  agent.health_status ?? "-",
121
- agent.pricing_version ?? "-",
122
141
  formatCapabilities(agent.capabilities),
123
142
  ]);
124
143
  // eslint-disable-next-line no-console
@@ -135,6 +154,7 @@ const printAgentDetails = (agent) => {
135
154
  ["Rating", formatNumber(agent.rating)],
136
155
  ["Reasoning rating", formatNumber(agent.reasoning_rating)],
137
156
  ["Max complexity", formatNumber(agent.max_complexity)],
157
+ ["Cost / 1M tokens", formatNumber(agent.cost_per_million)],
138
158
  ["Context window", formatNumber(agent.context_window)],
139
159
  ["Supports tools", formatBoolean(agent.supports_tools)],
140
160
  ["Supports reasoning", formatBoolean(agent.supports_reasoning)],
@@ -151,7 +171,7 @@ const printAgentDetails = (agent) => {
151
171
  };
152
172
  const printSyncSummary = (summary) => {
153
173
  // eslint-disable-next-line no-console
154
- console.log(`Synced ${summary.agents.length} cloud agents (created=${summary.created}, updated=${summary.updated}).`);
174
+ console.log(`Synced ${summary.agents.length} cloud agents (created=${summary.created}, updated=${summary.updated}, deleted=${summary.deleted}).`);
155
175
  if (summary.agents.length === 0) {
156
176
  return;
157
177
  }
@@ -199,6 +219,10 @@ export class CloudCommands {
199
219
  const agents = await api.listCloudAgents({
200
220
  provider: resolveString(parsed.flags.provider),
201
221
  limit: resolvePositiveInt(parsed.flags.limit, "--limit"),
222
+ maxCostPerMillion: resolveNonNegativeNumber(parsed.flags["max-cost-per-1m-token"], "--max-cost-per-1m-token"),
223
+ minContextWindow: resolvePositiveInt(parsed.flags["min-context"], "--min-context"),
224
+ minReasoningRating: resolveNonNegativeNumber(parsed.flags["min-reasoning"], "--min-reasoning"),
225
+ sortByCatalogRating: Boolean(parsed.flags["sorted-by-catalog-rating"] || parsed.flags["sort-by-catalog-rating"]),
202
226
  });
203
227
  if (parsed.flags.json) {
204
228
  // eslint-disable-next-line no-console
@@ -228,6 +252,7 @@ export class CloudCommands {
228
252
  const summary = await api.syncCloudAgents({
229
253
  provider: resolveString(parsed.flags.provider),
230
254
  limit: resolvePositiveInt(parsed.flags.limit, "--limit"),
255
+ pruneMissing: Boolean(parsed.flags.prune),
231
256
  });
232
257
  if (parsed.flags.json) {
233
258
  // eslint-disable-next-line no-console
@@ -1 +1 @@
1
- {"version":3,"file":"ConfigCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/config/ConfigCommands.ts"],"names":[],"mappings":"AAYA,qBAAa,cAAc;WACZ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAsBhD"}
1
+ {"version":3,"file":"ConfigCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/config/ConfigCommands.ts"],"names":[],"mappings":"AAYA,qBAAa,cAAc;WACZ,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAyBhD"}
@@ -1,4 +1,4 @@
1
- import { MswarmConfigStore } from "@mcoda/core";
1
+ import { MswarmApi, MswarmConfigStore } from "@mcoda/core";
2
2
  const USAGE = `
3
3
  Usage: mcoda config set mswarm-api-key <KEY>
4
4
 
@@ -27,7 +27,8 @@ export class ConfigCommands {
27
27
  }
28
28
  const store = new MswarmConfigStore();
29
29
  await store.saveApiKey(value);
30
+ const refresh = await MswarmApi.refreshManagedAgentAuth(value);
30
31
  // eslint-disable-next-line no-console
31
- console.log(`Saved encrypted mswarm API key to ${store.configPath()}.`);
32
+ console.log(`Saved encrypted mswarm API key to ${store.configPath()}. Refreshed managed cloud-agent auth for ${refresh.updated} agents.`);
32
33
  }
33
34
  }
@@ -0,0 +1,12 @@
1
+ type ParsedConsentArgs = {
2
+ subcommand?: string;
3
+ json: boolean;
4
+ policyVersion?: string;
5
+ reason?: string;
6
+ };
7
+ export declare class ConsentCommands {
8
+ static run(argv: string[]): Promise<void>;
9
+ }
10
+ export declare function parseConsentArgs(argv: string[]): ParsedConsentArgs;
11
+ export {};
12
+ //# sourceMappingURL=ConsentCommands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ConsentCommands.d.ts","sourceRoot":"","sources":["../../../src/commands/consent/ConsentCommands.ts"],"names":[],"mappings":"AA0BA,KAAK,iBAAiB,GAAG;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAcF,qBAAa,eAAe;WACb,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAmHhD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,iBAAiB,CAkClE"}