@moda-ai/cli 1.55.16 → 1.55.18

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 (31) hide show
  1. package/dist/{agent-a2xwfeeh.js → agent-cha3kg9d.js} +9 -9
  2. package/dist/{cli-86q35fpq.js → cli-0e8bfvn7.js} +8 -8
  3. package/dist/{cli-3gwbg0xp.js → cli-1exddmc0.js} +2 -2
  4. package/dist/{cli-b3cxcxgn.js → cli-3ezzeqcy.js} +669 -37
  5. package/dist/{cli-kf3d6y8c.js → cli-5hq827jt.js} +8 -2
  6. package/dist/{cli-xy6zn80e.js → cli-5q1gyvxn.js} +5 -5
  7. package/dist/{cli-7fc44hhq.js → cli-a1mv0ypm.js} +5 -5
  8. package/dist/{cli-zdeywyn9.js → cli-av3dqgj5.js} +4 -4
  9. package/dist/cli-bb7133m7.js +144 -0
  10. package/dist/{cli-2ars875d.js → cli-c8p69n55.js} +2 -2
  11. package/dist/{cli-atx672xv.js → cli-eazeanvt.js} +1 -1
  12. package/dist/{cli-53mvsfgn.js → cli-kg0kz05e.js} +3 -3
  13. package/dist/{cli-6ca1sz0a.js → cli-qmjnh4z9.js} +1 -1
  14. package/dist/cli.js +120 -49
  15. package/dist/{doctor-e2xrbpmp.js → doctor-kg0yq1wf.js} +9 -9
  16. package/dist/{fix-v8xka487.js → fix-q8er8egx.js} +7 -7
  17. package/dist/{harness-github-actions-301nak95.js → harness-github-actions-ver6cprq.js} +6 -6
  18. package/dist/{harness-28wbzncq.js → harness-v9s0k9s7.js} +6 -6
  19. package/dist/{index-ccdpy9ma.js → index-7zqa7t5c.js} +11 -11
  20. package/dist/{production-intelligence-0wqcvvxk.js → production-intelligence-k36jsvqx.js} +13 -13
  21. package/dist/{profile-commands-f5kysjrv.js → profile-commands-88sdwzbg.js} +3 -3
  22. package/dist/prompt-source-mcp.js +6 -6
  23. package/dist/{prompts-jg0stjfb.js → prompts-2r756vtd.js} +7 -7
  24. package/dist/{provision-25bw5rd7.js → provision-n3r7yway.js} +4 -4
  25. package/dist/{registry-39xzetsc.js → registry-5v63ga01.js} +4 -4
  26. package/dist/{skills-gjesa81c.js → skills-fed17et3.js} +6 -6
  27. package/dist/{sync-7ts9psky.js → sync-r4tncne4.js} +8 -8
  28. package/package.json +1 -1
  29. package/skills/integration/index.json +2 -2
  30. package/skills/moda-cli/SKILL.md +20 -8
  31. package/dist/cli-438g4nwh.js +0 -465
@@ -678,6 +678,427 @@ function resetApiRequestCount() {
678
678
  apiRequestCount = 0;
679
679
  }
680
680
 
