@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.
Files changed (44) hide show
  1. package/dist/{agent-nqmha8ck.js → agent-0w9rtdsw.js} +22 -16
  2. package/dist/cli-3n0gz4d0.js +17971 -0
  3. package/dist/{cli-b4740tnv.js → cli-3retgh64.js} +85 -1165
  4. package/dist/{cli-1mbb0ct0.js → cli-97jew729.js} +1 -1
  5. package/dist/{cli-sqsjd08w.js → cli-99p2jh28.js} +105 -893
  6. package/dist/{cli-k6q8dbpk.js → cli-9bgk5jeh.js} +8 -6
  7. package/dist/{cli-q6f6vrrr.js → cli-9bgnvth2.js} +5 -3
  8. package/dist/cli-9kfxkxmk.js +6994 -0
  9. package/dist/cli-cesds766.js +1516 -0
  10. package/dist/{cli-cdrvjva5.js → cli-dr6x0zv7.js} +28 -6
  11. package/dist/{cli-jtyvbd8d.js → cli-e23g9ywa.js} +1 -1
  12. package/dist/cli-fwpqghgc.js +569 -0
  13. package/dist/cli-k4tqwah4.js +89 -0
  14. package/dist/{cli-8tfk8qeb.js → cli-mg5zv4s6.js} +18 -15
  15. package/dist/{cli-jgfm7w1r.js → cli-n2hng3gv.js} +9 -6
  16. package/dist/cli-ns5fcnkz.js +341 -0
  17. package/dist/{cli-5g1tv80h.js → cli-ny48a8de.js} +12 -9
  18. package/dist/{cli-d577kq6h.js → cli-qpq84eee.js} +5220 -32715
  19. package/dist/cli-xq45etg1.js +1098 -0
  20. package/dist/cli-yf39avhh.js +754 -0
  21. package/dist/cli-yz8xcpyk.js +12 -0
  22. package/dist/cli.js +355 -283
  23. package/dist/doctor-k3ta6h2y.js +24 -0
  24. package/dist/{fix-crkwdkt4.js → fix-w5z02wt4.js} +47 -50
  25. package/dist/{harness-x3e7d68b.js → harness-7azmzytc.js} +15 -7
  26. package/dist/{harness-github-actions-fjhvhgpj.js → harness-github-actions-bv2qrnqb.js} +11 -5
  27. package/dist/harness-report-rd9c4e9v.js +54 -0
  28. package/dist/{index-2kf3fnnb.js → index-d1z50dsq.js} +45 -36
  29. package/dist/{production-intelligence-7n83c701.js → production-intelligence-wvsgjxth.js} +21 -18
  30. package/dist/{profile-commands-ct2t0bfr.js → profile-commands-h8evz9x0.js} +9 -5
  31. package/dist/prompt-attribution-1nytc9wj.js +148 -0
  32. package/dist/prompt-source-mcp.js +14 -7
  33. package/dist/prompt-sources-07tczyqa.js +19 -0
  34. package/dist/{prompts-92aqqb2k.js → prompts-6y9wfq5z.js} +8 -7
  35. package/dist/prompts-ab-ezrd63sk.js +70 -0
  36. package/dist/prompts-propose-2k3enm2q.js +255 -0
  37. package/dist/{provision-gn8raqpt.js → provision-y5bdbh4y.js} +9 -6
  38. package/dist/{registry-ex162j5y.js → registry-96aze5wp.js} +7 -4
  39. package/dist/{skills-2mbsj9bt.js → skills-j8865009.js} +7 -5
  40. package/dist/{sync-kghmmmk5.js → sync-ew7yvy0e.js} +16 -10
  41. package/package.json +1 -1
  42. package/skills/integration/index.json +2 -2
  43. package/dist/cli-bb7133m7.js +0 -144
  44. package/dist/doctor-w913fj4g.js +0 -22
