@moda-ai/cli 1.55.68 → 1.55.69

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,8 +1,8 @@
1
1
  import {
2
2
  buildDoctorReport
3
- } from "./cli-k5zerb77.js";
3
+ } from "./cli-45m0bz7q.js";
4
4
  import"./cli-27kkk5z4.js";
5
- import"./cli-0hhje3n9.js";
5
+ import"./cli-67sp41tx.js";
6
6
  import"./cli-mm48br00.js";
7
7
  import {
8
8
  readHarnessSyncState
@@ -95,7 +95,7 @@ async function buildAgentContext(context) {
95
95
  const graph = readHarnessGraphIfPresent(context.cwd);
96
96
  const reportState = readHarnessReportState(context.cwd);
97
97
  const syncState = readHarnessSyncState(context.cwd);
98
- const harness = graph ? await import("./harness-djtzm1c5.js") : undefined;
98
+ const harness = graph ? await import("./harness-zbxfgaer.js") : undefined;
99
99
  const topFindings = doctor.checks.filter((check) => check.status === "fail" || check.status === "warning").slice(0, 12).map(checkToFinding);
100
100
  const evidenceRefs = [
101
101
  ...doctor.checks.map(checkToEvidenceRef),
@@ -4,7 +4,7 @@ import {
4
4
  } from "./cli-27kkk5z4.js";
5
5
  import {
6
6
  inspectPromptManifest
7
- } from "./cli-0hhje3n9.js";
7
+ } from "./cli-67sp41tx.js";
8
8
  import {
9
9
  readHarnessSyncState,
10
10
  renderDoctorHuman,
@@ -395,7 +395,7 @@ async function harnessCurrentCheck(cwd, manifestPath, manifestExists, tenantId)
395
395
  };
396
396
  }
397
397
  try {
398
- const { scanHarness } = await import("./harness-djtzm1c5.js");
398
+ const { scanHarness } = await import("./harness-zbxfgaer.js");
399
399
  const current = scanHarness({
400
400
  rootDir: cwd,
401
401
  scannerVersion: "doctor",
@@ -5768,7 +5768,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
5768
5768
  const analyzedDefinitions = new Map;
5769
5769
  if (flags["no-analyze"] !== "true") {
5770
5770
  options.onProgress?.("Analyzing prompt sources before sync.");
5771
- const { analyzeHarnessPrompts } = await import("./harness-djtzm1c5.js");
5771
+ const { analyzeHarnessPrompts } = await import("./harness-zbxfgaer.js");
5772
5772
  const result = await analyzeHarnessPrompts({
5773
5773
  rootDir: process.cwd(),
5774
5774
  existing: established.flatMap((prompt) => prompt.sourceDefinition ? [prompt.sourceDefinition.source] : []),
@@ -5796,7 +5796,7 @@ async function runPromptSyncExclusive(flags, profileOptions, options) {
5796
5796
  const mergedSources = mergePromptSources(manifest.sources, extraSources);
5797
5797
  const manifestUpdate = stableJson(mergedSources) === stableJson(mergePromptSources(manifest.sources, [])) ? undefined : $stringify({ version: 2, prompt_paths: manifest.promptPaths, sources: mergedSources });
5798
5798
  const prompts = await discoverPrompts(extraSources);
5799
- const { checkPromptAttribution } = await import("./prompt-attribution-9b4j1d3f.js");
5799
+ const { checkPromptAttribution } = await import("./prompt-attribution-8qhwgssy.js");
5800
5800
  const attribution = checkPromptAttribution(process.cwd(), prompts.map((prompt) => prompt.key));
5801
5801
  const brokenAttribution = attribution.references.filter((reference) => reference.status === "missing");
5802
5802
  if (brokenAttribution.length) {
@@ -6102,7 +6102,7 @@ async function migratePromptManifest(options = {}) {
6102
6102
  let addedSources = [];
6103
6103
  let pendingSources = [];
6104
6104
  if (options.discover) {
6105
- const { analyzeHarnessPrompts } = await import("./harness-djtzm1c5.js");
6105
+ const { analyzeHarnessPrompts } = await import("./harness-zbxfgaer.js");
6106
6106
  const result = await analyzeHarnessPrompts({
6107
6107
  rootDir: root,
6108
6108
  existing: manifest.sources,
@@ -2181,10 +2181,21 @@ var MODEL_PATH = /\/chat\/completions\b|\/v1\/messages\b|\/v1\/responses\b|:gene
2181
2181
  var FRAMEWORK_MODULE = /^(?:agents(?:\/.*)?|@cloudflare\/think|@cloudflare\/ai-chat|@cloudflare\/agents|cloudflare:workers|cloudflare:workflows)$/;
2182
2182
  var FRAMEWORK_BASES = new Set(["Think", "Agent", "AIChatAgent", "McpAgent", "DurableObject", "WorkflowEntrypoint", "AgentWorkflow"]);
2183
2183
  var HOOK_BASES = new Set(["Think", "Agent", "AIChatAgent", "McpAgent"]);
2184
- var HOOK_METHODS = { getModel: "model", getSystemPrompt: "system", getTools: "tools" };
2185
- var HOOK_PROPERTIES = { model: "model", systemPrompt: "system" };
2186
- var TURN_HOOKS = new Set(["beforeTurn"]);
2187
- var TURN_CONFIG_KEYS = { model: "model", system: "system", tools: "tools" };
2184
+ var HOOK_METHODS = {
2185
+ getModel: "model",
2186
+ getTools: "tools",
2187
+ getSystemPrompt: "system",
2188
+ configureContext: "system",
2189
+ getInstructions: "system",
2190
+ instructions: "system",
2191
+ system: "system",
2192
+ systemPrompt: "system",
2193
+ buildSystemPrompt: "system",
2194
+ formatAgentToolInput: "messages"
2195
+ };
2196
+ var HOOK_PROPERTIES = { model: "model", systemPrompt: "system", instructions: "system", system: "system" };
2197
+ var TURN_HOOKS = new Set(["beforeTurn", "beforeStep", "prepareStep"]);
2198
+ var TURN_CONFIG_KEYS = { model: "model", system: "system", tools: "tools", messages: "messages" };
2188
2199
  function providerName(module) {
2189
2200
  if (module === "ai" || module === "@ai-sdk/gateway")
2190
2201
  return "ai-gateway";
@@ -2624,7 +2635,7 @@ var fetchSink = {
2624
2635
  };
2625
2636
  }
2626
2637
  };
2627
- var AGENT_ENTRY_METHODS = new Set(["run", "chat", "saveMessages", "sendMessage", "submitMessage", "prompt"]);
2638
+ var AGENT_ENTRY_METHODS = new Set(["run", "executeRun", "chat", "saveMessages", "sendMessage", "submitMessage", "prompt", "runAgentTool"]);
2628
2639
  var AGENT_BASES = new Set(["Think", "Agent", "AIChatAgent"]);
2629
2640
  var ENTRY_FIELDS = ["message", "context", "brief"];
2630
2641
  var STUB_GETTERS = new Set(["get", "getByName", "getAgentByName", "getServerByName", "routeAgentRequest", "getStub"]);
@@ -2716,6 +2727,7 @@ function structuralAgent(receiver, method, ctx) {
2716
2727
  } catch {
2717
2728
  return;
2718
2729
  }
2730
+ declaration ??= declaredMethod(receiver, method, ctx.checker);
2719
2731
  if (!declaration)
2720
2732
  return;
2721
2733
  const owner = declaration.parent;
@@ -2742,14 +2754,19 @@ var agentEntrySink = {
2742
2754
  const base = ctx.frameworkBase(candidate).base;
2743
2755
  return base !== undefined && AGENT_BASES.has(base);
2744
2756
  });
2757
+ const seam = method === "runAgentTool" && !cls && hasMethod(callee.expression, method, ctx) ? callee.expression : undefined;
2745
2758
  const target = cls ?? structuralAgent(callee.expression, method, ctx);
2746
- if (!target)
2759
+ if (!target && !seam)
2747
2760
  return;
2748
- const argument = call.arguments[0];
2749
- if (import_typescript5.default.isSpreadElement(argument))
2761
+ const argument = method === "runAgentTool" ? call.arguments[1] : call.arguments[0];
2762
+ if (!argument || import_typescript5.default.isSpreadElement(argument))
2750
2763
  return;
2751
2764
  const roles = [];
2752
- if (method === "saveMessages") {
2765
+ if (method === "runAgentTool") {
2766
+ const object = objectLiteralOf(argument, ctx.checker);
2767
+ const input = object ? propertyValue(object, "input") : undefined;
2768
+ roles.push(input ? { role: "user", node: input } : { role: "user", node: argument, key: "input" });
2769
+ } else if (method === "saveMessages") {
2753
2770
  roles.push({ role: "messages", node: argument });
2754
2771
  } else {
2755
2772
  const object = objectLiteralOf(argument, ctx.checker);
@@ -2761,9 +2778,85 @@ var agentEntrySink = {
2761
2778
  roles.push({ role: "user", node: argument });
2762
2779
  }
2763
2780
  }
2764
- return { api: `${className(target) ?? "agent"}.${method}`, roles };
2781
+ return { api: `${(target && className(target)) ?? "agent"}.${method}`, roles };
2765
2782
  }
2766
2783
  };
2784
+ function declaredMethod(receiver, method, checker) {
2785
+ const root = unwrap(receiver);
2786
+ if (!import_typescript5.default.isIdentifier(root))
2787
+ return;
2788
+ let annotation;
2789
+ try {
2790
+ const declaration = checker.getSymbolAtLocation(root)?.valueDeclaration;
2791
+ if (declaration && (import_typescript5.default.isParameter(declaration) || import_typescript5.default.isVariableDeclaration(declaration) || import_typescript5.default.isPropertySignature(declaration) || import_typescript5.default.isPropertyDeclaration(declaration)))
2792
+ annotation = declaration.type;
2793
+ } catch {
2794
+ return;
2795
+ }
2796
+ const seen = new Set;
2797
+ const search = (type, depth) => {
2798
+ if (!type || depth > 4 || seen.has(type))
2799
+ return;
2800
+ seen.add(type);
2801
+ if (import_typescript5.default.isIntersectionTypeNode(type) || import_typescript5.default.isUnionTypeNode(type)) {
2802
+ for (const member of type.types) {
2803
+ const found = search(member, depth + 1);
2804
+ if (found)
2805
+ return found;
2806
+ }
2807
+ return;
2808
+ }
2809
+ if (import_typescript5.default.isParenthesizedTypeNode(type))
2810
+ return search(type.type, depth + 1);
2811
+ const members = import_typescript5.default.isTypeLiteralNode(type) ? type.members : undefined;
2812
+ if (members)
2813
+ return members.find((member) => (import_typescript5.default.isMethodSignature(member) || import_typescript5.default.isPropertySignature(member)) && propertyNameText(member.name) === method);
2814
+ if (!import_typescript5.default.isTypeReferenceNode(type))
2815
+ return;
2816
+ return fromName(type.typeName, depth);
2817
+ };
2818
+ const fromName = (name, depth) => {
2819
+ let symbol;
2820
+ try {
2821
+ symbol = checker.getSymbolAtLocation(name);
2822
+ if (symbol && symbol.flags & import_typescript5.default.SymbolFlags.Alias)
2823
+ symbol = checker.getAliasedSymbol(symbol);
2824
+ } catch {
2825
+ return;
2826
+ }
2827
+ for (const declaration of symbol?.declarations ?? []) {
2828
+ if (seen.has(declaration))
2829
+ continue;
2830
+ seen.add(declaration);
2831
+ if (import_typescript5.default.isInterfaceDeclaration(declaration)) {
2832
+ const own = declaration.members.find((member) => (import_typescript5.default.isMethodSignature(member) || import_typescript5.default.isPropertySignature(member)) && propertyNameText(member.name) === method);
2833
+ if (own)
2834
+ return own;
2835
+ for (const clause of declaration.heritageClauses ?? []) {
2836
+ for (const base of clause.types) {
2837
+ const found = fromName(base.expression, depth + 1);
2838
+ if (found)
2839
+ return found;
2840
+ }
2841
+ }
2842
+ }
2843
+ if (import_typescript5.default.isTypeAliasDeclaration(declaration)) {
2844
+ const found = search(declaration.type, depth + 1);
2845
+ if (found)
2846
+ return found;
2847
+ }
2848
+ }
2849
+ return;
2850
+ };
2851
+ return search(annotation, 0);
2852
+ }
2853
+ function hasMethod(receiver, method, ctx) {
2854
+ try {
2855
+ return Boolean(ctx.checker.getTypeAtLocation(receiver).getProperty(method));
2856
+ } catch {
2857
+ return false;
2858
+ }
2859
+ }
2767
2860
  var CHAT_HOOK_MODULE = /^(?:@ai-sdk\/(?:react|svelte|vue|angular|solid)|ai\/(?:react|svelte|vue)|agents\/(?:ai-)?react|@cloudflare\/(?:think|ai-chat|agents)\/react)$/;
2768
2861
  var CHAT_HOOKS = new Set(["useChat", "useAgentChat", "Chat", "useCompletion"]);
2769
2862
  var CHAT_SEND = new Set(["sendMessage", "append", "submitMessage", "complete"]);
@@ -2943,8 +3036,8 @@ function hookSink(memo) {
2943
3036
  const returns = returnExpressions(member);
2944
3037
  for (const [key, role] of Object.entries(TURN_CONFIG_KEYS)) {
2945
3038
  if (returns.some((ret) => {
2946
- const value = unwrap(ret);
2947
- return import_typescript5.default.isObjectLiteralExpression(value) && hasProperty(value, key);
3039
+ const value = objectLiteralOf(ret, ctx.checker);
3040
+ return value !== undefined && hasProperty(value, key);
2948
3041
  })) {
2949
3042
  roles.push({ role, node: member, values: returns, key });
2950
3043
  }
@@ -2989,7 +3082,44 @@ var hostedModelSink = {
2989
3082
  };
2990
3083
  }
2991
3084
  };
2992
- var CALL_SINKS = [anthropicSink, openaiSink, aiSdkSink, workersAiSink, fetchSink, websocketSink, providerFactorySink, agentEntrySink, clientChatSink, hostedModelSink];
3085
+ var REALTIME_SEND = /send|emit|transmit|dispatch/i;
3086
+ var realtimeEventSink = {
3087
+ id: "realtime-event",
3088
+ sdk: "realtime",
3089
+ match(call, ctx) {
3090
+ if (!import_typescript5.default.isCallExpression(call) || call.arguments.length !== 1)
3091
+ return;
3092
+ const callee = import_typescript5.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
3093
+ if (!import_typescript5.default.isIdentifier(callee) || !REALTIME_SEND.test(callee.text))
3094
+ return;
3095
+ let sent = unwrap(call.arguments[0]);
3096
+ if (import_typescript5.default.isCallExpression(sent) && sent.expression.getText() === "JSON.stringify" && sent.arguments[0])
3097
+ sent = unwrap(sent.arguments[0]);
3098
+ const argument = objectLiteralOf(sent, ctx.checker);
3099
+ if (!argument)
3100
+ return;
3101
+ const type = propertyValue(argument, "type");
3102
+ const kind = type && (import_typescript5.default.isStringLiteral(type) || import_typescript5.default.isNoSubstitutionTemplateLiteral(type)) ? type.text : undefined;
3103
+ if (kind === "session.update") {
3104
+ const session = propertyValue(argument, "session");
3105
+ const object = session ? objectLiteralOf(session, ctx.checker) : undefined;
3106
+ const instructions = object ? propertyValue(object, "instructions") : undefined;
3107
+ return instructions ? { api: "realtime.session.update", provider: "openai", roles: [{ role: "system", node: instructions }] } : undefined;
3108
+ }
3109
+ if (kind === "conversation.item.create") {
3110
+ const item = propertyValue(argument, "item");
3111
+ const object = item ? objectLiteralOf(item, ctx.checker) : undefined;
3112
+ const role = object ? propertyValue(object, "role") : undefined;
3113
+ const roleText = role && import_typescript5.default.isStringLiteral(role) ? role.text : undefined;
3114
+ const content = object ? propertyValue(object, "content") : undefined;
3115
+ if (!content || roleText !== "system" && roleText !== "user")
3116
+ return;
3117
+ return { api: "realtime.conversation.item.create", provider: "openai", roles: [{ role: roleText === "system" ? "system" : "messages", node: content }] };
3118
+ }
3119
+ return;
3120
+ }
3121
+ };
3122
+ var CALL_SINKS = [realtimeEventSink, anthropicSink, openaiSink, aiSdkSink, workersAiSink, fetchSink, websocketSink, providerFactorySink, agentEntrySink, clientChatSink, hostedModelSink];
2993
3123
  function registerCallSink(recognizer) {
2994
3124
  CALL_SINKS.push(recognizer);
2995
3125
  }
@@ -3027,7 +3157,7 @@ function normalizePath(path) {
3027
3157
  return path.replace(/\\/g, "/");
3028
3158
  }
3029
3159
  function isTextFile2(path) {
3030
- return /\.(ts|tsx|js|jsx|mjs|cjs|py|md|json|ya?ml|toml|txt|sh|rb|go|rs|swift|kt|java|cs|php|sql|graphql|gql|proto|css|scss|less|html|vue|svelte)$/i.test(path);
3160
+ return /\.(ts|tsx|js|jsx|mjs|cjs|py|md|mdx|prompt|json|ya?ml|toml|txt|sh|rb|go|rs|swift|kt|java|cs|php|sql|graphql|gql|proto|css|scss|less|html|vue|svelte)$/i.test(path);
3031
3161
  }
3032
3162
  function isSecretishPath2(path) {
3033
3163
  const normalized = normalizePath(path).toLowerCase();
@@ -3583,7 +3713,7 @@ function keyedValueConsumer(source, line, key, column) {
3583
3713
 
3584
3714
  // src/harness-candidates.ts
3585
3715
  import { mkdirSync as mkdirSync5, writeFileSync as writeFileSync5 } from "node:fs";
3586
- import { basename as basename7, dirname as dirname8, extname as extname7, resolve as resolve10 } from "node:path";
3716
+ import { basename as basename7, dirname as dirname9, extname as extname7, resolve as resolve10 } from "node:path";
3587
3717
 
3588
3718
  // src/harness.ts
3589
3719
  import { createHash as createHash7 } from "node:crypto";
@@ -3600,7 +3730,7 @@ import {
3600
3730
  writeFileSync as writeFileSync4,
3601
3731
  rmSync as rmSync4
3602
3732
  } from "node:fs";
3603
- import { basename as basename6, delimiter, dirname as dirname7, join as join11, relative as relative9, resolve as resolve9, sep as sep5 } from "node:path";
3733
+ import { basename as basename6, delimiter, dirname as dirname8, join as join11, relative as relative9, resolve as resolve9, sep as sep5 } from "node:path";
3604
3734
  import { confirm, select } from "@inquirer/prompts";
3605
3735
 
3606
3736
  // src/analyst-tui.ts
@@ -17304,7 +17434,7 @@ function promoteEvalSuites(files, confidence2, naming) {
17304
17434
 
17305
17435
  // src/harness-extract/prompts/resolver.ts
17306
17436
  var import_typescript8 = __toESM(require_typescript(), 1);
17307
- import { relative as relative8 } from "node:path";
17437
+ import { dirname as dirname7, relative as relative8, resolve as resolvePath } from "node:path";
17308
17438
  var DEFAULT_MAX_DEPTH = 24;
17309
17439
  var DEFAULT_MAX_PARAM_LEVELS = 3;
17310
17440
  var PROMPT_FIELDS = new Set([
@@ -17352,6 +17482,7 @@ var TEXT_PRESERVING_METHODS = new Set([
17352
17482
  var ARRAY_ASSEMBLY_METHODS = new Set(["join", "concat", "flat", "filter", "slice", "reverse", "sort", "toSorted"]);
17353
17483
  var CALLBACK_METHODS = new Set(["map", "flatMap", "then", "catch"]);
17354
17484
  var TEST_SOURCE = /(?:^|\/)(?:__tests__|__mocks__|fixtures?|test-fixtures)\/|(?:^|\/)[^/]*\.(?:test|spec)\.[^/]+$/i;
17485
+ var TEXT_MODULE = /\.(?:md|mdx|txt|prompt)(?:\?raw)?$/;
17355
17486
  var LOCAL_ONLY_SITE = /^(?:scripts|evals?)\//;
17356
17487
  function readsAsInstructions(text) {
17357
17488
  const plain = text.replace(/\{\{[^}]*\}\}/g, " x ");
@@ -17371,7 +17502,11 @@ function isDataWrapper(text) {
17371
17502
  `).map((line) => line.trim()).filter(Boolean);
17372
17503
  if (lines.length === 0)
17373
17504
  return true;
17374
- return lines.every((line) => (line.replace(/\{\{[^}]*\}\}/g, " ").replace(/<\/?[\w-]+>/g, " ").match(/[A-Za-z]{2,}/g) ?? []).length < 4);
17505
+ return lines.every((line) => (stripMarkup(line).match(/[A-Za-z]{2,}/g) ?? []).length < 4);
17506
+ }
17507
+ function stripMarkup(line) {
17508
+ const phrase = (value) => (value.match(/[A-Za-z]{2,}/g) ?? []).length >= 4 ? ` ${value} ` : " ";
17509
+ return line.replace(/\{\{[^}]*\}\}/g, " ").replace(/<\/?[\w-]+((?:\s+[\w-]+(?:="[^"]*")?)*)\s*\/?>/g, (_, attrs) => attrs.replace(/[\w-]+="([^"]*)"|[\w-]+/g, (_name, value) => value === undefined ? " " : phrase(value))).replace(/<\/?[\w-]+|\/?>/g, " ");
17375
17510
  }
17376
17511
  var SHORT_TEXT = 300;
17377
17512
  var DIRECTIVE_ANYWHERE = /\b(?:you(?! were)|must|should|do not|don't|never|always|only|avoid|make sure|ensure|instead)\b/i;
@@ -17542,7 +17677,7 @@ class PromptResolver {
17542
17677
  };
17543
17678
  });
17544
17679
  return {
17545
- refs: refs.filter((ref) => this.keepAll || readsAsInstructions(ref.text) && !isDataWrapper(ref.text) && (ref.text.length >= SHORT_TEXT || ref.role === "questions" || ref.role === "tool-description" || hasDirective(ref.text)) && (ref.role !== "tool-description" || isInstructionDescription(ref.text))),
17680
+ refs: refs.filter((ref) => this.keepAll || ref.kind === "file" || readsAsInstructions(ref.text) && !isDataWrapper(ref.text) && (ref.text.length >= SHORT_TEXT || ref.role === "questions" || ref.role === "tool-description" || hasDirective(ref.text)) && (ref.role !== "tool-description" || isInstructionDescription(ref.text))),
17546
17681
  unresolved: [...this.unresolved.values()]
17547
17682
  };
17548
17683
  }
@@ -17617,6 +17752,10 @@ class PromptResolver {
17617
17752
  }
17618
17753
  if (import_typescript8.default.isArrowFunction(expr) || import_typescript8.default.isFunctionExpression(expr)) {
17619
17754
  this.builderBody(expr, { node: expr, name: owner?.name, kind: "builder" }, walk);
17755
+ return;
17756
+ }
17757
+ if ((import_typescript8.default.isMethodDeclaration(expr) || import_typescript8.default.isGetAccessorDeclaration(expr) || import_typescript8.default.isFunctionDeclaration(expr)) && expr.body) {
17758
+ this.builderBody(expr, { node: expr, name: declarationName(expr), kind: "builder" }, walk);
17620
17759
  }
17621
17760
  }
17622
17761
  objectValue(object, walk) {
@@ -17663,6 +17802,8 @@ class PromptResolver {
17663
17802
  this.value(property.initializer, { node: property, name: role ? undefined : key, kind }, this.messageRole(inner, role));
17664
17803
  } else if (import_typescript8.default.isShorthandPropertyAssignment(property)) {
17665
17804
  this.identifier(property.name, undefined, inner);
17805
+ } else if (import_typescript8.default.isMethodDeclaration(property) || import_typescript8.default.isGetAccessorDeclaration(property)) {
17806
+ this.builderBody(property, { node: property, name: key, kind: "builder" }, this.messageRole(inner, role));
17666
17807
  }
17667
17808
  }
17668
17809
  }
@@ -17674,6 +17815,11 @@ class PromptResolver {
17674
17815
  identifier(identifier, owner, walk) {
17675
17816
  if (identifier.text === "undefined")
17676
17817
  return;
17818
+ const file = this.importedTextFile(identifier);
17819
+ if (file) {
17820
+ this.fileRef(file, walk);
17821
+ return;
17822
+ }
17677
17823
  const declarations = this.declarationsOf(identifier);
17678
17824
  if (declarations.length === 0) {
17679
17825
  this.markUnresolved(identifier, "external", walk);
@@ -17956,11 +18102,19 @@ class PromptResolver {
17956
18102
  this.indexCallers();
17957
18103
  const names = [name, ...this.aliasesByName.get(name) ?? []];
17958
18104
  const candidates = names.flatMap((alias) => this.callersByName.get(alias) ?? []);
18105
+ const signatures = this.implementedSignatures(fn, name);
17959
18106
  return candidates.filter((call) => {
17960
18107
  const callee = import_typescript8.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
17961
- return this.declarationsOf(callee).some((declaration) => functionOf(declaration) === fn || declaration === fn);
18108
+ return this.declarationsOf(callee).some((declaration) => functionOf(declaration) === fn || declaration === fn || signatures.has(declaration));
17962
18109
  });
17963
18110
  }
18111
+ implementedSignatures(fn, name) {
18112
+ if (!import_typescript8.default.isMethodDeclaration(fn) || !import_typescript8.default.isObjectLiteralExpression(fn.parent))
18113
+ return new Set;
18114
+ const checker = this.context.checkerFor(this.relative(fn.getSourceFile().fileName));
18115
+ const property = checker?.getContextualType(fn.parent)?.getProperty(name);
18116
+ return new Set((property?.declarations ?? []).filter(import_typescript8.default.isMethodSignature));
18117
+ }
17964
18118
  sourceFiles() {
17965
18119
  const byName = new Map;
17966
18120
  for (const program of this.context.programs) {
@@ -18099,6 +18253,30 @@ class PromptResolver {
18099
18253
  ref.via = ref.via.filter((f) => walk.flags.includes(f));
18100
18254
  ref.pieces.set(at.getStart(sf), text);
18101
18255
  }
18256
+ importedTextFile(identifier) {
18257
+ const checker = this.context.checkerFor(this.relative(identifier.getSourceFile().fileName));
18258
+ const clause = checker?.getSymbolAtLocation(identifier)?.declarations?.find(import_typescript8.default.isImportClause);
18259
+ const statement = clause?.parent;
18260
+ if (!statement || !import_typescript8.default.isStringLiteral(statement.moduleSpecifier))
18261
+ return;
18262
+ const spec = statement.moduleSpecifier.text;
18263
+ if (!TEXT_MODULE.test(spec) || !spec.startsWith("."))
18264
+ return;
18265
+ return this.relative(resolvePath(dirname7(statement.getSourceFile().fileName), spec.replace(/\?raw$/, "")));
18266
+ }
18267
+ fileRef(path, walk) {
18268
+ if (TEST_SOURCE.test(path))
18269
+ return;
18270
+ const id = path;
18271
+ let ref = this.refs.get(id);
18272
+ if (!ref) {
18273
+ ref = { id, path, line: 1, endLine: 1, start: 0, kind: "file", role: walk.role, text: "", callSiteIds: [], hops: walk.hops, via: [...walk.flags], pieces: new Map };
18274
+ this.refs.set(id, ref);
18275
+ }
18276
+ if (!ref.callSiteIds.includes(walk.site.id))
18277
+ ref.callSiteIds.push(walk.site.id);
18278
+ ref.via = ref.via.filter((f) => walk.flags.includes(f));
18279
+ }
18102
18280
  markUnresolved(node, reason, walk) {
18103
18281
  const sf = node.getSourceFile();
18104
18282
  const path = this.relative(sf.fileName);
@@ -18331,6 +18509,20 @@ function refArtifact(ref, sites, agentForScope, toolAgents = new Map) {
18331
18509
  const direct = ref.via.length === 0;
18332
18510
  const where = `${ref.path}:${ref.line}`;
18333
18511
  const reach = first2 ? `${first2.callee} at ${first2.path}:${first2.line}` : "a model call";
18512
+ if (ref.kind === "file") {
18513
+ return {
18514
+ id: stableId("prompt", ref.path),
18515
+ type: "prompt",
18516
+ name: promptNameFromPath(ref.path),
18517
+ scope: agentIds.length === 1 ? "agent" : "shared",
18518
+ ...agentIds.length === 1 ? { ownedByAgentId: agentIds[0] } : {},
18519
+ usedByAgentIds: agentIds,
18520
+ sourcePath: ref.path,
18521
+ confidence: DIRECT_PROMPT_CONFIDENCE,
18522
+ confidenceReason: `Call site: prompt file ${ref.path} is imported and passed to ${reach} as ${ref.role}.`,
18523
+ evidence
18524
+ };
18525
+ }
18334
18526
  return {
18335
18527
  id: stableId("prompt", `${ref.path.replace(/\.[^.]+$/, "")}:L${ref.line}${ref.column ? `C${ref.column}` : ""}`),
18336
18528
  type: "prompt",
@@ -18719,7 +18911,7 @@ async function runHarnessCommand(context) {
18719
18911
  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.");
18720
18912
  }
18721
18913
  if (context.flags["github-actions"] === "true") {
18722
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-g0tmyctn.js");
18914
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-ed8ncma3.js");
18723
18915
  const result = await runGithubActionsAnalyze(rootDir, {
18724
18916
  writeReport: (report2) => {
18725
18917
  const normalized = normalizeHarnessReport(report2);
@@ -18869,7 +19061,7 @@ async function runHarnessCommand(context) {
18869
19061
  const promoteWritten = [];
18870
19062
  if (promoteOut && !context.dryRun) {
18871
19063
  const target = resolve9(context.cwd, promoteOut);
18872
- mkdirSync4(dirname7(target), { recursive: true });
19064
+ mkdirSync4(dirname8(target), { recursive: true });
18873
19065
  writeFileSync4(target, `${JSON.stringify(promoted, null, 2)}
18874
19066
  `, "utf8");
18875
19067
  promoteWritten.push(target);
@@ -18892,7 +19084,7 @@ async function runHarnessCommand(context) {
18892
19084
  }
18893
19085
  case "extract": {
18894
19086
  writeHumanProgress(context, "Harness extract: tracing model call sites (no LLM, no network)...");
18895
- const { extractHarness: extractHarness2, serializeExtractResult } = await import("./index-c9c01ayp.js");
19087
+ const { extractHarness: extractHarness2, serializeExtractResult } = await import("./index-s1agk3km.js");
18896
19088
  const result = extractHarness2(rootDir, { fresh: true });
18897
19089
  writeHumanProgress(context, `Harness extract: ${result.callSites.length} call sites, ${result.roles.length} traced roles across ${result.files} files (${result.programs} programs, ${result.durationMs.toLocaleString()} ms).`);
18898
19090
  context.output.writeData(serializeExtractResult(result), {
@@ -19332,7 +19524,7 @@ function readExternalAnalystReport(rootDir, result, adapter, concern) {
19332
19524
  let debugHint = "";
19333
19525
  try {
19334
19526
  const debugPath = resolve9(rootDir, MODA_DIR, "analyst-debug.log");
19335
- mkdirSync4(dirname7(debugPath), { recursive: true });
19527
+ mkdirSync4(dirname8(debugPath), { recursive: true });
19336
19528
  writeFileSync4(debugPath, [
19337
19529
  `# analyst=${adapter} status=${result.status} signal=${result.signal} timedOut=${result.timedOut} maxBufferExceeded=${result.maxBufferExceeded}`,
19338
19530
  "# ----- stdout -----",
@@ -20639,7 +20831,7 @@ function resolveExternalHarnessAnalystInvocation(options) {
20639
20831
  };
20640
20832
  }
20641
20833
  function createPromptAnalystIsolation(adapter, rootDir) {
20642
- const moduleDir = dirname7(fileURLToPath(import.meta.url));
20834
+ const moduleDir = dirname8(fileURLToPath(import.meta.url));
20643
20835
  const bundled = resolve9(moduleDir, "prompt-source-mcp.js");
20644
20836
  const source = resolve9(moduleDir, "prompt-source-mcp.ts");
20645
20837
  const bundledServer = existsSync8(bundled);
@@ -21533,7 +21725,7 @@ async function syncHarnessWithRemote(context, body) {
21533
21725
  }
21534
21726
  function writeHarnessSyncState(rootDir, state) {
21535
21727
  const path = join11(rootDir, SYNC_STATE_PATH);
21536
- mkdirSync4(dirname7(path), { recursive: true });
21728
+ mkdirSync4(dirname8(path), { recursive: true });
21537
21729
  writeFileSync4(path, `${JSON.stringify(state, null, 2)}
21538
21730
  `);
21539
21731
  return SYNC_STATE_PATH;
@@ -21651,7 +21843,7 @@ function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
21651
21843
  if (fresher.length === 0)
21652
21844
  return;
21653
21845
  const newest = fresher[0];
21654
- const subdir = normalizePath2(dirname7(dirname7(newest.path)));
21846
+ const subdir = normalizePath2(dirname8(dirname8(newest.path)));
21655
21847
  const rootState = existsSync8(join11(rootDir, HARNESS_REPORT_PATH)) ? `older ${HARNESS_REPORT_PATH}` : `no ${HARNESS_REPORT_PATH}`;
21656
21848
  writeHarnessNotice(context, `A fresher harness report exists at ${newest.path} (this directory has ${rootState}). If you meant that report, re-run with --path=${subdir}.`);
21657
21849
  }
@@ -21672,7 +21864,7 @@ function writeHarnessArtifacts(graph, rootDir, options = {}) {
21672
21864
  }
21673
21865
  function writeHarnessSummary(graph, rootDir) {
21674
21866
  const summaryPath = join11(rootDir, HARNESS_SUMMARY_PATH);
21675
- mkdirSync4(dirname7(summaryPath), { recursive: true });
21867
+ mkdirSync4(dirname8(summaryPath), { recursive: true });
21676
21868
  writeFileSync4(summaryPath, renderHarnessMarkdown(graph));
21677
21869
  return HARNESS_SUMMARY_PATH;
21678
21870
  }
@@ -22062,7 +22254,7 @@ function runtimeAgentFromAnnotation(annotation) {
22062
22254
  kind: "runtime_agent",
22063
22255
  purpose: first2(values.purpose) ?? first2(values.description),
22064
22256
  familyId: first2(values.family),
22065
- root: normalizePath2(first2(values.root) ?? dirname7(annotation.evidence.path)),
22257
+ root: normalizePath2(first2(values.root) ?? dirname8(annotation.evidence.path)),
22066
22258
  entrypointIds: values.entrypoint ?? [stableId("entry", annotation.evidence.path)],
22067
22259
  channelAdapterIds: values.channel ?? [],
22068
22260
  artifactIds: [...values.artifact ?? [], ...values.prompt ?? [], ...values.tool ?? []],
@@ -22298,7 +22490,7 @@ function inferRuntimeAgent(file, graph) {
22298
22490
  name: titleFromId(file.path.replace(/\.(ts|tsx|js|mjs|py)$/i, "")),
22299
22491
  kind: "runtime_agent",
22300
22492
  purpose: inferAgentPurpose(file),
22301
- root: normalizePath2(dirname7(file.path)),
22493
+ root: normalizePath2(dirname8(file.path)),
22302
22494
  entrypointIds: [entryId],
22303
22495
  channelAdapterIds: channelIds,
22304
22496
  artifactIds,
@@ -23897,7 +24089,7 @@ function detectPromptFile(file, out) {
23897
24089
  return;
23898
24090
  if (/(^|\/)(docs?|documentation|examples?|\.github)\//i.test(file.path))
23899
24091
  return;
23900
- const dir = dirname8(file.path);
24092
+ const dir = dirname9(file.path);
23901
24093
  const nameHint = PROMPT_NAME_HINT.test(base);
23902
24094
  const dirHint = AGENTIC_DIR_HINT.test(dir);
23903
24095
  const score = instructionScore(file.text.slice(0, 20000));
@@ -23960,7 +24152,7 @@ function detectPromptLoaderReferences(file, filesByPath, out) {
23960
24152
  function normalizeLoaderTarget(sourcePath, reference) {
23961
24153
  if (reference.startsWith("/"))
23962
24154
  return;
23963
- const parts = [...dirname8(sourcePath).split("/"), ...reference.split("/")];
24155
+ const parts = [...dirname9(sourcePath).split("/"), ...reference.split("/")];
23964
24156
  const normalized = [];
23965
24157
  for (const part of parts) {
23966
24158
  if (!part || part === ".")
@@ -24041,7 +24233,7 @@ function detectHarnessCandidates(rootDir) {
24041
24233
  }
24042
24234
  function writeHarnessCandidatesReport(report, outPath) {
24043
24235
  const target = resolve10(outPath);
24044
- mkdirSync5(dirname8(target), { recursive: true });
24236
+ mkdirSync5(dirname9(target), { recursive: true });
24045
24237
  writeFileSync5(target, `${JSON.stringify(report, null, 2)}
24046
24238
  `, "utf8");
24047
24239
  return target;
package/dist/cli.js CHANGED
@@ -2975,25 +2975,25 @@ function leafManifestFields(leaf, commands) {
2975
2975
  import { fileURLToPath } from "url";
2976
2976
  import { realpathSync } from "fs";
2977
2977
  async function runPromptsCommand(...args) {
2978
- return (await import("./prompts-82tfn871.js")).runPromptsCommand(...args);
2978
+ return (await import("./prompts-6gv5qqp6.js")).runPromptsCommand(...args);
2979
2979
  }
2980
2980
  async function runSkillsCommand(...args) {
2981
2981
  return (await import("./skills-c25dmy28.js")).runSkillsCommand(...args);
2982
2982
  }
2983
2983
  async function runHarnessCommand(...args) {
2984
- return (await import("./harness-djtzm1c5.js")).runHarnessCommand(...args);
2984
+ return (await import("./harness-zbxfgaer.js")).runHarnessCommand(...args);
2985
2985
  }
2986
2986
  async function runSyncCommand(...args) {
2987
- return (await import("./sync-0cpxcrtd.js")).runSyncCommand(...args);
2987
+ return (await import("./sync-q549frt7.js")).runSyncCommand(...args);
2988
2988
  }
2989
2989
  async function runRegistryCommand(...args) {
2990
2990
  return (await import("./registry-ztn727mn.js")).runRegistryCommand(...args);
2991
2991
  }
2992
2992
  async function runDoctorCommand(...args) {
2993
- return (await import("./doctor-m9tg540h.js")).runDoctorCommand(...args);
2993
+ return (await import("./doctor-zzxmt09g.js")).runDoctorCommand(...args);
2994
2994
  }
2995
2995
  async function runStatusCommand(...args) {
2996
- return (await import("./doctor-m9tg540h.js")).runStatusCommand(...args);
2996
+ return (await import("./doctor-zzxmt09g.js")).runStatusCommand(...args);
2997
2997
  }
2998
2998
  async function runAuthCommand(...args) {
2999
2999
  return (await import("./profile-commands-fa2858ez.js")).runAuthCommand(...args);
@@ -3005,7 +3005,7 @@ async function runProfilesCommand(...args) {
3005
3005
  return (await import("./profile-commands-fa2858ez.js")).runProfilesCommand(...args);
3006
3006
  }
3007
3007
  async function runAgentCommand(...args) {
3008
- return (await import("./agent-vep29dgt.js")).runAgentCommand(...args);
3008
+ return (await import("./agent-grf8tb4m.js")).runAgentCommand(...args);
3009
3009
  }
3010
3010
  async function runProductionCommand(...args) {
3011
3011
  return (await import("./production-intelligence-40teyxyv.js")).runProductionCommand(...args);
@@ -6769,7 +6769,7 @@ var commandRegistry = createCommandRegistry([
6769
6769
  resetApiRequestCountBeforeRun: true,
6770
6770
  telemetry: "result-and-error",
6771
6771
  handler: async (context) => {
6772
- const { runInit } = await import("./index-beap2kft.js");
6772
+ const { runInit } = await import("./index-x0knnchy.js");
6773
6773
  if (context.outputMode === "agent-stream") {
6774
6774
  context.output.writeEvent({
6775
6775
  event: "started",
@@ -3,9 +3,9 @@ import {
3
3
  promptsDiscoveredCheck,
4
4
  runDoctorCommand,
5
5
  runStatusCommand
6
- } from "./cli-k5zerb77.js";
6
+ } from "./cli-45m0bz7q.js";
7
7
  import"./cli-27kkk5z4.js";
8
- import"./cli-0hhje3n9.js";
8
+ import"./cli-67sp41tx.js";
9
9
  import"./cli-mm48br00.js";
10
10
  import"./cli-k0vxtzxb.js";
11
11
  import"./cli-m702wdtv.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildSourceSnapshot
3
- } from "./cli-3hkwxecd.js";
3
+ } from "./cli-bwzvsmwk.js";
4
4
  import"./cli-k0vxtzxb.js";
5
5
  import"./cli-97fnztpy.js";
6
6
  import"./cli-9ww72mrd.js";
@@ -46,7 +46,7 @@ import {
46
46
  writeHarnessAnalyzeResult,
47
47
  writeHarnessArtifacts,
48
48
  writeHumanProgress
49
- } from "./cli-3hkwxecd.js";
49
+ } from "./cli-bwzvsmwk.js";
50
50
  import"./cli-k0vxtzxb.js";
51
51
  import"./cli-97fnztpy.js";
52
52
  import {
@@ -19,7 +19,7 @@ import {
19
19
  serializeExtractResult,
20
20
  toolNamesOf,
21
21
  valueChildren
22
- } from "./cli-3hkwxecd.js";
22
+ } from "./cli-bwzvsmwk.js";
23
23
  import"./cli-k0vxtzxb.js";
24
24
  import"./cli-97fnztpy.js";
25
25
  import"./cli-9ww72mrd.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildDoctorReport
3
- } from "./cli-k5zerb77.js";
3
+ } from "./cli-45m0bz7q.js";
4
4
  import {
5
5
  selectTenantAndCreateKey
6
6
  } from "./cli-rdwy3y4f.js";
@@ -20,7 +20,7 @@ import {
20
20
  import {
21
21
  initPrompts,
22
22
  runPromptSync
23
- } from "./cli-0hhje3n9.js";
23
+ } from "./cli-67sp41tx.js";
24
24
  import {
25
25
  agentsMdProblem,
26
26
  runSkillSync
@@ -46,7 +46,7 @@ import {
46
46
  runCodingAgent,
47
47
  runHarnessCommand,
48
48
  startRemoteAnalyze
49
- } from "./cli-3hkwxecd.js";
49
+ } from "./cli-bwzvsmwk.js";
50
50
  import {
51
51
  canonicalText,
52
52
  renderInitBanner,
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  inventoryFiles,
3
3
  safePromptEvidencePath
4
- } from "./cli-3hkwxecd.js";
4
+ } from "./cli-bwzvsmwk.js";
5
5
  import"./cli-k0vxtzxb.js";
6
6
  import"./cli-97fnztpy.js";
7
7
  import"./cli-9ww72mrd.js";
@@ -3,7 +3,7 @@ import {
3
3
  checkPromptMapping,
4
4
  discoverHarnessPromptSources,
5
5
  safePromptEvidencePath
6
- } from "./cli-3hkwxecd.js";
6
+ } from "./cli-bwzvsmwk.js";
7
7
  import"./cli-k0vxtzxb.js";
8
8
  import"./cli-97fnztpy.js";
9
9
  import"./cli-9ww72mrd.js";
@@ -9,7 +9,7 @@ import {
9
9
  runPromptSync,
10
10
  runPromptsCommand,
11
11
  writePromptSyncProgress
12
- } from "./cli-0hhje3n9.js";
12
+ } from "./cli-67sp41tx.js";
13
13
  import {
14
14
  promptSourceHashPayload
15
15
  } from "./cli-mm48br00.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  runPromptsCommand
3
- } from "./cli-0hhje3n9.js";
3
+ } from "./cli-67sp41tx.js";
4
4
  import {
5
5
  runSkillsCommand
6
6
  } from "./cli-p2tfx93b.js";
@@ -10,7 +10,7 @@ import"./cli-hcwdz9sd.js";
10
10
  import"./cli-mm48br00.js";
11
11
  import {
12
12
  runHarnessCommand
13
- } from "./cli-3hkwxecd.js";
13
+ } from "./cli-bwzvsmwk.js";
14
14
  import"./cli-k0vxtzxb.js";
15
15
  import"./cli-97fnztpy.js";
16
16
  import"./cli-9ww72mrd.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moda-ai/cli",
3
- "version": "1.55.68",
3
+ "version": "1.55.69",
4
4
  "description": "CLI for Moda: production monitoring and evals for AI agents.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "schema_version": "moda.skill_index.v1",
3
- "bundled_at": "2026-10-21T06:24:28.685Z",
4
- "cli_version": "1.55.68",
3
+ "bundled_at": "2026-10-21T06:32:22.959Z",
4
+ "cli_version": "1.55.69",
5
5
  "skills": [
6
6
  {
7
7
  "id": "integration-cloudflare-think",