@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.
- package/README.md +1 -1
- package/dist/{agent-x1gwrrvd.js → agent-5ax7fqhe.js} +8 -8
- package/dist/{cli-5y9tj6cb.js → cli-4m0rgkx4.js} +7 -2
- package/dist/{cli-daqkdnm1.js → cli-4pc0a18x.js} +1 -1
- package/dist/{cli-1z1sx8dg.js → cli-5aa48ry5.js} +5 -4
- package/dist/{cli-5fhqfx04.js → cli-8pcq2et6.js} +1 -1
- package/dist/{cli-fpd1pfvt.js → cli-8pksf2x7.js} +5 -5
- package/dist/{cli-s1w5phms.js → cli-d4cdczhe.js} +5 -5
- package/dist/{cli-0xc5htv7.js → cli-dmm9jm9m.js} +1 -1
- package/dist/{cli-t0pb7qbs.js → cli-e24fjyrb.js} +118 -10
- package/dist/{cli-pmzh2qjy.js → cli-sejqvvhv.js} +14 -6
- package/dist/{cli-h62j4jn7.js → cli-t4xfvrry.js} +34 -15
- package/dist/{cli-9a0a3v13.js → cli-tztzrh6b.js} +2 -2
- package/dist/{cli-k5drmy8r.js → cli-wwbr5caw.js} +8 -8
- package/dist/{cli-77ekrx7d.js → cli-xcpwp0gb.js} +14 -7
- package/dist/{cli-stfpr2ct.js → cli-xx0pjzkh.js} +4 -4
- package/dist/cli.js +33 -29
- package/dist/{doctor-wrgajgev.js → doctor-k4tdgvgv.js} +7 -7
- package/dist/{fix-7aajsdbf.js → fix-nk5xffz8.js} +4 -4
- package/dist/{harness-1rn1hqzz.js → harness-avynbq4f.js} +5 -5
- package/dist/{harness-github-actions-m95qvgbs.js → harness-github-actions-gd6vyxb0.js} +5 -5
- package/dist/{index-svfzq5rb.js → index-63k2a6gb.js} +11 -11
- package/dist/{production-intelligence-7jvfdz6b.js → production-intelligence-0z6v6tpp.js} +5 -3
- package/dist/{profile-commands-se9947c1.js → profile-commands-mh3kfqkn.js} +98 -20
- package/dist/{prompt-attribution-hc6mcvee.js → prompt-attribution-wvvnzw4m.js} +5 -5
- package/dist/prompt-source-mcp.js +5 -5
- package/dist/{prompts-ab-ws66335h.js → prompts-ab-y7egdzg4.js} +7 -7
- package/dist/{prompts-propose-a9m0p9nr.js → prompts-propose-5nw25v9a.js} +7 -7
- package/dist/{prompts-xe5bgbx8.js → prompts-snnbyxmz.js} +5 -5
- package/dist/{provision-a9kkfvp7.js → provision-t1dpzcjp.js} +5 -5
- package/dist/{registry-j2dsfh6v.js → registry-8zkxefjs.js} +3 -3
- package/dist/{skills-vveagdwe.js → skills-d4215fa9.js} +5 -5
- package/dist/{sync-yy3fgnxe.js → sync-17f9yxb1.js} +7 -7
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +4 -3
- package/skills/moda-cli/references/auth.md +16 -7
- package/skills/moda-cli/references/output-protocol.md +1 -1
- package/skills/moda-cli/references/search-and-traces.md +3 -1
- 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-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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-
|
|
16
|
+
} from "./cli-8pcq2et6.js";
|
|
17
17
|
import {
|
|
18
18
|
assertFlags,
|
|
19
19
|
assertPositionals,
|
|
20
20
|
writeDryRun
|
|
21
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-tztzrh6b.js";
|
|
22
22
|
import {
|
|
23
23
|
callControlAPI
|
|
24
|
-
} from "./cli-
|
|
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-
|
|
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-
|
|
29
|
+
} from "./cli-4m0rgkx4.js";
|
|
30
30
|
import {
|
|
31
31
|
createCommandContext
|
|
32
|
-
} from "./cli-
|
|
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-
|
|
90
|
+
} from "./cli-tztzrh6b.js";
|
|
91
91
|
import {
|
|
92
92
|
ApiError,
|
|
93
93
|
callControlAPI,
|
|
94
94
|
callDataAPI
|
|
95
|
-
} from "./cli-
|
|
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-
|
|
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-
|
|
3251
|
+
return (await import("./prompts-snnbyxmz.js")).runPromptsCommand(...args);
|
|
3252
3252
|
}
|
|
3253
3253
|
async function runSkillsCommand(...args) {
|
|
3254
|
-
return (await import("./skills-
|
|
3254
|
+
return (await import("./skills-d4215fa9.js")).runSkillsCommand(...args);
|
|
3255
3255
|
}
|
|
3256
3256
|
async function runFixCommand(...args) {
|
|
3257
|
-
return (await import("./fix-
|
|
3257
|
+
return (await import("./fix-nk5xffz8.js")).runFixCommand(...args);
|
|
3258
3258
|
}
|
|
3259
3259
|
async function runFixesCommand(...args) {
|
|
3260
|
-
return (await import("./fix-
|
|
3260
|
+
return (await import("./fix-nk5xffz8.js")).runFixesCommand(...args);
|
|
3261
3261
|
}
|
|
3262
3262
|
async function runHarnessCommand(...args) {
|
|
3263
|
-
return (await import("./harness-
|
|
3263
|
+
return (await import("./harness-avynbq4f.js")).runHarnessCommand(...args);
|
|
3264
3264
|
}
|
|
3265
3265
|
async function runSyncCommand(...args) {
|
|
3266
|
-
return (await import("./sync-
|
|
3266
|
+
return (await import("./sync-17f9yxb1.js")).runSyncCommand(...args);
|
|
3267
3267
|
}
|
|
3268
3268
|
async function runRegistryCommand(...args) {
|
|
3269
|
-
return (await import("./registry-
|
|
3269
|
+
return (await import("./registry-8zkxefjs.js")).runRegistryCommand(...args);
|
|
3270
3270
|
}
|
|
3271
3271
|
async function runDoctorCommand(...args) {
|
|
3272
|
-
return (await import("./doctor-
|
|
3272
|
+
return (await import("./doctor-k4tdgvgv.js")).runDoctorCommand(...args);
|
|
3273
3273
|
}
|
|
3274
3274
|
async function runStatusCommand(...args) {
|
|
3275
|
-
return (await import("./doctor-
|
|
3275
|
+
return (await import("./doctor-k4tdgvgv.js")).runStatusCommand(...args);
|
|
3276
3276
|
}
|
|
3277
3277
|
async function runAuthCommand(...args) {
|
|
3278
|
-
return (await import("./profile-commands-
|
|
3278
|
+
return (await import("./profile-commands-mh3kfqkn.js")).runAuthCommand(...args);
|
|
3279
3279
|
}
|
|
3280
3280
|
async function runConfigCommand(...args) {
|
|
3281
|
-
return (await import("./profile-commands-
|
|
3281
|
+
return (await import("./profile-commands-mh3kfqkn.js")).runConfigCommand(...args);
|
|
3282
3282
|
}
|
|
3283
3283
|
async function runProfilesCommand(...args) {
|
|
3284
|
-
return (await import("./profile-commands-
|
|
3284
|
+
return (await import("./profile-commands-mh3kfqkn.js")).runProfilesCommand(...args);
|
|
3285
3285
|
}
|
|
3286
3286
|
async function runAgentCommand(...args) {
|
|
3287
|
-
return (await import("./agent-
|
|
3287
|
+
return (await import("./agent-5ax7fqhe.js")).runAgentCommand(...args);
|
|
3288
3288
|
}
|
|
3289
3289
|
async function runProductionCommand(...args) {
|
|
3290
|
-
return (await import("./production-intelligence-
|
|
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({
|
|
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-
|
|
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-
|
|
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-
|
|
7
|
-
import"./cli-
|
|
8
|
-
import"./cli-
|
|
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-
|
|
11
|
+
import"./cli-8pcq2et6.js";
|
|
12
12
|
import"./cli-e0kbye4s.js";
|
|
13
|
-
import"./cli-
|
|
14
|
-
import"./cli-
|
|
15
|
-
import"./cli-
|
|
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-
|
|
5
|
+
} from "./cli-4pc0a18x.js";
|
|
6
6
|
import {
|
|
7
7
|
assertFlags
|
|
8
|
-
} from "./cli-
|
|
8
|
+
} from "./cli-tztzrh6b.js";
|
|
9
9
|
import {
|
|
10
10
|
callControlAPI
|
|
11
|
-
} from "./cli-
|
|
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-
|
|
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-
|
|
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-
|
|
50
|
+
import"./cli-8pcq2et6.js";
|
|
51
51
|
import"./cli-e0kbye4s.js";
|
|
52
|
-
import"./cli-
|
|
53
|
-
import"./cli-
|
|
54
|
-
import"./cli-
|
|
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-
|
|
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-
|
|
8
|
+
import"./cli-8pcq2et6.js";
|
|
9
9
|
import"./cli-e0kbye4s.js";
|
|
10
|
-
import"./cli-
|
|
11
|
-
import"./cli-
|
|
10
|
+
import"./cli-tztzrh6b.js";
|
|
11
|
+
import"./cli-dmm9jm9m.js";
|
|
12
12
|
import {
|
|
13
13
|
recordApiRequest
|
|
14
|
-
} from "./cli-
|
|
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-
|
|
3
|
+
} from "./cli-t4xfvrry.js";
|
|
4
4
|
import {
|
|
5
5
|
selectTenantAndCreateKey
|
|
6
|
-
} from "./cli-
|
|
7
|
-
import"./cli-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
65
|
+
} from "./cli-8pcq2et6.js";
|
|
66
66
|
import"./cli-e0kbye4s.js";
|
|
67
|
-
import"./cli-
|
|
68
|
-
import"./cli-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
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
|
-
}
|
|
275
|
-
|
|
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 === "
|
|
280
|
-
|
|
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
|
|
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:
|
|
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 {
|