@@ -0,0 +1,89 @@
1
+ // src/errors.ts
2
+ class CliInputError extends Error {
3
+ usage;
4
+ reason;
5
+ details;
6
+ constructor(message, usage, reason, details) {
7
+ super(message);
8
+ this.usage = usage;
9
+ this.reason = reason;
10
+ this.details = details;
11
+ this.name = "CliInputError";
12
+ }
13
+ }
14
+ var inputDetails = new WeakMap;
15
+ function attachInputDetails(error, details) {
16
+ inputDetails.set(error, details);
17
+ }
18
+ function inputDetailsOf(error) {
19
+ if (error instanceof CliInputError && error.details)
20
+ return error.details;
21
+ return error !== null && typeof error === "object" ? inputDetails.get(error) : undefined;
22
+ }
23
+
24
+ class CliAccessError extends Error {
25
+ guidance;
26
+ constructor(message, options = {}) {
27
+ super(message);
28
+ this.name = "CliAccessError";
29
+ this.guidance = options.guidance;
30
+ }
31
+ }
32
+
33
+ class CliInputRequiredError extends Error {
34
+ input_request;
35
+ constructor(message, input_request, usage) {
36
+ super(message);
37
+ this.input_request = input_request;
38
+ this.name = "CliInputRequiredError";
39
+ if (usage)
40
+ this.usage = usage;
41
+ }
42
+ usage;
43
+ }
44
+
45
+ class CliAuthError extends Error {
46
+ auth;
47
+ constructor(message, auth, usage) {
48
+ super(message);
49
+ this.auth = auth;
50
+ this.name = "CliAuthError";
51
+ if (usage)
52
+ this.usage = usage;
53
+ }
54
+ usage;
55
+ }
56
+
57
+ class CliNotFoundError extends Error {
58
+ entity;
59
+ id;
60
+ usage;
61
+ constructor(entity, id, message, usage) {
62
+ super(message ?? `No ${entity} found for id "${id}" in this tenant.`);
63
+ this.entity = entity;
64
+ this.id = id;
65
+ this.usage = usage;
66
+ this.name = "CliNotFoundError";
67
+ }
68
+ }
69
+
70
+ class CliCancellationError extends Error {
71
+ constructor(message) {
72
+ super(message);
73
+ this.name = "CliCancellationError";
74
+ }
75
+ }
76
+ function isNetworkLikeError(error) {
77
+ 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));
78
+ }
79
+ function isApiLikeError(error) {
80
+ return error instanceof Error && (error.name === "ApiError" || ("statusCode" in error) && typeof error.statusCode === "number");
81
+ }
82
+ function apiErrorStatus(error) {
83
+ if (!isApiLikeError(error))
84
+ return;
85
+ const status = error.statusCode;
86
+ return typeof status === "number" ? status : undefined;
87
+ }
88
+
89
+ export { CliInputError, attachInputDetails, inputDetailsOf, CliAccessError, CliInputRequiredError, CliAuthError, CliNotFoundError, CliCancellationError, isNetworkLikeError, isApiLikeError, apiErrorStatus };
@@ -1,30 +1,33 @@
1
+ import {
2
+ SKILL_SOURCE_HARNESS,
3
+ SKILL_SOURCE_INTEGRATION_BUNDLED,
4
+ claudeSkillToCursorRule,
5
+ detectAgents,
6
+ pruneManagedSkillPaths,
7
+ readSkillsManifest,
8
+ writeSkillsManifest
9
+ } from "./cli-8dtnwp9r.js";
1
10
  import {
2
11
  createCommandContext
3
- } from "./cli-cdrvjva5.js";
12
+ } from "./cli-dr6x0zv7.js";
4
13
  import {
5
14
  assertFlags,
6
15
  assertPositionals,
7
16
  writeDryRun
8
- } from "./cli-jgfm7w1r.js";
17
+ } from "./cli-n2hng3gv.js";
9
18
  import {
10
19
  callControlAPI
11
- } from "./cli-jtyvbd8d.js";
20
+ } from "./cli-e23g9ywa.js";
12
21
  import {
13
- CliInputError,
14
22
  recordApiRequest,
15
23
  resolveApiKey,
16
24
  resolveIngestUrl,
17
- resolveTenantId
18
- } from "./cli-sqsjd08w.js";
25
+ resolveTenantId,
26
+ shellArg
27
+ } from "./cli-99p2jh28.js";
19
28
  import {
20
- SKILL_SOURCE_HARNESS,
21
- SKILL_SOURCE_INTEGRATION_BUNDLED,
22
- claudeSkillToCursorRule,
23
- detectAgents,
24
- pruneManagedSkillPaths,
25
- readSkillsManifest,
26
- writeSkillsManifest
27
- } from "./cli-8dtnwp9r.js";
29
+ CliInputError
30
+ } from "./cli-k4tqwah4.js";
28
31
  import {
29
32
  __require
30
33
  } from "./cli-0v6na3yp.js";
