@moda-ai/cli 1.55.10 → 1.55.12

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.
@@ -1,5 +1,20 @@
1
1
  import {
2
- CliAccessError,
2
+ stripAnsi
3
+ } from "./cli-97fnztpy.js";
4
+ import {
5
+ createCommandContext,
6
+ stringOption
7
+ } from "./cli-4x9w6ey7.js";
8
+ import {
9
+ assertFlags,
10
+ assertPositionals,
11
+ requireTenant
12
+ } from "./cli-k7vwt56h.js";
13
+ import {
14
+ ApiError,
15
+ callControlAPI
16
+ } from "./cli-ryd7nzke.js";
17
+ import {
3
18
  CliInputError,
4
19
  CliInputRequiredError,
5
20
  DEFAULT_MAX_INVENTORY_FILES,
@@ -8,7 +23,6 @@ import {
8
23
  MAX_SCANNED_FILE_BYTES,
9
24
  SECRET_KEYS,
10
25
  SKIPPED_DIRS,
11
- createCommandContext,
12
26
  embeddedTenantIdFromApiKey,
13
27
  getActiveProfile,
14
28
  isEvalLikePath,
@@ -21,13 +35,11 @@ import {
21
35
  redactDeep,
22
36
  redactString,
23
37
  resolveApiKey,
24
- resolveApiTenantId,
25
38
  resolveIngestUrl,
26
39
  resolveModaBaseUrl,
27
40
  resolveTenantId,
28
- shouldInventoryFile,
29
- stringOption
30
- } from "./cli-0qnghzg4.js";
41
+ shouldInventoryFile
42
+ } from "./cli-kwz900s4.js";
31
43
  import {
32
44
  __commonJS,
33
45
  __require,
@@ -9456,7 +9468,7 @@ var require_typescript = __commonJS((exports, module) => {
9456
9468
  commandLineOptionOfCustomType: () => commandLineOptionOfCustomType,
9457
9469
  commentPragmas: () => commentPragmas,
9458
9470
  commonOptionsWithBuild: () => commonOptionsWithBuild,
9459
- compact: () => compact2,
9471
+ compact: () => compact,
9460
9472
  compareBooleans: () => compareBooleans,
9461
9473
  compareDataObjects: () => compareDataObjects,
9462
9474
  compareDiagnostics: () => compareDiagnostics,
@@ -11976,7 +11988,7 @@ var require_typescript = __commonJS((exports, module) => {
11976
11988
  }
11977
11989
  return true;
11978
11990
  }
11979
- function compact2(array) {
11991
+ function compact(array) {
11980
11992
  let result;
11981
11993
  if (array !== undefined) {
11982
11994
  for (let i = 0;i < array.length; i++) {
@@ -97633,7 +97645,7 @@ ${lanes.join(`
97633
97645
  const savedPendingExpressions = pendingExpressions;
97634
97646
  pendingExpressions = undefined;
97635
97647
  node = factory2.updateBinaryExpression(node, visitNode(node.left, assignmentTargetVisitor, isExpression), node.operatorToken, visitNode(node.right, visitor, isExpression));
97636
- const expr = some(pendingExpressions) ? factory2.inlineExpressions(compact2([...pendingExpressions, node])) : node;
97648
+ const expr = some(pendingExpressions) ? factory2.inlineExpressions(compact([...pendingExpressions, node])) : node;
97637
97649
  pendingExpressions = savedPendingExpressions;
97638
97650
  return expr;
97639
97651
  }
@@ -107437,14 +107449,14 @@ ${lanes.join(`
107437
107449
  }
107438
107450
  }
107439
107451
  function createImportCallExpressionAMD(arg, containsLexicalThis) {
107440
- const resolve8 = factory2.createUniqueName("resolve");
107452
+ const resolve7 = factory2.createUniqueName("resolve");
107441
107453
  const reject = factory2.createUniqueName("reject");
107442
107454
  const parameters = [
107443
- factory2.createParameterDeclaration(undefined, undefined, resolve8),
107455
+ factory2.createParameterDeclaration(undefined, undefined, resolve7),
107444
107456
  factory2.createParameterDeclaration(undefined, undefined, reject)
107445
107457
  ];
107446
107458
  const body = factory2.createBlock([
107447
- factory2.createExpressionStatement(factory2.createCallExpression(factory2.createIdentifier("require"), undefined, [factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve8, reject]))
107459
+ factory2.createExpressionStatement(factory2.createCallExpression(factory2.createIdentifier("require"), undefined, [factory2.createArrayLiteralExpression([arg || factory2.createOmittedExpression()]), resolve7, reject]))
107448
107460
  ]);
107449
107461
  let func;
107450
107462
  if (languageVersion >= 2) {
@@ -110425,7 +110437,7 @@ ${lanes.join(`
110425
110437
  let parameterProperties;
110426
110438
  if (ctor) {
110427
110439
  const oldDiag2 = getSymbolAccessibilityDiagnostic;
110428
- parameterProperties = compact2(flatMap(ctor.parameters, (param) => {
110440
+ parameterProperties = compact(flatMap(ctor.parameters, (param) => {
110429
110441
  if (!hasSyntacticModifier(param, 31) || shouldStripInternal(param))
110430
110442
  return;
110431
110443
  getSymbolAccessibilityDiagnostic = createGetSymbolAccessibilityDiagnosticForNode(param);
@@ -141758,7 +141770,7 @@ ${newComment.split(`
141758
141770
  }
141759
141771
  const checker = context.program.getTypeChecker();
141760
141772
  const trackChanges = (cb) => ts_textChanges_exports.ChangeTracker.with(context, cb);
141761
- return compact2([
141773
+ return compact([
141762
141774
  getDeclarationSiteFix(context, expression, errorCode, checker, trackChanges),
141763
141775
  getUseSiteFix(context, expression, errorCode, checker, trackChanges)
141764
141776
  ]);
@@ -160752,7 +160764,7 @@ ${content}
160752
160764
  const lastToken = last(children);
160753
160765
  const separateLastToken = separateTrailingSemicolon && lastToken.kind === 27;
160754
160766
  const rightChildren = children.slice(splitTokenIndex + 1, separateLastToken ? children.length - 1 : undefined);
160755
- const result = compact2([
160767
+ const result = compact([
160756
160768
  leftChildren.length ? createSyntaxList2(leftChildren) : undefined,
160757
160769
  splitToken,
160758
160770
  rightChildren.length ? createSyntaxList2(rightChildren) : undefined
@@ -165456,7 +165468,7 @@ ${options.prefix}` : `
165456
165468
  commandLineOptionOfCustomType: () => commandLineOptionOfCustomType,
165457
165469
  commentPragmas: () => commentPragmas,
165458
165470
  commonOptionsWithBuild: () => commonOptionsWithBuild,
165459
- compact: () => compact2,
165471
+ compact: () => compact,
165460
165472
  compareBooleans: () => compareBooleans,
165461
165473
  compareDataObjects: () => compareDataObjects,
165462
165474
  compareDiagnostics: () => compareDiagnostics,
@@ -177619,8 +177631,8 @@ Additional information: BADCLIENT: Bad error code, ${badCode} not found in range
177619
177631
  installPackage(options) {
177620
177632
  this.packageInstallId++;
177621
177633
  const request = { kind: "installPackage", ...options, id: this.packageInstallId };
177622
- const promise = new Promise((resolve8, reject) => {
177623
- (this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map)).set(this.packageInstallId, { resolve: resolve8, reject });
177634
+ const promise = new Promise((resolve7, reject) => {
177635
+ (this.packageInstalledPromise ?? (this.packageInstalledPromise = /* @__PURE__ */ new Map)).set(this.packageInstallId, { resolve: resolve7, reject });
177624
177636
  });
177625
177637
  this.installer.send(request);
177626
177638
  return promise;
@@ -177889,668 +177901,14 @@ import {
177889
177901
  lstatSync as lstatSync10,
177890
177902
  mkdtempSync as mkdtempSync2,
177891
177903
  mkdirSync as mkdirSync6,
177892
- readFileSync as readFileSync18,
177904
+ readFileSync as readFileSync17,
177893
177905
  readdirSync as readdirSync4,
177894
177906
  writeFileSync as writeFileSync6,
177895
177907
  rmSync as rmSync4
177896
177908
  } from "node:fs";
177897
- import { basename as basename7, delimiter, dirname as dirname9, join as join10, relative as relative8, resolve as resolve14, sep as sep5 } from "node:path";
177909
+ import { basename as basename7, delimiter, dirname as dirname9, join as join10, relative as relative8, resolve as resolve13, sep as sep5 } from "node:path";
177898
177910
  import { confirm as confirm2, select } from "@inquirer/prompts";
177899
177911
 
177900
- // src/parity-commands.ts
177901
- import { readFileSync } from "node:fs";
177902
- import { resolve } from "node:path";
177903
-
177904
- // src/api-key-headers.ts
177905
- var PLATFORM_API_KEY_PREFIX = "moda_pk_";
177906
- var TENANT_HEADER = "x-moda-tenant-id";
177907
- function isPlatformApiKey(key) {
177908
- return Boolean(key?.startsWith(PLATFORM_API_KEY_PREFIX));
177909
- }
177910
- var platformTenantOverride;
177911
- function setPlatformTenantOverride(tenantId) {
177912
- platformTenantOverride = tenantId;
177913
- }
177914
- var TENANT_PATH = /\/tenants\/([^/?#]+)/;
177915
- function tenantFromUrl(url) {
177916
- const match = url ? TENANT_PATH.exec(url) : null;
177917
- return match ? decodeURIComponent(match[1]) : undefined;
177918
- }
177919
- function apiKeyHeaders(key, options = {}, url) {
177920
- const headers = { "x-api-key": key };
177921
- if (isPlatformApiKey(key)) {
177922
- const tenantId = tenantFromUrl(url) || platformTenantOverride || resolveTenantId(options);
177923
- if (tenantId)
177924
- headers[TENANT_HEADER] = tenantId;
177925
- }
177926
- return headers;
177927
- }
177928
-
177929
- // src/api-client.ts
177930
- var REQUEST_TIMEOUT_MS = 30000;
177931
- var MAX_RETRIES = 3;
177932
- var INITIAL_BACKOFF_MS = 500;
177933
- var NETWORK_RETRY_DELAY_MS = 1000;
177934
-
177935
- class ApiError extends Error {
177936
- statusCode;
177937
- responseBody;
177938
- code;
177939
- suggestions;
177940
- readable;
177941
- constructor(message, statusCode, responseBody) {
177942
- const typed = parseTypedErrorBody(responseBody);
177943
- const platform = platformFailure(responseBody);
177944
- const readable = typed?.code === "audit_too_large" || platform !== null;
177945
- super(readable ? `API error (${statusCode}): ${typed?.message ?? platform?.message}` : message);
177946
- this.statusCode = statusCode;
177947
- this.responseBody = responseBody;
177948
- this.name = "ApiError";
177949
- this.code = typed?.code ?? platform?.code;
177950
- this.suggestions = typed?.suggestions;
177951
- this.readable = readable;
177952
- }
177953
- }
177954
- function parseTypedErrorBody(body) {
177955
- if (!body.trimStart().startsWith("{"))
177956
- return null;
177957
- try {
177958
- const parsed = JSON.parse(body);
177959
- if (typeof parsed.code !== "string")
177960
- return null;
177961
- const suggestions = Array.isArray(parsed.suggestions) ? parsed.suggestions.filter((s) => typeof s === "string") : undefined;
177962
- return {
177963
- code: parsed.code,
177964
- message: typeof parsed.message === "string" ? parsed.message : undefined,
177965
- suggestions
177966
- };
177967
- } catch {
177968
- return null;
177969
- }
177970
- }
177971
- var DETERMINISTIC_PLATFORM_FAILURES = [
177972
- "FUNCTION_INVOCATION_FAILED",
177973
- "FUNCTION_RESPONSE_PAYLOAD_TOO_LARGE"
177974
- ];
177975
- function platformFailure(body) {
177976
- const code = DETERMINISTIC_PLATFORM_FAILURES.find((c) => body.includes(c));
177977
- if (!code)
177978
- return null;
177979
- const requestId = /\b([a-z]{3}\d::[A-Za-z0-9:-]+)/.exec(body)?.[1];
177980
- const cause = code === "FUNCTION_RESPONSE_PAYLOAD_TOO_LARGE" ? "the response was larger than the hosting platform allows" : "the server function crashed (typically out of memory or an oversized response)";
177981
- return {
177982
- code,
177983
- message: `The Moda API could not complete this request: ${cause} [${code}` + `${requestId ? `, request ${requestId}` : ""}]. Retrying the same request will fail the same way; ` + "narrow it (a smaller --limit, a single trace, or fewer results) and report it with `moda feedback` if it persists."
177984
- };
177985
- }
177986
- function isRetryableResponse(status, body) {
177987
- if (!isRetryable(status))
177988
- return false;
177989
- return platformFailure(body) === null;
177990
- }
177991
-
177992
- class NetworkError extends Error {
177993
- constructor(message) {
177994
- super(message);
177995
- this.name = "NetworkError";
177996
- }
177997
- }
177998
- function networkErrorMessage(error, url) {
177999
- const message = error instanceof Error ? error.message : String(error);
178000
- const cause = error instanceof Error ? error.cause : undefined;
178001
- const code = typeof cause?.code === "string" ? `: ${cause.code}` : "";
178002
- return `Network error: ${message} (could not reach ${url.split("?")[0]}${code})`;
178003
- }
178004
- function isRetryable(status) {
178005
- return status === 429 || status >= 500;
178006
- }
178007
- async function callDataAPI(endpoint, init = { method: "GET" }, requestOptions = {}) {
178008
- const url = `${resolveModaBaseUrl()}/api/v1/data${endpoint}`;
178009
- return callModaAPI(url, init, {}, requestOptions);
178010
- }
178011
- async function callControlAPI(endpoint, options = {}, profileOptions = {}, requestOptions = {}) {
178012
- const url = `${resolveModaBaseUrl(profileOptions)}/api${endpoint}`;
178013
- return callModaAPI(url, options, profileOptions, requestOptions);
178014
- }
178015
- async function callModaAPI(url, options, profileOptions = {}, requestOptions = {}) {
178016
- const timeoutMs = requestOptions.timeoutMs ?? REQUEST_TIMEOUT_MS;
178017
- const method = (options.method ?? "GET").toUpperCase();
178018
- const maxRetries = requestOptions.retries ?? (method === "GET" || method === "HEAD" ? MAX_RETRIES : 0);
178019
- const initialNetworkRetryBudget = requestOptions.retryOnceOnNetworkError ? 1 : 0;
178020
- let networkRetryBudget = initialNetworkRetryBudget;
178021
- let connectionClose = false;
178022
- const maxAttempts = maxRetries + initialNetworkRetryBudget + 1;
178023
- for (let attempt = 0;attempt < maxAttempts; attempt++) {
178024
- if (attempt > 0) {
178025
- const backoff = connectionClose ? requestOptions.networkRetryDelayMs ?? NETWORK_RETRY_DELAY_MS : INITIAL_BACKOFF_MS * Math.pow(2, attempt - 1);
178026
- await new Promise((resolve) => setTimeout(resolve, backoff));
178027
- }
178028
- const controller = new AbortController;
178029
- const timeout = setTimeout(() => controller.abort(), timeoutMs);
178030
- try {
178031
- recordApiRequest();
178032
- const response = await fetch(url, {
178033
- ...options,
178034
- headers: {
178035
- ...apiKeyHeaders(resolveApiKey(profileOptions) ?? "", profileOptions, url),
178036
- "Content-Type": "application/json",
178037
- ...options.headers ?? {},
178038
- ...connectionClose ? { Connection: "close" } : {}
178039
- },
178040
- signal: controller.signal
178041
- });
178042
- if (!response.ok) {
178043
- const errorText = await response.text();
178044
- const error = new ApiError(`API error (${response.status}): ${errorText}`, response.status, errorText);
178045
- if (isRetryableResponse(response.status, errorText) && attempt < maxRetries) {
178046
- continue;
178047
- }
178048
- throw error;
178049
- }
178050
- if (response.status === 204)
178051
- return null;
178052
- if (typeof response.text !== "function")
178053
- return response.json();
178054
- const text = await response.text();
178055
- return text.trim() === "" ? null : JSON.parse(text);
178056
- } catch (error) {
178057
- if (error instanceof ApiError)
178058
- throw error;
178059
- const isAbort = error instanceof DOMException && error.name === "AbortError";
178060
- const wrapped = isAbort ? new Error(`Request timed out after ${timeoutMs}ms: ${url}`) : new NetworkError(networkErrorMessage(error, url));
178061
- if (attempt < maxRetries) {
178062
- continue;
178063
- }
178064
- if (!isAbort && networkRetryBudget > 0) {
178065
- networkRetryBudget -= 1;
178066
- connectionClose = true;
178067
- requestOptions.onNetworkRetry?.();
178068
- continue;
178069
- }
178070
- throw wrapped;
178071
- } finally {
178072
- clearTimeout(timeout);
178073
- }
178074
- }
178075
- throw new NetworkError(`Request retries exhausted: ${url}`);
178076
- }
178077
-
178078
- // src/parity-commands.ts
178079
- var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
178080
- var WINDOWS = ["24h", "7d", "30d", "90d"];
178081
- function profileOptions(context) {
178082
- return { profile: context.profile, env: context.env };
178083
- }
178084
- function requireKey(context) {
178085
- if (!resolveApiKey(profileOptions(context))) {
178086
- throw new CliInputError(`No Moda API key found for moda ${context.command}.`, "Set MODA_API_KEY, run `moda auth login --api-key`, or select a profile with an API key.");
178087
- }
178088
- }
178089
- function requireTenant(context) {
178090
- const key = resolveApiKey(profileOptions(context));
178091
- const keyTenant = key ? embeddedTenantIdFromApiKey(key) : undefined;
178092
- const flagTenant = context.flags["tenant-id"];
178093
- if (flagTenant && keyTenant && flagTenant !== keyTenant) {
178094
- throw new CliInputError(`--tenant-id=${flagTenant} does not match this API key's tenant (${keyTenant}), so nothing was sent.`, "Drop --tenant-id (the key names its tenant) or use a key for that tenant.");
178095
- }
178096
- const tenantId = flagTenant || resolveApiTenantId(profileOptions(context));
178097
- if (!tenantId) {
178098
- throw new CliInputError("Could not determine the tenant.", "Use a signed API key (it names its tenant), set MODA_TENANT_ID, or pass --tenant-id=<id>.");
178099
- }
178100
- if (isPlatformApiKey(key))
178101
- setPlatformTenantOverride(tenantId);
178102
- return tenantId;
178103
- }
178104
- function assertFlags(command, flags, allowed) {
178105
- if (command.startsWith("signals "))
178106
- allowed = [...allowed, "tenant-id"];
178107
- const globals = [
178108
- "agent",
178109
- "json",
178110
- "human",
178111
- "prose",
178112
- "quiet",
178113
- "verbose",
178114
- "yes",
178115
- "profile",
178116
- "progress",
178117
- "format",
178118
- "no-telemetry",
178119
- "no-update-check",
178120
- "help",
178121
- "version",
178122
- "json-schemas",
178123
- "stream",
178124
- "no-stream",
178125
- "tui",
178126
- "no-tui"
178127
- ];
178128
- const known = new Set([...allowed, ...globals]);
178129
- const unknown = Object.keys(flags).filter((flag) => !known.has(flag));
178130
- if (unknown.includes("dry-run")) {
178131
- throw new CliInputError(`'moda ${command}' has no dry-run mode, so nothing was sent.`, "Remove --dry-run to run it for real.");
178132
- }
178133
- if (unknown.length > 0) {
178134
- throw new CliInputError(`Unknown flag${unknown.length > 1 ? "s" : ""} ${unknown.map((flag) => `--${flag}`).join(", ")} for 'moda ${command}'.`, `Valid flags: ${allowed.map((flag) => `--${flag}`).join(", ") || "(none)"}.`);
178135
- }
178136
- }
178137
- function assertPositionals(command, positionals, max, usage) {
178138
- if (positionals.length > max) {
178139
- throw new CliInputError(`Unexpected argument${positionals.length - max > 1 ? "s" : ""} '${positionals.slice(max).join(" ")}' for 'moda ${command}', so nothing was sent.`, `Usage: ${usage}`);
178140
- }
178141
- }
178142
- function oneOf(name, value, allowed) {
178143
- if (value === undefined)
178144
- return;
178145
- if (!allowed.includes(value)) {
178146
- throw new CliInputError(`--${name} must be one of ${allowed.join(", ")} (got '${value}').`);
178147
- }
178148
- return value;
178149
- }
178150
- function csv(value) {
178151
- if (value === undefined)
178152
- return;
178153
- const items = value.split(",").map((item) => item.trim()).filter(Boolean);
178154
- return items.length > 0 ? items : undefined;
178155
- }
178156
- function readBodyFile(flags, cwd) {
178157
- if (!flags.file)
178158
- return {};
178159
- if (flags.file === "true")
178160
- throw new CliInputError("Missing path for --file.");
178161
- let parsed;
178162
- try {
178163
- parsed = JSON.parse(readFileSync(resolve(cwd, flags.file), "utf8"));
178164
- } catch (error) {
178165
- throw new CliInputError(`Could not read --file ${flags.file}: ${error instanceof Error ? error.message : String(error)}`);
178166
- }
178167
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
178168
- throw new CliInputError("--file must contain a JSON object (the request body).");
178169
- }
178170
- return parsed;
178171
- }
178172
- function compact(value) {
178173
- return Object.fromEntries(Object.entries(value).filter(([, item]) => item !== undefined));
178174
- }
178175
- var LLM_WRITE_TIMEOUT_MS = 180000;
178176
- async function send(context, plane, method, endpoint, body, options = {}) {
178177
- const init = { method, ...body !== undefined ? { body: JSON.stringify(body) } : {} };
178178
- if (method !== "GET" && context.dryRun) {
178179
- context.output.writeData({
178180
- dryRun: true,
178181
- planned: { method, endpoint: plane === "data" ? `/api/v1/data${endpoint}` : `/api${endpoint}`, ...body !== undefined ? { body } : {} }
178182
- }, { summary: { text: `Dry run: would ${method} ${endpoint}. Nothing was sent.`, confidence: "high" } });
178183
- return;
178184
- }
178185
- const requestOptions = method === "GET" ? {} : { retries: 0, ...options.slow ? { timeoutMs: LLM_WRITE_TIMEOUT_MS } : {} };
178186
- const data = plane === "data" ? await callDataAPI(endpoint, init, requestOptions) : await callControlAPI(endpoint, init, profileOptions(context), requestOptions);
178187
- context.output.writeData(data ?? { ok: true });
178188
- }
178189
- var USER_COHORTS = ["all", "power_users", "heavy_tool_users", "frustrated", "at_risk", "new_this_week", "silent_sufferers"];
178190
- var USER_SORTS = ["last_seen", "health_score", "conversation_count", "frustration_max"];
178191
- var HEALTH = ["healthy", "at_risk", "frustrated"];
178192
- async function runUsersCommand(context) {
178193
- const flags = context.flags;
178194
- assertFlags("users", flags, [
178195
- "window",
178196
- "page",
178197
- "page-size",
178198
- "limit",
178199
- "search",
178200
- "cohort",
178201
- "sort",
178202
- "order",
178203
- "health-status",
178204
- "min-health",
178205
- "max-health",
178206
- "min-conversations",
178207
- "min-tool-failures",
178208
- "tenant-id"
178209
- ]);
178210
- if (context.positionals.length > 0) {
178211
- throw new CliInputError(`'moda users' takes no arguments. For one user use 'moda user <user_id>'.`);
178212
- }
178213
- if (flags.limit !== undefined && flags["page-size"] !== undefined && flags.limit !== flags["page-size"]) {
178214
- throw new CliInputError(`Got --limit=${flags.limit} and --page-size=${flags["page-size"]}; they are the same flag for 'moda users', so nothing was sent.`, "Pass only one of --limit / --page-size.", "flag_conflict");
178215
- }
178216
- requireKey(context);
178217
- const tenantId = requireTenant(context);
178218
- const query = new URLSearchParams(compact({
178219
- window: oneOf("window", flags.window, WINDOWS),
178220
- page: flags.page,
178221
- pageSize: flags["page-size"] ?? flags.limit,
178222
- search: flags.search,
178223
- cohort: oneOf("cohort", flags.cohort, USER_COHORTS),
178224
- sortBy: oneOf("sort", flags.sort, USER_SORTS),
178225
- sortOrder: oneOf("order", flags.order, ["asc", "desc"]),
178226
- healthStatus: csv(flags["health-status"])?.map((value) => oneOf("health-status", value, HEALTH)).join(","),
178227
- minHealthScore: flags["min-health"],
178228
- maxHealthScore: flags["max-health"],
178229
- minConversations: flags["min-conversations"],
178230
- minToolFailures: flags["min-tool-failures"]
178231
- }));
178232
- const suffix = query.toString() ? `?${query.toString()}` : "";
178233
- await send(context, "control", "GET", `/tenants/${encodeURIComponent(tenantId)}/users${suffix}`);
178234
- return { exitCode: 0 };
178235
- }
178236
- async function runUserCommand(context) {
178237
- const flags = context.flags;
178238
- assertFlags("user", flags, ["window", "activity-cursor", "tenant-id"]);
178239
- assertPositionals("user", context.positionals, 1, "moda user <user_id> [--window=24h|7d|30d|90d]");
178240
- const userId = context.positionals[0];
178241
- if (!userId)
178242
- throw new CliInputError("<user_id> is required.", "Usage: moda user <user_id> [--window=24h|7d|30d|90d]");
178243
- requireKey(context);
178244
- const tenantId = requireTenant(context);
178245
- const query = new URLSearchParams(compact({
178246
- window: oneOf("window", flags.window, WINDOWS),
178247
- activityCursor: flags["activity-cursor"]
178248
- }));
178249
- const suffix = query.toString() ? `?${query.toString()}` : "";
178250
- await send(context, "control", "GET", `/tenants/${encodeURIComponent(tenantId)}/users/${encodeURIComponent(userId)}${suffix}`);
178251
- return { exitCode: 0 };
178252
- }
178253
- async function runProblemReopenCommand(context) {
178254
- assertFlags("problem-reopen", context.flags, ["reason", "dry-run"]);
178255
- assertPositionals("problem-reopen", context.positionals, 1, "moda problem-reopen <problem_id> [--reason=TEXT]");
178256
- const problemId = context.positionals[0];
178257
- const usage = "Usage: moda problem-reopen <problem_id> [--reason=TEXT]";
178258
- if (!problemId || !UUID_RE.test(problemId))
178259
- throw new CliInputError("<problem_id> (UUID) is required.", usage);
178260
- const reason = context.flags.reason;
178261
- if (reason !== undefined && reason.length > 500)
178262
- throw new CliInputError("--reason must be 500 characters or fewer.");
178263
- requireKey(context);
178264
- await send(context, "data", "POST", `/problems/${problemId}/reopen`, compact({ reason }));
178265
- return { exitCode: 0 };
178266
- }
178267
- var SIGNAL_FIELD_FLAGS = [
178268
- "name",
178269
- "description",
178270
- "pass-criteria",
178271
- "fail-criteria",
178272
- "polarity",
178273
- "locus",
178274
- "tool-names",
178275
- "keyword-hints",
178276
- "use-case-id",
178277
- "message-types",
178278
- "note",
178279
- "file"
178280
- ];
178281
- function signalBody(flags, cwd) {
178282
- const fromFile = readBodyFile(flags, cwd);
178283
- const scope = compact({
178284
- toolNames: csv(flags["tool-names"]),
178285
- keywordHints: csv(flags["keyword-hints"]),
178286
- useCaseId: flags["use-case-id"],
178287
- messageTypes: csv(flags["message-types"])
178288
- });
178289
- return {
178290
- ...fromFile,
178291
- ...compact({
178292
- name: flags.name,
178293
- description: flags.description,
178294
- passCriteria: flags["pass-criteria"],
178295
- failCriteria: flags["fail-criteria"],
178296
- polarity: oneOf("polarity", flags.polarity, ["violation", "expectation"]),
178297
- locus: oneOf("locus", flags.locus, ["agent", "tool_output", "user_input"]),
178298
- note: flags.note
178299
- }),
178300
- ...Object.keys(scope).length > 0 ? { scope: { ...fromFile.scope ?? {}, ...scope } } : {}
178301
- };
178302
- }
178303
- var SIGNAL_USAGE = [
178304
- "moda signals list custom signals",
178305
- 'moda signals draft --note="…" AI-draft criteria from a description',
178306
- "moda signals create --name --description --pass-criteria --fail-criteria [--polarity --locus --tool-names=a,b] [--file=body.json]",
178307
- "moda signals update <id> [same flags] edit a signal",
178308
- "moda signals activate|pause|delete <id> (delete: drafts only; archive is dashboard-only)",
178309
- "moda signals examples <id> add|update|remove --conversation-id=ID [--label=fits|does_not_fit --note --msg-index]",
178310
- 'moda signals refine <id> --request="…" propose a criteria edit',
178311
- "moda signals revise <id> --conversation-ids=a,b re-derive criteria from labelled traces",
178312
- "moda signals proposals <id> | accept <id> <proposal_id> | reject <id> <proposal_id>",
178313
- "moda signals search <id> [--mode=wizard|full] | search-status <id> <search_id> | search-stop <id> <search_id>",
178314
- "moda signals preview --file=detector.json [--conversation-ids=a,b --max-examples=N]",
178315
- "All write subcommands accept --dry-run (prints the request, sends nothing)."
178316
- ].join(`
178317
- `);
178318
- async function runSignalsManagementCommand(sub, context) {
178319
- const flags = context.flags;
178320
- const args = context.positionals.slice(1);
178321
- const arity = {
178322
- draft: 0,
178323
- create: 0,
178324
- preview: 0,
178325
- update: 1,
178326
- activate: 1,
178327
- pause: 1,
178328
- delete: 1,
178329
- examples: 2,
178330
- refine: 1,
178331
- revise: 1,
178332
- proposals: 1,
178333
- accept: 2,
178334
- reject: 2,
178335
- search: 1,
178336
- "search-status": 2,
178337
- "search-stop": 2
178338
- };
178339
- if (sub in arity)
178340
- assertPositionals(`signals ${sub}`, args, arity[sub], SIGNAL_USAGE.split(`
178341
- `)[0]);
178342
- const base = () => `/tenants/${encodeURIComponent(requireTenant(context))}/custom-signals`;
178343
- const id = (index = 0, what = "a signal id") => {
178344
- const value = args[index];
178345
- if (!value)
178346
- throw new CliInputError(`moda signals ${sub} needs ${what}.`, `Usage:
178347
- ${SIGNAL_USAGE}`);
178348
- return encodeURIComponent(value);
178349
- };
178350
- const start = () => requireKey(context);
178351
- switch (sub) {
178352
- case "draft": {
178353
- assertFlags("signals draft", flags, ["note", "file", "dry-run"]);
178354
- const body = { ...readBodyFile(flags, context.cwd), ...compact({ note: flags.note }) };
178355
- if (!body.note)
178356
- throw new CliInputError("--note is required (describe what the signal should catch).");
178357
- start();
178358
- await send(context, "control", "POST", `${base()}/draft`, body, { slow: true });
178359
- return { exitCode: 0 };
178360
- }
178361
- case "create": {
178362
- assertFlags("signals create", flags, [...SIGNAL_FIELD_FLAGS, "dry-run"]);
178363
- const body = signalBody(flags, context.cwd);
178364
- const missing = ["name", "description", "passCriteria", "failCriteria"].filter((field) => !body[field]);
178365
- if (missing.length > 0) {
178366
- throw new CliInputError(`Missing ${missing.join(", ")} for signals create.`, 'Pass --name --description --pass-criteria --fail-criteria, or a --file with those fields. Tip: `moda signals draft --note="…"` drafts them.');
178367
- }
178368
- start();
178369
- await send(context, "control", "POST", base(), body);
178370
- return { exitCode: 0 };
178371
- }
178372
- case "update": {
178373
- assertFlags("signals update", flags, [...SIGNAL_FIELD_FLAGS, "dry-run"]);
178374
- const signalId = id();
178375
- const body = signalBody(flags, context.cwd);
178376
- if (Object.keys(body).length === 0)
178377
- throw new CliInputError("Nothing to update: pass at least one field flag or --file.");
178378
- start();
178379
- await send(context, "control", "PATCH", `${base()}/${signalId}`, body);
178380
- return { exitCode: 0 };
178381
- }
178382
- case "activate":
178383
- case "pause": {
178384
- assertFlags(`signals ${sub}`, flags, ["dry-run"]);
178385
- const signalId = id();
178386
- start();
178387
- await send(context, "control", "POST", `${base()}/${signalId}/${sub}`);
178388
- return { exitCode: 0 };
178389
- }
178390
- case "delete": {
178391
- assertFlags("signals delete", flags, ["dry-run"]);
178392
- const signalId = id();
178393
- start();
178394
- await send(context, "control", "DELETE", `${base()}/${signalId}`);
178395
- return { exitCode: 0 };
178396
- }
178397
- case "examples": {
178398
- const signalId = id();
178399
- const action = args[1];
178400
- const conversationId = flags["conversation-id"];
178401
- if (!action || !["add", "update", "remove"].includes(action)) {
178402
- throw new CliInputError("Usage: moda signals examples <id> add|update|remove --conversation-id=ID …");
178403
- }
178404
- if (!conversationId)
178405
- throw new CliInputError("--conversation-id is required.");
178406
- if (action === "add") {
178407
- assertFlags("signals examples add", flags, ["conversation-id", "label", "note", "msg-index", "msg-dedup-token", "criteria", "verdict", "dry-run"]);
178408
- const label = oneOf("label", flags.label, ["fits", "does_not_fit"]);
178409
- if (!label)
178410
- throw new CliInputError("--label=fits|does_not_fit is required.");
178411
- start();
178412
- await send(context, "control", "POST", `${base()}/${signalId}/examples`, compact({
178413
- conversationId,
178414
- label,
178415
- source: "api",
178416
- note: flags.note,
178417
- msgIndex: flags["msg-index"] !== undefined ? Number(flags["msg-index"]) : undefined,
178418
- msgDedupToken: flags["msg-dedup-token"],
178419
- criteria: oneOf("criteria", flags.criteria, ["pass", "fail"]),
178420
- verdict: oneOf("verdict", flags.verdict, ["accept", "reject"])
178421
- }));
178422
- } else if (action === "update") {
178423
- assertFlags("signals examples update", flags, ["conversation-id", "label", "note", "blurb", "dry-run"]);
178424
- const body = compact({ label: oneOf("label", flags.label, ["fits", "does_not_fit"]), note: flags.note, blurb: flags.blurb });
178425
- if (Object.keys(body).length === 0)
178426
- throw new CliInputError("Nothing to update: pass --label, --note, or --blurb.");
178427
- start();
178428
- await send(context, "control", "PATCH", `${base()}/${signalId}/examples/${encodeURIComponent(conversationId)}`, body);
178429
- } else {
178430
- assertFlags("signals examples remove", flags, ["conversation-id", "dry-run"]);
178431
- start();
178432
- await send(context, "control", "DELETE", `${base()}/${signalId}/examples/${encodeURIComponent(conversationId)}`);
178433
- }
178434
- return { exitCode: 0 };
178435
- }
178436
- case "refine": {
178437
- assertFlags("signals refine", flags, ["request", "dry-run"]);
178438
- const signalId = id();
178439
- const request = flags.request;
178440
- if (!request || request.length > 2000)
178441
- throw new CliInputError("--request (1–2000 characters) is required.");
178442
- start();
178443
- await send(context, "control", "POST", `${base()}/${signalId}/refine`, { request }, { slow: true });
178444
- return { exitCode: 0 };
178445
- }
178446
- case "revise": {
178447
- assertFlags("signals revise", flags, ["conversation-ids", "dry-run"]);
178448
- const signalId = id();
178449
- const conversationIds = csv(flags["conversation-ids"]);
178450
- if (!conversationIds)
178451
- throw new CliInputError("--conversation-ids=a,b is required.");
178452
- start();
178453
- await send(context, "control", "POST", `${base()}/${signalId}/revise`, { conversationIds }, { slow: true });
178454
- return { exitCode: 0 };
178455
- }
178456
- case "proposals": {
178457
- assertFlags("signals proposals", flags, []);
178458
- const signalId = id();
178459
- start();
178460
- await send(context, "control", "GET", `${base()}/${signalId}/proposals`);
178461
- return { exitCode: 0 };
178462
- }
178463
- case "accept":
178464
- case "reject": {
178465
- assertFlags(`signals ${sub}`, flags, ["dry-run"]);
178466
- const signalId = id();
178467
- const proposalId = id(1, "a proposal id (see `moda signals proposals <id>`)");
178468
- start();
178469
- await send(context, "control", "POST", `${base()}/${signalId}/proposals/${proposalId}/${sub}`);
178470
- return { exitCode: 0 };
178471
- }
178472
- case "search": {
178473
- assertFlags("signals search", flags, ["mode", "exclude-conversation-ids", "dry-run"]);
178474
- const signalId = id();
178475
- start();
178476
- await send(context, "control", "POST", `${base()}/${signalId}/search`, compact({
178477
- mode: oneOf("mode", flags.mode, ["wizard", "full"]),
178478
- excludeConversationIds: csv(flags["exclude-conversation-ids"])
178479
- }), { slow: true });
178480
- return { exitCode: 0 };
178481
- }
178482
- case "search-status":
178483
- case "search-stop": {
178484
- assertFlags(`signals ${sub}`, flags, sub === "search-stop" ? ["dry-run"] : []);
178485
- const signalId = id();
178486
- const searchId = id(1, "a search id (returned by `moda signals search <id>`)");
178487
- start();
178488
- await send(context, "control", sub === "search-stop" ? "POST" : "GET", `${base()}/${signalId}/searches/${searchId}${sub === "search-stop" ? "/stop" : ""}`);
178489
- return { exitCode: 0 };
178490
- }
178491
- case "preview": {
178492
- assertFlags("signals preview", flags, ["file", "conversation-ids", "max-examples"]);
178493
- const body = readBodyFile(flags, context.cwd);
178494
- if (!body.detector)
178495
- throw new CliInputError('--file must contain {"detector": {...}} (optionally scope).');
178496
- start();
178497
- try {
178498
- await send(context, "control", "POST", `${base()}/detector-preview`, {
178499
- ...body,
178500
- ...compact({
178501
- conversationIds: csv(flags["conversation-ids"]),
178502
- maxExamples: flags["max-examples"] !== undefined ? Number(flags["max-examples"]) : undefined
178503
- })
178504
- });
178505
- } catch (error) {
178506
- if (isTenantFeatureNotFound(error)) {
178507
- throw new CliAccessError("The signal builder is not enabled for this tenant, so `moda signals preview` is unavailable (the API answered 404).", { guidance: "Ask Moda to enable the signal-builder feature for this tenant. Other `moda signals` subcommands still work." });
178508
- }
178509
- throw error;
178510
- }
178511
- return { exitCode: 0 };
178512
- }
178513
- default:
178514
- throw unknownSignalsSubcommandError(sub, args);
178515
- }
178516
- }
178517
- function isTenantFeatureNotFound(error) {
178518
- if (!(error instanceof ApiError) || error.statusCode !== 404)
178519
- return false;
178520
- try {
178521
- const body = JSON.parse(error.responseBody);
178522
- return body.message === "Not Found" && body.error === undefined;
178523
- } catch {
178524
- return false;
178525
- }
178526
- }
178527
- var SIGNALS_MANAGEMENT_SUBCOMMANDS = new Set([
178528
- "draft",
178529
- "create",
178530
- "update",
178531
- "activate",
178532
- "pause",
178533
- "delete",
178534
- "examples",
178535
- "refine",
178536
- "revise",
178537
- "proposals",
178538
- "accept",
178539
- "reject",
178540
- "search",
178541
- "search-status",
178542
- "search-stop",
178543
- "preview"
178544
- ]);
178545
- function unknownSignalsSubcommandError(sub, args = []) {
178546
- if (sub === "archive") {
178547
- const id = args[0] ?? "<signal_id>";
178548
- 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}.`);
178549
- }
178550
- 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:
178551
- ${SIGNAL_USAGE}`);
178552
- }
178553
-
178554
177912
  // src/analyst-tui.ts
178555
177913
  class AnalystTui {
178556
177914
  state;
@@ -178655,16 +178013,16 @@ class AnalystTui {
178655
178013
  this.active = false;
178656
178014
  }
178657
178015
  pushTimeline(label, message) {
178658
- const compact2 = compactWhitespace(message);
178659
- if (!compact2)
178016
+ const compact = compactWhitespace(message);
178017
+ if (!compact)
178660
178018
  return;
178661
178019
  const last = this.state.timeline.at(-1);
178662
- if (last?.label === label && last.message === compact2)
178020
+ if (last?.label === label && last.message === compact)
178663
178021
  return;
178664
178022
  this.state.timeline.push({
178665
178023
  time: timeOfDay(new Date),
178666
178024
  label,
178667
- message: compact2
178025
+ message: compact
178668
178026
  });
178669
178027
  if (this.state.timeline.length > 80)
178670
178028
  this.state.timeline.splice(0, this.state.timeline.length - 80);
@@ -178804,7 +178162,7 @@ function fitToScreen(lines, rows, width) {
178804
178162
  function trimVisible(value, width) {
178805
178163
  if (visibleLength(value) <= width)
178806
178164
  return value;
178807
- const stripped = stripAnsi(value);
178165
+ const stripped = stripAnsi2(value);
178808
178166
  return stripped.length > width ? `${stripped.slice(0, Math.max(0, width - 3))}...` : stripped;
178809
178167
  }
178810
178168
  function rule(width) {
@@ -178833,165 +178191,26 @@ function compactWhitespace(value) {
178833
178191
  return value.replace(/\s+/g, " ").trim();
178834
178192
  }
178835
178193
  function visibleLength(value) {
178836
- return stripAnsi(value).length;
178194
+ return stripAnsi2(value).length;
178837
178195
  }
178838
- function stripAnsi(value) {
178196
+ function stripAnsi2(value) {
178839
178197
  return value.replace(/\u001b\[[0-9;?]*[A-Za-z]/g, "");
178840
178198
  }
178841
178199
 
178842
178200
  // src/harness-remote.ts
178843
- import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
178201
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "node:fs";
178844
178202
  import { join as join2 } from "node:path";
178845
178203
 
178846
- // src/markdown-terminal.ts
178847
- function shouldColorTerminalOutput(opts = {}) {
178848
- const env = opts.env ?? process.env;
178849
- const isTTY = opts.isTTY ?? process.stdout.isTTY === true;
178850
- if (!isTTY)
178851
- return false;
178852
- if (env.NO_COLOR !== undefined)
178853
- return false;
178854
- if (env.TERM === "dumb")
178855
- return false;
178856
- return true;
178857
- }
178858
- function terminalStyles(color) {
178859
- const paint = (open, close) => (text) => color ? `\x1B[${open}m${text}\x1B[${close}m` : text;
178860
- return {
178861
- bold: paint("1", "22"),
178862
- italic: paint("3", "23"),
178863
- dim: paint("2", "22"),
178864
- code: paint("36", "39"),
178865
- heading: paint("1;4", "22;24")
178866
- };
178867
- }
178868
- var FENCE_RE = /^\s*(`{3,}|~{3,})/;
178869
- var FENCE_CLOSE_RE = /^\s*(`{3,}|~{3,})\s*$/;
178870
- var TABLE_ROW_RE = /^\s*\|.*\S/;
178871
- var ANSI_RE = /\u001b(?:\[[0-9;?]*[ -/]*[@-~]|\][^\u0007\u001b]*(?:\u0007|\u001b\\)|[@-Z\\-_])/g;
178872
- function stripAnsi2(text) {
178873
- return text.replace(ANSI_RE, "");
178874
- }
178875
- function parseFenceOpen(line) {
178876
- const match = FENCE_RE.exec(line);
178877
- if (!match)
178878
- return null;
178879
- return { char: match[1][0], len: match[1].length };
178880
- }
178881
- function isFenceClose(line, fence) {
178882
- const match = FENCE_CLOSE_RE.exec(line);
178883
- return match !== null && match[1][0] === fence.char && match[1].length >= fence.len;
178884
- }
178885
- var HEADER_RE = /^(#{1,6})\s+(.*?)\s*#*\s*$/;
178886
- var BULLET_RE = /^(\s*)([-*+])\s+(.*)$/;
178887
- var ORDERED_RE = /^(\s*)(\d+)[.)]\s+(.*)$/;
178888
- function renderMarkdownForTerminal(markdown, opts) {
178889
- const style = terminalStyles(opts.color);
178890
- const out = [];
178891
- const listStack = [];
178892
- let fence = null;
178893
- for (const raw of markdown.replace(/\r\n/g, `
178894
- `).split(`
178895
- `)) {
178896
- if (fence) {
178897
- out.push(stripAnsi2(raw));
178898
- if (isFenceClose(raw, fence))
178899
- fence = null;
178900
- continue;
178901
- }
178902
- const opened = parseFenceOpen(raw);
178903
- if (opened) {
178904
- fence = opened;
178905
- listStack.length = 0;
178906
- out.push(stripAnsi2(raw));
178907
- continue;
178908
- }
178909
- if (TABLE_ROW_RE.test(raw)) {
178910
- out.push(stripAnsi2(raw));
178911
- continue;
178912
- }
178913
- const line = raw.replace(/\s+$/, "");
178914
- if (line === "") {
178915
- out.push("");
178916
- continue;
178917
- }
178918
- const header = HEADER_RE.exec(line);
178919
- if (header) {
178920
- listStack.length = 0;
178921
- const text = renderInline(header[2], terminalStyles(false));
178922
- if (out.length > 0 && out[out.length - 1] !== "")
178923
- out.push("");
178924
- out.push(header[1].length <= 2 ? style.heading(text) : style.bold(text));
178925
- continue;
178926
- }
178927
- const bullet = BULLET_RE.exec(line);
178928
- const ordered = bullet ? null : ORDERED_RE.exec(line);
178929
- if (bullet || ordered) {
178930
- const match = bullet ?? ordered;
178931
- const level = resolveListLevel(match[1].length, listStack);
178932
- const indent = " ".repeat(level);
178933
- const text = renderInline(match[3], style);
178934
- if (bullet) {
178935
- out.push(`${indent}${level === 0 ? "•" : "-"} ${text}`);
178936
- } else {
178937
- out.push(`${indent}${match[2]}. ${text}`);
178938
- }
178939
- continue;
178940
- }
178941
- if (!/^\s{2,}/.test(line))
178942
- listStack.length = 0;
178943
- out.push(renderInline(line, style));
178944
- }
178945
- return collapseBlankRuns(out).join(`
178946
- `);
178947
- }
178948
- function resolveListLevel(indent, stack) {
178949
- while (stack.length > 0 && indent < stack[stack.length - 1] - 1)
178950
- stack.pop();
178951
- if (stack.length === 0 || indent > stack[stack.length - 1] + 1)
178952
- stack.push(indent);
178953
- return stack.length - 1;
178954
- }
178955
- function renderInline(text, style) {
178956
- const codeSpans = [];
178957
- let result = stripAnsi2(text).replace(/`([^`]+)`/g, (_, code) => {
178958
- codeSpans.push(code);
178959
- return `\x00${codeSpans.length - 1}\x00`;
178960
- });
178961
- result = result.replace(/\*\*([^\s*](?:[^*]*[^\s*])?)\*\*/g, (_, inner) => style.bold(inner));
178962
- result = result.replace(/__([^\s_](?:[^_]*[^\s_])?)__/g, (_, inner) => style.bold(inner));
178963
- result = result.replace(/(?<![\w*])\*([^\s*](?:[^*\n]*[^\s*])?)\*(?![\w*])/g, (_, inner) => style.italic(inner));
178964
- result = result.replace(/(?<![\w_])_([^\s_](?:[^_\n]*[^\s_])?)_(?![\w_])/g, (_, inner) => style.italic(inner));
178965
- return result.replace(/\u0000(\d+)\u0000/g, (_, index) => style.code(codeSpans[Number(index)]));
178966
- }
178967
- function collapseBlankRuns(lines) {
178968
- const collapsed = [];
178969
- let blanks = 0;
178970
- for (const line of lines) {
178971
- if (line === "") {
178972
- blanks += 1;
178973
- continue;
178974
- }
178975
- if (blanks > 0)
178976
- collapsed.push("", ...blanks === 2 ? [""] : []);
178977
- blanks = 0;
178978
- collapsed.push(line);
178979
- }
178980
- if (blanks > 0)
178981
- collapsed.push("", ...blanks === 2 ? [""] : []);
178982
- return collapsed;
178983
- }
178984
-
178985
178204
  // src/harness-report.ts
178986
178205
  import { createHash } from "node:crypto";
178987
178206
  import {
178988
178207
  existsSync,
178989
178208
  lstatSync,
178990
178209
  mkdirSync,
178991
- readFileSync as readFileSync2,
178210
+ readFileSync,
178992
178211
  writeFileSync
178993
178212
  } from "node:fs";
178994
- import { basename, dirname, join, relative, resolve as resolve2 } from "node:path";
178213
+ import { basename, dirname, join, relative, resolve } from "node:path";
178995
178214
  import { confirm } from "@inquirer/prompts";
178996
178215
  var HARNESS_REPORT_SCHEMA_VERSION = "harness_report.v0.1";
178997
178216
  var HARNESS_REPORT_VALIDATION_SCHEMA_VERSION = "harness_report_validation.v0.1";
@@ -179509,12 +178728,12 @@ function loadHarnessReportForSync(rootDir, reportPath, options) {
179509
178728
  `));
179510
178729
  }
179511
178730
  const approvalPath = join(rootDir, HARNESS_REPORT_APPROVAL_PATH);
179512
- const approval = existsSync(approvalPath) ? JSON.parse(readFileSync2(approvalPath, "utf8")) : null;
178731
+ const approval = existsSync(approvalPath) ? JSON.parse(readFileSync(approvalPath, "utf8")) : null;
179513
178732
  const approved = approval?.schemaVersion === HARNESS_REPORT_APPROVAL_SCHEMA_VERSION && approval.reportId === report.reportId && approval.reportHash === hashHarnessReport(report) && approval.approved === true;
179514
178733
  return { report, validation, approval, approved };
179515
178734
  }
179516
178735
  function readHarnessReport(reportPath) {
179517
- return normalizeHarnessReport(JSON.parse(readFileSync2(reportPath, "utf8")));
178736
+ return normalizeHarnessReport(JSON.parse(readFileSync(reportPath, "utf8")));
179518
178737
  }
179519
178738
  function normalizeHarnessReport(value) {
179520
178739
  const report = cloneJson(value);
@@ -180105,7 +179324,7 @@ function limitReportEvidence(claims, citations) {
180105
179324
  };
180106
179325
  }
180107
179326
  function resolveHarnessReportPath(rootDir, value) {
180108
- return resolve2(rootDir, value && value !== "true" ? value : HARNESS_REPORT_PATH);
179327
+ return resolve(rootDir, value && value !== "true" ? value : HARNESS_REPORT_PATH);
180109
179328
  }
180110
179329
  function writeHarnessReportArtifacts(options) {
180111
179330
  const written = [];
@@ -180242,14 +179461,14 @@ function upsertCitation(citations, citationIndex, evidence, rootDir) {
180242
179461
  function citationExcerpt(rootDir, path, line) {
180243
179462
  if (isUnsafeCitationPath(path))
180244
179463
  return {};
180245
- const absPath = resolve2(rootDir, path);
179464
+ const absPath = resolve(rootDir, path);
180246
179465
  if (!isInside(rootDir, absPath) || !existsSync(absPath))
180247
179466
  return {};
180248
179467
  try {
180249
179468
  const stat = lstatSync(absPath);
180250
179469
  if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 128 * 1024)
180251
179470
  return {};
180252
- const lines = readFileSync2(absPath, "utf8").split(/\r?\n/);
179471
+ const lines = readFileSync(absPath, "utf8").split(/\r?\n/);
180253
179472
  const selected = line ? lines[line - 1] : lines.find((candidate) => candidate.trim().length > 0);
180254
179473
  if (!selected)
180255
179474
  return {};
@@ -180387,7 +179606,7 @@ function validateCitation(citation, rootDir, errors, warnings, options) {
180387
179606
  errors.push(`Citation ${citation.id} points to an unsafe path.`);
180388
179607
  return;
180389
179608
  }
180390
- const absPath = resolve2(rootDir, citation.path);
179609
+ const absPath = resolve(rootDir, citation.path);
180391
179610
  if (!isInside(rootDir, absPath)) {
180392
179611
  errors.push(`Citation ${citation.id} points outside the harness root.`);
180393
179612
  return;
@@ -180406,7 +179625,7 @@ function validateCitation(citation, rootDir, errors, warnings, options) {
180406
179625
  }
180407
179626
  if (!stat.isFile())
180408
179627
  errors.push(`Citation ${citation.id} does not point to a file.`);
180409
- const lines = readFileSync2(absPath, "utf8").split(/\r?\n/);
179628
+ const lines = readFileSync(absPath, "utf8").split(/\r?\n/);
180410
179629
  if (citation.line !== undefined) {
180411
179630
  const lineCount = lines.length;
180412
179631
  if (citation.line < 1 || citation.line > lineCount) {
@@ -180457,7 +179676,7 @@ function isSecretishPath2(path) {
180457
179676
  return name === ".env" || name.startsWith(".env.") || name.includes("secret") || name.includes("private-key") || name.endsWith(".pem");
180458
179677
  }
180459
179678
  function isInside(rootDir, absPath) {
180460
- const rel = relative(resolve2(rootDir), resolve2(absPath));
179679
+ const rel = relative(resolve(rootDir), resolve(absPath));
180461
179680
  return rel === "" || !rel.startsWith("..") && !rel.startsWith("/");
180462
179681
  }
180463
179682
  function writeJson(path, value) {
@@ -180517,7 +179736,7 @@ function readRemoteRunState(rootDir) {
180517
179736
  if (!existsSync2(path))
180518
179737
  return;
180519
179738
  try {
180520
- const parsed = JSON.parse(readFileSync3(path, "utf8"));
179739
+ const parsed = JSON.parse(readFileSync2(path, "utf8"));
180521
179740
  if (!parsed || typeof parsed.run_id !== "string" || parsed.run_id.length === 0)
180522
179741
  return;
180523
179742
  return {
@@ -180813,7 +180032,7 @@ function serverFailedReportValidation(final) {
180813
180032
  return typeof validation === "object" && validation !== null && !Array.isArray(validation) && validation.status === "fail";
180814
180033
  }
180815
180034
  function sanitizeProgressText(text) {
180816
- return stripAnsi2(text).replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/\s+/g, " ").trim();
180035
+ return stripAnsi(text).replace(/[\u0000-\u001f\u007f]+/g, " ").replace(/\s+/g, " ").trim();
180817
180036
  }
180818
180037
  function normalizeRemoteProgress(value) {
180819
180038
  if (typeof value !== "object" || value === null || Array.isArray(value))
@@ -180878,22 +180097,22 @@ async function remoteAnalyzeFetch(url, apiKey, init, timeoutMs) {
180878
180097
 
180879
180098
  // src/harness-register/register.ts
180880
180099
  import * as fs from "node:fs";
180881
- import { mkdtempSync, readFileSync as readFileSync8, rmSync as rmSync3 } from "node:fs";
180100
+ import { mkdtempSync, readFileSync as readFileSync7, rmSync as rmSync3 } from "node:fs";
180882
180101
  import { Readable as Readable2 } from "node:stream";
180883
180102
  import { tmpdir } from "node:os";
180884
- import { basename as basename4, join as join8, resolve as resolve5 } from "node:path";
180103
+ import { basename as basename4, join as join8, resolve as resolve4 } from "node:path";
180885
180104
 
180886
180105
  // src/harness-register/collect-adapter.ts
180887
180106
  import { createHash as createHash4 } from "node:crypto";
180888
180107
  import { execFileSync } from "node:child_process";
180889
- import { copyFileSync, createReadStream, existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync7, realpathSync as realpathSync4, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
180108
+ import { copyFileSync, createReadStream, existsSync as existsSync6, mkdirSync as mkdirSync4, readFileSync as readFileSync6, realpathSync as realpathSync4, rmSync as rmSync2, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
180890
180109
  import { dirname as dirname5, join as join7 } from "node:path";
180891
180110
 
180892
180111
  // ../../packages/harness-bundle/src/contract.ts
180893
180112
  var HARNESS_BUNDLE_SCHEMA = "moda_harness_bundle.v1";
180894
180113
  var DEPENDENCY_MAP_SCHEMA = "moda_dependency_map.v1";
180895
180114
  // ../../packages/harness-bundle/src/detect/files.ts
180896
- import { existsSync as existsSync3, lstatSync as lstatSync2, readdirSync, readFileSync as readFileSync4, realpathSync } from "node:fs";
180115
+ import { existsSync as existsSync3, lstatSync as lstatSync2, readdirSync, readFileSync as readFileSync3, realpathSync } from "node:fs";
180897
180116
  import { join as join3, sep } from "node:path";
180898
180117
 
180899
180118
  // ../../packages/harness-bundle/src/detect/text.ts
@@ -181244,7 +180463,7 @@ function readManifest(dir) {
181244
180463
  if (!existsSync3(path))
181245
180464
  return;
181246
180465
  try {
181247
- const parsed = JSON.parse(readFileSync4(path, "utf8"));
180466
+ const parsed = JSON.parse(readFileSync3(path, "utf8"));
181248
180467
  if (isRecord2(parsed) && parsed.schema === HARNESS_BUNDLE_SCHEMA && Array.isArray(parsed.files)) {
181249
180468
  return parsed;
181250
180469
  }
@@ -181263,7 +180482,7 @@ function readText(abs, maxBytes) {
181263
180482
  const st = lstatSync2(abs);
181264
180483
  if (!st.isFile() || st.size > maxBytes)
181265
180484
  return;
181266
- const buf = readFileSync4(abs);
180485
+ const buf = readFileSync3(abs);
181267
180486
  if (buf.subarray(0, 8000).includes(0))
181268
180487
  return;
181269
180488
  return buf.toString("utf8");
@@ -186085,8 +185304,8 @@ function detectDependencies(input) {
186085
185304
  }
186086
185305
  // ../../packages/harness-bundle/src/collect/collect.ts
186087
185306
  import { createHash as createHash2 } from "node:crypto";
186088
- import { closeSync, existsSync as existsSync4, lstatSync as lstatSync3, openSync, readdirSync as readdirSync2, readFileSync as readFileSync5, readlinkSync, readSync, realpathSync as realpathSync2 } from "node:fs";
186089
- import { basename as basename3, dirname as dirname3, isAbsolute, join as join5, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
185307
+ import { closeSync, existsSync as existsSync4, lstatSync as lstatSync3, openSync, readdirSync as readdirSync2, readFileSync as readFileSync4, readlinkSync, readSync, realpathSync as realpathSync2 } from "node:fs";
185308
+ import { basename as basename3, dirname as dirname3, isAbsolute, join as join5, relative as relative2, resolve as resolve2, sep as sep2 } from "node:path";
186090
185309
 
186091
185310
  // ../../packages/harness-bundle/src/collect/rules.ts
186092
185311
  var VCS_DIRS = new Set([".git", ".hg", ".svn", ".bzr", "_darcs", ".jj", ".sl"]);
@@ -188519,7 +187738,7 @@ class Collector {
188519
187738
  listedArtifacts = new Map;
188520
187739
  constructor(repoRoot, opts) {
188521
187740
  this.opts = opts;
188522
- this.start = realpathSync2(resolve3(repoRoot));
187741
+ this.start = realpathSync2(resolve2(repoRoot));
188523
187742
  this.root = this.start;
188524
187743
  this.budget = { ...DEFAULT_BUDGET, ...stripUndefined(opts.budget ?? {}) };
188525
187744
  }
@@ -188531,13 +187750,13 @@ class Collector {
188531
187750
  this.gitMode = true;
188532
187751
  }
188533
187752
  }
188534
- const harnessAbs = realpathSync2(resolve3(this.start, this.opts.harnessRoot ?? "."));
187753
+ const harnessAbs = realpathSync2(resolve2(this.start, this.opts.harnessRoot ?? "."));
188535
187754
  const harnessRel = toPosix(relative2(this.root, harnessAbs));
188536
187755
  if (isOutside(harnessRel)) {
188537
187756
  throw new Error(`Harness root ${harnessAbs} is outside the bundle root ${this.root}`);
188538
187757
  }
188539
187758
  for (const skip of this.opts.skipPaths ?? []) {
188540
- const rel2 = toPosix(relative2(this.root, resolve3(skip)));
187759
+ const rel2 = toPosix(relative2(this.root, resolve2(skip)));
188541
187760
  if (rel2 !== "" && !isOutside(rel2))
188542
187761
  this.skipRel.add(rel2);
188543
187762
  }
@@ -188715,7 +187934,7 @@ class Collector {
188715
187934
  try {
188716
187935
  const manifestPath = join5(this.root, outDir, MANIFEST_FILE);
188717
187936
  if (lstatSync3(manifestPath).size <= MAX_PREVIOUS_MANIFEST_BYTES) {
188718
- const previous = JSON.parse(readFileSync5(manifestPath, "utf8"));
187937
+ const previous = JSON.parse(readFileSync4(manifestPath, "utf8"));
188719
187938
  for (const a of previous.deployArtifacts ?? [])
188720
187939
  if (typeof a.path === "string")
188721
187940
  listed.add(a.path);
@@ -188878,7 +188097,7 @@ class Collector {
188878
188097
  }
188879
188098
  let buf;
188880
188099
  try {
188881
- buf = readFileSync5(abs);
188100
+ buf = readFileSync4(abs);
188882
188101
  } catch {
188883
188102
  this.excludeFile(path, "unreadable", "read_failed", st.size);
188884
188103
  return;
@@ -188917,7 +188136,7 @@ class Collector {
188917
188136
  this.excludeFile(path, "unreadable", "readlink_failed");
188918
188137
  return;
188919
188138
  }
188920
- const lexical = resolve3(dirname3(abs), target);
188139
+ const lexical = resolve2(dirname3(abs), target);
188921
188140
  let real = lexical;
188922
188141
  try {
188923
188142
  real = realpathSync2(abs);
@@ -189049,7 +188268,7 @@ class Collector {
189049
188268
  return skip(`${st.size} bytes exceeds ${limit}`);
189050
188269
  let buf;
189051
188270
  try {
189052
- buf = readFileSync5(abs);
188271
+ buf = readFileSync4(abs);
189053
188272
  } catch {
189054
188273
  return skip("unreadable");
189055
188274
  }
@@ -189254,8 +188473,8 @@ function stripUndefined(value) {
189254
188473
  }
189255
188474
  // ../../packages/harness-bundle/src/collect/write.ts
189256
188475
  import { createHash as createHash3, randomUUID } from "node:crypto";
189257
- import { createWriteStream, existsSync as existsSync5, lstatSync as lstatSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync3, readFileSync as readFileSync6, readlinkSync as readlinkSync2, realpathSync as realpathSync3, renameSync, rmSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
189258
- import { dirname as dirname4, isAbsolute as isAbsolute2, join as join6, relative as relative3, resolve as resolve4, sep as sep3 } from "node:path";
188476
+ import { createWriteStream, existsSync as existsSync5, lstatSync as lstatSync4, mkdirSync as mkdirSync3, readdirSync as readdirSync3, readFileSync as readFileSync5, readlinkSync as readlinkSync2, realpathSync as realpathSync3, renameSync, rmSync, statSync, writeFileSync as writeFileSync3 } from "node:fs";
188477
+ import { dirname as dirname4, isAbsolute as isAbsolute2, join as join6, relative as relative3, resolve as resolve3, sep as sep3 } from "node:path";
189259
188478
  import { Readable, Transform } from "node:stream";
189260
188479
  import { pipeline } from "node:stream/promises";
189261
188480
  import { createGzip } from "node:zlib";
@@ -189431,7 +188650,7 @@ function* tarChunks(files) {
189431
188650
  throw new Error(`${file.path} changed after collection; re-run the collector`);
189432
188651
  entry = { path: file.path, type: "symlink", mode: 511, linkTarget: file.symlinkTarget };
189433
188652
  } else {
189434
- const body = readFileSync6(file.absolutePath);
188653
+ const body = readFileSync5(file.absolutePath);
189435
188654
  const executableNow = (statSync(file.absolutePath).mode & 73) !== 0;
189436
188655
  if (sha256(body) !== file.sha256 || executableNow !== file.executable) {
189437
188656
  throw new Error(`${file.path} changed after collection; re-run the collector`);
@@ -189502,7 +188721,7 @@ function redactEnvExamples(result, dir) {
189502
188721
  if (!file.categories.includes("env_example") || file.symlinkTarget !== undefined)
189503
188722
  continue;
189504
188723
  redacted = true;
189505
- const body = Buffer.from(envNamesOnly(readFileSync7(file.absolutePath, "utf8")));
188724
+ const body = Buffer.from(envNamesOnly(readFileSync6(file.absolutePath, "utf8")));
189506
188725
  const target = join7(dir, file.path);
189507
188726
  mkdirSync4(dirname5(target), { recursive: true });
189508
188727
  writeFileSync4(target, body, { mode: file.executable ? 493 : 420 });
@@ -189518,7 +188737,7 @@ function redactEnvExamples(result, dir) {
189518
188737
  for (const file of result.files) {
189519
188738
  if (file.encoding !== "text" || file.symlinkTarget !== undefined || file.bytes > MAX_ENV_RESCAN_BYTES)
189520
188739
  continue;
189521
- env.scanFile(file.path, readFileSync7(file.absolutePath, "utf8"), file.categories);
188740
+ env.scanFile(file.path, readFileSync6(file.absolutePath, "utf8"), file.categories);
189522
188741
  }
189523
188742
  result.manifest.env = env.finalize(new Set(result.files.map((file) => file.path)));
189524
188743
  }
@@ -189563,8 +188782,8 @@ function insideCheckout(dir) {
189563
188782
  }
189564
188783
  async function digestFile(path) {
189565
188784
  const hash = createHash4("sha256");
189566
- await new Promise((resolve5, reject) => {
189567
- createReadStream(path).on("data", (chunk) => hash.update(chunk)).on("error", reject).on("end", () => resolve5());
188785
+ await new Promise((resolve4, reject) => {
188786
+ createReadStream(path).on("data", (chunk) => hash.update(chunk)).on("error", reject).on("end", () => resolve4());
189568
188787
  });
189569
188788
  return { path, sha256: hash.digest("hex"), bytes: statSync2(path).size };
189570
188789
  }
@@ -189588,8 +188807,8 @@ var EXCLUSION_REASONS = {
189588
188807
  };
189589
188808
  async function runHarnessRegister(context, argv = process.argv) {
189590
188809
  const options = parseRegisterOptions(context, argv);
189591
- const profileOptions2 = { profile: context.profile, env: context.env };
189592
- if (!context.dryRun && !resolveApiKey(profileOptions2)) {
188810
+ const profileOptions = { profile: context.profile, env: context.env };
188811
+ if (!context.dryRun && !resolveApiKey(profileOptions)) {
189593
188812
  throw new CliInputError("No Moda API key found for harness register.", "Run `moda harness register --dry-run` to review the bundle without one, or set MODA_API_KEY / run `moda auth login --api-key=<key>`.");
189594
188813
  }
189595
188814
  const outDir = mkdtempSync(join8(tmpdir(), "moda-harness-register-"));
@@ -189603,7 +188822,7 @@ async function runHarnessRegister(context, argv = process.argv) {
189603
188822
  }
189604
188823
  }
189605
188824
  async function registerCollected(context, options, collected) {
189606
- const profileOptions2 = { profile: context.profile, env: context.env };
188825
+ const profileOptions = { profile: context.profile, env: context.env };
189607
188826
  const report = buildRegisterReport(collected);
189608
188827
  if (context.dryRun) {
189609
188828
  emit(context, { ...report, dryRun: true }, renderRegisterReport(report, null));
@@ -189625,7 +188844,7 @@ async function registerCollected(context, options, collected) {
189625
188844
  ...gitFields(collected.manifest),
189626
188845
  ...options.imageRef ? { imageRef: options.imageRef } : {}
189627
188846
  })
189628
- }, profileOptions2));
188847
+ }, profileOptions));
189629
188848
  const files = {
189630
188849
  bundle: collected.bundle.path,
189631
188850
  manifest: collected.manifestFile.path,
@@ -189635,29 +188854,29 @@ async function registerCollected(context, options, collected) {
189635
188854
  const path = files[target.name];
189636
188855
  if (!path)
189637
188856
  throw new Error(`Moda asked for ${target.name}, which was not collected.`);
189638
- await putObject(target, path, resolveModaBaseUrl(profileOptions2));
188857
+ await putObject(target, path, resolveModaBaseUrl(profileOptions));
189639
188858
  }
189640
- const completed = await callControlAPI(`/harness-registrations/${encodeURIComponent(created.registration.id)}/complete`, { method: "POST" }, profileOptions2, { timeoutMs: 300000 });
189641
- await withFullChecklist(completed, profileOptions2);
189642
- const dashboardUrl = `${resolveModaBaseUrl(profileOptions2)}${completed.dashboardPath}`;
188859
+ const completed = await callControlAPI(`/harness-registrations/${encodeURIComponent(created.registration.id)}/complete`, { method: "POST" }, profileOptions, { timeoutMs: 300000 });
188860
+ await withFullChecklist(completed, profileOptions);
188861
+ const dashboardUrl = `${resolveModaBaseUrl(profileOptions)}${completed.dashboardPath}`;
189643
188862
  emit(context, { ...report, dryRun: false, registration: { ...completed, dashboardUrl } }, renderRegisterReport(report, { ...completed, dashboardUrl }), completed.status === "failed" ? "error" : undefined);
189644
188863
  return { exitCode: completed.status === "failed" ? 1 : 0 };
189645
188864
  }
189646
188865
  async function runHarnessRegistration(context) {
189647
188866
  const action = context.positionals[1] ?? "list";
189648
- const profileOptions2 = { profile: context.profile, env: context.env };
189649
- if (!resolveApiKey(profileOptions2)) {
188867
+ const profileOptions = { profile: context.profile, env: context.env };
188868
+ if (!resolveApiKey(profileOptions)) {
189650
188869
  throw new CliInputError(`No Moda API key found for harness registration ${action}.`, "Set MODA_API_KEY, run `moda auth login --api-key=<key>`, or select a profile with an API key.");
189651
188870
  }
189652
188871
  if (context.flags["tenant-id"])
189653
188872
  requireTenant(context);
189654
- const baseUrl = resolveModaBaseUrl(profileOptions2);
188873
+ const baseUrl = resolveModaBaseUrl(profileOptions);
189655
188874
  if (action === "status") {
189656
188875
  const id = context.positionals[2];
189657
188876
  if (!id)
189658
188877
  throw new CliInputError("Missing registration id.", "Usage: moda harness registration status <id> (ids from `moda harness registration list`)");
189659
- const registration = await callControlAPI(`/harness-registrations/${encodeURIComponent(id)}`, {}, profileOptions2);
189660
- await withFullChecklist(registration, profileOptions2);
188878
+ const registration = await callControlAPI(`/harness-registrations/${encodeURIComponent(id)}`, {}, profileOptions);
188879
+ await withFullChecklist(registration, profileOptions);
189661
188880
  const dashboardUrl = `${baseUrl}${registration.dashboardPath}`;
189662
188881
  emit(context, { ...registration, dashboardUrl }, renderRegistrationStatus({ ...registration, dashboardUrl }));
189663
188882
  return { exitCode: 0 };
@@ -189674,26 +188893,26 @@ async function runHarnessRegistration(context) {
189674
188893
  if (context.flags["include-retired"] === "true")
189675
188894
  query.set("includeRetired", "true");
189676
188895
  const suffix = query.toString() ? `?${query}` : "";
189677
- const response = await whenEnabled(() => callControlAPI(`/harness-registrations${suffix}`, {}, profileOptions2));
188896
+ const response = await whenEnabled(() => callControlAPI(`/harness-registrations${suffix}`, {}, profileOptions));
189678
188897
  emit(context, response, renderRegistrationList(response.registrations, baseUrl));
189679
188898
  return { exitCode: 0 };
189680
188899
  }
189681
188900
  throw new CliInputError(`Unknown harness registration command '${action}'.`, "Usage: moda harness registration list|status <id>");
189682
188901
  }
189683
- async function withFullChecklist(registration, profileOptions2) {
188902
+ async function withFullChecklist(registration, profileOptions) {
189684
188903
  try {
189685
- await loadFullChecklist(registration, profileOptions2);
188904
+ await loadFullChecklist(registration, profileOptions);
189686
188905
  } catch {
189687
188906
  registration.checklistIncomplete = true;
189688
188907
  }
189689
188908
  }
189690
- async function loadFullChecklist(registration, profileOptions2) {
188909
+ async function loadFullChecklist(registration, profileOptions) {
189691
188910
  const total = registration.checklistCounts?.total ?? 0;
189692
188911
  if (!registration.checklist || registration.checklist.items.length >= total)
189693
188912
  return;
189694
188913
  const items = [];
189695
188914
  for (let page = 0;items.length < total && page < 100; page++) {
189696
- const response = await callControlAPI(`/harness-registrations/${encodeURIComponent(registration.id)}/checklist?offset=${items.length}&limit=500`, {}, profileOptions2);
188915
+ const response = await callControlAPI(`/harness-registrations/${encodeURIComponent(registration.id)}/checklist?offset=${items.length}&limit=500`, {}, profileOptions);
189697
188916
  if (response.items.length === 0)
189698
188917
  break;
189699
188918
  items.push(...response.items);
@@ -189753,7 +188972,7 @@ function parseRegisterOptions(context, argv) {
189753
188972
  if (!ENV_NAME.test(name))
189754
188973
  throw new CliInputError(`'${name}' is not an env var name.`, "Pass the variable name, never its value, e.g. --model-base-url-env=OPENAI_BASE_URL.");
189755
188974
  }
189756
- const harnessRoot = resolve5(context.cwd, flags.root ?? ".");
188975
+ const harnessRoot = resolve4(context.cwd, flags.root ?? ".");
189757
188976
  const harnessName = positionals[1] ?? defaultHarnessName(harnessRoot);
189758
188977
  if (!HARNESS_NAME.test(harnessName)) {
189759
188978
  throw new CliInputError(`Harness name '${harnessName}' is not valid.`, 'Use 1-128 letters, digits, ".", "_" or "-", e.g. `moda harness register support-agent`.');
@@ -189764,7 +188983,7 @@ function parseRegisterOptions(context, argv) {
189764
188983
  }
189765
188984
  function defaultHarnessName(root) {
189766
188985
  try {
189767
- const name = JSON.parse(readFileSync8(join8(root, "package.json"), "utf8")).name;
188986
+ const name = JSON.parse(readFileSync7(join8(root, "package.json"), "utf8")).name;
189768
188987
  if (typeof name === "string" && name)
189769
188988
  return sanitizeName(name.replace(/^@[^/]+\//, ""));
189770
188989
  } catch {}
@@ -190020,8 +189239,8 @@ function formatBytes(bytes) {
190020
189239
  }
190021
189240
 
190022
189241
  // src/harness-artifact-bodies.ts
190023
- import { existsSync as existsSync7, lstatSync as lstatSync5, readFileSync as readFileSync9, realpathSync as realpathSync5 } from "node:fs";
190024
- import { basename as basename5, dirname as dirname6, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve6 } from "node:path";
189242
+ import { existsSync as existsSync7, lstatSync as lstatSync5, readFileSync as readFileSync8, realpathSync as realpathSync5 } from "node:fs";
189243
+ import { basename as basename5, dirname as dirname6, isAbsolute as isAbsolute3, relative as relative4, resolve as resolve5 } from "node:path";
190025
189244
  var MAX_SCANNED_FILE_BYTES2 = 512 * 1024;
190026
189245
  var SNAPSHOT_BUDGET_SKIP_REASONS = new Set([
190027
189246
  "file too large for harness scan",
@@ -190084,13 +189303,13 @@ function readBoundedRepoText(absPath, rootDir) {
190084
189303
  return;
190085
189304
  }
190086
189305
  try {
190087
- return readFileSync9(absPath, "utf8");
189306
+ return readFileSync8(absPath, "utf8");
190088
189307
  } catch {
190089
189308
  return;
190090
189309
  }
190091
189310
  }
190092
189311
  function readRepoRelativeText(rootDir, relPath) {
190093
- return readBoundedRepoText(resolve6(rootDir, relPath), rootDir);
189312
+ return readBoundedRepoText(resolve5(rootDir, relPath), rootDir);
190094
189313
  }
190095
189314
  function isDedicatedToolFilePath(path) {
190096
189315
  return /(^|\/)tools?\//i.test(path) && /\.(ts|tsx|js|mjs|py)$/i.test(path);
@@ -190117,8 +189336,8 @@ function extractToolBodyFromText(text, toolName) {
190117
189336
  const normalizedName = toolName.replace(/\s+/g, "").toLowerCase();
190118
189337
  for (let index = 0;index < lines.length; index += 1) {
190119
189338
  const line = lines[index];
190120
- const compact2 = line.replace(/\s+/g, "").toLowerCase();
190121
- const mentionsTool = compact2.includes(normalizedName) || compact2.includes(`def${normalizedName}`);
189339
+ const compact = line.replace(/\s+/g, "").toLowerCase();
189340
+ const mentionsTool = compact.includes(normalizedName) || compact.includes(`def${normalizedName}`);
190122
189341
  if (!mentionsTool)
190123
189342
  continue;
190124
189343
  if (line.includes("function_tool") || line.includes("tool(") || line.includes("createTool") || line.includes("functionTool") || line.includes("dynamicTool") || line.includes("new Tool") || line.includes("def ")) {
@@ -190131,14 +189350,14 @@ function annotatedSourceCandidates(sourcePath, annotation) {
190131
189350
  const explicitSourcePath = normalizePath2(sourcePath) !== normalizePath2(annotation.evidence.path);
190132
189351
  if (!explicitSourcePath) {
190133
189352
  return [
190134
- resolve6(annotation.rootDir, sourcePath),
190135
- resolve6(dirname6(annotation.sourceAbsPath), sourcePath),
189353
+ resolve5(annotation.rootDir, sourcePath),
189354
+ resolve5(dirname6(annotation.sourceAbsPath), sourcePath),
190136
189355
  annotation.sourceAbsPath
190137
189356
  ];
190138
189357
  }
190139
- const rootAbs = resolve6(annotation.rootDir);
190140
- const candidates = walkAncestorDirs(dirname6(annotation.sourceAbsPath), rootAbs).map((dir) => resolve6(dir, sourcePath));
190141
- candidates.push(resolve6(annotation.rootDir, sourcePath));
189358
+ const rootAbs = resolve5(annotation.rootDir);
189359
+ const candidates = walkAncestorDirs(dirname6(annotation.sourceAbsPath), rootAbs).map((dir) => resolve5(dir, sourcePath));
189360
+ candidates.push(resolve5(annotation.rootDir, sourcePath));
190142
189361
  return candidates;
190143
189362
  }
190144
189363
  function readAnnotatedSourceText(sourcePath, annotation) {
@@ -190219,9 +189438,9 @@ function readSourcePathRelativeToEvidence(artifact, rootDir) {
190219
189438
  const evidencePath = firstEvidencePath(artifact);
190220
189439
  if (!evidencePath)
190221
189440
  return;
190222
- const rootAbs = resolve6(rootDir);
190223
- for (const dir of walkAncestorDirs(dirname6(resolve6(rootDir, evidencePath)), rootAbs)) {
190224
- const text = readBoundedRepoText(resolve6(dir, artifact.sourcePath), rootDir);
189441
+ const rootAbs = resolve5(rootDir);
189442
+ for (const dir of walkAncestorDirs(dirname6(resolve5(rootDir, evidencePath)), rootAbs)) {
189443
+ const text = readBoundedRepoText(resolve5(dir, artifact.sourcePath), rootDir);
190225
189444
  if (text !== undefined)
190226
189445
  return text;
190227
189446
  }
@@ -190251,7 +189470,7 @@ function enrichScanCaptureMetadata(graph) {
190251
189470
 
190252
189471
  // src/harness-candidates.ts
190253
189472
  import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
190254
- import { basename as basename6, dirname as dirname7, extname, resolve as resolve7 } from "node:path";
189473
+ import { basename as basename6, dirname as dirname7, extname, resolve as resolve6 } from "node:path";
190255
189474
  var MAX_CANDIDATES_PER_FILE_PER_SIGNAL = 20;
190256
189475
  var MIN_PROMPT_LITERAL_CHARS = 160;
190257
189476
  var CONFIDENCE_WEIGHT = {
@@ -190777,7 +189996,7 @@ function detectHarnessCandidatesInFiles(files) {
190777
189996
  function detectHarnessCandidates(rootDir) {
190778
189997
  const startedAt = Date.now();
190779
189998
  const skipped = [];
190780
- const root = resolve7(rootDir);
189999
+ const root = resolve6(rootDir);
190781
190000
  const inventory = inventoryFiles(root, skipped, {
190782
190001
  includeFile: (path) => PROMPT_DOC_EXTENSIONS.has(extname(path).toLowerCase()) || [".json", ".yaml", ".yml"].includes(extname(path).toLowerCase()) || extname(path).toLowerCase() === ".rs" && RUST_PROMPT_PATH_HINT.test(path)
190783
190002
  });
@@ -190803,7 +190022,7 @@ function detectHarnessCandidates(rootDir) {
190803
190022
  return redactDeep(report);
190804
190023
  }
190805
190024
  function writeHarnessCandidatesReport(report, outPath) {
190806
- const target = resolve7(outPath);
190025
+ const target = resolve6(outPath);
190807
190026
  mkdirSync5(dirname7(target), { recursive: true });
190808
190027
  writeFileSync5(target, `${JSON.stringify(report, null, 2)}
190809
190028
  `, "utf8");
@@ -190817,8 +190036,8 @@ import { extname as extname8 } from "node:path";
190817
190036
  // src/prompt-sources.ts
190818
190037
  var import_typescript2 = __toESM(require_typescript(), 1);
190819
190038
  import { createHash as createHash5 } from "node:crypto";
190820
- import { lstatSync as lstatSync7, readFileSync as readFileSync12, realpathSync as realpathSync8 } from "node:fs";
190821
- import { extname as extname3, isAbsolute as isAbsolute4, relative as relative5, resolve as resolve10 } from "node:path";
190039
+ import { lstatSync as lstatSync7, readFileSync as readFileSync11, realpathSync as realpathSync8 } from "node:fs";
190040
+ import { extname as extname3, isAbsolute as isAbsolute4, relative as relative5, resolve as resolve9 } from "node:path";
190822
190041
 
190823
190042
  // src/prompt-frameworks.ts
190824
190043
  var PYTHON_AGENT_MODULES = [
@@ -190839,15 +190058,15 @@ var TYPESCRIPT_AGENT_MODULES = [
190839
190058
 
190840
190059
  // src/prompt-source-code.ts
190841
190060
  var import_typescript = __toESM(require_typescript(), 1);
190842
- import { existsSync as existsSync8, lstatSync as lstatSync6, readFileSync as readFileSync10, realpathSync as realpathSync6 } from "node:fs";
190843
- import { dirname as dirname8, extname as extname2, join as join9, resolve as resolve8 } from "node:path";
190061
+ import { existsSync as existsSync8, lstatSync as lstatSync6, readFileSync as readFileSync9, realpathSync as realpathSync6 } from "node:fs";
190062
+ import { dirname as dirname8, extname as extname2, join as join9, resolve as resolve7 } from "node:path";
190844
190063
  var EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"];
190845
190064
  var MAX_BYTES = 2 * 1024 * 1024;
190846
190065
  var MAX_DEPTH = 32;
190847
190066
  var MAX_FILES = 256;
190848
190067
  var MAX_GRAPH_BYTES = 16 * 1024 * 1024;
190849
190068
  function extractCodeSource(rootDir, sourcePath, symbol, forceDependencyGraph = false) {
190850
- const state = { root: resolve8(rootDir), files: [], unresolved: [], visiting: new Set, importsVisited: new Set, parsed: new Map, assignments: new Map, bytesRead: 0 };
190069
+ const state = { root: resolve7(rootDir), files: [], unresolved: [], visiting: new Set, importsVisited: new Set, parsed: new Map, assignments: new Map, bytesRead: 0 };
190851
190070
  const file = safeFile(state.root, state.root, sourcePath);
190852
190071
  const parsed = parseFile(file, state);
190853
190072
  const target = symbol ? findSymbol(parsed, symbol) : findInstructionCandidate(parsed);
@@ -190880,7 +190099,7 @@ function parseFile(filePath, state) {
190880
190099
  const cached = state.parsed.get(path);
190881
190100
  if (cached)
190882
190101
  return cached;
190883
- const text = readFileSync10(path, "utf8");
190102
+ const text = readFileSync9(path, "utf8");
190884
190103
  state.bytesRead += Buffer.byteLength(text);
190885
190104
  state.files.push(path);
190886
190105
  const scriptKind = extname2(path) === ".json" ? import_typescript.default.ScriptKind.JSON : /\.tsx?$/.test(extname2(path)) ? import_typescript.default.ScriptKind.TSX : import_typescript.default.ScriptKind.JSX;
@@ -190895,7 +190114,7 @@ function parseFile(filePath, state) {
190895
190114
  function safeFile(root, base, requested) {
190896
190115
  if (requested.includes("\x00"))
190897
190116
  throw new Error(`Prompt source path contains NUL: ${requested}`);
190898
- const candidate = resolve8(base, requested);
190117
+ const candidate = resolve7(base, requested);
190899
190118
  let cursor = candidate;
190900
190119
  while (cursor !== root) {
190901
190120
  let stat2;
@@ -190911,7 +190130,7 @@ function safeFile(root, base, requested) {
190911
190130
  break;
190912
190131
  cursor = next;
190913
190132
  }
190914
- const rootReal = resolve8(root);
190133
+ const rootReal = resolve7(root);
190915
190134
  let real;
190916
190135
  try {
190917
190136
  real = requireRealpath(candidate);
@@ -191248,7 +190467,7 @@ function isBindingMutated(file, name) {
191248
190467
  function moduleSpecifier(from, specifier) {
191249
190468
  if (!specifier.startsWith("."))
191250
190469
  return;
191251
- const base = resolve8(dirname8(from), specifier);
190470
+ const base = resolve7(dirname8(from), specifier);
191252
190471
  const stripped = /\.(?:js|jsx|mjs|cjs)$/.test(base) ? base.slice(0, base.lastIndexOf(".")) : base;
191253
190472
  for (const candidate of [base, stripped, ...EXTENSIONS.map((ext) => `${base}${ext}`), ...EXTENSIONS.map((ext) => `${stripped}${ext}`), ...EXTENSIONS.map((ext) => join9(base, `index${ext}`)), ...EXTENSIONS.map((ext) => join9(stripped, `index${ext}`))])
191254
190473
  if (existsSync8(candidate) && lstatSync6(candidate).isFile())
@@ -191268,7 +190487,7 @@ function nodeRange(file, node) {
191268
190487
  };
191269
190488
  }
191270
190489
  function inspectCodeSelectors(rootDir, sourcePath, symbol) {
191271
- const state = { root: resolve8(rootDir), files: [], unresolved: [], visiting: new Set, importsVisited: new Set, parsed: new Map, assignments: new Map, bytesRead: 0 };
190490
+ const state = { root: resolve7(rootDir), files: [], unresolved: [], visiting: new Set, importsVisited: new Set, parsed: new Map, assignments: new Map, bytesRead: 0 };
191272
190491
  const parsed = parseFile(safeFile(state.root, state.root, sourcePath), state);
191273
190492
  if (symbol) {
191274
190493
  const node = findSymbol(parsed, symbol);
@@ -191318,8 +190537,8 @@ function referenceNames(node) {
191318
190537
 
191319
190538
  // src/prompt-source-python.ts
191320
190539
  import { spawnSync as spawnSync2 } from "node:child_process";
191321
- import { readFileSync as readFileSync11, realpathSync as realpathSync7 } from "node:fs";
191322
- import { resolve as resolve9 } from "node:path";
190540
+ import { readFileSync as readFileSync10, realpathSync as realpathSync7 } from "node:fs";
190541
+ import { resolve as resolve8 } from "node:path";
191323
190542
  var PYTHON_AGENT_MODULES_LITERAL = JSON.stringify(PYTHON_AGENT_MODULES);
191324
190543
  var SELECTOR_HELPER = String.raw`import ast,json,os,sys
191325
190544
  request=json.loads(sys.stdin.read()); root=os.path.realpath(request['root']); path=os.path.abspath(request['path']); wanted=request.get('symbol')
@@ -191380,7 +190599,7 @@ else:
191380
190599
  print(json.dumps({'candidates':found},ensure_ascii=False))`;
191381
190600
  function inspectPythonSelectors(rootDir, sourcePath, symbol) {
191382
190601
  const root = realpathSync7(rootDir);
191383
- const absolute = resolve9(root, sourcePath);
190602
+ const absolute = resolve8(root, sourcePath);
191384
190603
  const result = spawnSync2("python3", ["-I", "-c", SELECTOR_HELPER], {
191385
190604
  input: JSON.stringify({ root, path: absolute, ...symbol ? { symbol } : {} }),
191386
190605
  encoding: "utf8",
@@ -191525,7 +190744,7 @@ except SystemExit: pass
191525
190744
  except Exception as error: print(json.dumps({'candidates':[],'error':str(error)}))`;
191526
190745
  function discoverPythonPromptSources(rootDir, sourcePath) {
191527
190746
  const result = spawnSync2("python3", ["-I", "-c", DISCOVERY_HELPER], {
191528
- input: JSON.stringify({ root: rootDir, path: resolve9(rootDir, sourcePath) }),
190747
+ input: JSON.stringify({ root: rootDir, path: resolve8(rootDir, sourcePath) }),
191529
190748
  encoding: "utf8",
191530
190749
  maxBuffer: 4 * 1024 * 1024,
191531
190750
  timeout: 1e4
@@ -191785,7 +191004,7 @@ except Exception as e:
191785
191004
  function extractPythonSource(rootDir, sourcePath, symbol, _forceDependencyGraph = false) {
191786
191005
  let raw = "";
191787
191006
  try {
191788
- raw = readFileSync11(sourcePath, "utf8");
191007
+ raw = readFileSync10(sourcePath, "utf8");
191789
191008
  } catch {}
191790
191009
  const result = spawnSync2("python3", ["-I", "-c", HELPER], {
191791
191010
  input: JSON.stringify({ root: rootDir, path: sourcePath, symbol, force: _forceDependencyGraph }),
@@ -191879,7 +191098,7 @@ function resolvePromptSource(rootDir, source) {
191879
191098
  } else if (source.selector?.symbol) {
191880
191099
  throw new Error(`${sourcePath}: symbol selectors require a JavaScript, TypeScript, or Python source file`);
191881
191100
  } else if (ext === ".json" || ext === ".yaml" || ext === ".yml" || hasPointer || source.kind === "messages") {
191882
- const parsed = parseStructured(readFileSync12(sourceAbs, "utf8"), sourcePath, ext);
191101
+ const parsed = parseStructured(readFileSync11(sourceAbs, "utf8"), sourcePath, ext);
191883
191102
  const selected = hasPointer ? jsonPointer(parsed, source.selector.pointer, sourcePath) : parsed;
191884
191103
  const selectedField = source.selector?.pointer?.split("/").at(-1)?.replaceAll("~1", "/").replaceAll("~0", "~");
191885
191104
  const inferredKind = !source.kind && selectedField && /^(?:template|system_template|instance_template)$/.test(selectedField) ? "template" : source.kind;
@@ -191889,7 +191108,7 @@ function resolvePromptSource(rootDir, source) {
191889
191108
  messages = structured.messages;
191890
191109
  kind = structured.kind;
191891
191110
  } else {
191892
- const raw = readFileSync12(sourceAbs, "utf8");
191111
+ const raw = readFileSync11(sourceAbs, "utf8");
191893
191112
  if (ext === ".md" && /\.prompt\.md$/i.test(sourcePath)) {
191894
191113
  const legacy = parseLegacyMarkdown(raw);
191895
191114
  content = legacy.content;
@@ -191912,7 +191131,7 @@ function resolvePromptSource(rootDir, source) {
191912
191131
  const depAbs = safePath(root, dependency.path);
191913
191132
  files.add(depAbs);
191914
191133
  if (typeof dependency.selector?.pointer === "string") {
191915
- const parsed = parseStructured(readFileSync12(depAbs, "utf8"), dependency.path, extname3(depAbs).toLowerCase());
191134
+ const parsed = parseStructured(readFileSync11(depAbs, "utf8"), dependency.path, extname3(depAbs).toLowerCase());
191916
191135
  jsonPointer(parsed, dependency.selector.pointer, dependency.path);
191917
191136
  } else if (dependency.selector?.symbol && CODE_EXTENSIONS2.has(extname3(depAbs).toLowerCase())) {
191918
191137
  const dep = extname3(depAbs).toLowerCase() === ".py" ? extractPythonSource(root, depAbs, dependency.selector.symbol) : extractCodeSource(root, depAbs, dependency.selector.symbol);
@@ -191935,7 +191154,7 @@ function resolvePromptSource(rootDir, source) {
191935
191154
  assertSafeMaterializedContent(content, sourcePath);
191936
191155
  else
191937
191156
  assertSafeMaterializedContent(materialized, sourcePath);
191938
- const dependencies = [...files].sort().map((path) => ({ path: relative5(root, path).replaceAll("\\", "/"), contentHash: sha2562(readFileSync12(path)) }));
191157
+ const dependencies = [...files].sort().map((path) => ({ path: relative5(root, path).replaceAll("\\", "/"), contentHash: sha2562(readFileSync11(path)) }));
191939
191158
  const sourceHash = sha2562(JSON.stringify({ kind, content, systemPrompt: systemPrompt ?? null, messages: messages ?? null }));
191940
191159
  const sourceDefinition = {
191941
191160
  schemaVersion: 1,
@@ -192005,7 +191224,7 @@ function discoverStructuredPromptSources(rootDir, sourcePath) {
192005
191224
  const ext = extname3(file).toLowerCase();
192006
191225
  if (![".json", ".yaml", ".yml"].includes(ext))
192007
191226
  return [];
192008
- const value = parseStructured(readFileSync12(file, "utf8"), sourcePath, ext);
191227
+ const value = parseStructured(readFileSync11(file, "utf8"), sourcePath, ext);
192009
191228
  const sources = [];
192010
191229
  const base = sourcePath.replace(/\.[^.]+$/, "").replace(/[^A-Za-z0-9_.-]+/g, ".");
192011
191230
  const dedicatedPath = /(^|\/)prompts?(?:\/|\.[^/]+$)|\.prompt\.[^.]+$/i.test(sourcePath);
@@ -192081,14 +191300,14 @@ function discoverCodePromptCandidates(rootDir, sourcePath) {
192081
191300
  addName(candidate.symbol, candidate.knownBuilder === true);
192082
191301
  modelInputs.add(candidate.symbol);
192083
191302
  }
192084
- for (const match of readFileSync12(file, "utf8").matchAll(/^(?:(?:async\s+)?def\s+([A-Za-z_]\w*)|([A-Za-z_]\w*)\s*=\s*([^\n#]+))/gm)) {
191303
+ for (const match of readFileSync11(file, "utf8").matchAll(/^(?:(?:async\s+)?def\s+([A-Za-z_]\w*)|([A-Za-z_]\w*)\s*=\s*([^\n#]+))/gm)) {
192085
191304
  const name = match[1] ?? match[2];
192086
191305
  const rhs = match[3] ?? "";
192087
191306
  if (name && isPromptName2(name) && (match[1] || /['"`\[({+]/.test(rhs) || /^[A-Za-z_]\w*\s*$/.test(rhs)))
192088
191307
  addName(name, Boolean(match[1]));
192089
191308
  }
192090
191309
  } else {
192091
- const sf = import_typescript2.default.createSourceFile(file, readFileSync12(file, "utf8"), import_typescript2.default.ScriptTarget.Latest, true, import_typescript2.default.ScriptKind.TSX);
191310
+ const sf = import_typescript2.default.createSourceFile(file, readFileSync11(file, "utf8"), import_typescript2.default.ScriptTarget.Latest, true, import_typescript2.default.ScriptKind.TSX);
192092
191311
  const agentConstructors = new Set;
192093
191312
  for (const statement of sf.statements) {
192094
191313
  if (!import_typescript2.default.isImportDeclaration(statement) || !import_typescript2.default.isStringLiteral(statement.moduleSpecifier) || !TYPESCRIPT_AGENT_MODULES.includes(statement.moduleSpecifier.text))
@@ -192270,13 +191489,13 @@ function jsonPointer(value, pointer, path) {
192270
191489
  return current;
192271
191490
  }
192272
191491
  function safeRoot(dir) {
192273
- const root = realpathSync8(resolve10(dir));
191492
+ const root = realpathSync8(resolve9(dir));
192274
191493
  if (!lstatSync7(root).isDirectory())
192275
191494
  throw new Error(`Prompt source root is not a directory: ${dir}`);
192276
191495
  return root;
192277
191496
  }
192278
191497
  function safePath(root, requested) {
192279
- const candidate = resolve10(root, requested);
191498
+ const candidate = resolve9(root, requested);
192280
191499
  rejectSymlinkPath(root, candidate, requested);
192281
191500
  const real = realpathSync8(candidate);
192282
191501
  if (!(real === root || real.startsWith(`${root}/`)))
@@ -192322,12 +191541,12 @@ function sha2562(input) {
192322
191541
  }
192323
191542
 
192324
191543
  // src/prompt-source-verification/index.ts
192325
- import { readFileSync as readFileSync16 } from "node:fs";
191544
+ import { readFileSync as readFileSync15 } from "node:fs";
192326
191545
  import { z } from "zod";
192327
191546
 
192328
191547
  // src/prompt-source-validation.ts
192329
191548
  import { existsSync as existsSync9, lstatSync as lstatSync8 } from "node:fs";
192330
- import { extname as extname4, relative as relative6, resolve as resolve11 } from "node:path";
191549
+ import { extname as extname4, relative as relative6, resolve as resolve10 } from "node:path";
192331
191550
  function checkPromptMapping(rootDir, unknownMapping) {
192332
191551
  const repairs = [];
192333
191552
  const unresolved = [];
@@ -192343,10 +191562,10 @@ function checkPromptMapping(rootDir, unknownMapping) {
192343
191562
  if (JSON.stringify(normalized) !== JSON.stringify(sourceValue))
192344
191563
  repairs.push("Omitted empty selector/dependency containers");
192345
191564
  const source = validatePromptSource(normalized);
192346
- const absolute = resolve11(rootDir, source.path);
191565
+ const absolute = resolve10(rootDir, source.path);
192347
191566
  if (!existsSync9(absolute) || !lstatSync8(absolute).isFile())
192348
191567
  throw new Error(`${source.path}: source path is unavailable`);
192349
- const rel2 = relative6(resolve11(rootDir), absolute).replaceAll("\\", "/");
191568
+ const rel2 = relative6(resolve10(rootDir), absolute).replaceAll("\\", "/");
192350
191569
  if (rel2 !== source.path)
192351
191570
  repairs.push(`normalized path to ${rel2}`);
192352
191571
  let selected = { ...source, path: rel2 };
@@ -192411,23 +191630,23 @@ function isPromptDefinitionPath(path) {
192411
191630
  }
192412
191631
 
192413
191632
  // src/prompt-source-verification/evidence.ts
192414
- import { readFileSync as readFileSync15 } from "node:fs";
191633
+ import { readFileSync as readFileSync14 } from "node:fs";
192415
191634
  import { extname as extname7 } from "node:path";
192416
191635
 
192417
191636
  // src/prompt-source-verification/paths.ts
192418
191637
  import { lstatSync as lstatSync9, realpathSync as realpathSync9 } from "node:fs";
192419
- import { isAbsolute as isAbsolute5, relative as relative7, resolve as resolve12, sep as sep4 } from "node:path";
191638
+ import { isAbsolute as isAbsolute5, relative as relative7, resolve as resolve11, sep as sep4 } from "node:path";
192420
191639
  function safePromptEvidencePath(rootDir, path) {
192421
191640
  const root = realpathSync9(rootDir);
192422
191641
  if (!path || isAbsolute5(path))
192423
191642
  throw new Error("Evidence path must be repository-relative");
192424
- const absolute = resolve12(root, path);
191643
+ const absolute = resolve11(root, path);
192425
191644
  const rel2 = relative7(root, absolute);
192426
191645
  if (!rel2 || rel2 === ".." || rel2.startsWith(`..${sep4}`) || isAbsolute5(rel2))
192427
191646
  throw new Error("Evidence escapes repository");
192428
191647
  let current = root;
192429
191648
  for (const part of rel2.split(sep4)) {
192430
- current = resolve12(current, part);
191649
+ current = resolve11(current, part);
192431
191650
  if (lstatSync9(current).isSymbolicLink())
192432
191651
  throw new Error("Evidence path is symlinked");
192433
191652
  }
@@ -192441,14 +191660,14 @@ function safePromptEvidencePath(rootDir, path) {
192441
191660
  var import_typescript3 = __toESM(require_typescript(), 1);
192442
191661
  import { execFileSync as execFileSync2 } from "node:child_process";
192443
191662
  import { extname as extname5 } from "node:path";
192444
- import { readFileSync as readFileSync13 } from "node:fs";
191663
+ import { readFileSync as readFileSync12 } from "node:fs";
192445
191664
  function proveSink(root, sink) {
192446
191665
  const file = safePromptEvidencePath(root, sink.path);
192447
191666
  const cache = new Map;
192448
191667
  if (!cache.has(file)) {
192449
191668
  if (extname5(file) === ".py") {
192450
191669
  try {
192451
- const rows = JSON.parse(execFileSync2("python3", ["-I", "-c", PYTHON_PROOF], { input: readFileSync13(file, "utf8"), encoding: "utf8", timeout: 1e4, maxBuffer: 2 * 1024 * 1024 }));
191670
+ const rows = JSON.parse(execFileSync2("python3", ["-I", "-c", PYTHON_PROOF], { input: readFileSync12(file, "utf8"), encoding: "utf8", timeout: 1e4, maxBuffer: 2 * 1024 * 1024 }));
192452
191671
  cache.set(file, new Map(Object.entries(rows).map(([line, proof]) => [Number(line), proof])));
192453
191672
  } catch {
192454
191673
  cache.set(file, new Map);
@@ -192615,7 +191834,7 @@ print(json.dumps(rows))
192615
191834
  `;
192616
191835
 
192617
191836
  // src/prompt-source-location.ts
192618
- import { readFileSync as readFileSync14 } from "node:fs";
191837
+ import { readFileSync as readFileSync13 } from "node:fs";
192619
191838
  import { extname as extname6 } from "node:path";
192620
191839
  function structuredExcerpt(text, source) {
192621
191840
  if (source.selector?.pointer === undefined)
@@ -192669,7 +191888,7 @@ function promptDefinitionExcerpt(rootDir, source) {
192669
191888
  return;
192670
191889
  return { ...extraction.range, text: extraction.sourceText, ...extraction.declarationKind ? { declarationKind: extraction.declarationKind } : {} };
192671
191890
  }
192672
- const text = readFileSync14(file, "utf8");
191891
+ const text = readFileSync13(file, "utf8");
192673
191892
  return structuredExcerpt(text, source);
192674
191893
  }
192675
191894
  function promptDefinitionRange(rootDir, source) {
@@ -192696,7 +191915,7 @@ function reviewEvidence(rootDir, source, evidence) {
192696
191915
  for (const item of evidence) {
192697
191916
  let text;
192698
191917
  try {
192699
- text = readFileSync15(safePromptEvidencePath(rootDir, item.path), "utf8");
191918
+ text = readFileSync14(safePromptEvidencePath(rootDir, item.path), "utf8");
192700
191919
  } catch (error) {
192701
191920
  if (item.kind === "model_endpoint")
192702
191921
  return { valid: false, endpointVerified: false, reason: error instanceof Error ? error.message : String(error) };
@@ -192811,7 +192030,7 @@ async function independentlyVerifyPromptSource(rootDir, source, verifier) {
192811
192030
  let priorJudgment;
192812
192031
  try {
192813
192032
  const before = JSON.stringify(checked.resolved.sourceDefinition);
192814
- const sourceBytes = readFileSync16(safePromptEvidencePath(rootDir, source.path), "utf8");
192033
+ const sourceBytes = readFileSync15(safePromptEvidencePath(rootDir, source.path), "utf8");
192815
192034
  const instruction = promptVerificationInstruction(checked.source, checked.sourceHash, promptDefinitionExcerpt(rootDir, checked.source));
192816
192035
  for (let attempt = 0;attempt < 2; attempt++) {
192817
192036
  const repair = attempt ? `
@@ -192842,7 +192061,7 @@ ${output}` : "";
192842
192061
  }
192843
192062
  if (reviewed.truncated || reviewed.sourceHash !== checked.sourceHash)
192844
192063
  return pending("Verifier output is truncated or cites a different source hash", reviewed.evidence, reviewed.role, normalizeUsage(undefined, false));
192845
- if (before !== snapshot() || readFileSync16(safePromptEvidencePath(rootDir, source.path), "utf8") !== sourceBytes)
192064
+ if (before !== snapshot() || readFileSync15(safePromptEvidencePath(rootDir, source.path), "utf8") !== sourceBytes)
192846
192065
  return pending("Source changed during verification", reviewed.evidence, reviewed.role, normalizeUsage(undefined, false));
192847
192066
  if (reviewed.role === "non_prompt")
192848
192067
  return { status: "rejected", reason: reviewed.reason, evidence: reviewed.evidence, sourceHash: checked.sourceHash, role: reviewed.role, usage: normalizeUsage(undefined, false) };
@@ -193202,8 +192421,8 @@ function applyPromptDiscovery(graph, discovery) {
193202
192421
  }
193203
192422
 
193204
192423
  // src/harness-candidate-promotion.ts
193205
- import { readFileSync as readFileSync17 } from "node:fs";
193206
- import { resolve as resolve13 } from "node:path";
192424
+ import { readFileSync as readFileSync16 } from "node:fs";
192425
+ import { resolve as resolve12 } from "node:path";
193207
192426
  var PROMOTED_CONFIDENCE = {
193208
192427
  high: 0.85,
193209
192428
  medium: 0.6
@@ -193233,7 +192452,7 @@ function readFileLines(rootDir, path, cache) {
193233
192452
  return cached;
193234
192453
  let lines;
193235
192454
  try {
193236
- lines = readFileSync17(resolve13(rootDir, path), "utf8").split(/\r?\n/);
192455
+ lines = readFileSync16(resolve12(rootDir, path), "utf8").split(/\r?\n/);
193237
192456
  } catch {
193238
192457
  lines = null;
193239
192458
  }
@@ -194516,7 +193735,7 @@ async function runHarnessCommand(context) {
194516
193735
  return runHarnessRegister(context);
194517
193736
  if (subcommand === "registration")
194518
193737
  return runHarnessRegistration(context);
194519
- const rootDir = resolve14(context.cwd, context.flags.path ?? ".");
193738
+ const rootDir = resolve13(context.cwd, context.flags.path ?? ".");
194520
193739
  const selectedAgentId = selectedRuntimeAgentId(context.flags);
194521
193740
  const tenant = resolveHarnessTenant(context.flags, context);
194522
193741
  const scanPlan = buildCommandScanPlan(context, rootDir);
@@ -194712,11 +193931,11 @@ async function runHarnessCommand(context) {
194712
193931
  if (!idOrKey) {
194713
193932
  throw new CliInputError("Missing harness id or key to delete.", "Usage: moda harness delete <harness-id-or-key> [--yes]");
194714
193933
  }
194715
- const profileOptions2 = { profile: context.profile, env: context.env };
194716
- if (!resolveApiKey(profileOptions2) && !context.dryRun) {
193934
+ const profileOptions = { profile: context.profile, env: context.env };
193935
+ if (!resolveApiKey(profileOptions) && !context.dryRun) {
194717
193936
  throw new CliInputError("No Moda API key found for harness delete.", "Run `moda init` first, set MODA_API_KEY, or select a profile with an API key.");
194718
193937
  }
194719
- const identity3 = describeSyncIdentity(profileOptions2);
193938
+ const identity3 = describeSyncIdentity(profileOptions);
194720
193939
  if (identity3) {
194721
193940
  const label = identity3.tenantSource === "api-key" ? describeSyncTenantLabel(identity3) : describeSyncTenantLabel({
194722
193941
  tenantId: tenant?.tenantId ?? identity3.tenantId,
@@ -194734,7 +193953,7 @@ async function runHarnessCommand(context) {
194734
193953
  return { exitCode: 0 };
194735
193954
  }
194736
193955
  await confirmHarnessDelete(context, idOrKey);
194737
- const response = await callControlAPI(`/harnesses/${encodeURIComponent(idOrKey)}`, { method: "DELETE" }, profileOptions2);
193956
+ const response = await callControlAPI(`/harnesses/${encodeURIComponent(idOrKey)}`, { method: "DELETE" }, profileOptions);
194738
193957
  writeHumanProgress(context, `Deleted harness ${response.harnessKey ?? idOrKey} from tenant ${response.tenantId ?? "unknown"} ` + `(${response.deleted?.versions ?? 0} versions, ${response.deleted?.agents ?? 0} agents, ` + `${response.deleted?.artifacts ?? 0} artifacts, ${response.deleted?.relationships ?? 0} relationships).`);
194739
193958
  context.output.writeData({ ...response, dryRun: false });
194740
193959
  return { exitCode: 0 };
@@ -194777,7 +193996,7 @@ async function runHarnessCommand(context) {
194777
193996
  throw new CliInputError("Focused remote prompt analysis is not supported yet.", "Use local --analyst=claude|codex|cursor|local-scan, or drop --concern for a full remote report.");
194778
193997
  }
194779
193998
  if (context.flags["github-actions"] === "true") {
194780
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-wpkr7jjr.js");
193999
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-nph5t2s7.js");
194781
194000
  const result = await runGithubActionsAnalyze(rootDir, {
194782
194001
  writeReport: (report2) => {
194783
194002
  const normalized = normalizeHarnessReport(report2);
@@ -194919,7 +194138,7 @@ async function runHarnessCommand(context) {
194919
194138
  throw new CliInputError("Missing output path for --out.", "Usage: moda harness candidates --out=<file>");
194920
194139
  }
194921
194140
  if (outFlag && !context.dryRun) {
194922
- written.push(writeHarnessCandidatesReport(report, resolve14(context.cwd, outFlag)));
194141
+ written.push(writeHarnessCandidatesReport(report, resolve13(context.cwd, outFlag)));
194923
194142
  }
194924
194143
  writeHumanProgress(context, `Harness candidates: ${report.stats.candidateCount} candidates across ${report.stats.filesWithCandidates} files (${report.stats.filesScanned} scanned, ${report.stats.filesPerSecond.toLocaleString()} files/sec).`);
194925
194144
  context.output.writeData({ scanPlan, ...report, written, dryRun: context.dryRun });
@@ -195018,8 +194237,8 @@ async function runHarnessCommand(context) {
195018
194237
  if (context.flags[flag] === "true")
195019
194238
  throw new CliInputError(`--${flag} needs a value.`);
195020
194239
  }
195021
- const profileOptions2 = { profile: context.profile, env: context.env };
195022
- if (!resolveApiKey(profileOptions2)) {
194240
+ const profileOptions = { profile: context.profile, env: context.env };
194241
+ if (!resolveApiKey(profileOptions)) {
195023
194242
  throw new CliInputError(`No Moda API key found for harness ${subcommand}.`, "Set MODA_API_KEY, run `moda auth login --api-key`, or select a profile with an API key.");
195024
194243
  }
195025
194244
  const query = new URLSearchParams;
@@ -195039,7 +194258,7 @@ async function runHarnessCommand(context) {
195039
194258
  query.set("to", context.flags.to);
195040
194259
  const suffix = query.toString() ? `?${query.toString()}` : "";
195041
194260
  const path = subcommand === "list" ? `/harnesses${suffix}` : `/harnesses/${encodeURIComponent(idOrKey)}${subcommand === "show" ? "" : `/${subcommand}`}${suffix}`;
195042
- context.output.writeData(await callControlAPI(path, {}, profileOptions2));
194261
+ context.output.writeData(await callControlAPI(path, {}, profileOptions));
195043
194262
  return { exitCode: 0 };
195044
194263
  }
195045
194264
  default:
@@ -195111,7 +194330,7 @@ async function runPromptConcernAnalysis(context, rootDir, scanPlan, tenant) {
195111
194330
  const manifest = join10(rootDir, ".moda/prompts.yml");
195112
194331
  let existing = [];
195113
194332
  if (existsSync10(manifest)) {
195114
- const document = $parseDocument(readFileSync18(manifest, "utf8"));
194333
+ const document = $parseDocument(readFileSync17(manifest, "utf8"));
195115
194334
  if (document.errors.length)
195116
194335
  throw new CliInputError("Invalid prompt manifest.", document.errors[0].message);
195117
194336
  existing = document.toJS({ maxAliasCount: 20 })?.sources ?? [];
@@ -195340,7 +194559,7 @@ function buildExternalAnalystEnv(env) {
195340
194559
  return next;
195341
194560
  }
195342
194561
  function readExternalAnalystReport(rootDir, result, adapter, concern) {
195343
- const reportPath = resolve14(rootDir, HARNESS_REPORT_PATH);
194562
+ const reportPath = resolve13(rootDir, HARNESS_REPORT_PATH);
195344
194563
  if (existsSync10(reportPath))
195345
194564
  return repairExternalAnalystReport(readHarnessReport(reportPath), rootDir, { concern });
195346
194565
  const output = [
@@ -195355,7 +194574,7 @@ function readExternalAnalystReport(rootDir, result, adapter, concern) {
195355
194574
  return parsed;
195356
194575
  let debugHint = "";
195357
194576
  try {
195358
- const debugPath = resolve14(rootDir, MODA_DIR, "analyst-debug.log");
194577
+ const debugPath = resolve13(rootDir, MODA_DIR, "analyst-debug.log");
195359
194578
  mkdirSync6(dirname9(debugPath), { recursive: true });
195360
194579
  writeFileSync6(debugPath, [
195361
194580
  `# analyst=${adapter} status=${result.status} signal=${result.signal} timedOut=${result.timedOut} maxBufferExceeded=${result.maxBufferExceeded}`,
@@ -195577,12 +194796,12 @@ function repairCitationLines(report, rootDir) {
195577
194796
  if (citation.type !== "file" && citation.type !== "generated_doc" || !citation.path || !citation.excerpt)
195578
194797
  continue;
195579
194798
  const excerpt2 = citation.excerpt;
195580
- const candidatePath = resolve14(rootDir, citation.path);
194799
+ const candidatePath = resolve13(rootDir, citation.path);
195581
194800
  if (!existsSync10(candidatePath))
195582
194801
  continue;
195583
194802
  let text;
195584
194803
  try {
195585
- text = readFileSync18(candidatePath, "utf8");
194804
+ text = readFileSync17(candidatePath, "utf8");
195586
194805
  } catch {
195587
194806
  continue;
195588
194807
  }
@@ -196182,8 +195401,8 @@ function resolveExternalHarnessAnalystInvocation(options) {
196182
195401
  }
196183
195402
  function createPromptAnalystIsolation(adapter, rootDir) {
196184
195403
  const moduleDir = dirname9(fileURLToPath(import.meta.url));
196185
- const bundled = resolve14(moduleDir, "prompt-source-mcp.js");
196186
- const source = resolve14(moduleDir, "prompt-source-mcp.ts");
195404
+ const bundled = resolve13(moduleDir, "prompt-source-mcp.js");
195405
+ const source = resolve13(moduleDir, "prompt-source-mcp.ts");
196187
195406
  const bundledServer = existsSync10(bundled);
196188
195407
  const serverPath = bundledServer ? bundled : source;
196189
195408
  const command = bundledServer ? process.execPath : resolveBunRuntime();
@@ -196693,11 +195912,11 @@ function splitCommandLine(commandLine) {
196693
195912
  return commandLine.trim().split(/\s+/).filter(Boolean);
196694
195913
  }
196695
195914
  function truncateText(value, maxLength) {
196696
- const compact2 = value.replace(/\s+/g, " ").trim();
196697
- return compact2.length > maxLength ? `${compact2.slice(0, maxLength - 1)}...` : compact2;
195915
+ const compact = value.replace(/\s+/g, " ").trim();
195916
+ return compact.length > maxLength ? `${compact.slice(0, maxLength - 1)}...` : compact;
196698
195917
  }
196699
195918
  function scanHarness(options = {}) {
196700
- const rootDir = resolve14(options.rootDir ?? process.cwd());
195919
+ const rootDir = resolve13(options.rootDir ?? process.cwd());
196701
195920
  const skipped = [];
196702
195921
  const files = inventoryFiles(rootDir, skipped);
196703
195922
  const annotations = files.flatMap((file) => parseAnnotations(file));
@@ -196799,7 +196018,7 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
196799
196018
  let text = "";
196800
196019
  if (isTextFile(path)) {
196801
196020
  try {
196802
- text = readFileSync18(current, "utf8");
196021
+ text = readFileSync17(current, "utf8");
196803
196022
  inventoryTextBytes += Buffer.byteLength(text, "utf8");
196804
196023
  } catch {
196805
196024
  return;
@@ -196812,7 +196031,7 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
196812
196031
  return inputs;
196813
196032
  }
196814
196033
  function buildSourceSnapshot(rootDir) {
196815
- const root2 = resolve14(rootDir);
196034
+ const root2 = resolve13(rootDir);
196816
196035
  const maxFiles = numericEnv("MODA_HARNESS_MAX_FILES", DEFAULT_MAX_INVENTORY_FILES);
196817
196036
  const maxTextBytes = numericEnv("MODA_HARNESS_MAX_TEXT_BYTES", DEFAULT_MAX_INVENTORY_TEXT_BYTES);
196818
196037
  const inputs = collectSnapshotInputs(root2, maxFiles, maxTextBytes);
@@ -197022,8 +196241,8 @@ function plannedDryRunRemote(plan) {
197022
196241
  }
197023
196242
  async function syncHarnessWithRemote(context, body) {
197024
196243
  assertHarnessGraphSyncSize(body.graph);
197025
- const profileOptions2 = { profile: context.profile, env: context.env };
197026
- const hasApiKey = Boolean(resolveApiKey(profileOptions2));
196244
+ const profileOptions = { profile: context.profile, env: context.env };
196245
+ const hasApiKey = Boolean(resolveApiKey(profileOptions));
197027
196246
  if (context.dryRun && !hasApiKey)
197028
196247
  return;
197029
196248
  return await callControlAPI("/harnesses/sync", {
@@ -197032,14 +196251,14 @@ async function syncHarnessWithRemote(context, body) {
197032
196251
  ...body,
197033
196252
  dryRun: context.dryRun
197034
196253
  })
197035
- }, profileOptions2);
196254
+ }, profileOptions);
197036
196255
  }
197037
196256
  function readHarnessSyncState(rootDir) {
197038
196257
  const path = join10(rootDir, SYNC_STATE_PATH);
197039
196258
  if (!existsSync10(path))
197040
196259
  return;
197041
196260
  try {
197042
- const parsed = JSON.parse(readFileSync18(path, "utf8"));
196261
+ const parsed = JSON.parse(readFileSync17(path, "utf8"));
197043
196262
  if (!isRecord4(parsed) || parsed.schemaVersion !== "sync_state.v0.1") {
197044
196263
  return;
197045
196264
  }
@@ -197156,7 +196375,7 @@ function findFresherHarnessReports(rootDir) {
197156
196375
  return fresher.sort((a, b) => b.mtimeMs - a.mtimeMs);
197157
196376
  }
197158
196377
  function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
197159
- const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath3(relative8(rootDir, resolve14(rootDir, explicitReport))) : undefined;
196378
+ const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath3(relative8(rootDir, resolve13(rootDir, explicitReport))) : undefined;
197160
196379
  if (explicitReportPath && explicitReportPath !== normalizePath3(HARNESS_REPORT_PATH))
197161
196380
  return;
197162
196381
  let fresher;
@@ -197173,7 +196392,7 @@ function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
197173
196392
  writeHarnessNotice(context, `A fresher harness report exists at ${newest.path} (this directory has ${rootState}). If you meant that report, re-run with --path=${subdir}.`);
197174
196393
  }
197175
196394
  function readHarnessGraph(manifestPath) {
197176
- return JSON.parse(readFileSync18(manifestPath, "utf8"));
196395
+ return JSON.parse(readFileSync17(manifestPath, "utf8"));
197177
196396
  }
197178
196397
  function writeHarnessArtifacts(graph, rootDir, options = {}) {
197179
196398
  const modaDir = join10(rootDir, MODA_DIR);
@@ -197358,7 +196577,7 @@ function explainAgent(graph, agent) {
197358
196577
  }
197359
196578
  function inventoryFiles(rootDir, skipped, options = {}) {
197360
196579
  const files = [];
197361
- const rootReal = resolve14(rootDir);
196580
+ const rootReal = resolve13(rootDir);
197362
196581
  const maxFiles = numericEnv("MODA_HARNESS_MAX_FILES", DEFAULT_MAX_INVENTORY_FILES);
197363
196582
  const maxTextBytes = numericEnv("MODA_HARNESS_MAX_TEXT_BYTES", DEFAULT_MAX_INVENTORY_TEXT_BYTES);
197364
196583
  let textBytes = 0;
@@ -197412,7 +196631,7 @@ function inventoryFiles(rootDir, skipped, options = {}) {
197412
196631
  recordSkipped(skipped, { path: rel2, reason: "scan text budget exceeded" });
197413
196632
  } else {
197414
196633
  try {
197415
- item.text = readFileSync18(current, "utf8");
196634
+ item.text = readFileSync17(current, "utf8");
197416
196635
  textBytes += Buffer.byteLength(item.text, "utf8");
197417
196636
  } catch {
197418
196637
  recordSkipped(skipped, { path: rel2, reason: "text read failed" });
@@ -197719,7 +196938,7 @@ function maybeAddPromptArtifact(graph, file) {
197719
196938
  if (!isPrompt)
197720
196939
  return;
197721
196940
  const id = stableId2("prompt", file.path);
197722
- const text = file.text ?? readFileSync18(file.absPath, "utf8");
196941
+ const text = file.text ?? readFileSync17(file.absPath, "utf8");
197723
196942
  upsertArtifact(graph, {
197724
196943
  id,
197725
196944
  type: "prompt",
@@ -198300,7 +197519,7 @@ function detectProviderPackagesInManifests(rootDir) {
198300
197519
  const packageJsonPath = join10(rootDir, "package.json");
198301
197520
  if (existsSync10(packageJsonPath)) {
198302
197521
  try {
198303
- const deps = packageDependencyNames(readFileSync18(packageJsonPath, "utf8"));
197522
+ const deps = packageDependencyNames(readFileSync17(packageJsonPath, "utf8"));
198304
197523
  for (const provider of PROVIDER_CATALOG) {
198305
197524
  for (const name of provider.packageNames) {
198306
197525
  if (deps.has(name))
@@ -198312,7 +197531,7 @@ function detectProviderPackagesInManifests(rootDir) {
198312
197531
  const pyprojectPath = join10(rootDir, "pyproject.toml");
198313
197532
  if (existsSync10(pyprojectPath)) {
198314
197533
  try {
198315
- const deps = pyprojectDependencyNames(readFileSync18(pyprojectPath, "utf8"));
197534
+ const deps = pyprojectDependencyNames(readFileSync17(pyprojectPath, "utf8"));
198316
197535
  for (const provider of PROVIDER_CATALOG) {
198317
197536
  for (const name of provider.packageNames) {
198318
197537
  if (deps.has(name.toLowerCase()))
@@ -198695,7 +197914,7 @@ function upsertDeployment(graph, next) {
198695
197914
  }
198696
197915
  function contentHashForAnnotatedSource(sourcePath, annotation) {
198697
197916
  const bodyAnnotation = annotation;
198698
- const rootCandidate = resolve14(annotation.rootDir, sourcePath);
197917
+ const rootCandidate = resolve13(annotation.rootDir, sourcePath);
198699
197918
  const candidates = [
198700
197919
  rootCandidate,
198701
197920
  ...annotatedSourceCandidates(sourcePath, bodyAnnotation).filter((c) => c !== rootCandidate)
@@ -198729,7 +197948,7 @@ function readSmallTextFileForHash(absPath, rootDir) {
198729
197948
  if (!isTextFile(rel2))
198730
197949
  return;
198731
197950
  try {
198732
- return readFileSync18(absPath, "utf8");
197951
+ return readFileSync17(absPath, "utf8");
198733
197952
  } catch {
198734
197953
  return;
198735
197954
  }
@@ -198822,4 +198041,4 @@ function hashText(text) {
198822
198041
  return createHash7("sha256").update(text).digest("hex");
198823
198042
  }
198824
198043
 
198825
- export { isPlatformApiKey, setPlatformTenantOverride, apiKeyHeaders, ApiError, callDataAPI, callControlAPI, $isSeq, $parseDocument, $stringify, require_typescript, inspectCodeSelectors, inspectPythonSelectors, resolvePromptSource, backfillPromptSource, HARNESS_REPORT_PATH, HARNESS_REPORT_APPROVAL_PATH, HARNESS_ANALYZE_CONCERNS, validateHarnessReport, readHarnessReport, normalizeHarnessReport, hashHarnessReport, hashStableJson, assertFlags, assertPositionals, runUsersCommand, runUserCommand, runProblemReopenCommand, runSignalsManagementCommand, SIGNALS_MANAGEMENT_SUBCOMMANDS, unknownSignalsSubcommandError, shouldColorTerminalOutput, terminalStyles, stripAnsi2 as stripAnsi, renderMarkdownForTerminal, startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, canonicalText, renderDoctorHuman, renderStatusHuman, renderInitBanner, renderInitStep, renderInitNote, renderInitSetupPlan, renderInitComplete, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, repairExternalAnalystReport, deriveRelationshipsFromGraph, mergeDeterministicArtifacts, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, readHarnessSyncState, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId2 as stableId, titleFromId2 as titleFromId, promptNameFromPath };
198044
+ export { $isSeq, $parseDocument, $stringify, require_typescript, inspectCodeSelectors, inspectPythonSelectors, resolvePromptSource, backfillPromptSource, HARNESS_REPORT_PATH, HARNESS_REPORT_APPROVAL_PATH, HARNESS_ANALYZE_CONCERNS, validateHarnessReport, readHarnessReport, normalizeHarnessReport, hashHarnessReport, hashStableJson, startRemoteAnalyze, pollRemoteAnalyzeUntilDone, isRecoverableRemoteRun, checkPromptMapping, safePromptEvidencePath, discoverHarnessPromptSources, canonicalText, renderDoctorHuman, renderStatusHuman, renderInitBanner, renderInitStep, renderInitNote, renderInitSetupPlan, renderInitComplete, runHarnessCommand, writeHarnessAnalyzeResult, emitWrittenArtifacts, analyzeHarnessPrompts, repairExternalAnalystReport, deriveRelationshipsFromGraph, mergeDeterministicArtifacts, describeCodingAgentEvent, analystEventProgress, isRetryableExternalAnalystFailure, sleep, summarizeInvalidAnalystReport, isDeterministicLocalAnalyst, resolveHarnessAnalyzeConcern, detectAvailableCodingAgents, codingAgentDisplayName, runCodingAgent, resolveAnalystModel, renderExternalHarnessAnalystPrompt, CONCERN_CANDIDATE_KINDS, SEED_CANDIDATE_KIND_LABELS, renderAnalystCandidateLines, renderAnalystSeedLines, truncateText, scanHarness, summarizeHarness, buildSourceSnapshot, writeHumanProgress, readHarnessSyncState, describeSyncIdentity, describeSyncTenantLabel, findFresherHarnessReports, writeHarnessArtifacts, assertHarnessGraphSyncQuality, graphForSync, inventoryFiles, numericEnv, numericEnvAllowZero, computeDeterministicFloor, stableId2 as stableId, titleFromId2 as titleFromId, promptNameFromPath };