@moda-ai/cli 1.55.43 → 1.55.45

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.
Files changed (40) hide show
  1. package/README.md +1 -1
  2. package/dist/{agent-x1gwrrvd.js → agent-5ax7fqhe.js} +8 -8
  3. package/dist/{cli-5y9tj6cb.js → cli-4m0rgkx4.js} +7 -2
  4. package/dist/{cli-daqkdnm1.js → cli-4pc0a18x.js} +1 -1
  5. package/dist/{cli-1z1sx8dg.js → cli-5aa48ry5.js} +5 -4
  6. package/dist/{cli-5fhqfx04.js → cli-8pcq2et6.js} +1 -1
  7. package/dist/{cli-fpd1pfvt.js → cli-8pksf2x7.js} +5 -5
  8. package/dist/{cli-s1w5phms.js → cli-d4cdczhe.js} +5 -5
  9. package/dist/{cli-0xc5htv7.js → cli-dmm9jm9m.js} +1 -1
  10. package/dist/{cli-t0pb7qbs.js → cli-e24fjyrb.js} +118 -10
  11. package/dist/{cli-pmzh2qjy.js → cli-sejqvvhv.js} +14 -6
  12. package/dist/{cli-h62j4jn7.js → cli-t4xfvrry.js} +34 -15
  13. package/dist/{cli-9a0a3v13.js → cli-tztzrh6b.js} +2 -2
  14. package/dist/{cli-k5drmy8r.js → cli-wwbr5caw.js} +8 -8
  15. package/dist/{cli-77ekrx7d.js → cli-xcpwp0gb.js} +14 -7
  16. package/dist/{cli-stfpr2ct.js → cli-xx0pjzkh.js} +4 -4
  17. package/dist/cli.js +33 -29
  18. package/dist/{doctor-wrgajgev.js → doctor-k4tdgvgv.js} +7 -7
  19. package/dist/{fix-7aajsdbf.js → fix-nk5xffz8.js} +4 -4
  20. package/dist/{harness-1rn1hqzz.js → harness-avynbq4f.js} +5 -5
  21. package/dist/{harness-github-actions-m95qvgbs.js → harness-github-actions-gd6vyxb0.js} +5 -5
  22. package/dist/{index-svfzq5rb.js → index-63k2a6gb.js} +11 -11
  23. package/dist/{production-intelligence-7jvfdz6b.js → production-intelligence-0z6v6tpp.js} +5 -3
  24. package/dist/{profile-commands-se9947c1.js → profile-commands-mh3kfqkn.js} +98 -20
  25. package/dist/{prompt-attribution-hc6mcvee.js → prompt-attribution-wvvnzw4m.js} +5 -5
  26. package/dist/prompt-source-mcp.js +5 -5
  27. package/dist/{prompts-ab-ws66335h.js → prompts-ab-y7egdzg4.js} +7 -7
  28. package/dist/{prompts-propose-a9m0p9nr.js → prompts-propose-5nw25v9a.js} +7 -7
  29. package/dist/{prompts-xe5bgbx8.js → prompts-snnbyxmz.js} +5 -5
  30. package/dist/{provision-a9kkfvp7.js → provision-t1dpzcjp.js} +5 -5
  31. package/dist/{registry-j2dsfh6v.js → registry-8zkxefjs.js} +3 -3
  32. package/dist/{skills-vveagdwe.js → skills-d4215fa9.js} +5 -5
  33. package/dist/{sync-yy3fgnxe.js → sync-17f9yxb1.js} +7 -7
  34. package/package.json +1 -1
  35. package/skills/integration/index.json +2 -2
  36. package/skills/moda-cli/SKILL.md +4 -3
  37. package/skills/moda-cli/references/auth.md +16 -7
  38. package/skills/moda-cli/references/output-protocol.md +1 -1
  39. package/skills/moda-cli/references/search-and-traces.md +3 -1
  40. package/skills/moda-cli/references/troubleshooting.md +14 -0
@@ -5,7 +5,7 @@ import {
5
5
  resolveApiKey,
6
6
  resolveApiKeyFromActiveProfile,
7
7
  resolveModaBaseUrl
8
- } from "./cli-t0pb7qbs.js";
8
+ } from "./cli-e24fjyrb.js";
9
9
 
10
10
  // src/api-key-auth.ts
11
11
  var PROBE_TIMEOUT_MS = 1e4;
@@ -37,25 +37,32 @@ async function fetchApiKeyProbe(baseUrl, headers, timeoutMs) {
37
37
  return probe("overview");
38
38
  }
