@moda-ai/cli 1.55.4 → 1.55.5
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 +7 -0
- package/dist/{cli-73v8mqh1.js → cli-dw1zrtvn.js} +41 -31
- package/dist/{cli-9v0c1xe1.js → cli-tzqez7mw.js} +36 -19
- package/dist/{cli-9kyw5qx0.js → cli-vxdtfys2.js} +4 -2
- package/dist/{cli-zp7a97sp.js → cli-xtj2m4hs.js} +29 -1
- package/dist/{cli-t5v7mhvj.js → cli-zbpetb7v.js} +6 -1
- package/dist/cli.js +216 -64
- package/dist/{harness-github-actions-5syjp1sz.js → harness-github-actions-f3xffdf7.js} +8 -2
- package/dist/{harness-x6kaz47j.js → harness-sqkgk49d.js} +2 -2
- package/dist/{index-8vvznb36.js → index-025z9q34.js} +8 -5
- package/dist/prompt-source-mcp.js +2 -2
- package/dist/{provision-2z73642d.js → provision-69h38y7d.js} +3 -3
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/skills/moda-cli/SKILL.md +12 -7
package/dist/cli.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
runPromptsCommand,
|
|
9
9
|
runSkillsCommand,
|
|
10
10
|
runStatusCommand
|
|
11
|
-
} from "./cli-
|
|
11
|
+
} from "./cli-dw1zrtvn.js";
|
|
12
12
|
import"./cli-mm48br00.js";
|
|
13
13
|
import {
|
|
14
14
|
ApiError,
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
assertPositionals,
|
|
21
21
|
callControlAPI,
|
|
22
22
|
callDataAPI,
|
|
23
|
-
getApiRequestCount,
|
|
24
23
|
graphForSync,
|
|
25
24
|
hashHarnessReport,
|
|
26
25
|
hashStableJson,
|
|
@@ -28,7 +27,6 @@ import {
|
|
|
28
27
|
readHarnessReport,
|
|
29
28
|
readHarnessSyncState,
|
|
30
29
|
renderMarkdownForTerminal,
|
|
31
|
-
resetApiRequestCount,
|
|
32
30
|
runHarnessCommand,
|
|
33
31
|
runProblemReopenCommand,
|
|
34
32
|
runSignalsManagementCommand,
|
|
@@ -41,7 +39,7 @@ import {
|
|
|
41
39
|
terminalStyles,
|
|
42
40
|
unknownSignalsSubcommandError,
|
|
43
41
|
validateHarnessReport
|
|
44
|
-
} from "./cli-
|
|
42
|
+
} from "./cli-tzqez7mw.js";
|
|
45
43
|
import"./cli-ssfq84k5.js";
|
|
46
44
|
import {
|
|
47
45
|
authFetch,
|
|
@@ -50,7 +48,7 @@ import {
|
|
|
50
48
|
loadAuthSession,
|
|
51
49
|
login,
|
|
52
50
|
revokeCliSessionToken
|
|
53
|
-
} from "./cli-
|
|
51
|
+
} from "./cli-zbpetb7v.js";
|
|
54
52
|
import {
|
|
55
53
|
AGENT_ERROR_CODES,
|
|
56
54
|
CliAccessError,
|
|
@@ -79,11 +77,15 @@ import {
|
|
|
79
77
|
ensureSecretFilePermissions,
|
|
80
78
|
explicitOutputMode,
|
|
81
79
|
getActiveProfile,
|
|
80
|
+
getApiRequestCount,
|
|
82
81
|
getModaDir,
|
|
83
82
|
getModaPaths,
|
|
84
83
|
isApiLikeError,
|
|
85
84
|
isNetworkLikeError,
|
|
86
85
|
loadProfileConfig,
|
|
86
|
+
parseBooleanFlagValue,
|
|
87
|
+
recordApiRequest,
|
|
88
|
+
resetApiRequestCount,
|
|
87
89
|
resolveApiKey,
|
|
88
90
|
resolveApiKeyFromActiveProfile,
|
|
89
91
|
resolveApiTenantId,
|
|
@@ -101,7 +103,7 @@ import {
|
|
|
101
103
|
validateConfig,
|
|
102
104
|
wasOutputCancelled,
|
|
103
105
|
writeSecretJsonFile
|
|
104
|
-
} from "./cli-
|
|
106
|
+
} from "./cli-xtj2m4hs.js";
|
|
105
107
|
import {
|
|
106
108
|
__require
|
|
107
109
|
} from "./cli-0v6na3yp.js";
|
|
@@ -112,9 +114,21 @@ import { z as z2 } from "zod";
|
|
|
112
114
|
|
|
113
115
|
// src/schemas.ts
|
|
114
116
|
import { z } from "zod";
|
|
115
|
-
var boolFlag = () => z.preprocess((val) =>
|
|
117
|
+
var boolFlag = () => z.preprocess((val) => {
|
|
118
|
+
const text = String(val).toLowerCase();
|
|
119
|
+
if (["true", "1", "yes", "on"].includes(text))
|
|
120
|
+
return true;
|
|
121
|
+
if (["false", "0", "no", "off"].includes(text))
|
|
122
|
+
return false;
|
|
123
|
+
return val;
|
|
124
|
+
}, z.boolean()).optional();
|
|
125
|
+
var DAYS_BACK_MESSAGE = "must be a whole number from 1 to 90 (e.g. --days-back=7)";
|
|
126
|
+
var daysBackFlag = (fallback) => {
|
|
127
|
+
const days = z.number({ invalid_type_error: DAYS_BACK_MESSAGE }).int(DAYS_BACK_MESSAGE).min(1, DAYS_BACK_MESSAGE).max(90, DAYS_BACK_MESSAGE);
|
|
128
|
+
return fallback === undefined ? days.optional() : days.default(fallback).optional();
|
|
129
|
+
};
|
|
116
130
|
var OverviewSchema = z.object({
|
|
117
|
-
days_back:
|
|
131
|
+
days_back: daysBackFlag(7)
|
|
118
132
|
});
|
|
119
133
|
var ClustersSchema = z.object({
|
|
120
134
|
parent_id: z.string().optional(),
|
|
@@ -154,25 +168,17 @@ var WorldStateSchema = z.object({
|
|
|
154
168
|
format: z.enum(["frames", "fold-inputs"]).optional(),
|
|
155
169
|
message_count: z.number().min(1).max(1e6).optional()
|
|
156
170
|
});
|
|
157
|
-
var lenientBoolFlag = () => z.preprocess((val) => {
|
|
158
|
-
const text = String(val).toLowerCase();
|
|
159
|
-
if (["true", "1", "yes", "on"].includes(text))
|
|
160
|
-
return true;
|
|
161
|
-
if (["false", "0", "no", "off"].includes(text))
|
|
162
|
-
return false;
|
|
163
|
-
return val;
|
|
164
|
-
}, z.boolean()).optional();
|
|
165
171
|
var ContextSchema = z.object({
|
|
166
172
|
conversation_id: z.string().min(1),
|
|
167
173
|
msg_index: z.number().int().min(0).optional(),
|
|
168
174
|
window: z.number().int().min(0).optional(),
|
|
169
|
-
metadata_only:
|
|
170
|
-
all:
|
|
175
|
+
metadata_only: boolFlag(),
|
|
176
|
+
all: boolFlag(),
|
|
171
177
|
from: z.number().int().min(0).optional(),
|
|
172
178
|
max_messages: z.number().int().min(1).max(5000).optional()
|
|
173
179
|
});
|
|
174
180
|
var FrustrationsSchema = z.object({
|
|
175
|
-
days_back:
|
|
181
|
+
days_back: daysBackFlag(7),
|
|
176
182
|
limit: z.number().min(1).max(20).default(10).optional(),
|
|
177
183
|
offset: z.number().min(0).default(0).optional(),
|
|
178
184
|
include_window: boolFlag(),
|
|
@@ -181,10 +187,10 @@ var FrustrationsSchema = z.object({
|
|
|
181
187
|
conversation_id: z.string().min(1).max(256).optional()
|
|
182
188
|
});
|
|
183
189
|
var ToolFailuresSchema = z.object({
|
|
184
|
-
days_back:
|
|
190
|
+
days_back: daysBackFlag(7)
|
|
185
191
|
});
|
|
186
192
|
var ProblemsSchema = z.object({
|
|
187
|
-
days_back:
|
|
193
|
+
days_back: daysBackFlag(30),
|
|
188
194
|
limit: z.number().min(1).max(25).default(25).optional()
|
|
189
195
|
});
|
|
190
196
|
var REMAINDER_FAMILIES = [
|
|
@@ -197,7 +203,7 @@ var REMAINDER_FAMILIES = [
|
|
|
197
203
|
"conversation_reader"
|
|
198
204
|
];
|
|
199
205
|
var ProblemsRemainderSchema = z.object({
|
|
200
|
-
days_back:
|
|
206
|
+
days_back: daysBackFlag(30),
|
|
201
207
|
limit: z.number().min(1).max(25).default(25).optional(),
|
|
202
208
|
family: z.enum(REMAINDER_FAMILIES).optional(),
|
|
203
209
|
cursor: z.string().min(1).max(4096).optional()
|
|
@@ -264,7 +270,7 @@ var ProblemLinearFileSchema = z.object({
|
|
|
264
270
|
var SignalSchema = z.object({
|
|
265
271
|
id: z.string().min(1).max(255),
|
|
266
272
|
detections: boolFlag(),
|
|
267
|
-
days_back:
|
|
273
|
+
days_back: daysBackFlag(),
|
|
268
274
|
limit: z.number().min(1).max(20).optional(),
|
|
269
275
|
offset: z.number().min(0).max(1e4).optional()
|
|
270
276
|
});
|
|
@@ -335,7 +341,7 @@ var EMOTION_FAMILIES = [
|
|
|
335
341
|
"positive"
|
|
336
342
|
];
|
|
337
343
|
var EmotionsSchema = z.object({
|
|
338
|
-
days_back:
|
|
344
|
+
days_back: daysBackFlag(7),
|
|
339
345
|
limit: z.number().min(1).max(20).default(10).optional(),
|
|
340
346
|
offset: z.number().min(0).max(1e4).optional(),
|
|
341
347
|
family: z.enum(EMOTION_FAMILIES).optional(),
|
|
@@ -343,7 +349,7 @@ var EmotionsSchema = z.object({
|
|
|
343
349
|
conversation_id: z.string().min(1).max(256).optional()
|
|
344
350
|
});
|
|
345
351
|
var HallucinationsSchema = z.object({
|
|
346
|
-
days_back:
|
|
352
|
+
days_back: daysBackFlag(7),
|
|
347
353
|
limit: z.number().min(1).max(20).default(10).optional(),
|
|
348
354
|
offset: z.number().min(0).max(1e4).optional(),
|
|
349
355
|
conversation_id: z.string().max(200).optional(),
|
|
@@ -371,7 +377,7 @@ var LAZINESS_FAMILIES = [
|
|
|
371
377
|
"data_regression"
|
|
372
378
|
];
|
|
373
379
|
var LazinessSchema = z.object({
|
|
374
|
-
days_back:
|
|
380
|
+
days_back: daysBackFlag(7),
|
|
375
381
|
limit: z.number().min(1).max(50).default(10).optional(),
|
|
376
382
|
offset: z.number().min(0).max(1e4).optional(),
|
|
377
383
|
conversation_id: z.string().max(200).optional(),
|
|
@@ -392,7 +398,7 @@ var TailSchema = z.object({
|
|
|
392
398
|
var ToolFailureDetailSchema = z.object({
|
|
393
399
|
tool_name: z.string(),
|
|
394
400
|
subtype: z.string().optional(),
|
|
395
|
-
days_back:
|
|
401
|
+
days_back: daysBackFlag(7),
|
|
396
402
|
limit: z.number().min(1).max(20).default(5).optional(),
|
|
397
403
|
offset: z.number().min(0).default(0).optional(),
|
|
398
404
|
include_window: boolFlag(),
|
|
@@ -819,8 +825,12 @@ async function runFixesCommand(context) {
|
|
|
819
825
|
throw new CliInputError(`Unknown fixes subcommand '${context.positional}'`, FIX_USAGE);
|
|
820
826
|
}
|
|
821
827
|
const query = new URLSearchParams;
|
|
822
|
-
|
|
823
|
-
|
|
828
|
+
const status = (context.flags.status ?? "").trim().toUpperCase();
|
|
829
|
+
if (context.flags.status !== undefined && !status) {
|
|
830
|
+
throw new CliInputError("--status must name a fix status.", FIX_USAGE);
|
|
831
|
+
}
|
|
832
|
+
if (status)
|
|
833
|
+
query.set("status", status);
|
|
824
834
|
if (context.flags.limit) {
|
|
825
835
|
const limit = Number(context.flags.limit);
|
|
826
836
|
if (!Number.isInteger(limit) || limit < 1 || limit > 100) {
|
|
@@ -3465,6 +3475,8 @@ import { randomUUID } from "node:crypto";
|
|
|
3465
3475
|
var TELEMETRY_TIMEOUT_MS = 500;
|
|
3466
3476
|
var INVOCATION_ID = randomUUID();
|
|
3467
3477
|
var TELEMETRY_FLAG = "no-telemetry";
|
|
3478
|
+
var MAX_TELEMETRY_DURATION_MS = 86400000;
|
|
3479
|
+
var MAX_TELEMETRY_API_REQUEST_COUNT = 1e6;
|
|
3468
3480
|
var SEARCH_SURFACE_BY_COMMAND = {
|
|
3469
3481
|
search: "message",
|
|
3470
3482
|
conversations: "conversation",
|
|
@@ -3506,7 +3518,7 @@ function buildSearchAdoptionTelemetry(input) {
|
|
|
3506
3518
|
adoption.search_mode_requested = SEARCH_MODES2.includes(requested) ? requested : "hybrid";
|
|
3507
3519
|
}
|
|
3508
3520
|
if (command === "context") {
|
|
3509
|
-
adoption.used_msg_index = flags["msg-index"] !== undefined ? 1 : 0;
|
|
3521
|
+
adoption.used_msg_index = flags["msg-index"] !== undefined || flags["message-index"] !== undefined ? 1 : 0;
|
|
3510
3522
|
}
|
|
3511
3523
|
if (recorded.search_mode_effective) {
|
|
3512
3524
|
adoption.search_mode_effective = recorded.search_mode_effective;
|
|
@@ -3597,8 +3609,8 @@ async function sendCliUsageTelemetry(input) {
|
|
|
3597
3609
|
error_type: input.errorType,
|
|
3598
3610
|
...validationReason ? { validation_reason: validationReason } : {},
|
|
3599
3611
|
exit_code: input.exitCode,
|
|
3600
|
-
duration_ms:
|
|
3601
|
-
api_request_count:
|
|
3612
|
+
duration_ms: clampInt(input.durationMs, 0, MAX_TELEMETRY_DURATION_MS) ?? 0,
|
|
3613
|
+
api_request_count: clampInt(input.apiRequestCount, 0, MAX_TELEMETRY_API_REQUEST_COUNT) ?? 0,
|
|
3602
3614
|
cli_version: VERSION,
|
|
3603
3615
|
node_version: process.versions.node,
|
|
3604
3616
|
platform: process.platform,
|
|
@@ -4818,6 +4830,7 @@ function redactApiKey(key) {
|
|
|
4818
4830
|
async function probeApiKey(key, options = {}) {
|
|
4819
4831
|
let response;
|
|
4820
4832
|
try {
|
|
4833
|
+
recordApiRequest();
|
|
4821
4834
|
response = await fetch(`${resolveModaBaseUrl(options)}/api/v1/data/overview`, {
|
|
4822
4835
|
method: "GET",
|
|
4823
4836
|
headers: apiKeyHeaders(key, options),
|
|
@@ -6161,6 +6174,7 @@ async function streamAsk(options) {
|
|
|
6161
6174
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
6162
6175
|
let response;
|
|
6163
6176
|
try {
|
|
6177
|
+
recordApiRequest();
|
|
6164
6178
|
response = await fetchImpl(url, {
|
|
6165
6179
|
method: "POST",
|
|
6166
6180
|
headers: {
|
|
@@ -6220,7 +6234,7 @@ var ASK_SCHEMA_VERSION = "production_ask.v0.1";
|
|
|
6220
6234
|
var INVESTIGATION_PROBLEM_LIMIT = 3;
|
|
6221
6235
|
var INVESTIGATION_PROBLEM_SLOTS = INVESTIGATION_PROBLEM_LIMIT;
|
|
6222
6236
|
async function runProductionCommand(context) {
|
|
6223
|
-
const daysBack =
|
|
6237
|
+
const daysBack = daysBackFlag2(context.flags);
|
|
6224
6238
|
if (context.command === "overview") {
|
|
6225
6239
|
const briefing = await loadOverviewBriefing({ daysBack, cwd: context.cwd });
|
|
6226
6240
|
if (context.flags.raw === "true") {
|
|
@@ -7555,7 +7569,7 @@ function numberValue(value) {
|
|
|
7555
7569
|
}
|
|
7556
7570
|
return 0;
|
|
7557
7571
|
}
|
|
7558
|
-
function
|
|
7572
|
+
function daysBackFlag2(flags, fallback = 7) {
|
|
7559
7573
|
const raw = flags["days-back"];
|
|
7560
7574
|
if (raw === undefined)
|
|
7561
7575
|
return fallback;
|
|
@@ -7810,8 +7824,64 @@ function parseArgs(argv) {
|
|
|
7810
7824
|
...bareFlags.length > 0 ? { bareFlags } : {}
|
|
7811
7825
|
};
|
|
7812
7826
|
}
|
|
7813
|
-
var
|
|
7814
|
-
|
|
7827
|
+
var RAW_BOOLEAN_FLAGS = new Set([
|
|
7828
|
+
"dry-run",
|
|
7829
|
+
"yes",
|
|
7830
|
+
"live",
|
|
7831
|
+
"local",
|
|
7832
|
+
"watch",
|
|
7833
|
+
"promote",
|
|
7834
|
+
"no-promote",
|
|
7835
|
+
"promote-on-win",
|
|
7836
|
+
"undo",
|
|
7837
|
+
"all",
|
|
7838
|
+
"wait",
|
|
7839
|
+
"no-wait",
|
|
7840
|
+
"wait-for-completion",
|
|
7841
|
+
"summary",
|
|
7842
|
+
"list",
|
|
7843
|
+
"save",
|
|
7844
|
+
"sync",
|
|
7845
|
+
"replay",
|
|
7846
|
+
"no-replay",
|
|
7847
|
+
"remote",
|
|
7848
|
+
"no-remote",
|
|
7849
|
+
"raw",
|
|
7850
|
+
"pr",
|
|
7851
|
+
"packet",
|
|
7852
|
+
"transcript",
|
|
7853
|
+
"gate",
|
|
7854
|
+
"discover",
|
|
7855
|
+
"experimental",
|
|
7856
|
+
"force",
|
|
7857
|
+
"force-reprocess",
|
|
7858
|
+
"reprocess-segments",
|
|
7859
|
+
"online",
|
|
7860
|
+
"offline",
|
|
7861
|
+
"progress",
|
|
7862
|
+
"stream",
|
|
7863
|
+
"no-stream",
|
|
7864
|
+
"quiet",
|
|
7865
|
+
"verbose",
|
|
7866
|
+
"allow-untrack",
|
|
7867
|
+
"github-actions",
|
|
7868
|
+
"no-clustering",
|
|
7869
|
+
"no-analyze",
|
|
7870
|
+
"improve-candidates",
|
|
7871
|
+
"hook-stdin",
|
|
7872
|
+
"auto-generate",
|
|
7873
|
+
"allow-no-agents",
|
|
7874
|
+
"allow-any-model",
|
|
7875
|
+
"json",
|
|
7876
|
+
"human",
|
|
7877
|
+
"prose",
|
|
7878
|
+
"json-schemas",
|
|
7879
|
+
"help",
|
|
7880
|
+
"tui",
|
|
7881
|
+
"no-tui",
|
|
7882
|
+
"no-telemetry",
|
|
7883
|
+
"no-update-check"
|
|
7884
|
+
]);
|
|
7815
7885
|
var GLOBAL_BOOLEAN_FLAGS = new Set([
|
|
7816
7886
|
"agent",
|
|
7817
7887
|
"json",
|
|
@@ -7828,6 +7898,20 @@ var GLOBAL_BOOLEAN_FLAGS = new Set([
|
|
|
7828
7898
|
"tui",
|
|
7829
7899
|
"no-tui"
|
|
7830
7900
|
]);
|
|
7901
|
+
var BOOLEAN_WORDS = new Set(["true", "false", "yes", "no", "on", "off"]);
|
|
7902
|
+
var META_SWITCHES = new Set([
|
|
7903
|
+
"json",
|
|
7904
|
+
"human",
|
|
7905
|
+
"prose",
|
|
7906
|
+
"quiet",
|
|
7907
|
+
"verbose",
|
|
7908
|
+
"help",
|
|
7909
|
+
"json-schemas",
|
|
7910
|
+
"tui",
|
|
7911
|
+
"no-tui",
|
|
7912
|
+
"no-telemetry",
|
|
7913
|
+
"no-update-check"
|
|
7914
|
+
]);
|
|
7831
7915
|
var COMMAND_BOOLEAN_FLAGS = {
|
|
7832
7916
|
context: new Set(["all", "metadata-only"])
|
|
7833
7917
|
};
|
|
@@ -7852,7 +7936,15 @@ function parseFlag(args, index, flags, beforeCommand, bareFlags, command = "") {
|
|
|
7852
7936
|
set(key, "true", true);
|
|
7853
7937
|
return index;
|
|
7854
7938
|
}
|
|
7855
|
-
|
|
7939
|
+
const switchName = key.replace(/_/g, "-");
|
|
7940
|
+
if (META_SWITCHES.has(switchName)) {
|
|
7941
|
+
set(key, "true", true);
|
|
7942
|
+
return index;
|
|
7943
|
+
}
|
|
7944
|
+
const idFollows = COMMAND_BOOLEAN_FLAGS[command]?.has(switchName) === true;
|
|
7945
|
+
const isSwitch = RAW_BOOLEAN_FLAGS.has(switchName) || idFollows;
|
|
7946
|
+
const takesNext = BOOLEAN_WORDS.has(next?.toLowerCase() ?? "") || !idFollows && (next === "0" || next === "1");
|
|
7947
|
+
if (!beforeCommand && isSwitch && !takesNext) {
|
|
7856
7948
|
set(key, "true", true);
|
|
7857
7949
|
return index;
|
|
7858
7950
|
}
|
|
@@ -8022,11 +8114,11 @@ Options:
|
|
|
8022
8114
|
--version Show version number
|
|
8023
8115
|
--json-schemas Print JSON Schemas for the agent output contract
|
|
8024
8116
|
|
|
8025
|
-
Common flags:
|
|
8026
|
-
--days-back=N
|
|
8027
|
-
--
|
|
8028
|
-
--
|
|
8029
|
-
--
|
|
8117
|
+
Common flags (a command rejects any it does not take; see 'moda <command> --help'):
|
|
8118
|
+
--days-back=N Whole days to look back, 1-90 (overview, problems, emotions, laziness, tool-failures, ...)
|
|
8119
|
+
--time-range=RANGE Window for traces, search, clusters instead (all|1h|3d|7d|24h|30d|90d)
|
|
8120
|
+
--limit=N Maximum results to return (users: alias of --page-size)
|
|
8121
|
+
--offset=N Number of results to skip (paged lists)
|
|
8030
8122
|
--profile=NAME Use a named local Moda profile
|
|
8031
8123
|
--json Emit machine-readable JSON
|
|
8032
8124
|
--agent Emit schema-versioned agent JSON
|
|
@@ -8756,6 +8848,12 @@ var WINDOW_FLAG_HINTS = {
|
|
|
8756
8848
|
days_back: "This command takes --time-range (e.g. --time-range=7d), not --days-back.",
|
|
8757
8849
|
time_range: "This command takes --days-back=N (1-90), not --time-range."
|
|
8758
8850
|
};
|
|
8851
|
+
var COMMAND_FLAG_HINTS = {
|
|
8852
|
+
problems: {
|
|
8853
|
+
family: "'moda problems' ranks every family together. To filter by family use 'moda problems remainder --family=<family>' " + "(signals no Problem explains yet) or 'moda problem <problem_id> --traces --family=<family>' (one Problem's traces).",
|
|
8854
|
+
cursor: "'moda problems' has no cursor; 'moda problems remainder --cursor=<next_cursor>' pages the unexplained signals."
|
|
8855
|
+
}
|
|
8856
|
+
};
|
|
8759
8857
|
function editDistance(a, b) {
|
|
8760
8858
|
const row = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
8761
8859
|
for (let i = 1;i <= a.length; i++) {
|
|
@@ -8789,6 +8887,9 @@ function parseCommandFlags(schema, args, command, options = {}) {
|
|
|
8789
8887
|
const flagKeys = schemaKeys.filter((key) => key !== options.positionalKey);
|
|
8790
8888
|
const valid = flagKeys.map((key) => `--${key.replace(/_/g, "-")}`);
|
|
8791
8889
|
const hints = unknown.map((key) => {
|
|
8890
|
+
const commandHint = COMMAND_FLAG_HINTS[command]?.[key];
|
|
8891
|
+
if (commandHint)
|
|
8892
|
+
return commandHint;
|
|
8792
8893
|
const windowAlternative = key === "days_back" ? "time_range" : key === "time_range" ? "days_back" : undefined;
|
|
8793
8894
|
if (windowAlternative && WINDOW_FLAG_HINTS[key] && flagKeys.includes(windowAlternative))
|
|
8794
8895
|
return WINDOW_FLAG_HINTS[key];
|
|
@@ -8816,6 +8917,30 @@ function shellArg(value) {
|
|
|
8816
8917
|
return `"${value}"`;
|
|
8817
8918
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
8818
8919
|
}
|
|
8920
|
+
function semanticIndexCoverage(coverage) {
|
|
8921
|
+
const ratio = asRecord(asRecord(coverage)?.semantic_index)?.coverage_ratio;
|
|
8922
|
+
if (typeof ratio !== "number" || !Number.isFinite(ratio) || ratio < 0 || ratio > 1)
|
|
8923
|
+
return;
|
|
8924
|
+
return `${Number((ratio * 100).toFixed(1))}%`;
|
|
8925
|
+
}
|
|
8926
|
+
function searchDegradeWarning(reason, requestedMode, coverage) {
|
|
8927
|
+
const lead = `Search degraded to keyword mode (${reason}):`;
|
|
8928
|
+
const notComparable = "keyword scores are not comparable to semantic scores";
|
|
8929
|
+
switch (reason) {
|
|
8930
|
+
case "semantic_unavailable":
|
|
8931
|
+
return `${lead} the requested ${requestedMode} ranking did not run, and ${notComparable}. Retry, or use --mode=keyword with exact identifiers.`;
|
|
8932
|
+
case "semantic_index_empty":
|
|
8933
|
+
return `${lead} the semantic index has no embeddings for this tenant in this time window, so the requested ${requestedMode} ranking cannot run and a retry will not help. ` + `The results are keyword matches (${notComparable}); use --mode=keyword with exact identifiers.`;
|
|
8934
|
+
case "semantic_index_partial": {
|
|
8935
|
+
const percent = semanticIndexCoverage(coverage);
|
|
8936
|
+
return `${lead} the semantic index covers ${percent ? `only ${percent}` : "only part"} of the messages in this time window, so the requested ${requestedMode} ranking did not run and a retry will not help. ` + `The results are keyword matches (${notComparable}); use --mode=keyword with exact identifiers.`;
|
|
8937
|
+
}
|
|
8938
|
+
case "below_relevance_floor":
|
|
8939
|
+
return `${lead} no semantic hit cleared the relevance floor, so the requested ${requestedMode} ranking returned nothing and these are keyword matches (${notComparable}). ` + "Rephrase the query, or use --mode=keyword with exact identifiers.";
|
|
8940
|
+
default:
|
|
8941
|
+
return `${lead} the requested ${requestedMode} ranking did not run, and ${notComparable}. Use --mode=keyword with exact identifiers.`;
|
|
8942
|
+
}
|
|
8943
|
+
}
|
|
8819
8944
|
function searchCoverageWarnings(coverage, timeRange) {
|
|
8820
8945
|
const record = asRecord(coverage);
|
|
8821
8946
|
if (!record)
|
|
@@ -9008,6 +9133,24 @@ function assertHandParsedFlags(command, flags, positionals) {
|
|
|
9008
9133
|
throw new CliInputError(/nothing was sent/i.test(error.message) ? error.message : `${error.message} Nothing was sent.`, `${error.usage ?? ""} Id flags (--<name>-id=ID) are attached as refs; put other detail in the note. ${FEEDBACK_USAGE}`.trim(), error.reason);
|
|
9009
9134
|
}
|
|
9010
9135
|
}
|
|
9136
|
+
function normalizeBooleanFlags(target) {
|
|
9137
|
+
let error;
|
|
9138
|
+
for (const [key, raw] of Object.entries(target)) {
|
|
9139
|
+
const name = key.replace(/_/g, "-");
|
|
9140
|
+
if (!RAW_BOOLEAN_FLAGS.has(name))
|
|
9141
|
+
continue;
|
|
9142
|
+
const value = parseBooleanFlagValue(raw);
|
|
9143
|
+
if (value === undefined) {
|
|
9144
|
+
error ??= new CliInputError(`--${name}=${raw} is not a yes/no value, so nothing was run.`, `--${name} is a switch: pass --${name}, or --${name}=true|false (also 1|0, yes|no, on|off).`, `bad_boolean:${name}`);
|
|
9145
|
+
continue;
|
|
9146
|
+
}
|
|
9147
|
+
if (name === "dry-run" && !value)
|
|
9148
|
+
delete target[key];
|
|
9149
|
+
else
|
|
9150
|
+
target[key] = value ? "true" : "false";
|
|
9151
|
+
}
|
|
9152
|
+
return error;
|
|
9153
|
+
}
|
|
9011
9154
|
var PROFILE_MANAGING_COMMANDS = new Set(["profiles", "auth", "init", "provision", "status", "config", "keys", "manifest", "agent", "doctor"]);
|
|
9012
9155
|
async function runProblemsRemainder(flags, context) {
|
|
9013
9156
|
const params = parseCommandFlags(ProblemsRemainderSchema, flagsToArgs(flags), "problems remainder");
|
|
@@ -9039,15 +9182,17 @@ function processingDisabledWarning(data, family) {
|
|
|
9039
9182
|
`${family === "emotion" ? "Emotion" : "Frustration"} analysis is disabled for this tenant (${setting} = false), ` + "so zero results do NOT mean users are not frustrated. Enable it in Settings → Account → Signal processing; " + "only traces ingested after enabling are analyzed."
|
|
9040
9183
|
];
|
|
9041
9184
|
}
|
|
9042
|
-
var CONTEXT_USAGE = "Usage: moda context <conversation_id> [--msg-index=N] [--window=0-5 | --metadata-only]";
|
|
9185
|
+
var CONTEXT_USAGE = "Usage: moda context <conversation_id> [--msg-index=N (alias --message-index)] [--window=0-5 | --metadata-only]";
|
|
9043
9186
|
var CONTEXT_ALL_USAGE = "Usage: moda context <conversation_id> --all [--from=N] [--max-messages=N]";
|
|
9187
|
+
var CONTEXT_FLAG_ALIASES = { "message-index": "msg-index" };
|
|
9044
9188
|
var CONTEXT_MAX_WINDOW = 5;
|
|
9045
9189
|
var EMPTY_ANCHOR_VALUES = new Set(["", "null", "undefined", "none"]);
|
|
9046
9190
|
function parseContextRequest(positional, rawFlags) {
|
|
9047
9191
|
const flags = {};
|
|
9048
9192
|
const flagIds = [];
|
|
9049
9193
|
for (const [rawKey, value] of Object.entries(rawFlags)) {
|
|
9050
|
-
const
|
|
9194
|
+
const kebab = rawKey.replace(/_/g, "-");
|
|
9195
|
+
const key = CONTEXT_FLAG_ALIASES[kebab] ?? kebab;
|
|
9051
9196
|
if (key === "conversation-id") {
|
|
9052
9197
|
if (value !== "true")
|
|
9053
9198
|
flagIds.push(value);
|
|
@@ -9404,7 +9549,7 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
9404
9549
|
const actualMode = asString(searchRecord.search_mode);
|
|
9405
9550
|
const warnings = [];
|
|
9406
9551
|
if (degradeReason && degradeReason !== "none") {
|
|
9407
|
-
warnings.push(
|
|
9552
|
+
warnings.push(searchDegradeWarning(degradeReason, params.mode ?? "hybrid", searchRecord.coverage));
|
|
9408
9553
|
} else if (params.mode && actualMode && actualMode !== params.mode && params.mode !== "hybrid") {
|
|
9409
9554
|
warnings.push(`Search ran in ${actualMode} mode instead of the requested ${params.mode} mode.`);
|
|
9410
9555
|
}
|
|
@@ -10041,6 +10186,9 @@ async function runCommand(command, positional, flags, positionals = positional ?
|
|
|
10041
10186
|
const kinds = { quote: "frustration_quote", tool: "tool_call", laziness: "laziness", hallucination: "hallucination", "custom-signal": "custom_signal" };
|
|
10042
10187
|
const query2 = new URLSearchParams;
|
|
10043
10188
|
if (flags.kind !== undefined) {
|
|
10189
|
+
if (flags.kind === "problem" || flags.kind === "problem-detection") {
|
|
10190
|
+
throw new CliInputError(`'moda false-positives' cannot list --kind=${flags.kind}: ${flags.kind === "problem" ? "a dismissed Problem is recorded as Problem feedback" : "a problem-detection false positive is recorded as a detection review on its Problem"}, not in the false-positive log this command reads. Nothing was sent.`, flags.kind === "problem" ? "Read it with 'moda problem <problem_id> --feedback'. --kind for this list takes " + Object.keys(kinds).join("|") + "." : "Read them per trace with 'moda detection-reviews <conversation_id>' or 'moda false-positives <conversation_id>'. --kind for this list takes " + Object.keys(kinds).join("|") + ".", "unsupported_kind");
|
|
10191
|
+
}
|
|
10044
10192
|
if (!kinds[flags.kind])
|
|
10045
10193
|
throw new CliInputError(`--kind must be one of ${Object.keys(kinds).join("|")}`);
|
|
10046
10194
|
query2.set("kind", kinds[flags.kind]);
|
|
@@ -10270,7 +10418,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
10270
10418
|
resetApiRequestCountBeforeRun: true,
|
|
10271
10419
|
telemetry: "result",
|
|
10272
10420
|
handler: async (context) => {
|
|
10273
|
-
const { runInit } = await import("./index-
|
|
10421
|
+
const { runInit } = await import("./index-025z9q34.js");
|
|
10274
10422
|
if (context.outputMode === "agent-stream") {
|
|
10275
10423
|
context.output.writeEvent({
|
|
10276
10424
|
event: "started",
|
|
@@ -10311,7 +10459,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
10311
10459
|
resetApiRequestCountBeforeRun: true,
|
|
10312
10460
|
telemetry: "result-and-error",
|
|
10313
10461
|
handler: async (context) => {
|
|
10314
|
-
const { runProvision } = await import("./provision-
|
|
10462
|
+
const { runProvision } = await import("./provision-69h38y7d.js");
|
|
10315
10463
|
return runProvision(context, {
|
|
10316
10464
|
resumeCommand: buildResumeCommand("provision", context.rawFlags)
|
|
10317
10465
|
});
|
|
@@ -10556,7 +10704,8 @@ var commandRegistry = createCommandRegistry([
|
|
|
10556
10704
|
description: "List end users with health, frustration and activity (the dashboard Users page)",
|
|
10557
10705
|
examples: [
|
|
10558
10706
|
"moda users --window=30d --sort=health_score --order=asc",
|
|
10559
|
-
"moda users --cohort=frustrated --min-conversations=3"
|
|
10707
|
+
"moda users --cohort=frustrated --min-conversations=3",
|
|
10708
|
+
"moda users --limit=50 # --limit is an alias of --page-size"
|
|
10560
10709
|
],
|
|
10561
10710
|
auth: "api-key",
|
|
10562
10711
|
outputModes: ["human", "json", "agent"],
|
|
@@ -10774,7 +10923,7 @@ var commandRegistry = createCommandRegistry([
|
|
|
10774
10923
|
description: "Get windowed trace context (messages around one turn), or the whole trace with --all",
|
|
10775
10924
|
examples: [
|
|
10776
10925
|
"moda context <conversation_id> --window=3",
|
|
10777
|
-
"moda context <conversation_id> --msg-index=40 --window=0",
|
|
10926
|
+
"moda context <conversation_id> --msg-index=40 --window=0 # --message-index is an alias",
|
|
10778
10927
|
"moda context <conversation_id> --metadata-only # summary + total_messages, no messages",
|
|
10779
10928
|
"moda context <conversation_id> --all",
|
|
10780
10929
|
"moda context <conversation_id> --all --from=500 --max-messages=500"
|
|
@@ -11195,6 +11344,15 @@ var commandRegistry = createCommandRegistry([
|
|
|
11195
11344
|
})
|
|
11196
11345
|
}
|
|
11197
11346
|
]);
|
|
11347
|
+
function apiErrorType(status) {
|
|
11348
|
+
if (typeof status !== "number" || status < 400 || status >= 500)
|
|
11349
|
+
return "api_error";
|
|
11350
|
+
if (status === 404)
|
|
11351
|
+
return "api_not_found";
|
|
11352
|
+
if (status === 409)
|
|
11353
|
+
return "api_conflict";
|
|
11354
|
+
return "api_client_error";
|
|
11355
|
+
}
|
|
11198
11356
|
function classifyCliError(error) {
|
|
11199
11357
|
if (error instanceof CliAuthError)
|
|
11200
11358
|
return "auth_error";
|
|
@@ -11208,7 +11366,7 @@ function classifyCliError(error) {
|
|
|
11208
11366
|
return "validation_error";
|
|
11209
11367
|
}
|
|
11210
11368
|
if (error instanceof ApiError || isApiLikeError(error)) {
|
|
11211
|
-
return
|
|
11369
|
+
return apiErrorType(error.statusCode);
|
|
11212
11370
|
}
|
|
11213
11371
|
if (isNetworkLikeError(error)) {
|
|
11214
11372
|
return "network_error";
|
|
@@ -11307,6 +11465,7 @@ async function dispatchParsedCommand(parsed, startedAt = Date.now()) {
|
|
|
11307
11465
|
}
|
|
11308
11466
|
async function dispatchParsedCommandInner(parsed, startedAt) {
|
|
11309
11467
|
const { command, flags } = parsed;
|
|
11468
|
+
const switchError = normalizeBooleanFlags(flags);
|
|
11310
11469
|
const commandFlags = stripUpdateCheckFlag(stripTelemetryFlag(flags));
|
|
11311
11470
|
const telemetryDisabled = isTelemetryDisabled(flags);
|
|
11312
11471
|
const updateCheckDisabled = isUpdateCheckDisabled(flags);
|
|
@@ -11356,19 +11515,8 @@ async function dispatchParsedCommandInner(parsed, startedAt) {
|
|
|
11356
11515
|
if (parsed.shortFlags?.length) {
|
|
11357
11516
|
return failEarly(new CliInputError(`Short options are not supported (${parsed.shortFlags.join(", ")}), so nothing was run.`, `Use the long form, e.g. --dry-run, --json, --quiet. See 'moda ${command} --help'.`));
|
|
11358
11517
|
}
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
if (raw === undefined)
|
|
11362
|
-
continue;
|
|
11363
|
-
const value = raw.trim().toLowerCase();
|
|
11364
|
-
if (DRY_RUN_TRUE.has(value))
|
|
11365
|
-
target["dry-run"] = "true";
|
|
11366
|
-
else if (DRY_RUN_FALSE.has(value))
|
|
11367
|
-
delete target["dry-run"];
|
|
11368
|
-
else {
|
|
11369
|
-
return failEarly(new CliInputError(`--dry-run=${raw} is not a yes/no value, so nothing was run.`, "Pass --dry-run (or --dry-run=true) to preview, or omit it to run for real."));
|
|
11370
|
-
}
|
|
11371
|
-
}
|
|
11518
|
+
if (switchError)
|
|
11519
|
+
return failEarly(switchError);
|
|
11372
11520
|
if (commandFlags.profile === "true" || commandFlags.profile === "") {
|
|
11373
11521
|
return failEarly(new CliInputError("--profile needs a value, e.g. --profile=prod.", "List profiles with 'moda profiles list'."));
|
|
11374
11522
|
}
|
|
@@ -11539,6 +11687,7 @@ if (isMain) {
|
|
|
11539
11687
|
export {
|
|
11540
11688
|
telemetryCommandName,
|
|
11541
11689
|
stripLoneSurrogates,
|
|
11690
|
+
searchDegradeWarning,
|
|
11542
11691
|
searchCoverageWarnings,
|
|
11543
11692
|
runCommand,
|
|
11544
11693
|
resolveTailSignal,
|
|
@@ -11546,6 +11695,7 @@ export {
|
|
|
11546
11695
|
parseContextRequest,
|
|
11547
11696
|
parseCommandFlags,
|
|
11548
11697
|
parseArgs,
|
|
11698
|
+
normalizeBooleanFlags,
|
|
11549
11699
|
initFlagsForContext,
|
|
11550
11700
|
flagsToArgs,
|
|
11551
11701
|
dispatchParsedCommand,
|
|
@@ -11558,8 +11708,10 @@ export {
|
|
|
11558
11708
|
buildResumeCommand,
|
|
11559
11709
|
auditCapStatus,
|
|
11560
11710
|
TAIL_LIMITS,
|
|
11711
|
+
RAW_BOOLEAN_FLAGS,
|
|
11561
11712
|
LEGACY_WINDOW_MAX_MESSAGES,
|
|
11562
11713
|
FULL_TRANSCRIPT_DEFAULT_MAX_MESSAGES,
|
|
11563
11714
|
CliInputError,
|
|
11564
|
-
CONTEXT_MAX_WINDOW
|
|
11715
|
+
CONTEXT_MAX_WINDOW,
|
|
11716
|
+
CONTEXT_FLAG_ALIASES
|
|
11565
11717
|
};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildSourceSnapshot
|
|
3
|
-
} from "./cli-
|
|
4
|
-
import
|
|
3
|
+
} from "./cli-tzqez7mw.js";
|
|
4
|
+
import {
|
|
5
|
+
recordApiRequest
|
|
6
|
+
} from "./cli-xtj2m4hs.js";
|
|
5
7
|
import"./cli-0v6na3yp.js";
|
|
6
8
|
|
|
7
9
|
// src/harness-github-actions.ts
|
|
@@ -34,6 +36,7 @@ async function runGithubActionsAnalyze(rootDir, deps = {}) {
|
|
|
34
36
|
const base = (env.MODA_GITHUB_URL || DEFAULT_MODA_GITHUB_URL).replace(/\/+$/, "");
|
|
35
37
|
const audience = env.MODA_GHA_AUDIENCE || DEFAULT_GHA_AUDIENCE;
|
|
36
38
|
const oidcToken = await requestOidcToken(env, audience, fetchImpl);
|
|
39
|
+
recordApiRequest();
|
|
37
40
|
const exchangeRes = await fetchImpl(`${base}/gha/exchange`, {
|
|
38
41
|
method: "POST",
|
|
39
42
|
headers: { "Content-Type": "application/json" },
|
|
@@ -45,6 +48,7 @@ async function runGithubActionsAnalyze(rootDir, deps = {}) {
|
|
|
45
48
|
const exchange = await exchangeRes.json();
|
|
46
49
|
const authHeader = { Authorization: `Bearer ${exchange.token}`, "Content-Type": "application/json" };
|
|
47
50
|
const snapshot = buildSnapshot(rootDir);
|
|
51
|
+
recordApiRequest();
|
|
48
52
|
const analyzeRes = await fetchImpl(`${base}/gha/analyze`, {
|
|
49
53
|
method: "POST",
|
|
50
54
|
headers: authHeader,
|
|
@@ -60,6 +64,7 @@ async function runGithubActionsAnalyze(rootDir, deps = {}) {
|
|
|
60
64
|
let report;
|
|
61
65
|
let validation;
|
|
62
66
|
for (let attempt = 0;attempt < maxAttempts; attempt += 1) {
|
|
67
|
+
recordApiRequest();
|
|
63
68
|
const pollRes = await fetchImpl(`${base}/gha/analyze/${encodeURIComponent(analysisRunId)}`, { headers: { Authorization: authHeader.Authorization } });
|
|
64
69
|
if (!pollRes.ok)
|
|
65
70
|
throw new GithubActionsAnalyzeError(`Hosted analysis poll failed (${pollRes.status}).`);
|
|
@@ -77,6 +82,7 @@ async function runGithubActionsAnalyze(rootDir, deps = {}) {
|
|
|
77
82
|
}
|
|
78
83
|
let synced = false;
|
|
79
84
|
if (status === "completed" && validationPassed && exchange.capabilities.includes("sync") && report) {
|
|
85
|
+
recordApiRequest();
|
|
80
86
|
const syncRes = await fetchImpl(`${base}/gha/sync`, {
|
|
81
87
|
method: "POST",
|
|
82
88
|
headers: authHeader,
|
|
@@ -42,8 +42,8 @@ import {
|
|
|
42
42
|
writeHarnessAnalyzeResult,
|
|
43
43
|
writeHarnessArtifacts,
|
|
44
44
|
writeHumanProgress
|
|
45
|
-
} from "./cli-
|
|
46
|
-
import"./cli-
|
|
45
|
+
} from "./cli-tzqez7mw.js";
|
|
46
|
+
import"./cli-xtj2m4hs.js";
|
|
47
47
|
import"./cli-0v6na3yp.js";
|
|
48
48
|
export {
|
|
49
49
|
writeHumanProgress,
|