@moda-ai/cli 1.55.62 → 1.55.64

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.
@@ -29,7 +29,7 @@ import {
29
29
  stampRemoteSnapshotTruncation,
30
30
  validateHarnessReport,
31
31
  writeHarnessReportArtifacts
32
- } from "./cli-kmq9pgef.js";
32
+ } from "./cli-1fcx3eyn.js";
33
33
  import {
34
34
  createCommandContext,
35
35
  stringOption
@@ -94,6 +94,9 @@ import {
94
94
  redactDeep,
95
95
  shouldInventoryFile
96
96
  } from "./cli-9a4b1wxz.js";
97
+ import {
98
+ extractHarnessWithContext
99
+ } from "./cli-vqhaj5tv.js";
97
100
  import {
98
101
  mergeBoundRuntimeClasses,
99
102
  tagComponentStatus
@@ -121,7 +124,7 @@ import {
121
124
  writeFileSync as writeFileSync5,
122
125
  rmSync as rmSync4
123
126
  } from "node:fs";
124
- import { basename as basename7, delimiter, dirname as dirname7, join as join9, relative as relative6, resolve as resolve10, sep as sep5 } from "node:path";
127
+ import { basename as basename7, delimiter, dirname as dirname7, join as join9, relative as relative7, resolve as resolve10, sep as sep5 } from "node:path";
125
128
  import { confirm, select } from "@inquirer/prompts";
126
129
 
127
130
  // src/analyst-tui.ts
@@ -15470,6 +15473,1092 @@ function promoteAll(report, rootDir) {
15470
15473
  return [...byId.values()];
15471
15474
  }
15472
15475
 
15476
+ // src/harness-extract/prompts/resolver.ts
15477
+ var import_typescript3 = __toESM(require_typescript(), 1);
15478
+ import { relative as relative6 } from "node:path";
15479
+ var DEFAULT_MAX_DEPTH = 24;
15480
+ var DEFAULT_MAX_PARAM_LEVELS = 3;
15481
+ var PROMPT_FIELDS = new Set([
15482
+ "content",
15483
+ "text",
15484
+ "system",
15485
+ "prompt",
15486
+ "instructions",
15487
+ "instruction",
15488
+ "systemPrompt",
15489
+ "system_prompt",
15490
+ "systemMessage",
15491
+ "system_message",
15492
+ "systemInstruction",
15493
+ "system_instruction",
15494
+ "messages",
15495
+ "user",
15496
+ "question",
15497
+ "questions",
15498
+ "task",
15499
+ "brief",
15500
+ "criteria",
15501
+ "rubric",
15502
+ "template",
15503
+ "backstory",
15504
+ "goal",
15505
+ "provider",
15506
+ "get",
15507
+ "render"
15508
+ ]);
15509
+ var PROMPT_FIELD_NAME = /(?:prompt|instructions?|system|brief|intent|task|questions?|directive|guidance|rules?|context|section|block|persona|role|criteria|rubric|template|content|text|preamble|framing|nudge|reminder|policy)$/i;
15510
+ var TEXT_PRESERVING_METHODS = new Set([
15511
+ "trim",
15512
+ "trimStart",
15513
+ "trimEnd",
15514
+ "replace",
15515
+ "replaceAll",
15516
+ "concat",
15517
+ "slice",
15518
+ "toString",
15519
+ "normalize",
15520
+ "padEnd",
15521
+ "padStart"
15522
+ ]);
15523
+ var ARRAY_ASSEMBLY_METHODS = new Set(["join", "concat", "flat", "filter", "slice", "reverse", "sort", "toSorted"]);
15524
+ var CALLBACK_METHODS = new Set(["map", "flatMap", "then", "catch"]);
15525
+ var TEST_SOURCE = /(?:^|\/)(?:__tests__|__mocks__|fixtures?|test-fixtures)\/|(?:^|\/)[^/]*\.(?:test|spec)\.[^/]+$/i;
15526
+ var LOCAL_ONLY_SITE = /^(?:scripts|evals?)\//;
15527
+ function readsAsInstructions2(text) {
15528
+ const plain = text.replace(/\{\{[^}]*\}\}/g, " x ");
15529
+ if (/^\s*(?:SELECT|WITH|INSERT|UPDATE|DELETE|CREATE|ALTER)\b/i.test(plain))
15530
+ return false;
15531
+ if (/^\s*(?:https?:\/\/|\/[\w-]+\/)\S*\s*$/.test(plain))
15532
+ return false;
15533
+ if (/^[\s\w,.()'"=]+$/.test(plain) && (plain.match(/,/g) ?? []).length >= 3 && !/[.!?:]\s/.test(plain))
15534
+ return false;
15535
+ if ((plain.match(/[{};=]/g) ?? []).length > plain.length / 25)
15536
+ return false;
15537
+ const words = plain.match(/[A-Za-z]{2,}/g) ?? [];
15538
+ return words.length >= 6 && /\s/.test(plain.trim());
15539
+ }
15540
+ function isDataWrapper(text) {
15541
+ const lines = text.split(`
15542
+ `).map((line) => line.trim()).filter(Boolean);
15543
+ if (lines.length === 0)
15544
+ return true;
15545
+ return lines.every((line) => (line.replace(/\{\{[^}]*\}\}/g, " ").replace(/<\/?[\w-]+>/g, " ").match(/[A-Za-z]{2,}/g) ?? []).length < 4);
15546
+ }
15547
+ var SHORT_TEXT = 300;
15548
+ var DIRECTIVE_ANYWHERE = /\b(?:you(?! were)|must|should|do not|don't|never|always|only|avoid|make sure|ensure|instead)\b/i;
15549
+ var DIRECTIVE_VERB = /(?:^|[.!?:;\n]\s*|\]\s*)(?:keep|write|reply|respond|return|answer|use|include|output|list|describe|summari[sz]e|explain|decide|pick|choose|rate|score|classify|label|extract|generate|draft|revise|rewrite|translate|tell|ask|call|check|verify|follow|format|limit|stop|continue|focus|consider|act|identify|compare|judge|review|repair|fix|plan|propose|suggest|recommend|find|search|read|treat|cite|flag|mark|rank|group|merge|drop|skip|wait|confirm)\b/i;
15550
+ function hasDirective(text) {
15551
+ const plain = text.replace(/\{\{[^}]*\}\}/g, " ").trim();
15552
+ return DIRECTIVE_ANYWHERE.test(plain) || DIRECTIVE_VERB.test(plain);
15553
+ }
15554
+ function isInstructionDescription(text) {
15555
+ if (text.length >= 2000)
15556
+ return true;
15557
+ if (text.length < 600)
15558
+ return false;
15559
+ return /\b(?:you must|always|never|do not|don't|only (?:use|call)|use this (?:tool|when)|call this (?:tool|when|before|after)|before (?:calling|using)|when to use)\b/i.test(text);
15560
+ }
15561
+ function toolDefinitionSite(tool) {
15562
+ return {
15563
+ id: `tool:${tool.toolId}`,
15564
+ path: tool.definition.path,
15565
+ line: tool.definition.line,
15566
+ col: 1,
15567
+ callee: tool.name,
15568
+ sdk: "tool-definition",
15569
+ language: "ts",
15570
+ scope: tool.scope,
15571
+ promptArgs: [],
15572
+ isTest: false,
15573
+ isEval: false
15574
+ };
15575
+ }
15576
+ function resolvePromptArguments(callSites, context, options = {}) {
15577
+ const resolver = new PromptResolver(context, options);
15578
+ for (const tool of options.toolDefinitions ?? []) {
15579
+ const node = nodeOf(tool.definition, context);
15580
+ if (node)
15581
+ resolver.resolveTools(toolDefinitionSite(tool), node);
15582
+ }
15583
+ for (const site of callSites) {
15584
+ if (!/\.[cm]?[jt]sx?$/.test(site.path))
15585
+ continue;
15586
+ for (const { role, arg } of site.promptArgs) {
15587
+ const node = nodeOf(arg, context);
15588
+ if (!node)
15589
+ continue;
15590
+ resolver.resolveArgument(site, role, node, arg.key ? arg.key.split(".") : []);
15591
+ }
15592
+ const tools = site.toolsArg ? nodeOf(site.toolsArg, context) : undefined;
15593
+ if (tools)
15594
+ resolver.resolveTools(site, tools);
15595
+ }
15596
+ return resolver.result();
15597
+ }
15598
+
15599
+ class PromptResolver {
15600
+ context;
15601
+ refs = new Map;
15602
+ unresolved = new Map;
15603
+ maxDepth;
15604
+ maxParamLevels;
15605
+ keepAll;
15606
+ callersByName = new Map;
15607
+ aliasesByName = new Map;
15608
+ callersIndexed = false;
15609
+ methodIndex;
15610
+ constructor(context, options) {
15611
+ this.context = context;
15612
+ this.maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;
15613
+ this.maxParamLevels = options.maxParamLevels ?? DEFAULT_MAX_PARAM_LEVELS;
15614
+ this.keepAll = options.keepAll === true;
15615
+ }
15616
+ resolveArgument(site, role, node, project = []) {
15617
+ const walk = { site, role, depth: 0, paramLevels: 0, bindings: new Map, hops: [], seen: new Set, project, flags: [] };
15618
+ this.value(node, undefined, walk);
15619
+ }
15620
+ resolveTools(site, node) {
15621
+ const walk = { site, role: "tool-description", depth: 0, paramLevels: 0, bindings: new Map, hops: [], seen: new Set, project: [], flags: [] };
15622
+ this.toolDefinitions(node, walk, 0, new Set);
15623
+ }
15624
+ toolDefinitions(node, walk, depth, seen) {
15625
+ if (depth > 8 || seen.has(node))
15626
+ return;
15627
+ seen.add(node);
15628
+ const expr = unwrap(node);
15629
+ if (import_typescript3.default.isArrayLiteralExpression(expr)) {
15630
+ for (const element of expr.elements)
15631
+ this.toolDefinitions(import_typescript3.default.isSpreadElement(element) ? element.expression : element, walk, depth + 1, seen);
15632
+ return;
15633
+ }
15634
+ if (import_typescript3.default.isObjectLiteralExpression(expr)) {
15635
+ const description = expr.properties.find((p2) => propertyName(p2) === "description");
15636
+ const handler = expr.properties.find((p2) => /^(?:execute|handler|run|invoke|call|func)$/.test(propertyName(p2) ?? ""));
15637
+ if (description || handler) {
15638
+ if (description && import_typescript3.default.isPropertyAssignment(description)) {
15639
+ this.value(description.initializer, { node: description, name: toolName(expr) ? `${toolName(expr)} description` : "description", kind: "literal" }, walk);
15640
+ }
15641
+ if (handler) {
15642
+ const fn = import_typescript3.default.isPropertyAssignment(handler) ? unwrap(handler.initializer) : handler;
15643
+ const resultWalk = { ...walk, role: "tool-result", namedOnly: true };
15644
+ if (import_typescript3.default.isArrowFunction(fn) || import_typescript3.default.isFunctionExpression(fn) || import_typescript3.default.isMethodDeclaration(fn))
15645
+ this.builderBody(fn, { node: fn, kind: "builder" }, resultWalk);
15646
+ else
15647
+ this.value(fn, undefined, resultWalk);
15648
+ }
15649
+ return;
15650
+ }
15651
+ for (const property of expr.properties) {
15652
+ if (import_typescript3.default.isPropertyAssignment(property))
15653
+ this.toolDefinitions(property.initializer, walk, depth + 1, seen);
15654
+ else if (import_typescript3.default.isShorthandPropertyAssignment(property))
15655
+ this.toolDefinitions(property.name, walk, depth + 1, seen);
15656
+ else if (import_typescript3.default.isSpreadAssignment(property))
15657
+ this.toolDefinitions(property.expression, walk, depth + 1, seen);
15658
+ }
15659
+ return;
15660
+ }
15661
+ if (import_typescript3.default.isIdentifier(expr) || import_typescript3.default.isPropertyAccessExpression(expr)) {
15662
+ for (const declaration of this.declarationsOf(import_typescript3.default.isPropertyAccessExpression(expr) ? expr.name : expr)) {
15663
+ const init = import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) ? declaration.initializer : undefined;
15664
+ if (init)
15665
+ this.toolDefinitions(init, walk, depth + 1, seen);
15666
+ const fn = functionOf(declaration);
15667
+ if (fn?.body)
15668
+ this.returnsOf(fn, (value) => this.toolDefinitions(value, walk, depth + 1, seen));
15669
+ }
15670
+ return;
15671
+ }
15672
+ if (import_typescript3.default.isCallExpression(expr)) {
15673
+ const callee = import_typescript3.default.isPropertyAccessExpression(expr.expression) ? expr.expression.name : expr.expression;
15674
+ const fns = this.declarationsOf(callee).map(functionOf).filter((fn) => fn?.body);
15675
+ if (fns.length > 0)
15676
+ for (const fn of fns)
15677
+ this.returnsOf(fn, (value) => this.toolDefinitions(value, walk, depth + 1, seen));
15678
+ for (const argument of expr.arguments)
15679
+ this.toolDefinitions(argument, walk, depth + 1, seen);
15680
+ }
15681
+ }
15682
+ returnsOf(fn, each) {
15683
+ const body = fn.body;
15684
+ if (!body)
15685
+ return;
15686
+ if (!import_typescript3.default.isBlock(body)) {
15687
+ each(body);
15688
+ return;
15689
+ }
15690
+ const visit = (node) => {
15691
+ if (node !== fn && import_typescript3.default.isFunctionLike(node))
15692
+ return;
15693
+ if (import_typescript3.default.isReturnStatement(node) && node.expression)
15694
+ each(node.expression);
15695
+ import_typescript3.default.forEachChild(node, visit);
15696
+ };
15697
+ visit(body);
15698
+ }
15699
+ result() {
15700
+ const firstOnLine = new Map;
15701
+ for (const ref of this.refs.values()) {
15702
+ const line = `${ref.path}:${ref.line}`;
15703
+ firstOnLine.set(line, Math.min(firstOnLine.get(line) ?? Infinity, ref.start));
15704
+ }
15705
+ const refs = [...this.refs.values()].map(({ pieces, start, ...ref }) => {
15706
+ const later = start > firstOnLine.get(`${ref.path}:${ref.line}`);
15707
+ const column = later ? this.columnOf(ref.path, start) : undefined;
15708
+ return {
15709
+ ...ref,
15710
+ ...column ? { id: `${ref.id}:${column}`, column } : {},
15711
+ text: [...pieces.entries()].sort((a, b) => a[0] - b[0]).map(([, text]) => text).join(`
15712
+ `)
15713
+ };
15714
+ });
15715
+ return {
15716
+ refs: refs.filter((ref) => this.keepAll || readsAsInstructions2(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))),
15717
+ unresolved: [...this.unresolved.values()]
15718
+ };
15719
+ }
15720
+ value(node, owner, walk) {
15721
+ if (walk.depth > this.maxDepth) {
15722
+ this.markUnresolved(node, "depth-limit", walk);
15723
+ return;
15724
+ }
15725
+ const expr = unwrap(node);
15726
+ if (walk.project.length > 0 && (import_typescript3.default.isStringLiteral(expr) || import_typescript3.default.isNoSubstitutionTemplateLiteral(expr) || import_typescript3.default.isTemplateExpression(expr) || import_typescript3.default.isBinaryExpression(expr) && expr.operatorToken.kind === import_typescript3.default.SyntaxKind.PlusToken)) {
15727
+ return;
15728
+ }
15729
+ if (import_typescript3.default.isStringLiteral(expr) || import_typescript3.default.isNoSubstitutionTemplateLiteral(expr)) {
15730
+ this.text(expr, expr.text, owner, walk);
15731
+ return;
15732
+ }
15733
+ if (import_typescript3.default.isTemplateExpression(expr)) {
15734
+ const sf = expr.getSourceFile();
15735
+ let text = expr.head.text;
15736
+ for (const span of expr.templateSpans) {
15737
+ text += `{{${span.expression.getText(sf).replace(/\s+/g, " ").slice(0, 60)}}}${span.literal.text}`;
15738
+ }
15739
+ this.text(expr, text, owner ?? { node: expr, kind: "template" }, walk);
15740
+ for (const span of expr.templateSpans)
15741
+ this.value(span.expression, undefined, flag(walk, "interpolated"));
15742
+ return;
15743
+ }
15744
+ if (import_typescript3.default.isBinaryExpression(expr)) {
15745
+ if (expr.operatorToken.kind === import_typescript3.default.SyntaxKind.PlusToken) {
15746
+ this.value(expr.left, owner, walk);
15747
+ this.value(expr.right, owner, walk);
15748
+ } else if (expr.operatorToken.kind === import_typescript3.default.SyntaxKind.BarBarToken || expr.operatorToken.kind === import_typescript3.default.SyntaxKind.QuestionQuestionToken) {
15749
+ this.value(expr.left, owner, walk);
15750
+ this.value(expr.right, owner, walk);
15751
+ }
15752
+ return;
15753
+ }
15754
+ if (import_typescript3.default.isConditionalExpression(expr)) {
15755
+ this.value(expr.whenTrue, owner, walk);
15756
+ this.value(expr.whenFalse, owner, walk);
15757
+ return;
15758
+ }
15759
+ if (import_typescript3.default.isArrayLiteralExpression(expr)) {
15760
+ for (const element of expr.elements) {
15761
+ this.value(import_typescript3.default.isSpreadElement(element) ? element.expression : element, owner, walk);
15762
+ }
15763
+ return;
15764
+ }
15765
+ if (import_typescript3.default.isObjectLiteralExpression(expr)) {
15766
+ this.objectValue(expr, walk);
15767
+ return;
15768
+ }
15769
+ if (import_typescript3.default.isIdentifier(expr)) {
15770
+ this.identifier(expr, owner, walk);
15771
+ return;
15772
+ }
15773
+ if (import_typescript3.default.isPropertyAccessExpression(expr)) {
15774
+ this.propertyAccess(expr, owner, walk);
15775
+ return;
15776
+ }
15777
+ if (import_typescript3.default.isElementAccessExpression(expr)) {
15778
+ this.elementAccess(expr, owner, walk);
15779
+ return;
15780
+ }
15781
+ if (import_typescript3.default.isCallExpression(expr)) {
15782
+ this.call(expr, owner, walk);
15783
+ return;
15784
+ }
15785
+ if (import_typescript3.default.isTaggedTemplateExpression(expr)) {
15786
+ this.value(expr.template, owner, walk);
15787
+ return;
15788
+ }
15789
+ if (import_typescript3.default.isArrowFunction(expr) || import_typescript3.default.isFunctionExpression(expr)) {
15790
+ this.builderBody(expr, { node: expr, name: owner?.name, kind: "builder" }, walk);
15791
+ }
15792
+ }
15793
+ objectValue(object, walk) {
15794
+ if (walk.project.length > 0) {
15795
+ const [field, ...rest] = walk.project;
15796
+ const inner = { ...walk, project: rest };
15797
+ for (const property of object.properties) {
15798
+ if (import_typescript3.default.isSpreadAssignment(property)) {
15799
+ this.value(property.expression, undefined, walk);
15800
+ continue;
15801
+ }
15802
+ if (propertyName(property) !== field)
15803
+ continue;
15804
+ if (import_typescript3.default.isPropertyAssignment(property))
15805
+ this.value(property.initializer, { node: property, name: field, kind: "literal" }, inner);
15806
+ else if (import_typescript3.default.isShorthandPropertyAssignment(property))
15807
+ this.identifier(property.name, undefined, inner);
15808
+ else if (import_typescript3.default.isMethodDeclaration(property) || import_typescript3.default.isGetAccessorDeclaration(property))
15809
+ this.builderBody(property, { node: property, name: field, kind: "builder" }, inner);
15810
+ }
15811
+ return;
15812
+ }
15813
+ const role = stringField(object, "role");
15814
+ if (role && /^(?:assistant|tool|function|model)$/.test(role))
15815
+ return;
15816
+ for (const property of object.properties) {
15817
+ if (import_typescript3.default.isSpreadAssignment(property)) {
15818
+ this.value(property.expression, undefined, walk);
15819
+ continue;
15820
+ }
15821
+ const key = propertyName(property);
15822
+ if (!key)
15823
+ continue;
15824
+ const promptField = PROMPT_FIELDS.has(key) || walk.promptObject === true;
15825
+ if (!promptField) {
15826
+ if (import_typescript3.default.isPropertyAssignment(property) && import_typescript3.default.isObjectLiteralExpression(unwrap(property.initializer))) {
15827
+ this.objectValue(unwrap(property.initializer), walk);
15828
+ }
15829
+ continue;
15830
+ }
15831
+ const inner = PROMPT_FIELDS.has(key) && !/^(?:content|text|messages|user|system|prompt)$/.test(key) ? { ...walk, promptObject: true } : walk;
15832
+ if (import_typescript3.default.isPropertyAssignment(property)) {
15833
+ const kind = role ? "message" : "literal";
15834
+ this.value(property.initializer, { node: property, name: role ? undefined : key, kind }, this.messageRole(inner, role));
15835
+ } else if (import_typescript3.default.isShorthandPropertyAssignment(property)) {
15836
+ this.identifier(property.name, undefined, inner);
15837
+ }
15838
+ }
15839
+ }
15840
+ messageRole(walk, role) {
15841
+ if (!role || walk.role !== "messages")
15842
+ return walk;
15843
+ return { ...walk, role: role === "system" || role === "developer" ? "system" : "user" };
15844
+ }
15845
+ identifier(identifier, owner, walk) {
15846
+ if (identifier.text === "undefined")
15847
+ return;
15848
+ const declarations = this.declarationsOf(identifier);
15849
+ if (declarations.length === 0) {
15850
+ this.markUnresolved(identifier, "external", walk);
15851
+ return;
15852
+ }
15853
+ for (const declaration of declarations)
15854
+ this.declaration(declaration, identifier, owner, walk);
15855
+ }
15856
+ propertyAccess(access, owner, walk) {
15857
+ const sf = access.getSourceFile();
15858
+ const text = access.getText(sf);
15859
+ if (/^(?:process\.env|import\.meta\.env|Deno\.env)\b/.test(text)) {
15860
+ this.markUnresolved(access, "env", walk);
15861
+ return;
15862
+ }
15863
+ const declarations = this.declarationsOf(access.name).filter(hasValue);
15864
+ if (walk.flags.includes("interpolated") && !PROMPT_FIELD_NAME.test(access.name.text) && declarations.length >= 3 && declarations.every((d) => import_typescript3.default.isPropertyAssignment(d) || import_typescript3.default.isShorthandPropertyAssignment(d))) {
15865
+ return;
15866
+ }
15867
+ if (declarations.length > 0) {
15868
+ for (const declaration of declarations)
15869
+ this.declaration(declaration, access, owner, walk);
15870
+ return;
15871
+ }
15872
+ if (walk.project.length === 0 && !PROMPT_FIELD_NAME.test(access.name.text))
15873
+ return;
15874
+ this.value(access.expression, owner, { ...flag(walk, "projected"), project: [access.name.text, ...walk.project] });
15875
+ }
15876
+ elementAccess(access, owner, walk) {
15877
+ const key = unwrap(access.argumentExpression);
15878
+ const literalKey = import_typescript3.default.isStringLiteral(key) || import_typescript3.default.isNumericLiteral(key) || import_typescript3.default.isNoSubstitutionTemplateLiteral(key) ? key.text : undefined;
15879
+ if (literalKey !== undefined) {
15880
+ const declarations = this.declarationsOf(access.argumentExpression);
15881
+ if (declarations.length > 0) {
15882
+ for (const declaration of declarations)
15883
+ this.declaration(declaration, access, owner, walk);
15884
+ return;
15885
+ }
15886
+ }
15887
+ const table = this.objectLiteralOf(access.expression);
15888
+ if (!table) {
15889
+ this.value(access.expression, owner, walk);
15890
+ return;
15891
+ }
15892
+ const next = this.step(literalKey ? walk : flag(walk, "dynamic-key"), access, literalKey ? `table field ${literalKey}` : "every field of a table read with a dynamic key");
15893
+ if (!next)
15894
+ return;
15895
+ if (import_typescript3.default.isArrayLiteralExpression(table)) {
15896
+ const elements = literalKey !== undefined && import_typescript3.default.isNumericLiteral(key) ? [table.elements[Number(literalKey)]].filter(Boolean) : table.elements;
15897
+ for (const element of elements)
15898
+ this.value(import_typescript3.default.isSpreadElement(element) ? element.expression : element, undefined, next);
15899
+ return;
15900
+ }
15901
+ for (const property of table.properties) {
15902
+ const name = propertyName(property);
15903
+ if (literalKey !== undefined && name !== literalKey)
15904
+ continue;
15905
+ if (import_typescript3.default.isPropertyAssignment(property))
15906
+ this.value(property.initializer, { node: property, name, kind: "literal" }, next);
15907
+ else if (import_typescript3.default.isMethodDeclaration(property))
15908
+ this.builderBody(property, { node: property, name, kind: "builder" }, next);
15909
+ else if (import_typescript3.default.isShorthandPropertyAssignment(property))
15910
+ this.identifier(property.name, undefined, next);
15911
+ }
15912
+ }
15913
+ call(call, owner, walk) {
15914
+ const callee = call.expression;
15915
+ if (import_typescript3.default.isPropertyAccessExpression(callee)) {
15916
+ const method = callee.name.text;
15917
+ if (method === "finally") {
15918
+ this.value(callee.expression, owner, walk);
15919
+ return;
15920
+ }
15921
+ if (CALLBACK_METHODS.has(method)) {
15922
+ const callbacks = call.arguments.map(unwrap).filter((a) => import_typescript3.default.isArrowFunction(a) || import_typescript3.default.isFunctionExpression(a));
15923
+ for (const callback of callbacks)
15924
+ this.builderBody(callback, owner ?? { node: callback, kind: "builder" }, walk);
15925
+ if (callbacks.length === 0)
15926
+ for (const argument of call.arguments)
15927
+ this.value(argument, owner, walk);
15928
+ if (method === "catch")
15929
+ this.value(callee.expression, owner, walk);
15930
+ return;
15931
+ }
15932
+ if (TEXT_PRESERVING_METHODS.has(method) || ARRAY_ASSEMBLY_METHODS.has(method)) {
15933
+ this.value(callee.expression, owner, walk);
15934
+ if (method === "concat")
15935
+ for (const argument of call.arguments)
15936
+ this.value(argument, owner, walk);
15937
+ return;
15938
+ }
15939
+ }
15940
+ if (walk.project.length > 0 && import_typescript3.default.isPropertyAccessExpression(callee) && callee.getText() === "JSON.stringify" && call.arguments[0]) {
15941
+ this.value(call.arguments[0], owner, walk);
15942
+ return;
15943
+ }
15944
+ if (import_typescript3.default.isIdentifier(callee) && /^(?:String|dedent|outdent|stripIndent|stripIndents|trim)$/.test(callee.text)) {
15945
+ for (const argument of call.arguments)
15946
+ this.value(argument, owner, walk);
15947
+ return;
15948
+ }
15949
+ const declarations = this.declarationsOf(import_typescript3.default.isPropertyAccessExpression(callee) ? callee.name : callee);
15950
+ let functions = declarations.map(functionOf).filter((fn) => Boolean(fn));
15951
+ if (functions.length === 0 && import_typescript3.default.isPropertyAccessExpression(callee)) {
15952
+ const methods = this.methodsNamed(callee.name.text);
15953
+ if (methods.length === 1)
15954
+ functions = methods;
15955
+ }
15956
+ functions = functions.filter((fn) => fn.body);
15957
+ if (functions.length === 0) {
15958
+ this.markUnresolved(call, /\b(?:fetch|read|load|get|query|select|find)\w*\s*$/i.test(callee.getText(call.getSourceFile())) ? "io" : "external", walk);
15959
+ return;
15960
+ }
15961
+ for (const fn of functions) {
15962
+ if (walk.seen.has(fn))
15963
+ continue;
15964
+ const name = functionName(fn);
15965
+ const next = this.step(walk, fn, `builder ${name ?? "function"} called at ${this.where(call)}`);
15966
+ if (!next)
15967
+ continue;
15968
+ next.bindings = new Map(next.bindings);
15969
+ bindParameters(fn, call.arguments, walk.bindings, next.bindings);
15970
+ this.builderBody(fn, { node: fn, name, kind: "builder" }, next);
15971
+ }
15972
+ }
15973
+ builderBody(fn, owner, walk) {
15974
+ const body = fn.body;
15975
+ if (!body)
15976
+ return;
15977
+ const inner = { ...walk, seen: new Set(walk.seen).add(fn) };
15978
+ if (!import_typescript3.default.isBlock(body)) {
15979
+ this.value(body, owner, inner);
15980
+ return;
15981
+ }
15982
+ const visit = (node) => {
15983
+ if (node !== fn && import_typescript3.default.isFunctionLike(node))
15984
+ return;
15985
+ if (import_typescript3.default.isReturnStatement(node) && node.expression)
15986
+ this.value(node.expression, owner, inner);
15987
+ import_typescript3.default.forEachChild(node, visit);
15988
+ };
15989
+ visit(body);
15990
+ }
15991
+ declaration(declaration, at, owner, walk) {
15992
+ if (walk.seen.has(declaration))
15993
+ return;
15994
+ if (import_typescript3.default.isParameter(declaration) || import_typescript3.default.isBindingElement(declaration) && isParameterBinding(declaration)) {
15995
+ this.parameter(declaration, at, owner, walk);
15996
+ return;
15997
+ }
15998
+ const sf = declaration.getSourceFile();
15999
+ if (this.isExternal(sf)) {
16000
+ this.markUnresolved(at, "external", walk);
16001
+ return;
16002
+ }
16003
+ const name = declarationName(declaration);
16004
+ const next = this.step(walk, declaration, `${name ?? "value"} defined here`);
16005
+ if (!next)
16006
+ return;
16007
+ next.seen = new Set(next.seen).add(declaration);
16008
+ if (import_typescript3.default.isVariableDeclaration(declaration)) {
16009
+ if (declaration.initializer) {
16010
+ const fn2 = unwrap(declaration.initializer);
16011
+ if (import_typescript3.default.isArrowFunction(fn2) || import_typescript3.default.isFunctionExpression(fn2)) {
16012
+ this.builderBody(fn2, { node: declaration, name, kind: "builder" }, next);
16013
+ } else {
16014
+ this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
16015
+ }
16016
+ }
16017
+ this.assembly(declaration, ownerFor(declaration, name, owner), next);
16018
+ return;
16019
+ }
16020
+ if (import_typescript3.default.isPropertyAssignment(declaration)) {
16021
+ this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
16022
+ return;
16023
+ }
16024
+ if (import_typescript3.default.isShorthandPropertyAssignment(declaration)) {
16025
+ this.identifier(declaration.name, owner, next);
16026
+ return;
16027
+ }
16028
+ if (import_typescript3.default.isPropertyDeclaration(declaration)) {
16029
+ if (declaration.initializer)
16030
+ this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
16031
+ if (name && import_typescript3.default.isClassLike(declaration.parent)) {
16032
+ const visit = (node) => {
16033
+ if (import_typescript3.default.isBinaryExpression(node) && node.operatorToken.kind === import_typescript3.default.SyntaxKind.EqualsToken && import_typescript3.default.isPropertyAccessExpression(node.left) && node.left.expression.kind === import_typescript3.default.SyntaxKind.ThisKeyword && node.left.name.text === name) {
16034
+ this.value(node.right, undefined, next);
16035
+ }
16036
+ import_typescript3.default.forEachChild(node, visit);
16037
+ };
16038
+ visit(declaration.parent);
16039
+ }
16040
+ return;
16041
+ }
16042
+ if (import_typescript3.default.isEnumMember(declaration) && declaration.initializer) {
16043
+ this.value(declaration.initializer, ownerFor(declaration, name, owner), next);
16044
+ return;
16045
+ }
16046
+ const fn = functionOf(declaration);
16047
+ if (fn)
16048
+ this.builderBody(fn, { node: declaration, name, kind: "builder" }, next);
16049
+ }
16050
+ assembly(declaration, owner, walk) {
16051
+ if (!import_typescript3.default.isIdentifier(declaration.name))
16052
+ return;
16053
+ const name = declaration.name.text;
16054
+ const scope = enclosingScope(declaration);
16055
+ if (!scope)
16056
+ return;
16057
+ const isThis = (identifier) => identifier.text === name && this.declarationsOf(identifier).includes(declaration);
16058
+ const visit = (node) => {
16059
+ if (import_typescript3.default.isCallExpression(node) && import_typescript3.default.isPropertyAccessExpression(node.expression) && import_typescript3.default.isIdentifier(node.expression.expression) && isThis(node.expression.expression) && /^(?:push|unshift|splice)$/.test(node.expression.name.text)) {
16060
+ const args = node.expression.name.text === "splice" ? node.arguments.slice(2) : node.arguments;
16061
+ for (const argument of args)
16062
+ this.value(argument, owner, walk);
16063
+ }
16064
+ if (import_typescript3.default.isBinaryExpression(node) && import_typescript3.default.isIdentifier(node.left) && isThis(node.left)) {
16065
+ if (node.operatorToken.kind === import_typescript3.default.SyntaxKind.PlusEqualsToken)
16066
+ this.value(node.right, owner, walk);
16067
+ if (node.operatorToken.kind === import_typescript3.default.SyntaxKind.EqualsToken && node.right !== declaration.initializer)
16068
+ this.value(node.right, owner, walk);
16069
+ }
16070
+ import_typescript3.default.forEachChild(node, visit);
16071
+ };
16072
+ visit(scope);
16073
+ }
16074
+ parameter(declaration, at, owner, walk) {
16075
+ const bound = walk.bindings.get(declaration);
16076
+ if (bound) {
16077
+ this.value(bound.expr, undefined, { ...walk, bindings: bound.bindings, project: [...bound.project ?? [], ...walk.project] });
16078
+ return;
16079
+ }
16080
+ const parameter = import_typescript3.default.isParameter(declaration) ? declaration : parameterOf(declaration);
16081
+ const fn = parameter?.parent;
16082
+ if (!parameter || !fn || !import_typescript3.default.isFunctionLike(fn)) {
16083
+ this.markUnresolved(at, "param-unbound", walk);
16084
+ return;
16085
+ }
16086
+ if (walk.paramLevels >= this.maxParamLevels) {
16087
+ this.markUnresolved(at, "depth-limit", walk);
16088
+ return;
16089
+ }
16090
+ if (parameter.initializer)
16091
+ this.value(parameter.initializer, owner, walk);
16092
+ const callers = this.callersOf(fn);
16093
+ if (callers.length === 0) {
16094
+ if (!parameter.initializer)
16095
+ this.markUnresolved(at, "param-unbound", walk);
16096
+ return;
16097
+ }
16098
+ const index = fn.parameters.indexOf(parameter);
16099
+ for (const caller of callers) {
16100
+ const argument = caller.arguments[index];
16101
+ if (!argument)
16102
+ continue;
16103
+ const next = this.step(flag(walk, "caller-argument"), caller, `argument ${index + 1} at a caller of ${functionName(fn) ?? "the function"}`);
16104
+ if (!next)
16105
+ continue;
16106
+ next.paramLevels += 1;
16107
+ next.bindings = new Map;
16108
+ if (import_typescript3.default.isBindingElement(declaration)) {
16109
+ const field = bindingField(declaration);
16110
+ const object = import_typescript3.default.isObjectLiteralExpression(unwrap(argument)) ? unwrap(argument) : undefined;
16111
+ const property = object?.properties.find((p2) => propertyName(p2) === field);
16112
+ if (property && import_typescript3.default.isPropertyAssignment(property))
16113
+ this.value(property.initializer, undefined, next);
16114
+ else if (property && import_typescript3.default.isShorthandPropertyAssignment(property))
16115
+ this.identifier(property.name, undefined, next);
16116
+ else if (!object && field)
16117
+ this.value(argument, undefined, { ...next, project: [field, ...next.project] });
16118
+ continue;
16119
+ }
16120
+ this.value(argument, undefined, next);
16121
+ }
16122
+ }
16123
+ callersOf(fn) {
16124
+ const name = functionName(fn);
16125
+ if (!name)
16126
+ return [];
16127
+ this.indexCallers();
16128
+ const names = [name, ...this.aliasesByName.get(name) ?? []];
16129
+ const candidates = names.flatMap((alias) => this.callersByName.get(alias) ?? []);
16130
+ return candidates.filter((call) => {
16131
+ const callee = import_typescript3.default.isPropertyAccessExpression(call.expression) ? call.expression.name : call.expression;
16132
+ return this.declarationsOf(callee).some((declaration) => functionOf(declaration) === fn || declaration === fn);
16133
+ });
16134
+ }
16135
+ sourceFiles() {
16136
+ const byName = new Map;
16137
+ for (const program of this.context.programs) {
16138
+ for (const file of program.getSourceFiles()) {
16139
+ if (!this.isExternal(file) && !byName.has(file.fileName))
16140
+ byName.set(file.fileName, file);
16141
+ }
16142
+ }
16143
+ return [...byName.values()];
16144
+ }
16145
+ methodsNamed(name) {
16146
+ if (!this.methodIndex) {
16147
+ this.methodIndex = new Map;
16148
+ for (const file of this.sourceFiles()) {
16149
+ {
16150
+ const visit = (node) => {
16151
+ if (import_typescript3.default.isClassLike(node)) {
16152
+ for (const member of node.members) {
16153
+ if ((import_typescript3.default.isMethodDeclaration(member) || import_typescript3.default.isGetAccessorDeclaration(member)) && member.body && member.name && import_typescript3.default.isIdentifier(member.name)) {
16154
+ const list = this.methodIndex.get(member.name.text) ?? [];
16155
+ list.push(member);
16156
+ this.methodIndex.set(member.name.text, list);
16157
+ }
16158
+ }
16159
+ }
16160
+ import_typescript3.default.forEachChild(node, visit);
16161
+ };
16162
+ visit(file);
16163
+ }
16164
+ }
16165
+ }
16166
+ return this.methodIndex.get(name) ?? [];
16167
+ }
16168
+ indexCallers() {
16169
+ if (this.callersIndexed)
16170
+ return;
16171
+ this.callersIndexed = true;
16172
+ for (const file of this.sourceFiles()) {
16173
+ {
16174
+ const visit = (node) => {
16175
+ if (import_typescript3.default.isCallExpression(node)) {
16176
+ const callee = import_typescript3.default.isPropertyAccessExpression(node.expression) ? node.expression.name : node.expression;
16177
+ if (import_typescript3.default.isIdentifier(callee)) {
16178
+ const list = this.callersByName.get(callee.text) ?? [];
16179
+ list.push(node);
16180
+ this.callersByName.set(callee.text, list);
16181
+ }
16182
+ }
16183
+ if ((import_typescript3.default.isImportSpecifier(node) || import_typescript3.default.isExportSpecifier(node)) && node.propertyName && import_typescript3.default.isIdentifier(node.propertyName)) {
16184
+ const aliases = this.aliasesByName.get(node.propertyName.text) ?? new Set;
16185
+ aliases.add(node.name.text);
16186
+ this.aliasesByName.set(node.propertyName.text, aliases);
16187
+ }
16188
+ import_typescript3.default.forEachChild(node, visit);
16189
+ };
16190
+ visit(file);
16191
+ }
16192
+ }
16193
+ }
16194
+ objectLiteralOf(node) {
16195
+ let current = unwrap(node);
16196
+ for (let i = 0;i < 6; i++) {
16197
+ if (import_typescript3.default.isObjectLiteralExpression(current) || import_typescript3.default.isArrayLiteralExpression(current))
16198
+ return current;
16199
+ const target = import_typescript3.default.isPropertyAccessExpression(current) ? current.name : current;
16200
+ const declaration = this.declarationsOf(target)[0];
16201
+ if (!declaration)
16202
+ return;
16203
+ const initializer = import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isPropertyDeclaration(declaration) ? declaration.initializer : undefined;
16204
+ if (!initializer)
16205
+ return;
16206
+ current = unwrap(initializer);
16207
+ }
16208
+ return;
16209
+ }
16210
+ declarationsOf(node) {
16211
+ const path = this.relative(node.getSourceFile().fileName);
16212
+ const checker = this.context.checkerFor(path);
16213
+ if (!checker)
16214
+ return [];
16215
+ let symbol = import_typescript3.default.isShorthandPropertyAssignment(node.parent) && node.parent.name === node ? checker.getShorthandAssignmentValueSymbol(node.parent) : checker.getSymbolAtLocation(node);
16216
+ if (!symbol)
16217
+ return [];
16218
+ if (symbol.flags & import_typescript3.default.SymbolFlags.Alias) {
16219
+ try {
16220
+ symbol = checker.getAliasedSymbol(symbol);
16221
+ } catch {
16222
+ return [];
16223
+ }
16224
+ }
16225
+ return (symbol.declarations ?? []).filter((declaration) => !this.isExternal(declaration.getSourceFile()));
16226
+ }
16227
+ step(walk, node, reason) {
16228
+ if (walk.depth + 1 > this.maxDepth) {
16229
+ this.markUnresolved(node, "depth-limit", walk);
16230
+ return;
16231
+ }
16232
+ const hop = { path: this.relative(node.getSourceFile().fileName), line: lineOf2(node), reason };
16233
+ return { ...walk, depth: walk.depth + 1, hops: [...walk.hops, hop] };
16234
+ }
16235
+ text(at, text, owner, walk) {
16236
+ if (walk.namedOnly && !owner?.name)
16237
+ return;
16238
+ const anchor = owner?.node ?? at;
16239
+ const sf = anchor.getSourceFile();
16240
+ const path = this.relative(sf.fileName);
16241
+ if (TEST_SOURCE.test(path))
16242
+ return;
16243
+ if (LOCAL_ONLY_SITE.test(walk.site.path) && path !== walk.site.path)
16244
+ return;
16245
+ const line = lineOf2(anchor);
16246
+ const id = `${path}:${line}`;
16247
+ const key = owner ? `${path}@${anchor.getStart(sf)}` : id;
16248
+ let ref = this.refs.get(key);
16249
+ if (!ref) {
16250
+ ref = {
16251
+ id,
16252
+ path,
16253
+ line,
16254
+ endLine: sf.getLineAndCharacterOfPosition(anchor.getEnd()).line + 1,
16255
+ ...owner?.name ? { name: owner.name } : {},
16256
+ kind: owner?.kind ?? "literal",
16257
+ role: walk.role,
16258
+ text: "",
16259
+ callSiteIds: [],
16260
+ hops: walk.hops,
16261
+ via: [...walk.flags],
16262
+ pieces: new Map,
16263
+ start: anchor.getStart(sf)
16264
+ };
16265
+ this.refs.set(key, ref);
16266
+ }
16267
+ ref.start = Math.min(ref.start, anchor.getStart(sf));
16268
+ if (!ref.callSiteIds.includes(walk.site.id))
16269
+ ref.callSiteIds.push(walk.site.id);
16270
+ ref.via = ref.via.filter((f) => walk.flags.includes(f));
16271
+ ref.pieces.set(at.getStart(sf), text);
16272
+ }
16273
+ markUnresolved(node, reason, walk) {
16274
+ const sf = node.getSourceFile();
16275
+ const path = this.relative(sf.fileName);
16276
+ const line = lineOf2(node);
16277
+ const key = `${walk.site.id}|${path}:${line}|${reason}`;
16278
+ if (this.unresolved.has(key))
16279
+ return;
16280
+ this.unresolved.set(key, {
16281
+ callSiteId: walk.site.id,
16282
+ role: walk.role,
16283
+ path,
16284
+ line,
16285
+ expression: node.getText(sf).replace(/\s+/g, " ").slice(0, 120),
16286
+ reason
16287
+ });
16288
+ }
16289
+ columnOf(path, start) {
16290
+ const sf = this.sourceFiles().find((file) => this.relative(file.fileName) === path);
16291
+ return sf ? sf.getLineAndCharacterOfPosition(start).character + 1 : undefined;
16292
+ }
16293
+ where(node) {
16294
+ return `${this.relative(node.getSourceFile().fileName)}:${lineOf2(node)}`;
16295
+ }
16296
+ relative(fileName) {
16297
+ const rel2 = relative6(this.context.rootDir, fileName).replace(/\\/g, "/");
16298
+ return rel2.startsWith("..") ? fileName : rel2;
16299
+ }
16300
+ isExternal(sf) {
16301
+ return sf.isDeclarationFile || /(?:^|\/)node_modules\//.test(sf.fileName);
16302
+ }
16303
+ }
16304
+ function nodeOf(ref, context) {
16305
+ const node = context.nodeAt(ref);
16306
+ return node && import_typescript3.default.isShorthandPropertyAssignment(node) ? node.name : node;
16307
+ }
16308
+ function toolName(definition) {
16309
+ const name = stringField(definition, "name");
16310
+ if (name)
16311
+ return name;
16312
+ const parent = definition.parent;
16313
+ if (import_typescript3.default.isPropertyAssignment(parent))
16314
+ return propertyName(parent);
16315
+ if (import_typescript3.default.isCallExpression(parent) && import_typescript3.default.isPropertyAssignment(parent.parent))
16316
+ return propertyName(parent.parent);
16317
+ if (import_typescript3.default.isCallExpression(parent) && import_typescript3.default.isVariableDeclaration(parent.parent) && import_typescript3.default.isIdentifier(parent.parent.name))
16318
+ return parent.parent.name.text;
16319
+ return;
16320
+ }
16321
+ function flag(walk, f) {
16322
+ return walk.flags.includes(f) ? walk : { ...walk, flags: [...walk.flags, f] };
16323
+ }
16324
+ function unwrap(node) {
16325
+ let current = node;
16326
+ for (;; ) {
16327
+ if (import_typescript3.default.isParenthesizedExpression(current) || import_typescript3.default.isAsExpression(current) || import_typescript3.default.isNonNullExpression(current) || import_typescript3.default.isAwaitExpression(current) || import_typescript3.default.isTypeAssertionExpression(current) || import_typescript3.default.isSatisfiesExpression(current)) {
16328
+ current = current.expression;
16329
+ continue;
16330
+ }
16331
+ return current;
16332
+ }
16333
+ }
16334
+ function lineOf2(node) {
16335
+ const sf = node.getSourceFile();
16336
+ return sf.getLineAndCharacterOfPosition(node.getStart(sf)).line + 1;
16337
+ }
16338
+ function propertyName(property) {
16339
+ const name = property.name;
16340
+ if (!name)
16341
+ return;
16342
+ if (import_typescript3.default.isIdentifier(name) || import_typescript3.default.isStringLiteral(name) || import_typescript3.default.isNumericLiteral(name) || import_typescript3.default.isPrivateIdentifier(name))
16343
+ return name.text;
16344
+ return;
16345
+ }
16346
+ function stringField(object, field) {
16347
+ for (const property of object.properties) {
16348
+ if (!import_typescript3.default.isPropertyAssignment(property) || propertyName(property) !== field)
16349
+ continue;
16350
+ const value = unwrap(property.initializer);
16351
+ if (import_typescript3.default.isStringLiteral(value) || import_typescript3.default.isNoSubstitutionTemplateLiteral(value))
16352
+ return value.text;
16353
+ }
16354
+ return;
16355
+ }
16356
+ function declarationName(declaration) {
16357
+ const name = declaration.name;
16358
+ if (name && (import_typescript3.default.isIdentifier(name) || import_typescript3.default.isStringLiteral(name) || import_typescript3.default.isPrivateIdentifier(name)))
16359
+ return name.text;
16360
+ return;
16361
+ }
16362
+ function functionName(fn) {
16363
+ const own = declarationName(fn);
16364
+ if (own)
16365
+ return own;
16366
+ const parent = fn.parent;
16367
+ if (parent && (import_typescript3.default.isVariableDeclaration(parent) || import_typescript3.default.isPropertyAssignment(parent) || import_typescript3.default.isPropertyDeclaration(parent))) {
16368
+ return declarationName(parent);
16369
+ }
16370
+ return;
16371
+ }
16372
+ function functionOf(declaration) {
16373
+ if (import_typescript3.default.isFunctionDeclaration(declaration) || import_typescript3.default.isMethodDeclaration(declaration) || import_typescript3.default.isGetAccessorDeclaration(declaration) || import_typescript3.default.isArrowFunction(declaration) || import_typescript3.default.isFunctionExpression(declaration)) {
16374
+ return declaration;
16375
+ }
16376
+ if ((import_typescript3.default.isVariableDeclaration(declaration) || import_typescript3.default.isPropertyAssignment(declaration) || import_typescript3.default.isPropertyDeclaration(declaration)) && declaration.initializer) {
16377
+ const init = unwrap(declaration.initializer);
16378
+ if (import_typescript3.default.isArrowFunction(init) || import_typescript3.default.isFunctionExpression(init))
16379
+ return init;
16380
+ }
16381
+ return;
16382
+ }
16383
+ function hasValue(declaration) {
16384
+ return !import_typescript3.default.isPropertySignature(declaration) && !import_typescript3.default.isMethodSignature(declaration) && !import_typescript3.default.isIndexSignatureDeclaration(declaration);
16385
+ }
16386
+ function ownerFor(declaration, name, outer) {
16387
+ if (outer?.kind === "builder" && outer.node.getSourceFile() === declaration.getSourceFile() && contains(outer.node, declaration))
16388
+ return outer;
16389
+ return { node: declaration, name, kind: "literal" };
16390
+ }
16391
+ function contains(outer, inner) {
16392
+ return inner.getStart() >= outer.getStart() && inner.getEnd() <= outer.getEnd();
16393
+ }
16394
+ function enclosingScope(declaration) {
16395
+ for (let node = declaration.parent;node; node = node.parent) {
16396
+ if (import_typescript3.default.isBlock(node) || import_typescript3.default.isSourceFile(node) || import_typescript3.default.isModuleBlock(node))
16397
+ return node;
16398
+ }
16399
+ return;
16400
+ }
16401
+ function isParameterBinding(element) {
16402
+ return Boolean(parameterOf(element));
16403
+ }
16404
+ function parameterOf(element) {
16405
+ for (let node = element.parent;node; node = node.parent) {
16406
+ if (import_typescript3.default.isParameter(node))
16407
+ return node;
16408
+ if (!import_typescript3.default.isBindingElement(node) && !import_typescript3.default.isObjectBindingPattern(node) && !import_typescript3.default.isArrayBindingPattern(node))
16409
+ return;
16410
+ }
16411
+ return;
16412
+ }
16413
+ function bindingField(element) {
16414
+ const name = element.propertyName ?? element.name;
16415
+ return import_typescript3.default.isIdentifier(name) || import_typescript3.default.isStringLiteral(name) ? name.text : undefined;
16416
+ }
16417
+ function bindParameters(fn, args, outer, into) {
16418
+ fn.parameters.forEach((parameter, index) => {
16419
+ const argument = args[index];
16420
+ if (!argument)
16421
+ return;
16422
+ if (import_typescript3.default.isIdentifier(parameter.name)) {
16423
+ into.set(parameter, { expr: argument, bindings: outer });
16424
+ return;
16425
+ }
16426
+ if (import_typescript3.default.isObjectBindingPattern(parameter.name)) {
16427
+ const object = unwrap(argument);
16428
+ for (const element of parameter.name.elements) {
16429
+ const field = bindingField(element);
16430
+ if (!import_typescript3.default.isObjectLiteralExpression(object)) {
16431
+ if (field)
16432
+ into.set(element, { expr: argument, bindings: outer, project: [field] });
16433
+ continue;
16434
+ }
16435
+ const property = object.properties.find((p2) => propertyName(p2) === field);
16436
+ if (property && import_typescript3.default.isPropertyAssignment(property))
16437
+ into.set(element, { expr: property.initializer, bindings: outer });
16438
+ else if (property && import_typescript3.default.isShorthandPropertyAssignment(property))
16439
+ into.set(element, { expr: property.name, bindings: outer });
16440
+ }
16441
+ }
16442
+ });
16443
+ }
16444
+
16445
+ // src/harness-extract/prompts/assembler.ts
16446
+ var DIRECT_PROMPT_CONFIDENCE = 0.9;
16447
+ var INDIRECT_PROMPT_CONFIDENCE = 0.75;
16448
+ var MAX_HOP_EVIDENCE = 4;
16449
+ var CALL_PATH_REASON = "call path:";
16450
+ var MAX_BODY_CHARS = 64 * 1024;
16451
+ function assemblePromptArtifacts(resolution, callSites, promoted, options = {}) {
16452
+ const allow = new Set(options.allow ?? ["caller-argument", "dynamic-key", "interpolated", "projected"]);
16453
+ const sites = new Map(callSites.map((site) => [site.id, site]));
16454
+ const toolAgents = new Map;
16455
+ for (const tool of options.toolDefinitions ?? []) {
16456
+ const site = toolDefinitionSite(tool);
16457
+ sites.set(site.id, site);
16458
+ toolAgents.set(site.id, tool.agentIds ?? []);
16459
+ }
16460
+ const kept = resolution.refs.filter((ref) => ref.via.every((flag2) => allow.has(flag2)));
16461
+ const resolved = kept.map((ref) => refArtifact(ref, sites, options.agentForScope, toolAgents));
16462
+ const refs = new Map(resolved.map((artifact, index) => [artifact, kept[index]]));
16463
+ const byId = new Map;
16464
+ for (const artifact of resolved)
16465
+ byId.set(artifact.id, artifact);
16466
+ let merged = 0;
16467
+ let keptPromoted = 0;
16468
+ const artifacts = [...resolved];
16469
+ for (const artifact of promoted) {
16470
+ if (artifact.type !== "prompt") {
16471
+ artifacts.push(artifact);
16472
+ continue;
16473
+ }
16474
+ const same = byId.get(artifact.id) ?? sameDefinition(artifact, resolved, refs);
16475
+ if (same) {
16476
+ mergeInto(same, artifact);
16477
+ merged += 1;
16478
+ continue;
16479
+ }
16480
+ artifacts.push(artifact);
16481
+ keptPromoted += 1;
16482
+ }
16483
+ return {
16484
+ artifacts,
16485
+ unresolved: unresolvedReports(resolution, sites),
16486
+ stats: { resolved: resolved.length, merged, keptPromoted }
16487
+ };
16488
+ }
16489
+ function refArtifact(ref, sites, agentForScope, toolAgents = new Map) {
16490
+ const callSites = ref.callSiteIds.map((id) => sites.get(id)).filter((site) => Boolean(site));
16491
+ const agentIds = [...new Set(callSites.flatMap((site) => toolAgents.get(site.id) ?? site.agentIds ?? (site.scope && agentForScope ? agentForScope(site.scope) : [])))].sort();
16492
+ const first2 = callSites[0];
16493
+ const evidence = [{ path: ref.path, line: ref.line, reason: `prompt ${ref.kind} definition` }];
16494
+ for (const site of callSites.slice(0, MAX_HOP_EVIDENCE)) {
16495
+ evidence.push({ path: site.path, line: site.line, reason: `passed to a model call: ${site.callee} as ${ref.role}` });
16496
+ }
16497
+ for (const hop of ref.hops.slice(-MAX_HOP_EVIDENCE)) {
16498
+ if (hop.path === ref.path && hop.line === ref.line)
16499
+ continue;
16500
+ evidence.push({ path: hop.path, line: hop.line, reason: `${CALL_PATH_REASON} ${hop.reason}` });
16501
+ }
16502
+ const direct = ref.via.length === 0;
16503
+ const where = `${ref.path}:${ref.line}`;
16504
+ const reach = first2 ? `${first2.callee} at ${first2.path}:${first2.line}` : "a model call";
16505
+ return {
16506
+ id: stableId("prompt", `${ref.path.replace(/\.[^.]+$/, "")}:L${ref.line}${ref.column ? `C${ref.column}` : ""}`),
16507
+ type: "prompt",
16508
+ name: ref.name ? titleFromId(ref.name) : `Inline Prompt (${where})`,
16509
+ scope: agentIds.length === 1 ? "agent" : "shared",
16510
+ ...agentIds.length === 1 ? { ownedByAgentId: agentIds[0] } : {},
16511
+ usedByAgentIds: agentIds,
16512
+ confidence: direct ? DIRECT_PROMPT_CONFIDENCE : INDIRECT_PROMPT_CONFIDENCE,
16513
+ confidenceReason: direct ? `Call site: ${ref.kind === "builder" ? "builder" : "text"} ${ref.name ?? ""} at ${where} is passed to ${reach} as ${ref.role}.`.replace(/\s+/g, " ") : `Call site: ${ref.name ?? "text"} at ${where} reaches ${reach} as ${ref.role} through ${ref.via.join(", ")}.`,
16514
+ evidence,
16515
+ body: ref.text.length > MAX_BODY_CHARS ? `${ref.text.slice(0, MAX_BODY_CHARS)}
16516
+ [truncated]` : ref.text
16517
+ };
16518
+ }
16519
+ function sameDefinition(promoted, resolved, refs) {
16520
+ const at = promoted.evidence[0];
16521
+ const line = at?.line;
16522
+ if (!at || line === undefined || promoted.sourcePath)
16523
+ return;
16524
+ const columned = /C\d+$/.test(promoted.id);
16525
+ const span = (ref) => ref.endLine - ref.line;
16526
+ return resolved.map((candidate) => ({ candidate, ref: refs.get(candidate) })).filter(({ ref }) => ref.path === at.path && (ref.line === line ? !columned && !ref.column : ref.line < line && line <= ref.endLine)).sort((a, b) => Number(b.ref.line === line) - Number(a.ref.line === line) || span(a.ref) - span(b.ref))[0]?.candidate;
16527
+ }
16528
+ function mergeInto(target, promoted) {
16529
+ const seen = new Set(target.evidence.map((e) => `${e.path}:${e.line}`));
16530
+ for (const evidence of promoted.evidence) {
16531
+ if (!seen.has(`${evidence.path}:${evidence.line}`))
16532
+ target.evidence.push(evidence);
16533
+ }
16534
+ target.confidence = Math.max(target.confidence, promoted.confidence);
16535
+ if ((promoted.body?.length ?? 0) > (target.body?.length ?? 0) && target.body?.includes("{{") !== true)
16536
+ target.body = promoted.body;
16537
+ if (target.id !== promoted.id)
16538
+ target.id = promoted.id;
16539
+ }
16540
+ function unresolvedReports(resolution, sites) {
16541
+ const resolvedSites = new Set(resolution.refs.flatMap((ref) => ref.callSiteIds.map((id) => `${id}|${ref.role}`)));
16542
+ const reports = new Map;
16543
+ for (const value of resolution.unresolved) {
16544
+ if (resolvedSites.has(`${value.callSiteId}|${value.role}`))
16545
+ continue;
16546
+ const site = sites.get(value.callSiteId);
16547
+ if (!site)
16548
+ continue;
16549
+ const key = `${value.callSiteId}|${value.role}`;
16550
+ const report = reports.get(key) ?? { callSiteId: site.id, path: site.path, line: site.line, role: value.role, values: [] };
16551
+ report.values.push({ path: value.path, line: value.line, expression: value.expression, reason: value.reason });
16552
+ reports.set(key, report);
16553
+ }
16554
+ return [...reports.values()];
16555
+ }
16556
+
16557
+ // src/harness-extract/prompts/index.ts
16558
+ function promptArtifactsFromCallSites(callSites, context, promoted, options = {}) {
16559
+ return assemblePromptArtifacts(resolvePromptArguments(callSites, context, options), callSites, promoted, options);
16560
+ }
16561
+
15473
16562
  // src/harness-sync-limits.ts
