@moda-ai/cli 1.55.26 → 1.55.28
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/dist/{agent-nqmha8ck.js → agent-0w9rtdsw.js} +22 -16
- package/dist/cli-3n0gz4d0.js +17971 -0
- package/dist/{cli-b4740tnv.js → cli-3retgh64.js} +85 -1165
- package/dist/{cli-1mbb0ct0.js → cli-97jew729.js} +1 -1
- package/dist/{cli-sqsjd08w.js → cli-99p2jh28.js} +105 -893
- package/dist/{cli-k6q8dbpk.js → cli-9bgk5jeh.js} +8 -6
- package/dist/{cli-q6f6vrrr.js → cli-9bgnvth2.js} +5 -3
- package/dist/cli-9kfxkxmk.js +6994 -0
- package/dist/cli-cesds766.js +1516 -0
- package/dist/{cli-cdrvjva5.js → cli-dr6x0zv7.js} +28 -6
- package/dist/{cli-jtyvbd8d.js → cli-e23g9ywa.js} +1 -1
- package/dist/cli-fwpqghgc.js +569 -0
- package/dist/cli-k4tqwah4.js +89 -0
- package/dist/{cli-8tfk8qeb.js → cli-mg5zv4s6.js} +18 -15
- package/dist/{cli-jgfm7w1r.js → cli-n2hng3gv.js} +9 -6
- package/dist/cli-ns5fcnkz.js +341 -0
- package/dist/{cli-5g1tv80h.js → cli-ny48a8de.js} +12 -9
- package/dist/{cli-d577kq6h.js → cli-qpq84eee.js} +5220 -32715
- package/dist/cli-xq45etg1.js +1098 -0
- package/dist/cli-yf39avhh.js +754 -0
- package/dist/cli-yz8xcpyk.js +12 -0
- package/dist/cli.js +355 -283
- package/dist/doctor-k3ta6h2y.js +24 -0
- package/dist/{fix-crkwdkt4.js → fix-w5z02wt4.js} +47 -50
- package/dist/{harness-x3e7d68b.js → harness-7azmzytc.js} +15 -7
- package/dist/{harness-github-actions-fjhvhgpj.js → harness-github-actions-bv2qrnqb.js} +11 -5
- package/dist/harness-report-rd9c4e9v.js +54 -0
- package/dist/{index-2kf3fnnb.js → index-d1z50dsq.js} +45 -36
- package/dist/{production-intelligence-7n83c701.js → production-intelligence-wvsgjxth.js} +21 -18
- package/dist/{profile-commands-ct2t0bfr.js → profile-commands-h8evz9x0.js} +9 -5
- package/dist/prompt-attribution-1nytc9wj.js +148 -0
- package/dist/prompt-source-mcp.js +14 -7
- package/dist/prompt-sources-07tczyqa.js +19 -0
- package/dist/{prompts-92aqqb2k.js → prompts-6y9wfq5z.js} +8 -7
- package/dist/prompts-ab-ezrd63sk.js +70 -0
- package/dist/prompts-propose-2k3enm2q.js +255 -0
- package/dist/{provision-gn8raqpt.js → provision-y5bdbh4y.js} +9 -6
- package/dist/{registry-ex162j5y.js → registry-96aze5wp.js} +7 -4
- package/dist/{skills-2mbsj9bt.js → skills-j8865009.js} +7 -5
- package/dist/{sync-kghmmmk5.js → sync-ew7yvy0e.js} +16 -10
- package/package.json +1 -1
- package/skills/integration/index.json +2 -2
- package/dist/cli-bb7133m7.js +0 -144
- package/dist/doctor-w913fj4g.js +0 -22
|
@@ -1,3 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CliAccessError,
|
|
3
|
+
CliAuthError,
|
|
4
|
+
CliCancellationError,
|
|
5
|
+
CliInputError,
|
|
6
|
+
CliInputRequiredError,
|
|
7
|
+
CliNotFoundError,
|
|
8
|
+
apiErrorStatus,
|
|
9
|
+
inputDetailsOf,
|
|
10
|
+
isApiLikeError,
|
|
11
|
+
isNetworkLikeError
|
|
12
|
+
} from "./cli-k4tqwah4.js";
|
|
13
|
+
import {
|
|
14
|
+
redactDeep
|
|
15
|
+
} from "./cli-ns5fcnkz.js";
|
|
16
|
+
|
|
1
17
|
// src/profiles.ts
|
|
2
18
|
import {
|
|
3
19
|
chmodSync,
|
|
@@ -449,6 +465,14 @@ function resolveBaseUrl(options = {}) {
|
|
|
449
465
|
return PROD_BASE_URL;
|
|
450
466
|
}
|
|
451
467
|
}
|
|
468
|
+
function resolveBaseUrlStrict(options = {}) {
|
|
469
|
+
try {
|
|
470
|
+
getActiveProfile(options);
|
|
471
|
+
} catch {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
return resolveBaseUrl(options);
|
|
475
|
+
}
|
|
452
476
|
function resolveIngestUrl(options = {}) {
|
|
453
477
|
const environment = activeProfileEnvironment(options);
|
|
454
478
|
const envIngest = optionalString(getEnv(options).MODA_INGEST_URL);
|
|
@@ -531,94 +555,6 @@ function writeSecretJsonFile(path, value) {
|
|
|
531
555
|
} catch {}
|
|
532
556
|
}
|
|
533
557
|
|
|
534
|
-
// src/errors.ts
|
|
535
|
-
class CliInputError extends Error {
|
|
536
|
-
usage;
|
|
537
|
-
reason;
|
|
538
|
-
details;
|
|
539
|
-
constructor(message, usage, reason, details) {
|
|
540
|
-
super(message);
|
|
541
|
-
this.usage = usage;
|
|
542
|
-
this.reason = reason;
|
|
543
|
-
this.details = details;
|
|
544
|
-
this.name = "CliInputError";
|
|
545
|
-
}
|
|
546
|
-
}
|
|
547
|
-
var inputDetails = new WeakMap;
|
|
548
|
-
function attachInputDetails(error, details) {
|
|
549
|
-
inputDetails.set(error, details);
|
|
550
|
-
}
|
|
551
|
-
function inputDetailsOf(error) {
|
|
552
|
-
if (error instanceof CliInputError && error.details)
|
|
553
|
-
return error.details;
|
|
554
|
-
return error !== null && typeof error === "object" ? inputDetails.get(error) : undefined;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
class CliAccessError extends Error {
|
|
558
|
-
guidance;
|
|
559
|
-
constructor(message, options = {}) {
|
|
560
|
-
super(message);
|
|
561
|
-
this.name = "CliAccessError";
|
|
562
|
-
this.guidance = options.guidance;
|
|
563
|
-
}
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
class CliInputRequiredError extends Error {
|
|
567
|
-
input_request;
|
|
568
|
-
constructor(message, input_request, usage) {
|
|
569
|
-
super(message);
|
|
570
|
-
this.input_request = input_request;
|
|
571
|
-
this.name = "CliInputRequiredError";
|
|
572
|
-
if (usage)
|
|
573
|
-
this.usage = usage;
|
|
574
|
-
}
|
|
575
|
-
usage;
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
class CliAuthError extends Error {
|
|
579
|
-
auth;
|
|
580
|
-
constructor(message, auth, usage) {
|
|
581
|
-
super(message);
|
|
582
|
-
this.auth = auth;
|
|
583
|
-
this.name = "CliAuthError";
|
|
584
|
-
if (usage)
|
|
585
|
-
this.usage = usage;
|
|
586
|
-
}
|
|
587
|
-
usage;
|
|
588
|
-
}
|
|
589
|
-
|
|
590
|
-
class CliNotFoundError extends Error {
|
|
591
|
-
entity;
|
|
592
|
-
id;
|
|
593
|
-
usage;
|
|
594
|
-
constructor(entity, id, message, usage) {
|
|
595
|
-
super(message ?? `No ${entity} found for id "${id}" in this tenant.`);
|
|
596
|
-
this.entity = entity;
|
|
597
|
-
this.id = id;
|
|
598
|
-
this.usage = usage;
|
|
599
|
-
this.name = "CliNotFoundError";
|
|
600
|
-
}
|
|
601
|
-
}
|
|
602
|
-
|
|
603
|
-
class CliCancellationError extends Error {
|
|
604
|
-
constructor(message) {
|
|
605
|
-
super(message);
|
|
606
|
-
this.name = "CliCancellationError";
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
function isNetworkLikeError(error) {
|
|
610
|
-
return error instanceof Error && (error.message.startsWith("Network error:") || error.message.startsWith("Request timed out") || error.name === "AbortError" || /(?:ECONNRESET|ECONNREFUSED|ETIMEDOUT|ENOTFOUND|socket hang up)/i.test(error.message));
|
|
611
|
-
}
|
|
612
|
-
function isApiLikeError(error) {
|
|
613
|
-
return error instanceof Error && (error.name === "ApiError" || ("statusCode" in error) && typeof error.statusCode === "number");
|
|
614
|
-
}
|
|
615
|
-
function apiErrorStatus(error) {
|
|
616
|
-
if (!isApiLikeError(error))
|
|
617
|
-
return;
|
|
618
|
-
const status = error.statusCode;
|
|
619
|
-
return typeof status === "number" ? status : undefined;
|
|
620
|
-
}
|
|
621
|
-
|
|
622
558
|
// src/config.ts
|
|
623
559
|
import { readFileSync as readFileSync2 } from "node:fs";
|
|
624
560
|
var pkg = JSON.parse(readFileSync2(new URL("../package.json", import.meta.url), "utf8"));
|
|
@@ -663,11 +599,12 @@ function resolveApiTenantId(options = {}) {
|
|
|
663
599
|
const apiKey = resolveApiKey(options);
|
|
664
600
|
return (apiKey ? embeddedTenantIdFromApiKey(apiKey) : undefined) || resolveTenantId(options);
|
|
665
601
|
}
|
|
666
|
-
var MODA_API_KEY = process.env.MODA_API_KEY;
|
|
667
|
-
var MODA_INGEST_URL = process.env.MODA_INGEST_URL || DEFAULT_INGEST_URL;
|
|
668
602
|
function resolveModaBaseUrl(options = {}) {
|
|
669
603
|
return resolveBaseUrl(options) || PROD_BASE_URL;
|
|
670
604
|
}
|
|
605
|
+
function resolveModaBaseUrlStrict(options = {}) {
|
|
606
|
+
return resolveBaseUrlStrict(options);
|
|
607
|
+
}
|
|
671
608
|
function validateConfig() {
|
|
672
609
|
if (!resolveApiKey()) {
|
|
673
610
|
throw new CliAuthError('No Moda API key found. Set MODA_API_KEY=moda_sk_... in the environment, save one with "moda auth login --api-key", or run "moda init" for interactive setup.', {
|
|
@@ -677,6 +614,31 @@ function validateConfig() {
|
|
|
677
614
|
}
|
|
678
615
|
}
|
|
679
616
|
|
|
617
|
+
// src/api-key-headers.ts
|
|
618
|
+
var PLATFORM_API_KEY_PREFIX = "moda_pk_";
|
|
619
|
+
var TENANT_HEADER = "x-moda-tenant-id";
|
|
620
|
+
function isPlatformApiKey(key) {
|
|
621
|
+
return Boolean(key?.startsWith(PLATFORM_API_KEY_PREFIX));
|
|
622
|
+
}
|
|
623
|
+
var platformTenantOverride;
|
|
624
|
+
function setPlatformTenantOverride(tenantId) {
|
|
625
|
+
platformTenantOverride = tenantId;
|
|
626
|
+
}
|
|
627
|
+
var TENANT_PATH = /\/tenants\/([^/?#]+)/;
|
|
628
|
+
function tenantFromUrl(url) {
|
|
629
|
+
const match = url ? TENANT_PATH.exec(url) : null;
|
|
630
|
+
return match ? decodeURIComponent(match[1]) : undefined;
|
|
631
|
+
}
|
|
632
|
+
function apiKeyHeaders(key, options = {}, url) {
|
|
633
|
+
const headers = { "x-api-key": key };
|
|
634
|
+
if (isPlatformApiKey(key)) {
|
|
635
|
+
const tenantId = tenantFromUrl(url) || platformTenantOverride || resolveTenantId(options);
|
|
636
|
+
if (tenantId)
|
|
637
|
+
headers[TENANT_HEADER] = tenantId;
|
|
638
|
+
}
|
|
639
|
+
return headers;
|
|
640
|
+
}
|
|
641
|
+
|
|
680
642
|
// src/api-request-count.ts
|
|
681
643
|
var apiRequestCount = 0;
|
|
682
644
|
function recordApiRequest() {
|
|
@@ -689,765 +651,13 @@ function resetApiRequestCount() {
|
|
|
689
651
|
apiRequestCount = 0;
|
|
690
652
|
}
|
|
691
653
|
|
|
692
|
-
//
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
var DEFAULT_MAX_INVENTORY_TEXT_BYTES = 48 * 1024 * 1024;
|
|
696
|
-
var MAX_SNAPSHOT_BODY_BYTES = 4500000;
|
|
697
|
-
var MAX_RECORDED_SKIPS = 1000;
|
|
698
|
-
var SKIPPED_DIRS = new Set([
|
|
699
|
-
".angular",
|
|
700
|
-
".cache",
|
|
701
|
-
".expo",
|
|
702
|
-
".git",
|
|
703
|
-
".hg",
|
|
704
|
-
".idea",
|
|
705
|
-
".svn",
|
|
706
|
-
".next",
|
|
707
|
-
".nuxt",
|
|
708
|
-
".output",
|
|
709
|
-
".parcel-cache",
|
|
710
|
-
".pytest_cache",
|
|
711
|
-
".ruff_cache",
|
|
712
|
-
".serverless",
|
|
713
|
-
".sst",
|
|
714
|
-
".turbo",
|
|
715
|
-
".wrangler",
|
|
716
|
-
".wrangler-shared",
|
|
717
|
-
".moda",
|
|
718
|
-
".moda-test",
|
|
719
|
-
".moda-test-home",
|
|
720
|
-
".moda-cli-workspaces",
|
|
721
|
-
".moda-cli-benchmarks",
|
|
722
|
-
"node_modules",
|
|
723
|
-
"dist",
|
|
724
|
-
"build",
|
|
725
|
-
"coverage",
|
|
726
|
-
"out",
|
|
727
|
-
"target",
|
|
728
|
-
"logs",
|
|
729
|
-
"tmp",
|
|
730
|
-
"temp",
|
|
731
|
-
"__pycache__",
|
|
732
|
-
".venv",
|
|
733
|
-
"venv"
|
|
734
|
-
]);
|
|
735
|
-
var SKIPPED_PATH_PREFIXES = [
|
|
736
|
-
".claude/worktrees",
|
|
737
|
-
".codex/environments"
|
|
738
|
-
];
|
|
739
|
-
function posixNormalize(path) {
|
|
740
|
-
const absolute = path.startsWith("/");
|
|
741
|
-
const parts = path.split("/").filter((part) => part !== "" && part !== ".");
|
|
742
|
-
const normalized = parts.join("/");
|
|
743
|
-
return absolute ? `/${normalized}` : normalized;
|
|
744
|
-
}
|
|
745
|
-
function basename(path) {
|
|
746
|
-
const normalized = posixNormalize(path);
|
|
747
|
-
const index = normalized.lastIndexOf("/");
|
|
748
|
-
return index === -1 ? normalized : normalized.slice(index + 1);
|
|
749
|
-
}
|
|
750
|
-
function extname(path) {
|
|
751
|
-
const name = basename(path);
|
|
752
|
-
const index = name.lastIndexOf(".");
|
|
753
|
-
return index <= 0 ? "" : name.slice(index);
|
|
754
|
-
}
|
|
755
|
-
function isSkippedDir(path) {
|
|
756
|
-
return SKIPPED_DIRS.has(basename(path));
|
|
757
|
-
}
|
|
758
|
-
function isSkippedPathPrefix(path) {
|
|
759
|
-
const normalized = posixNormalize(path);
|
|
760
|
-
return SKIPPED_PATH_PREFIXES.some((prefix) => normalized === prefix || normalized.startsWith(`${prefix}/`));
|
|
761
|
-
}
|
|
762
|
-
function isSourceFile(path) {
|
|
763
|
-
return /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(path);
|
|
764
|
-
}
|
|
765
|
-
function isPackageOrLockfile(path) {
|
|
766
|
-
return path === "package.json" || path === "pyproject.toml" || path === "bun.lock" || path === "bun.lockb" || path === "pnpm-lock.yaml" || path === "yarn.lock";
|
|
767
|
-
}
|
|
768
|
-
function isPromptLikePath(path) {
|
|
769
|
-
return /(^|\/)prompts?\//i.test(path) && /\.(prompt\.)?(md|json|ya?ml)$/i.test(path);
|
|
770
|
-
}
|
|
771
|
-
function isSkillLikePath(path) {
|
|
772
|
-
return /(^|\/)(\.claude\/skills|\.cursor\/rules|skills?)\//i.test(path) && /\.(md|mdc)$/i.test(path);
|
|
773
|
-
}
|
|
774
|
-
function isEvalLikePath(path) {
|
|
775
|
-
return /(^|\/)(evals?|tests?|__tests__)\//i.test(path) && /\.(ts|tsx|js|mjs|py|json|ya?ml)$/i.test(path);
|
|
776
|
-
}
|
|
777
|
-
function isDeploymentLikePath(path) {
|
|
778
|
-
return /(^|\/)(wrangler\.toml|vercel\.json|render\.ya?ml|railway\.json|Dockerfile|docker-compose\.ya?ml)$/i.test(path) || /^\.github\/workflows\/[^/]+\.ya?ml$/i.test(path);
|
|
779
|
-
}
|
|
780
|
-
function isDeveloperAgentConfigPath(path) {
|
|
781
|
-
return path === ".claude/settings.json" || path === ".codex/hooks.json" || path === ".cursor/hooks.json";
|
|
782
|
-
}
|
|
783
|
-
function isReadmeOrAgents(path) {
|
|
784
|
-
const name = basename(path);
|
|
785
|
-
return name === "README.md" || name === "AGENTS.md";
|
|
786
|
-
}
|
|
787
|
-
function shouldInventoryFile(path) {
|
|
788
|
-
const normalized = posixNormalize(path);
|
|
789
|
-
const name = basename(normalized);
|
|
790
|
-
const extension = extname(normalized).toLowerCase();
|
|
791
|
-
if (isSourceFile(normalized))
|
|
792
|
-
return true;
|
|
793
|
-
if (isPackageOrLockfile(normalized))
|
|
794
|
-
return true;
|
|
795
|
-
if (isPromptLikePath(normalized))
|
|
796
|
-
return true;
|
|
797
|
-
if (isSkillLikePath(normalized))
|
|
798
|
-
return true;
|
|
799
|
-
if (isEvalLikePath(normalized))
|
|
800
|
-
return true;
|
|
801
|
-
if (isDeploymentLikePath(normalized))
|
|
802
|
-
return true;
|
|
803
|
-
if (isDeveloperAgentConfigPath(normalized))
|
|
804
|
-
return true;
|
|
805
|
-
if (isReadmeOrAgents(normalized))
|
|
806
|
-
return true;
|
|
807
|
-
return extension === ".toml" && (name === "pyproject.toml" || name === "wrangler.toml");
|
|
808
|
-
}
|
|
809
|
-
function isTextFile(path) {
|
|
810
|
-
const extension = extname(path).toLowerCase();
|
|
811
|
-
return [
|
|
812
|
-
"",
|
|
813
|
-
".cjs",
|
|
814
|
-
".js",
|
|
815
|
-
".json",
|
|
816
|
-
".jsx",
|
|
817
|
-
".md",
|
|
818
|
-
".mdc",
|
|
819
|
-
".mjs",
|
|
820
|
-
".py",
|
|
821
|
-
".toml",
|
|
822
|
-
".ts",
|
|
823
|
-
".tsx",
|
|
824
|
-
".txt",
|
|
825
|
-
".yaml",
|
|
826
|
-
".yml"
|
|
827
|
-
].includes(extension);
|
|
828
|
-
}
|
|
829
|
-
function isSecretishPath(path) {
|
|
830
|
-
const name = basename(path).toLowerCase();
|
|
831
|
-
return name === ".env" || name.startsWith(".env.") || name.includes("secret") || name.includes("private-key") || name.endsWith(".pem");
|
|
832
|
-
}
|
|
833
|
-
|
|
834
|
-
// ../../packages/harness-snapshot/src/redact.ts
|
|
835
|
-
var REDACTED = "[REDACTED]";
|
|
836
|
-
var MAX_DEPTH = 256;
|
|
837
|
-
var SECRET_KEYS = new Set([
|
|
838
|
-
"api_key",
|
|
839
|
-
"apikey",
|
|
840
|
-
"token",
|
|
841
|
-
"access_token",
|
|
842
|
-
"authorization",
|
|
843
|
-
"secret",
|
|
844
|
-
"password",
|
|
845
|
-
"cli_token"
|
|
846
|
-
]);
|
|
847
|
-
var SECRET_PATTERNS = [
|
|
848
|
-
{ pattern: /\bmoda_sk_[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
|
|
849
|
-
{ pattern: /\bmoda_pk_[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
|
|
850
|
-
{ pattern: /\bmoda_ct_[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
|
|
851
|
-
{ pattern: /\bBearer\s+([A-Za-z0-9._~+/-]+=*)\b/gi, prefixLength: 8 },
|
|
852
|
-
{ pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
|
|
853
|
-
{ pattern: /\bsk-ant-api\d{2}-[A-Za-z0-9_-]{20,}\b/g, prefixLength: 12 },
|
|
854
|
-
{ pattern: /\bsk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{20,}\b/g, prefixLength: 8 },
|
|
855
|
-
{ pattern: /\bAKIA[A-Z0-9]{16}\b/g, prefixLength: 8 },
|
|
856
|
-
{ pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g, prefixLength: 8 },
|
|
857
|
-
{ pattern: /\bgh[pousr]_[A-Za-z0-9]{36,}\b/g, prefixLength: 8 },
|
|
858
|
-
{ pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, prefixLength: 8 }
|
|
859
|
-
];
|
|
860
|
-
function redactDeep(value) {
|
|
861
|
-
return redactValue(value, 0, new WeakSet);
|
|
862
|
-
}
|
|
863
|
-
function redactValue(value, depth, seen) {
|
|
864
|
-
if (typeof value === "string")
|
|
865
|
-
return redactString(value);
|
|
866
|
-
if (value === null || typeof value !== "object")
|
|
867
|
-
return value;
|
|
868
|
-
if (depth >= MAX_DEPTH)
|
|
869
|
-
return "[MaxDepth]";
|
|
870
|
-
if (seen.has(value))
|
|
871
|
-
return "[Circular]";
|
|
872
|
-
seen.add(value);
|
|
873
|
-
if (Array.isArray(value)) {
|
|
874
|
-
try {
|
|
875
|
-
return value.map((item) => redactValue(item, depth + 1, seen));
|
|
876
|
-
} finally {
|
|
877
|
-
seen.delete(value);
|
|
878
|
-
}
|
|
879
|
-
}
|
|
880
|
-
const out = {};
|
|
881
|
-
try {
|
|
882
|
-
for (const [key, item] of Object.entries(value)) {
|
|
883
|
-
out[key] = shouldRedactKey(key) ? redactSecretValue(item) : redactValue(item, depth + 1, seen);
|
|
884
|
-
}
|
|
885
|
-
} finally {
|
|
886
|
-
seen.delete(value);
|
|
887
|
-
}
|
|
888
|
-
return out;
|
|
889
|
-
}
|
|
890
|
-
function shouldRedactKey(key) {
|
|
891
|
-
return SECRET_KEYS.has(key.replace(/[-\s]/g, "_").toLowerCase());
|
|
892
|
-
}
|
|
893
|
-
function redactSecretValue(value) {
|
|
894
|
-
if (typeof value !== "string")
|
|
895
|
-
return REDACTED;
|
|
896
|
-
const redacted = redactString(value);
|
|
897
|
-
if (redacted !== value)
|
|
898
|
-
return redacted;
|
|
899
|
-
if (/^(configured|missing|not_configured|none|present|absent)$/i.test(value))
|
|
900
|
-
return value;
|
|
901
|
-
return REDACTED;
|
|
902
|
-
}
|
|
903
|
-
function redactStringWithCount(input) {
|
|
904
|
-
let text = input;
|
|
905
|
-
let redactionCount = 0;
|
|
906
|
-
for (const { pattern, prefixLength } of SECRET_PATTERNS) {
|
|
907
|
-
text = text.replace(pattern, (match) => {
|
|
908
|
-
redactionCount += 1;
|
|
909
|
-
if (/^Bearer\s+/i.test(match)) {
|
|
910
|
-
const token = match.replace(/^Bearer\s+/i, "");
|
|
911
|
-
return `Bearer ${token.slice(0, prefixLength)}...[REDACTED]`;
|
|
912
|
-
}
|
|
913
|
-
return `${match.slice(0, prefixLength)}...[REDACTED]`;
|
|
914
|
-
});
|
|
915
|
-
}
|
|
916
|
-
return { text, redactionCount };
|
|
917
|
-
}
|
|
918
|
-
function redactString(input) {
|
|
919
|
-
return redactStringWithCount(input).text;
|
|
920
|
-
}
|
|
921
|
-
function redactSnapshotText(text) {
|
|
922
|
-
const parts = text.split(/(\r\n|\r|\n)/);
|
|
923
|
-
let redactionCount = 0;
|
|
924
|
-
for (let index = 0;index < parts.length; index += 2) {
|
|
925
|
-
const redacted = redactStringWithCount(parts[index] ?? "");
|
|
926
|
-
parts[index] = redacted.text;
|
|
927
|
-
redactionCount += redacted.redactionCount;
|
|
928
|
-
}
|
|
929
|
-
return { text: parts.join(""), redactionCount };
|
|
930
|
-
}
|
|
931
|
-
|
|
932
|
-
// ../../packages/harness-snapshot/src/pack.ts
|
|
933
|
-
function utf8ByteLength(value) {
|
|
934
|
-
let bytes = 0;
|
|
935
|
-
for (let index = 0;index < value.length; index += 1) {
|
|
936
|
-
const code = value.charCodeAt(index);
|
|
937
|
-
if (code <= 127) {
|
|
938
|
-
bytes += 1;
|
|
939
|
-
} else if (code <= 2047) {
|
|
940
|
-
bytes += 2;
|
|
941
|
-
} else if (code >= 55296 && code <= 56319) {
|
|
942
|
-
const next = value.charCodeAt(index + 1);
|
|
943
|
-
if (next >= 56320 && next <= 57343) {
|
|
944
|
-
bytes += 4;
|
|
945
|
-
index += 1;
|
|
946
|
-
} else {
|
|
947
|
-
bytes += 3;
|
|
948
|
-
}
|
|
949
|
-
} else {
|
|
950
|
-
bytes += 3;
|
|
951
|
-
}
|
|
952
|
-
}
|
|
953
|
-
return bytes;
|
|
954
|
-
}
|
|
955
|
-
function isValidRelativePath(path) {
|
|
956
|
-
if (path.length === 0 || path.startsWith("/") || path.includes("\\"))
|
|
957
|
-
return false;
|
|
958
|
-
return !path.split("/").some((part) => part === "..");
|
|
959
|
-
}
|
|
960
|
-
function packSnapshot(inputs, opts) {
|
|
961
|
-
const maxFiles = opts.maxFiles ?? DEFAULT_MAX_INVENTORY_FILES;
|
|
962
|
-
const maxTextBytes = opts.maxTextBytes ?? DEFAULT_MAX_INVENTORY_TEXT_BYTES;
|
|
963
|
-
const maxSnapshotBytes = opts.maxSnapshotBytes ?? MAX_SNAPSHOT_BODY_BYTES;
|
|
964
|
-
const files = [];
|
|
965
|
-
const skips = [];
|
|
966
|
-
let inventoryTextBytes = 0;
|
|
967
|
-
let serializedBytes = 0;
|
|
968
|
-
let byteCount = 0;
|
|
969
|
-
let truncated = false;
|
|
970
|
-
const recordSkip = (path, reason) => {
|
|
971
|
-
if (skips.length < MAX_RECORDED_SKIPS)
|
|
972
|
-
skips.push({ path, reason });
|
|
973
|
-
};
|
|
974
|
-
const sorted = [...inputs].sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
|
|
975
|
-
for (const input of sorted) {
|
|
976
|
-
if (!isValidRelativePath(input.path)) {
|
|
977
|
-
recordSkip(input.path, "invalid relative path");
|
|
978
|
-
continue;
|
|
979
|
-
}
|
|
980
|
-
const path = posixNormalize(input.path);
|
|
981
|
-
if (input.isSymlink) {
|
|
982
|
-
recordSkip(path, "symlink skipped for safety");
|
|
983
|
-
continue;
|
|
984
|
-
}
|
|
985
|
-
if (isSecretishPath(path)) {
|
|
986
|
-
recordSkip(path, "secret-bearing path");
|
|
987
|
-
continue;
|
|
988
|
-
}
|
|
989
|
-
if (!shouldInventoryFile(path)) {
|
|
990
|
-
recordSkip(path, "not an inventory file");
|
|
991
|
-
continue;
|
|
992
|
-
}
|
|
993
|
-
if (!isTextFile(path)) {
|
|
994
|
-
recordSkip(path, "non-text file");
|
|
995
|
-
continue;
|
|
996
|
-
}
|
|
997
|
-
if (input.byteSize > MAX_SCANNED_FILE_BYTES) {
|
|
998
|
-
recordSkip(path, "file too large");
|
|
999
|
-
truncated = true;
|
|
1000
|
-
continue;
|
|
1001
|
-
}
|
|
1002
|
-
if (files.length >= maxFiles || inventoryTextBytes + input.byteSize > maxTextBytes) {
|
|
1003
|
-
recordSkip(path, "inventory budget");
|
|
1004
|
-
truncated = true;
|
|
1005
|
-
continue;
|
|
1006
|
-
}
|
|
1007
|
-
const text = opts.redact === false ? input.text : redactSnapshotText(input.text).text;
|
|
1008
|
-
const file = { path, text };
|
|
1009
|
-
const serializedCost = utf8ByteLength(JSON.stringify(file)) + 1;
|
|
1010
|
-
if (serializedBytes + serializedCost > maxSnapshotBytes) {
|
|
1011
|
-
recordSkip(path, "snapshot budget");
|
|
1012
|
-
truncated = true;
|
|
1013
|
-
break;
|
|
1014
|
-
}
|
|
1015
|
-
files.push(file);
|
|
1016
|
-
inventoryTextBytes += input.byteSize;
|
|
1017
|
-
serializedBytes += serializedCost;
|
|
1018
|
-
byteCount += utf8ByteLength(text);
|
|
1019
|
-
}
|
|
1020
|
-
return {
|
|
1021
|
-
snapshot: {
|
|
1022
|
-
repo: { name: opts.repoName, root: "." },
|
|
1023
|
-
files,
|
|
1024
|
-
truncated,
|
|
1025
|
-
fileCount: files.length,
|
|
1026
|
-
byteCount,
|
|
1027
|
-
...opts.gitCommit ? { gitCommit: opts.gitCommit } : {}
|
|
1028
|
-
},
|
|
1029
|
-
skips
|
|
1030
|
-
};
|
|
1031
|
-
}
|
|
1032
|
-
// src/batch-reads.ts
|
|
1033
|
-
import { readFile } from "node:fs/promises";
|
|
1034
|
-
var BATCH_MAX_TARGETS = 25;
|
|
1035
|
-
var BATCH_CONCURRENCY = 4;
|
|
1036
|
-
var ANCHOR_SUFFIX = /^(.+)@(\d+)$/;
|
|
1037
|
-
function parseBatchTarget(text, anchors, usage) {
|
|
1038
|
-
const raw = text.trim();
|
|
1039
|
-
if (raw.startsWith("{")) {
|
|
1040
|
-
let parsed;
|
|
1041
|
-
try {
|
|
1042
|
-
parsed = JSON.parse(raw);
|
|
1043
|
-
} catch {
|
|
1044
|
-
throw new CliInputError(`Could not parse the JSON target ${JSON.stringify(raw)}.`, usage, "bad_batch_target");
|
|
1045
|
-
}
|
|
1046
|
-
const record = parsed;
|
|
1047
|
-
const id = record?.id ?? record?.conversation_id ?? record?.trace_id;
|
|
1048
|
-
if (typeof id !== "string" || id.trim() === "") {
|
|
1049
|
-
throw new CliInputError(`JSON target ${JSON.stringify(raw)} has no "id" string.`, usage, "bad_batch_target");
|
|
1050
|
-
}
|
|
1051
|
-
const index = record.msg_index ?? record.message_index;
|
|
1052
|
-
if (index !== undefined && index !== null) {
|
|
1053
|
-
if (!anchors) {
|
|
1054
|
-
throw new CliInputError(`JSON target ${JSON.stringify(raw)} has a msg_index, which this command does not take.`, usage, "bad_batch_target");
|
|
1055
|
-
}
|
|
1056
|
-
if (typeof index !== "number" || !Number.isSafeInteger(index) || index < 0) {
|
|
1057
|
-
throw new CliInputError(`JSON target ${JSON.stringify(raw)} has an invalid msg_index (want an integer >= 0).`, usage, "bad_batch_target");
|
|
1058
|
-
}
|
|
1059
|
-
return { raw, id, msgIndex: index };
|
|
1060
|
-
}
|
|
1061
|
-
return { raw, id };
|
|
1062
|
-
}
|
|
1063
|
-
if (anchors) {
|
|
1064
|
-
const match = ANCHOR_SUFFIX.exec(raw);
|
|
1065
|
-
if (match) {
|
|
1066
|
-
const msgIndex = Number(match[2]);
|
|
1067
|
-
if (!Number.isSafeInteger(msgIndex)) {
|
|
1068
|
-
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");
|
|
1069
|
-
}
|
|
1070
|
-
return { raw, id: match[1], msgIndex };
|
|
1071
|
-
}
|
|
1072
|
-
}
|
|
1073
|
-
return { raw, id: raw };
|
|
1074
|
-
}
|
|
1075
|
-
function parseTargetLines(text, anchors, usage) {
|
|
1076
|
-
return text.split(/\r?\n/).map((line) => line.trim()).filter((line) => line !== "").map((line) => parseBatchTarget(line, anchors, usage));
|
|
1077
|
-
}
|
|
1078
|
-
async function readStdinText() {
|
|
1079
|
-
if (process.stdin.isTTY) {
|
|
1080
|
-
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");
|
|
1081
|
-
}
|
|
1082
|
-
const chunks = [];
|
|
1083
|
-
for await (const chunk of process.stdin)
|
|
1084
|
-
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
1085
|
-
return Buffer.concat(chunks).toString("utf8");
|
|
1086
|
-
}
|
|
1087
|
-
async function readIdsFrom(source, usage) {
|
|
1088
|
-
if (source === "" || source === "true") {
|
|
1089
|
-
throw new CliInputError("--ids-from needs a value: - (stdin) or a file path.", usage, "missing_flag_value");
|
|
1090
|
-
}
|
|
1091
|
-
if (source === "-")
|
|
1092
|
-
return readStdinText();
|
|
1093
|
-
try {
|
|
1094
|
-
return await readFile(source, "utf8");
|
|
1095
|
-
} catch (error) {
|
|
1096
|
-
const code = error.code;
|
|
1097
|
-
throw new CliInputError(`Could not read --ids-from file ${JSON.stringify(source)}${typeof code === "string" ? ` (${code})` : ""}.`, usage, "ids_from_unreadable");
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
async function collectBatchTargets(positionals, idsFrom, options) {
|
|
1101
|
-
const targets = positionals.map((value) => parseBatchTarget(value, options.anchors, options.usage));
|
|
1102
|
-
if (idsFrom !== undefined) {
|
|
1103
|
-
targets.push(...parseTargetLines(await readIdsFrom(idsFrom, options.usage), options.anchors, options.usage));
|
|
1104
|
-
}
|
|
1105
|
-
const seen = new Set;
|
|
1106
|
-
const unique = targets.filter((target) => {
|
|
1107
|
-
const key = `${target.id}\x00${target.msgIndex ?? ""}`;
|
|
1108
|
-
if (seen.has(key))
|
|
1109
|
-
return false;
|
|
1110
|
-
seen.add(key);
|
|
1111
|
-
return true;
|
|
1112
|
-
});
|
|
1113
|
-
if (unique.length === 0) {
|
|
1114
|
-
throw new CliInputError(`No targets: --ids-from gave no ids (one per line).`, options.usage, "missing_positional");
|
|
1115
|
-
}
|
|
1116
|
-
if (unique.length > BATCH_MAX_TARGETS) {
|
|
1117
|
-
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");
|
|
1118
|
-
}
|
|
1119
|
-
return unique;
|
|
1120
|
-
}
|
|
1121
|
-
async function mapWithConcurrency(items, limit, fn, options = {}) {
|
|
1122
|
-
const results = new Array(items.length);
|
|
1123
|
-
let next = 0;
|
|
1124
|
-
let failure;
|
|
1125
|
-
const worker = async () => {
|
|
1126
|
-
while (!failure && next < items.length && (options.shouldStart?.(next) ?? true)) {
|
|
1127
|
-
const index = next++;
|
|
1128
|
-
try {
|
|
1129
|
-
results[index] = await fn(items[index], index);
|
|
1130
|
-
} catch (error) {
|
|
1131
|
-
failure ??= { error };
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
};
|
|
1135
|
-
await Promise.all(Array.from({ length: Math.max(1, Math.min(limit, items.length)) }, worker));
|
|
1136
|
-
if (failure)
|
|
1137
|
-
throw failure.error;
|
|
1138
|
-
return next < items.length ? results.slice(0, next) : results;
|
|
1139
|
-
}
|
|
1140
|
-
function idNeedsJsonTarget(id) {
|
|
1141
|
-
return ANCHOR_SUFFIX.test(id);
|
|
1142
|
-
}
|
|
1143
|
-
function contextTarget(id) {
|
|
1144
|
-
const verbatim = id === id.trim() && !id.startsWith("{") && !idNeedsJsonTarget(id);
|
|
1145
|
-
return verbatim ? id : JSON.stringify({ id });
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
// src/transforms.ts
|
|
1149
|
-
function asRecord(value) {
|
|
1150
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
654
|
+
// src/shell-quote.ts
|
|
655
|
+
function shellArg(value) {
|
|
656
|
+
if (/^[A-Za-z0-9_.,:@%+/=-]+$/.test(value))
|
|
1151
657
|
return value;
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
}
|
|
1155
|
-
function asString(value) {
|
|
1156
|
-
return typeof value === "string" ? value : null;
|
|
1157
|
-
}
|
|
1158
|
-
function asNumber(value) {
|
|
1159
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
1160
|
-
}
|
|
1161
|
-
function frustrationAnchorIndex(row) {
|
|
1162
|
-
if (!row)
|
|
1163
|
-
return null;
|
|
1164
|
-
const userQuotes = Array.isArray(row.user_quotes) ? row.user_quotes : [];
|
|
1165
|
-
const firstQuote = asRecord(userQuotes[0]);
|
|
1166
|
-
const resolved = asNumber(firstQuote?.msg_index) ?? asNumber(row.anchor_msg_index);
|
|
1167
|
-
if (resolved !== null)
|
|
1168
|
-
return resolved;
|
|
1169
|
-
const keyTurns = Array.isArray(row.key_turns) ? row.key_turns : [];
|
|
1170
|
-
const firstTurn = keyTurns.find((t) => typeof t === "number");
|
|
1171
|
-
if (firstTurn !== undefined)
|
|
1172
|
-
return firstTurn;
|
|
1173
|
-
return asNumber(firstQuote?.turn);
|
|
1174
|
-
}
|
|
1175
|
-
function buildFrustrationAnchor(row) {
|
|
1176
|
-
const conversation_id = asString(row.conversation_id) ?? "";
|
|
1177
|
-
const userQuotes = Array.isArray(row.user_quotes) ? row.user_quotes : [];
|
|
1178
|
-
const firstQuote = asRecord(userQuotes[0]);
|
|
1179
|
-
const keyTurnsRaw = Array.isArray(row.key_turns) ? row.key_turns : [];
|
|
1180
|
-
const all_turns = keyTurnsRaw.filter((t) => typeof t === "number");
|
|
1181
|
-
const msg_index = frustrationAnchorIndex(row);
|
|
1182
|
-
let signal = null;
|
|
1183
|
-
let quote_preview = null;
|
|
1184
|
-
if (firstQuote) {
|
|
1185
|
-
signal = asString(firstQuote.signal);
|
|
1186
|
-
const quote = asString(firstQuote.quote);
|
|
1187
|
-
if (quote !== null) {
|
|
1188
|
-
let end = 0;
|
|
1189
|
-
let points = 0;
|
|
1190
|
-
for (const ch of quote) {
|
|
1191
|
-
if (points++ === 200)
|
|
1192
|
-
break;
|
|
1193
|
-
end += ch.length;
|
|
1194
|
-
}
|
|
1195
|
-
quote_preview = quote.slice(0, end);
|
|
1196
|
-
}
|
|
1197
|
-
}
|
|
1198
|
-
return {
|
|
1199
|
-
kind: "frustration",
|
|
1200
|
-
conversation_id,
|
|
1201
|
-
msg_index,
|
|
1202
|
-
signal,
|
|
1203
|
-
quote_preview,
|
|
1204
|
-
all_turns,
|
|
1205
|
-
no_anchor: msg_index === null
|
|
1206
|
-
};
|
|
1207
|
-
}
|
|
1208
|
-
function buildToolFailureAnchor(row, toolName) {
|
|
1209
|
-
const conversation_id = asString(row.conversation_id) ?? "";
|
|
1210
|
-
const msg_index = asNumber(row.msg_index);
|
|
1211
|
-
const tool_use_id = asString(row.tool_use_id);
|
|
1212
|
-
const error_subtype = asString(row.error_subtype);
|
|
1213
|
-
return {
|
|
1214
|
-
kind: "tool_failure",
|
|
1215
|
-
conversation_id,
|
|
1216
|
-
msg_index,
|
|
1217
|
-
tool_name: toolName,
|
|
1218
|
-
tool_use_id,
|
|
1219
|
-
error_subtype,
|
|
1220
|
-
no_anchor: msg_index === null
|
|
1221
|
-
};
|
|
1222
|
-
}
|
|
1223
|
-
function frustrationsFromEmotions(response) {
|
|
1224
|
-
if (!Array.isArray(response.detections) || Array.isArray(response.frustrations))
|
|
1225
|
-
return response;
|
|
1226
|
-
const summary = asRecord(response.summary) ?? {};
|
|
1227
|
-
const pagination = asRecord(response.pagination) ?? {};
|
|
1228
|
-
const byFamily = asRecord(summary.by_family) ?? {};
|
|
1229
|
-
const totalAnalyzed = asNumber(summary.conversations_analyzed) ?? 0;
|
|
1230
|
-
const byFamilyConversations = asRecord(summary.conversations_by_family);
|
|
1231
|
-
const frustrated = asNumber(byFamilyConversations?.frustration) ?? asNumber(byFamily.frustration) ?? 0;
|
|
1232
|
-
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 }) => ({
|
|
1233
|
-
...row,
|
|
1234
|
-
is_frustrated: is_detected === true,
|
|
1235
|
-
frustration_score: score,
|
|
1236
|
-
target: row.elicitor === "bot" || row.elicitor === "external" ? row.elicitor : "ambiguous",
|
|
1237
|
-
conversation: conversation_context ?? null
|
|
1238
|
-
}));
|
|
1239
|
-
const atRisk = asNumber(pagination.at_risk) ?? Math.max(0, (asNumber(pagination.total) ?? 0) - frustrated);
|
|
1240
|
-
const signalBreakdown = {};
|
|
1241
|
-
for (const item of Array.isArray(response.signal_breakdown) ? response.signal_breakdown : []) {
|
|
1242
|
-
const row = asRecord(item);
|
|
1243
|
-
if (row?.family === "frustration" && typeof row.signal === "string") {
|
|
1244
|
-
signalBreakdown[row.signal] = asNumber(row.count) ?? 0;
|
|
1245
|
-
}
|
|
1246
|
-
}
|
|
1247
|
-
const { detections: _detections, ...rest } = response;
|
|
1248
|
-
return {
|
|
1249
|
-
...rest,
|
|
1250
|
-
summary: {
|
|
1251
|
-
total_analyzed: totalAnalyzed,
|
|
1252
|
-
frustrated_count: frustrated,
|
|
1253
|
-
at_risk_count: atRisk,
|
|
1254
|
-
frustration_rate_pct: totalAnalyzed > 0 ? Math.round(frustrated / totalAnalyzed * 1000) / 10 : 0
|
|
1255
|
-
},
|
|
1256
|
-
signal_breakdown: signalBreakdown,
|
|
1257
|
-
frustrations,
|
|
1258
|
-
source: "emotion_detections"
|
|
1259
|
-
};
|
|
1260
|
-
}
|
|
1261
|
-
function withFrustrationAnchors(response) {
|
|
1262
|
-
if (!Array.isArray(response.frustrations))
|
|
1263
|
-
return response;
|
|
1264
|
-
const frustrations = response.frustrations.map((item) => {
|
|
1265
|
-
const row = asRecord(item);
|
|
1266
|
-
if (!row)
|
|
1267
|
-
return item;
|
|
1268
|
-
const anchor = buildFrustrationAnchor(row);
|
|
1269
|
-
return { ...row, anchor };
|
|
1270
|
-
});
|
|
1271
|
-
return { ...response, frustrations };
|
|
1272
|
-
}
|
|
1273
|
-
var TOOL_FAILURE_CONTEXT_RADIUS = 2;
|
|
1274
|
-
function shellWord(value) {
|
|
1275
|
-
return /^[\w@%+=:,./-]+$/.test(value) ? value : `'${value.replace(/'/g, `'\\''`)}'`;
|
|
1276
|
-
}
|
|
1277
|
-
function trimFailureWindow(value, radius, fallbackCenter) {
|
|
1278
|
-
const conv = asRecord(value);
|
|
1279
|
-
if (!conv)
|
|
1280
|
-
return value ?? null;
|
|
1281
|
-
const { coverage: _coverage, context, ...convRest } = conv;
|
|
1282
|
-
const ctx = asRecord(context);
|
|
1283
|
-
if (!ctx)
|
|
1284
|
-
return convRest;
|
|
1285
|
-
const center = asNumber(ctx.center_index) ?? fallbackCenter;
|
|
1286
|
-
const messages = (Array.isArray(ctx.messages) ? ctx.messages : []).map((message) => asRecord(message)).filter((message) => {
|
|
1287
|
-
const index = asNumber(message?.index);
|
|
1288
|
-
return message !== null && (center === null || index === null || Math.abs(index - center) <= radius);
|
|
1289
|
-
}).map(({ content_blocks, ...message }) => {
|
|
1290
|
-
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;
|
|
1291
|
-
return covered || content_blocks === undefined ? message : { ...message, content_blocks };
|
|
1292
|
-
});
|
|
1293
|
-
const indexes = messages.map((message) => asNumber(message.index)).filter((index) => index !== null);
|
|
1294
|
-
return {
|
|
1295
|
-
...convRest,
|
|
1296
|
-
context: {
|
|
1297
|
-
...ctx,
|
|
1298
|
-
...indexes.length > 0 ? { from_index: Math.min(...indexes), to_index: Math.max(...indexes) } : {},
|
|
1299
|
-
messages
|
|
1300
|
-
}
|
|
1301
|
-
};
|
|
1302
|
-
}
|
|
1303
|
-
function trimToolFailureConversations(response, opts) {
|
|
1304
|
-
if (!Array.isArray(response.examples))
|
|
1305
|
-
return response;
|
|
1306
|
-
const examples = response.examples.map((item) => {
|
|
1307
|
-
const row = asRecord(item);
|
|
1308
|
-
if (!row)
|
|
1309
|
-
return item;
|
|
1310
|
-
const { conversation, window, ...rest } = row;
|
|
1311
|
-
const conversationId = asString(row.conversation_id);
|
|
1312
|
-
const msgIndex = asNumber(asRecord(row.anchor)?.msg_index) ?? asNumber(row.msg_index);
|
|
1313
|
-
return {
|
|
1314
|
-
...rest,
|
|
1315
|
-
...conversationId && msgIndex !== null ? { context_command: `moda traces get ${shellWord(contextTarget(conversationId))} --msg-index=${msgIndex} --window=${TOOL_FAILURE_CONTEXT_RADIUS}` } : {},
|
|
1316
|
-
...opts.drop ? {} : { conversation: trimFailureWindow(conversation, TOOL_FAILURE_CONTEXT_RADIUS, msgIndex) },
|
|
1317
|
-
..."window" in row ? { window: trimFailureWindow(window, opts.windowRadius ?? TOOL_FAILURE_CONTEXT_RADIUS, msgIndex) } : {}
|
|
1318
|
-
};
|
|
1319
|
-
});
|
|
1320
|
-
return { ...response, examples };
|
|
1321
|
-
}
|
|
1322
|
-
function withToolFailureAnchors(response) {
|
|
1323
|
-
if (!Array.isArray(response.examples))
|
|
1324
|
-
return response;
|
|
1325
|
-
const toolName = asString(response.tool_name) ?? "";
|
|
1326
|
-
const examples = response.examples.map((item) => {
|
|
1327
|
-
const row = asRecord(item);
|
|
1328
|
-
if (!row)
|
|
1329
|
-
return item;
|
|
1330
|
-
const anchor = buildToolFailureAnchor(row, toolName);
|
|
1331
|
-
return { ...row, anchor };
|
|
1332
|
-
});
|
|
1333
|
-
return { ...response, examples };
|
|
1334
|
-
}
|
|
1335
|
-
function embeddedWindowSize(conversation) {
|
|
1336
|
-
if (!conversation)
|
|
1337
|
-
return null;
|
|
1338
|
-
const ctx = asRecord(conversation.context);
|
|
1339
|
-
if (!ctx)
|
|
1340
|
-
return null;
|
|
1341
|
-
const center = asNumber(ctx.center_index);
|
|
1342
|
-
const from = asNumber(ctx.from_index);
|
|
1343
|
-
const to = asNumber(ctx.to_index);
|
|
1344
|
-
if (center === null || from === null || to === null)
|
|
1345
|
-
return null;
|
|
1346
|
-
return Math.min(center - from, to - center);
|
|
1347
|
-
}
|
|
1348
|
-
var DETECTION_CONTEXT_RADIUS = 2;
|
|
1349
|
-
function withoutDetectionWindows(response, listKey, windowKey) {
|
|
1350
|
-
const list = response[listKey];
|
|
1351
|
-
if (!Array.isArray(list))
|
|
1352
|
-
return response;
|
|
1353
|
-
const rows = list.map((item) => {
|
|
1354
|
-
const row = asRecord(item);
|
|
1355
|
-
if (!row)
|
|
1356
|
-
return item;
|
|
1357
|
-
const { [windowKey]: _window, ...rest } = row;
|
|
1358
|
-
const conversationId = asString(row.conversation_id);
|
|
1359
|
-
const msgIndex = asNumber(asRecord(row.anchor)?.msg_index) ?? frustrationAnchorIndex(row);
|
|
1360
|
-
return {
|
|
1361
|
-
...rest,
|
|
1362
|
-
...conversationId && msgIndex !== null ? { context_command: `moda traces get ${shellWord(contextTarget(conversationId))} --msg-index=${msgIndex} --window=${DETECTION_CONTEXT_RADIUS}` } : {}
|
|
1363
|
-
};
|
|
1364
|
-
});
|
|
1365
|
-
return { ...response, [listKey]: rows };
|
|
1366
|
-
}
|
|
1367
|
-
var PROBLEM_COMPACT_EVIDENCE = 5;
|
|
1368
|
-
var PROBLEM_COMPACT_OMITTED_BLOCKS = [
|
|
1369
|
-
"rubric",
|
|
1370
|
-
"trend",
|
|
1371
|
-
"sub_problems",
|
|
1372
|
-
"affected_conversations",
|
|
1373
|
-
"remainder",
|
|
1374
|
-
"confidence",
|
|
1375
|
-
"change_history",
|
|
1376
|
-
"stories"
|
|
1377
|
-
];
|
|
1378
|
-
function readCommand(command, purpose) {
|
|
1379
|
-
return { command, purpose, mutability: "read", requires_approval: false };
|
|
1380
|
-
}
|
|
1381
|
-
function evidenceMsgIndex(row) {
|
|
1382
|
-
return asNumber(row.anchor_msg_index) ?? asNumber(asRecord(asRecord(row.snippet_parsed)?.anchor)?.msg_index);
|
|
1383
|
-
}
|
|
1384
|
-
function compactProblemDossier(response, problemId) {
|
|
1385
|
-
const id = shellWord(asString(response.problem_id) ?? problemId);
|
|
1386
|
-
const evidence = (Array.isArray(response.evidence) ? response.evidence : []).map((item) => asRecord(item)).filter((row) => row !== null);
|
|
1387
|
-
const topEvidence = evidence.slice(0, PROBLEM_COMPACT_EVIDENCE).map((row) => {
|
|
1388
|
-
const conversationId = asString(row.conversation_id);
|
|
1389
|
-
const msgIndex = evidenceMsgIndex(row);
|
|
1390
|
-
return {
|
|
1391
|
-
attribution_id: row.attribution_id ?? null,
|
|
1392
|
-
conversation_id: conversationId,
|
|
1393
|
-
msg_index: msgIndex,
|
|
1394
|
-
signal_family: row.signal_family ?? null,
|
|
1395
|
-
signal_type: row.signal_type ?? null,
|
|
1396
|
-
confidence: row.confidence ?? null,
|
|
1397
|
-
causal_rationale: row.causal_rationale ?? null,
|
|
1398
|
-
door: row.door ?? null,
|
|
1399
|
-
replay_verified: row.replay_verified ?? null,
|
|
1400
|
-
...conversationId && msgIndex !== null ? { context_command: `moda traces get ${shellWord(contextTarget(conversationId))} --msg-index=${msgIndex}` } : {}
|
|
1401
|
-
};
|
|
1402
|
-
});
|
|
1403
|
-
const reportsBlock = asRecord(response.investigation_reports);
|
|
1404
|
-
const reports = (Array.isArray(reportsBlock?.items) ? reportsBlock.items : []).map((item) => asRecord(item)).filter((row) => row !== null).map((row) => ({
|
|
1405
|
-
report_id: row.report_id ?? null,
|
|
1406
|
-
conversation_id: row.conversation_id ?? null,
|
|
1407
|
-
mechanism: row.mechanism ?? null,
|
|
1408
|
-
suspected_surface: row.suspected_surface ?? null,
|
|
1409
|
-
severity: row.severity ?? null,
|
|
1410
|
-
problem_found: row.problem_found ?? null
|
|
1411
|
-
}));
|
|
1412
|
-
const verification = asRecord(response.verification);
|
|
1413
|
-
const { samples: _samples, ...verificationCounts } = verification ?? {};
|
|
1414
|
-
const dossier = asRecord(response.dossier);
|
|
1415
|
-
const { representative_story_keys: _storyKeys, ...dossierSummary } = dossier ?? {};
|
|
1416
|
-
const trend = Array.isArray(response.trend) ? response.trend : [];
|
|
1417
|
-
const data = {
|
|
1418
|
-
found: response.found ?? true,
|
|
1419
|
-
problem_id: response.problem_id ?? problemId,
|
|
1420
|
-
requested_problem_id: response.requested_problem_id ?? problemId,
|
|
1421
|
-
alias_resolved: response.alias_resolved ?? false,
|
|
1422
|
-
view: "compact",
|
|
1423
|
-
header: response.header ?? null,
|
|
1424
|
-
dossier: dossier ? dossierSummary : null,
|
|
1425
|
-
verification: verification ? verificationCounts : null,
|
|
1426
|
-
...response.impact_identity !== undefined ? { impact_identity: response.impact_identity } : {},
|
|
1427
|
-
...response.hierarchy !== undefined ? { hierarchy: response.hierarchy } : {},
|
|
1428
|
-
...trend.length > 0 ? { trend_latest: trend[trend.length - 1], trend_points: trend.length } : {},
|
|
1429
|
-
top_evidence: topEvidence,
|
|
1430
|
-
evidence_in_dossier: evidence.length,
|
|
1431
|
-
reports,
|
|
1432
|
-
omitted: {
|
|
1433
|
-
evidence_rows: Math.max(0, evidence.length - topEvidence.length),
|
|
1434
|
-
report_narratives: reports.length,
|
|
1435
|
-
reports_has_more: reportsBlock?.has_more === true,
|
|
1436
|
-
blocks: PROBLEM_COMPACT_OMITTED_BLOCKS.filter((key) => (key in response))
|
|
1437
|
-
},
|
|
1438
|
-
full_command: `moda problems get ${id} --full`
|
|
1439
|
-
};
|
|
1440
|
-
const nextCommands = [
|
|
1441
|
-
readCommand(`moda problems get ${id} --evidence --limit=20`, "Page every evidence row with its anchor (follow next_cursor)."),
|
|
1442
|
-
readCommand(`moda problems get ${id} --reports`, "Page investigation reports with narratives and citations."),
|
|
1443
|
-
readCommand(`moda problems get ${id} --traces`, "Page affected traces with their latest anchor."),
|
|
1444
|
-
readCommand(`moda problems get ${id} --full`, "The complete dossier, every block (large).")
|
|
1445
|
-
];
|
|
1446
|
-
const first = topEvidence.find((row) => typeof row.context_command === "string");
|
|
1447
|
-
if (first?.context_command) {
|
|
1448
|
-
nextCommands.push(readCommand(first.context_command, "Read the trace around the top evidence anchor."));
|
|
1449
|
-
}
|
|
1450
|
-
return { data, nextCommands };
|
|
658
|
+
if (!/["$`\\!]/.test(value))
|
|
659
|
+
return `"${value}"`;
|
|
660
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
1451
661
|
}
|
|
1452
662
|
|
|
1453
663
|
// src/legacy-names.ts
|
|
@@ -1618,8 +828,8 @@ function canonicalCommandText(text) {
|
|
|
1618
828
|
|
|
1619
829
|
// src/output.ts
|
|
1620
830
|
import { randomUUID } from "node:crypto";
|
|
1621
|
-
import { lstatSync, mkdirSync as mkdirSync2, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
1622
|
-
import { tmpdir } from "node:os";
|
|
831
|
+
import { chmodSync as chmodSync2, lstatSync, mkdirSync as mkdirSync2, readdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
832
|
+
import { tmpdir, userInfo } from "node:os";
|
|
1623
833
|
import { join as join2 } from "node:path";
|
|
1624
834
|
var SUGGESTION_KEY = /(_commands?|^hints?|^suggestions?)$/i;
|
|
1625
835
|
function canonicalDeep(value, rewriteStrings) {
|
|
@@ -1713,7 +923,7 @@ var CUSTOMER_CONTENT_KEYS = new Set([
|
|
|
1713
923
|
"response"
|
|
1714
924
|
]);
|
|
1715
925
|
function withProfileOnCommands(value, profile) {
|
|
1716
|
-
const flag = `--profile=${
|
|
926
|
+
const flag = `--profile=${shellArg(profile)}`;
|
|
1717
927
|
const visit = (node, key, inCommandList) => {
|
|
1718
928
|
const isCommandKey = key !== undefined && (GENERATED_COMMAND_KEY.test(key) || inCommandList && key === "command");
|
|
1719
929
|
if (typeof node === "string")
|
|
@@ -1722,7 +932,7 @@ function withProfileOnCommands(value, profile) {
|
|
|
1722
932
|
const list = key !== undefined && GENERATED_COMMAND_LIST_KEY.test(key);
|
|
1723
933
|
return node.map((item) => typeof item === "string" ? visit(item, isCommandKey ? key : undefined, false) : visit(item, undefined, list));
|
|
1724
934
|
}
|
|
1725
|
-
const record =
|
|
935
|
+
const record = asRecord(node);
|
|
1726
936
|
if (!record)
|
|
1727
937
|
return node;
|
|
1728
938
|
return Object.fromEntries(Object.entries(record).map(([entryKey, entry]) => [
|
|
@@ -2493,11 +1703,11 @@ function normalizeSummary(summary, command, status, data) {
|
|
|
2493
1703
|
return inferSummary(command, status, data);
|
|
2494
1704
|
}
|
|
2495
1705
|
function inferSummary(command, status, data) {
|
|
2496
|
-
const record =
|
|
1706
|
+
const record = asRecord(data);
|
|
2497
1707
|
if (status === "error") {
|
|
2498
1708
|
return { text: `${command} failed.`, confidence: "high" };
|
|
2499
1709
|
}
|
|
2500
|
-
const summary =
|
|
1710
|
+
const summary = asRecord(record?.summary);
|
|
2501
1711
|
if (summary) {
|
|
2502
1712
|
const statusValue = typeof summary.status === "string" ? summary.status : undefined;
|
|
2503
1713
|
const fail = typeof summary.fail === "number" ? summary.fail : undefined;
|
|
@@ -2549,11 +1759,11 @@ function inferMutability(command) {
|
|
|
2549
1759
|
return "read";
|
|
2550
1760
|
}
|
|
2551
1761
|
function inferWarnings(data) {
|
|
2552
|
-
const record =
|
|
1762
|
+
const record = asRecord(data);
|
|
2553
1763
|
const direct = record?.warnings;
|
|
2554
1764
|
if (Array.isArray(direct))
|
|
2555
1765
|
return direct.filter((item) => typeof item === "string");
|
|
2556
|
-
const validation =
|
|
1766
|
+
const validation = asRecord(record?.validation);
|
|
2557
1767
|
if (Array.isArray(validation?.warnings)) {
|
|
2558
1768
|
return validation.warnings.filter((item) => typeof item === "string");
|
|
2559
1769
|
}
|
|
@@ -2591,10 +1801,37 @@ function pruneAgentFullOutputs(dir, keep, now = Date.now()) {
|
|
|
2591
1801
|
} catch {}
|
|
2592
1802
|
}
|
|
2593
1803
|
}
|
|
1804
|
+
function currentUserTag() {
|
|
1805
|
+
if (typeof process.getuid === "function")
|
|
1806
|
+
return String(process.getuid());
|
|
1807
|
+
try {
|
|
1808
|
+
return userInfo().username.replace(/[^A-Za-z0-9_.-]+/g, "_") || "user";
|
|
1809
|
+
} catch {
|
|
1810
|
+
return "user";
|
|
1811
|
+
}
|
|
1812
|
+
}
|
|
1813
|
+
function defaultAgentOutputDir() {
|
|
1814
|
+
return join2(tmpdir(), `moda-agent-output-${currentUserTag()}`);
|
|
1815
|
+
}
|
|
1816
|
+
function ensurePrivateDir(dir) {
|
|
1817
|
+
mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
1818
|
+
const stat = lstatSync(dir);
|
|
1819
|
+
if (!stat.isDirectory())
|
|
1820
|
+
throw new Error(`${dir} is not a directory.`);
|
|
1821
|
+
if (typeof process.getuid === "function" && stat.uid !== process.getuid()) {
|
|
1822
|
+
throw new Error(`${dir} is owned by another user.`);
|
|
1823
|
+
}
|
|
1824
|
+
if (process.platform !== "win32" && (stat.mode & 63) !== 0)
|
|
1825
|
+
chmodSync2(dir, 448);
|
|
1826
|
+
}
|
|
2594
1827
|
function writeAgentFullOutput(command, data) {
|
|
2595
1828
|
try {
|
|
2596
|
-
const
|
|
2597
|
-
|
|
1829
|
+
const configured = process.env.MODA_AGENT_OUTPUT_DIR;
|
|
1830
|
+
const dir = configured || defaultAgentOutputDir();
|
|
1831
|
+
if (configured)
|
|
1832
|
+
mkdirSync2(dir, { recursive: true, mode: 448 });
|
|
1833
|
+
else
|
|
1834
|
+
ensurePrivateDir(dir);
|
|
2598
1835
|
const slug = command.replace(/[^a-zA-Z0-9_-]+/g, "-").replace(/^-+|-+$/g, "") || "output";
|
|
2599
1836
|
const stamp = new Date().toISOString().replace(/[:.]/g, "-");
|
|
2600
1837
|
const path = join2(dir, `${slug}-${stamp}-${randomUUID().slice(0, 8)}.json`);
|
|
@@ -2615,7 +1852,7 @@ function contentBlocksRedundant(message) {
|
|
|
2615
1852
|
const hasToolResults = Array.isArray(message.tool_results) && message.tool_results.length > 0;
|
|
2616
1853
|
const texts = [];
|
|
2617
1854
|
for (const item of blocks) {
|
|
2618
|
-
const block =
|
|
1855
|
+
const block = asRecord(item);
|
|
2619
1856
|
if (!block)
|
|
2620
1857
|
return false;
|
|
2621
1858
|
if (block.type === "text") {
|
|
@@ -2647,7 +1884,7 @@ function shedRedundantContentBlocks(value) {
|
|
|
2647
1884
|
visit(item);
|
|
2648
1885
|
return;
|
|
2649
1886
|
}
|
|
2650
|
-
const record =
|
|
1887
|
+
const record = asRecord(node);
|
|
2651
1888
|
if (!record)
|
|
2652
1889
|
return;
|
|
2653
1890
|
if ("content_blocks" in record && contentBlocksRedundant(record)) {
|
|
@@ -2669,17 +1906,17 @@ function continuationCommand(invocation, overrides) {
|
|
|
2669
1906
|
const dashAt = invocation.positionals.findIndex((value) => value.startsWith("-"));
|
|
2670
1907
|
const leading = dashAt === -1 ? invocation.positionals : invocation.positionals.slice(0, dashAt);
|
|
2671
1908
|
const trailing = dashAt === -1 ? [] : invocation.positionals.slice(dashAt);
|
|
2672
|
-
const parts = ["moda", invocation.command, ...leading.map((value) =>
|
|
1909
|
+
const parts = ["moda", invocation.command, ...leading.map((value) => shellArg(value))];
|
|
2673
1910
|
for (const [key, value] of Object.entries(invocation.flags)) {
|
|
2674
1911
|
const flag = normalize2(key);
|
|
2675
1912
|
if (overridden.has(flag) || CONTINUATION_SECRET_FLAGS.has(flag))
|
|
2676
1913
|
continue;
|
|
2677
|
-
parts.push(bare.has(flag) && value === "true" ? `--${flag}` : `--${flag}=${
|
|
1914
|
+
parts.push(bare.has(flag) && value === "true" ? `--${flag}` : `--${flag}=${shellArg(String(value))}`);
|
|
2678
1915
|
}
|
|
2679
1916
|
for (const [key, value] of Object.entries(overrides))
|
|
2680
|
-
parts.push(`--${normalize2(key)}=${
|
|
1917
|
+
parts.push(`--${normalize2(key)}=${shellArg(String(value))}`);
|
|
2681
1918
|
if (trailing.length > 0)
|
|
2682
|
-
parts.push("--", ...trailing.map((value) =>
|
|
1919
|
+
parts.push("--", ...trailing.map((value) => shellArg(value)));
|
|
2683
1920
|
return canonicalCommandText(parts.join(" "));
|
|
2684
1921
|
}
|
|
2685
1922
|
var PAGED_LIST_BY_COMMAND = {
|
|
@@ -2700,7 +1937,7 @@ function rewritePagination(list, isTopLevel, invocation) {
|
|
|
2700
1937
|
const { parent, array, originalLength } = list;
|
|
2701
1938
|
if (!parent)
|
|
2702
1939
|
return;
|
|
2703
|
-
const nested =
|
|
1940
|
+
const nested = asRecord(parent.pagination);
|
|
2704
1941
|
const inline = !nested && !isTopLevel && (("has_more" in parent) || ("next_cursor" in parent)) ? parent : undefined;
|
|
2705
1942
|
const pagination = nested ?? inline;
|
|
2706
1943
|
if (!pagination)
|
|
@@ -2840,7 +2077,7 @@ function boundForAgent(data, maxBytes = agentMaxOutputBytes(), options = {}) {
|
|
|
2840
2077
|
fullOutputPath
|
|
2841
2078
|
};
|
|
2842
2079
|
}
|
|
2843
|
-
const root =
|
|
2080
|
+
const root = asRecord(bounded);
|
|
2844
2081
|
const notes = [];
|
|
2845
2082
|
const nextCommands = [];
|
|
2846
2083
|
for (const list of droppedLists.values()) {
|
|
@@ -2878,7 +2115,7 @@ function boundForAgent(data, maxBytes = agentMaxOutputBytes(), options = {}) {
|
|
|
2878
2115
|
...nextCommands.length > 0 ? { nextCommands } : {}
|
|
2879
2116
|
};
|
|
2880
2117
|
}
|
|
2881
|
-
function
|
|
2118
|
+
function asRecord(value) {
|
|
2882
2119
|
return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
|
|
2883
2120
|
}
|
|
2884
2121
|
function extractSuggestedCommands(text) {
|
|
@@ -2886,29 +2123,4 @@ function extractSuggestedCommands(text) {
|
|
|
2886
2123
|
return commands.length > 0 ? commands : undefined;
|
|
2887
2124
|
}
|
|
2888
2125
|
|
|
2889
|
-
|
|
2890
|
-
var PLATFORM_API_KEY_PREFIX = "moda_pk_";
|
|
2891
|
-
var TENANT_HEADER = "x-moda-tenant-id";
|
|
2892
|
-
function isPlatformApiKey(key) {
|
|
2893
|
-
return Boolean(key?.startsWith(PLATFORM_API_KEY_PREFIX));
|
|
2894
|
-
}
|
|
2895
|
-
var platformTenantOverride;
|
|
2896
|
-
function setPlatformTenantOverride(tenantId) {
|
|
2897
|
-
platformTenantOverride = tenantId;
|
|
2898
|
-
}
|
|
2899
|
-
var TENANT_PATH = /\/tenants\/([^/?#]+)/;
|
|
2900
|
-
function tenantFromUrl(url) {
|
|
2901
|
-
const match = url ? TENANT_PATH.exec(url) : null;
|
|
2902
|
-
return match ? decodeURIComponent(match[1]) : undefined;
|
|
2903
|
-
}
|
|
2904
|
-
function apiKeyHeaders(key, options = {}, url) {
|
|
2905
|
-
const headers = { "x-api-key": key };
|
|
2906
|
-
if (isPlatformApiKey(key)) {
|
|
2907
|
-
const tenantId = tenantFromUrl(url) || platformTenantOverride || resolveTenantId(options);
|
|
2908
|
-
if (tenantId)
|
|
2909
|
-
headers[TENANT_HEADER] = tenantId;
|
|
2910
|
-
}
|
|
2911
|
-
return headers;
|
|
2912
|
-
}
|
|
2913
|
-
|
|
2914
|
-
export { PROD_BASE_URL, DEFAULT_INGEST_URL, getModaPaths, getModaDir, isLoopbackBaseUrl, describeBaseUrlSource, loadProfileConfig, saveProfileConfig, getActiveProfile, setActiveProfile, upsertProfile, clearStoredApiKeyCredentials, secretFilePathFromRef, resolveSecretReference, resolveApiKeyFromActiveProfile, resolveTenantIdFromActiveProfile, ensureSecretFilePermissions, writeSecretJsonFile, CliInputError, attachInputDetails, inputDetailsOf, CliAccessError, CliInputRequiredError, CliAuthError, CliNotFoundError, CliCancellationError, isNetworkLikeError, isApiLikeError, apiErrorStatus, VERSION, MODA_BASE_URL, loadCliConfig, saveCliConfig, resolveApiKey, embeddedTenantIdFromApiKey, resolveIngestUrl2 as resolveIngestUrl, resolveTenantId, resolveApiTenantId, resolveModaBaseUrl, validateConfig, isPlatformApiKey, setPlatformTenantOverride, apiKeyHeaders, 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, BATCH_MAX_TARGETS, BATCH_CONCURRENCY, parseBatchTarget, collectBatchTargets, mapWithConcurrency, contextTarget, asRecord, asString, asNumber, frustrationAnchorIndex, frustrationsFromEmotions, withFrustrationAnchors, shellWord, trimToolFailureConversations, withToolFailureAnchors, embeddedWindowSize, withoutDetectionWindows, compactProblemDossier, LEGACY_NAMES, canonicalCommandText, 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, continuationCommand };
|
|
2126
|
+
export { PROD_BASE_URL, DEFAULT_INGEST_URL, getModaPaths, getModaDir, isLoopbackBaseUrl, describeBaseUrlSource, loadProfileConfig, saveProfileConfig, getActiveProfile, setActiveProfile, upsertProfile, clearStoredApiKeyCredentials, secretFilePathFromRef, resolveSecretReference, resolveApiKeyFromActiveProfile, resolveTenantIdFromActiveProfile, ensureSecretFilePermissions, writeSecretJsonFile, VERSION, MODA_BASE_URL, loadCliConfig, saveCliConfig, resolveApiKey, embeddedTenantIdFromApiKey, resolveIngestUrl2 as resolveIngestUrl, resolveTenantId, resolveApiTenantId, resolveModaBaseUrl, resolveModaBaseUrlStrict, validateConfig, isPlatformApiKey, setPlatformTenantOverride, apiKeyHeaders, recordApiRequest, getApiRequestCount, resetApiRequestCount, shellArg, LEGACY_NAMES, canonicalCommandText, 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, continuationCommand };
|