@@ -672,7 +675,7 @@ async function runSkillsCommand(input) {
672
675
  "accepted: true",
673
676
  result.generation_run_id && `generation_run_id: ${result.generation_run_id}`,
674
677
  result.message && `message: ${result.message}`,
675
- result.generation_run_id && `follow progress: moda skills status ${result.generation_run_id}`
678
+ result.generation_run_id && `follow progress: moda skills status ${shellArg(result.generation_run_id)}`
676
679
  ].filter(Boolean).join(`
677
680
  `));
678
681
  } else {
@@ -2,17 +2,20 @@ import {
2
2
  ApiError,
3
3
  callControlAPI,
4
4
  callDataAPI
5
- } from "./cli-jtyvbd8d.js";
5
+ } from "./cli-e23g9ywa.js";
6
6
  import {
7
- CliAccessError,
8
- CliInputError,
9
7
  continuationCommand,
10
8
  embeddedTenantIdFromApiKey,
11
9
  isPlatformApiKey,
12
10
  resolveApiKey,
13
11
  resolveApiTenantId,
14
- setPlatformTenantOverride
15
- } from "./cli-sqsjd08w.js";
12
+ setPlatformTenantOverride,
13
+ shellArg
14
+ } from "./cli-99p2jh28.js";
15
+ import {
16
+ CliAccessError,
17
+ CliInputError
18
+ } from "./cli-k4tqwah4.js";
16
19
 
17
20
  // src/schemas.ts
18
21
  import { z } from "zod";
@@ -1332,7 +1335,7 @@ var SIGNALS_MANAGEMENT_SUBCOMMANDS = new Set([
1332
1335
  ]);