15474
16563
  var MAX_HARNESS_SYNC_GRAPH_BYTES = 2000000;
15475
16564
  function assertHarnessGraphSyncSize(graph) {
@@ -15655,7 +16744,7 @@ async function runHarnessCommand(context) {
15655
16744
  report: {
15656
16745
  reportId: report.reportId,
15657
16746
  reportHash,
15658
- path: normalizePath2(relative6(rootDir, reportPath)) || ".moda/harness-report.json"
16747
+ path: normalizePath2(relative7(rootDir, reportPath)) || ".moda/harness-report.json"
15659
16748
  },
15660
16749
  validation,
15661
16750
  approval: {
@@ -15801,7 +16890,7 @@ async function runHarnessCommand(context) {
15801
16890
  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.");
15802
16891
  }
15803
16892
  if (context.flags["github-actions"] === "true") {
15804
- const { runGithubActionsAnalyze } = await import("./harness-github-actions-bgfnh4tw.js");
16893
+ const { runGithubActionsAnalyze } = await import("./harness-github-actions-vt8tt6n9.js");
15805
16894
  const result = await runGithubActionsAnalyze(rootDir, {
15806
16895
  writeReport: (report2) => {
15807
16896
  const normalized = normalizeHarnessReport(report2);
@@ -15923,7 +17012,7 @@ async function runHarnessCommand(context) {
15923
17012
  report: {
15924
17013
  reportId: approval.report.reportId,
15925
17014
  reportHash: hashHarnessReport(approval.report),
15926
- path: normalizePath2(relative6(rootDir, reportPath)) || ".moda/harness-report.json"
17015
+ path: normalizePath2(relative7(rootDir, reportPath)) || ".moda/harness-report.json"
15927
17016
  },
15928
17017
  validation: approval.validation,
15929
17018
  approval: approval.approval
@@ -15974,7 +17063,7 @@ async function runHarnessCommand(context) {
15974
17063
  }
15975
17064
  case "extract": {
15976
17065
  writeHumanProgress(context, "Harness extract: tracing model call sites (no LLM, no network)...");
15977
- const { extractHarness, serializeExtractResult } = await import("./index-gtqxj0fp.js");
17066
+ const { extractHarness, serializeExtractResult } = await import("./index-xkgawks9.js");
15978
17067
  const result = extractHarness(rootDir, { fresh: true });
15979
17068
  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).`);
15980
17069
  context.output.writeData(serializeExtractResult(result));
@@ -16069,9 +17158,9 @@ async function runHarnessCommand(context) {
16069
17158
  const readFlags = { list: ["limit", "offset"], show: ["version"], versions: ["limit", "offset"], diff: ["from", "to"] };
16070
17159
  assertFlags(`harness ${subcommand}`, context.flags, [...readFlags[subcommand], "path"]);
16071
17160
  assertPositionals(`harness ${subcommand}`, context.positionals, subcommand === "list" ? 1 : 2, `moda harness ${subcommand}${subcommand === "list" ? "" : " <harness-id-or-key>"}`);
16072
- for (const flag of readFlags[subcommand]) {
16073
- if (context.flags[flag] === "true")
16074
- throw new CliInputError(`--${flag} needs a value.`);
17161
+ for (const flag2 of readFlags[subcommand]) {
17162
+ if (context.flags[flag2] === "true")
17163
+ throw new CliInputError(`--${flag2} needs a value.`);
16075
17164
  }
16076
17165
  const profileOptions = { profile: context.profile, env: context.env };
16077
17166
  if (!resolveApiKey(profileOptions)) {
@@ -16530,7 +17619,7 @@ function modelIdsUsedInSource(rootDir, ids) {
16530
17619
  const walk = (current) => {
16531
17620
  if (pending.size === 0)
16532
17621
  return false;
16533
- const rel2 = normalizePath2(relative6(rootReal, current)) || ".";
17622
+ const rel2 = normalizePath2(relative7(rootReal, current)) || ".";
16534
17623
  let stat;
16535
17624
  try {
16536
17625
  stat = lstatSync7(current);
@@ -16760,6 +17849,8 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
16760
17849
  let promoted;
16761
17850
  try {
16762
17851
  promoted = promoteHarnessCandidates(detectHarnessCandidates(rootDir), rootDir, { fullEvidence: true });
17852
+ if (!allowedTypes || allowedTypes.has("prompt"))
17853
+ promoted = withCallSitePrompts(rootDir, promoted);
16763
17854
  } catch {
16764
17855
  return { added: 0 };
16765
17856
  }
@@ -16801,6 +17892,18 @@ function mergeDeterministicArtifacts(graph, rootDir, options = {}) {
16801
17892
  }
16802
17893
  return { added };
16803
17894
  }
17895
+ function withCallSitePrompts(rootDir, promoted) {
17896
+ if (process.env.MODA_HARNESS_CALLSITE_PROMPTS === "0")
17897
+ return promoted;
17898
+ try {
17899
+ const { result, ctx } = extractHarnessWithContext(rootDir);
17900
+ const sites = result.callSites.filter((site) => !site.isTest);
17901
+ const toolDefinitions = result.toolDefinitions ?? [];
17902
+ return promptArtifactsFromCallSites(sites, ctx, promoted, { toolDefinitions }).artifacts;
17903
+ } catch {
17904
+ return promoted;
17905
+ }
17906
+ }
16804
17907
  function backfillRefutationEvidenceReasons(graph) {
16805
17908
  for (const unknown of graph.unknowns ?? []) {
16806
17909
  if (!/refut/i.test(String(unknown.id ?? "")))
@@ -16907,7 +18010,7 @@ ${existing.body ?? ""}`, promoted.name)))
16907
18010
  return true;
16908
18011
  }
16909
18012
  const promotedName = promoted.name.toLowerCase();
16910
- const isDefinitionLine = (entry) => typeof entry.line === "number" && !/^(?:passed to a model call|prompt-named literal referenced)/.test(entry.reason ?? "");
18013
+ const isDefinitionLine = (entry) => typeof entry.line === "number" && !/^(?:passed to a model call|prompt-named literal referenced|call path:)/.test(entry.reason ?? "");
16911
18014
  const promotedLines = promoted.evidence.filter(isDefinitionLine);
16912
18015
  const promotedSource = artifactSourceKey(promoted);
16913
18016
  const isWholeFilePrompt = promoted.type === "prompt" && Boolean(promoted.sourcePath);
@@ -17293,10 +18396,10 @@ function parseExternalAgentEventBody(event) {
17293
18396
  const subtype = stringValue(event.subtype);
17294
18397
  if (type === "rate_limit_event")
17295
18398
  return { kind: "rate_limit", message: "rate limit wait" };
17296
- const toolName = stringValue(event.name) ?? stringValue(event.tool_name) ?? stringValue(event.toolName) ?? stringValue(call?.name);
17297
- if (toolName && /tool|call|exec|command|bash/i.test(`${type ?? ""} ${subtype ?? ""}`)) {
18399
+ const toolName2 = stringValue(event.name) ?? stringValue(event.tool_name) ?? stringValue(event.toolName) ?? stringValue(call?.name);
18400
+ if (toolName2 && /tool|call|exec|command|bash/i.test(`${type ?? ""} ${subtype ?? ""}`)) {
17298
18401
  const detail = toolInputDetail(event.input ?? event.arguments ?? call?.input ?? call?.arguments);
17299
- return { kind: "tool", toolName, message: `tool ${toolName}`, ...detail ? { detail } : {} };
18402
+ return { kind: "tool", toolName: toolName2, message: `tool ${toolName2}`, ...detail ? { detail } : {} };
17300
18403
  }
17301
18404
  const directText = stringValue(event.text) ?? stringValue(event.message) ?? stringValue(event.delta) ?? stringValue(event.result);
17302
18405
  if (directText && !isLowSignalEventType(type)) {
@@ -17653,8 +18756,8 @@ var READ_ONLY_CLAUDE_ARG_FLAGS = new Map([
17653
18756
  function readOnlyClaudeExtraArgs(args) {
17654
18757
  const kept = [];
17655
18758
  for (let i = 0;i < args.length; i += 1) {
17656
- const [flag, inline] = args[i].split(/=(.*)/s, 2);
17657
- const takesValue = READ_ONLY_CLAUDE_ARG_FLAGS.get(flag);
18759
+ const [flag2, inline] = args[i].split(/=(.*)/s, 2);
18760
+ const takesValue = READ_ONLY_CLAUDE_ARG_FLAGS.get(flag2);
17658
18761
  if (takesValue === undefined) {
17659
18762
  if (inline === undefined && args[i + 1] !== undefined && !args[i + 1].startsWith("-"))
17660
18763
  i += 1;
@@ -17663,7 +18766,7 @@ function readOnlyClaudeExtraArgs(args) {
17663
18766
  if (takesValue && inline === undefined) {
17664
18767
  if (args[i + 1] === undefined)
17665
18768
  continue;
17666
- kept.push(flag, args[i + 1]);
18769
+ kept.push(flag2, args[i + 1]);
17667
18770
  i += 1;
17668
18771
  } else {
17669
18772
  kept.push(args[i]);
@@ -18179,7 +19282,7 @@ function collectSnapshotInputs(rootDir, maxFiles, maxTextBytes) {
18179
19282
  let inventoryFileCount = 0;
18180
19283
  let inventoryTextBytes = 0;
18181
19284
  function walk(current) {
18182
- const path = normalizePath2(relative6(rootDir, current)) || ".";
19285
+ const path = normalizePath2(relative7(rootDir, current)) || ".";
18183
19286
  let stat;
18184
19287
  try {
18185
19288
  stat = lstatSync7(current);
@@ -18250,7 +19353,7 @@ function buildSourceSnapshot(rootDir) {
18250
19353
  }
18251
19354
  function buildCommandScanPlan(context, rootDir) {
18252
19355
  const explicitPath = context.flags.path !== undefined;
18253
- const rel2 = normalizePath2(relative6(context.cwd, rootDir)) || ".";
19356
+ const rel2 = normalizePath2(relative7(context.cwd, rootDir)) || ".";
18254
19357
  const scope = explicitPath && rel2 !== "." ? "narrow" : "broad";
18255
19358
  const machineReadable = context.outputMode !== "human";
18256
19359
  const approvalRequired = context.positional === "analyze" && scope === "broad" && !context.yes;
@@ -18335,7 +19438,7 @@ function writeHumanBlock(context, message) {
18335
19438
  function buildHarnessReadPlan(rootDir, pathWasExplicit) {
18336
19439
  return {
18337
19440
  scope: pathWasExplicit ? "narrow" : "broad",
18338
- rootPaths: [normalizePath2(relative6(rootDir, rootDir)) || "."],
19441
+ rootPaths: [normalizePath2(relative7(rootDir, rootDir)) || "."],
18339
19442
  willRead: [
18340
19443
  "package manifests",
18341
19444
  "source files under the selected path",
@@ -18548,7 +19651,7 @@ function findFresherHarnessReports(rootDir) {
18548
19651
  const candidate = lstatSync7(join9(child, HARNESS_REPORT_PATH));
18549
19652
  if (candidate.isFile() && candidate.mtimeMs > rootMtimeMs) {
18550
19653
  fresher.push({
18551
- path: normalizePath2(relative6(rootDir, join9(child, HARNESS_REPORT_PATH))),
19654
+ path: normalizePath2(relative7(rootDir, join9(child, HARNESS_REPORT_PATH))),
18552
19655
  mtimeMs: candidate.mtimeMs
18553
19656
  });
18554
19657
  }
@@ -18560,7 +19663,7 @@ function findFresherHarnessReports(rootDir) {
18560
19663
  return fresher.sort((a, b) => b.mtimeMs - a.mtimeMs);
18561
19664
  }
18562
19665
  function warnFresherSubdirHarnessReports(context, rootDir, explicitReport) {
18563
- const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath2(relative6(rootDir, resolve10(rootDir, explicitReport))) : undefined;
19666
+ const explicitReportPath = explicitReport && explicitReport !== "true" ? normalizePath2(relative7(rootDir, resolve10(rootDir, explicitReport))) : undefined;
18564
19667
  if (explicitReportPath && explicitReportPath !== normalizePath2(HARNESS_REPORT_PATH))
18565
19668
  return;
18566
19669
  let fresher;
@@ -18767,7 +19870,7 @@ function inventoryFiles(rootDir, skipped, options = {}) {
18767
19870
  const maxTextBytes = numericEnv("MODA_HARNESS_MAX_TEXT_BYTES", DEFAULT_MAX_INVENTORY_TEXT_BYTES);
18768
19871
  let textBytes = 0;
18769
19872
  function walk(current) {
18770
- const rel2 = normalizePath2(relative6(rootReal, current)) || ".";
19873
+ const rel2 = normalizePath2(relative7(rootReal, current)) || ".";
18771
19874
  let stat;
18772
19875
  try {
18773
19876
  stat = lstatSync7(current);
@@ -20118,7 +21221,7 @@ function contentHashForAnnotatedSource(sourcePath, annotation) {
20118
21221
  function readSmallTextFileForHash(absPath, rootDir) {
20119
21222
  if (!existsSync8(absPath))
20120
21223
  return;
20121
- const rel2 = normalizePath2(relative6(rootDir, absPath));
21224
+ const rel2 = normalizePath2(relative7(rootDir, absPath));
20122
21225
  if (isSecretishPath(rel2))
20123
21226
  return;
20124
21227
  let stat;