681
+ // src/batch-reads.ts
682
+ import { readFile } from "node:fs/promises";
683
+ var BATCH_MAX_TARGETS = 25;
684
+ var BATCH_CONCURRENCY = 4;
685
+ var ANCHOR_SUFFIX = /^(.+)@(\d+)$/;
686
+ function parseBatchTarget(text, anchors, usage) {
687
+ const raw = text.trim();
688
+ if (raw.startsWith("{")) {
689
+ let parsed;
690
+ try {
691
+ parsed = JSON.parse(raw);
692
+ } catch {
693
+ throw new CliInputError(`Could not parse the JSON target ${JSON.stringify(raw)}.`, usage, "bad_batch_target");
694
+ }
695
+ const record = parsed;
696
+ const id = record?.id ?? record?.conversation_id ?? record?.trace_id;
697
+ if (typeof id !== "string" || id.trim() === "") {
698
+ throw new CliInputError(`JSON target ${JSON.stringify(raw)} has no "id" string.`, usage, "bad_batch_target");
699
+ }
700
+ const index = record.msg_index ?? record.message_index;
701
+ if (index !== undefined && index !== null) {
702
+ if (!anchors) {
703
+ throw new CliInputError(`JSON target ${JSON.stringify(raw)} has a msg_index, which this command does not take.`, usage, "bad_batch_target");
704
+ }
705
+ if (typeof index !== "number" || !Number.isSafeInteger(index) || index < 0) {
706
+ throw new CliInputError(`JSON target ${JSON.stringify(raw)} has an invalid msg_index (want an integer >= 0).`, usage, "bad_batch_target");
707
+ }
708
+ return { raw, id, msgIndex: index };
709
+ }
710
+ return { raw, id };
711
+ }
712
+ if (anchors) {
713
+ const match = ANCHOR_SUFFIX.exec(raw);
714
+ if (match) {
715
+ const msgIndex = Number(match[2]);
716
+ if (!Number.isSafeInteger(msgIndex)) {
717
+ throw new CliInputError(`Target ${JSON.stringify(raw)} has an @msg_index past ${Number.MAX_SAFE_INTEGER}. ` + 'If the id itself ends in @<digits>, pass it as {"id": "..."}.', usage, "bad_batch_target");
718
+ }
719
+ return { raw, id: match[1], msgIndex };
720
+ }
721
+ }
722
+ return { raw, id: raw };
723
+ }
724
+ function parseTargetLines(text, anchors, usage) {
725
+ return text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "").map((line) => parseBatchTarget(line, anchors, usage));
726
+ }
727
+ async function readStdinText() {
728
+ if (process.stdin.isTTY) {
729
+ throw new CliInputError("--ids-from=- reads targets from stdin, but stdin is a terminal. Pipe ids in (one per line) or pass a file path.", undefined, "ids_from_tty");
730
+ }
731
+ const chunks = [];
732
+ for await (const chunk of process.stdin)
733
+ chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
734
+ return Buffer.concat(chunks).toString("utf8");
735
+ }
736
+ async function readIdsFrom(source, usage) {
737
+ if (source === "" || source === "true") {
738
+ throw new CliInputError("--ids-from needs a value: - (stdin) or a file path.", usage, "missing_flag_value");
739
+ }
740
+ if (source === "-")
741
+ return readStdinText();
742
+ try {
743
+ return await readFile(source, "utf8");
744
+ } catch (error) {
745
+ const code = error.code;
746
+ throw new CliInputError(`Could not read --ids-from file ${JSON.stringify(source)}${typeof code === "string" ? ` (${code})` : ""}.`, usage, "ids_from_unreadable");
747
+ }
748
+ }
749
+ async function collectBatchTargets(positionals, idsFrom, options) {
750
+ const targets = positionals.map((value) => parseBatchTarget(value, options.anchors, options.usage));
751
+ if (idsFrom !== undefined) {
752
+ targets.push(...parseTargetLines(await readIdsFrom(idsFrom, options.usage), options.anchors, options.usage));
753
+ }
754
+ const seen = new Set;
755
+ const unique = targets.filter((target) => {
756
+ const key = `${target.id}\x00${target.msgIndex ?? ""}`;
757
+ if (seen.has(key))
758
+ return false;
759
+ seen.add(key);
760
+ return true;
761
+ });
762
+ if (unique.length === 0) {
763
+ throw new CliInputError(`No targets: --ids-from gave no ids (one per line).`, options.usage, "missing_positional");
764
+ }
765
+ if (unique.length > BATCH_MAX_TARGETS) {
766
+ throw new CliInputError(`Got ${unique.length} targets; 'moda ${options.command}' reads at most ${BATCH_MAX_TARGETS} per call, so nothing was read. ` + `Split the ids into calls of ${BATCH_MAX_TARGETS} or fewer.`, options.usage, "batch_too_large");
767
+ }
768
+ return unique;
769
+ }
770
+ async function mapWithConcurrency(items, limit, fn) {
771
+ const results = new Array(items.length);
772
+ let next = 0;
773
+ let failure;
774
+ const worker = async () => {
775
+ while (!failure && next < items.length) {
776
+ const index = next++;
777
+ try {
778
+ results[index] = await fn(items[index], index);
779
+ } catch (error) {
780
+ failure ??= { error };
781
+ }
782
+ }
783
+ };
784
+ await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, worker));
785
+ if (failure)
786
+ throw failure.error;
787
+ return results;
788
+ }
789
+ function idNeedsJsonTarget(id) {
790
+ return ANCHOR_SUFFIX.test(id);
791
+ }
792
+ function contextTarget(id) {
793
+ const verbatim = id === id.trim() && !id.startsWith("{") && !idNeedsJsonTarget(id);
794
+ return verbatim ? id : JSON.stringify({ id });
795
+ }
796
+
797
+ // src/transforms.ts
798
+ function asRecord(value) {
799
+ if (value && typeof value === "object" && !Array.isArray(value)) {
800
+ return value;
801
+ }
802
+ return null;
803
+ }
804
+ function asString(value) {
805
+ return typeof value === "string" ? value : null;
806
+ }
807
+ function asNumber(value) {
808
+ return typeof value === "number" && Number.isFinite(value) ? value : null;
809
+ }
810
+ function frustrationAnchorIndex(row) {
811
+ if (!row)
812
+ return null;
813
+ const userQuotes = Array.isArray(row.user_quotes) ? row.user_quotes : [];
814
+ const firstQuote = asRecord(userQuotes[0]);
815
+ const resolved = asNumber(firstQuote?.msg_index) ?? asNumber(row.anchor_msg_index);
816
+ if (resolved !== null)
817
+ return resolved;
818
+ const keyTurns = Array.isArray(row.key_turns) ? row.key_turns : [];
819
+ const firstTurn = keyTurns.find((t) => typeof t === "number");
820
+ if (firstTurn !== undefined)
821
+ return firstTurn;
822
+ return asNumber(firstQuote?.turn);
823
+ }
824
+ function buildFrustrationAnchor(row) {
825
+ const conversation_id = asString(row.conversation_id) ?? "";
826
+ const userQuotes = Array.isArray(row.user_quotes) ? row.user_quotes : [];
827
+ const firstQuote = asRecord(userQuotes[0]);
828
+ const keyTurnsRaw = Array.isArray(row.key_turns) ? row.key_turns : [];
829
+ const all_turns = keyTurnsRaw.filter((t) => typeof t === "number");
830
+ const msg_index = frustrationAnchorIndex(row);
831
+ let signal = null;
832
+ let quote_preview = null;
833
+ if (firstQuote) {
834
+ signal = asString(firstQuote.signal);
835
+ const quote = asString(firstQuote.quote);
836
+ if (quote !== null) {
837
+ let end = 0;
838
+ let points = 0;
839
+ for (const ch of quote) {
840
+ if (points++ === 200)
841
+ break;
842
+ end += ch.length;
843
+ }
844
+ quote_preview = quote.slice(0, end);
845
+ }
846
+ }
847
+ return {
848
+ kind: "frustration",
849
+ conversation_id,
850
+ msg_index,
851
+ signal,
852
+ quote_preview,
853
+ all_turns,
854
+ no_anchor: msg_index === null
855
+ };
856
+ }
857
+ function buildToolFailureAnchor(row, toolName) {
858
+ const conversation_id = asString(row.conversation_id) ?? "";
859
+ const msg_index = asNumber(row.msg_index);
860
+ const tool_use_id = asString(row.tool_use_id);
861
+ const error_subtype = asString(row.error_subtype);
862
+ return {
863
+ kind: "tool_failure",
864
+ conversation_id,
865
+ msg_index,
866
+ tool_name: toolName,
867
+ tool_use_id,
868
+ error_subtype,
869
+ no_anchor: msg_index === null
870
+ };
871
+ }
872
+ function frustrationsFromEmotions(response) {
873
+ if (!Array.isArray(response.detections) || Array.isArray(response.frustrations))
874
+ return response;
875
+ const summary = asRecord(response.summary) ?? {};
876
+ const pagination = asRecord(response.pagination) ?? {};
877
+ const byFamily = asRecord(summary.by_family) ?? {};
878
+ const totalAnalyzed = asNumber(summary.conversations_analyzed) ?? 0;
879
+ const byFamilyConversations = asRecord(summary.conversations_by_family);
880
+ const frustrated = asNumber(byFamilyConversations?.frustration) ?? asNumber(byFamily.frustration) ?? 0;
881
+ const frustrations = response.detections.map((item) => asRecord(item)).filter((row) => row !== null && (row.family === undefined || row.family === "frustration")).map(({ conversation_context, score, is_detected, ...row }) => ({
882
+ ...row,
883
+ is_frustrated: is_detected === true,
884
+ frustration_score: score,
885
+ target: row.elicitor === "bot" || row.elicitor === "external" ? row.elicitor : "ambiguous",
886
+ conversation: conversation_context ?? null
887
+ }));
888
+ const atRisk = asNumber(pagination.at_risk) ?? Math.max(0, (asNumber(pagination.total) ?? 0) - frustrated);
889
+ const signalBreakdown = {};
890
+ for (const item of Array.isArray(response.signal_breakdown) ? response.signal_breakdown : []) {
891
+ const row = asRecord(item);
892
+ if (row?.family === "frustration" && typeof row.signal === "string") {
893
+ signalBreakdown[row.signal] = asNumber(row.count) ?? 0;
894
+ }
895
+ }
896
+ const { detections: _detections, ...rest } = response;
897
+ return {
898
+ ...rest,
899
+ summary: {
900
+ total_analyzed: totalAnalyzed,
901
+ frustrated_count: frustrated,
902
+ at_risk_count: atRisk,
903
+ frustration_rate_pct: totalAnalyzed > 0 ? Math.round(frustrated / totalAnalyzed * 1000) / 10 : 0
904
+ },
905
+ signal_breakdown: signalBreakdown,
906
+ frustrations,
907
+ source: "emotion_detections"
908
+ };
909
+ }
910
+ function withFrustrationAnchors(response) {
911
+ if (!Array.isArray(response.frustrations))
912
+ return response;
913
+ const frustrations = response.frustrations.map((item) => {
914
+ const row = asRecord(item);
915
+ if (!row)
916
+ return item;
917
+ const anchor = buildFrustrationAnchor(row);
918
+ return { ...row, anchor };
919
+ });
920
+ return { ...response, frustrations };
921
+ }
922
+ var TOOL_FAILURE_CONTEXT_RADIUS = 2;
923
+ function shellWord(value) {
924
+ return /^[\w@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
925
+ }
926
+ function trimFailureWindow(value, radius, fallbackCenter) {
927
+ const conv = asRecord(value);
928
+ if (!conv)
929
+ return value ?? null;
930
+ const { coverage: _coverage, context, ...convRest } = conv;
931
+ const ctx = asRecord(context);
932
+ if (!ctx)
933
+ return convRest;
934
+ const center = asNumber(ctx.center_index) ?? fallbackCenter;
935
+ const messages = (Array.isArray(ctx.messages) ? ctx.messages : []).map((message) => asRecord(message)).filter((message) => {
936
+ const index = asNumber(message?.index);
937
+ return message !== null && (center === null || index === null || Math.abs(index - center) <= radius);
938
+ }).map(({ content_blocks, ...message }) => {
939
+ const covered = typeof message.content === "string" && message.content.length > 0 || Array.isArray(message.tool_calls) && message.tool_calls.length > 0 || Array.isArray(message.tool_results) && message.tool_results.length > 0;
940
+ return covered || content_blocks === undefined ? message : { ...message, content_blocks };
941
+ });
942
+ const indexes = messages.map((message) => asNumber(message.index)).filter((index) => index !== null);
943
+ return {
944
+ ...convRest,
945
+ context: {
946
+ ...ctx,
947
+ ...indexes.length > 0 ? { from_index: Math.min(...indexes), to_index: Math.max(...indexes) } : {},
948
+ messages
949
+ }
950
+ };
951
+ }
952
+ function trimToolFailureConversations(response, opts) {
953
+ if (!Array.isArray(response.examples))
954
+ return response;
955
+ const examples = response.examples.map((item) => {
956
+ const row = asRecord(item);
957
+ if (!row)
958
+ return item;
959
+ const { conversation, window, ...rest } = row;
960
+ const conversationId = asString(row.conversation_id);
961
+ const msgIndex = asNumber(asRecord(row.anchor)?.msg_index) ?? asNumber(row.msg_index);
962
+ return {
963
+ ...rest,
964
+ ...conversationId && msgIndex !== null ? { context_command: `moda context ${shellWord(contextTarget(conversationId))} --msg-index=${msgIndex} --window=${TOOL_FAILURE_CONTEXT_RADIUS}` } : {},
965
+ ...opts.drop ? {} : { conversation: trimFailureWindow(conversation, TOOL_FAILURE_CONTEXT_RADIUS, msgIndex) },
966
+ ..."window" in row ? { window: trimFailureWindow(window, opts.windowRadius ?? TOOL_FAILURE_CONTEXT_RADIUS, msgIndex) } : {}
967
+ };
968
+ });
969
+ return { ...response, examples };
970
+ }
971
+ function withToolFailureAnchors(response) {
972
+ if (!Array.isArray(response.examples))
973
+ return response;
974
+ const toolName = asString(response.tool_name) ?? "";
975
+ const examples = response.examples.map((item) => {
976
+ const row = asRecord(item);
977
+ if (!row)
978
+ return item;
979
+ const anchor = buildToolFailureAnchor(row, toolName);
980
+ return { ...row, anchor };
981
+ });
982
+ return { ...response, examples };
983
+ }
984
+ function embeddedWindowSize(conversation) {
985
+ if (!conversation)
986
+ return null;
987
+ const ctx = asRecord(conversation.context);
988
+ if (!ctx)
989
+ return null;
990
+ const center = asNumber(ctx.center_index);
991
+ const from = asNumber(ctx.from_index);
992
+ const to = asNumber(ctx.to_index);
993
+ if (center === null || from === null || to === null)
994
+ return null;
995
+ return Math.min(center - from, to - center);
996
+ }
997
+ var DETECTION_CONTEXT_RADIUS = 2;
998
+ function withoutDetectionWindows(response, listKey, windowKey) {
999
+ const list = response[listKey];
1000
+ if (!Array.isArray(list))
1001
+ return response;
1002
+ const rows = list.map((item) => {
1003
+ const row = asRecord(item);
1004
+ if (!row)
1005
+ return item;
1006
+ const { [windowKey]: _window, ...rest } = row;
1007
+ const conversationId = asString(row.conversation_id);
1008
+ const msgIndex = asNumber(asRecord(row.anchor)?.msg_index) ?? frustrationAnchorIndex(row);
1009
+ return {
1010
+ ...rest,
1011
+ ...conversationId && msgIndex !== null ? { context_command: `moda context ${shellWord(contextTarget(conversationId))} --msg-index=${msgIndex} --window=${DETECTION_CONTEXT_RADIUS}` } : {}
1012
+ };
1013
+ });
1014
+ return { ...response, [listKey]: rows };
1015
+ }
1016
+ var PROBLEM_COMPACT_EVIDENCE = 5;
1017
+ var PROBLEM_COMPACT_OMITTED_BLOCKS = [
1018
+ "rubric",
1019
+ "trend",
1020
+ "sub_problems",
1021
+ "affected_conversations",
1022
+ "remainder",
1023
+ "confidence",
1024
+ "change_history",
1025
+ "stories"
1026
+ ];
1027
+ function readCommand(command, purpose) {
1028
+ return { command, purpose, mutability: "read", requires_approval: false };
1029
+ }
1030
+ function evidenceMsgIndex(row) {
1031
+ return asNumber(row.anchor_msg_index) ?? asNumber(asRecord(asRecord(row.snippet_parsed)?.anchor)?.msg_index);
1032
+ }
1033
+ function compactProblemDossier(response, problemId) {
1034
+ const id = shellWord(asString(response.problem_id) ?? problemId);
1035
+ const evidence = (Array.isArray(response.evidence) ? response.evidence : []).map((item) => asRecord(item)).filter((row) => row !== null);
1036
+ const topEvidence = evidence.slice(0, PROBLEM_COMPACT_EVIDENCE).map((row) => {
1037
+ const conversationId = asString(row.conversation_id);
1038
+ const msgIndex = evidenceMsgIndex(row);
1039
+ return {
1040
+ attribution_id: row.attribution_id ?? null,
1041
+ conversation_id: conversationId,
1042
+ msg_index: msgIndex,
1043
+ signal_family: row.signal_family ?? null,
1044
+ signal_type: row.signal_type ?? null,
1045
+ confidence: row.confidence ?? null,
1046
+ causal_rationale: row.causal_rationale ?? null,
1047
+ door: row.door ?? null,
1048
+ replay_verified: row.replay_verified ?? null,
1049
+ ...conversationId && msgIndex !== null ? { context_command: `moda context ${shellWord(contextTarget(conversationId))} --msg-index=${msgIndex}` } : {}
1050
+ };
1051
+ });
1052
+ const reportsBlock = asRecord(response.investigation_reports);
1053
+ const reports = (Array.isArray(reportsBlock?.items) ? reportsBlock.items : []).map((item) => asRecord(item)).filter((row) => row !== null).map((row) => ({
1054
+ report_id: row.report_id ?? null,
1055
+ conversation_id: row.conversation_id ?? null,
1056
+ mechanism: row.mechanism ?? null,
1057
+ suspected_surface: row.suspected_surface ?? null,
1058
+ severity: row.severity ?? null,
1059
+ problem_found: row.problem_found ?? null
1060
+ }));
1061
+ const verification = asRecord(response.verification);
1062
+ const { samples: _samples, ...verificationCounts } = verification ?? {};
1063
+ const dossier = asRecord(response.dossier);
1064
+ const { representative_story_keys: _storyKeys, ...dossierSummary } = dossier ?? {};
1065
+ const trend = Array.isArray(response.trend) ? response.trend : [];
1066
+ const data = {
1067
+ found: response.found ?? true,
1068
+ problem_id: response.problem_id ?? problemId,
1069
+ requested_problem_id: response.requested_problem_id ?? problemId,
1070
+ alias_resolved: response.alias_resolved ?? false,
1071
+ view: "compact",
1072
+ header: response.header ?? null,
1073
+ dossier: dossier ? dossierSummary : null,
1074
+ verification: verification ? verificationCounts : null,
1075
+ ...response.impact_identity !== undefined ? { impact_identity: response.impact_identity } : {},
1076
+ ...response.hierarchy !== undefined ? { hierarchy: response.hierarchy } : {},
1077
+ ...trend.length > 0 ? { trend_latest: trend[trend.length - 1], trend_points: trend.length } : {},
1078
+ top_evidence: topEvidence,
1079
+ evidence_in_dossier: evidence.length,
1080
+ reports,
1081
+ omitted: {
1082
+ evidence_rows: Math.max(0, evidence.length - topEvidence.length),
1083
+ report_narratives: reports.length,
1084
+ reports_has_more: reportsBlock?.has_more === true,
1085
+ blocks: PROBLEM_COMPACT_OMITTED_BLOCKS.filter((key) => (key in response))
1086
+ },
1087
+ full_command: `moda problem ${id} --full`
1088
+ };
1089
+ const nextCommands = [
1090
+ readCommand(`moda problem ${id} --evidence --limit=20`, "Page every evidence row with its anchor (follow next_cursor)."),
1091
+ readCommand(`moda problem ${id} --reports`, "Page investigation reports with narratives and citations."),
1092
+ readCommand(`moda problem ${id} --traces`, "Page affected traces with their latest anchor."),
1093
+ readCommand(`moda problem ${id} --full`, "The complete dossier, every block (large).")
1094
+ ];
1095
+ const first = topEvidence.find((row) => typeof row.context_command === "string");
1096
+ if (first?.context_command) {
1097
+ nextCommands.push(readCommand(first.context_command, "Read the trace around the top evidence anchor."));
1098
+ }
1099
+ return { data, nextCommands };
1100
+ }
1101
+
681
1102
  // ../../packages/harness-snapshot/src/policy.ts
682
1103
  var MAX_SCANNED_FILE_BYTES = 512 * 1024;
683
1104
  var DEFAULT_MAX_INVENTORY_FILES = 12000;
@@ -1053,6 +1474,25 @@ var AGENT_ERROR_CODES = [
1053
1474
  "output_error",
1054
1475
  "not_found"
1055
1476
  ];
1477
+ var MODA_COMMAND = /^(?:moda |.*\| moda )/;
1478
+ function withProfileFlag(command, flag) {
1479
+ return MODA_COMMAND.test(command) && !/(?:^|\s)--profile(?:[=\s]|$)/.test(command) ? `${command} ${flag}` : command;
1480
+ }
1481
+ function withProfileOnCommands(value, profile) {
1482
+ const flag = `--profile=${shellWord(profile)}`;
1483
+ const visit = (node, key) => {
1484
+ const isCommandKey = key !== undefined && /commands?$/.test(key);
1485
+ if (typeof node === "string")
1486
+ return isCommandKey ? withProfileFlag(node, flag) : node;
1487
+ if (Array.isArray(node))
1488
+ return node.map((item) => visit(item, isCommandKey ? key : undefined));
1489
+ const record = asRecord2(node);
1490
+ if (!record)
1491
+ return node;
1492
+ return Object.fromEntries(Object.entries(record).map(([entryKey, entry]) => [entryKey, visit(entry, entryKey)]));
1493
+ };
1494
+ return visit(value, undefined);
1495
+ }
1056
1496
  var FALLBACK_RUN_ID = randomUUID();
1057
1497
  var fallbackSeq = 0;
1058
1498
  var stdoutClosed = false;
@@ -1217,7 +1657,8 @@ function createCliOutput(options) {
1217
1657
  nextCommands: writeOptions.nextCommands,
1218
1658
  artifacts: writeOptions.artifacts,
1219
1659
  warnings: writeOptions.warnings,
1220
- errors: writeOptions.errors
1660
+ errors: writeOptions.errors,
1661
+ invocation: options.invocation
1221
1662
  });