1333
1336
  function unknownSignalsSubcommandError(sub, args = []) {
1334
1337
  if (sub === "archive") {
1335
- const id = args[0] ?? "<signal_id>";
1338
+ const id = args[0] ? shellArg(args[0]) : "<signal_id>";
1336
1339
  return new CliInputError(`Unknown signals subcommand 'archive': archiving a signal is dashboard-only, so nothing was sent.`, `To stop a signal from running, pause it: moda signals pause ${id}. Drafts can be deleted with moda signals delete ${id}.`);
1337
1340
  }
1338
1341
  return new CliInputError(`Unknown signals subcommand '${sub}', so nothing was sent. Valid subcommands: ${[...SIGNALS_MANAGEMENT_SUBCOMMANDS].join(", ")}.`, `Bare 'moda signals' lists custom signals; 'moda signal <signal_id>' opens one. Usage:
@@ -0,0 +1,341 @@
1
+ // ../../packages/harness-snapshot/src/policy.ts
2
+ var MAX_SCANNED_FILE_BYTES = 512 * 1024;
3
+ var DEFAULT_MAX_INVENTORY_FILES = 12000;
4
+ var DEFAULT_MAX_INVENTORY_TEXT_BYTES = 48 * 1024 * 1024;
5
+ var MAX_SNAPSHOT_BODY_BYTES = 4500000;
6
+ var MAX_RECORDED_SKIPS = 1000;
7
+ var SKIPPED_DIRS = new Set([
8
+ ".angular",
9
+ ".cache",
10
+ ".expo",
11
+ ".git",
12
+ ".hg",
13
+ ".idea",
14
+ ".svn",
15
+ ".next",
16
+ ".nuxt",
17
+ ".output",
18
+ ".parcel-cache",
19
+ ".pytest_cache",
20
+ ".ruff_cache",
21
+ ".serverless",
22
+ ".sst",
23
+ ".turbo",
24
+ ".wrangler",
25
+ ".wrangler-shared",
26
+ ".moda",
27
+ ".moda-test",
28
+ ".moda-test-home",
29
+ ".moda-cli-workspaces",
30
+ ".moda-cli-benchmarks",
31
+ "node_modules",
32
+ "dist",
33
+ "build",
34
+ "coverage",
35
+ "out",
36
+ "target",
37
+ "logs",
38
+ "tmp",
39
+ "temp",
40
+ "__pycache__",
41
+ ".venv",
42
+ "venv"
43
+ ]);
44
+ var SKIPPED_PATH_PREFIXES = [
45
+ ".claude/worktrees",
46
+ ".codex/environments"
47
+ ];
48
+ function posixNormalize(path) {
49
+ const absolute = path.startsWith("/");
50
+ const parts = path.split("/").filter((part) => part !== "" && part !== ".");
51
+ const normalized = parts.join("/");
52
+ return absolute ? `/${normalized}` : normalized;
53
+ }
54
+ function basename(path) {
55
+ const normalized = posixNormalize(path);
56
+ const index = normalized.lastIndexOf("/");
57
+ return index === -1 ? normalized : normalized.slice(index + 1);
58
+ }
59
+ function extname(path) {
60
+ const name = basename(path);
61
+ const index = name.lastIndexOf(".");
62
+ return index <= 0 ? "" : name.slice(index);
63
+ }
64
+ function isSkippedDir(path) {
65
+ return SKIPPED_DIRS.has(basename(path));
66
+ }
67
+ function isSkippedPathPrefix(path) {
68
+ const normalized = posixNormalize(path);
69
+ return SKIPPED_PATH_PREFIXES.some((prefix) => normalized === prefix || normalized.startsWith(`${prefix}/`));
70
+ }
71
+ function isSourceFile(path) {
72
+ return /\.(ts|tsx|js|jsx|mjs|cjs|py)$/i.test(path);
73
+ }
74
+ function isPackageOrLockfile(path) {
75
+ return path === "package.json" || path === "pyproject.toml" || path === "bun.lock" || path === "bun.lockb" || path === "pnpm-lock.yaml" || path === "yarn.lock";
76
+ }
77
+ function isPromptLikePath(path) {
78
+ return /(^|\/)prompts?\//i.test(path) && /\.(prompt\.)?(md|json|ya?ml)$/i.test(path);
79
+ }
80
+ function isSkillLikePath(path) {
81
+ return /(^|\/)(\.claude\/skills|\.cursor\/rules|skills?)\//i.test(path) && /\.(md|mdc)$/i.test(path);
82
+ }
83
+ function isEvalLikePath(path) {
84
+ return /(^|\/)(evals?|tests?|__tests__)\//i.test(path) && /\.(ts|tsx|js|mjs|py|json|ya?ml)$/i.test(path);
85
+ }
86
+ function isDeploymentLikePath(path) {
87
+ 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);
88
+ }
89
+ function isDeveloperAgentConfigPath(path) {
90
+ return path === ".claude/settings.json" || path === ".codex/hooks.json" || path === ".cursor/hooks.json";
91
+ }
92
+ function isReadmeOrAgents(path) {
93
+ const name = basename(path);
94
+ return name === "README.md" || name === "AGENTS.md";
95
+ }
96
+ function shouldInventoryFile(path) {
97
+ const normalized = posixNormalize(path);
98
+ const name = basename(normalized);
99
+ const extension = extname(normalized).toLowerCase();
100
+ if (isSourceFile(normalized))
101
+ return true;
102
+ if (isPackageOrLockfile(normalized))
103
+ return true;
104
+ if (isPromptLikePath(normalized))
105
+ return true;
106
+ if (isSkillLikePath(normalized))
107
+ return true;
108
+ if (isEvalLikePath(normalized))
109
+ return true;
110
+ if (isDeploymentLikePath(normalized))
111
+ return true;
112
+ if (isDeveloperAgentConfigPath(normalized))
113
+ return true;
114
+ if (isReadmeOrAgents(normalized))
115
+ return true;
116
+ return extension === ".toml" && (name === "pyproject.toml" || name === "wrangler.toml");
117
+ }
118
+ function isTextFile(path) {
119
+ const extension = extname(path).toLowerCase();
120
+ return [
121
+ "",
122
+ ".cjs",
123
+ ".js",
124
+ ".json",
125
+ ".jsx",
126
+ ".md",
127
+ ".mdc",
128
+ ".mjs",
129
+ ".py",
130
+ ".toml",
131
+ ".ts",
132
+ ".tsx",
133
+ ".txt",
134
+ ".yaml",
135
+ ".yml"
136
+ ].includes(extension);
137
+ }
138
+ function isSecretishPath(path) {
139
+ const name = basename(path).toLowerCase();
140
+ return name === ".env" || name.startsWith(".env.") || name.includes("secret") || name.includes("private-key") || name.endsWith(".pem");
141
+ }
142
+
143
+ // ../../packages/harness-snapshot/src/redact.ts
144
+ var REDACTED = "[REDACTED]";
145
+ var MAX_DEPTH = 256;
146
+ var SECRET_KEYS = new Set([
147
+ "api_key",
148
+ "apikey",
149
+ "token",
150
+ "access_token",
151
+ "authorization",
152
+ "secret",
153
+ "password",
154
+ "cli_token"
155
+ ]);
156
+ var SECRET_PATTERNS = [
157
+ { pattern: /\bmoda_sk_[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
158
+ { pattern: /\bmoda_pk_[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
159
+ { pattern: /\bmoda_ct_[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
160
+ { pattern: /\bBearer\s+([A-Za-z0-9._~+/-]+=*)\b/gi, prefixLength: 8 },
161
+ { pattern: /\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\b/g, prefixLength: 8 },
162
+ { pattern: /\bsk-ant-api\d{2}-[A-Za-z0-9_-]{20,}\b/g, prefixLength: 12 },
163
+ { pattern: /\bsk-(?:proj-|svcacct-)?[A-Za-z0-9_-]{20,}\b/g, prefixLength: 8 },
164
+ { pattern: /\bAKIA[A-Z0-9]{16}\b/g, prefixLength: 8 },
165
+ { pattern: /\bAIza[A-Za-z0-9_-]{35}\b/g, prefixLength: 8 },
166
+ { pattern: /\bgh[pousr]_[A-Za-z0-9]{36,}\b/g, prefixLength: 8 },
167
+ { pattern: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g, prefixLength: 8 }
168
+ ];
169
+ function redactDeep(value) {
170
+ return redactValue(value, 0, new WeakSet);
171
+ }
172
+ function redactValue(value, depth, seen) {
173
+ if (typeof value === "string")
174
+ return redactString(value);
175
+ if (value === null || typeof value !== "object")
176
+ return value;
177
+ if (depth >= MAX_DEPTH)
178
+ return "[MaxDepth]";
179
+ if (seen.has(value))
180
+ return "[Circular]";
181
+ seen.add(value);
182
+ if (Array.isArray(value)) {
183
+ try {
184
+ return value.map((item) => redactValue(item, depth + 1, seen));
185
+ } finally {
186
+ seen.delete(value);
187
+ }
188
+ }
189
+ const out = {};
190
+ try {
191
+ for (const [key, item] of Object.entries(value)) {
192
+ out[key] = shouldRedactKey(key) ? redactSecretValue(item) : redactValue(item, depth + 1, seen);
193
+ }
194
+ } finally {
195
+ seen.delete(value);
196
+ }
197
+ return out;
198
+ }
199
+ function shouldRedactKey(key) {
200
+ return SECRET_KEYS.has(key.replace(/[-\s]/g, "_").toLowerCase());
201
+ }
202
+ function redactSecretValue(value) {
203
+ if (typeof value !== "string")
204
+ return REDACTED;
205
+ const redacted = redactString(value);
206
+ if (redacted !== value)
207
+ return redacted;
208
+ if (/^(configured|missing|not_configured|none|present|absent)$/i.test(value))
209
+ return value;
210
+ return REDACTED;
211
+ }
212
+ function redactStringWithCount(input) {
213
+ let text = input;
214
+ let redactionCount = 0;
215
+ for (const { pattern, prefixLength } of SECRET_PATTERNS) {
216
+ text = text.replace(pattern, (match) => {
217
+ redactionCount += 1;
218
+ if (/^Bearer\s+/i.test(match)) {
219
+ const token = match.replace(/^Bearer\s+/i, "");
220
+ return `Bearer ${token.slice(0, prefixLength)}...[REDACTED]`;
221
+ }
222
+ return `${match.slice(0, prefixLength)}...[REDACTED]`;
223
+ });
224
+ }
225
+ return { text, redactionCount };
226
+ }
227
+ function redactString(input) {
228
+ return redactStringWithCount(input).text;
229
+ }
230
+ function redactSnapshotText(text) {
231
+ const parts = text.split(/(\r\n|\r|\n)/);
232
+ let redactionCount = 0;
233
+ for (let index = 0;index < parts.length; index += 2) {
234
+ const redacted = redactStringWithCount(parts[index] ?? "");
235
+ parts[index] = redacted.text;
236
+ redactionCount += redacted.redactionCount;
237
+ }
238
+ return { text: parts.join(""), redactionCount };
239
+ }
240
+
241
+ // ../../packages/harness-snapshot/src/pack.ts
242
+ function utf8ByteLength(value) {
243
+ let bytes = 0;
244
+ for (let index = 0;index < value.length; index += 1) {
245
+ const code = value.charCodeAt(index);
246
+ if (code <= 127) {
247
+ bytes += 1;
248
+ } else if (code <= 2047) {
249
+ bytes += 2;
250
+ } else if (code >= 55296 && code <= 56319) {
251
+ const next = value.charCodeAt(index + 1);
252
+ if (next >= 56320 && next <= 57343) {
253
+ bytes += 4;
254
+ index += 1;
255
+ } else {
256
+ bytes += 3;
257
+ }
258
+ } else {
259
+ bytes += 3;
260
+ }
261
+ }
262
+ return bytes;
263
+ }
264
+ function isValidRelativePath(path) {
265
+ if (path.length === 0 || path.startsWith("/") || path.includes("\\"))
266
+ return false;
267
+ return !path.split("/").some((part) => part === "..");
268
+ }
269
+ function packSnapshot(inputs, opts) {
270
+ const maxFiles = opts.maxFiles ?? DEFAULT_MAX_INVENTORY_FILES;
271
+ const maxTextBytes = opts.maxTextBytes ?? DEFAULT_MAX_INVENTORY_TEXT_BYTES;
272
+ const maxSnapshotBytes = opts.maxSnapshotBytes ?? MAX_SNAPSHOT_BODY_BYTES;
273
+ const files = [];
274
+ const skips = [];
275
+ let inventoryTextBytes = 0;
276
+ let serializedBytes = 0;
277
+ let byteCount = 0;
278
+ let truncated = false;
279
+ const recordSkip = (path, reason) => {
280
+ if (skips.length < MAX_RECORDED_SKIPS)
281
+ skips.push({ path, reason });
282
+ };
283
+ const sorted = [...inputs].sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0);
284
+ for (const input of sorted) {
285
+ if (!isValidRelativePath(input.path)) {
286
+ recordSkip(input.path, "invalid relative path");
287
+ continue;
288
+ }
289
+ const path = posixNormalize(input.path);
290
+ if (input.isSymlink) {
291
+ recordSkip(path, "symlink skipped for safety");
292
+ continue;
293
+ }
294
+ if (isSecretishPath(path)) {
295
+ recordSkip(path, "secret-bearing path");
296
+ continue;
297
+ }
298
+ if (!shouldInventoryFile(path)) {
299
+ recordSkip(path, "not an inventory file");
300
+ continue;
301
+ }
302
+ if (!isTextFile(path)) {
303
+ recordSkip(path, "non-text file");
304
+ continue;
305
+ }
306
+ if (input.byteSize > MAX_SCANNED_FILE_BYTES) {
307
+ recordSkip(path, "file too large");
308
+ truncated = true;
309
+ continue;
310
+ }
311
+ if (files.length >= maxFiles || inventoryTextBytes + input.byteSize > maxTextBytes) {
312
+ recordSkip(path, "inventory budget");
313
+ truncated = true;
314
+ continue;
315
+ }
316
+ const text = opts.redact === false ? input.text : redactSnapshotText(input.text).text;
317
+ const file = { path, text };
318
+ const serializedCost = utf8ByteLength(JSON.stringify(file)) + 1;
319
+ if (serializedBytes + serializedCost > maxSnapshotBytes) {
320
+ recordSkip(path, "snapshot budget");
321
+ truncated = true;
322
+ break;
323
+ }
324
+ files.push(file);
325
+ inventoryTextBytes += input.byteSize;
326
+ serializedBytes += serializedCost;
327
+ byteCount += utf8ByteLength(text);
328
+ }
329
+ return {
330
+ snapshot: {
331
+ repo: { name: opts.repoName, root: "." },
332
+ files,
333
+ truncated,
334
+ fileCount: files.length,
335
+ byteCount,
336
+ ...opts.gitCommit ? { gitCommit: opts.gitCommit } : {}
337
+ },
338
+ skips
339
+ };
340
+ }
341
+ export { 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 };
@@ -1,19 +1,18 @@
1
1
  import {
2
2
  isAuthSessionValid,
3
3
  loadAuthSession
4
- } from "./cli-q6f6vrrr.js";
4
+ } from "./cli-9bgnvth2.js";
5
5
  import {
6
6
  inspectPromptManifest
7
- } from "./cli-b4740tnv.js";
7
+ } from "./cli-3retgh64.js";
8
8
  import {
9
9
  readHarnessSyncState,
10
10
  renderDoctorHuman,
11
- renderStatusHuman,
12
- scanHarness
13
- } from "./cli-d577kq6h.js";
11
+ renderStatusHuman
12
+ } from "./cli-xq45etg1.js";
14
13
  import {
15
14
  callDataAPI
16
- } from "./cli-jtyvbd8d.js";
15
+ } from "./cli-e23g9ywa.js";
17
16
  import {
18
17
  ensureSecretFilePermissions,
19
18
  getActiveProfile,
@@ -27,7 +26,10 @@ import {
27
26
  resolveSecretReference,
28
27
  resolveTenantId,
29
28
  secretFilePathFromRef
30
- } from "./cli-sqsjd08w.js";
29
+ } from "./cli-99p2jh28.js";
30
+ import {
31
+ __require
32
+ } from "./cli-0v6na3yp.js";
31
33
 
32
34
  // src/doctor.ts
33
35
  import { createHash } from "node:crypto";
@@ -167,7 +169,7 @@ async function buildDoctorReport(context, options) {
167
169
  remediation: manifestExists ? undefined : "Run `moda harness scan --summary` to scan the project and write a harness manifest.",
168
170
  nextCommand: manifestExists ? undefined : "moda harness scan --summary"
169
171
  });
170
- checks.push(harnessCurrentCheck(context.cwd, manifestPath, manifestExists, tenantId));
172
+ checks.push(await harnessCurrentCheck(context.cwd, manifestPath, manifestExists, tenantId));
171
173
  checks.push(harnessSyncStateCheck(context.cwd));
172
174
  checks.push(promptsDiscoveredCheck(context.cwd));
173
175
  checks.push(discoveryCheck("skills_discovered", "harness", "Skills are discovered", context.cwd, [
@@ -361,7 +363,7 @@ function localBaseUrlCheck(environment, baseUrl) {
361
363
  evidence: [{ label: "base_url", value: baseUrl }]
362
364
  };
363
365
  }
364
- function harnessCurrentCheck(cwd, manifestPath, manifestExists, tenantId) {
366
+ async function harnessCurrentCheck(cwd, manifestPath, manifestExists, tenantId) {
365
367
  if (!manifestExists) {
366
368
  return {
367
369
  id: "harness_manifest_current",
@@ -374,6 +376,7 @@ function harnessCurrentCheck(cwd, manifestPath, manifestExists, tenantId) {
374
376
  };
375
377
  }
376
378
  try {
379
+ const { scanHarness } = await import("./harness-7azmzytc.js");
377
380
  const current = scanHarness({
378
381
  rootDir: cwd,
379
382
  scannerVersion: "doctor",