@nathapp/nax 0.69.10 → 0.70.0-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/nax.js +899 -580
  2. package/package.json +1 -1
package/dist/nax.js CHANGED
@@ -16705,7 +16705,8 @@ var init_schemas_model = __esm(() => {
16705
16705
  ConfiguredModelSchema = exports_external.union([ModelTierSchema, ConfiguredModelObjectSchema]);
16706
16706
  TierConfigSchema = exports_external.object({
16707
16707
  tier: exports_external.string().min(1, "Tier name must be non-empty"),
16708
- attempts: exports_external.number().int().min(1).max(20, { message: "attempts must be 1-20" })
16708
+ attempts: exports_external.number().int().min(1).max(20, { message: "attempts must be 1-20" }),
16709
+ agent: exports_external.string().min(1, { message: "agent must be non-empty" }).optional()
16709
16710
  });
16710
16711
  });
16711
16712
 
@@ -17000,7 +17001,7 @@ var init_schemas_execution = __esm(() => {
17000
17001
  });
17001
17002
 
17002
17003
  // src/config/schemas-infra.ts
17003
- var PlanConfigSchema, AcceptanceFixConfigSchema, AcceptanceConfigSchema, LlmRoutingConfigSchema, RoutingConfigSchema, OptimizerConfigSchema, PluginConfigEntrySchema, HooksConfigSchema, InteractionConfigSchema, StorySizeGateConfigSchema, PromptAuditConfigSchema, AgentFallbackConfigSchema, DEFAULT_AGENT_IDLE_WATCHDOG_CONFIG, AgentIdleWatchdogConfigSchema, AgentAcpConfigSchema, AgentConfigSchema, PrecheckConfigSchema, PromptsConfigSchema, ProjectProfileSchema, VALID_AGENT_TYPES, GenerateConfigSchema, CuratorThresholdsSchema, CuratorConfigSchema;
17004
+ var PlanConfigSchema, AcceptanceFixConfigSchema, AcceptanceConfigSchema, LlmRoutingConfigSchema, AgentRoutingProfileSchema, AgentRoutingConfigSchema, RoutingConfigSchema, OptimizerConfigSchema, PluginConfigEntrySchema, HooksConfigSchema, InteractionConfigSchema, StorySizeGateConfigSchema, PromptAuditConfigSchema, AgentFallbackConfigSchema, DEFAULT_AGENT_IDLE_WATCHDOG_CONFIG, AgentIdleWatchdogConfigSchema, AgentAcpConfigSchema, AgentConfigSchema, PrecheckConfigSchema, PromptsConfigSchema, ProjectProfileSchema, VALID_AGENT_TYPES, GenerateConfigSchema, CuratorThresholdsSchema, CuratorConfigSchema;
17004
17005
  var init_schemas_infra = __esm(() => {
17005
17006
  init_zod();
17006
17007
  init_schemas_model();
@@ -17054,9 +17055,57 @@ var init_schemas_infra = __esm(() => {
17054
17055
  retries: exports_external.number().int().min(0, { message: "llm.retries must be >= 0" }).optional(),
17055
17056
  retryDelayMs: exports_external.number().int().min(0, { message: "llm.retryDelayMs must be >= 0" }).optional()
17056
17057
  });
17058
+ AgentRoutingProfileSchema = exports_external.object({
17059
+ id: exports_external.string().min(1),
17060
+ target: exports_external.object({
17061
+ agent: exports_external.string().min(1),
17062
+ model: ModelTierSchema
17063
+ }),
17064
+ strengths: exports_external.array(exports_external.string().min(1)).min(1),
17065
+ weaknesses: exports_external.array(exports_external.string().min(1)).optional(),
17066
+ costTier: exports_external.enum(["low", "medium", "high"]).optional(),
17067
+ affinity: exports_external.object({
17068
+ taskTypes: exports_external.array(exports_external.string().min(1)).optional(),
17069
+ domains: exports_external.array(exports_external.string().min(1)).optional()
17070
+ }).optional()
17071
+ });
17072
+ AgentRoutingConfigSchema = exports_external.object({
17073
+ enabled: exports_external.boolean().default(true),
17074
+ strategy: exports_external.enum(["off", "llm"]).default("off"),
17075
+ default: exports_external.string().optional(),
17076
+ profiles: exports_external.array(AgentRoutingProfileSchema).default([])
17077
+ }).superRefine((cfg, ctx) => {
17078
+ const ids = cfg.profiles.map((p) => p.id);
17079
+ const seen = new Set;
17080
+ for (const [i, id] of ids.entries()) {
17081
+ if (seen.has(id)) {
17082
+ ctx.addIssue({
17083
+ code: "custom",
17084
+ path: ["profiles", i, "id"],
17085
+ message: `Duplicate profile id "${id}"`
17086
+ });
17087
+ }
17088
+ seen.add(id);
17089
+ }
17090
+ if (cfg.default !== undefined && !ids.includes(cfg.default)) {
17091
+ ctx.addIssue({
17092
+ code: "custom",
17093
+ path: ["default"],
17094
+ message: `Default profile "${cfg.default}" is not in the profiles list`
17095
+ });
17096
+ }
17097
+ if (cfg.strategy === "llm" && cfg.profiles.length === 0) {
17098
+ ctx.addIssue({
17099
+ code: "custom",
17100
+ path: ["strategy"],
17101
+ message: 'strategy "llm" requires at least one profile in routing.agents.profiles'
17102
+ });
17103
+ }
17104
+ });
17057
17105
  RoutingConfigSchema = exports_external.object({
17058
17106
  strategy: exports_external.enum(["keyword", "llm"]),
17059
- llm: LlmRoutingConfigSchema.optional()
17107
+ llm: LlmRoutingConfigSchema.optional(),
17108
+ agents: AgentRoutingConfigSchema.default({ enabled: true, strategy: "off", profiles: [] })
17060
17109
  });
17061
17110
  OptimizerConfigSchema = exports_external.object({
17062
17111
  enabled: exports_external.boolean(),
@@ -17313,7 +17362,8 @@ var init_schemas3 = __esm(() => {
17313
17362
  cacheDecisions: true,
17314
17363
  mode: "hybrid",
17315
17364
  timeoutMs: 30000
17316
- }
17365
+ },
17366
+ agents: { enabled: true, strategy: "off", profiles: [] }
17317
17367
  }),
17318
17368
  execution: ExecutionConfigSchema.default({
17319
17369
  maxIterations: 10,
@@ -17618,6 +17668,48 @@ var init_schemas3 = __esm(() => {
17618
17668
  }).refine((data) => data.version === 1, {
17619
17669
  message: "Invalid version: expected 1",
17620
17670
  path: ["version"]
17671
+ }).superRefine((data, ctx) => {
17672
+ const tierOrder = data.autoMode?.escalation?.tierOrder ?? [];
17673
+ const knownAgents = Object.keys(data.models ?? {});
17674
+ for (const [i, rung] of tierOrder.entries()) {
17675
+ if (rung.agent === undefined)
17676
+ continue;
17677
+ if (!knownAgents.includes(rung.agent)) {
17678
+ ctx.addIssue({
17679
+ code: "custom",
17680
+ path: ["autoMode", "escalation", "tierOrder", i, "agent"],
17681
+ message: `Agent "${rung.agent}" is not defined in config.models (known: ${knownAgents.join(", ")})`
17682
+ });
17683
+ } else {
17684
+ const agentTiers = data.models?.[rung.agent] ?? {};
17685
+ if (!(rung.tier in agentTiers)) {
17686
+ ctx.addIssue({
17687
+ code: "custom",
17688
+ path: ["autoMode", "escalation", "tierOrder", i, "tier"],
17689
+ message: `Tier "${rung.tier}" is not defined for agent "${rung.agent}" in config.models`
17690
+ });
17691
+ }
17692
+ }
17693
+ }
17694
+ const profiles = data.routing.agents?.profiles ?? [];
17695
+ for (const [pi, profile] of profiles.entries()) {
17696
+ const { agent: pAgent, model: pModel } = profile.target;
17697
+ const hasMatchingRung = tierOrder.some((r) => r.tier === pModel && r.agent === pAgent);
17698
+ if (!hasMatchingRung) {
17699
+ ctx.addIssue({
17700
+ code: "custom",
17701
+ path: ["routing", "agents", "profiles", pi, "target"],
17702
+ message: `Profile "${profile.id}" target (${pAgent}@${pModel}) has no matching rung in autoMode.escalation.tierOrder \u2014 escalation from this profile has no defined path. To fix: agent-qualify the ladder by adding a rung { "tier": "${pModel}", "agent": "${pAgent}", "attempts": <n> } (and an agent on every other rung) to autoMode.escalation.tierOrder.`
17703
+ });
17704
+ }
17705
+ if (!knownAgents.includes(pAgent)) {
17706
+ ctx.addIssue({
17707
+ code: "custom",
17708
+ path: ["routing", "agents", "profiles", pi, "target", "agent"],
17709
+ message: `Profile "${profile.id}" target agent "${pAgent}" is not defined in config.models`
17710
+ });
17711
+ }
17712
+ }
17621
17713
  });
17622
17714
  });
17623
17715
 
@@ -19140,7 +19232,7 @@ var reviewConfigSelector, planConfigSelector, decomposeConfigSelector, rectifyCo
19140
19232
  var init_selectors = __esm(() => {
19141
19233
  reviewConfigSelector = pickSelector("review", "review", "debate", "models", "execution", "project", "quality", "agent");
19142
19234
  planConfigSelector = pickSelector("plan", "plan", "debate", "agent", "project");
19143
- decomposeConfigSelector = pickSelector("decompose", "plan", "agent");
19235
+ decomposeConfigSelector = pickSelector("decompose", "plan", "agent", "routing");
19144
19236
  rectifyConfigSelector = pickSelector("rectify", "execution");
19145
19237
  acceptanceConfigSelector = pickSelector("acceptance", "acceptance");
19146
19238
  acceptanceFixConfigSelector = pickSelector("acceptance-fix", "acceptance", "execution");
@@ -19452,6 +19544,7 @@ __export(exports_config, {
19452
19544
  acceptanceFixConfigSelector: () => acceptanceFixConfigSelector,
19453
19545
  acceptanceConfigSelector: () => acceptanceConfigSelector,
19454
19546
  VALID_TEST_STRATEGIES: () => VALID_TEST_STRATEGIES,
19547
+ TierConfigSchema: () => TierConfigSchema,
19455
19548
  TddConfigSchema: () => TddConfigSchema,
19456
19549
  THREE_SESSION_STRATEGIES: () => THREE_SESSION_STRATEGIES,
19457
19550
  TEST_STRATEGY_GUIDE: () => TEST_STRATEGY_GUIDE,
@@ -19467,12 +19560,15 @@ __export(exports_config, {
19467
19560
  DEFAULT_CONFIG: () => DEFAULT_CONFIG,
19468
19561
  ConfiguredModelSchema: () => ConfiguredModelSchema,
19469
19562
  COMPLEXITY_GUIDE: () => COMPLEXITY_GUIDE,
19563
+ AgentRoutingProfileSchema: () => AgentRoutingProfileSchema,
19564
+ AgentRoutingConfigSchema: () => AgentRoutingConfigSchema,
19470
19565
  AcceptanceConfigSchema: () => AcceptanceConfigSchema,
19471
19566
  AC_QUALITY_RULES: () => AC_QUALITY_RULES
19472
19567
  });
19473
19568
  var init_config = __esm(() => {
19474
19569
  init_schema();
19475
19570
  init_schemas_model();
19571
+ init_schemas_infra();
19476
19572
  init_schemas_debate();
19477
19573
  init_schemas_execution();
19478
19574
  init_loader();
@@ -29887,6 +29983,73 @@ var init_builder = __esm(() => {
29887
29983
  };
29888
29984
  });
29889
29985
 
29986
+ // src/context/greenfield.ts
29987
+ async function gitLsFiles2(workdir) {
29988
+ try {
29989
+ const proc = _greenfieldDeps.spawn(["git", "ls-files"], {
29990
+ cwd: workdir,
29991
+ stdout: "pipe",
29992
+ stderr: "pipe"
29993
+ });
29994
+ const exitCode = await proc.exited;
29995
+ if (exitCode !== 0)
29996
+ return null;
29997
+ const output = await new Response(proc.stdout).text();
29998
+ return output.split(`
29999
+ `).filter(Boolean);
30000
+ } catch {
30001
+ return null;
30002
+ }
30003
+ }
30004
+ async function hasTestFiles(workdir, patterns) {
30005
+ const files = await gitLsFiles2(workdir);
30006
+ if (files !== null) {
30007
+ return files.some((f) => isTestFileByPatterns(f, patterns));
30008
+ }
30009
+ for (const pattern of patterns) {
30010
+ const g = new Bun.Glob(pattern);
30011
+ for await (const path3 of g.scan({ cwd: workdir, onlyFiles: true })) {
30012
+ if (!path3.split("/").some((seg) => IGNORE_DIRS.has(seg))) {
30013
+ return true;
30014
+ }
30015
+ }
30016
+ }
30017
+ return false;
30018
+ }
30019
+ async function isGreenfieldStory(_story, workdir, patterns) {
30020
+ try {
30021
+ return !await hasTestFiles(workdir, patterns ?? DEFAULT_TEST_FILE_PATTERNS);
30022
+ } catch {
30023
+ return false;
30024
+ }
30025
+ }
30026
+ var _greenfieldDeps, IGNORE_DIRS;
30027
+ var init_greenfield = __esm(() => {
30028
+ init_test_runners();
30029
+ _greenfieldDeps = {
30030
+ spawn: Bun.spawn
30031
+ };
30032
+ IGNORE_DIRS = new Set([
30033
+ "node_modules",
30034
+ "dist",
30035
+ ".next",
30036
+ ".nuxt",
30037
+ ".cache",
30038
+ "coverage",
30039
+ "vendor",
30040
+ "__pycache__",
30041
+ ".venv",
30042
+ "venv",
30043
+ ".eggs",
30044
+ "target",
30045
+ ".gradle",
30046
+ "out",
30047
+ "tmp",
30048
+ "temp",
30049
+ ".git"
30050
+ ]);
30051
+ });
30052
+
29890
30053
  // src/context/index.ts
29891
30054
  var init_context = __esm(() => {
29892
30055
  init_feature_resolver();
@@ -29896,6 +30059,7 @@ var init_context = __esm(() => {
29896
30059
  init_engine();
29897
30060
  init_test_scanner();
29898
30061
  init_auto_detect();
30062
+ init_greenfield();
29899
30063
  });
29900
30064
 
29901
30065
  // src/prompts/core/section-accumulator.ts
@@ -34834,36 +34998,40 @@ ${outputFormat}`,
34834
34998
 
34835
34999
  // src/agents/shared/decompose.ts
34836
35000
  function parseDecomposeOutput(output) {
34837
- const jsonMatch = output.match(/```(?:json)?\s*(\[[\s\S]*?\])\s*```/);
34838
- let jsonText = jsonMatch ? jsonMatch[1] : output;
34839
- if (!jsonMatch) {
34840
- const arrayMatch = output.match(/\[[\s\S]*\]/);
34841
- if (arrayMatch) {
34842
- jsonText = arrayMatch[0];
34843
- }
34844
- }
34845
35001
  let parsed;
34846
35002
  try {
34847
- parsed = JSON.parse(jsonText.trim());
35003
+ parsed = parseLLMJson(output);
34848
35004
  } catch (error48) {
34849
- throw new Error(`Failed to parse decompose output as JSON: ${error48.message}
34850
-
34851
- Output:
34852
- ${output.slice(0, 500)}`);
35005
+ throw new NaxError("Failed to parse decompose output as JSON", "DECOMPOSE_PARSE_FAILED", {
35006
+ stage: "decompose",
35007
+ outputSnippet: output.slice(0, 500),
35008
+ cause: error48
35009
+ });
34853
35010
  }
34854
35011
  if (!Array.isArray(parsed)) {
34855
- throw new Error("Decompose output is not an array");
35012
+ throw new NaxError("Decompose output is not an array", "DECOMPOSE_PARSE_FAILED", {
35013
+ stage: "decompose"
35014
+ });
34856
35015
  }
34857
35016
  const stories = parsed.map((item, index) => {
34858
35017
  if (typeof item !== "object" || item === null) {
34859
- throw new Error(`Story at index ${index} is not an object`);
35018
+ throw new NaxError(`Story at index ${index} is not an object`, "DECOMPOSE_PARSE_FAILED", {
35019
+ stage: "decompose",
35020
+ index
35021
+ });
34860
35022
  }
34861
35023
  const record2 = item;
34862
35024
  if (!record2.id || typeof record2.id !== "string") {
34863
- throw new Error(`Story at index ${index} missing valid 'id' field`);
35025
+ throw new NaxError(`Story at index ${index} missing valid 'id' field`, "DECOMPOSE_PARSE_FAILED", {
35026
+ stage: "decompose",
35027
+ index
35028
+ });
34864
35029
  }
34865
35030
  if (!record2.title || typeof record2.title !== "string") {
34866
- throw new Error(`Story ${record2.id} missing valid 'title' field`);
35031
+ throw new NaxError(`Story ${record2.id} missing valid 'title' field`, "DECOMPOSE_PARSE_FAILED", {
35032
+ stage: "decompose",
35033
+ storyId: record2.id
35034
+ });
34867
35035
  }
34868
35036
  return {
34869
35037
  id: record2.id,
@@ -34878,11 +35046,14 @@ ${output.slice(0, 500)}`);
34878
35046
  reasoning: String(record2.reasoning || "No reasoning provided"),
34879
35047
  estimatedLOC: Number(record2.estimatedLOC) || 0,
34880
35048
  risks: Array.isArray(record2.risks) ? record2.risks : [],
34881
- testStrategy: resolveTestStrategy(typeof record2.testStrategy === "string" ? record2.testStrategy : undefined)
35049
+ testStrategy: resolveTestStrategy(typeof record2.testStrategy === "string" ? record2.testStrategy : undefined),
35050
+ agentProfileId: typeof record2.agentProfileId === "string" && record2.agentProfileId.length > 0 ? record2.agentProfileId : undefined
34882
35051
  };
34883
35052
  });
34884
35053
  if (stories.length === 0) {
34885
- throw new Error("Decompose returned empty story array");
35054
+ throw new NaxError("Decompose returned empty story array", "DECOMPOSE_PARSE_FAILED", {
35055
+ stage: "decompose"
35056
+ });
34886
35057
  }
34887
35058
  return stories;
34888
35059
  }
@@ -34893,7 +35064,8 @@ function coerceComplexity(value) {
34893
35064
  return "medium";
34894
35065
  }
34895
35066
  var init_decompose = __esm(() => {
34896
- init_test_strategy();
35067
+ init_config();
35068
+ init_errors();
34897
35069
  });
34898
35070
 
34899
35071
  // src/agents/shared/decompose-prompt.ts
@@ -34932,10 +35104,10 @@ function buildPlanModePromptSync(input) {
34932
35104
  `);
34933
35105
  builder = builder.inputData("Sibling Stories", siblingsSummary);
34934
35106
  }
34935
- return builder.jsonSchema(DECOMPOSE_PLAN_SCHEMA).build();
35107
+ return builder.agentProfiles(input.profiles ?? []).jsonSchema(DECOMPOSE_PLAN_SCHEMA).build();
34936
35108
  }
34937
35109
  function buildSpecModePromptSync(input) {
34938
- return OneShotPromptBuilder.for("decomposer").instructions(SPEC_DECOMPOSE_INSTRUCTIONS).inputData("Codebase Context", input.codebaseContext).inputData("Feature Specification", input.specContent).jsonSchema(DECOMPOSE_SPEC_SCHEMA).build();
35110
+ return OneShotPromptBuilder.for("decomposer").instructions(SPEC_DECOMPOSE_INSTRUCTIONS).inputData("Codebase Context", input.codebaseContext).inputData("Feature Specification", input.specContent).agentProfiles(input.profiles ?? []).jsonSchema(DECOMPOSE_SPEC_SCHEMA).build();
34939
35111
  }
34940
35112
  async function buildPlanModePrompt(options) {
34941
35113
  const targetStory = options.targetStory;
@@ -34948,10 +35120,10 @@ async function buildPlanModePrompt(options) {
34948
35120
  `);
34949
35121
  builder = builder.inputData("Sibling Stories", siblingsSummary);
34950
35122
  }
34951
- return builder.jsonSchema(DECOMPOSE_PLAN_SCHEMA).build();
35123
+ return builder.agentProfiles(options.profiles ?? []).jsonSchema(DECOMPOSE_PLAN_SCHEMA).build();
34952
35124
  }
34953
35125
  async function buildSpecModePrompt(options) {
34954
- return OneShotPromptBuilder.for("decomposer").instructions(SPEC_DECOMPOSE_INSTRUCTIONS).inputData("Codebase Context", options.codebaseContext).inputData("Feature Specification", options.specContent).jsonSchema(DECOMPOSE_SPEC_SCHEMA).build();
35126
+ return OneShotPromptBuilder.for("decomposer").instructions(SPEC_DECOMPOSE_INSTRUCTIONS).inputData("Codebase Context", options.codebaseContext).inputData("Feature Specification", options.specContent).agentProfiles(options.profiles ?? []).jsonSchema(DECOMPOSE_SPEC_SCHEMA).build();
34955
35127
  }
34956
35128
  var DECOMPOSE_SPEC_SCHEMA, DECOMPOSE_PLAN_SCHEMA, SPEC_DECOMPOSE_INSTRUCTIONS;
34957
35129
  var init_decompose_prompt = __esm(() => {
@@ -34973,7 +35145,8 @@ var init_decompose_prompt = __esm(() => {
34973
35145
  reasoning: "Why this complexity level",
34974
35146
  estimatedLOC: 150,
34975
35147
  risks: ["Risk 1"],
34976
- testStrategy: "test-after"
35148
+ testStrategy: "test-after",
35149
+ agentProfileId: ""
34977
35150
  }
34978
35151
  ]
34979
35152
  };
@@ -34993,7 +35166,8 @@ var init_decompose_prompt = __esm(() => {
34993
35166
  reasoning: "Why this complexity",
34994
35167
  estimatedLOC: 0,
34995
35168
  risks: [],
34996
- testStrategy: "no-test | tdd-simple | three-session-tdd-lite | three-session-tdd | test-after"
35169
+ testStrategy: "no-test | tdd-simple | three-session-tdd-lite | three-session-tdd | test-after",
35170
+ agentProfileId: ""
34997
35171
  }
34998
35172
  ]
34999
35173
  };
@@ -35013,6 +35187,7 @@ For each story, provide:
35013
35187
  11. risks: Array of implementation risks
35014
35188
  12. testStrategy: "no-test" | "test-after" | "tdd-simple" | "three-session-tdd" | "three-session-tdd-lite"
35015
35189
  13. noTestJustification: string (REQUIRED when testStrategy is "no-test" \u2014 explain why tests are unnecessary)
35190
+ 14. agentProfileId: (optional) profile id from the Agent Profiles table \u2014 assign the best-matching profile for each story; omit if no profiles are listed or none fits well
35016
35191
 
35017
35192
  ${COMPLEXITY_GUIDE}
35018
35193
 
@@ -35028,11 +35203,15 @@ Consider:
35028
35203
  });