1222
1663
  };
1223
1664
  const output = {
@@ -1227,6 +1668,12 @@ function createCliOutput(options) {
1227
1668
  const bypassQuiet = writeOptions.bypassQuiet === true;
1228
1669
  if (options.quiet && !bypassQuiet)
1229
1670
  return;
1671
+ const profile = options.invocation?.flags.profile;
1672
+ if (profile) {
1673
+ data = withProfileOnCommands(data, profile);
1674
+ if (writeOptions.nextCommands)
1675
+ writeOptions = { ...writeOptions, nextCommands: withProfileOnCommands(writeOptions.nextCommands, profile) };
1676
+ }
1230
1677
  if (options.mode === "agent" || options.mode === "agent-stream") {
1231
1678
  if (state.terminal)
1232
1679
  return;
@@ -1368,7 +1815,7 @@ function createAgentEnvelope(options) {
1368
1815
  findings: text.findings,
1369
1816
  evidence_refs: text.evidence_refs,
1370
1817
  recommended_actions: text.recommended_actions,
1371
- next_commands: text.next_commands,
1818
+ next_commands: [...text.next_commands, ...bounded.nextCommands ?? []],
1372
1819
  artifacts: [
1373
1820
  ...options.artifacts ?? [],
1374
1821
  ...bounded.fullOutputPath ? [{ kind: "full_output", path: bounded.fullOutputPath, description: "Complete command output (the same JSON --json prints); data in this envelope was bounded." }] : [],
@@ -1396,9 +1843,9 @@ function createAgentEnvelope(options) {
1396
1843
  const sizeOf = (value) => Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
1397
1844
  const rebound = (current) => {
1398
1845
  const overhead = sizeOf(current) - sizeOf(current.data);
1399
- return build(boundForAgent(safeData, Math.max(1024, maxBytes - overhead - 1024), { writeFullOutput }));
1846
+ return build(boundForAgent(safeData, Math.max(1024, maxBytes - overhead - 1024), { writeFullOutput, invocation: options.invocation }));
1400
1847
  };
1401
- let envelope = build(boundForAgent(safeData, maxBytes, { writeFullOutput }));
1848
+ let envelope = build(boundForAgent(safeData, maxBytes, { writeFullOutput, invocation: options.invocation }));
1402
1849
  if (sizeOf(envelope) > maxBytes)
1403
1850
  envelope = rebound(envelope);
1404
1851
  if (sizeOf(envelope) > maxBytes && !saveFailed) {
@@ -1750,11 +2197,11 @@ function normalizeSummary(summary, command, status, data) {
1750
2197
  return inferSummary(command, status, data);
1751
2198
  }
1752
2199
  function inferSummary(command, status, data) {
1753
- const record = asRecord(data);
2200
+ const record = asRecord2(data);
1754
2201
  if (status === "error") {
1755
2202
  return { text: `${command} failed.`, confidence: "high" };
1756
2203
  }
1757
- const summary = asRecord(record?.summary);
2204
+ const summary = asRecord2(record?.summary);
1758
2205
  if (summary) {
1759
2206
  const statusValue = typeof summary.status === "string" ? summary.status : undefined;
1760
2207
  const fail = typeof summary.fail === "number" ? summary.fail : undefined;
@@ -1806,18 +2253,21 @@ function inferMutability(command) {
1806
2253
  return "read";
1807
2254
  }
1808
2255
  function inferWarnings(data) {
1809
- const record = asRecord(data);
2256
+ const record = asRecord2(data);
1810
2257
  const direct = record?.warnings;
1811
2258
  if (Array.isArray(direct))
1812
2259
  return direct.filter((item) => typeof item === "string");
1813
- const validation = asRecord(record?.validation);
2260
+ const validation = asRecord2(record?.validation);
1814
2261
  if (Array.isArray(validation?.warnings)) {
1815
2262
  return validation.warnings.filter((item) => typeof item === "string");
1816
2263
  }
1817
2264
  return [];
1818
2265
  }
2266
+ var DEFAULT_AGENT_MAX_OUTPUT_BYTES = 24000;
1819
2267
  function agentMaxOutputBytes() {
1820
- return Number(process.env.MODA_AGENT_MAX_OUTPUT_BYTES ?? 200000);
2268
+ const raw = process.env.MODA_AGENT_MAX_OUTPUT_BYTES;
2269
+ const value = raw === undefined || raw.trim() === "" ? Number.NaN : Number(raw);
2270
+ return Number.isFinite(value) && value > 0 ? value : DEFAULT_AGENT_MAX_OUTPUT_BYTES;
1821
2271
  }
1822
2272
  var AGENT_FULL_OUTPUT_FILE = /-\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2}-\d{3}Z-[0-9a-f]{8}\.json$/;
1823
2273
  function agentOutputRetentionMs() {
@@ -1860,6 +2310,158 @@ function writeAgentFullOutput(command, data) {
1860
2310
  return;
1861
2311
  }
1862
2312
  }
2313
+ function contentBlocksRedundant(message) {
2314
+ const blocks = message.content_blocks;
2315
+ if (!Array.isArray(blocks))
2316
+ return false;
2317
+ const content = typeof message.content === "string" ? message.content : typeof message.text === "string" ? message.text : "";
2318
+ const hasToolCalls = Array.isArray(message.tool_calls) && message.tool_calls.length > 0;
2319
+ const hasToolResults = Array.isArray(message.tool_results) && message.tool_results.length > 0;
2320
+ const texts = [];
2321
+ for (const item of blocks) {
2322
+ const block = asRecord2(item);
2323
+ if (!block)
2324
+ return false;
2325
+ if (block.type === "text") {
2326
+ if (typeof block.text !== "string")
2327
+ return false;
2328
+ texts.push(block.text);
2329
+ continue;
2330
+ }
2331
+ if (block.type === "tool_use" && hasToolCalls)
2332
+ continue;
2333
+ if (block.type === "tool_result" && hasToolResults)
2334
+ continue;
2335
+ return false;
2336
+ }
2337
+ if (texts.length === 0)
2338
+ return true;
2339
+ const trimmed = content.trim();
2340
+ return [texts.join(""), texts.join(`
2341
+ `), texts.join(`
2342
+
2343
+ `)].some((joined) => joined.trim() === trimmed);
2344
+ }
2345
+ function shedRedundantContentBlocks(value) {
2346
+ let shed = 0;
2347
+ const visit = (node) => {
2348
+ if (Array.isArray(node)) {
2349
+ for (const item of node)
2350
+ if (item && typeof item === "object")
2351
+ visit(item);
2352
+ return;
2353
+ }
2354
+ const record = asRecord2(node);
2355
+ if (!record)
2356
+ return;
2357
+ if ("content_blocks" in record && contentBlocksRedundant(record)) {
2358
+ delete record.content_blocks;
2359
+ shed += 1;
2360
+ }
2361
+ for (const item of Object.values(record))
2362
+ if (item && typeof item === "object")
2363
+ visit(item);
2364
+ };
2365
+ visit(value);
2366
+ return shed;
2367
+ }
2368
+ var CONTINUATION_SECRET_FLAGS = new Set(["api-key", "api_key", "token"]);
2369
+ function continuationCommand(invocation, overrides) {
2370
+ const normalize2 = (key) => key.replace(/_/g, "-");
2371
+ const overridden = new Set(Object.keys(overrides).map(normalize2));
2372
+ const bare = new Set((invocation.bareFlags ?? []).map(normalize2));
2373
+ const parts = ["moda", invocation.command, ...invocation.positionals.map((value) => shellWord(value))];
2374
+ for (const [key, value] of Object.entries(invocation.flags)) {
2375
+ const flag = normalize2(key);
2376
+ if (overridden.has(flag) || CONTINUATION_SECRET_FLAGS.has(flag))
2377
+ continue;
2378
+ parts.push(bare.has(flag) && value === "true" ? `--${flag}` : `--${flag}=${shellWord(String(value))}`);
2379
+ }
2380
+ for (const [key, value] of Object.entries(overrides))
2381
+ parts.push(`--${normalize2(key)}=${shellWord(String(value))}`);
2382
+ return parts.join(" ");
2383
+ }
2384
+ var PAGED_LIST_BY_COMMAND = {
2385
+ "tool-failure-detail": "examples",
2386
+ emotions: "detections",
2387
+ frustrations: "frustrations",
2388
+ "problems remainder": "groups"
2389
+ };
2390
+ function pagedListFor(invocation) {
2391
+ const subcommand = invocation.positionals[0];
2392
+ return (subcommand !== undefined ? PAGED_LIST_BY_COMMAND[`${invocation.command} ${subcommand}`] : undefined) ?? PAGED_LIST_BY_COMMAND[invocation.command];
2393
+ }
2394
+ var MAX_PAGE_OFFSET = 1e4;
2395
+ function rewritePagination(list, isTopLevel, invocation) {
2396
+ const { parent, array, originalLength } = list;
2397
+ if (!parent)
2398
+ return;
2399
+ const nested = asRecord2(parent.pagination);
2400
+ const inline = !nested && !isTopLevel && (("has_more" in parent) || ("next_cursor" in parent)) ? parent : undefined;
2401
+ const pagination = nested ?? inline;
2402
+ if (!pagination)
2403
+ return;
2404
+ const listKey = list.path.split(".").pop() ?? list.path;
2405
+ const arrayKeys = Object.keys(parent).filter((key) => Array.isArray(parent[key]));
2406
+ if (arrayKeys.length > 1) {
2407
+ const paged = invocation ? pagedListFor(invocation) : undefined;
2408
+ if (paged === undefined || paged !== listKey)
2409
+ return;
2410
+ }
2411
+ if (typeof pagination.returned === "number" ? pagination.returned !== originalLength : typeof pagination.limit === "number" && originalLength > pagination.limit) {
2412
+ return;
2413
+ }
2414
+ const kept = array.length;
2415
+ const omitted = originalLength - kept;
2416
+ const offset = typeof pagination.offset === "number" && Number.isFinite(pagination.offset) ? pagination.offset : undefined;
2417
+ const hadCursor = typeof pagination.next_cursor === "string" && pagination.next_cursor.length > 0;
2418
+ if (typeof pagination.limit === "number") {
2419
+ pagination.requested_limit = pagination.limit;
2420
+ pagination.limit = kept;
2421
+ }
2422
+ pagination.returned = kept;
2423
+ pagination.omitted_for_byte_limit = omitted;
2424
+ pagination.has_more = true;
2425
+ const pastOffsetCap = offset !== undefined && offset + kept > MAX_PAGE_OFFSET;
2426
+ if (offset !== undefined && !pastOffsetCap)
2427
+ pagination.next_offset = offset + kept;
2428
+ if (hadCursor)
2429
+ pagination.next_cursor = null;
2430
+ const where = `data.${list.path}`;
2431
+ if (pastOffsetCap) {
2432
+ return {
2433
+ note: `${where} holds ${kept} of ${originalLength} row(s); the omitted rows start past --offset=${MAX_PAGE_OFFSET}, ` + "the deepest offset the API pages to, so no --offset command can fetch them. Read them from the saved full output " + "(truncation.data.full_output_path) or rerun this page with --json"
2434
+ };
2435
+ }
2436
+ if (!isTopLevel || !invocation) {
2437
+ return { note: `${where} holds ${kept} of ${originalLength} row(s)` };
2438
+ }
2439
+ if (offset !== undefined) {
2440
+ const command = continuationCommand(invocation, { offset: offset + kept, limit: omitted });
2441
+ return {
2442
+ note: `${where} holds ${kept} of ${originalLength} row(s); pagination.next_offset=${offset + kept}. Fetch the ${omitted} omitted row(s) with: ${command}`,
2443
+ nextCommand: {
2444
+ command,
2445
+ purpose: `Fetch the ${omitted} row(s) of this page that were left out to fit the agent byte limit.`,
2446
+ mutability: "read",
2447
+ requires_approval: false
2448
+ }
2449
+ };
2450
+ }
2451
+ if (hadCursor || "next_cursor" in pagination || "cursor" in invocation.flags) {
2452
+ const command = continuationCommand(invocation, { limit: kept });
2453
+ return {
2454
+ note: `${where} holds ${kept} of ${originalLength} row(s); next_cursor was cleared because it skipped the omitted rows. Rerun ${command} for a next_cursor that starts at the first omitted row`,
2455
+ nextCommand: {
2456
+ command,
2457
+ purpose: `Re-read this page at --limit=${kept} (what fits) to get a next_cursor that starts at the first omitted row.`,
2458
+ mutability: "read",
2459
+ requires_approval: false
2460
+ }
2461
+ };
2462
+ }
2463
+ return { note: `${where} holds ${kept} of ${originalLength} row(s)` };
2464
+ }
1863
2465
  function boundForAgent(data, maxBytes = agentMaxOutputBytes(), options = {}) {
1864
2466
  const sizeOf = (value) => Buffer.byteLength(JSON.stringify(value) ?? "", "utf8");
1865
2467
  const serialized = JSON.stringify(data) ?? "";
@@ -1870,46 +2472,56 @@ function boundForAgent(data, maxBytes = agentMaxOutputBytes(), options = {}) {
1870
2472
  if (options.writeFullOutput && !fullOutputPath)
1871
2473
  return { data, saveFailed: true };
1872
2474
  const bounded = JSON.parse(serialized);
1873
- let boundedBytes = originalBytes;
2475
+ const shedContentBlocks = shedRedundantContentBlocks(bounded);
2476
+ const shedFields = shedContentBlocks > 0 ? { content_blocks: shedContentBlocks } : {};
2477
+ let boundedBytes = shedContentBlocks > 0 ? sizeOf(bounded) : originalBytes;
1874
2478
  const droppedItems = {};
1875
- const collectArrays = (value, path, out) => {
2479
+ const droppedLists = new Map;
2480
+ const collectArrays = (value, path, parent, out) => {
1876
2481
  if (Array.isArray(value)) {
1877
2482
  if (value.length > 1)
1878
- out.push({ path, array: value, itemBytes: value.map((item) => sizeOf(item) + 1) });
2483
+ out.push({ path, array: value, itemBytes: value.map((item) => sizeOf(item) + 1), parent });
1879
2484
  value.forEach((item, index) => {
1880
2485
  if (item && typeof item === "object")
1881
- collectArrays(item, `${path}[${index}]`, out);
2486
+ collectArrays(item, `${path}[${index}]`, undefined, out);
1882
2487
  });
1883
2488
  } else if (value && typeof value === "object") {
1884
- for (const [key, item] of Object.entries(value)) {
2489
+ const record = value;
2490
+ for (const [key, item] of Object.entries(record)) {
1885
2491
  if (item && typeof item === "object")
1886
- collectArrays(item, path ? `${path}.${key}` : key, out);
2492
+ collectArrays(item, path ? `${path}.${key}` : key, record, out);
1887
2493
  }
1888
2494
  }
1889
2495
  };
1890
- for (let round = 0;round < 25 && boundedBytes > maxBytes; round++) {
1891
- const arrays = [];
1892
- collectArrays(bounded, "", arrays);
1893
- const largest = arrays.map((entry) => ({ ...entry, total: entry.itemBytes.reduce((sum, bytes) => sum + bytes, 0) })).sort((left, right) => right.total - left.total)[0];
1894
- if (!largest)
1895
- break;
1896
- let overshoot = boundedBytes - maxBytes;
1897
- let drop = 0;
1898
- for (let index = largest.array.length - 1;index >= 1 && overshoot > 0; index--) {
1899
- overshoot -= largest.itemBytes[index];
1900
- drop += 1;
2496
+ if (boundedBytes > maxBytes) {
2497
+ for (let round = 0;round < 25 && boundedBytes > maxBytes; round++) {
2498
+ const arrays = [];
2499
+ collectArrays(bounded, "", undefined, arrays);
2500
+ const largest = arrays.map((entry) => ({ ...entry, total: entry.itemBytes.reduce((sum, bytes) => sum + bytes, 0) })).sort((left, right) => right.total - left.total)[0];
2501
+ if (!largest)
2502
+ break;
2503
+ let overshoot = boundedBytes - maxBytes;
2504
+ let drop = 0;
2505
+ for (let index = largest.array.length - 1;index >= 1 && overshoot > 0; index--) {
2506
+ overshoot -= largest.itemBytes[index];
2507
+ drop += 1;
2508
+ }
2509
+ if (drop === 0)
2510
+ break;
2511
+ const key = largest.path || "(root)";
2512
+ if (!droppedLists.has(key)) {
2513
+ droppedLists.set(key, { path: key, parent: largest.parent, array: largest.array, originalLength: largest.array.length });
2514
+ }
2515
+ largest.array.splice(largest.array.length - drop, drop);
2516
+ droppedItems[key] = (droppedItems[key] ?? 0) + drop;
2517
+ boundedBytes = sizeOf(bounded);
1901
2518
  }
1902
- if (drop === 0)
1903
- break;
1904
- largest.array.splice(largest.array.length - drop, drop);
1905
- const key = largest.path || "(root)";
1906
- droppedItems[key] = (droppedItems[key] ?? 0) + drop;
1907
- boundedBytes = sizeOf(bounded);
1908
2519
  }
1909
2520
  const dropped = Object.entries(droppedItems);
1910
2521
  const whereIsTheRest = fullOutputPath ? `The complete output (every item, no text shortened) is in ${fullOutputPath}; read it in line ranges or query it with jq. ` : "The complete output could not be saved to a file. ";
1911
2522
  const howToGetMore = whereIsTheRest + "Alternatively narrow the query (a smaller --limit, with --offset or --cursor paging where the command supports it), " + "rerun with --json (no byte limit), or raise MODA_AGENT_MAX_OUTPUT_BYTES.";
1912
2523
  const pathField = fullOutputPath ? { full_output_path: fullOutputPath } : {};
2524
+ const shedNote = shedContentBlocks > 0 ? `removed content_blocks from ${shedContentBlocks} message(s) whose content already holds the same text` : "";
1913
2525
  if (boundedBytes > maxBytes) {
1914
2526
  return {
1915
2527
  data: { truncated: true, original_bytes: originalBytes, max_bytes: maxBytes, ...pathField },
@@ -1920,25 +2532,45 @@ function boundForAgent(data, maxBytes = agentMaxOutputBytes(), options = {}) {
1920
2532
  fullOutputPath
1921
2533
  };
1922
2534
  }
2535
+ const root = asRecord2(bounded);
2536
+ const notes = [];
2537
+ const nextCommands = [];
2538
+ for (const list of droppedLists.values()) {
2539
+ const rewritten = rewritePagination(list, root !== undefined && list.parent === root, options.invocation);
2540
+ if (!rewritten)
2541
+ continue;
2542
+ notes.push(rewritten.note);
2543
+ if (rewritten.nextCommand)
2544
+ nextCommands.push(rewritten.nextCommand);
2545
+ }
2546
+ const omittedTotal = dropped.reduce((sum, [, count]) => sum + count, 0);
2547
+ const actions = [
2548
+ ...shedNote ? [shedNote] : [],
2549
+ ...dropped.map(([path, count]) => `dropped the last ${count} item(s) of data.${path}`)
2550
+ ];
2551
+ const warning = `Output was ${originalBytes} bytes, over the ${maxBytes}-byte agent limit: ${actions.join("; ")}.` + (notes.length > 0 ? ` ${notes.join(". ")}.` : "") + (omittedTotal > 0 ? ` ${howToGetMore}` : ` Nothing else was left out. ${whereIsTheRest}`);
1923
2552
  return {
1924
2553
  data: bounded,
1925
- warning: `Output was ${originalBytes} bytes, over the ${maxBytes}-byte agent limit: ${dropped.map(([path, count]) => `dropped the last ${count} item(s) of data.${path}`).join("; ")}. ${howToGetMore}`,
2554
+ warning,
1926
2555
  truncation: {
1927
2556
  data: {
1928
2557
  original_bytes: originalBytes,
1929
2558
  bounded_bytes: boundedBytes,
1930
2559
  max_bytes: maxBytes,
1931
2560
  reason: "agent_output_byte_limit",
2561
+ ...Object.keys(shedFields).length > 0 ? { shed_fields: shedFields } : {},
1932
2562
  dropped_items: droppedItems,
2563
+ ...omittedTotal > 0 ? { omitted_rows: omittedTotal } : {},
1933
2564
  structure_preserved: true,
1934
- complete: false,
2565
+ complete: omittedTotal === 0,
1935
2566
  ...pathField
1936
2567
  }
1937
2568
  },
1938
- fullOutputPath
2569
+ fullOutputPath,
2570
+ ...nextCommands.length > 0 ? { nextCommands } : {}
1939
2571
  };
1940
2572
  }
1941
- function asRecord(value) {
2573
+ function asRecord2(value) {
1942
2574
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
1943
2575
  }
1944
2576
  function extractSuggestedCommands(text) {
@@ -1946,4 +2578,4 @@ function extractSuggestedCommands(text) {
1946
2578
  return commands.length > 0 ? commands : undefined;
1947
2579
  }
1948
2580
 
1949
- export { PROD_BASE_URL, DEFAULT_INGEST_URL, getModaPaths, getModaDir, isLoopbackBaseUrl, describeBaseUrlSource, loadProfileConfig, saveProfileConfig, getActiveProfile, setActiveProfile, upsertProfile, clearStoredApiKeyCredentials, secretFilePathFromRef, resolveSecretReference, resolveApiKeyFromActiveProfile, resolveTenantIdFromActiveProfile, ensureSecretFilePermissions, writeSecretJsonFile, CliInputError, CliAccessError, CliInputRequiredError, CliAuthError, CliNotFoundError, CliCancellationError, isNetworkLikeError, isApiLikeError, apiErrorStatus, VERSION, MODA_BASE_URL, loadCliConfig, saveCliConfig, resolveApiKey, embeddedTenantIdFromApiKey, resolveIngestUrl2 as resolveIngestUrl, resolveTenantId, resolveApiTenantId, resolveModaBaseUrl, validateConfig, recordApiRequest, getApiRequestCount, resetApiRequestCount, MAX_SCANNED_FILE_BYTES, DEFAULT_MAX_INVENTORY_FILES, DEFAULT_MAX_INVENTORY_TEXT_BYTES, MAX_RECORDED_SKIPS, SKIPPED_DIRS, isSkippedDir, isSkippedPathPrefix, isEvalLikePath, shouldInventoryFile, isTextFile, isSecretishPath, SECRET_KEYS, redactDeep, redactString, packSnapshot, setAgentUpdateNotice, EXIT_OK, EXIT_ERROR, EXIT_DEGRADED, EXIT_AUTH_REQUIRED, EXIT_INPUT_REQUIRED, EXIT_CANCELLED, AGENT_ERROR_CODES, wasOutputCancelled, safeWriteStdout, safeWriteStderr, explicitOutputMode, outputModeFromFlags, resolveOutputMode, createCliOutput, agentEnvelopeFits, errorToAgentError, agentMaxOutputBytes };
2581
+ export { PROD_BASE_URL, DEFAULT_INGEST_URL, getModaPaths, getModaDir, isLoopbackBaseUrl, describeBaseUrlSource, loadProfileConfig, saveProfileConfig, getActiveProfile, setActiveProfile, upsertProfile, clearStoredApiKeyCredentials, secretFilePathFromRef, resolveSecretReference, resolveApiKeyFromActiveProfile, resolveTenantIdFromActiveProfile, ensureSecretFilePermissions, writeSecretJsonFile, CliInputError, CliAccessError, CliInputRequiredError, CliAuthError, CliNotFoundError, CliCancellationError, isNetworkLikeError, isApiLikeError, apiErrorStatus, VERSION, MODA_BASE_URL, loadCliConfig, saveCliConfig, resolveApiKey, embeddedTenantIdFromApiKey, resolveIngestUrl2 as resolveIngestUrl, resolveTenantId, resolveApiTenantId, resolveModaBaseUrl, validateConfig, recordApiRequest, getApiRequestCount, resetApiRequestCount, BATCH_MAX_TARGETS, BATCH_CONCURRENCY, parseBatchTarget, collectBatchTargets, mapWithConcurrency, contextTarget, asRecord, asString, asNumber, frustrationAnchorIndex, frustrationsFromEmotions, withFrustrationAnchors, shellWord, trimToolFailureConversations, withToolFailureAnchors, embeddedWindowSize, withoutDetectionWindows, compactProblemDossier, MAX_SCANNED_FILE_BYTES, DEFAULT_MAX_INVENTORY_FILES, DEFAULT_MAX_INVENTORY_TEXT_BYTES, MAX_RECORDED_SKIPS, SKIPPED_DIRS, isSkippedDir, isSkippedPathPrefix, isEvalLikePath, shouldInventoryFile, isTextFile, isSecretishPath, SECRET_KEYS, redactDeep, redactString, packSnapshot, setAgentUpdateNotice, EXIT_OK, EXIT_ERROR, EXIT_DEGRADED, EXIT_AUTH_REQUIRED, EXIT_INPUT_REQUIRED, EXIT_CANCELLED, AGENT_ERROR_CODES, wasOutputCancelled, safeWriteStdout, safeWriteStderr, explicitOutputMode, outputModeFromFlags, resolveOutputMode, createCliOutput, agentEnvelopeFits, errorToAgentError, agentMaxOutputBytes };