39
39
  async function probeApiKey(key, options = {}) {
40
+ const baseUrl = resolveModaBaseUrl(options);
40
41
  let response;
41
42
  try {
42
- response = await fetchApiKeyProbe(resolveModaBaseUrl(options), apiKeyHeaders(key, options), PROBE_TIMEOUT_MS);
43
+ response = await fetchApiKeyProbe(baseUrl, apiKeyHeaders(key, options), PROBE_TIMEOUT_MS);
43
44
  } catch (error) {
44
45
  const reason = error instanceof Error ? error.message : String(error);
45
46
  return { outcome: "unreachable", reason };
46
47
  }
47
48
  if (response.status === 401 || response.status === 403) {
48
- return { outcome: "rejected", status: response.status };
49
+ const body2 = await response.text().catch(() => {
50
+ return;
51
+ });
52
+ return { outcome: "rejected", status: response.status, ...body2 ? { body: body2 } : {} };
49
53
  }
50
54
  if (response.status !== 200) {
51
- return { outcome: "unreachable", reason: `HTTP ${response.status}` };
55
+ return { outcome: "unreachable", reason: `HTTP ${response.status}`, status: response.status };
52
56
  }
57
+ let body;
53
58
  try {
54
- await response.json();
59
+ body = await response.json();
55
60
  } catch {
56
- return { outcome: "unreachable", reason: "non-JSON response from the Data API" };
61
+ return { outcome: "unreachable", reason: "non-JSON response from the Data API", status: response.status };
57
62
  }
58
- return { outcome: "live" };
63
+ const record = body !== null && typeof body === "object" && !Array.isArray(body) ? body : undefined;
64
+ const identity = record && typeof record.tenant_id === "string" && typeof record.key_kind === "string" ? record : undefined;
65
+ return identity ? { outcome: "live", identity } : { outcome: "live" };
59
66
  }
60
67
 
61
68
  export { resolveApiKeyCredential, redactApiKey, fetchApiKeyProbe, probeApiKey };
@@ -13,22 +13,22 @@ import {
13
13
  } from "./cli-hcwdz9sd.js";
14
14
  import {
15
15
  createCommandContext
16
- } from "./cli-5fhqfx04.js";
16
+ } from "./cli-8pcq2et6.js";
17
17
  import {
18
18
  assertFlags,
19
19
  assertPositionals,
20
20
  writeDryRun
21
- } from "./cli-9a0a3v13.js";
21
+ } from "./cli-tztzrh6b.js";
22
22
  import {
23
23
  callControlAPI
24
- } from "./cli-0xc5htv7.js";
24
+ } from "./cli-dmm9jm9m.js";
25
25
  import {
26
26
  recordApiRequest,
27
27
  resolveApiKey,
28
28
  resolveIngestUrl,
29
29
  resolveTenantId,
30
30
  shellArg
31
- } from "./cli-t0pb7qbs.js";
31
+ } from "./cli-e24fjyrb.js";
32
32
  import {
33
33
  CliInputError
34
34
  } from "./cli-k4tqwah4.js";