35029
35204
 
35030
35205
  // src/operations/decompose.ts
35031
- var decomposeOp;
35206
+ var _decomposeOpDeps, decomposeOp;
35032
35207
  var init_decompose2 = __esm(() => {
35033
35208
  init_decompose();
35034
35209
  init_decompose_prompt();
35035
35210
  init_config();
35211
+ init_logger2();
35212
+ _decomposeOpDeps = {
35213
+ getSafeLogger
35214
+ };
35036
35215
  decomposeOp = {
35037
35216
  kind: "complete",
35038
35217
  name: "decompose",
@@ -35041,21 +35220,62 @@ var init_decompose2 = __esm(() => {
35041
35220
  config: decomposeConfigSelector,
35042
35221
  model: (_input, ctx) => ctx.config.plan.model,
35043
35222
  timeoutMs: (_input, ctx) => (ctx.config.plan.decomposeTimeoutSeconds ?? ctx.config.plan.timeoutSeconds ?? 600) * 1000,
35044
- build(input, _ctx) {
35223
+ build(input, ctx) {
35224
+ const agentRouting = ctx.config.routing?.agents;
35225
+ const profiles = agentRouting?.enabled === true ? agentRouting.profiles ?? [] : [];
35045
35226
  const prompt = buildDecomposePromptSync({
35046
35227
  specContent: input.specContent,
35047
35228
  codebaseContext: input.codebaseContext,
35048
35229
  targetStory: input.targetStory,
35049
35230
  siblings: input.siblings,
35050
- maxAcCount: input.maxAcCount
35231
+ maxAcCount: input.maxAcCount,
35232
+ profiles
35051
35233
  });
35052
35234
  return {
35053
35235
  role: { id: "role", content: "", overridable: false },
35054
35236
  task: { id: "task", content: prompt, overridable: false }
35055
35237
  };
35056
35238
  },
35057
- parse(output, _input, _ctx) {
35058
- return parseDecomposeOutput(output);
35239
+ parse(output, _input, ctx) {
35240
+ const stories = parseDecomposeOutput(output);
35241
+ const agentRouting = ctx.config.routing?.agents;
35242
+ if (agentRouting?.enabled !== true) {
35243
+ return stories;
35244
+ }
35245
+ const profiles = agentRouting.profiles ?? [];
35246
+ if (profiles.length === 0) {
35247
+ return stories;
35248
+ }
35249
+ const defaultProfile = agentRouting.default ? profiles.find((p) => p.id === agentRouting.default) : undefined;
35250
+ return stories.map((story) => {
35251
+ if (story.agentProfileId) {
35252
+ const profile = profiles.find((p) => p.id === story.agentProfileId);
35253
+ if (profile) {
35254
+ return {
35255
+ ...story,
35256
+ routing: {
35257
+ ...story.routing,
35258
+ agent: profile.target.agent,
35259
+ agentProfileId: profile.id,
35260
+ profileModelTier: profile.target.model
35261
+ }
35262
+ };
35263
+ }
35264
+ _decomposeOpDeps.getSafeLogger()?.warn("decompose", `Story ${story.id} selected unknown agent profile "${story.agentProfileId}" \u2014 falling back to ${defaultProfile ? `default profile "${defaultProfile.id}"` : "no profile"}`, { storyId: story.id, agentProfileId: story.agentProfileId });
35265
+ }
35266
+ if (defaultProfile) {
35267
+ return {
35268
+ ...story,
35269
+ routing: {
35270
+ ...story.routing,
35271
+ agent: defaultProfile.target.agent,
35272
+ agentProfileId: defaultProfile.id,
35273
+ profileModelTier: defaultProfile.target.model
35274
+ }
35275
+ };
35276
+ }
35277
+ return story;
35278
+ });
35059
35279
  }
35060
35280
  };
35061
35281
  });
@@ -35471,6 +35691,7 @@ __export(exports_routing, {
35471
35691
  resolveRouting: () => resolveRouting,
35472
35692
  determineTestStrategy: () => determineTestStrategy,
35473
35693
  complexityToModelTier: () => complexityToModelTier,
35694
+ clearCache: () => clearCache,
35474
35695
  classifyComplexity: () => classifyComplexity,
35475
35696
  _tryLlmBatchRouteDeps: () => _tryLlmBatchRouteDeps,
35476
35697
  ROUTING_INSTRUCTIONS: () => ROUTING_INSTRUCTIONS
@@ -38442,73 +38663,6 @@ var init_plan_critic_llm = __esm(() => {
38442
38663
  };
38443
38664
  });
38444
38665
 
38445
- // src/context/greenfield.ts
38446
- async function gitLsFiles2(workdir) {
38447
- try {
38448
- const proc = _greenfieldDeps.spawn(["git", "ls-files"], {
38449
- cwd: workdir,
38450
- stdout: "pipe",
38451
- stderr: "pipe"
38452
- });
38453
- const exitCode = await proc.exited;
38454
- if (exitCode !== 0)
38455
- return null;
38456
- const output = await new Response(proc.stdout).text();
38457
- return output.split(`
38458
- `).filter(Boolean);
38459
- } catch {
38460
- return null;
38461
- }
38462
- }
38463
- async function hasTestFiles(workdir, patterns) {
38464
- const files = await gitLsFiles2(workdir);
38465
- if (files !== null) {
38466
- return files.some((f) => isTestFileByPatterns(f, patterns));
38467
- }
38468
- for (const pattern of patterns) {
38469
- const g = new Bun.Glob(pattern);
38470
- for await (const path5 of g.scan({ cwd: workdir, onlyFiles: true })) {
38471
- if (!path5.split("/").some((seg) => IGNORE_DIRS.has(seg))) {
38472
- return true;
38473
- }
38474
- }
38475
- }
38476
- return false;
38477
- }
38478
- async function isGreenfieldStory(_story, workdir, patterns) {
38479
- try {
38480
- return !await hasTestFiles(workdir, patterns ?? DEFAULT_TEST_FILE_PATTERNS);
38481
- } catch {
38482
- return false;
38483
- }
38484
- }
38485
- var _greenfieldDeps, IGNORE_DIRS;
38486
- var init_greenfield = __esm(() => {
38487
- init_test_runners();
38488
- _greenfieldDeps = {
38489
- spawn: Bun.spawn
38490
- };
38491
- IGNORE_DIRS = new Set([
38492
- "node_modules",
38493
- "dist",
38494
- ".next",
38495
- ".nuxt",
38496
- ".cache",
38497
- "coverage",
38498
- "vendor",
38499
- "__pycache__",
38500
- ".venv",
38501
- "venv",
38502
- ".eggs",
38503
- "target",
38504
- ".gradle",
38505
- "out",
38506
- "tmp",
38507
- "temp",
38508
- ".git"
38509
- ]);
38510
- });
38511
-
38512
38666
  // src/operations/greenfield-gate.ts
38513
38667
  var greenfieldGateConfigSelector, greenfieldGateOp;
38514
38668
  var init_greenfield_gate = __esm(() => {
@@ -42879,9 +43033,59 @@ ${body}`
42879
43033
  this.acc.add(jsonSchemaSection(schema));
42880
43034
  return this;
42881
43035
  }
43036
+ agentProfiles(profiles) {
43037
+ const cards = OneShotPromptBuilder.agentCapabilityCards(profiles);
43038
+ if (cards.length === 0)
43039
+ return this;
43040
+ this.acc.add({
43041
+ id: "agent-profiles",
43042
+ overridable: false,
43043
+ content: `${cards}
43044
+
43045
+ ${OneShotPromptBuilder.agentProfileInstruction()}`
43046
+ });
43047
+ return this;
43048
+ }
42882
43049
  build() {
42883
43050
  return this.acc.join();
42884
43051
  }
43052
+ static agentProfileInstruction() {
43053
+ return [
43054
+ "When agent profiles are listed above, pick exactly ONE profile id per story and set it on the `agentProfileId` field. Apply these steps in order:",
43055
+ "1. Eliminate any profile whose weaknesses conflict with the story.",
43056
+ "2. Keep profiles whose strengths or affinity cover the story's main job (task type + primary domain).",
43057
+ "3. If more than one remains, choose the LOWEST cost profile.",
43058
+ "4. If none clearly fit, omit `agentProfileId` entirely \u2014 never invent a profile id."
43059
+ ].join(`
43060
+ `);
43061
+ }
43062
+ static agentCapabilityCards(profiles) {
43063
+ if (profiles.length === 0)
43064
+ return "";
43065
+ const header = [
43066
+ "## Agent Profiles",
43067
+ "",
43068
+ "| ID | Agent | Tier | Strengths | Weaknesses | Affinity | Cost |",
43069
+ "|---|---|---|---|---|---|---|"
43070
+ ];
43071
+ const rows = profiles.map((p) => {
43072
+ const esc2 = OneShotPromptBuilder.escapeCell;
43073
+ const id = esc2(p.id);
43074
+ const agent = esc2(p.target.agent);
43075
+ const model = esc2(p.target.model);
43076
+ const strengths = p.strengths.map(esc2).join(", ");
43077
+ const weaknesses = p.weaknesses?.length ? p.weaknesses.map(esc2).join("; ") : "\u2014";
43078
+ const affinityParts = [...p.affinity?.taskTypes ?? [], ...p.affinity?.domains ?? []];
43079
+ const affinity = affinityParts.length ? affinityParts.map(esc2).join(", ") : "\u2014";
43080
+ const cost = esc2(p.costTier ?? "\u2014");
43081
+ return `| ${id} | ${agent} | ${model} | ${strengths} | ${weaknesses} | ${affinity} | ${cost} |`;
43082
+ });
43083
+ return [...header, ...rows].join(`
43084
+ `);
43085
+ }
43086
+ static escapeCell(value) {
43087
+ return value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
43088
+ }
42885
43089
  }
42886
43090
  var init_one_shot_builder = __esm(() => {
42887
43091
  init_core3();
@@ -51577,10 +51781,9 @@ function mapDecomposedStoriesToUserStories(stories, parentStoryId, parentWorkdir
51577
51781
  });
51578
51782
  }
51579
51783
  if (!story.contextFiles || story.contextFiles.length === 0) {
51580
- throw new NaxError(`Entry ${entryIndex} (${story.id}) has empty contextFiles`, "DECOMPOSE_VALIDATION_FAILED", {
51581
- stage: "decompose-mapper",
51582
- entryIndex,
51784
+ getSafeLogger()?.warn("decompose-mapper", `Entry ${entryIndex} (${story.id}) has empty contextFiles \u2014 continuing`, {
51583
51785
  storyId: story.id,
51786
+ entryIndex,
51584
51787
  parentStoryId
51585
51788
  });
51586
51789
  }
@@ -51602,13 +51805,17 @@ function mapDecomposedStoriesToUserStories(stories, parentStoryId, parentWorkdir
51602
51805
  complexity: story.complexity,
51603
51806
  testStrategy: story.testStrategy ?? "test-after",
51604
51807
  reasoning: story.reasoning,
51605
- modelTier: "balanced"
51808
+ modelTier: story.routing?.profileModelTier ?? "balanced",
51809
+ ...story.routing?.agent !== undefined && { agent: story.routing.agent },
51810
+ ...story.routing?.agentProfileId !== undefined && { agentProfileId: story.routing.agentProfileId },
51811
+ ...story.routing?.profileModelTier !== undefined && { profileModelTier: story.routing.profileModelTier }
51606
51812
  }
51607
51813
  };
51608
51814
  });
51609
51815
  }
51610
51816
  var init_decompose_mapper = __esm(() => {
51611
51817
  init_errors();
51818
+ init_logger2();
51612
51819
  });
51613
51820
 
51614
51821
  // src/cli/plan-decompose.ts
@@ -51650,8 +51857,12 @@ async function planDecomposeCommand(workdir, config2, options) {
51650
51857
  const rt = createPlanRuntime(config2, workdir, options.feature);
51651
51858
  const agentManager = rt.agentManager;
51652
51859
  const adapterForCapCheck = agentManager.getAgent(agentName);
51653
- if (!adapterForCapCheck)
51654
- throw new Error(`[decompose] No agent adapter found for '${agentName}'`);
51860
+ if (!adapterForCapCheck) {
51861
+ throw new NaxError(`No agent adapter found for '${agentName}'`, "AGENT_NOT_FOUND", {
51862
+ stage: "decompose",
51863
+ agentName
51864
+ });
51865
+ }
51655
51866
  const timeoutSeconds = config2?.plan?.timeoutSeconds ?? DEFAULT_TIMEOUT_SECONDS2;
51656
51867
  const maxAcCount = config2?.precheck?.storySizeGate?.maxAcCount ?? Number.POSITIVE_INFINITY;
51657
51868
  const maxReplanAttempts = config2?.precheck?.storySizeGate?.maxReplanAttempts ?? 3;
@@ -51663,6 +51874,8 @@ async function planDecomposeCommand(workdir, config2, options) {
51663
51874
  for (let attempt = 0;attempt < maxReplanAttempts; attempt++) {
51664
51875
  if (attempt === 0 && debateDecompEnabled) {
51665
51876
  const decomposeStageConfig = debateStages.decompose;
51877
+ const agentRoutingForDebate = config2.routing?.agents;
51878
+ const profilesForDebate = agentRoutingForDebate?.enabled === true ? agentRoutingForDebate.profiles ?? [] : [];
51666
51879
  const prompt = await buildDecomposePromptAsync({
51667
51880
  specContent: "",
51668
51881
  codebaseContext,
@@ -51671,7 +51884,8 @@ async function planDecomposeCommand(workdir, config2, options) {
51671
51884
  siblings,
51672
51885
  featureName: options.feature,
51673
51886
  storyId: options.storyId,
51674
- maxAcCount: config2?.precheck?.storySizeGate?.maxAcCount
51887
+ maxAcCount: config2?.precheck?.storySizeGate?.maxAcCount,
51888
+ profiles: profilesForDebate
51675
51889
  });
51676
51890
  const decompCallCtx = {
51677
51891
  runtime: rt,
@@ -51744,7 +51958,11 @@ ${repairHint}` : codebaseContext;
51744
51958
  ...subStoriesWithParent,
51745
51959
  ...updatedStories.slice(originalIndex + 1)
51746
51960
  ];
51747
- const updatedPrd = { ...prd, userStories: finalStories };
51961
+ const updatedPrd = {
51962
+ ...prd,
51963
+ userStories: finalStories,
51964
+ routingProfile: config2.profile ?? "default"
51965
+ };
51748
51966
  await _planDeps.writeFile(prdPath, JSON.stringify(updatedPrd, null, 2));
51749
51967
  return () => {};
51750
51968
  }
@@ -52681,6 +52899,103 @@ var init_semantic_verdict = __esm(() => {
52681
52899
  });
52682
52900
 
52683
52901
  // src/acceptance/hardening.ts
52902
+ import path10 from "path";
52903
+ async function processPackageGroup(ctx, packageDir, groupStories, language, result) {
52904
+ const logger = getSafeLogger();
52905
+ const groupRefined = [];
52906
+ for (const story of groupStories) {
52907
+ const callCtx = {
52908
+ runtime: ctx.runtime,
52909
+ packageView: ctx.runtime.packages.resolve(packageDir),
52910
+ packageDir,
52911
+ storyId: story.id,
52912
+ featureName: ctx.prd.feature,
52913
+ agentName: ctx.agentManager.getDefault()
52914
+ };
52915
+ const refined = await _hardeningDeps.callOp(callCtx, acceptanceRefineOp, {
52916
+ criteria: story.suggestedCriteria ?? [],
52917
+ codebaseContext: "",
52918
+ storyId: story.id,
52919
+ testStrategy: ctx.config.acceptance?.testStrategy,
52920
+ testFramework: ctx.config.acceptance?.testFramework,
52921
+ storyTitle: story.title,
52922
+ storyDescription: story.description
52923
+ });
52924
+ groupRefined.push(...refined);
52925
+ }
52926
+ const suggestedTestPath = resolveSuggestedPackageFeatureTestPath(packageDir, ctx.prd.feature, ctx.config.acceptance?.suggestedTestPath, language);
52927
+ const criteriaList = groupRefined.map((c, i) => `AC-${i + 1}: ${c.refined}`).join(`
52928
+ `);
52929
+ const frameworkOverrideLine = ctx.config.acceptance?.testFramework ? `
52930
+ [FRAMEWORK OVERRIDE: Use ${ctx.config.acceptance.testFramework} as the test framework regardless of what you detect.]` : "";
52931
+ const genCallCtx = {
52932
+ runtime: ctx.runtime,
52933
+ packageView: ctx.runtime.packages.resolve(packageDir),
52934
+ packageDir,
52935
+ storyId: groupStories[0]?.id,
52936
+ featureName: ctx.prd.feature,
52937
+ agentName: ctx.agentManager.getDefault()
52938
+ };
52939
+ const genResult = await _hardeningDeps.callOp(genCallCtx, acceptanceGenerateOp, {
52940
+ featureName: ctx.prd.feature,
52941
+ criteriaList,
52942
+ frameworkOverrideLine,
52943
+ targetTestFilePath: suggestedTestPath
52944
+ });
52945
+ let testCode = genResult.testCode;
52946
+ if (!testCode) {
52947
+ const skeletonCriteria = groupRefined.map((c, i) => ({
52948
+ id: `AC-${i + 1}`,
52949
+ text: c.refined,
52950
+ lineNumber: i + 1
52951
+ }));
52952
+ testCode = generateSkeletonTests(ctx.prd.feature, skeletonCriteria, ctx.config.acceptance?.testFramework, language);
52953
+ logger?.warn("acceptance", "Hardening generate op returned no test code \u2014 using skeleton", {
52954
+ storyIds: groupStories.map((s) => s.id),
52955
+ storiesProcessed: groupStories.length
52956
+ });
52957
+ }
52958
+ await _hardeningDeps.writeFile(suggestedTestPath, testCode);
52959
+ const testCmd = buildAcceptanceRunCommand(suggestedTestPath, ctx.config.project?.testFramework, ctx.config.acceptance?.command, packageDir);
52960
+ const proc = _hardeningDeps.spawn(testCmd, { cwd: packageDir, stdout: "pipe", stderr: "pipe" });
52961
+ const [exitCode, stdout, stderr] = await Promise.all([
52962
+ proc.exited,
52963
+ new Response(proc.stdout).text(),
52964
+ new Response(proc.stderr).text()
52965
+ ]);
52966
+ const output = `${stdout}
52967
+ ${stderr}`;
52968
+ const failedACs = parseTestFailures(output);
52969
+ const failedSet = new Set(failedACs.map((ac) => ac.toUpperCase()));
52970
+ const refinedByStory = new Map;
52971
+ for (const r of groupRefined) {
52972
+ const list = refinedByStory.get(r.storyId) ?? [];
52973
+ list.push(r);
52974
+ refinedByStory.set(r.storyId, list);
52975
+ }
52976
+ let acIndex = 0;
52977
+ for (const story of groupStories) {
52978
+ const storyRefined = refinedByStory.get(story.id) ?? [];
52979
+ const toPromote = [];
52980
+ const toDiscard = [];
52981
+ for (const refined of storyRefined) {
52982
+ acIndex++;
52983
+ const acId = `AC-${acIndex}`;
52984
+ if (refined.testable === false || failedSet.has(acId) || exitCode !== 0 && failedACs.length === 0) {
52985
+ toDiscard.push(refined.original);
52986
+ } else {
52987
+ toPromote.push(refined.original);
52988
+ }
52989
+ }
52990
+ if (toPromote.length > 0) {
52991
+ const existingACs = new Set(story.acceptanceCriteria);
52992
+ story.acceptanceCriteria = [...story.acceptanceCriteria, ...toPromote.filter((ac) => !existingACs.has(ac))];
52993
+ result.promoted.push(...toPromote);
52994
+ }
52995
+ result.discarded.push(...toDiscard);
52996
+ story.suggestedCriteria = toDiscard.length > 0 ? toDiscard : undefined;
52997
+ }
52998
+ }
52684
52999
  async function runHardeningPass(ctx) {
52685
53000
  const logger = getSafeLogger();
52686
53001
  const result = { promoted: [], discarded: [] };
@@ -52693,105 +53008,17 @@ async function runHardeningPass(ctx) {
52693
53008
  totalSuggestedACs: storiesWithSuggested.reduce((n, s) => n + (s.suggestedCriteria?.length ?? 0), 0)
52694
53009
  });
52695
53010
  try {
52696
- const allRefined = [];
53011
+ const packageGroups = new Map;
52697
53012
  for (const story of storiesWithSuggested) {
52698
- const criteria = story.suggestedCriteria ?? [];
52699
- const callCtx = {
52700
- runtime: ctx.runtime,
52701
- packageView: ctx.runtime.packages.resolve(ctx.workdir),
52702
- packageDir: ctx.workdir,
52703
- storyId: story.id,
52704
- featureName: ctx.prd.feature,
52705
- agentName: ctx.agentManager.getDefault()
52706
- };
52707
- const refined = await _hardeningDeps.callOp(callCtx, acceptanceRefineOp, {
52708
- criteria,
52709
- codebaseContext: "",
52710
- storyId: story.id,
52711
- testStrategy: ctx.config.acceptance?.testStrategy,
52712
- testFramework: ctx.config.acceptance?.testFramework,
52713
- storyTitle: story.title,
52714
- storyDescription: story.description
52715
- });
52716
- allRefined.push(...refined);
52717
- }
52718
- const language = ctx.config.project?.language;
52719
- const suggestedTestPath = resolveSuggestedPackageFeatureTestPath(ctx.workdir, ctx.prd.feature, ctx.config.acceptance?.suggestedTestPath, language);
52720
- const criteriaList = allRefined.map((c, i) => `AC-${i + 1}: ${c.refined}`).join(`
52721
- `);
52722
- const frameworkOverrideLine = ctx.config.acceptance?.testFramework ? `
52723
- [FRAMEWORK OVERRIDE: Use ${ctx.config.acceptance.testFramework} as the test framework regardless of what you detect.]` : "";
52724
- const genCallCtx = {
52725
- runtime: ctx.runtime,
52726
- packageView: ctx.runtime.packages.resolve(ctx.workdir),
52727
- packageDir: ctx.workdir,
52728
- storyId: storiesWithSuggested[0]?.id,
52729
- featureName: ctx.prd.feature,
52730
- agentName: ctx.agentManager.getDefault()
52731
- };
52732
- const genResult = await _hardeningDeps.callOp(genCallCtx, acceptanceGenerateOp, {
52733
- featureName: ctx.prd.feature,
52734
- criteriaList,
52735
- frameworkOverrideLine,
52736
- targetTestFilePath: suggestedTestPath
52737
- });
52738
- let testCode = genResult.testCode;
52739
- if (!testCode) {
52740
- const skeletonCriteria = allRefined.map((c, i) => ({
52741
- id: `AC-${i + 1}`,
52742
- text: c.refined,
52743
- lineNumber: i + 1
52744
- }));
52745
- testCode = generateSkeletonTests(ctx.prd.feature, skeletonCriteria, ctx.config.acceptance?.testFramework, language);
52746
- logger?.warn("acceptance", "Hardening generate op returned no test code \u2014 using skeleton", {
52747
- storyIds: storiesWithSuggested.map((s) => s.id),
52748
- storiesProcessed: storiesWithSuggested.length
52749
- });
53013
+ const wd = story.workdir ?? "";
53014
+ if (!packageGroups.has(wd))
53015
+ packageGroups.set(wd, []);
53016
+ packageGroups.get(wd)?.push(story);
52750
53017
  }
52751
- await _hardeningDeps.writeFile(suggestedTestPath, testCode);
52752
- const testCmd = buildAcceptanceRunCommand(suggestedTestPath, ctx.config.project?.testFramework, ctx.config.acceptance?.command, ctx.workdir);
52753
- const proc = _hardeningDeps.spawn(testCmd, {
52754
- cwd: ctx.workdir,
52755
- stdout: "pipe",
52756
- stderr: "pipe"
52757
- });
52758
- const [exitCode, stdout, stderr] = await Promise.all([
52759
- proc.exited,
52760
- new Response(proc.stdout).text(),
52761
- new Response(proc.stderr).text()
52762
- ]);
52763
- const output = `${stdout}
52764
- ${stderr}`;
52765
- const failedACs = parseTestFailures(output);
52766
- const failedSet = new Set(failedACs.map((ac) => ac.toUpperCase()));
52767
- const refinedByStory = new Map;
52768
- for (const r of allRefined) {
52769
- const list = refinedByStory.get(r.storyId) ?? [];
52770
- list.push(r);
52771
- refinedByStory.set(r.storyId, list);
52772
- }
52773
- let acIndex = 0;
52774
- for (const story of storiesWithSuggested) {
52775
- const storyRefined = refinedByStory.get(story.id) ?? [];
52776
- const toPromote = [];
52777
- const toDiscard = [];
52778
- for (const refinedCriterion of storyRefined) {
52779
- acIndex++;
52780
- const acId = `AC-${acIndex}`;
52781
- const nonTestable = refinedCriterion.testable === false;
52782
- if (nonTestable || failedSet.has(acId) || exitCode !== 0 && failedACs.length === 0) {
52783
- toDiscard.push(refinedCriterion.original);
52784
- } else {
52785
- toPromote.push(refinedCriterion.original);
52786
- }
52787
- }
52788
- if (toPromote.length > 0) {
52789
- const existingACs = new Set(story.acceptanceCriteria);
52790
- story.acceptanceCriteria = [...story.acceptanceCriteria, ...toPromote.filter((ac) => !existingACs.has(ac))];
52791
- result.promoted.push(...toPromote);
52792
- }
52793
- result.discarded.push(...toDiscard);
52794
- story.suggestedCriteria = toDiscard.length > 0 ? toDiscard : undefined;
53018
+ for (const [wd, groupStories] of packageGroups.entries()) {
53019
+ const packageDir = wd ? path10.join(ctx.workdir, wd) : ctx.workdir;
53020
+ const detectedLang = await _hardeningDeps.detectLanguage(packageDir);
53021
+ await processPackageGroup(ctx, packageDir, groupStories, detectedLang ?? ctx.config.project?.language, result);
52795
53022
  }
52796
53023
  if (result.promoted.length > 0) {
52797
53024
  await _hardeningDeps.savePRD(ctx.prd, ctx.prdPath);
@@ -52816,6 +53043,7 @@ var init_hardening = __esm(() => {
52816
53043
  init_logger2();
52817
53044
  init_operations();
52818
53045
  init_prd();
53046
+ init_detector();
52819
53047
  init_ac_parser();
52820
53048
  init_generator();
52821
53049
  init_test_path();
@@ -52825,7 +53053,8 @@ var init_hardening = __esm(() => {
52825
53053
  spawn: Bun.spawn,
52826
53054
  writeFile: async (p, c) => {
52827
53055
  await Bun.write(p, c);
52828
- }
53056
+ },
53057
+ detectLanguage
52829
53058
  };
52830
53059
  });
52831
53060
 
@@ -53079,7 +53308,7 @@ __export(exports_acceptance_setup, {
53079
53308
  acceptanceSetupStage: () => acceptanceSetupStage,
53080
53309
  _acceptanceSetupDeps: () => _acceptanceSetupDeps
53081
53310
  });
53082
- import path10 from "path";
53311
+ import path11 from "path";
53083
53312
  function computeACFingerprint(criteria) {
53084
53313
  const sorted = [...criteria].sort().join(`
53085
53314
  `);
@@ -53152,7 +53381,7 @@ var init_acceptance_setup = __esm(() => {
53152
53381
  },
53153
53382
  autoCommitIfDirty,
53154
53383
  loadGroupConfig: async (projectDir, relativeWorkdir) => {
53155
- return loadConfigForWorkdir(path10.join(projectDir, ".nax", "config.json"), relativeWorkdir || undefined);
53384
+ return loadConfigForWorkdir(path11.join(projectDir, ".nax", "config.json"), relativeWorkdir || undefined);
53156
53385
  },
53157
53386
  runTest: async (_testPath, _workdir, _cmd) => {
53158
53387
  const cmd = _cmd;
@@ -53196,7 +53425,7 @@ ${stderr}` };
53196
53425
  }
53197
53426
  const language = ctx.config.project?.language;
53198
53427
  const testPathConfig = ctx.config.acceptance.testPath;
53199
- const metaPath = path10.join(ctx.featureDir, "acceptance-meta.json");
53428
+ const metaPath = path11.join(ctx.featureDir, "acceptance-meta.json");
53200
53429
  const allCriteria = ctx.prd.userStories.filter((s) => !s.id.startsWith("US-FIX-") && s.status !== "decomposed").flatMap((s) => s.acceptanceCriteria);
53201
53430
  const featureName = ctx.prd.feature ?? ctx.prd.featureName;
53202
53431
  const groups = await groupStoriesByPackage(ctx.prd, ctx.workdir, featureName, testPathConfig, language);
@@ -53311,7 +53540,7 @@ ${stderr}` };
53311
53540
  testable: c.testable,
53312
53541
  storyId: c.storyId
53313
53542
  })), null, 2);
53314
- await _acceptanceSetupDeps.writeFile(path10.join(ctx.featureDir, "acceptance-refined.json"), refinedJsonContent);
53543
+ await _acceptanceSetupDeps.writeFile(path11.join(ctx.featureDir, "acceptance-refined.json"), refinedJsonContent);
53315
53544
  }
53316
53545
  const fingerprint2 = computeACFingerprint(allCriteria);
53317
53546
  await _acceptanceSetupDeps.writeMeta(metaPath, {
@@ -53325,7 +53554,7 @@ ${stderr}` };
53325
53554
  }
53326
53555
  const acceptanceTestPaths = [];
53327
53556
  for (const g of groups) {
53328
- const relativeWorkdir = path10.relative(ctx.projectDir, g.packageDir);
53557
+ const relativeWorkdir = path11.relative(ctx.projectDir, g.packageDir);
53329
53558
  let groupConfig = ctx.config;
53330
53559
  if (relativeWorkdir && relativeWorkdir !== ".") {
53331
53560
  try {
@@ -53894,7 +54123,7 @@ var init_story_context = __esm(() => {
53894
54123
 
53895
54124
  // src/execution/lock.ts
53896
54125
  import { unlink as unlink2 } from "fs/promises";
53897
- import path11 from "path";
54126
+ import path12 from "path";
53898
54127
  function getSafeLogger3() {
53899
54128
  try {
53900
54129
  return getLogger();
@@ -53911,7 +54140,7 @@ function isProcessAlive(pid) {
53911
54140
  }
53912
54141
  }
53913
54142
  async function acquireLock(workdir) {
53914
- const lockPath = path11.join(workdir, "nax.lock");
54143
+ const lockPath = path12.join(workdir, "nax.lock");
53915
54144
  const lockFile = Bun.file(lockPath);
53916
54145
  try {
53917
54146
  const exists = await lockFile.exists();
@@ -53963,7 +54192,7 @@ async function acquireLock(workdir) {
53963
54192
  }
53964
54193
  }
53965
54194
  async function releaseLock(workdir) {
53966
- const lockPath = path11.join(workdir, "nax.lock");
54195
+ const lockPath = path12.join(workdir, "nax.lock");
53967
54196
  try {
53968
54197
  await unlink2(lockPath);
53969
54198
  } catch (error48) {
@@ -55523,6 +55752,16 @@ var init_plan_inputs = __esm(() => {
55523
55752
  });
55524
55753
 
55525
55754
  // src/pipeline/stages/execution-helpers.ts
55755
+ function resolveExecutionAgent(opts) {
55756
+ const { routedAgent, defaultAgent, getAgent } = opts;
55757
+ if (routedAgent !== undefined) {
55758
+ const routed = getAgent(routedAgent);
55759
+ if (routed)
55760
+ return { agentName: routedAgent, agent: routed, degraded: false };
55761
+ return { agentName: defaultAgent, agent: getAgent(defaultAgent), degraded: true };
55762
+ }
55763
+ return { agentName: defaultAgent, agent: getAgent(defaultAgent), degraded: false };
55764
+ }
55526
55765
  function routeTddFailure(failureCategory, isLiteMode, ctx, reviewReason, failureDetail) {
55527
55766
  const buildReason = (category) => {
55528
55767
  const trimmedDetail = failureDetail?.trim();
@@ -56021,6 +56260,7 @@ var init_execution = __esm(() => {
56021
56260
  init_logger2();
56022
56261
  init_git();
56023
56262
  init_execution_helpers();
56263
+ init_execution_helpers();
56024
56264
  RUNTIME_CRASH_CODES = new Set(["CALL_OP_NO_OUTPUT", "CALL_OP_MAX_RETRIES"]);
56025
56265
  executionStage = {
56026
56266
  name: "execution",
@@ -56028,9 +56268,21 @@ var init_execution = __esm(() => {
56028
56268
  async execute(ctx) {
56029
56269
  const logger = getLogger();
56030
56270
  const defaultAgent = ctx.agentManager?.getDefault() ?? "claude";
56031
- const agent = (ctx.agentGetFn ?? _executionDeps.getAgent)(defaultAgent);
56271
+ const resolved = resolveExecutionAgent({
56272
+ routedAgent: ctx.routing.agent,
56273
+ defaultAgent,
56274
+ getAgent: ctx.agentGetFn ?? _executionDeps.getAgent
56275
+ });
56276
+ if (resolved.degraded) {
56277
+ logger.warn("execution", "Routed agent unavailable \u2014 degrading to default agent", {
56278
+ storyId: ctx.story.id,
56279
+ routedAgent: ctx.routing.agent,
56280
+ defaultAgent
56281
+ });
56282
+ }
56283
+ const agent = resolved.agent;
56032
56284
  if (!agent)
56033
- return { action: "fail", reason: `Agent "${defaultAgent}" not found` };
56285
+ return { action: "fail", reason: `Agent "${resolved.agentName}" not found` };
56034
56286
  let effectiveTier = ctx.routing.modelTier;
56035
56287
  if (!_executionDeps.validateAgentForTier(agent, ctx.routing.modelTier)) {
56036
56288
  effectiveTier = agent.capabilities.supportedTiers[0] ?? ctx.routing.modelTier;
@@ -56054,7 +56306,7 @@ var init_execution = __esm(() => {
56054
56306
  runtime: ctx.runtime,
56055
56307
  packageView,
56056
56308
  packageDir: ctx.workdir,
56057
- agentName: ctx.routing.agent ?? defaultAgent,
56309
+ agentName: resolved.agentName,
56058
56310
  storyId: ctx.story.id,
56059
56311
  featureName: ctx.prd.feature,
56060
56312
  story: ctx.story,
@@ -56472,7 +56724,7 @@ function parseQueueFile(content) {
56472
56724
  var init_queue = () => {};
56473
56725
 
56474
56726
  // src/execution/queue-handler.ts
56475
- import path12 from "path";
56727
+ import path13 from "path";
56476
56728
  function getSafeLogger4() {
56477
56729
  try {
56478
56730
  return getLogger();
@@ -56481,8 +56733,8 @@ function getSafeLogger4() {
56481
56733
  }
56482
56734
  }
56483
56735
  async function readQueueFile(workdir) {
56484
- const queuePath = path12.join(workdir, ".queue.txt");
56485
- const processingPath = path12.join(workdir, ".queue.txt.processing");
56736
+ const queuePath = path13.join(workdir, ".queue.txt");
56737
+ const processingPath = path13.join(workdir, ".queue.txt.processing");
56486
56738
  const logger = getSafeLogger4();
56487
56739
  try {
56488
56740
  const file3 = Bun.file(queuePath);
@@ -56507,7 +56759,7 @@ async function readQueueFile(workdir) {
56507
56759
  }
56508
56760
  }
56509
56761
  async function clearQueueFile(workdir) {
56510
- const processingPath = path12.join(workdir, ".queue.txt.processing");
56762
+ const processingPath = path13.join(workdir, ".queue.txt.processing");
56511
56763
  const logger = getSafeLogger4();
56512
56764
  try {
56513
56765
  const file3 = Bun.file(processingPath);
@@ -56585,13 +56837,12 @@ var init_queue_check = __esm(() => {
56585
56837
  // src/pipeline/stages/routing.ts
56586
56838
  var routingStage, _routingDeps;
56587
56839
  var init_routing2 = __esm(() => {
56588
- init_test_runners();
56589
- init_paths3();
56590
- init_greenfield();
56840
+ init_context();
56591
56841
  init_logger2();
56592
56842
  init_prd();
56593
56843
  init_routing();
56594
- init_llm();
56844
+ init_test_runners();
56845
+ init_paths3();
56595
56846
  routingStage = {
56596
56847
  name: "routing",
56597
56848
  enabled: () => true,
@@ -56603,26 +56854,35 @@ var init_routing2 = __esm(() => {
56603
56854
  const decision = await _routingDeps.resolveRouting(ctx.story, ctx.config, ctx.plugins, ctx);
56604
56855
  const TIER_RANK = { fast: 0, balanced: 1, powerful: 2 };
56605
56856
  const derivedTier = decision.modelTier;
56857
+ const profileTier = ctx.story.routing?.profileModelTier;
56858
+ const candidateTier = profileTier ?? derivedTier;
56859
+ const candidateRank = TIER_RANK[candidateTier];
56606
56860
  const previousTier = ctx.story.routing?.modelTier;
56607
56861
  const previousRank = previousTier !== undefined ? TIER_RANK[previousTier] : undefined;
56608
- const derivedRank = TIER_RANK[derivedTier];
56609
- if (previousTier !== undefined && previousRank === undefined) {
56862
+ const hasEscalationRecords = (ctx.story.escalations?.length ?? 0) > 0;
56863
+ if (previousTier !== undefined && previousRank === undefined && !hasEscalationRecords) {
56610
56864
  logger?.warn("routing", "Ignoring unknown previousTier \u2014 not escalating", {
56611
56865
  storyId: ctx.story.id,
56612
56866
  previousTier,
56613
- derivedTier
56867
+ candidateTier
56614
56868
  });
56615
56869
  }
56616
- const isEscalated = previousTier !== undefined && previousRank !== undefined && derivedRank !== undefined && previousRank > derivedRank;
56617
- const modelTier = isEscalated ? previousTier : derivedTier;
56618
- const routing = { ...decision, modelTier, agent: ctx.story.routing?.agent };
56870
+ const isEscalated = previousTier !== undefined && (previousRank !== undefined && candidateRank !== undefined ? previousRank > candidateRank : hasEscalationRecords);
56871
+ const modelTier = isEscalated ? previousTier : candidateTier;
56872
+ const routing = { ...decision, modelTier, agent: ctx.story.routing?.agent ?? decision.agent };
56873
+ const neverEscalated = !hasEscalationRecords;
56874
+ const initialAgent = ctx.story.routing?.initialAgent ?? (neverEscalated ? routing.agent : undefined);
56875
+ const initialProfileId = ctx.story.routing?.initialProfileId ?? (neverEscalated ? ctx.story.routing?.agentProfileId : undefined);
56619
56876
  ctx.story.routing = {
56620
56877
  ...ctx.story.routing ?? {},
56621
56878
  complexity: routing.complexity,
56622
56879
  initialComplexity: ctx.story.routing?.initialComplexity ?? routing.complexity,
56623
56880
  testStrategy: routing.testStrategy,
56624
56881
  reasoning: routing.reasoning ?? "",
56625
- modelTier: routing.modelTier
56882
+ modelTier: routing.modelTier,
56883
+ ...routing.agent !== undefined && { agent: routing.agent },
56884
+ ...initialAgent !== undefined && { initialAgent },
56885
+ ...initialProfileId !== undefined && { initialProfileId }
56626
56886
  };
56627
56887
  if (ctx.prdPath) {
56628
56888
  await _routingDeps.savePRD(ctx.prd, ctx.prdPath);
@@ -56652,13 +56912,13 @@ var init_routing2 = __esm(() => {
56652
56912
  }
56653
56913
  ctx.routing = routing;
56654
56914
  logger.debug("routing", "Task classified", {
56915
+ storyId: ctx.story.id,
56655
56916
  complexity: ctx.routing.complexity,
56656
56917
  modelTier: ctx.routing.modelTier,
56657
- testStrategy: ctx.routing.testStrategy,
56658
- storyId: ctx.story.id
56918
+ testStrategy: ctx.routing.testStrategy
56659
56919
  });
56660
56920
  if (ctx.stories.length === 1) {
56661
- logger.debug("routing", "Routing reasoning", { reasoning: ctx.routing.reasoning, storyId: ctx.story.id });
56921
+ logger.debug("routing", "Routing reasoning", { storyId: ctx.story.id, reasoning: ctx.routing.reasoning });
56662
56922
  }
56663
56923
  return { action: "continue" };
56664
56924
  }
@@ -56730,6 +56990,7 @@ var init_pipeline = __esm(() => {
56730
56990
  init_runner4();
56731
56991
  init_events();
56732
56992
  init_stages();
56993
+ init_execution_helpers();
56733
56994
  init_event_bus();
56734
56995
  });
56735
56996
 
@@ -57136,11 +57397,11 @@ __export(exports_init_context, {
57136
57397
  _initContextDeps: () => _initContextDeps
57137
57398
  });
57138
57399
  import { basename as basename9, join as join52 } from "path";
57139
- async function bunFileExists(path13) {
57140
- return Bun.file(path13).exists();
57400
+ async function bunFileExists(path14) {
57401
+ return Bun.file(path14).exists();
57141
57402
  }
57142
- async function bunMkdirp(path13) {
57143
- const proc = Bun.spawn(["mkdir", "-p", path13]);
57403
+ async function bunMkdirp(path14) {
57404
+ const proc = Bun.spawn(["mkdir", "-p", path14]);
57144
57405
  await proc.exited;
57145
57406
  }
57146
57407
  async function findFiles(dir, maxFiles = 200) {
@@ -57206,8 +57467,8 @@ async function detectEntryPoints(projectRoot) {
57206
57467
  const candidates = ["src/index.ts", "src/main.ts", "main.go", "src/lib.rs"];
57207
57468
  const found = [];
57208
57469
  for (const candidate of candidates) {
57209
- const path13 = join52(projectRoot, candidate);
57210
- if (await bunFileExists(path13)) {
57470
+ const path14 = join52(projectRoot, candidate);
57471
+ if (await bunFileExists(path14)) {
57211
57472
  found.push(candidate);
57212
57473
  }
57213
57474
  }
@@ -57217,8 +57478,8 @@ async function detectConfigFiles(projectRoot) {
57217
57478
  const candidates = ["tsconfig.json", "biome.json", "turbo.json", ".env.example"];
57218
57479
  const found = [];
57219
57480
  for (const candidate of candidates) {
57220
- const path13 = join52(projectRoot, candidate);
57221
- if (await bunFileExists(path13)) {
57481
+ const path14 = join52(projectRoot, candidate);
57482
+ if (await bunFileExists(path14)) {
57222
57483
  found.push(candidate);
57223
57484
  }
57224
57485
  }
@@ -58004,10 +58265,10 @@ var init_setup_analyze = __esm(() => {
58004
58265
  init_workspace();
58005
58266
  CANONICAL_SCRIPTS = ["build", "test", "lint", "type-check", "lint:fix"];
58006
58267
  _analyzeRepoDeps = {
58007
- fileExists: async (path13) => Bun.file(path13).exists(),
58008
- readJson: async (path13) => {
58268
+ fileExists: async (path14) => Bun.file(path14).exists(),
58269
+ readJson: async (path14) => {
58009
58270
  try {
58010
- const f = Bun.file(path13);
58271
+ const f = Bun.file(path14);
58011
58272
  if (!await f.exists())
58012
58273
  return null;
58013
58274
  return JSON.parse(await f.text());
@@ -58062,9 +58323,9 @@ async function fillScripts(workdir, analysis) {
58062
58323
  var TYPE_CHECK_KEY = "type-check", TYPE_CHECK_SCRIPT = "tsc --noEmit -p tsconfig.json", TYPE_CHECK_TURBO_PASSTHROUGH = "turbo run type-check", _fillScriptsDeps;
58063
58324
  var init_setup_fill = __esm(() => {
58064
58325
  _fillScriptsDeps = {
58065
- readJson: async (path13) => {
58326
+ readJson: async (path14) => {
58066
58327
  try {
58067
- const f = Bun.file(path13);
58328
+ const f = Bun.file(path14);
58068
58329
  if (!await f.exists())
58069
58330
  return null;
58070
58331
  return JSON.parse(await f.text());
@@ -58072,8 +58333,8 @@ var init_setup_fill = __esm(() => {
58072
58333
  return null;
58073
58334
  }
58074
58335
  },
58075
- writeFile: async (path13, content) => {
58076
- await Bun.write(path13, content);
58336
+ writeFile: async (path14, content) => {
58337
+ await Bun.write(path14, content);
58077
58338
  }
58078
58339
  };
58079
58340
  });
@@ -58194,10 +58455,10 @@ var init_setup = __esm(() => {
58194
58455
  },
58195
58456
  generateSetupPlan: (ctx, analysis) => generateSetupPlan(ctx, analysis),
58196
58457
  runGate: (workdir, config2) => runSetupGate(workdir, config2),
58197
- fileExists: (path13) => Bun.file(path13).exists(),
58198
- writeFile: (path13, content) => Bun.write(path13, content).then(() => {}),
58199
- mkdir: async (path13) => {
58200
- const proc = Bun.spawn(["mkdir", "-p", path13]);
58458
+ fileExists: (path14) => Bun.file(path14).exists(),
58459
+ writeFile: (path14, content) => Bun.write(path14, content).then(() => {}),
58460
+ mkdir: async (path14) => {
58461
+ const proc = Bun.spawn(["mkdir", "-p", path14]);
58201
58462
  await proc.exited;
58202
58463
  },
58203
58464
  stdout: (msg) => {
@@ -58212,7 +58473,7 @@ var init_setup = __esm(() => {
58212
58473
  });
58213
58474
 
58214
58475
  // src/plugins/builtin/curator/collect.ts
58215
- import * as path13 from "path";
58476
+ import * as path14 from "path";
58216
58477
  function now() {
58217
58478
  return new Date().toISOString();
58218
58479
  }
@@ -58262,7 +58523,7 @@ function tokenCount(story) {
58262
58523
  }
58263
58524
  async function collectFromMetrics(context) {
58264
58525
  const observations = [];
58265
- const metricsPath = path13.join(context.outputDir, "metrics.json");
58526
+ const metricsPath = path14.join(context.outputDir, "metrics.json");
58266
58527
  try {
58267
58528
  const data = await readJsonFile(metricsPath);
58268
58529
  const runs = Array.isArray(data) ? data : [data];
@@ -58312,11 +58573,11 @@ function findingMessage(finding) {
58312
58573
  }
58313
58574
  async function collectFromReviewAudit(context) {
58314
58575
  const observations = [];
58315
- const auditDir = path13.join(context.outputDir, "review-audit");
58576
+ const auditDir = path14.join(context.outputDir, "review-audit");
58316
58577
  try {
58317
58578
  const glob = new Bun.Glob("**/*.json");
58318
58579
  for await (const file3 of glob.scan({ cwd: auditDir, absolute: false })) {
58319
- const fullPath = path13.join(auditDir, file3);
58580
+ const fullPath = path14.join(auditDir, file3);
58320
58581
  try {
58321
58582
  const audit = asRecord3(await readJsonFile(fullPath));
58322
58583
  if (!audit)
@@ -58356,11 +58617,11 @@ async function collectFromReviewAudit(context) {
58356
58617
  }
58357
58618
  async function collectFromContextManifests(context) {
58358
58619
  const observations = [];
58359
- const featuresDir = path13.join(context.workdir, ".nax", "features");
58620
+ const featuresDir = path14.join(context.workdir, ".nax", "features");
58360
58621
  try {
58361
58622
  const glob = new Bun.Glob("*/stories/*/context-manifest-*.json");
58362
58623
  for await (const file3 of glob.scan({ cwd: featuresDir, absolute: false })) {
58363
- const fullPath = path13.join(featuresDir, file3);
58624
+ const fullPath = path14.join(featuresDir, file3);
58364
58625
  try {
58365
58626
  const parts = file3.split("/");
58366
58627
  const featureId = parts[0] ?? context.feature;
@@ -58913,10 +59174,10 @@ function renderProposals(proposals, runId, observationCount) {
58913
59174
 
58914
59175
  // src/plugins/builtin/curator/rollup.ts
58915
59176
  import { appendFile as appendFile3, mkdir as mkdir9, writeFile } from "fs/promises";
58916
- import * as path14 from "path";
59177
+ import * as path15 from "path";
58917
59178
  async function appendToRollup(observations, rollupPath) {
58918
59179
  try {
58919
- const dir = path14.dirname(rollupPath);
59180
+ const dir = path15.dirname(rollupPath);
58920
59181
  await mkdir9(dir, { recursive: true });
58921
59182
  if (observations.length === 0) {
58922
59183
  const f = Bun.file(rollupPath);
@@ -58935,7 +59196,7 @@ var init_rollup = () => {};
58935
59196
 
58936
59197
  // src/plugins/builtin/curator/index.ts
58937
59198
  import { mkdir as mkdir10 } from "fs/promises";
58938
- import * as path15 from "path";
59199
+ import * as path16 from "path";
58939
59200
  function getCuratorEnabled(context) {
58940
59201
  const cfg = context.config;
58941
59202
  if (!cfg)
@@ -59008,7 +59269,7 @@ var init_curator = __esm(() => {
59008
59269
  const observations = await collectObservations(curatorContext);
59009
59270
  if (context.outputDir) {
59010
59271
  const { observationsPath, rollupPath } = resolveCuratorOutputs(curatorContext);
59011
- const runDir = path15.dirname(observationsPath);
59272
+ const runDir = path16.dirname(observationsPath);
59012
59273
  await mkdir10(runDir, { recursive: true });
59013
59274
  await Bun.write(observationsPath, observations.map((o) => JSON.stringify(o)).join(`
59014
59275
  `) + (observations.length > 0 ? `
@@ -59016,7 +59277,7 @@ var init_curator = __esm(() => {
59016
59277
  const thresholds = getCuratorThresholds(context);
59017
59278
  const proposals = runHeuristics(observations, thresholds);
59018
59279
  const markdown = renderProposals(proposals, context.runId, observations.length);
59019
- const proposalsMdPath = path15.join(runDir, "curator-proposals.md");
59280
+ const proposalsMdPath = path16.join(runDir, "curator-proposals.md");
59020
59281
  await Bun.write(proposalsMdPath, markdown);
59021
59282
  await appendToRollup(observations, rollupPath);
59022
59283
  }
@@ -59386,14 +59647,14 @@ var init_validator = __esm(() => {
59386
59647
 
59387
59648
  // src/plugins/loader.ts
59388
59649
  import * as fs from "fs/promises";
59389
- import * as path16 from "path";
59650
+ import * as path17 from "path";
59390
59651
  function getSafeLogger6() {
59391
59652
  return getSafeLogger();
59392
59653
  }
59393
59654
  function extractPluginName(pluginPath) {
59394
- const basename11 = path16.basename(pluginPath);
59655
+ const basename11 = path17.basename(pluginPath);
59395
59656
  if (basename11 === "index.ts" || basename11 === "index.js" || basename11 === "index.mjs") {
59396
- return path16.basename(path16.dirname(pluginPath));
59657
+ return path17.basename(path17.dirname(pluginPath));
59397
59658
  }
59398
59659
  return basename11.replace(/\.(ts|js|mjs)$/, "");
59399
59660
  }
@@ -59479,7 +59740,7 @@ async function discoverPlugins(dir, isTestFileFn) {
59479
59740
  try {
59480
59741
  const entries = await fs.readdir(dir, { withFileTypes: true });
59481
59742
  for (const entry of entries) {
59482
- const fullPath = path16.join(dir, entry.name);
59743
+ const fullPath = path17.join(dir, entry.name);
59483
59744
  if (entry.isFile()) {
59484
59745
  if (isPluginFile(entry.name, isTestFileFn)) {
59485
59746
  discovered.push({ path: fullPath });
@@ -59487,7 +59748,7 @@ async function discoverPlugins(dir, isTestFileFn) {
59487
59748
  } else if (entry.isDirectory()) {
59488
59749
  const indexPaths = ["index.ts", "index.js", "index.mjs"];
59489
59750
  for (const indexFile of indexPaths) {
59490
- const indexPath = path16.join(fullPath, indexFile);
59751
+ const indexPath = path17.join(fullPath, indexFile);
59491
59752
  try {
59492
59753
  await fs.access(indexPath);
59493
59754
  discovered.push({ path: indexPath });
@@ -59512,13 +59773,13 @@ function isPluginFile(filename, isTestFileFn) {
59512
59773
  return !FALLBACK_TEST_FILE_RE.test(filename);
59513
59774
  }
59514
59775
  function resolveModulePath(modulePath, projectRoot) {
59515
- if (path16.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
59776
+ if (path17.isAbsolute(modulePath) || !modulePath.startsWith("./") && !modulePath.startsWith("../")) {
59516
59777
  return modulePath;
59517
59778
  }
59518
59779
  if (projectRoot) {
59519
- return path16.resolve(projectRoot, modulePath);
59780
+ return path17.resolve(projectRoot, modulePath);
59520
59781
  }
59521
- return path16.resolve(modulePath);
59782
+ return path17.resolve(modulePath);
59522
59783
  }
59523
59784
  async function loadAndValidatePlugin(initialModulePath, config2, allowedRoots = [], originalPath) {
59524
59785
  let attemptedPath = initialModulePath;
@@ -59834,7 +60095,7 @@ var package_default;
59834
60095
  var init_package = __esm(() => {
59835
60096
  package_default = {
59836
60097
  name: "@nathapp/nax",
59837
- version: "0.69.10",
60098
+ version: "0.70.0-canary.1",
59838
60099
  description: "AI Coding Agent Orchestrator \u2014 loops until done",
59839
60100
  type: "module",
59840
60101
  bin: {
@@ -59929,8 +60190,8 @@ var init_version = __esm(() => {
59929
60190
  NAX_VERSION = package_default.version;
59930
60191
  NAX_COMMIT = (() => {
59931
60192
  try {
59932
- if (/^[0-9a-f]{6,10}$/.test("5b5bf412"))
59933
- return "5b5bf412";
60193
+ if (/^[0-9a-f]{6,10}$/.test("f895b7d3"))
60194
+ return "f895b7d3";
59934
60195
  } catch {}
59935
60196
  try {
59936
60197
  const result = Bun.spawnSync(["git", "rev-parse", "--short", "HEAD"], {
@@ -60316,7 +60577,7 @@ async function readSourceFileContent(filePath, workdir) {
60316
60577
  var MAX_SOURCE_FILES = 5, MAX_FILE_LINES2 = 500;
60317
60578
 
60318
60579
  // src/execution/lifecycle/acceptance-helpers.ts
60319
- import path18 from "path";
60580
+ import path19 from "path";
60320
60581
  function isStubTestFile(content) {
60321
60582
  return isStubTestContent(content);
60322
60583
  }
@@ -60335,7 +60596,7 @@ function isTestLevelFailure(failedACs, totalACs, semanticVerdicts) {
60335
60596
  async function loadSpecContent(featureDir) {
60336
60597
  if (!featureDir)
60337
60598
  return "";
60338
- const specPath = path18.join(featureDir, "spec.md");
60599
+ const specPath = path19.join(featureDir, "spec.md");
60339
60600
  const specFile = Bun.file(specPath);
60340
60601
  return await specFile.exists() ? await specFile.text() : "";
60341
60602
  }
@@ -60355,7 +60616,7 @@ async function loadAcceptanceTestContent2(featureDir, testPaths, configuredTestP
60355
60616
  }
60356
60617
  if (!configuredTestPath)
60357
60618
  return [];
60358
- const resolvedPath = path18.join(featureDir, configuredTestPath);
60619
+ const resolvedPath = path19.join(featureDir, configuredTestPath);
60359
60620
  const testFile = Bun.file(resolvedPath);
60360
60621
  const content = await testFile.exists() ? await testFile.text() : "";
60361
60622
  return [{ content, path: resolvedPath }];
@@ -60372,7 +60633,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
60372
60633
  const { unlink: unlink3 } = await import("fs/promises");
60373
60634
  await unlink3(testPath);
60374
60635
  if (acceptanceContext.featureDir) {
60375
- const metaPath = path18.join(acceptanceContext.featureDir, "acceptance-meta.json");
60636
+ const metaPath = path19.join(acceptanceContext.featureDir, "acceptance-meta.json");
60376
60637
  try {
60377
60638
  await unlink3(metaPath);
60378
60639
  } catch {}
@@ -60386,7 +60647,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
60386
60647
  const changedFilesRaw = diffOutput.split(`
60387
60648
  `).map((f) => f.trim()).filter((f) => f.length > 0);
60388
60649
  const repoRoot = acceptanceContext.projectDir ?? workdir;
60389
- const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ? path18.join(acceptanceContext.projectDir, acceptanceContext.story.workdir) : undefined;
60650
+ const packageDir = acceptanceContext.story.workdir && acceptanceContext.projectDir ? path19.join(acceptanceContext.projectDir, acceptanceContext.story.workdir) : undefined;
60390
60651
  const ignoreMatchers = acceptanceContext.naxIgnoreIndex?.getMatchers(packageDir) ?? await resolveNaxIgnorePatterns(repoRoot, packageDir);
60391
60652
  const changedFiles = filterNaxInternalPaths(changedFilesRaw, ignoreMatchers);
60392
60653
  const MAX_BYTES = 51200;
@@ -60395,7 +60656,7 @@ async function regenerateAcceptanceTest(testPath, acceptanceContext) {
60395
60656
  for (const file3 of changedFiles) {
60396
60657
  if (totalBytes >= MAX_BYTES)
60397
60658
  break;
60398
- const filePath = path18.join(workdir, file3);
60659
+ const filePath = path19.join(workdir, file3);
60399
60660
  try {
60400
60661
  const fileContent = await _regenerateDeps.readFile(filePath);
60401
60662
  const remaining = MAX_BYTES - totalBytes;
@@ -60854,9 +61115,9 @@ var init_scratch_purge = __esm(() => {
60854
61115
  return [];
60855
61116
  }
60856
61117
  },
60857
- fileExists: (path19) => Bun.file(path19).exists(),
60858
- readFile: (path19) => Bun.file(path19).text(),
60859
- remove: (path19) => rm(path19, { recursive: true, force: true }),
61118
+ fileExists: (path20) => Bun.file(path20).exists(),
61119
+ readFile: (path20) => Bun.file(path20).text(),
61120
+ remove: (path20) => rm(path20, { recursive: true, force: true }),
60860
61121
  move: async (src, dest) => {
60861
61122
  await mkdir12(dirname12(dest), { recursive: true });
60862
61123
  await rename(src, dest);
@@ -62560,17 +62821,12 @@ var init_merge = __esm(() => {
62560
62821
  });
62561
62822
 
62562
62823
  // src/execution/escalation/escalation.ts
62563
- function escalateTier(currentTier, tierOrder) {
62564
- const getName = (t) => t.tier ?? t.name ?? null;
62565
- const currentIndex = tierOrder.findIndex((t) => getName(t) === currentTier);
62566
- if (currentIndex === -1 || currentIndex === tierOrder.length - 1) {
62567
- return null;
62568
- }
62569
- const next = tierOrder[currentIndex + 1];
62570
- const nextName = getName(next);
62571
- if (!nextName)
62824
+ function escalateTier(currentRung, tierOrder) {
62825
+ const i = currentRung.agent !== undefined ? tierOrder.findIndex((t) => t.tier === currentRung.tier && t.agent === currentRung.agent) : tierOrder.findIndex((t) => t.tier === currentRung.tier);
62826
+ if (i === -1 || i === tierOrder.length - 1)
62572
62827
  return null;
62573
- return { tier: nextName, agent: next.agent };
62828
+ const next = tierOrder[i + 1];
62829
+ return { tier: next.tier, agent: next.agent };
62574
62830
  }
62575
62831
  function calculateMaxIterations(tierOrder) {
62576
62832
  return tierOrder.reduce((sum, t) => sum + t.attempts, 0);
@@ -62633,9 +62889,9 @@ var _quoteIntegrityDeps, CONTEXT_LINES = 3;
62633
62889
  var init_quote_integrity = __esm(() => {
62634
62890
  init_logger2();
62635
62891
  _quoteIntegrityDeps = {
62636
- readFile: async (path20) => {
62892
+ readFile: async (path21) => {
62637
62893
  try {
62638
- return await Bun.file(path20).text();
62894
+ return await Bun.file(path21).text();
62639
62895
  } catch {
62640
62896
  return null;
62641
62897
  }
@@ -62790,7 +63046,10 @@ async function handleTierEscalation(ctx) {
62790
63046
  });
62791
63047
  return { outcome: "retry-same", prdDirty: false, prd: ctx.prd };
62792
63048
  }
62793
- const escalationResult = escalateTier(ctx.routing.modelTier, ctx.config.autoMode.escalation.tierOrder);
63049
+ const escalationTierOrder = ctx.config.autoMode.escalation.tierOrder;
63050
+ const hasAgentRungs = escalationTierOrder.some((r) => r.agent !== undefined);
63051
+ const currentRung = hasAgentRungs ? { tier: ctx.routing.modelTier, agent: ctx.story.routing?.agent } : { tier: ctx.routing.modelTier };
63052
+ const escalationResult = escalateTier(currentRung, escalationTierOrder);
62794
63053
  const nextAgent = escalationResult?.agent;
62795
63054
  const escalateWholeBatch = ctx.config.autoMode.escalation.escalateEntireBatch ?? true;
62796
63055
  const storiesToEscalate = ctx.isBatchExecution && escalateWholeBatch ? ctx.storiesToExecute : [ctx.story];
@@ -62898,7 +63157,8 @@ var init_tier_escalation = __esm(() => {
62898
63157
  init_quote_integrity();
62899
63158
  init_tier_outcome();
62900
63159
  _tierEscalationDeps = {
62901
- savePRD
63160
+ savePRD,
63161
+ getSafeLogger
62902
63162
  };
62903
63163
  });
62904
63164
 
@@ -62912,7 +63172,7 @@ var exports_merge_conflict_rectify = {};
62912
63172
  __export(exports_merge_conflict_rectify, {
62913
63173
  rectifyConflictedStory: () => rectifyConflictedStory
62914
63174
  });
62915
- import path20 from "path";
63175
+ import path21 from "path";
62916
63176
  async function closeStaleAcpSession(worktreePath, sessionName) {
62917
63177
  const logger = getSafeLogger();
62918
63178
  try {
@@ -62939,7 +63199,7 @@ async function rectifyConflictedStory(options) {
62939
63199
  await worktreeManager.remove(workdir, storyId);
62940
63200
  } catch {}
62941
63201
  await worktreeManager.create(workdir, storyId);
62942
- const worktreePath = path20.join(workdir, ".nax-wt", storyId);
63202
+ const worktreePath = path21.join(workdir, ".nax-wt", storyId);
62943
63203
  const { formatSessionName: formatSessionName2 } = await Promise.resolve().then(() => (init_naming(), exports_naming));
62944
63204
  const staleSessionName = formatSessionName2({
62945
63205
  workdir: worktreePath,
@@ -63622,7 +63882,7 @@ __export(exports_parallel_batch, {
63622
63882
  runParallelBatch: () => runParallelBatch,
63623
63883
  _parallelBatchDeps: () => _parallelBatchDeps
63624
63884
  });
63625
- import path21 from "path";
63885
+ import path22 from "path";
63626
63886
  async function runParallelBatch(options) {
63627
63887
  const { stories, ctx, prd } = options;
63628
63888
  const { workdir, config: config2, maxConcurrency, pipelineContext, eventEmitter, agentGetFn, hooks, pluginRegistry } = ctx;
@@ -63641,9 +63901,9 @@ async function runParallelBatch(options) {
63641
63901
  });
63642
63902
  throw error48;
63643
63903
  }
63644
- worktreePaths.set(story.id, path21.join(workdir, ".nax-wt", story.id));
63904
+ worktreePaths.set(story.id, path22.join(workdir, ".nax-wt", story.id));
63645
63905
  }
63646
- const rootConfigPath = path21.join(workdir, ".nax", "config.json");
63906
+ const rootConfigPath = path22.join(workdir, ".nax", "config.json");
63647
63907
  const profileOverride = config2.profile && config2.profile !== "default" ? { profile: config2.profile } : undefined;
63648
63908
  const storyEffectiveConfigs = new Map;
63649
63909
  const configResults = await Promise.allSettled(stories.filter((story) => story.workdir).map(async (story) => {
@@ -64560,7 +64820,7 @@ __export(exports_migrate, {
64560
64820
  });
64561
64821
  import { existsSync as existsSync33 } from "fs";
64562
64822
  import { mkdir as mkdir16, readdir as readdir5, rename as rename3 } from "fs/promises";
64563
- import path22 from "path";
64823
+ import path23 from "path";
64564
64824
  async function detectGeneratedContent(naxDir) {
64565
64825
  if (!existsSync33(naxDir))
64566
64826
  return [];
@@ -64573,17 +64833,17 @@ async function detectGeneratedContent(naxDir) {
64573
64833
  }
64574
64834
  for (const entry of entries) {
64575
64835
  if (GENERATED_NAMES.has(entry)) {
64576
- candidates.push({ name: entry, srcPath: path22.join(naxDir, entry) });
64836
+ candidates.push({ name: entry, srcPath: path23.join(naxDir, entry) });
64577
64837
  }
64578
64838
  }
64579
- const featuresDir = path22.join(naxDir, "features");
64839
+ const featuresDir = path23.join(naxDir, "features");
64580
64840
  if (existsSync33(featuresDir)) {
64581
64841
  let featureDirs = [];
64582
64842
  try {
64583
64843
  featureDirs = await readdir5(featuresDir);
64584
64844
  } catch {}
64585
64845
  for (const fid of featureDirs) {
64586
- const featureDir = path22.join(featuresDir, fid);
64846
+ const featureDir = path23.join(featuresDir, fid);
64587
64847
  let subEntries = [];
64588
64848
  try {
64589
64849
  subEntries = await readdir5(featureDir);
@@ -64593,12 +64853,12 @@ async function detectGeneratedContent(naxDir) {
64593
64853
  for (const sub of subEntries) {
64594
64854
  if (GENERATED_FEATURE_SUBNAMES.has(sub)) {
64595
64855
  candidates.push({
64596
- name: path22.join("features", fid, sub),
64597
- srcPath: path22.join(featureDir, sub)
64856
+ name: path23.join("features", fid, sub),
64857
+ srcPath: path23.join(featureDir, sub)
64598
64858
  });
64599
64859
  }
64600
64860
  if (sub === "stories") {
64601
- const storiesDir = path22.join(featureDir, "stories");
64861
+ const storiesDir = path23.join(featureDir, "stories");
64602
64862
  let storyDirs = [];
64603
64863
  try {
64604
64864
  storyDirs = await readdir5(storiesDir);
@@ -64606,7 +64866,7 @@ async function detectGeneratedContent(naxDir) {
64606
64866
  continue;
64607
64867
  }
64608
64868
  for (const sid of storyDirs) {
64609
- const storyDir = path22.join(storiesDir, sid);
64869
+ const storyDir = path23.join(storiesDir, sid);
64610
64870
  let storyEntries = [];
64611
64871
  try {
64612
64872
  storyEntries = await readdir5(storyDir);
@@ -64616,8 +64876,8 @@ async function detectGeneratedContent(naxDir) {
64616
64876
  for (const se of storyEntries) {
64617
64877
  if (se.startsWith("context-manifest-") && se.endsWith(".json")) {
64618
64878
  candidates.push({
64619
- name: path22.join("features", fid, "stories", sid, se),
64620
- srcPath: path22.join(storyDir, se)
64879
+ name: path23.join("features", fid, "stories", sid, se),
64880
+ srcPath: path23.join(storyDir, se)
64621
64881
  });
64622
64882
  }
64623
64883
  }
@@ -64638,15 +64898,15 @@ async function migrateCommand(options) {
64638
64898
  name: options.reclaim
64639
64899
  });
64640
64900
  }
64641
- const src = path22.join(globalConfigDir(), options.reclaim);
64901
+ const src = path23.join(globalConfigDir(), options.reclaim);
64642
64902
  if (!existsSync33(src)) {
64643
64903
  throw new NaxError(`Nothing to reclaim: ~/.nax/${options.reclaim} does not exist`, "MIGRATE_RECLAIM_NOT_FOUND", {
64644
64904
  stage: "migrate",
64645
64905
  name: options.reclaim
64646
64906
  });
64647
64907
  }
64648
- const archiveBase = path22.join(globalConfigDir(), "_archive");
64649
- const archiveDest = path22.join(archiveBase, `${options.reclaim}-${Date.now()}`);
64908
+ const archiveBase = path23.join(globalConfigDir(), "_archive");
64909
+ const archiveDest = path23.join(archiveBase, `${options.reclaim}-${Date.now()}`);
64650
64910
  await mkdir16(archiveBase, { recursive: true });
64651
64911
  await rename3(src, archiveDest);
64652
64912
  logger.info("migrate", `Reclaimed: archived to ${archiveDest}`, { storyId: "_migrate" });
@@ -64683,8 +64943,8 @@ async function migrateCommand(options) {
64683
64943
  logger.info("migrate", `Merged: identity for "${options.merge}" updated`, { storyId: "_migrate" });
64684
64944
  return;
64685
64945
  }
64686
- const naxDir = path22.join(options.workdir, ".nax");
64687
- const configPath = path22.join(naxDir, "config.json");
64946
+ const naxDir = path23.join(options.workdir, ".nax");
64947
+ const configPath = path23.join(naxDir, "config.json");
64688
64948
  if (!existsSync33(configPath)) {
64689
64949
  throw new NaxError("No .nax/config.json found \u2014 run nax init first", "MIGRATE_NO_CONFIG", {
64690
64950
  stage: "migrate",
@@ -64700,7 +64960,7 @@ async function migrateCommand(options) {
64700
64960
  cause: e
64701
64961
  });
64702
64962
  }
64703
- const projectKey = config2.name?.trim() || path22.basename(options.workdir);
64963
+ const projectKey = config2.name?.trim() || path23.basename(options.workdir);
64704
64964
  const destBase = projectOutputDir(projectKey, config2.outputDir);
64705
64965
  const candidates = await detectGeneratedContent(naxDir);
64706
64966
  if (candidates.length === 0) {
@@ -64709,7 +64969,7 @@ async function migrateCommand(options) {
64709
64969
  }
64710
64970
  if (options.dryRun) {
64711
64971
  for (const c of candidates) {
64712
- logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${path22.join(destBase, c.name)}`, {
64972
+ logger.info("migrate", `[dry-run] Would move: ${c.srcPath} -> ${path23.join(destBase, c.name)}`, {
64713
64973
  storyId: "_migrate"
64714
64974
  });
64715
64975
  }
@@ -64718,8 +64978,8 @@ async function migrateCommand(options) {
64718
64978
  await mkdir16(destBase, { recursive: true });
64719
64979
  let moved = 0;
64720
64980
  for (const candidate of candidates) {
64721
- const dest = path22.join(destBase, candidate.name);
64722
- await mkdir16(path22.dirname(dest), { recursive: true });
64981
+ const dest = path23.join(destBase, candidate.name);
64982
+ await mkdir16(path23.dirname(dest), { recursive: true });
64723
64983
  if (existsSync33(dest)) {
64724
64984
  throw new NaxError(`Migration conflict: destination already exists.
64725
64985
  Source: ${candidate.srcPath}
@@ -64749,7 +65009,7 @@ async function migrateCommand(options) {
64749
65009
  moved++;
64750
65010
  logger.info("migrate", `Moved: ${candidate.name}`, { storyId: "_migrate" });
64751
65011
  }
64752
- await Bun.write(path22.join(destBase, ".migrated-from"), JSON.stringify({ from: options.workdir, migratedAt: new Date().toISOString() }, null, 2));
65012
+ await Bun.write(path23.join(destBase, ".migrated-from"), JSON.stringify({ from: options.workdir, migratedAt: new Date().toISOString() }, null, 2));
64753
65013
  logger.info("migrate", `Migration complete: ${moved} entries moved`, {
64754
65014
  storyId: "_migrate",
64755
65015
  destBase
@@ -64866,7 +65126,7 @@ __export(exports_precheck_runner, {
64866
65126
  runPrecheckValidation: () => runPrecheckValidation
64867
65127
  });
64868
65128
  import { mkdirSync as mkdirSync6 } from "fs";
64869
- import path23 from "path";
65129
+ import path24 from "path";
64870
65130
  async function runPrecheckValidation(ctx) {
64871
65131
  const logger = getSafeLogger();
64872
65132
  if (process.env.NAX_PRECHECK !== "1") {
@@ -64881,7 +65141,7 @@ async function runPrecheckValidation(ctx) {
64881
65141
  silent: true
64882
65142
  });
64883
65143
  if (ctx.logFilePath) {
64884
- mkdirSync6(path23.dirname(ctx.logFilePath), { recursive: true });
65144
+ mkdirSync6(path24.dirname(ctx.logFilePath), { recursive: true });
64885
65145
  const precheckLog = {
64886
65146
  type: "precheck",
64887
65147
  timestamp: new Date().toISOString(),
@@ -65178,11 +65438,33 @@ var init_paused_story_prompts = __esm(() => {
65178
65438
  // src/execution/lifecycle/run-setup.ts
65179
65439
  var exports_run_setup = {};
65180
65440
  __export(exports_run_setup, {
65441
+ warnProfileMismatch: () => warnProfileMismatch,
65181
65442
  warnFallbackMisconfiguration: () => warnFallbackMisconfiguration,
65182
65443
  setupRun: () => setupRun,
65183
65444
  _runSetupDeps: () => _runSetupDeps
65184
65445
  });
65185
- import path24 from "path";
65446
+ import path25 from "path";
65447
+ function warnProfileMismatch(prd, config2, logger) {
65448
+ const profiles = config2.routing?.agents?.profiles ?? [];
65449
+ const profileIds = new Set(profiles.map((p) => p.id));
65450
+ if (prd.routingProfile !== undefined) {
65451
+ const current = config2.profile ?? "default";
65452
+ if (prd.routingProfile !== current) {
65453
+ logger?.warn("prd", `PRD was planned with config profile "${prd.routingProfile}" but this run resolved profile "${current}" \u2014 the escalation ladder and agent profiles may differ from what plan assumed. Re-run with --profile ${prd.routingProfile} to match.`, { storyId: "prd", plannedProfile: prd.routingProfile, currentProfile: current });
65454
+ }
65455
+ }
65456
+ const knownAgents = new Set(Object.keys(config2.models ?? {}));
65457
+ for (const story of prd.userStories) {
65458
+ const profileId = story.routing?.agentProfileId;
65459
+ if (profileId && !profileIds.has(profileId)) {
65460
+ logger?.warn("setup", `Story ${story.id} was planned with profile ${profileId} which no longer exists in config \u2014 routing.agent assignment retained`, { storyId: story.id, agentProfileId: profileId });
65461
+ }
65462
+ const storyAgent = story.routing?.agent;
65463
+ if (storyAgent && !knownAgents.has(storyAgent)) {
65464
+ logger?.warn("setup", `Story ${story.id} routes to agent "${storyAgent}" which is not defined in config.models \u2014 execution will degrade to the default agent`, { storyId: story.id, agent: storyAgent });
65465
+ }
65466
+ }
65467
+ }
65186
65468
  function warnFallbackMisconfiguration(config2, agentGetFn, logger) {
65187
65469
  if (!agentGetFn)
65188
65470
  return;
@@ -65196,6 +65478,7 @@ function warnFallbackMisconfiguration(config2, agentGetFn, logger) {
65196
65478
  continue;
65197
65479
  if (!agentGetFn(candidate)) {
65198
65480
  logger?.warn("fallback", "Fallback candidate not available \u2014 will be skipped if triggered", {
65481
+ storyId: "_setup",
65199
65482
  primaryAgent,
65200
65483
  candidate
65201
65484
  });
@@ -65281,7 +65564,7 @@ async function setupRun(options) {
65281
65564
  statusWriter.setPrd(prd);
65282
65565
  {
65283
65566
  const { detectGeneratedContent: detectGeneratedContent2, migrateCommand: migrateCommand2 } = await Promise.resolve().then(() => (init_migrate(), exports_migrate));
65284
- const naxDir = path24.join(workdir, ".nax");
65567
+ const naxDir = path25.join(workdir, ".nax");
65285
65568
  const candidates = await detectGeneratedContent2(naxDir).catch(() => []);
65286
65569
  if (candidates.length > 0) {
65287
65570
  logger?.info("setup", "Found generated content under .nax/ \u2014 migrating to output dir", {
@@ -65308,7 +65591,7 @@ async function setupRun(options) {
65308
65591
  remoteUrl = new TextDecoder().decode(gitResult.stdout).trim() || null;
65309
65592
  }
65310
65593
  } catch {}
65311
- const projectKey = config2.name?.trim() || path24.basename(workdir);
65594
+ const projectKey = config2.name?.trim() || path25.basename(workdir);
65312
65595
  await claimProjectIdentity2(projectKey, workdir, remoteUrl).catch((err) => {
65313
65596
  if (err instanceof NaxError && err.code === "RUN_NAME_COLLISION") {
65314
65597
  throw err;
@@ -65363,8 +65646,8 @@ async function setupRun(options) {
65363
65646
  explicit: Object.fromEntries(explicitFields.map((f) => [f, existingProjectConfig[f]])),
65364
65647
  detected: Object.fromEntries(autodetectedFields.map((f) => [f, detectedProfile[f]]))
65365
65648
  });
65366
- const globalPluginsDir = path24.join(globalConfigDir(), "plugins");
65367
- const projectPluginsDir = path24.join(workdir, ".nax", "plugins");
65649
+ const globalPluginsDir = path25.join(globalConfigDir(), "plugins");
65650
+ const projectPluginsDir = path25.join(workdir, ".nax", "plugins");
65368
65651
  const configPlugins = config2.plugins || [];
65369
65652
  const resolvedPatterns = await resolveTestFilePatterns(config2, workdir);
65370
65653
  const isTestFileFn = (filename) => resolvedPatterns.regex.some((re) => re.test(filename));
@@ -65393,6 +65676,7 @@ async function setupRun(options) {
65393
65676
  });
65394
65677
  prd = initResult.prd;
65395
65678
  statusWriter.setPrd(prd);
65679
+ warnProfileMismatch(prd, config2, logger);
65396
65680
  let counts = initResult.storyCounts;
65397
65681
  if (counts.paused > 0 && interactionChain !== null) {
65398
65682
  const { promptForPausedStories: promptForPausedStories2 } = await Promise.resolve().then(() => (init_paused_story_prompts(), exports_paused_story_prompts));
@@ -66855,11 +67139,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
66855
67139
  fiber = fiber.next, id--;
66856
67140
  return fiber;
66857
67141
  }
66858
- function copyWithSetImpl(obj, path25, index, value) {
66859
- if (index >= path25.length)
67142
+ function copyWithSetImpl(obj, path26, index, value) {
67143
+ if (index >= path26.length)
66860
67144
  return value;
66861
- var key = path25[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
66862
- updated[key] = copyWithSetImpl(obj[key], path25, index + 1, value);
67145
+ var key = path26[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
67146
+ updated[key] = copyWithSetImpl(obj[key], path26, index + 1, value);
66863
67147
  return updated;
66864
67148
  }
66865
67149
  function copyWithRename(obj, oldPath, newPath) {
@@ -66879,11 +67163,11 @@ var require_react_reconciler_development = __commonJS((exports, module) => {
66879
67163
  index + 1 === oldPath.length ? (updated[newPath[index]] = updated[oldKey], isArrayImpl(updated) ? updated.splice(oldKey, 1) : delete updated[oldKey]) : updated[oldKey] = copyWithRenameImpl(obj[oldKey], oldPath, newPath, index + 1);
66880
67164
  return updated;
66881
67165
  }
66882
- function copyWithDeleteImpl(obj, path25, index) {
66883
- var key = path25[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
66884
- if (index + 1 === path25.length)
67166
+ function copyWithDeleteImpl(obj, path26, index) {
67167
+ var key = path26[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
67168
+ if (index + 1 === path26.length)
66885
67169
  return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
66886
- updated[key] = copyWithDeleteImpl(obj[key], path25, index + 1);
67170
+ updated[key] = copyWithDeleteImpl(obj[key], path26, index + 1);
66887
67171
  return updated;
66888
67172
  }
66889
67173
  function shouldSuspendImpl() {
@@ -76906,29 +77190,29 @@ Check the top-level render call using <` + componentName2 + ">.");
76906
77190
  var didWarnAboutNestedUpdates = false;
76907
77191
  var didWarnAboutFindNodeInStrictMode = {};
76908
77192
  var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, scheduleRetry = null, setErrorHandler = null, setSuspenseHandler = null;
76909
- overrideHookState = function(fiber, id, path25, value) {
77193
+ overrideHookState = function(fiber, id, path26, value) {
76910
77194
  id = findHook(fiber, id);
76911
- id !== null && (path25 = copyWithSetImpl(id.memoizedState, path25, 0, value), id.memoizedState = path25, id.baseState = path25, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path25 = enqueueConcurrentRenderForLane(fiber, 2), path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2));
77195
+ id !== null && (path26 = copyWithSetImpl(id.memoizedState, path26, 0, value), id.memoizedState = path26, id.baseState = path26, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path26 = enqueueConcurrentRenderForLane(fiber, 2), path26 !== null && scheduleUpdateOnFiber(path26, fiber, 2));
76912
77196
  };
76913
- overrideHookStateDeletePath = function(fiber, id, path25) {
77197
+ overrideHookStateDeletePath = function(fiber, id, path26) {
76914
77198
  id = findHook(fiber, id);
76915
- id !== null && (path25 = copyWithDeleteImpl(id.memoizedState, path25, 0), id.memoizedState = path25, id.baseState = path25, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path25 = enqueueConcurrentRenderForLane(fiber, 2), path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2));
77199
+ id !== null && (path26 = copyWithDeleteImpl(id.memoizedState, path26, 0), id.memoizedState = path26, id.baseState = path26, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path26 = enqueueConcurrentRenderForLane(fiber, 2), path26 !== null && scheduleUpdateOnFiber(path26, fiber, 2));
76916
77200
  };
76917
77201
  overrideHookStateRenamePath = function(fiber, id, oldPath, newPath) {
76918
77202
  id = findHook(fiber, id);
76919
77203
  id !== null && (oldPath = copyWithRename(id.memoizedState, oldPath, newPath), id.memoizedState = oldPath, id.baseState = oldPath, fiber.memoizedProps = assign2({}, fiber.memoizedProps), oldPath = enqueueConcurrentRenderForLane(fiber, 2), oldPath !== null && scheduleUpdateOnFiber(oldPath, fiber, 2));
76920
77204
  };
76921
- overrideProps = function(fiber, path25, value) {
76922
- fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path25, 0, value);
77205
+ overrideProps = function(fiber, path26, value) {
77206
+ fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path26, 0, value);
76923
77207
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
76924
- path25 = enqueueConcurrentRenderForLane(fiber, 2);
76925
- path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2);
77208
+ path26 = enqueueConcurrentRenderForLane(fiber, 2);
77209
+ path26 !== null && scheduleUpdateOnFiber(path26, fiber, 2);
76926
77210
  };
76927
- overridePropsDeletePath = function(fiber, path25) {
76928
- fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path25, 0);
77211
+ overridePropsDeletePath = function(fiber, path26) {
77212
+ fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path26, 0);
76929
77213
  fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
76930
- path25 = enqueueConcurrentRenderForLane(fiber, 2);
76931
- path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2);
77214
+ path26 = enqueueConcurrentRenderForLane(fiber, 2);
77215
+ path26 !== null && scheduleUpdateOnFiber(path26, fiber, 2);
76932
77216
  };
76933
77217
  overridePropsRenamePath = function(fiber, oldPath, newPath) {
76934
77218
  fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
@@ -80983,8 +81267,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
80983
81267
  }
80984
81268
  return false;
80985
81269
  }
80986
- function utils_getInObject(object2, path25) {
80987
- return path25.reduce(function(reduced, attr) {
81270
+ function utils_getInObject(object2, path26) {
81271
+ return path26.reduce(function(reduced, attr) {
80988
81272
  if (reduced) {
80989
81273
  if (utils_hasOwnProperty.call(reduced, attr)) {
80990
81274
  return reduced[attr];
@@ -80996,11 +81280,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
80996
81280
  return null;
80997
81281
  }, object2);
80998
81282
  }
80999
- function deletePathInObject(object2, path25) {
81000
- var length = path25.length;
81001
- var last2 = path25[length - 1];
81283
+ function deletePathInObject(object2, path26) {
81284
+ var length = path26.length;
81285
+ var last2 = path26[length - 1];
81002
81286
  if (object2 != null) {
81003
- var parent = utils_getInObject(object2, path25.slice(0, length - 1));
81287
+ var parent = utils_getInObject(object2, path26.slice(0, length - 1));
81004
81288
  if (parent) {
81005
81289
  if (src_isArray(parent)) {
81006
81290
  parent.splice(last2, 1);
@@ -81026,11 +81310,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81026
81310
  }
81027
81311
  }
81028
81312
  }
81029
- function utils_setInObject(object2, path25, value) {
81030
- var length = path25.length;
81031
- var last2 = path25[length - 1];
81313
+ function utils_setInObject(object2, path26, value) {
81314
+ var length = path26.length;
81315
+ var last2 = path26[length - 1];
81032
81316
  if (object2 != null) {
81033
- var parent = utils_getInObject(object2, path25.slice(0, length - 1));
81317
+ var parent = utils_getInObject(object2, path26.slice(0, length - 1));
81034
81318
  if (parent) {
81035
81319
  parent[last2] = value;
81036
81320
  }
@@ -81561,8 +81845,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81561
81845
  unserializable: Symbol("unserializable")
81562
81846
  };
81563
81847
  var LEVEL_THRESHOLD = 2;
81564
- function createDehydrated(type, inspectable, data, cleaned, path25) {
81565
- cleaned.push(path25);
81848
+ function createDehydrated(type, inspectable, data, cleaned, path26) {
81849
+ cleaned.push(path26);
81566
81850
  var dehydrated = {
81567
81851
  inspectable,
81568
81852
  type,
@@ -81580,13 +81864,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81580
81864
  }
81581
81865
  return dehydrated;
81582
81866
  }
81583
- function dehydrate(data, cleaned, unserializable, path25, isPathAllowed) {
81867
+ function dehydrate(data, cleaned, unserializable, path26, isPathAllowed) {
81584
81868
  var level = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
81585
81869
  var type = getDataType(data);
81586
81870
  var isPathAllowedCheck;
81587
81871
  switch (type) {
81588
81872
  case "html_element":
81589
- cleaned.push(path25);
81873
+ cleaned.push(path26);
81590
81874
  return {
81591
81875
  inspectable: false,
81592
81876
  preview_short: formatDataForPreview(data, false),
@@ -81595,7 +81879,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81595
81879
  type
81596
81880
  };
81597
81881
  case "function":
81598
- cleaned.push(path25);
81882
+ cleaned.push(path26);
81599
81883
  return {
81600
81884
  inspectable: false,
81601
81885
  preview_short: formatDataForPreview(data, false),
@@ -81604,14 +81888,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81604
81888
  type
81605
81889
  };
81606
81890
  case "string":
81607
- isPathAllowedCheck = isPathAllowed(path25);
81891
+ isPathAllowedCheck = isPathAllowed(path26);
81608
81892
  if (isPathAllowedCheck) {
81609
81893
  return data;
81610
81894
  } else {
81611
81895
  return data.length <= 500 ? data : data.slice(0, 500) + "...";
81612
81896
  }
81613
81897
  case "bigint":
81614
- cleaned.push(path25);
81898
+ cleaned.push(path26);
81615
81899
  return {
81616
81900
  inspectable: false,
81617
81901
  preview_short: formatDataForPreview(data, false),
@@ -81620,7 +81904,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81620
81904
  type
81621
81905
  };
81622
81906
  case "symbol":
81623
- cleaned.push(path25);
81907
+ cleaned.push(path26);
81624
81908
  return {
81625
81909
  inspectable: false,
81626
81910
  preview_short: formatDataForPreview(data, false),
@@ -81629,9 +81913,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81629
81913
  type
81630
81914
  };
81631
81915
  case "react_element": {
81632
- isPathAllowedCheck = isPathAllowed(path25);
81916
+ isPathAllowedCheck = isPathAllowed(path26);
81633
81917
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81634
- cleaned.push(path25);
81918
+ cleaned.push(path26);
81635
81919
  return {
81636
81920
  inspectable: true,
81637
81921
  preview_short: formatDataForPreview(data, false),
@@ -81648,19 +81932,19 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81648
81932
  preview_long: formatDataForPreview(data, true),
81649
81933
  name: getDisplayNameForReactElement(data) || "Unknown"
81650
81934
  };
81651
- unserializableValue.key = dehydrate(data.key, cleaned, unserializable, path25.concat(["key"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81935
+ unserializableValue.key = dehydrate(data.key, cleaned, unserializable, path26.concat(["key"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81652
81936
  if (data.$$typeof === REACT_LEGACY_ELEMENT_TYPE) {
81653
- unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable, path25.concat(["ref"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81937
+ unserializableValue.ref = dehydrate(data.ref, cleaned, unserializable, path26.concat(["ref"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81654
81938
  }
81655
- unserializableValue.props = dehydrate(data.props, cleaned, unserializable, path25.concat(["props"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81656
- unserializable.push(path25);
81939
+ unserializableValue.props = dehydrate(data.props, cleaned, unserializable, path26.concat(["props"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81940
+ unserializable.push(path26);
81657
81941
  return unserializableValue;
81658
81942
  }
81659
81943
  case "react_lazy": {
81660
- isPathAllowedCheck = isPathAllowed(path25);
81944
+ isPathAllowedCheck = isPathAllowed(path26);
81661
81945
  var payload = data._payload;
81662
81946
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81663
- cleaned.push(path25);
81947
+ cleaned.push(path26);
81664
81948
  var inspectable = payload !== null && hydration_typeof(payload) === "object" && (payload._status === 1 || payload._status === 2 || payload.status === "fulfilled" || payload.status === "rejected");
81665
81949
  return {
81666
81950
  inspectable,
@@ -81677,13 +81961,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81677
81961
  preview_long: formatDataForPreview(data, true),
81678
81962
  name: "lazy()"
81679
81963
  };
81680
- _unserializableValue._payload = dehydrate(payload, cleaned, unserializable, path25.concat(["_payload"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81681
- unserializable.push(path25);
81964
+ _unserializableValue._payload = dehydrate(payload, cleaned, unserializable, path26.concat(["_payload"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81965
+ unserializable.push(path26);
81682
81966
  return _unserializableValue;
81683
81967
  }
81684
81968
  case "array_buffer":
81685
81969
  case "data_view":
81686
- cleaned.push(path25);
81970
+ cleaned.push(path26);
81687
81971
  return {
81688
81972
  inspectable: false,
81689
81973
  preview_short: formatDataForPreview(data, false),
@@ -81693,21 +81977,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81693
81977
  type
81694
81978
  };
81695
81979
  case "array":
81696
- isPathAllowedCheck = isPathAllowed(path25);
81980
+ isPathAllowedCheck = isPathAllowed(path26);
81697
81981
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81698
- return createDehydrated(type, true, data, cleaned, path25);
81982
+ return createDehydrated(type, true, data, cleaned, path26);
81699
81983
  }
81700
81984
  var arr = [];
81701
81985
  for (var i = 0;i < data.length; i++) {
81702
- arr[i] = dehydrateKey(data, i, cleaned, unserializable, path25.concat([i]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81986
+ arr[i] = dehydrateKey(data, i, cleaned, unserializable, path26.concat([i]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81703
81987
  }
81704
81988
  return arr;
81705
81989
  case "html_all_collection":
81706
81990
  case "typed_array":
81707
81991
  case "iterator":
81708
- isPathAllowedCheck = isPathAllowed(path25);
81992
+ isPathAllowedCheck = isPathAllowed(path26);
81709
81993
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81710
- return createDehydrated(type, true, data, cleaned, path25);
81994
+ return createDehydrated(type, true, data, cleaned, path26);
81711
81995
  } else {
81712
81996
  var _unserializableValue2 = {
81713
81997
  unserializable: true,
@@ -81719,13 +82003,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81719
82003
  name: typeof data.constructor !== "function" || typeof data.constructor.name !== "string" || data.constructor.name === "Object" ? "" : data.constructor.name
81720
82004
  };
81721
82005
  Array.from(data).forEach(function(item, i2) {
81722
- return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable, path25.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82006
+ return _unserializableValue2[i2] = dehydrate(item, cleaned, unserializable, path26.concat([i2]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81723
82007
  });
81724
- unserializable.push(path25);
82008
+ unserializable.push(path26);
81725
82009
  return _unserializableValue2;
81726
82010
  }
81727
82011
  case "opaque_iterator":
81728
- cleaned.push(path25);
82012
+ cleaned.push(path26);
81729
82013
  return {
81730
82014
  inspectable: false,
81731
82015
  preview_short: formatDataForPreview(data, false),
@@ -81734,7 +82018,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81734
82018
  type
81735
82019
  };
81736
82020
  case "date":
81737
- cleaned.push(path25);
82021
+ cleaned.push(path26);
81738
82022
  return {
81739
82023
  inspectable: false,
81740
82024
  preview_short: formatDataForPreview(data, false),
@@ -81743,7 +82027,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81743
82027
  type
81744
82028
  };
81745
82029
  case "regexp":
81746
- cleaned.push(path25);
82030
+ cleaned.push(path26);
81747
82031
  return {
81748
82032
  inspectable: false,
81749
82033
  preview_short: formatDataForPreview(data, false),
@@ -81752,9 +82036,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81752
82036
  type
81753
82037
  };
81754
82038
  case "thenable":
81755
- isPathAllowedCheck = isPathAllowed(path25);
82039
+ isPathAllowedCheck = isPathAllowed(path26);
81756
82040
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81757
- cleaned.push(path25);
82041
+ cleaned.push(path26);
81758
82042
  return {
81759
82043
  inspectable: data.status === "fulfilled" || data.status === "rejected",
81760
82044
  preview_short: formatDataForPreview(data, false),
@@ -81775,8 +82059,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81775
82059
  preview_long: formatDataForPreview(data, true),
81776
82060
  name: "fulfilled Thenable"
81777
82061
  };
81778
- _unserializableValue3.value = dehydrate(data.value, cleaned, unserializable, path25.concat(["value"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81779
- unserializable.push(path25);
82062
+ _unserializableValue3.value = dehydrate(data.value, cleaned, unserializable, path26.concat(["value"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82063
+ unserializable.push(path26);
81780
82064
  return _unserializableValue3;
81781
82065
  }
81782
82066
  case "rejected": {
@@ -81787,12 +82071,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81787
82071
  preview_long: formatDataForPreview(data, true),
81788
82072
  name: "rejected Thenable"
81789
82073
  };
81790
- _unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable, path25.concat(["reason"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81791
- unserializable.push(path25);
82074
+ _unserializableValue4.reason = dehydrate(data.reason, cleaned, unserializable, path26.concat(["reason"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82075
+ unserializable.push(path26);
81792
82076
  return _unserializableValue4;
81793
82077
  }
81794
82078
  default:
81795
- cleaned.push(path25);
82079
+ cleaned.push(path26);
81796
82080
  return {
81797
82081
  inspectable: false,
81798
82082
  preview_short: formatDataForPreview(data, false),
@@ -81802,21 +82086,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81802
82086
  };
81803
82087
  }
81804
82088
  case "object":
81805
- isPathAllowedCheck = isPathAllowed(path25);
82089
+ isPathAllowedCheck = isPathAllowed(path26);
81806
82090
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81807
- return createDehydrated(type, true, data, cleaned, path25);
82091
+ return createDehydrated(type, true, data, cleaned, path26);
81808
82092
  } else {
81809
82093
  var object2 = {};
81810
82094
  getAllEnumerableKeys(data).forEach(function(key) {
81811
82095
  var name = key.toString();
81812
- object2[name] = dehydrateKey(data, key, cleaned, unserializable, path25.concat([name]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82096
+ object2[name] = dehydrateKey(data, key, cleaned, unserializable, path26.concat([name]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81813
82097
  });
81814
82098
  return object2;
81815
82099
  }
81816
82100
  case "class_instance": {
81817
- isPathAllowedCheck = isPathAllowed(path25);
82101
+ isPathAllowedCheck = isPathAllowed(path26);
81818
82102
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81819
- return createDehydrated(type, true, data, cleaned, path25);
82103
+ return createDehydrated(type, true, data, cleaned, path26);
81820
82104
  }
81821
82105
  var value = {
81822
82106
  unserializable: true,
@@ -81828,15 +82112,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81828
82112
  };
81829
82113
  getAllEnumerableKeys(data).forEach(function(key) {
81830
82114
  var keyAsString = key.toString();
81831
- value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path25.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82115
+ value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path26.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81832
82116
  });
81833
- unserializable.push(path25);
82117
+ unserializable.push(path26);
81834
82118
  return value;
81835
82119
  }
81836
82120
  case "error": {
81837
- isPathAllowedCheck = isPathAllowed(path25);
82121
+ isPathAllowedCheck = isPathAllowed(path26);
81838
82122
  if (level >= LEVEL_THRESHOLD && !isPathAllowedCheck) {
81839
- return createDehydrated(type, true, data, cleaned, path25);
82123
+ return createDehydrated(type, true, data, cleaned, path26);
81840
82124
  }
81841
82125
  var _value = {
81842
82126
  unserializable: true,
@@ -81846,22 +82130,22 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81846
82130
  preview_long: formatDataForPreview(data, true),
81847
82131
  name: data.name
81848
82132
  };
81849
- _value.message = dehydrate(data.message, cleaned, unserializable, path25.concat(["message"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81850
- _value.stack = dehydrate(data.stack, cleaned, unserializable, path25.concat(["stack"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82133
+ _value.message = dehydrate(data.message, cleaned, unserializable, path26.concat(["message"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82134
+ _value.stack = dehydrate(data.stack, cleaned, unserializable, path26.concat(["stack"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81851
82135
  if ("cause" in data) {
81852
- _value.cause = dehydrate(data.cause, cleaned, unserializable, path25.concat(["cause"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82136
+ _value.cause = dehydrate(data.cause, cleaned, unserializable, path26.concat(["cause"]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81853
82137
  }
81854
82138
  getAllEnumerableKeys(data).forEach(function(key) {
81855
82139
  var keyAsString = key.toString();
81856
- _value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path25.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
82140
+ _value[keyAsString] = dehydrate(data[key], cleaned, unserializable, path26.concat([keyAsString]), isPathAllowed, isPathAllowedCheck ? 1 : level + 1);
81857
82141
  });
81858
- unserializable.push(path25);
82142
+ unserializable.push(path26);
81859
82143
  return _value;
81860
82144
  }
81861
82145
  case "infinity":
81862
82146
  case "nan":
81863
82147
  case "undefined":
81864
- cleaned.push(path25);
82148
+ cleaned.push(path26);
81865
82149
  return {
81866
82150
  type
81867
82151
  };
@@ -81869,10 +82153,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81869
82153
  return data;
81870
82154
  }
81871
82155
  }
81872
- function dehydrateKey(parent, key, cleaned, unserializable, path25, isPathAllowed) {
82156
+ function dehydrateKey(parent, key, cleaned, unserializable, path26, isPathAllowed) {
81873
82157
  var level = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : 0;
81874
82158
  try {
81875
- return dehydrate(parent[key], cleaned, unserializable, path25, isPathAllowed, level);
82159
+ return dehydrate(parent[key], cleaned, unserializable, path26, isPathAllowed, level);
81876
82160
  } catch (error48) {
81877
82161
  var preview = "";
81878
82162
  if (hydration_typeof(error48) === "object" && error48 !== null && typeof error48.stack === "string") {
@@ -81880,7 +82164,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81880
82164
  } else if (typeof error48 === "string") {
81881
82165
  preview = error48;
81882
82166
  }
81883
- cleaned.push(path25);
82167
+ cleaned.push(path26);
81884
82168
  return {
81885
82169
  inspectable: false,
81886
82170
  preview_short: "[Exception]",
@@ -81890,8 +82174,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81890
82174
  };
81891
82175
  }
81892
82176
  }
81893
- function fillInPath(object2, data, path25, value) {
81894
- var target = getInObject(object2, path25);
82177
+ function fillInPath(object2, data, path26, value) {
82178
+ var target = getInObject(object2, path26);
81895
82179
  if (target != null) {
81896
82180
  if (!target[meta3.unserializable]) {
81897
82181
  delete target[meta3.inspectable];
@@ -81906,9 +82190,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81906
82190
  }
81907
82191
  if (value !== null && data.unserializable.length > 0) {
81908
82192
  var unserializablePath = data.unserializable[0];
81909
- var isMatch2 = unserializablePath.length === path25.length;
81910
- for (var i = 0;i < path25.length; i++) {
81911
- if (path25[i] !== unserializablePath[i]) {
82193
+ var isMatch2 = unserializablePath.length === path26.length;
82194
+ for (var i = 0;i < path26.length; i++) {
82195
+ if (path26[i] !== unserializablePath[i]) {
81912
82196
  isMatch2 = false;
81913
82197
  break;
81914
82198
  }
@@ -81917,13 +82201,13 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81917
82201
  upgradeUnserializable(value, value);
81918
82202
  }
81919
82203
  }
81920
- setInObject(object2, path25, value);
82204
+ setInObject(object2, path26, value);
81921
82205
  }
81922
82206
  function hydrate(object2, cleaned, unserializable) {
81923
- cleaned.forEach(function(path25) {
81924
- var length = path25.length;
81925
- var last2 = path25[length - 1];
81926
- var parent = getInObject(object2, path25.slice(0, length - 1));
82207
+ cleaned.forEach(function(path26) {
82208
+ var length = path26.length;
82209
+ var last2 = path26[length - 1];
82210
+ var parent = getInObject(object2, path26.slice(0, length - 1));
81927
82211
  if (!parent || !parent.hasOwnProperty(last2)) {
81928
82212
  return;
81929
82213
  }
@@ -81949,10 +82233,10 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
81949
82233
  parent[last2] = replaced;
81950
82234
  }
81951
82235
  });
81952
- unserializable.forEach(function(path25) {
81953
- var length = path25.length;
81954
- var last2 = path25[length - 1];
81955
- var parent = getInObject(object2, path25.slice(0, length - 1));
82236
+ unserializable.forEach(function(path26) {
82237
+ var length = path26.length;
82238
+ var last2 = path26[length - 1];
82239
+ var parent = getInObject(object2, path26.slice(0, length - 1));
81956
82240
  if (!parent || !parent.hasOwnProperty(last2)) {
81957
82241
  return;
81958
82242
  }
@@ -82073,11 +82357,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
82073
82357
  return gte2(version2, FIRST_DEVTOOLS_BACKEND_LOCKSTEP_VER);
82074
82358
  }
82075
82359
  function cleanForBridge(data, isPathAllowed) {
82076
- var path25 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
82360
+ var path26 = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];
82077
82361
  if (data !== null) {
82078
82362
  var cleanedPaths = [];
82079
82363
  var unserializablePaths = [];
82080
- var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths, path25, isPathAllowed);
82364
+ var cleanedData = dehydrate(data, cleanedPaths, unserializablePaths, path26, isPathAllowed);
82081
82365
  return {
82082
82366
  data: cleanedData,
82083
82367
  cleaned: cleanedPaths,
@@ -82087,18 +82371,18 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
82087
82371
  return null;
82088
82372
  }
82089
82373
  }
82090
- function copyWithDelete(obj, path25) {
82374
+ function copyWithDelete(obj, path26) {
82091
82375
  var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
82092
- var key = path25[index];
82376
+ var key = path26[index];
82093
82377
  var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
82094
- if (index + 1 === path25.length) {
82378
+ if (index + 1 === path26.length) {
82095
82379
  if (shared_isArray(updated)) {
82096
82380
  updated.splice(key, 1);
82097
82381
  } else {
82098
82382
  delete updated[key];
82099
82383
  }
82100
82384
  } else {
82101
- updated[key] = copyWithDelete(obj[key], path25, index + 1);
82385
+ updated[key] = copyWithDelete(obj[key], path26, index + 1);
82102
82386
  }
82103
82387
  return updated;
82104
82388
  }
@@ -82119,14 +82403,14 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
82119
82403
  }
82120
82404
  return updated;
82121
82405
  }
82122
- function copyWithSet(obj, path25, value) {
82406
+ function copyWithSet(obj, path26, value) {
82123
82407
  var index = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
82124
- if (index >= path25.length) {
82408
+ if (index >= path26.length) {
82125
82409
  return value;
82126
82410
  }
82127
- var key = path25[index];
82411
+ var key = path26[index];
82128
82412
  var updated = shared_isArray(obj) ? obj.slice() : utils_objectSpread({}, obj);
82129
- updated[key] = copyWithSet(obj[key], path25, value, index + 1);
82413
+ updated[key] = copyWithSet(obj[key], path26, value, index + 1);
82130
82414
  return updated;
82131
82415
  }
82132
82416
  function getEffectDurations(root) {
@@ -83454,12 +83738,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83454
83738
  }
83455
83739
  });
83456
83740
  bridge_defineProperty(_this, "overrideValueAtPath", function(_ref) {
83457
- var { id, path: path25, rendererID, type, value } = _ref;
83741
+ var { id, path: path26, rendererID, type, value } = _ref;
83458
83742
  switch (type) {
83459
83743
  case "context":
83460
83744
  _this.send("overrideContext", {
83461
83745
  id,
83462
- path: path25,
83746
+ path: path26,
83463
83747
  rendererID,
83464
83748
  wasForwarded: true,
83465
83749
  value
@@ -83468,7 +83752,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83468
83752
  case "hooks":
83469
83753
  _this.send("overrideHookState", {
83470
83754
  id,
83471
- path: path25,
83755
+ path: path26,
83472
83756
  rendererID,
83473
83757
  wasForwarded: true,
83474
83758
  value
@@ -83477,7 +83761,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83477
83761
  case "props":
83478
83762
  _this.send("overrideProps", {
83479
83763
  id,
83480
- path: path25,
83764
+ path: path26,
83481
83765
  rendererID,
83482
83766
  wasForwarded: true,
83483
83767
  value
@@ -83486,7 +83770,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83486
83770
  case "state":
83487
83771
  _this.send("overrideState", {
83488
83772
  id,
83489
- path: path25,
83773
+ path: path26,
83490
83774
  rendererID,
83491
83775
  wasForwarded: true,
83492
83776
  value
@@ -83820,12 +84104,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83820
84104
  }
83821
84105
  });
83822
84106
  agent_defineProperty(_this, "copyElementPath", function(_ref5) {
83823
- var { id, path: path25, rendererID } = _ref5;
84107
+ var { id, path: path26, rendererID } = _ref5;
83824
84108
  var renderer = _this._rendererInterfaces[rendererID];
83825
84109
  if (renderer == null) {
83826
84110
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
83827
84111
  } else {
83828
- var value = renderer.getSerializedElementValueByPath(id, path25);
84112
+ var value = renderer.getSerializedElementValueByPath(id, path26);
83829
84113
  if (value != null) {
83830
84114
  _this._bridge.send("saveToClipboard", value);
83831
84115
  } else {
@@ -83834,12 +84118,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83834
84118
  }
83835
84119
  });
83836
84120
  agent_defineProperty(_this, "deletePath", function(_ref6) {
83837
- var { hookID, id, path: path25, rendererID, type } = _ref6;
84121
+ var { hookID, id, path: path26, rendererID, type } = _ref6;
83838
84122
  var renderer = _this._rendererInterfaces[rendererID];
83839
84123
  if (renderer == null) {
83840
84124
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
83841
84125
  } else {
83842
- renderer.deletePath(type, id, hookID, path25);
84126
+ renderer.deletePath(type, id, hookID, path26);
83843
84127
  }
83844
84128
  });
83845
84129
  agent_defineProperty(_this, "getBackendVersion", function() {
@@ -83876,12 +84160,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83876
84160
  }
83877
84161
  });
83878
84162
  agent_defineProperty(_this, "inspectElement", function(_ref9) {
83879
- var { forceFullData, id, path: path25, rendererID, requestID } = _ref9;
84163
+ var { forceFullData, id, path: path26, rendererID, requestID } = _ref9;
83880
84164
  var renderer = _this._rendererInterfaces[rendererID];
83881
84165
  if (renderer == null) {
83882
84166
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
83883
84167
  } else {
83884
- _this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id, path25, forceFullData));
84168
+ _this._bridge.send("inspectedElement", renderer.inspectElement(requestID, id, path26, forceFullData));
83885
84169
  if (_this._persistedSelectionMatch === null || _this._persistedSelectionMatch.id !== id) {
83886
84170
  _this._persistedSelection = null;
83887
84171
  _this._persistedSelectionMatch = null;
@@ -83915,15 +84199,15 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
83915
84199
  }
83916
84200
  for (var rendererID in _this._rendererInterfaces) {
83917
84201
  var renderer = _this._rendererInterfaces[rendererID];
83918
- var path25 = null;
84202
+ var path26 = null;
83919
84203
  if (suspendedByPathIndex !== null && rendererPath !== null) {
83920
84204
  var suspendedByPathRendererIndex = suspendedByPathIndex - suspendedByOffset;
83921
84205
  var rendererHasRequestedSuspendedByPath = renderer.getElementAttributeByPath(id, ["suspendedBy", suspendedByPathRendererIndex]) !== undefined;
83922
84206
  if (rendererHasRequestedSuspendedByPath) {
83923
- path25 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
84207
+ path26 = ["suspendedBy", suspendedByPathRendererIndex].concat(rendererPath);
83924
84208
  }
83925
84209
  }
83926
- var inspectedRootsPayload = renderer.inspectElement(requestID, id, path25, forceFullData);
84210
+ var inspectedRootsPayload = renderer.inspectElement(requestID, id, path26, forceFullData);
83927
84211
  switch (inspectedRootsPayload.type) {
83928
84212
  case "hydrated-path":
83929
84213
  inspectedRootsPayload.path[1] += suspendedByOffset;
@@ -84017,20 +84301,20 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84017
84301
  }
84018
84302
  });
84019
84303
  agent_defineProperty(_this, "overrideValueAtPath", function(_ref15) {
84020
- var { hookID, id, path: path25, rendererID, type, value } = _ref15;
84304
+ var { hookID, id, path: path26, rendererID, type, value } = _ref15;
84021
84305
  var renderer = _this._rendererInterfaces[rendererID];
84022
84306
  if (renderer == null) {
84023
84307
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
84024
84308
  } else {
84025
- renderer.overrideValueAtPath(type, id, hookID, path25, value);
84309
+ renderer.overrideValueAtPath(type, id, hookID, path26, value);
84026
84310
  }
84027
84311
  });
84028
84312
  agent_defineProperty(_this, "overrideContext", function(_ref16) {
84029
- var { id, path: path25, rendererID, wasForwarded, value } = _ref16;
84313
+ var { id, path: path26, rendererID, wasForwarded, value } = _ref16;
84030
84314
  if (!wasForwarded) {
84031
84315
  _this.overrideValueAtPath({
84032
84316
  id,
84033
- path: path25,
84317
+ path: path26,
84034
84318
  rendererID,
84035
84319
  type: "context",
84036
84320
  value
@@ -84038,11 +84322,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84038
84322
  }
84039
84323
  });
84040
84324
  agent_defineProperty(_this, "overrideHookState", function(_ref17) {
84041
- var { id, hookID, path: path25, rendererID, wasForwarded, value } = _ref17;
84325
+ var { id, hookID, path: path26, rendererID, wasForwarded, value } = _ref17;
84042
84326
  if (!wasForwarded) {
84043
84327
  _this.overrideValueAtPath({
84044
84328
  id,
84045
- path: path25,
84329
+ path: path26,
84046
84330
  rendererID,
84047
84331
  type: "hooks",
84048
84332
  value
@@ -84050,11 +84334,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84050
84334
  }
84051
84335
  });
84052
84336
  agent_defineProperty(_this, "overrideProps", function(_ref18) {
84053
- var { id, path: path25, rendererID, wasForwarded, value } = _ref18;
84337
+ var { id, path: path26, rendererID, wasForwarded, value } = _ref18;
84054
84338
  if (!wasForwarded) {
84055
84339
  _this.overrideValueAtPath({
84056
84340
  id,
84057
- path: path25,
84341
+ path: path26,
84058
84342
  rendererID,
84059
84343
  type: "props",
84060
84344
  value
@@ -84062,11 +84346,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84062
84346
  }
84063
84347
  });
84064
84348
  agent_defineProperty(_this, "overrideState", function(_ref19) {
84065
- var { id, path: path25, rendererID, wasForwarded, value } = _ref19;
84349
+ var { id, path: path26, rendererID, wasForwarded, value } = _ref19;
84066
84350
  if (!wasForwarded) {
84067
84351
  _this.overrideValueAtPath({
84068
84352
  id,
84069
- path: path25,
84353
+ path: path26,
84070
84354
  rendererID,
84071
84355
  type: "state",
84072
84356
  value
@@ -84133,12 +84417,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84133
84417
  _this._bridge.send("stopInspectingHost", selected);
84134
84418
  });
84135
84419
  agent_defineProperty(_this, "storeAsGlobal", function(_ref23) {
84136
- var { count, id, path: path25, rendererID } = _ref23;
84420
+ var { count, id, path: path26, rendererID } = _ref23;
84137
84421
  var renderer = _this._rendererInterfaces[rendererID];
84138
84422
  if (renderer == null) {
84139
84423
  console.warn('Invalid renderer id "'.concat(rendererID, '" for element "').concat(id, '"'));
84140
84424
  } else {
84141
- renderer.storeAsGlobal(id, path25, count);
84425
+ renderer.storeAsGlobal(id, path26, count);
84142
84426
  }
84143
84427
  });
84144
84428
  agent_defineProperty(_this, "updateHookSettings", function(settings) {
@@ -84155,12 +84439,12 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84155
84439
  var rendererID = +rendererIDString;
84156
84440
  var renderer = _this._rendererInterfaces[rendererID];
84157
84441
  if (_this._lastSelectedRendererID === rendererID) {
84158
- var path25 = renderer.getPathForElement(_this._lastSelectedElementID);
84159
- if (path25 !== null) {
84160
- renderer.setTrackedPath(path25);
84442
+ var path26 = renderer.getPathForElement(_this._lastSelectedElementID);
84443
+ if (path26 !== null) {
84444
+ renderer.setTrackedPath(path26);
84161
84445
  _this._persistedSelection = {
84162
84446
  rendererID,
84163
- path: path25
84447
+ path: path26
84164
84448
  };
84165
84449
  }
84166
84450
  }
@@ -84235,11 +84519,11 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84235
84519
  var rendererID = _this._lastSelectedRendererID;
84236
84520
  var id = _this._lastSelectedElementID;
84237
84521
  var renderer = _this._rendererInterfaces[rendererID];
84238
- var path25 = renderer != null ? renderer.getPathForElement(id) : null;
84239
- if (path25 !== null) {
84522
+ var path26 = renderer != null ? renderer.getPathForElement(id) : null;
84523
+ if (path26 !== null) {
84240
84524
  storage_sessionStorageSetItem(SESSION_STORAGE_LAST_SELECTION_KEY, JSON.stringify({
84241
84525
  rendererID,
84242
- path: path25
84526
+ path: path26
84243
84527
  }));
84244
84528
  } else {
84245
84529
  storage_sessionStorageRemoveItem(SESSION_STORAGE_LAST_SELECTION_KEY);
@@ -84962,7 +85246,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
84962
85246
  hasElementWithId: function hasElementWithId() {
84963
85247
  return false;
84964
85248
  },
84965
- inspectElement: function inspectElement(requestID, id, path25) {
85249
+ inspectElement: function inspectElement(requestID, id, path26) {
84966
85250
  return {
84967
85251
  id,
84968
85252
  responseID: requestID,
@@ -90232,9 +90516,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
90232
90516
  }
90233
90517
  return null;
90234
90518
  }
90235
- function getElementAttributeByPath(id, path25) {
90519
+ function getElementAttributeByPath(id, path26) {
90236
90520
  if (isMostRecentlyInspectedElement(id)) {
90237
- return utils_getInObject(mostRecentlyInspectedElement, path25);
90521
+ return utils_getInObject(mostRecentlyInspectedElement, path26);
90238
90522
  }
90239
90523
  return;
90240
90524
  }
@@ -90937,9 +91221,9 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
90937
91221
  function isMostRecentlyInspectedElementCurrent(id) {
90938
91222
  return isMostRecentlyInspectedElement(id) && !hasElementUpdatedSinceLastInspected;
90939
91223
  }
90940
- function mergeInspectedPaths(path25) {
91224
+ function mergeInspectedPaths(path26) {
90941
91225
  var current = currentlyInspectedPaths;
90942
- path25.forEach(function(key) {
91226
+ path26.forEach(function(key) {
90943
91227
  if (!current[key]) {
90944
91228
  current[key] = {};
90945
91229
  }
@@ -90947,21 +91231,21 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
90947
91231
  });
90948
91232
  }
90949
91233
  function createIsPathAllowed(key, secondaryCategory) {
90950
- return function isPathAllowed(path25) {
91234
+ return function isPathAllowed(path26) {
90951
91235
  switch (secondaryCategory) {
90952
91236
  case "hooks":
90953
- if (path25.length === 1) {
91237
+ if (path26.length === 1) {
90954
91238
  return true;
90955
91239
  }
90956
- if (path25[path25.length - 2] === "hookSource" && path25[path25.length - 1] === "fileName") {
91240
+ if (path26[path26.length - 2] === "hookSource" && path26[path26.length - 1] === "fileName") {
90957
91241
  return true;
90958
91242
  }
90959
- if (path25[path25.length - 1] === "subHooks" || path25[path25.length - 2] === "subHooks") {
91243
+ if (path26[path26.length - 1] === "subHooks" || path26[path26.length - 2] === "subHooks") {
90960
91244
  return true;
90961
91245
  }
90962
91246
  break;
90963
91247
  case "suspendedBy":
90964
- if (path25.length < 5) {
91248
+ if (path26.length < 5) {
90965
91249
  return true;
90966
91250
  }
90967
91251
  break;
@@ -90972,8 +91256,8 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
90972
91256
  if (!current) {
90973
91257
  return false;
90974
91258
  }
90975
- for (var i = 0;i < path25.length; i++) {
90976
- current = current[path25[i]];
91259
+ for (var i = 0;i < path26.length; i++) {
91260
+ current = current[path26[i]];
90977
91261
  if (!current) {
90978
91262
  return false;
90979
91263
  }
@@ -91027,38 +91311,38 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
91027
91311
  break;
91028
91312
  }
91029
91313
  }
91030
- function storeAsGlobal(id, path25, count) {
91314
+ function storeAsGlobal(id, path26, count) {
91031
91315
  if (isMostRecentlyInspectedElement(id)) {
91032
- var value = utils_getInObject(mostRecentlyInspectedElement, path25);
91316
+ var value = utils_getInObject(mostRecentlyInspectedElement, path26);
91033
91317
  var key = "$reactTemp".concat(count);
91034
91318
  window[key] = value;
91035
91319
  console.log(key);
91036
91320
  console.log(value);
91037
91321
  }
91038
91322
  }
91039
- function getSerializedElementValueByPath(id, path25) {
91323
+ function getSerializedElementValueByPath(id, path26) {
91040
91324
  if (isMostRecentlyInspectedElement(id)) {
91041
- var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path25);
91325
+ var valueToCopy = utils_getInObject(mostRecentlyInspectedElement, path26);
91042
91326
  return serializeToString(valueToCopy);
91043
91327
  }
91044
91328
  }
91045
- function inspectElement(requestID, id, path25, forceFullData) {
91046
- if (path25 !== null) {
91047
- mergeInspectedPaths(path25);
91329
+ function inspectElement(requestID, id, path26, forceFullData) {
91330
+ if (path26 !== null) {
91331
+ mergeInspectedPaths(path26);
91048
91332
  }
91049
91333
  if (isMostRecentlyInspectedElement(id) && !forceFullData) {
91050
91334
  if (!hasElementUpdatedSinceLastInspected) {
91051
- if (path25 !== null) {
91335
+ if (path26 !== null) {
91052
91336
  var secondaryCategory = null;
91053
- if (path25[0] === "hooks" || path25[0] === "suspendedBy") {
91054
- secondaryCategory = path25[0];
91337
+ if (path26[0] === "hooks" || path26[0] === "suspendedBy") {
91338
+ secondaryCategory = path26[0];
91055
91339
  }
91056
91340
  return {
91057
91341
  id,
91058
91342
  responseID: requestID,
91059
91343
  type: "hydrated-path",
91060
- path: path25,
91061
- value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement, path25), createIsPathAllowed(null, secondaryCategory), path25)
91344
+ path: path26,
91345
+ value: cleanForBridge(utils_getInObject(mostRecentlyInspectedElement, path26), createIsPathAllowed(null, secondaryCategory), path26)
91062
91346
  };
91063
91347
  } else {
91064
91348
  return {
@@ -91254,7 +91538,7 @@ The error thrown in the component is:
91254
91538
  console.groupEnd();
91255
91539
  }
91256
91540
  }
91257
- function deletePath(type, id, hookID, path25) {
91541
+ function deletePath(type, id, hookID, path26) {
91258
91542
  var devtoolsInstance = idToDevToolsInstanceMap.get(id);
91259
91543
  if (devtoolsInstance === undefined) {
91260
91544
  console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
@@ -91268,11 +91552,11 @@ The error thrown in the component is:
91268
91552
  var instance2 = fiber.stateNode;
91269
91553
  switch (type) {
91270
91554
  case "context":
91271
- path25 = path25.slice(1);
91555
+ path26 = path26.slice(1);
91272
91556
  switch (fiber.tag) {
91273
91557
  case ClassComponent:
91274
- if (path25.length === 0) {} else {
91275
- deletePathInObject(instance2.context, path25);
91558
+ if (path26.length === 0) {} else {
91559
+ deletePathInObject(instance2.context, path26);
91276
91560
  }
91277
91561
  instance2.forceUpdate();
91278
91562
  break;
@@ -91282,21 +91566,21 @@ The error thrown in the component is:
91282
91566
  break;
91283
91567
  case "hooks":
91284
91568
  if (typeof overrideHookStateDeletePath === "function") {
91285
- overrideHookStateDeletePath(fiber, hookID, path25);
91569
+ overrideHookStateDeletePath(fiber, hookID, path26);
91286
91570
  }
91287
91571
  break;
91288
91572
  case "props":
91289
91573
  if (instance2 === null) {
91290
91574
  if (typeof overridePropsDeletePath === "function") {
91291
- overridePropsDeletePath(fiber, path25);
91575
+ overridePropsDeletePath(fiber, path26);
91292
91576
  }
91293
91577
  } else {
91294
- fiber.pendingProps = copyWithDelete(instance2.props, path25);
91578
+ fiber.pendingProps = copyWithDelete(instance2.props, path26);
91295
91579
  instance2.forceUpdate();
91296
91580
  }
91297
91581
  break;
91298
91582
  case "state":
91299
- deletePathInObject(instance2.state, path25);
91583
+ deletePathInObject(instance2.state, path26);
91300
91584
  instance2.forceUpdate();
91301
91585
  break;
91302
91586
  }
@@ -91351,7 +91635,7 @@ The error thrown in the component is:
91351
91635
  }
91352
91636
  }
91353
91637
  }
91354
- function overrideValueAtPath(type, id, hookID, path25, value) {
91638
+ function overrideValueAtPath(type, id, hookID, path26, value) {
91355
91639
  var devtoolsInstance = idToDevToolsInstanceMap.get(id);
91356
91640
  if (devtoolsInstance === undefined) {
91357
91641
  console.warn('Could not find DevToolsInstance with id "'.concat(id, '"'));
@@ -91365,13 +91649,13 @@ The error thrown in the component is:
91365
91649
  var instance2 = fiber.stateNode;
91366
91650
  switch (type) {
91367
91651
  case "context":
91368
- path25 = path25.slice(1);
91652
+ path26 = path26.slice(1);
91369
91653
  switch (fiber.tag) {
91370
91654
  case ClassComponent:
91371
- if (path25.length === 0) {
91655
+ if (path26.length === 0) {
91372
91656
  instance2.context = value;
91373
91657
  } else {
91374
- utils_setInObject(instance2.context, path25, value);
91658
+ utils_setInObject(instance2.context, path26, value);
91375
91659
  }
91376
91660
  instance2.forceUpdate();
91377
91661
  break;
@@ -91381,18 +91665,18 @@ The error thrown in the component is:
91381
91665
  break;
91382
91666
  case "hooks":
91383
91667
  if (typeof overrideHookState === "function") {
91384
- overrideHookState(fiber, hookID, path25, value);
91668
+ overrideHookState(fiber, hookID, path26, value);
91385
91669
  }
91386
91670
  break;
91387
91671
  case "props":
91388
91672
  switch (fiber.tag) {
91389
91673
  case ClassComponent:
91390
- fiber.pendingProps = copyWithSet(instance2.props, path25, value);
91674
+ fiber.pendingProps = copyWithSet(instance2.props, path26, value);
91391
91675
  instance2.forceUpdate();
91392
91676
  break;
91393
91677
  default:
91394
91678
  if (typeof overrideProps === "function") {
91395
- overrideProps(fiber, path25, value);
91679
+ overrideProps(fiber, path26, value);
91396
91680
  }
91397
91681
  break;
91398
91682
  }
@@ -91400,7 +91684,7 @@ The error thrown in the component is:
91400
91684
  case "state":
91401
91685
  switch (fiber.tag) {
91402
91686
  case ClassComponent:
91403
- utils_setInObject(instance2.state, path25, value);
91687
+ utils_setInObject(instance2.state, path26, value);
91404
91688
  instance2.forceUpdate();
91405
91689
  break;
91406
91690
  }
@@ -91686,14 +91970,14 @@ The error thrown in the component is:
91686
91970
  var trackedPathMatchInstance = null;
91687
91971
  var trackedPathMatchDepth = -1;
91688
91972
  var mightBeOnTrackedPath = false;
91689
- function setTrackedPath(path25) {
91690
- if (path25 === null) {
91973
+ function setTrackedPath(path26) {
91974
+ if (path26 === null) {
91691
91975
  trackedPathMatchFiber = null;
91692
91976
  trackedPathMatchInstance = null;
91693
91977
  trackedPathMatchDepth = -1;
91694
91978
  mightBeOnTrackedPath = false;
91695
91979
  }
91696
- trackedPath = path25;
91980
+ trackedPath = path26;
91697
91981
  }
91698
91982
  function updateTrackedPathStateBeforeMount(fiber, fiberInstance) {
91699
91983
  if (trackedPath === null || !mightBeOnTrackedPath) {
@@ -92457,9 +92741,9 @@ The error thrown in the component is:
92457
92741
  }
92458
92742
  var currentlyInspectedElementID = null;
92459
92743
  var currentlyInspectedPaths = {};
92460
- function mergeInspectedPaths(path25) {
92744
+ function mergeInspectedPaths(path26) {
92461
92745
  var current = currentlyInspectedPaths;
92462
- path25.forEach(function(key) {
92746
+ path26.forEach(function(key) {
92463
92747
  if (!current[key]) {
92464
92748
  current[key] = {};
92465
92749
  }
@@ -92467,13 +92751,13 @@ The error thrown in the component is:
92467
92751
  });
92468
92752
  }
92469
92753
  function createIsPathAllowed(key) {
92470
- return function isPathAllowed(path25) {
92754
+ return function isPathAllowed(path26) {
92471
92755
  var current = currentlyInspectedPaths[key];
92472
92756
  if (!current) {
92473
92757
  return false;
92474
92758
  }
92475
- for (var i = 0;i < path25.length; i++) {
92476
- current = current[path25[i]];
92759
+ for (var i = 0;i < path26.length; i++) {
92760
+ current = current[path26[i]];
92477
92761
  if (!current) {
92478
92762
  return false;
92479
92763
  }
@@ -92523,24 +92807,24 @@ The error thrown in the component is:
92523
92807
  break;
92524
92808
  }
92525
92809
  }
92526
- function storeAsGlobal(id, path25, count) {
92810
+ function storeAsGlobal(id, path26, count) {
92527
92811
  var inspectedElement = inspectElementRaw(id);
92528
92812
  if (inspectedElement !== null) {
92529
- var value = utils_getInObject(inspectedElement, path25);
92813
+ var value = utils_getInObject(inspectedElement, path26);
92530
92814
  var key = "$reactTemp".concat(count);
92531
92815
  window[key] = value;
92532
92816
  console.log(key);
92533
92817
  console.log(value);
92534
92818
  }
92535
92819
  }
92536
- function getSerializedElementValueByPath(id, path25) {
92820
+ function getSerializedElementValueByPath(id, path26) {
92537
92821
  var inspectedElement = inspectElementRaw(id);
92538
92822
  if (inspectedElement !== null) {
92539
- var valueToCopy = utils_getInObject(inspectedElement, path25);
92823
+ var valueToCopy = utils_getInObject(inspectedElement, path26);
92540
92824
  return serializeToString(valueToCopy);
92541
92825
  }
92542
92826
  }
92543
- function inspectElement(requestID, id, path25, forceFullData) {
92827
+ function inspectElement(requestID, id, path26, forceFullData) {
92544
92828
  if (forceFullData || currentlyInspectedElementID !== id) {
92545
92829
  currentlyInspectedElementID = id;
92546
92830
  currentlyInspectedPaths = {};
@@ -92553,8 +92837,8 @@ The error thrown in the component is:
92553
92837
  type: "not-found"
92554
92838
  };
92555
92839
  }
92556
- if (path25 !== null) {
92557
- mergeInspectedPaths(path25);
92840
+ if (path26 !== null) {
92841
+ mergeInspectedPaths(path26);
92558
92842
  }
92559
92843
  updateSelectedElement(id);
92560
92844
  inspectedElement.context = cleanForBridge(inspectedElement.context, createIsPathAllowed("context"));
@@ -92757,10 +93041,10 @@ The error thrown in the component is:
92757
93041
  console.groupEnd();
92758
93042
  }
92759
93043
  }
92760
- function getElementAttributeByPath(id, path25) {
93044
+ function getElementAttributeByPath(id, path26) {
92761
93045
  var inspectedElement = inspectElementRaw(id);
92762
93046
  if (inspectedElement !== null) {
92763
- return utils_getInObject(inspectedElement, path25);
93047
+ return utils_getInObject(inspectedElement, path26);
92764
93048
  }
92765
93049
  return;
92766
93050
  }
@@ -92777,14 +93061,14 @@ The error thrown in the component is:
92777
93061
  }
92778
93062
  return element.type;
92779
93063
  }
92780
- function deletePath(type, id, hookID, path25) {
93064
+ function deletePath(type, id, hookID, path26) {
92781
93065
  var internalInstance = idToInternalInstanceMap.get(id);
92782
93066
  if (internalInstance != null) {
92783
93067
  var publicInstance = internalInstance._instance;
92784
93068
  if (publicInstance != null) {
92785
93069
  switch (type) {
92786
93070
  case "context":
92787
- deletePathInObject(publicInstance.context, path25);
93071
+ deletePathInObject(publicInstance.context, path26);
92788
93072
  forceUpdate(publicInstance);
92789
93073
  break;
92790
93074
  case "hooks":
@@ -92792,12 +93076,12 @@ The error thrown in the component is:
92792
93076
  case "props":
92793
93077
  var element = internalInstance._currentElement;
92794
93078
  internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
92795
- props: copyWithDelete(element.props, path25)
93079
+ props: copyWithDelete(element.props, path26)
92796
93080
  });
92797
93081
  forceUpdate(publicInstance);
92798
93082
  break;
92799
93083
  case "state":
92800
- deletePathInObject(publicInstance.state, path25);
93084
+ deletePathInObject(publicInstance.state, path26);
92801
93085
  forceUpdate(publicInstance);
92802
93086
  break;
92803
93087
  }
@@ -92831,14 +93115,14 @@ The error thrown in the component is:
92831
93115
  }
92832
93116
  }
92833
93117
  }
92834
- function overrideValueAtPath(type, id, hookID, path25, value) {
93118
+ function overrideValueAtPath(type, id, hookID, path26, value) {
92835
93119
  var internalInstance = idToInternalInstanceMap.get(id);
92836
93120
  if (internalInstance != null) {
92837
93121
  var publicInstance = internalInstance._instance;
92838
93122
  if (publicInstance != null) {
92839
93123
  switch (type) {
92840
93124
  case "context":
92841
- utils_setInObject(publicInstance.context, path25, value);
93125
+ utils_setInObject(publicInstance.context, path26, value);
92842
93126
  forceUpdate(publicInstance);
92843
93127
  break;
92844
93128
  case "hooks":
@@ -92846,12 +93130,12 @@ The error thrown in the component is:
92846
93130
  case "props":
92847
93131
  var element = internalInstance._currentElement;
92848
93132
  internalInstance._currentElement = legacy_renderer_objectSpread(legacy_renderer_objectSpread({}, element), {}, {
92849
- props: copyWithSet(element.props, path25, value)
93133
+ props: copyWithSet(element.props, path26, value)
92850
93134
  });
92851
93135
  forceUpdate(publicInstance);
92852
93136
  break;
92853
93137
  case "state":
92854
- utils_setInObject(publicInstance.state, path25, value);
93138
+ utils_setInObject(publicInstance.state, path26, value);
92855
93139
  forceUpdate(publicInstance);
92856
93140
  break;
92857
93141
  }
@@ -92892,7 +93176,7 @@ The error thrown in the component is:
92892
93176
  return [];
92893
93177
  }
92894
93178
  function setTraceUpdatesEnabled(enabled) {}
92895
- function setTrackedPath(path25) {}
93179
+ function setTrackedPath(path26) {}
92896
93180
  function getOwnersList(id) {
92897
93181
  return null;
92898
93182
  }
@@ -96201,10 +96485,10 @@ init_setup();
96201
96485
  // src/cli/plugins.ts
96202
96486
  init_paths();
96203
96487
  init_loader4();
96204
- import * as path17 from "path";
96488
+ import * as path18 from "path";
96205
96489
  async function pluginsListCommand(config2, workdir, overrideGlobalPluginsDir) {
96206
- const globalPluginsDir = overrideGlobalPluginsDir ?? path17.join(globalConfigDir(), "plugins");
96207
- const projectPluginsDir = path17.join(workdir, ".nax", "plugins");
96490
+ const globalPluginsDir = overrideGlobalPluginsDir ?? path18.join(globalConfigDir(), "plugins");
96491
+ const projectPluginsDir = path18.join(workdir, ".nax", "plugins");
96208
96492
  const configPlugins = config2.plugins || [];
96209
96493
  const registry2 = await loadPlugins(globalPluginsDir, projectPluginsDir, configPlugins, workdir, config2.disabledPlugins);
96210
96494
  const plugins = registry2.plugins;
@@ -96254,10 +96538,10 @@ function formatSource(type, sourcePath) {
96254
96538
  return `built-in (${sourcePath})`;
96255
96539
  }
96256
96540
  if (type === "global") {
96257
- return `global (${path17.basename(sourcePath)})`;
96541
+ return `global (${path18.basename(sourcePath)})`;
96258
96542
  }
96259
96543
  if (type === "project") {
96260
- return `project (${path17.basename(sourcePath)})`;
96544
+ return `project (${path18.basename(sourcePath)})`;
96261
96545
  }
96262
96546
  return `config (${sourcePath})`;
96263
96547
  }
@@ -96649,10 +96933,10 @@ function deepDiffConfigs(global2, project, currentPath = []) {
96649
96933
  for (const key of Object.keys(project)) {
96650
96934
  const projectValue = project[key];
96651
96935
  const globalValue = global2[key];
96652
- const path18 = [...currentPath, key];
96653
- const pathStr = path18.join(".");
96936
+ const path19 = [...currentPath, key];
96937
+ const pathStr = path19.join(".");
96654
96938
  if (projectValue !== null && typeof projectValue === "object" && !Array.isArray(projectValue) && globalValue !== null && typeof globalValue === "object" && !Array.isArray(globalValue)) {
96655
- const nestedDiffs = deepDiffConfigs(globalValue, projectValue, path18);
96939
+ const nestedDiffs = deepDiffConfigs(globalValue, projectValue, path19);
96656
96940
  diffs.push(...nestedDiffs);
96657
96941
  } else {
96658
96942
  if (!deepEqual(projectValue, globalValue)) {
@@ -96695,11 +96979,11 @@ init_defaults();
96695
96979
  init_loader();
96696
96980
  import { existsSync as existsSync25 } from "fs";
96697
96981
  import { join as join63 } from "path";
96698
- async function loadConfigFile(path18) {
96699
- if (!existsSync25(path18))
96982
+ async function loadConfigFile(path19) {
96983
+ if (!existsSync25(path19))
96700
96984
  return null;
96701
96985
  try {
96702
- return await Bun.file(path18).json();
96986
+ return await Bun.file(path19).json();
96703
96987
  } catch {
96704
96988
  return null;
96705
96989
  }
@@ -96746,10 +97030,10 @@ async function configCommand(config2, options = {}) {
96746
97030
  console.log(`${"Field".padEnd(40)}${"Project Value".padEnd(20)}Global Value`);
96747
97031
  console.log("\u2500".repeat(80));
96748
97032
  for (const diff2 of diffs) {
96749
- const path18 = diff2.path.padEnd(40);
97033
+ const path19 = diff2.path.padEnd(40);
96750
97034
  const projectVal = formatValueForTable(diff2.projectValue);
96751
97035
  const globalVal = formatValueForTable(diff2.globalValue);
96752
- console.log(`${path18}${projectVal.padEnd(20)}${globalVal}`);
97036
+ console.log(`${path19}${projectVal.padEnd(20)}${globalVal}`);
96753
97037
  const description = FIELD_DESCRIPTIONS[diff2.path];
96754
97038
  if (description) {
96755
97039
  console.log(`${"".padEnd(40)}\u21B3 ${description}`);
@@ -96782,26 +97066,26 @@ function determineConfigSources() {
96782
97066
  project: projectPath && fileExists(projectPath) ? projectPath : null
96783
97067
  };
96784
97068
  }
96785
- function fileExists(path18) {
96786
- return existsSync26(path18);
97069
+ function fileExists(path19) {
97070
+ return existsSync26(path19);
96787
97071
  }
96788
- function displayConfigWithDescriptions(obj, path18, sources, indent = 0) {
97072
+ function displayConfigWithDescriptions(obj, path19, sources, indent = 0) {
96789
97073
  const indentStr = " ".repeat(indent);
96790
- const pathStr = path18.join(".");
97074
+ const pathStr = path19.join(".");
96791
97075
  if (obj === null || obj === undefined || typeof obj !== "object" || Array.isArray(obj)) {
96792
97076
  const description = FIELD_DESCRIPTIONS[pathStr];
96793
97077
  const value = formatValue(obj);
96794
97078
  if (description) {
96795
97079
  console.log(`${indentStr}# ${description}`);
96796
97080
  }
96797
- const key = path18[path18.length - 1] || "";
97081
+ const key = path19[path19.length - 1] || "";
96798
97082
  console.log(`${indentStr}${key}: ${value}`);
96799
97083
  console.log();
96800
97084
  return;
96801
97085
  }
96802
97086
  const entries = Object.entries(obj);
96803
97087
  const objAsRecord = obj;
96804
- const isPromptsSection = path18.join(".") === "prompts";
97088
+ const isPromptsSection = path19.join(".") === "prompts";
96805
97089
  if (isPromptsSection && !objAsRecord.overrides) {
96806
97090
  const description = FIELD_DESCRIPTIONS["prompts.overrides"];
96807
97091
  if (description) {
@@ -96824,7 +97108,7 @@ function displayConfigWithDescriptions(obj, path18, sources, indent = 0) {
96824
97108
  }
96825
97109
  for (let i = 0;i < entries.length; i++) {
96826
97110
  const [key, value] = entries[i];
96827
- const currentPath = [...path18, key];
97111
+ const currentPath = [...path19, key];
96828
97112
  const currentPathStr = currentPath.join(".");
96829
97113
  const description = FIELD_DESCRIPTIONS[currentPathStr];
96830
97114
  if (description) {
@@ -97136,11 +97420,11 @@ init_errors();
97136
97420
  import { mkdir as mkdir11 } from "fs/promises";
97137
97421
  import { basename as basename12, join as join66 } from "path";
97138
97422
  var _rulesCLIDeps = {
97139
- readFile: async (path18) => Bun.file(path18).text(),
97140
- writeFile: async (path18, content) => {
97141
- await Bun.write(path18, content);
97423
+ readFile: async (path19) => Bun.file(path19).text(),
97424
+ writeFile: async (path19, content) => {
97425
+ await Bun.write(path19, content);
97142
97426
  },
97143
- fileExists: async (path18) => Bun.file(path18).exists(),
97427
+ fileExists: async (path19) => Bun.file(path19).exists(),
97144
97428
  globInDir: (dir) => {
97145
97429
  try {
97146
97430
  return [...new Bun.Glob("*.md").scanSync({ cwd: dir })].sort().map((f) => join66(dir, f));
@@ -97148,8 +97432,8 @@ var _rulesCLIDeps = {
97148
97432
  return [];
97149
97433
  }
97150
97434
  },
97151
- mkdir: async (path18) => {
97152
- await mkdir11(path18, { recursive: true });
97435
+ mkdir: async (path19) => {
97436
+ await mkdir11(path19, { recursive: true });
97153
97437
  },
97154
97438
  globCanonicalRuleFiles: (workdir) => {
97155
97439
  try {
@@ -97313,6 +97597,35 @@ async function rulesLintCommand(options) {
97313
97597
  const scopeLabel = roots.length === 1 ? "repo root" : `${roots.length} rule roots`;
97314
97598
  console.log(`[OK] Canonical rules lint passed (${totalRuleFiles} file(s) across ${scopeLabel}).`);
97315
97599
  }
97600
+ // src/cli/resolve-run-profile.ts
97601
+ init_config();
97602
+ init_logger2();
97603
+ async function resolveRunProfileOverride(opts) {
97604
+ if (opts.cliProfile)
97605
+ return opts.cliProfile;
97606
+ if (opts.envProfile)
97607
+ return;
97608
+ const readJson = opts._readJson ?? (async (path19) => {
97609
+ const file3 = Bun.file(path19);
97610
+ if (!await file3.exists())
97611
+ return;
97612
+ return file3.json();
97613
+ });
97614
+ try {
97615
+ const prd = await readJson(opts.prdPath);
97616
+ if (prd && typeof prd.routingProfile === "string" && prd.routingProfile.length > 0) {
97617
+ const name = prd.routingProfile;
97618
+ if (name === "default")
97619
+ return name;
97620
+ const listNames = opts._listProfileNames ?? (async () => (await listProfiles(opts.projectRoot)).map((p) => p.name));
97621
+ const available = await listNames();
97622
+ if (available.includes(name))
97623
+ return name;
97624
+ getSafeLogger()?.warn("run", `PRD was planned with config profile "${name}" but no such profile exists \u2014 continuing with current config resolution`, { storyId: "prd", plannedProfile: name });
97625
+ }
97626
+ } catch {}
97627
+ return;
97628
+ }
97316
97629
  // src/commands/detect.ts
97317
97630
  init_source();
97318
97631
  init_config();
@@ -97328,14 +97641,14 @@ function resolveEffective(detected, configPatterns) {
97328
97641
  return "detected";
97329
97642
  return "none";
97330
97643
  }
97331
- async function loadRawConfig(path18) {
97332
- const f = Bun.file(path18);
97644
+ async function loadRawConfig(path19) {
97645
+ const f = Bun.file(path19);
97333
97646
  if (!await f.exists())
97334
97647
  return {};
97335
97648
  return JSON.parse(await f.text());
97336
97649
  }
97337
- async function writeRawConfig(path18, data) {
97338
- await Bun.write(path18, `${JSON.stringify(data, null, 2)}
97650
+ async function writeRawConfig(path19, data) {
97651
+ await Bun.write(path19, `${JSON.stringify(data, null, 2)}
97339
97652
  `);
97340
97653
  }
97341
97654
  function deepSet(obj, keyPath, value) {
@@ -98043,7 +98356,7 @@ init_prd();
98043
98356
  init_git();
98044
98357
  init_crash_recovery();
98045
98358
  init_story_context();
98046
- import path19 from "path";
98359
+ import path20 from "path";
98047
98360
  var _runnerCompletionDeps = {
98048
98361
  async runAcceptanceLoop(ctx) {
98049
98362
  const { runAcceptanceLoop: runAcceptanceLoop2 } = await Promise.resolve().then(() => (init_acceptance_loop(), exports_acceptance_loop));
@@ -98074,11 +98387,11 @@ async function runCompletionPhase(options) {
98074
98387
  options.statusWriter.setPostRunPhase("acceptance", { status: "running" });
98075
98388
  pipelineEventBus.emit({ type: "postrun:phase:started", phase: "acceptance" });
98076
98389
  const acceptanceTestPaths = options.featureDir ? await Promise.all((await groupStoriesByPackage(options.prd, options.workdir, options.feature, options.config.acceptance.testPath, options.config.project?.language)).map(async (g) => {
98077
- const relativeWorkdir = path19.relative(options.workdir, g.packageDir);
98390
+ const relativeWorkdir = path20.relative(options.workdir, g.packageDir);
98078
98391
  let groupConfig = options.config;
98079
98392
  if (relativeWorkdir && relativeWorkdir !== ".") {
98080
98393
  try {
98081
- groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(path19.join(options.workdir, ".nax", "config.json"), relativeWorkdir);
98394
+ groupConfig = await _runnerCompletionDeps.loadConfigForWorkdir(path20.join(options.workdir, ".nax", "config.json"), relativeWorkdir);
98082
98395
  } catch (error48) {
98083
98396
  logger?.warn("execution", "Falling back to root config for package acceptance settings", {
98084
98397
  packageDir: g.packageDir,
@@ -103325,8 +103638,8 @@ function Text({ color, backgroundColor, dimColor = false, bold = false, italic =
103325
103638
  }
103326
103639
 
103327
103640
  // node_modules/ink/build/components/ErrorOverview.js
103328
- var cleanupPath = (path25) => {
103329
- return path25?.replace(`file://${cwd()}/`, "");
103641
+ var cleanupPath = (path26) => {
103642
+ return path26?.replace(`file://${cwd()}/`, "");
103330
103643
  };
103331
103644
  var stackUtils = new import_stack_utils.default({
103332
103645
  cwd: cwd(),
@@ -106597,8 +106910,14 @@ program2.command("run").description("Run the orchestration loop for a feature").
106597
106910
  }
106598
106911
  const naxDir = findProjectDir(workdir);
106599
106912
  const cliOverrides = {};
106600
- if (options.profile) {
106601
- cliOverrides.profile = options.profile;
106913
+ const profileOverride = naxDir ? await resolveRunProfileOverride({
106914
+ prdPath: join87(naxDir, "features", options.feature, "prd.json"),
106915
+ projectRoot: workdir,
106916
+ cliProfile: options.profile,
106917
+ envProfile: process.env.NAX_PROFILE
106918
+ }) : options.profile;
106919
+ if (profileOverride) {
106920
+ cliOverrides.profile = profileOverride;
106602
106921
  }
106603
106922
  const config2 = await loadConfig(naxDir ?? undefined, cliOverrides);
106604
106923
  if (!naxDir) {
@@ -107032,8 +107351,8 @@ configProfileCmd.command("current").description("Show the currently active profi
107032
107351
  });
107033
107352
  configProfileCmd.command("create <name>").description("Create a new empty profile").option("-d, --dir <path>", "Project directory", process.cwd()).action(async (name, options) => {
107034
107353
  try {
107035
- const path25 = await profileCreateCommand(name, options.dir);
107036
- console.log(`Created profile at: ${path25}`);
107354
+ const path26 = await profileCreateCommand(name, options.dir);
107355
+ console.log(`Created profile at: ${path26}`);
107037
107356
  } catch (err) {
107038
107357
  console.error(source_default.red(`Error: ${err.message}`));
107039
107358
  process.exit(1);