package/dist/cli.js CHANGED
@@ -26,10 +26,10 @@ import {
26
26
  withSummaryCompare,
27
27
  withToolFailureAnchors,
28
28
  withoutDetectionWindows
29
- } from "./cli-5y9tj6cb.js";
29
+ } from "./cli-4m0rgkx4.js";
30
30
  import {
31
31
  createCommandContext
32
- } from "./cli-5fhqfx04.js";
32
+ } from "./cli-8pcq2et6.js";
33
33
  import {
34
34
  envOptOutSet,
35
35
  envSwitchedOff,
@@ -87,12 +87,12 @@ import {
87
87
  unknownSignalsSubcommandError,
88
88
  usageLine,
89
89
  writeDryRun
90
- } from "./cli-9a0a3v13.js";
90
+ } from "./cli-tztzrh6b.js";
91
91
  import {
92
92
  ApiError,
93
93
  callControlAPI,
94
94
  callDataAPI
95
- } from "./cli-0xc5htv7.js";
95
+ } from "./cli-dmm9jm9m.js";
96
96
  import {
97
97
  AGENT_ERROR_CODES,
98
98
  EXIT_AUTH_REQUIRED,
@@ -129,7 +129,7 @@ import {
129
129
  shellArg,
130
130
  validateConfig,
131
131
  wasOutputCancelled
132
- } from "./cli-t0pb7qbs.js";
132
+ } from "./cli-e24fjyrb.js";
133
133
  import {
134
134
  CliAccessError,
135
135
  CliAuthError,
@@ -3248,46 +3248,46 @@ function leafManifestFields(leaf, commands) {
3248
3248
  import { fileURLToPath } from "url";
3249
3249
  import { realpathSync } from "fs";
3250
3250
  async function runPromptsCommand(...args) {
3251
- return (await import("./prompts-xe5bgbx8.js")).runPromptsCommand(...args);
3251
+ return (await import("./prompts-snnbyxmz.js")).runPromptsCommand(...args);
3252
3252
  }
3253
3253
  async function runSkillsCommand(...args) {
3254
- return (await import("./skills-vveagdwe.js")).runSkillsCommand(...args);
3254
+ return (await import("./skills-d4215fa9.js")).runSkillsCommand(...args);
3255
3255
  }
3256
3256
  async function runFixCommand(...args) {
3257
- return (await import("./fix-7aajsdbf.js")).runFixCommand(...args);
3257
+ return (await import("./fix-nk5xffz8.js")).runFixCommand(...args);
3258
3258
  }
3259
3259
  async function runFixesCommand(...args) {
3260
- return (await import("./fix-7aajsdbf.js")).runFixesCommand(...args);
3260
+ return (await import("./fix-nk5xffz8.js")).runFixesCommand(...args);
3261
3261
  }
3262
3262
  async function runHarnessCommand(...args) {
3263
- return (await import("./harness-1rn1hqzz.js")).runHarnessCommand(...args);
3263
+ return (await import("./harness-avynbq4f.js")).runHarnessCommand(...args);
3264
3264
  }
3265
3265
  async function runSyncCommand(...args) {
3266
- return (await import("./sync-yy3fgnxe.js")).runSyncCommand(...args);
3266
+ return (await import("./sync-17f9yxb1.js")).runSyncCommand(...args);
3267
3267
  }
3268
3268
  async function runRegistryCommand(...args) {
3269
- return (await import("./registry-j2dsfh6v.js")).runRegistryCommand(...args);
3269
+ return (await import("./registry-8zkxefjs.js")).runRegistryCommand(...args);
3270
3270
  }
3271
3271
  async function runDoctorCommand(...args) {
3272
- return (await import("./doctor-wrgajgev.js")).runDoctorCommand(...args);
3272
+ return (await import("./doctor-k4tdgvgv.js")).runDoctorCommand(...args);
3273
3273
  }
3274
3274
  async function runStatusCommand(...args) {
3275
- return (await import("./doctor-wrgajgev.js")).runStatusCommand(...args);
3275
+ return (await import("./doctor-k4tdgvgv.js")).runStatusCommand(...args);
3276
3276
  }
3277
3277
  async function runAuthCommand(...args) {
3278
- return (await import("./profile-commands-se9947c1.js")).runAuthCommand(...args);
3278
+ return (await import("./profile-commands-mh3kfqkn.js")).runAuthCommand(...args);
3279
3279
  }
3280
3280
  async function runConfigCommand(...args) {
3281
- return (await import("./profile-commands-se9947c1.js")).runConfigCommand(...args);
3281
+ return (await import("./profile-commands-mh3kfqkn.js")).runConfigCommand(...args);
3282
3282
  }
3283
3283
  async function runProfilesCommand(...args) {
3284
- return (await import("./profile-commands-se9947c1.js")).runProfilesCommand(...args);
3284
+ return (await import("./profile-commands-mh3kfqkn.js")).runProfilesCommand(...args);
3285
3285
  }
3286
3286
  async function runAgentCommand(...args) {
3287
- return (await import("./agent-x1gwrrvd.js")).runAgentCommand(...args);
3287
+ return (await import("./agent-5ax7fqhe.js")).runAgentCommand(...args);
3288
3288
  }
3289
3289
  async function runProductionCommand(...args) {
3290
- return (await import("./production-intelligence-7jvfdz6b.js")).runProductionCommand(...args);
3290
+ return (await import("./production-intelligence-0z6v6tpp.js")).runProductionCommand(...args);
3291
3291
  }
3292
3292
  function parseArgs(argv) {
3293
3293
  const args = argv.slice(2);
@@ -4578,6 +4578,13 @@ async function searchFallbackToTraces(params) {
4578
4578
  params.until ? `--until=${shellArg(params.until)}` : "",
4579
4579
  `--limit=${limit}`
4580
4580
  ].filter(Boolean).join(" ");
4581
+ if (params.mode === "keyword") {
4582
+ return {
4583
+ kind: "notice",
4584
+ warning: "Message-level keyword search returned 0 results. No trace-level search was run: `moda traces --search` ranks by relevance (its results may not contain the exact words), so it cannot answer --mode=keyword. " + (params.originalMessagesRead ? "The original messages in this window were also read for a literal match." : "Zero results here does NOT mean the words never appear; the message index may be incomplete."),
4585
+ nextCommands: [{ command: tracesCommand, purpose: "See relevance-ranked trace-level results (they may not contain the exact words).", mutability: "read", requires_approval: false }]
4586
+ };
4587
+ }
4581
4588
  let traces;
4582
4589
  try {
4583
4590
  traces = asRecord(await callDataAPI(`/conversations?${query2.toString()}`)) ?? {};
@@ -4597,13 +4604,6 @@ async function searchFallbackToTraces(params) {
4597
4604
  const serverHasMore = pagination?.has_more === true;
4598
4605
  const traceMode = asString(traces.search_mode) ?? "keyword";
4599
4606
  const literal = traceMode === "keyword";
4600
- if (params.mode === "keyword" && !literal) {
4601
- return {
4602
- kind: "notice",
4603
- warning: `Message-level keyword search returned 0 results. Trace-level search is only available ${traceMode}-ranked here (results may not contain the exact words), so none are substituted for --mode=keyword. Zero results here does NOT mean the words never appear; the message index may be incomplete.`,
4604
- nextCommands: [{ command: tracesCommand, purpose: "See ranked trace-level results instead.", mutability: "read", requires_approval: false }]
4605
- };
4606
- }
4607
4607
  const results = rows.map((row) => ({
4608
4608
  match_grain: "trace",
4609
4609
  conversation_id: row.conversation_id,
@@ -5950,7 +5950,11 @@ async function runCommand(command, positional, flags, positionals = positional ?
5950
5950
  warnings.push(`--offset=${params.offset} was not applied: message-level search is not pageable (it returns the top --limit hits). --offset only pages the trace-level fallback. Narrow with --time-range/--user-id or raise --limit instead.`);
5951
5951
  }
5952
5952
  if (results.length === 0 && !params.conversation_id) {
5953
- const fallback = await searchFallbackToTraces({ ...params, offset: params.offset });
5953
+ const fallback = await searchFallbackToTraces({
5954
+ ...params,
5955
+ offset: params.offset,
5956
+ originalMessagesRead: asRecord(searchRecord.coverage)?.original_messages_search === "used"
5957
+ });
5954
5958
  if (fallback?.kind === "notice") {
5955
5959
  warnings.push(fallback.warning);
5956
5960
  context.output.writeData(data, { warnings, nextCommands: fallback.nextCommands });
@@ -7057,7 +7061,7 @@ var commandRegistry = createCommandRegistry([
7057
7061
  resetApiRequestCountBeforeRun: true,
7058
7062
  telemetry: "result-and-error",
7059
7063
  handler: async (context) => {
7060
- const { runInit } = await import("./index-svfzq5rb.js");
7064
+ const { runInit } = await import("./index-63k2a6gb.js");
7061
7065
  if (context.outputMode === "agent-stream") {
7062
7066
  context.output.writeEvent({
7063
7067
  event: "started",
@@ -7107,7 +7111,7 @@ var commandRegistry = createCommandRegistry([
7107
7111
  resetApiRequestCountBeforeRun: true,
7108
7112
  telemetry: "result-and-error",
7109
7113
  handler: async (context) => {
7110
- const { runProvision } = await import("./provision-a9kkfvp7.js");
7114
+ const { runProvision } = await import("./provision-t1dpzcjp.js");
7111
7115
  return runProvision(context, {
7112
7116
  resumeCommand: buildResumeCommand("provision", context.rawFlags)
7113
7117
  });
@@ -3,16 +3,16 @@ import {
3
3
  promptsDiscoveredCheck,
4
4
  runDoctorCommand,
5
5
  runStatusCommand
6
- } from "./cli-h62j4jn7.js";
7
- import"./cli-pmzh2qjy.js";
8
- import"./cli-k5drmy8r.js";
6
+ } from "./cli-t4xfvrry.js";
7
+ import"./cli-sejqvvhv.js";
8
+ import"./cli-wwbr5caw.js";
9
9
  import"./cli-mm48br00.js";
10
10
  import"./cli-xq45etg1.js";
11
- import"./cli-5fhqfx04.js";
11
+ import"./cli-8pcq2et6.js";
12
12
  import"./cli-e0kbye4s.js";
13
- import"./cli-9a0a3v13.js";
14
- import"./cli-0xc5htv7.js";
15
- import"./cli-t0pb7qbs.js";
13
+ import"./cli-tztzrh6b.js";
14
+ import"./cli-dmm9jm9m.js";
15
+ import"./cli-e24fjyrb.js";
16
16
  import"./cli-k4tqwah4.js";
17
17
  import"./cli-9kfxkxmk.js";
18
18
  import"./cli-ns5fcnkz.js";
@@ -2,13 +2,13 @@ import {
2
2
  DEFAULT_POLL_INTERVAL_MS,
3
3
  DEFAULT_WAIT_TIMEOUT_MS,
4
4
  fetchLatestRun
5
- } from "./cli-daqkdnm1.js";
5
+ } from "./cli-4pc0a18x.js";
6
6
  import {
7
7
  assertFlags
8
- } from "./cli-9a0a3v13.js";
8
+ } from "./cli-tztzrh6b.js";
9
9
  import {
10
10
  callControlAPI
11
- } from "./cli-0xc5htv7.js";
11
+ } from "./cli-dmm9jm9m.js";
12
12
  import {
13
13
  EXIT_DEGRADED,
14
14
  EXIT_ERROR,
@@ -17,7 +17,7 @@ import {
17
17
  resolveApiTenantId,
18
18
  shellArg,
19
19
  validateConfig
20
- } from "./cli-t0pb7qbs.js";
20
+ } from "./cli-e24fjyrb.js";
21
21
  import {
22
22
  CliInputError
23
23
  } from "./cli-k4tqwah4.js";
@@ -40,18 +40,18 @@ import {
40
40
  writeHarnessAnalyzeResult,
41
41
  writeHarnessArtifacts,
42
42
  writeHumanProgress
43
- } from "./cli-s1w5phms.js";
43
+ } from "./cli-d4cdczhe.js";
44
44
  import"./cli-xq45etg1.js";
45
45
  import"./cli-97fnztpy.js";
46
46
  import {
47
47
  HARNESS_ANALYZE_CONCERNS
48
48
  } from "./cli-cesds766.js";
49
49
  import"./cli-qpq84eee.js";
50
- import"./cli-5fhqfx04.js";
50
+ import"./cli-8pcq2et6.js";
51
51
  import"./cli-e0kbye4s.js";
52
- import"./cli-9a0a3v13.js";
53
- import"./cli-0xc5htv7.js";
54
- import"./cli-t0pb7qbs.js";
52
+ import"./cli-tztzrh6b.js";
53
+ import"./cli-dmm9jm9m.js";
54
+ import"./cli-e24fjyrb.js";
55
55
  import"./cli-k4tqwah4.js";
56
56
  import"./cli-9kfxkxmk.js";
57
57
  import"./cli-ns5fcnkz.js";
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  buildSourceSnapshot
3
- } from "./cli-s1w5phms.js";
3
+ } from "./cli-d4cdczhe.js";
4
4
  import"./cli-xq45etg1.js";
5
5
  import"./cli-97fnztpy.js";
6
6
  import"./cli-cesds766.js";
7
7
  import"./cli-qpq84eee.js";
8
- import"./cli-5fhqfx04.js";
8
+ import"./cli-8pcq2et6.js";
9
9
  import"./cli-e0kbye4s.js";
10
- import"./cli-9a0a3v13.js";
11
- import"./cli-0xc5htv7.js";
10
+ import"./cli-tztzrh6b.js";
11
+ import"./cli-dmm9jm9m.js";
12
12
  import {
13
13
  recordApiRequest
14
- } from "./cli-t0pb7qbs.js";
14
+ } from "./cli-e24fjyrb.js";
15
15
  import"./cli-k4tqwah4.js";
16
16
  import"./cli-9kfxkxmk.js";
17
17
  import"./cli-ns5fcnkz.js";
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  buildDoctorReport
3
- } from "./cli-h62j4jn7.js";
3
+ } from "./cli-t4xfvrry.js";
4
4
  import {
5
5
  selectTenantAndCreateKey
6
- } from "./cli-1z1sx8dg.js";
7
- import"./cli-77ekrx7d.js";
6
+ } from "./cli-5aa48ry5.js";
7
+ import"./cli-xcpwp0gb.js";
8
8
  import {
9
9
  ConnectCodeError,
10
10
  connectWithCode,
11
11
  loadAuthSession,
12
12
  loadToken,
13
13
  login
14
- } from "./cli-pmzh2qjy.js";
14
+ } from "./cli-sejqvvhv.js";
15
15
  import {
16
16
  bundledSkillsDir,
17
17
  installIntegrationSkill,
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  agentsMdProblem,
22
22
  runSkillSync
23
- } from "./cli-stfpr2ct.js";
23
+ } from "./cli-xx0pjzkh.js";
24
24
  import"./cli-qm5b1vck.js";
25
25
  import {
26
26
  detectAgents
@@ -32,7 +32,7 @@ import {
32
32
  import {
33
33
  initPrompts,
34
34
  runPromptSync
35
- } from "./cli-k5drmy8r.js";
35
+ } from "./cli-wwbr5caw.js";
36
36
  import"./cli-mm48br00.js";
37
37
  import {
38
38
  codingAgentDisplayName,
@@ -46,7 +46,7 @@ import {
46
46
  runCodingAgent,
47
47
  runHarnessCommand,
48
48
  startRemoteAnalyze
49
- } from "./cli-s1w5phms.js";
49
+ } from "./cli-d4cdczhe.js";
50
50
  import {
51
51
  canonicalText,
52
52
  renderInitBanner,
@@ -62,17 +62,17 @@ import"./cli-cesds766.js";
62
62
  import"./cli-qpq84eee.js";
63
63
  import {
64
64
  createCommandContext
65
- } from "./cli-5fhqfx04.js";
65
+ } from "./cli-8pcq2et6.js";
66
66
  import"./cli-e0kbye4s.js";
67
- import"./cli-9a0a3v13.js";
68
- import"./cli-0xc5htv7.js";
67
+ import"./cli-tztzrh6b.js";
68
+ import"./cli-dmm9jm9m.js";
69
69
  import {
70
70
  VERSION,
71
71
  recordApiRequest,
72
72
  resolveIngestUrl,
73
73
  resolveModaBaseUrl,
74
74
  shellArg
75
- } from "./cli-t0pb7qbs.js";
75
+ } from "./cli-e24fjyrb.js";
76
76
  import {
77
77
  CliAuthError,
78
78
  CliInputError
@@ -10,7 +10,7 @@ import {
10
10
  overviewTrendsQuery,
11
11
  renderTrendsHuman,
12
12
  trendsSummaryText
13
- } from "./cli-5y9tj6cb.js";
13
+ } from "./cli-4m0rgkx4.js";
14
14
  import {
15
15
  renderMarkdownForTerminal,
16
16
  shouldColorTerminalOutput,
@@ -21,7 +21,7 @@ import"./cli-e0kbye4s.js";
21
21
  import {
22
22
  callControlAPI,
23
23
  callDataAPI
24
- } from "./cli-0xc5htv7.js";
24
+ } from "./cli-dmm9jm9m.js";
25
25
  import {
26
26
  EXIT_DEGRADED,
27
27
  EXIT_OK,
@@ -31,7 +31,7 @@ import {
31
31
  resolveModaBaseUrl,
32
32
  safeWriteStderr,
33
33
  shellArg
34
- } from "./cli-t0pb7qbs.js";
34
+ } from "./cli-e24fjyrb.js";
35
35
  import {
36
36
  CliAuthError,
37
37
  CliInputError,
@@ -1271,6 +1271,7 @@ function coerceIntelligenceV1(record, context) {
1271
1271
  const nextCommands = Array.isArray(record.next_commands) ? record.next_commands.flatMap(coerceV1NextCommand) : [];
1272
1272
  const warnings = stringArray(record.warnings);
1273
1273
  const meta = asRecord(record.meta);
1274
+ const caveats = asRecord(record.caveats);
1274
1275
  return {
1275
1276
  schema_version: INTELLIGENCE_SCHEMA_VERSION,
1276
1277
  generated_at: asString(record.generated_at) ?? new Date().toISOString(),
@@ -1285,6 +1286,7 @@ function coerceIntelligenceV1(record, context) {
1285
1286
  evidence_refs: evidenceRefs,
1286
1287
  next_commands: nextCommands,
1287
1288
  warnings,
1289
+ ...caveats?.version === "moda.caveats.v1" ? { caveats } : {},
1288
1290
  ...meta ? { meta } : {}
1289
1291
  };
1290
1292
  }
@@ -2,7 +2,7 @@ import {
2
2
  probeApiKey,
3
3
  redactApiKey,
4
4
  resolveApiKeyCredential
5
- } from "./cli-77ekrx7d.js";
5
+ } from "./cli-xcpwp0gb.js";
6
6
  import {
7
7
  authFetch,
8
8
  clearAuthSession,
@@ -10,20 +10,29 @@ import {
10
10
  loadAuthSession,
11
11
  login,
12
12
  revokeCliSessionToken
13
- } from "./cli-pmzh2qjy.js";
13
+ } from "./cli-sejqvvhv.js";
14
+ import {
15
+ ApiError
16
+ } from "./cli-dmm9jm9m.js";
14
17
  import {
15
18
  DEFAULT_INGEST_URL,
16
19
  EXIT_AUTH_REQUIRED,
17
20
  EXIT_DEGRADED,
18
21
  EXIT_OK,
19
22
  PROD_BASE_URL,
23
+ apiForbiddenError,
24
+ apiForbiddenReason,
20
25
  clearStoredApiKeyCredentials,
21
26
  describeBaseUrlSource,
27
+ describeModaBaseUrl,
22
28
  embeddedTenantIdFromApiKey,
23
29
  ensureSecretFilePermissions,
30
+ errorBodyFields,
24
31
  getActiveProfile,
25
32
  getModaPaths,
26
33
  loadProfileConfig,
34
+ recordApiRequest,
35
+ refusedBaseUrlMessage,
27
36
  resolveApiKey,
28
37
  resolveApiKeyFromActiveProfile,
29
38
  resolveApiTenantId,
@@ -35,7 +44,7 @@ import {
35
44
  setActiveProfile,
36
45
  shellArg,
37
46
  upsertProfile
38
- } from "./cli-t0pb7qbs.js";
47
+ } from "./cli-e24fjyrb.js";
39
48
  import {
40
49
  CliInputError
41
50
  } from "./cli-k4tqwah4.js";
@@ -44,6 +53,30 @@ import"./cli-0v6na3yp.js";
44
53
 
45
54
  // src/profile-commands.ts
46
55
  var ONLINE_PROBE_TIMEOUT_MS = 5000;
56
+ function forbiddenProbeError(probe) {
57
+ if (probe.status !== 403)
58
+ return;
59
+ const fields = errorBodyFields(probe.body);
60
+ const reason = apiForbiddenReason(fields.code, fields.message);
61
+ if (!reason || reason === "read_only_key")
62
+ return;
63
+ return new ApiError(`API error (403): ${fields.message ?? "forbidden"}`, 403, probe.body ?? "");
64
+ }
65
+ async function probeDataApiReachable(baseUrl) {
66
+ try {
67
+ recordApiRequest();
68
+ const response = await fetch(`${baseUrl}/api/v1/data/whoami`, {
69
+ method: "GET",
70
+ signal: AbortSignal.timeout(ONLINE_PROBE_TIMEOUT_MS)
71
+ });
72
+ await response.body?.cancel().catch(() => {
73
+ return;
74
+ });
75
+ return { reachable: true, status: response.status, ok: false, error: "no API key to verify" };
76
+ } catch (error) {
77
+ return { reachable: false, ok: false, error: error instanceof Error ? error.message : String(error) };
78
+ }
79
+ }
47
80
  function subcommand(context) {
48
81
  return context.positionals[0];
49
82
  }
@@ -131,6 +164,9 @@ async function loginWithApiKey(context, candidate) {
131
164
  const authOptions = { profile: context.profile, env: context.env };
132
165
  const probe = await probeApiKey(key, authOptions);
133
166
  if (probe.outcome === "rejected") {
167
+ const forbidden = forbiddenProbeError(probe);
168
+ if (forbidden)
169
+ throw forbidden;
134
170
  throw new CliInputError(`API key rejected by the Moda API (HTTP ${probe.status}).`, 'The key is revoked, malformed, or belongs to another environment. Mint a new one with "moda provision --tenant-id=<org-id>", or check MODA_BASE_URL points at the right environment.');
135
171
  }
136
172
  if (probe.outcome === "unreachable") {
@@ -205,6 +241,9 @@ async function runAuthCommand(context) {
205
241
  env: context.env
206
242
  });
207
243
  if (probe.outcome === "rejected") {
244
+ const forbidden = forbiddenProbeError(probe);
245
+ if (forbidden)
246
+ throw forbidden;
208
247
  throw new CliInputError(`API key rejected by the Moda API (HTTP ${probe.status}).`, 'The key is revoked or belongs to another environment. Mint a new one with "moda provision --tenant-id=<org-id>", or run "moda auth login".');
209
248
  }
210
249
  context.output.writeData({
@@ -260,28 +299,67 @@ async function runAuthCommand(context) {
260
299
  if (session?.user_email) {
261
300
  data.user = { email: session.user_email };
262
301
  }
302
+ const warnings = [];
263
303
  if (boolFlag(context, "online")) {
264
- let online = { reachable: false };
265
- try {
266
- const response = await authFetch("/api/cli/context", { signal: AbortSignal.timeout(ONLINE_PROBE_TIMEOUT_MS) }, authOptions);
267
- online = { reachable: true, ok: response.ok };
268
- if (response.ok) {
269
- const body = await response.json();
270
- if (Array.isArray(body.tenants)) {
271
- online.tenantCount = body.tenants.length;
304
+ const baseUrl = resolveModaBaseUrl(authOptions);
305
+ let sessionProbe;
306
+ let tenantCount;
307
+ if (session) {
308
+ sessionProbe = { reachable: false, ok: false };
309
+ try {
310
+ const response = await authFetch("/api/cli/context", { signal: AbortSignal.timeout(ONLINE_PROBE_TIMEOUT_MS) }, authOptions);
311
+ sessionProbe = { reachable: true, status: response.status, ok: response.ok };
312
+ if (response.ok) {
313
+ const body = await response.json();
314
+ if (Array.isArray(body.tenants))
315
+ tenantCount = body.tenants.length;
272
316
  }
273
- }
274
- } catch {}
275
- data.online = online;
317
+ } catch {}
318
+ }
319
+ let dataApi;
276
320
  if (credential && data.apiKeyCredential.present) {
277
321
  const probe = await probeApiKey(credential.key, authOptions);
278
322
  data.apiKeyCredential.verified = probe.outcome === "live";
279
- if (probe.outcome === "rejected") {
280
- data.authenticated = loggedIn;
323
+ if (probe.outcome === "live") {
324
+ const identity = probe.identity;
325
+ dataApi = {
326
+ reachable: true,
327
+ status: 200,
328
+ ok: true,
329
+ ...typeof identity?.tenant_id === "string" ? { tenantId: identity.tenant_id } : {},
330
+ ...identity && "tenant_name" in identity ? { tenantName: typeof identity.tenant_name === "string" ? identity.tenant_name : null } : {},
331
+ ...typeof identity?.key_kind === "string" ? { keyKind: identity.key_kind } : {},
332
+ ...typeof identity?.scope === "string" ? { scope: identity.scope } : {}
333
+ };
334
+ } else if (probe.outcome === "rejected") {
335
+ const fields = errorBodyFields(probe.body);
336
+ dataApi = { reachable: true, status: probe.status, ok: false, error: fields.message ?? `HTTP ${probe.status}` };
337
+ const reason = apiForbiddenReason(fields.code, fields.message);
338
+ if (reason && reason !== "read_only_key") {
339
+ const described = apiForbiddenError(reason, fields.message);
340
+ warnings.push(`${described.message} ${described.cause}`);
341
+ } else {
342
+ data.authenticated = loggedIn;
343
+ }
344
+ } else {
345
+ dataApi = { reachable: probe.status !== undefined, ...probe.status !== undefined ? { status: probe.status } : {}, ok: false, error: probe.reason };
281
346
  }
347
+ } else {
348
+ dataApi = await probeDataApiReachable(baseUrl);
349
+ }
350
+ data.online = {
351
+ baseUrl,
352
+ reachable: dataApi.reachable || sessionProbe?.reachable === true,
353
+ ok: (credential ? dataApi.ok : true) && (sessionProbe ? sessionProbe.ok : true) && Boolean(credential || sessionProbe),
354
+ ...tenantCount !== undefined ? { tenantCount } : {},
355
+ ...sessionProbe ? { session: sessionProbe } : {},
356
+ dataApi
357
+ };
358
+ if (sessionProbe?.status === 404 && dataApi.reachable) {
359
+ warnings.push(`${baseUrl} answers the Data API but has no /api/cli/context, so it looks like the backend. ` + "Data commands work against it; browser login and control-plane commands need the frontend URL (http://localhost:3000 locally).");
282
360
  }
283
361
  }
284
- context.output.writeData(data);
362
+ context.output.writeData(data, warnings.length > 0 ? { warnings } : undefined);
285
363
  return { exitCode: data.authenticated ? EXIT_OK : EXIT_AUTH_REQUIRED };
286
364
  }
287
365
  case "token": {
@@ -417,7 +495,7 @@ async function runConfigCommand(context) {
417
495
  const options = { profile: profile.name, env: context.env };
418
496
  const envProfile = context.env.MODA_PROFILE?.trim();
419
497
  const apiKey = resolveApiKey(options);
420
- const baseUrl = resolveModaBaseUrl(options);
498
+ const base = describeModaBaseUrl(options);
421
499
  context.output.writeData({
422
500
  moda_dir: getModaPaths({ env: context.env }).dir,
423
501
  active_profile: profile.name,
@@ -427,14 +505,14 @@ async function runConfigCommand(context) {
427
505
  resolved: {
428
506
  api_key: redactSecret(apiKey),
429
507
  api_key_source: context.env.MODA_API_KEY ? "env:MODA_API_KEY" : profile.api_key_ref === "legacy:config.api_key" && apiKey ? "legacy_config" : resolveApiKeyFromActiveProfile(options) ? "profile" : apiKey ? "legacy_config" : "none",
430
- base_url: baseUrl,
508
+ base_url: base.refused ? null : base.url,
431
509
  base_url_source: describeBaseUrlSource(options),
432
510
  ingest_url: resolveIngestUrl(options),
433
511
  tenant_id: resolveApiTenantId(options),
434
512
  workspace_id: profile.workspace_id
435
513
  },
436
514
  migrations: config.migrations
437
- });
515
+ }, base.refused ? { warnings: [`${refusedBaseUrlMessage(base.refused)} Data commands exit 5 until you re-run with --profile=local or unset MODA_BASE_URL.`] } : undefined);
438
516
  return { exitCode: 0 };
439
517
  }
440
518
  export {