ur-agent 1.65.10 → 1.65.11

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.
package/dist/cli.js CHANGED
@@ -56962,13 +56962,19 @@ function normalizeQuestionOption(value) {
56962
56962
  const option = objectValue(value);
56963
56963
  if (!option)
56964
56964
  return null;
56965
- const label = typeof option.label === "string" && option.label.trim() ? option.label.trim() : typeof option.value === "string" && option.value.trim() ? option.value.trim() : "";
56966
- const description = typeof option.description === "string" && option.description.trim() ? option.description.trim() : label;
56967
- if (!label || !description)
56965
+ if (!sameKeys(option, ["label"], ["description", "preview"]))
56968
56966
  return null;
56967
+ if (typeof option.label !== "string" || !option.label.trim())
56968
+ return null;
56969
+ if (option.description !== undefined && (typeof option.description !== "string" || !option.description.trim())) {
56970
+ return null;
56971
+ }
56972
+ if (option.preview !== undefined && typeof option.preview !== "string") {
56973
+ return null;
56974
+ }
56969
56975
  return {
56970
- label,
56971
- description,
56976
+ label: option.label.trim(),
56977
+ ...typeof option.description === "string" ? { description: option.description.trim() } : {},
56972
56978
  ...typeof option.preview === "string" ? { preview: option.preview } : {}
56973
56979
  };
56974
56980
  }
@@ -56988,10 +56994,14 @@ function normalizeQuestion(value, index2) {
56988
56994
  ]);
56989
56995
  if (!questionText || !Array.isArray(question.options))
56990
56996
  return null;
56991
- const options = question.options.map(normalizeQuestionOption).filter((option) => option !== null);
56992
- if (options.length < 2 || options.length > 4)
56997
+ const normalizedOptions = question.options.map(normalizeQuestionOption);
56998
+ if (!normalizedOptions.every((option) => option !== null)) {
56999
+ return null;
57000
+ }
57001
+ const options = normalizedOptions;
57002
+ if (options.length < 2 || options.length > 8)
56993
57003
  return null;
56994
- const header = typeof question.header === "string" && question.header.trim() ? question.header.trim().slice(0, 12) : headerFromQuestion(questionText, index2);
57004
+ const header = typeof question.header === "string" && question.header.trim() ? question.header.trim() : headerFromQuestion(questionText, index2);
56995
57005
  return {
56996
57006
  question: questionText,
56997
57007
  header,
@@ -57295,135 +57305,7 @@ function synthesizeKimiToolCalls(message) {
57295
57305
  m.content = [...kept, ...synthesized];
57296
57306
  m.stop_reason = "tool_use";
57297
57307
  }
57298
- function clarifyHeader(question) {
57299
- const word = question.replace(/[^A-Za-z0-9]+/g, " ").split(/\s+/).find((part) => part && !CLARIFY_HEADER_STOP_WORDS.has(part.toLowerCase()));
57300
- return (word ?? "Options").slice(0, 12);
57301
- }
57302
- function cleanOption(raw) {
57303
- let opt = raw.trim();
57304
- opt = opt.replace(/^[\s"'`*_\-\u2013\u2014]+/, "").replace(/[\s"'`*_.?!,;:]+$/g, "");
57305
- for (let i2 = 0;i2 < 3; i2++) {
57306
- const before = opt;
57307
- opt = opt.replace(OPTION_LEADIN_RE, "").replace(OPTION_QUESTION_LEADIN_RE, "");
57308
- if (opt === before)
57309
- break;
57310
- }
57311
- opt = opt.replace(OPTION_TRAILING_QUALIFIER_RE, "");
57312
- opt = opt.replace(/\b(?:instead|please|etc\.?)$/i, "");
57313
- return opt.replace(/[\s,;:]+$/g, "").trim();
57314
- }
57315
- function splitEnumeration(s) {
57316
- if (!/\bor\b/i.test(s))
57317
- return null;
57318
- const parts = s.split(/\s*,?\s+or\s+|\s*,\s*/gi).map((p) => p.trim()).filter(Boolean);
57319
- return parts.length >= 2 ? parts : null;
57320
- }
57321
- function extractClarifyOptions(text) {
57322
- const trimmed = text.trim();
57323
- if (!trimmed)
57324
- return [];
57325
- const clauses = trimmed.split(/(?<=[?.!;])\s+/).map((c3) => c3.trim()).filter(Boolean);
57326
- const options = [];
57327
- for (const clause of clauses) {
57328
- const stripped = clause.replace(OPTION_LEADIN_RE, "");
57329
- const candidates = splitEnumeration(stripped) ?? [stripped];
57330
- for (const candidate of candidates) {
57331
- const cleaned = cleanOption(candidate);
57332
- if (!cleaned || cleaned.length > 120)
57333
- continue;
57334
- if (OPTION_CATCHALL_RE.test(cleaned))
57335
- continue;
57336
- options.push(cleaned);
57337
- }
57338
- }
57339
- const seen = new Set;
57340
- const unique = [];
57341
- for (const opt of options) {
57342
- const key = opt.toLowerCase();
57343
- if (seen.has(key))
57344
- continue;
57345
- seen.add(key);
57346
- unique.push(opt);
57347
- if (unique.length === 4)
57348
- break;
57349
- }
57350
- return unique;
57351
- }
57352
- function buildClarifyQuestion(segment) {
57353
- const s = segment.replace(/^\s*(?:\d+[.)]|[-*\u2022])\s+/, "").replace(/\*\*/g, "").trim();
57354
- const qEnd = s.indexOf("?");
57355
- if (qEnd === -1)
57356
- return null;
57357
- const question = s.slice(0, qEnd + 1).trim();
57358
- const remainder = s.slice(qEnd + 1).trim();
57359
- let options = extractClarifyOptions(remainder);
57360
- if (options.length < 2) {
57361
- const inner = question.replace(/\?+$/, "");
57362
- const lastClause = (inner.split(/(?<=[.!;])\s+/).pop() ?? inner).trim();
57363
- if (/\bor\b/i.test(lastClause)) {
57364
- const inline = extractClarifyOptions(lastClause + ".");
57365
- if (inline.length >= 2)
57366
- options = inline;
57367
- }
57368
- }
57369
- if (options.length < 2)
57370
- return null;
57371
- return {
57372
- question,
57373
- header: clarifyHeader(question),
57374
- options: options.map((label) => ({ label, description: label }))
57375
- };
57376
- }
57377
- function parseClarifyingQuestions(text, options = {}) {
57378
- if (!hasTool(options.availableToolNames, "AskUserQuestion"))
57379
- return null;
57380
- const trimmed = text.trim();
57381
- if (!trimmed || trimmed.length > CLARIFY_MAX_LEN)
57382
- return null;
57383
- if (trimmed.includes("```") || trimmed.includes("<|"))
57384
- return null;
57385
- const lines = trimmed.split(`
57386
- `).map((l) => l.trim()).filter(Boolean);
57387
- if (lines.length === 0 || !lines[lines.length - 1].endsWith("?"))
57388
- return null;
57389
- const isListItem = (l) => /^(?:\d+[.)]|[-*\u2022])\s+/.test(l);
57390
- let segments;
57391
- if (lines.some(isListItem)) {
57392
- segments = [];
57393
- for (const line of lines) {
57394
- if (isListItem(line) || segments.length === 0)
57395
- segments.push(line);
57396
- else
57397
- segments[segments.length - 1] += " " + line;
57398
- }
57399
- } else {
57400
- segments = trimmed.split(/\n{2,}/).map((s) => s.replace(/\n/g, " ").trim()).filter((s) => s.includes("?"));
57401
- if (segments.length === 0)
57402
- segments = [trimmed.replace(/\n/g, " ")];
57403
- }
57404
- const questions = [];
57405
- const seenQuestions = new Set;
57406
- for (const segment of segments) {
57407
- if (questions.length === 4)
57408
- break;
57409
- const built = buildClarifyQuestion(segment);
57410
- if (!built)
57411
- continue;
57412
- const key = built.question.toLowerCase();
57413
- if (seenQuestions.has(key))
57414
- continue;
57415
- seenQuestions.add(key);
57416
- questions.push(built);
57417
- }
57418
- if (questions.length === 0)
57419
- return null;
57420
- return {
57421
- id: `clarify_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 8)}`,
57422
- name: "AskUserQuestion",
57423
- input: { questions }
57424
- };
57425
- }
57426
- var SECTION_RE, CALL_RE, STRAY_RE, KimiToolCallParseError, CLARIFY_MAX_LEN = 2000, OPTION_LEADIN_RE, OPTION_QUESTION_LEADIN_RE, OPTION_CATCHALL_RE, OPTION_TRAILING_QUALIFIER_RE, CLARIFY_HEADER_STOP_WORDS;
57308
+ var SECTION_RE, CALL_RE, STRAY_RE, KimiToolCallParseError;
57427
57309
  var init_kimiToolCalls = __esm(() => {
57428
57310
  init_json();
57429
57311
  SECTION_RE = /<\|tool_calls_section_begin\|>([\s\S]*?)<\|tool_calls_section_end\|>/g;
@@ -57436,41 +57318,6 @@ var init_kimiToolCalls = __esm(() => {
57436
57318
  Object.setPrototypeOf(this, new.target.prototype);
57437
57319
  }
57438
57320
  };
57439
- OPTION_LEADIN_RE = /^(?:and\s+)?(?:or|also|just|maybe|perhaps|either|alternatively|optionally|well)\b[\s,:]*/i;
57440
- OPTION_QUESTION_LEADIN_RE = /^(?:(?:do|would|should|could|can|will)\s+(?:you|we|i)\s+(?:want|prefer|like|need|use|go\s+with|have)?|you\s+(?:could|can|might|may)|i\s+(?:could|can|would|might)|we\s+(?:could|can|might)|want|prefer|pick|choose|use|go\s+with|how\s+about|what\s+about)\b[\s,:]*/i;
57441
- OPTION_CATCHALL_RE = /^(?:(?:or\s+)?(?:something|anything|someone)\s+else|other(?:\s+option)?|none(?:\s+of\s+(?:the\s+)?(?:above|these))?|no|nope|not\s+sure|any(?:thing)?|else|you\s+(?:choose|decide|pick)|your\s+(?:call|choice))$/i;
57442
- OPTION_TRAILING_QUALIFIER_RE = /\s+(?:is|are|would\s+be|seems?|sounds?|looks?)\s+(?:the\s+)?(?:simplest|easiest|best|recommended|fastest|cleanest|most\s+\w+)(?:\s+(?:option|choice|approach))?$/i;
57443
- CLARIFY_HEADER_STOP_WORDS = new Set([
57444
- "a",
57445
- "about",
57446
- "also",
57447
- "an",
57448
- "and",
57449
- "are",
57450
- "be",
57451
- "can",
57452
- "could",
57453
- "do",
57454
- "does",
57455
- "for",
57456
- "i",
57457
- "is",
57458
- "or",
57459
- "should",
57460
- "support",
57461
- "that",
57462
- "the",
57463
- "this",
57464
- "to",
57465
- "want",
57466
- "we",
57467
- "what",
57468
- "which",
57469
- "with",
57470
- "without",
57471
- "would",
57472
- "you"
57473
- ]);
57474
57321
  });
57475
57322
 
57476
57323
  // src/services/api/ollama.ts
@@ -58115,11 +57962,6 @@ async function* streamURHQEvents(response, params, controller, requestId, textTo
58115
57962
  if (textToolFallbackAllowed) {
58116
57963
  const kimiParsed = parseKimiToolCalls(text);
58117
57964
  textToolCalls.push(...kimiParsed.toolCalls);
58118
- if (toolCalls.length === 0 && textToolCalls.length === 0) {
58119
- const clarify = parseClarifyingQuestions(text, { availableToolNames });
58120
- if (clarify)
58121
- textToolCalls.push(clarify);
58122
- }
58123
57965
  }
58124
57966
  const normalizedToolUses = normalizeOllamaToolUses(toolCalls, textToolCalls, availableToolNames, "Ollama stream");
58125
57967
  for (const call of normalizedToolUses) {
@@ -58260,9 +58102,6 @@ function ollamaResponseToURHQMessage(response, params, textToolFallbackAllowed)
58260
58102
  }) : { text: rawText, toolCalls: [] };
58261
58103
  const text = parsedText.text;
58262
58104
  const textToolCalls = [...parsedText.toolCalls];
58263
- const clarifyCall = textToolFallbackAllowed && structured.length === 0 && textToolCalls.length === 0 ? parseClarifyingQuestions(text, { availableToolNames }) : null;
58264
- if (clarifyCall)
58265
- textToolCalls.push(clarifyCall);
58266
58105
  const normalizedToolUses = normalizeOllamaToolUses(structured, textToolCalls, availableToolNames, "Ollama response");
58267
58106
  if (thinking) {
58268
58107
  content.push({
@@ -75597,7 +75436,7 @@ var init_auth = __esm(() => {
75597
75436
 
75598
75437
  // src/utils/userAgent.ts
75599
75438
  function getURCodeUserAgent() {
75600
- return `ur/${"1.65.10"}`;
75439
+ return `ur/${"1.65.11"}`;
75601
75440
  }
75602
75441
 
75603
75442
  // src/utils/workloadContext.ts
@@ -75619,7 +75458,7 @@ function getUserAgent() {
75619
75458
  const clientApp = process.env.UR_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}` : "";
75620
75459
  const workload = getWorkload();
75621
75460
  const workloadSuffix = workload ? `, workload/${workload}` : "";
75622
- return `ur-cli/${"1.65.10"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
75461
+ return `ur-cli/${"1.65.11"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
75623
75462
  }
75624
75463
  function getMCPUserAgent() {
75625
75464
  const parts = [];
@@ -75633,7 +75472,7 @@ function getMCPUserAgent() {
75633
75472
  parts.push(`client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}`);
75634
75473
  }
75635
75474
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
75636
- return `ur/${"1.65.10"}${suffix}`;
75475
+ return `ur/${"1.65.11"}${suffix}`;
75637
75476
  }
75638
75477
  function getWebFetchUserAgent() {
75639
75478
  return `UR-User (${getURCodeUserAgent()})`;
@@ -75771,7 +75610,7 @@ var init_user = __esm(() => {
75771
75610
  deviceId,
75772
75611
  sessionId: getSessionId(),
75773
75612
  email: getEmail(),
75774
- appVersion: "1.65.10",
75613
+ appVersion: "1.65.11",
75775
75614
  platform: getHostPlatformForAnalytics(),
75776
75615
  organizationUuid,
75777
75616
  accountUuid,
@@ -83971,7 +83810,7 @@ var init_metadata = __esm(() => {
83971
83810
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
83972
83811
  WHITESPACE_REGEX = /\s+/;
83973
83812
  getVersionBase = memoize_default(() => {
83974
- const match = "1.65.10".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
83813
+ const match = "1.65.11".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
83975
83814
  return match ? match[0] : undefined;
83976
83815
  });
83977
83816
  buildEnvContext = memoize_default(async () => {
@@ -84011,7 +83850,7 @@ var init_metadata = __esm(() => {
84011
83850
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
84012
83851
  isURCodeAction: isEnvTruthy(process.env.UR_CODE_ACTION),
84013
83852
  isURAiAuth: isURAISubscriber(),
84014
- version: "1.65.10",
83853
+ version: "1.65.11",
84015
83854
  versionBase: getVersionBase(),
84016
83855
  buildTime: "",
84017
83856
  deploymentEnvironment: env2.detectDeploymentEnvironment(),
@@ -84681,7 +84520,7 @@ function initialize1PEventLogging() {
84681
84520
  const platform2 = getPlatform();
84682
84521
  const attributes = {
84683
84522
  [import_semantic_conventions4.ATTR_SERVICE_NAME]: "ur",
84684
- [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.65.10"
84523
+ [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.65.11"
84685
84524
  };
84686
84525
  if (platform2 === "wsl") {
84687
84526
  const wslVersion = getWslVersion();
@@ -84709,7 +84548,7 @@ function initialize1PEventLogging() {
84709
84548
  })
84710
84549
  ]
84711
84550
  });
84712
- firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.65.10");
84551
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.65.11");
84713
84552
  }
84714
84553
  async function reinitialize1PEventLoggingIfConfigChanged() {
84715
84554
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -94597,7 +94436,7 @@ function formatAgentTrendReport(report = buildAgentTrendReport()) {
94597
94436
  function formatA2AAgentCard(options = {}, pretty = true) {
94598
94437
  return JSON.stringify(buildA2AAgentCard(options), null, pretty ? 2 : 0);
94599
94438
  }
94600
- var urVersion = "1.65.10", researchSnapshotDate = "2026-07-15", coverage, priorityRoadmap;
94439
+ var urVersion = "1.65.11", researchSnapshotDate = "2026-07-15", coverage, priorityRoadmap;
94601
94440
  var init_trends = __esm(() => {
94602
94441
  init_a2aCardSignature();
94603
94442
  coverage = [
@@ -97400,7 +97239,7 @@ function getAttributionHeader(fingerprint) {
97400
97239
  if (!isAttributionHeaderEnabled()) {
97401
97240
  return "";
97402
97241
  }
97403
- const version2 = `${"1.65.10"}.${fingerprint}`;
97242
+ const version2 = `${"1.65.11"}.${fingerprint}`;
97404
97243
  const entrypoint = process.env.UR_CODE_ENTRYPOINT ?? "unknown";
97405
97244
  const cch = "";
97406
97245
  const workload = getWorkload();
@@ -97921,6 +97760,10 @@ function getWriteToolDescription() {
97921
97760
 
97922
97761
  Usage:
97923
97762
  - This tool will overwrite the existing file if there is one at the provided path.${getPreReadInstruction()}
97763
+ - Every call must include both required fields in the same structured invocation: \`file_path\` and the complete literal file text in \`content\`.
97764
+ - Put the actual file text inside \`content\`; surrounding assistant prose is never copied into the file. Never call Write with only a path, and never invent or recover missing content from prose.
97765
+ - An empty \`content\` string creates an empty file. Use it only when an empty file is genuinely intended.
97766
+ - A file is not created or updated until this tool returns a success result. If validation fails, correct the arguments and retry; do not claim the write succeeded.
97924
97767
  - Prefer the Edit tool for modifying existing files \u2014 it only sends the diff. Only use this tool to create new files or for complete rewrites.
97925
97768
  - NEVER create documentation files (*.md) or README files unless explicitly requested by the User.
97926
97769
  - Only use emojis if the user explicitly requests it. Avoid writing emojis to files unless asked.`;
@@ -155269,7 +155112,7 @@ var init_projectSafety = __esm(() => {
155269
155112
  function getInstruments() {
155270
155113
  if (instruments)
155271
155114
  return instruments;
155272
- const meter = import_api10.metrics.getMeter("ur-agent.gen_ai", "1.65.10");
155115
+ const meter = import_api10.metrics.getMeter("ur-agent.gen_ai", "1.65.11");
155273
155116
  instruments = {
155274
155117
  operationDuration: meter.createHistogram("gen_ai.client.operation.duration", {
155275
155118
  description: "GenAI operation duration.",
@@ -155367,7 +155210,7 @@ function genAiAgentAttributes() {
155367
155210
  "gen_ai.operation.name": GEN_AI_OPERATION_INVOKE_AGENT,
155368
155211
  "gen_ai.provider.name": "ur",
155369
155212
  "gen_ai.agent.name": "UR-Nexus",
155370
- "gen_ai.agent.version": "1.65.10"
155213
+ "gen_ai.agent.version": "1.65.11"
155371
155214
  };
155372
155215
  }
155373
155216
  function genAiWorkflowAttributes(workflowName) {
@@ -155383,7 +155226,7 @@ function genAiWorkflowAttributes(workflowName) {
155383
155226
  function startGenAiWorkflowSpan(workflowName) {
155384
155227
  const attributes = genAiWorkflowAttributes(workflowName);
155385
155228
  const name = typeof attributes["gen_ai.workflow.name"] === "string" ? `invoke_workflow ${attributes["gen_ai.workflow.name"]}` : GEN_AI_OPERATION_INVOKE_WORKFLOW;
155386
- return import_api10.trace.getTracer("ur-agent.gen_ai", "1.65.10").startSpan(name, { kind: import_api10.SpanKind.INTERNAL, attributes });
155229
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.65.11").startSpan(name, { kind: import_api10.SpanKind.INTERNAL, attributes });
155387
155230
  }
155388
155231
  function endGenAiWorkflowSpan(span, options2 = {}) {
155389
155232
  try {
@@ -155421,7 +155264,7 @@ function startGenAiMemorySpan(operation, options2 = {}) {
155421
155264
  if (options2.recordCount !== undefined && Number.isInteger(options2.recordCount) && options2.recordCount >= 0) {
155422
155265
  attributes["gen_ai.memory.record.count"] = options2.recordCount;
155423
155266
  }
155424
- return import_api10.trace.getTracer("ur-agent.gen_ai", "1.65.10").startSpan(operation, { kind: import_api10.SpanKind.INTERNAL, attributes });
155267
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.65.11").startSpan(operation, { kind: import_api10.SpanKind.INTERNAL, attributes });
155425
155268
  }
155426
155269
  function endGenAiMemorySpan(span, options2 = {}) {
155427
155270
  try {
@@ -248904,7 +248747,7 @@ function getTelemetryAttributes() {
248904
248747
  attributes["session.id"] = sessionId;
248905
248748
  }
248906
248749
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
248907
- attributes["app.version"] = "1.65.10";
248750
+ attributes["app.version"] = "1.65.11";
248908
248751
  }
248909
248752
  const oauthAccount = getOauthAccountInfo();
248910
248753
  if (oauthAccount) {
@@ -265115,11 +264958,11 @@ Preview content is rendered as markdown in a monospace box. Multi-line text with
265115
264958
  html: `
265116
264959
  Preview feature:
265117
264960
  Use the optional \`preview\` field on options when presenting concrete artifacts that users need to visually compare:
265118
- - HTML mockups of UI layouts or components
265119
- - Formatted code snippets showing different implementations
265120
- - Visual comparisons or diagrams
264961
+ - Plain-text or ASCII mockups of UI layouts or components
264962
+ - Inert code snippets showing different implementations
264963
+ - Textual visual comparisons or diagrams
265121
264964
 
265122
- Preview content must be a self-contained HTML fragment (no <html>/<body> wrapper, no <script> or <style> tags \u2014 use inline style attributes instead). Do not use previews for simple preference questions where labels and descriptions suffice. Note: previews are only supported for single-select questions (not multiSelect).
264965
+ Preview content is untrusted text: raw HTML is not accepted or executed. It is escaped and rendered as inert preformatted text. Do not include HTML tags, attributes, URLs, scripts, styles, event handlers, or other executable markup. Do not use previews for simple preference questions where labels and descriptions suffice. Note: previews are only supported for single-select questions (not multiSelect).
265123
264966
  `
265124
264967
  };
265125
264968
  ASK_USER_QUESTION_TOOL_PROMPT = `Use this tool when you need to ask the user questions during execution. This allows you to:
@@ -265130,10 +264973,20 @@ Preview content must be a self-contained HTML fragment (no <html>/<body> wrapper
265130
264973
 
265131
264974
  Strongly prefer this tool over asking a question in plain assistant text. Any time your reply would end with a question that offers the user options or asks them to choose a direction (e.g. "Would you like A or B?", "Which approach should I take?", "Want me to do X or Y?"), call this tool with those options instead so the user gets a selectable arrow-key menu. Only ask in plain text when the answer is genuinely open-ended and cannot be expressed as a small set of choices.
265132
264975
 
264976
+ Strict input hierarchy:
264977
+ - Invoke the tool with exactly one top-level \`questions\` array containing 1-4 complete question objects.
264978
+ - Every question object contains \`question\`, a concise \`header\` (maximum 12 characters), and an \`options\` array with 2-8 option objects. Use \`multiSelect: true\` only when more than one choice may apply.
264979
+ - Every option object contains a \`label\`. Add \`description\` only when it contributes a real consequence, trade-off, or limitation; \`preview\` is optional.
264980
+ - Keep each question and its own options nested together. Never put option rows directly in the top-level \`questions\` array, and never send incomplete header/prompt-only entries.
264981
+
264982
+ Canonical valid tool arguments (invoke the structured tool; do not print this object as prose):
264983
+ {"questions":[{"question":"Which database should we use?","header":"Database","options":[{"label":"PostgreSQL (Recommended)","description":"Strong consistency and concurrency; requires a running server and migrations."},{"label":"SQLite","description":"Zero setup and a single file; unsuitable for multiple concurrent writers."}],"multiSelect":false}]}
264984
+
265133
264985
  Usage notes:
265134
264986
  - Users will always be able to select "Other" to provide custom text input, so it is safe to offer choices even when you are unsure you have listed every option
265135
264987
  - Use multiSelect: true to allow multiple answers to be selected for a question
265136
264988
  - If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
264989
+ - Do not over-question. Ask only decisions that materially affect the result and cannot be inferred safely. If more than four decisions are truly needed, ask the most blocking 1-4 first and ask the remainder in a later round.
265137
264990
 
265138
264991
  Writing the three fields \u2014 they must each carry DIFFERENT information:
265139
264992
  - \`header\` names the dimension being decided ("Database", "Auth method"). It is not a shortened copy of the question.
@@ -295438,7 +295291,7 @@ function getInstallationEnv() {
295438
295291
  return;
295439
295292
  }
295440
295293
  function getURCodeVersion() {
295441
- return "1.65.10";
295294
+ return "1.65.11";
295442
295295
  }
295443
295296
  async function getInstalledVSCodeExtensionVersion(command) {
295444
295297
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -302769,7 +302622,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
302769
302622
  const client2 = new Client({
302770
302623
  name: "ur",
302771
302624
  title: "UR",
302772
- version: "1.65.10",
302625
+ version: "1.65.11",
302773
302626
  description: "UR-Nexus autonomous engineering workflow engine",
302774
302627
  websiteUrl: PRODUCT_URL
302775
302628
  }, {
@@ -303129,7 +302982,7 @@ var init_client5 = __esm(() => {
303129
302982
  const client2 = new Client({
303130
302983
  name: "ur",
303131
302984
  title: "UR",
303132
- version: "1.65.10",
302985
+ version: "1.65.11",
303133
302986
  description: "UR-Nexus autonomous engineering workflow engine",
303134
302987
  websiteUrl: PRODUCT_URL
303135
302988
  }, {
@@ -315668,7 +315521,7 @@ async function createRuntime() {
315668
315521
  bootstrapTelemetry();
315669
315522
  const resource = defaultResource().merge(detectResources({ detectors: [envDetector] })).merge(resourceFromAttributes({
315670
315523
  [import_semantic_conventions7.ATTR_SERVICE_NAME]: "ur-agent",
315671
- [import_semantic_conventions7.ATTR_SERVICE_VERSION]: "1.65.10"
315524
+ [import_semantic_conventions7.ATTR_SERVICE_VERSION]: "1.65.11"
315672
315525
  }));
315673
315526
  const tracerProvider = exporters.traces.length > 0 ? new BasicTracerProvider({
315674
315527
  resource,
@@ -315701,11 +315554,11 @@ async function createRuntime() {
315701
315554
  setMeterProvider(meterProvider);
315702
315555
  setLoggerProvider(loggerProvider);
315703
315556
  if (meterProvider) {
315704
- const meter = meterProvider.getMeter("ur-agent", "1.65.10");
315557
+ const meter = meterProvider.getMeter("ur-agent", "1.65.11");
315705
315558
  setMeter(meter, (name, options2) => meter.createCounter(name, options2));
315706
315559
  }
315707
315560
  if (loggerProvider) {
315708
- setEventLogger(loggerProvider.getLogger("ur-agent.events", "1.65.10"));
315561
+ setEventLogger(loggerProvider.getLogger("ur-agent.events", "1.65.11"));
315709
315562
  }
315710
315563
  if (!cleanupRegistered2) {
315711
315564
  cleanupRegistered2 = true;
@@ -316367,9 +316220,9 @@ async function assertMinVersion() {
316367
316220
  if (false) {}
316368
316221
  try {
316369
316222
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
316370
- if (versionConfig.minVersion && lt("1.65.10", versionConfig.minVersion)) {
316223
+ if (versionConfig.minVersion && lt("1.65.11", versionConfig.minVersion)) {
316371
316224
  console.error(`
316372
- It looks like your version of UR (${"1.65.10"}) needs an update.
316225
+ It looks like your version of UR (${"1.65.11"}) needs an update.
316373
316226
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
316374
316227
 
316375
316228
  To update, please run:
@@ -316585,7 +316438,7 @@ async function installGlobalPackage(specificVersion) {
316585
316438
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
316586
316439
  logEvent("tengu_auto_updater_lock_contention", {
316587
316440
  pid: process.pid,
316588
- currentVersion: "1.65.10"
316441
+ currentVersion: "1.65.11"
316589
316442
  });
316590
316443
  return "in_progress";
316591
316444
  }
@@ -316594,7 +316447,7 @@ async function installGlobalPackage(specificVersion) {
316594
316447
  if (!env2.isRunningWithBun() && env2.isNpmFromWindowsPath()) {
316595
316448
  logError2(new Error("Windows NPM detected in WSL environment"));
316596
316449
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
316597
- currentVersion: "1.65.10"
316450
+ currentVersion: "1.65.11"
316598
316451
  });
316599
316452
  console.error(`
316600
316453
  Error: Windows NPM detected in WSL
@@ -317129,7 +316982,7 @@ function detectLinuxGlobPatternWarnings() {
317129
316982
  }
317130
316983
  async function getDoctorDiagnostic() {
317131
316984
  const installationType = await getCurrentInstallationType();
317132
- const version2 = typeof MACRO !== "undefined" ? "1.65.10" : "unknown";
316985
+ const version2 = typeof MACRO !== "undefined" ? "1.65.11" : "unknown";
317133
316986
  const installationPath = await getInstallationPath();
317134
316987
  const invokedBinary = getInvokedBinary();
317135
316988
  const multipleInstallations = await detectMultipleInstallations();
@@ -318064,8 +317917,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
318064
317917
  const maxVersion = await getMaxVersion();
318065
317918
  if (maxVersion && gt(version2, maxVersion)) {
318066
317919
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
318067
- if (gte("1.65.10", maxVersion)) {
318068
- logForDebugging(`Native installer: current version ${"1.65.10"} is already at or above maxVersion ${maxVersion}, skipping update`);
317920
+ if (gte("1.65.11", maxVersion)) {
317921
+ logForDebugging(`Native installer: current version ${"1.65.11"} is already at or above maxVersion ${maxVersion}, skipping update`);
318069
317922
  logEvent("tengu_native_update_skipped_max_version", {
318070
317923
  latency_ms: Date.now() - startTime,
318071
317924
  max_version: maxVersion,
@@ -318076,7 +317929,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
318076
317929
  version2 = maxVersion;
318077
317930
  }
318078
317931
  }
318079
- if (!forceReinstall && version2 === "1.65.10" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
317932
+ if (!forceReinstall && version2 === "1.65.11" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
318080
317933
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
318081
317934
  logEvent("tengu_native_update_complete", {
318082
317935
  latency_ms: Date.now() - startTime,
@@ -361148,7 +361001,7 @@ Usage:${getPreReadInstruction2()}
361148
361001
  - When editing text from Read tool output, ensure you preserve the exact indentation (tabs/spaces) as it appears AFTER the line number prefix. The line number prefix format is: ${prefixFormat}. Everything after that is the actual file content to match. Never include any part of the line number prefix in the old_string or new_string.
361149
361002
  - ALWAYS prefer editing existing files in the codebase. NEVER write new files unless explicitly required.
361150
361003
  - Only use emojis if the user explicitly requests it. Avoid adding emojis to files unless asked.
361151
- - \`old_string\` must be copied from the current file as one exact, contiguous block. If it is not found, re-read the target region and retry with a corrected smaller block; never retry the unchanged call.
361004
+ - \`old_string\` must be copied from a recent Read of the target file as one exact, contiguous block. Never reconstruct it from memory, from an earlier full-file Write, or from what you expected the file to contain. If it is not found, re-read the target region and retry with a corrected smaller block; never retry the unchanged call.
361152
361005
  - The edit will FAIL if \`old_string\` is not unique in the file. Either provide a larger string with more surrounding context to make it unique or use \`replace_all\` to change every instance of \`old_string\`.${minimalUniquenessHint}
361153
361006
  - Use \`replace_all\` for replacing and renaming strings across the file. This parameter is useful if you want to rename a variable for instance.`;
361154
361007
  }
@@ -361192,6 +361045,7 @@ var init_types11 = __esm(() => {
361192
361045
  structuredPatch: exports_external.array(hunkSchema()).describe("Diff patch showing the changes"),
361193
361046
  userModified: exports_external.boolean().describe("Whether the user modified the proposed changes"),
361194
361047
  replaceAll: exports_external.boolean().describe("Whether all occurrences were replaced"),
361048
+ alreadyApplied: exports_external.boolean().optional().describe("Whether the requested deletion-only replacement was already present and no write was needed"),
361195
361049
  gitDiff: gitDiffSchema().optional()
361196
361050
  }));
361197
361051
  });
@@ -363592,6 +363446,15 @@ function findActualString(fileContent, searchString) {
363592
363446
  }
363593
363447
  return findActualStringWhitespaceTolerant(fileContent, searchString);
363594
363448
  }
363449
+ function isDeletionOnlyEditAlreadyApplied(fileContent, oldString, newString, replaceAll) {
363450
+ if (replaceAll || oldString.length === 0 || newString.length === 0 || oldString === newString || !oldString.includes(newString) || findActualString(fileContent, oldString) !== null) {
363451
+ return false;
363452
+ }
363453
+ const actualNewString = findActualString(fileContent, newString);
363454
+ if (actualNewString === null)
363455
+ return false;
363456
+ return fileContent.split(actualNewString).length - 1 === 1;
363457
+ }
363595
363458
  function preserveQuoteStyle(oldString, actualOldString, newString) {
363596
363459
  if (oldString === actualOldString) {
363597
363460
  return newString;
@@ -363967,11 +363830,20 @@ function renderToolUseMessage9({
363967
363830
  function renderToolResultMessage8({
363968
363831
  filePath,
363969
363832
  structuredPatch: structuredPatch2,
363970
- originalFile
363833
+ originalFile,
363834
+ alreadyApplied
363971
363835
  }, _progressMessagesForMessage, {
363972
363836
  style,
363973
363837
  verbose
363974
363838
  }) {
363839
+ if (alreadyApplied) {
363840
+ return /* @__PURE__ */ jsx_dev_runtime132.jsxDEV(MessageResponse, {
363841
+ children: /* @__PURE__ */ jsx_dev_runtime132.jsxDEV(ThemedText, {
363842
+ dimColor: true,
363843
+ children: "Already up to date"
363844
+ }, undefined, false, undefined, this)
363845
+ }, undefined, false, undefined, this);
363846
+ }
363975
363847
  const isPlanFile = filePath.startsWith(getPlansDirectory());
363976
363848
  return /* @__PURE__ */ jsx_dev_runtime132.jsxDEV(FileEditToolUpdatedMessage, {
363977
363849
  filePath,
@@ -364447,6 +364319,9 @@ var init_FileEditTool = __esm(() => {
364447
364319
  const file2 = fileContent;
364448
364320
  const actualOldString = findActualString(file2, old_string);
364449
364321
  if (!actualOldString) {
364322
+ if (isDeletionOnlyEditAlreadyApplied(file2, old_string, new_string, replace_all)) {
364323
+ return { result: true };
364324
+ }
364450
364325
  return {
364451
364326
  result: false,
364452
364327
  behavior: "ask",
@@ -364510,6 +364385,27 @@ String: ${old_string}`,
364510
364385
  const { file_path, old_string, new_string, replace_all = false } = input;
364511
364386
  const fs4 = getFsImplementation();
364512
364387
  const absoluteFilePath = expandPath(file_path);
364388
+ const initialState = readFileForEdit(absoluteFilePath);
364389
+ if (initialState.fileExists) {
364390
+ const lastRead = readFileState.get(absoluteFilePath);
364391
+ if (!lastRead || getFileModificationTime(absoluteFilePath) > lastRead.timestamp || !fileStateMatchesContent(initialState.content, lastRead)) {
364392
+ throw new Error(FILE_UNEXPECTEDLY_MODIFIED_ERROR);
364393
+ }
364394
+ if (isDeletionOnlyEditAlreadyApplied(initialState.content, old_string, new_string, replace_all)) {
364395
+ return {
364396
+ data: {
364397
+ filePath: file_path,
364398
+ oldString: old_string,
364399
+ newString: new_string,
364400
+ originalFile: initialState.content,
364401
+ structuredPatch: [],
364402
+ userModified: userModified ?? false,
364403
+ replaceAll: replace_all,
364404
+ alreadyApplied: true
364405
+ }
364406
+ };
364407
+ }
364408
+ }
364513
364409
  const cwd2 = getCwd();
364514
364410
  if (!isEnvTruthy(process.env.UR_CODE_SIMPLE)) {
364515
364411
  const newSkillDirs = await discoverSkillDirsForPaths([absoluteFilePath], cwd2);
@@ -364627,7 +364523,14 @@ String: ${old_string}`,
364627
364523
  };
364628
364524
  },
364629
364525
  mapToolResultToToolResultBlockParam(data, toolUseID) {
364630
- const { filePath, userModified, replaceAll } = data;
364526
+ const { filePath, userModified, replaceAll, alreadyApplied } = data;
364527
+ if (alreadyApplied) {
364528
+ return {
364529
+ tool_use_id: toolUseID,
364530
+ type: "tool_result",
364531
+ content: `The file ${filePath} already contains the requested replacement. No change was needed.`
364532
+ };
364533
+ }
364631
364534
  const modifiedNote = userModified ? ". The user modified your proposed changes before accepting them. " : "";
364632
364535
  if (replaceAll) {
364633
364536
  return {
@@ -373287,6 +373190,21 @@ function TungstenLiveMonitor() {
373287
373190
  }
373288
373191
  var TungstenTool = null;
373289
373192
 
373193
+ // src/utils/zodToJsonSchema.ts
373194
+ function zodToJsonSchema3(schema) {
373195
+ const hit = cache3.get(schema);
373196
+ if (hit)
373197
+ return hit;
373198
+ const result = toJSONSchema(schema);
373199
+ cache3.set(schema, result);
373200
+ return result;
373201
+ }
373202
+ var cache3;
373203
+ var init_zodToJsonSchema2 = __esm(() => {
373204
+ init_v4();
373205
+ cache3 = new WeakMap;
373206
+ });
373207
+
373290
373208
  // src/tools/AskUserQuestionTool/AskUserQuestionTool.tsx
373291
373209
  function objectValue3(value) {
373292
373210
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -373306,81 +373224,108 @@ function stringField2(input, names) {
373306
373224
  }
373307
373225
  function normalizeQuestionOptionInput(value) {
373308
373226
  if (typeof value === "string") {
373309
- const label2 = value.trim();
373310
- return label2 ? {
373311
- label: label2,
373312
- description: label2
373227
+ const label = value.trim();
373228
+ return label ? {
373229
+ label
373313
373230
  } : value;
373314
373231
  }
373315
373232
  const option = objectValue3(value);
373316
373233
  if (!option)
373317
373234
  return value;
373318
- const label = typeof option.label === "string" && option.label.trim() ? option.label.trim() : typeof option.value === "string" && option.value.trim() ? option.value.trim() : typeof option.description === "string" && option.description.trim() ? option.description.trim() : "";
373319
- const description = typeof option.description === "string" && option.description.trim() ? option.description.trim() : label;
373320
- if (!label || !description)
373321
- return value;
373322
- return {
373323
- label,
373324
- description,
373325
- ...typeof option.preview === "string" ? {
373326
- preview: option.preview
373327
- } : {}
373328
- };
373235
+ const normalized = { ...option };
373236
+ if (typeof option.label === "string")
373237
+ normalized.label = option.label.trim();
373238
+ if (typeof option.description === "string")
373239
+ normalized.description = option.description.trim();
373240
+ if (typeof option.preview === "string")
373241
+ normalized.preview = normalizePreviewInput(option.preview);
373242
+ return normalized;
373243
+ }
373244
+ function normalizePreviewInput(preview) {
373245
+ if (getQuestionPreviewFormat() !== "html")
373246
+ return preview;
373247
+ const alreadySafe = preview.match(/^<pre data-ur-preview="text">([\s\S]*)<\/pre>$/);
373248
+ if (alreadySafe && !alreadySafe[1]?.includes("<"))
373249
+ return preview;
373250
+ const escaped = preview.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
373251
+ return `<pre data-ur-preview="text">${escaped}</pre>`;
373329
373252
  }
373330
373253
  function normalizeQuestionInput(value, index2) {
373331
373254
  const question = objectValue3(value);
373332
- if (!question || !Array.isArray(question.options))
373333
- return value;
373334
- const questionText = stringField2(question, ["question", "questionText", "question_text", "prompt", "text", "title", "message", "body"]);
373335
- if (!questionText)
373255
+ if (!question)
373336
373256
  return value;
373337
- return {
373338
- question: questionText,
373339
- header: typeof question.header === "string" && question.header.trim() ? question.header.trim().slice(0, ASK_USER_QUESTION_TOOL_CHIP_WIDTH) : headerFromQuestion2(questionText, index2),
373340
- options: question.options.map(normalizeQuestionOptionInput),
373341
- ...typeof question.multiSelect === "boolean" ? {
373342
- multiSelect: question.multiSelect
373343
- } : {}
373344
- };
373257
+ const normalized = { ...question };
373258
+ const questionText = stringField2(question, [...QUESTION_TEXT_ALIASES]);
373259
+ if (questionText)
373260
+ normalized.question = questionText;
373261
+ for (const alias of QUESTION_TEXT_ALIASES) {
373262
+ if (alias !== "question")
373263
+ delete normalized[alias];
373264
+ }
373265
+ let options2 = question.options;
373266
+ if (options2 === undefined && question.choices !== undefined) {
373267
+ options2 = question.choices;
373268
+ delete normalized.choices;
373269
+ }
373270
+ if (typeof options2 === "string") {
373271
+ const parsed = parseToolInputJsonLenient(options2);
373272
+ if (Array.isArray(parsed))
373273
+ options2 = parsed;
373274
+ }
373275
+ if (Array.isArray(options2)) {
373276
+ normalized.options = options2.map(normalizeQuestionOptionInput);
373277
+ }
373278
+ if (typeof question.header === "string" && question.header.trim()) {
373279
+ normalized.header = question.header.trim();
373280
+ } else if (questionText) {
373281
+ normalized.header = headerFromQuestion2(questionText, index2);
373282
+ }
373283
+ return normalized;
373345
373284
  }
373346
373285
  function normalizeAskUserQuestionInput2(value) {
373347
373286
  const input = objectValue3(value);
373348
373287
  if (!input)
373349
373288
  return value;
373350
- const commonFields = {
373351
- ...objectValue3(input.answers) ? {
373352
- answers: input.answers
373353
- } : {},
373354
- ...objectValue3(input.annotations) ? {
373355
- annotations: input.annotations
373356
- } : {},
373357
- ...objectValue3(input.metadata) ? {
373358
- metadata: input.metadata
373359
- } : {}
373360
- };
373361
- if (typeof input.questions === "string") {
373362
- const parsed = parseToolInputJsonLenient(input.questions);
373289
+ const normalized = { ...input };
373290
+ let questions = input.questions;
373291
+ if (typeof questions === "string") {
373292
+ const parsed = parseToolInputJsonLenient(questions);
373363
373293
  if (Array.isArray(parsed))
373364
- input.questions = parsed;
373294
+ questions = parsed;
373365
373295
  }
373366
- if (typeof input.options === "string") {
373367
- const parsed = parseToolInputJsonLenient(input.options);
373368
- if (Array.isArray(parsed))
373369
- input.options = parsed;
373296
+ if (Array.isArray(questions)) {
373297
+ normalized.questions = questions.map(normalizeQuestionInput);
373298
+ return normalized;
373370
373299
  }
373371
- if (Array.isArray(input.questions)) {
373372
- return {
373373
- questions: input.questions.map(normalizeQuestionInput),
373374
- ...commonFields
373375
- };
373300
+ let options2 = input.options;
373301
+ if (typeof options2 === "string") {
373302
+ const parsed = parseToolInputJsonLenient(options2);
373303
+ if (Array.isArray(parsed))
373304
+ options2 = parsed;
373376
373305
  }
373377
- if (typeof input.question === "string" && Array.isArray(input.options)) {
373306
+ if (stringField2(input, [...QUESTION_TEXT_ALIASES]) && Array.isArray(options2)) {
373307
+ const singleQuestion = normalizeQuestionInput({
373308
+ question: stringField2(input, [...QUESTION_TEXT_ALIASES]),
373309
+ ...input.header !== undefined ? {
373310
+ header: input.header
373311
+ } : {},
373312
+ options: options2,
373313
+ ...input.multiSelect !== undefined ? {
373314
+ multiSelect: input.multiSelect
373315
+ } : {}
373316
+ }, 0);
373317
+ for (const key of [...QUESTION_TEXT_ALIASES, "header", "options", "choices", "multiSelect"]) {
373318
+ delete normalized[key];
373319
+ }
373378
373320
  return {
373379
- questions: [normalizeQuestionInput(input, 0)],
373380
- ...commonFields
373321
+ ...normalized,
373322
+ questions: [singleQuestion]
373381
373323
  };
373382
373324
  }
373383
- return value;
373325
+ return normalized;
373326
+ }
373327
+ function boundedText(max2, field) {
373328
+ return exports_external.string().trim().min(1, `${field} cannot be empty`).max(max2, `${field} must be at most ${max2} characters`).refine((value) => !CONTROL_OR_ANSI_RE.test(value), `${field} must not contain control or ANSI escape characters`);
373384
373329
  }
373385
373330
  function AskUserQuestionResultMessage(t0) {
373386
373331
  const $2 = import_compiler_runtime114.c(3);
@@ -373445,18 +373390,15 @@ function _temp51(t0) {
373445
373390
  function validateHtmlPreview(preview) {
373446
373391
  if (preview === undefined)
373447
373392
  return null;
373448
- if (/<\s*(html|body|!doctype)\b/i.test(preview)) {
373449
- return "preview must be an HTML fragment, not a full document (no <html>, <body>, or <!DOCTYPE>)";
373450
- }
373451
- if (/<\s*(script|style)\b/i.test(preview)) {
373452
- return "preview must not contain <script> or <style> tags. Use inline styles via the style attribute if needed.";
373453
- }
373454
- if (!/<[a-z][^>]*>/i.test(preview)) {
373455
- return 'preview must contain HTML (previewFormat is set to "html"). Wrap content in a tag like <div> or <pre>.';
373393
+ if (getQuestionPreviewFormat() !== "html")
373394
+ return null;
373395
+ const safeTextWrapper = preview.match(/^<pre data-ur-preview="text">([\s\S]*)<\/pre>$/);
373396
+ if (!safeTextWrapper || safeTextWrapper[1]?.includes("<")) {
373397
+ return "HTML previews must use UR\u2019s escaped text wrapper; raw model-provided HTML is not rendered";
373456
373398
  }
373457
373399
  return null;
373458
373400
  }
373459
- var import_compiler_runtime114, jsx_dev_runtime145, questionOptionSchema, questionSchema, annotationsSchema, UNIQUENESS_REFINE, commonFields, inputSchema32, outputSchema27, AskUserQuestionTool;
373401
+ var import_compiler_runtime114, jsx_dev_runtime145, MAX_QUESTIONS = 4, MAX_OPTIONS = 8, MAX_QUESTION_CHARS = 500, MAX_LABEL_CHARS = 80, MAX_DESCRIPTION_CHARS = 500, MAX_PREVIEW_CHARS, MAX_PREVIEW_LINES = 200, MAX_ANSWER_CHARS = 2000, MAX_TOTAL_INPUT_CHARS, RESERVED_RECORD_KEYS, QUESTION_TEXT_ALIASES, CONTROL_OR_ANSI_RE, UNIQUENESS_REFINE, questionOptionSchema, questionSchema, annotationsSchema, responseFields, metadataSchema, requestObjectSchema, inputSchema32, modelInputJSONSchema, outputSchema27, AskUserQuestionTool;
373460
373402
  var init_AskUserQuestionTool = __esm(() => {
373461
373403
  init_state();
373462
373404
  init_MessageResponse();
@@ -373466,59 +373408,82 @@ var init_AskUserQuestionTool = __esm(() => {
373466
373408
  init_v4();
373467
373409
  init_ink2();
373468
373410
  init_Tool();
373411
+ init_zodToJsonSchema2();
373469
373412
  init_prompt9();
373470
373413
  import_compiler_runtime114 = __toESM(require_compiler_runtime(), 1);
373471
373414
  jsx_dev_runtime145 = __toESM(require_jsx_dev_runtime(), 1);
373472
- questionOptionSchema = lazySchema(() => exports_external.object({
373473
- label: exports_external.string().describe('The choice itself, 1-5 words. Name the option, do not restate the question: for "Which database?" use "PostgreSQL", not "Use PostgreSQL for the database".'),
373474
- description: exports_external.string().describe('What actually happens if this is chosen, and the cost of choosing it \u2014 the information the user needs that the label does not already give them. Must NOT restate the label in a full sentence. Bad: label "PostgreSQL" / description "Use PostgreSQL." Good: label "PostgreSQL" / description "Relational, strong consistency; needs a running server and a migration step." Include the trade-off, limitation, or consequence that makes this choice different from the others.'),
373475
- preview: exports_external.string().optional().describe("Optional preview content rendered when this option is focused. Use for mockups, code snippets, or visual comparisons that help users compare options. See the tool description for the expected content format.")
373476
- }));
373477
- questionSchema = lazySchema(() => exports_external.object({
373478
- question: exports_external.string().describe('The complete question to ask the user. Should be clear, specific, and end with a question mark. Example: "Which library should we use for date formatting?" If multiSelect is true, phrase it accordingly, e.g. "Which features do you want to enable?"'),
373479
- header: exports_external.string().describe(`The category being decided, as a chip/tag (max ${ASK_USER_QUESTION_TOOL_CHIP_WIDTH} chars). Name the dimension, not the question: for "Which database should we use?" the header is "Database", not "Which DB". Examples: "Auth method", "Library", "Approach".`),
373480
- options: exports_external.array(questionOptionSchema()).min(2).max(8).describe(`REQUIRED: 2-8 concrete choices. A question with no options is not askable here \u2014 if you cannot name at least two specific answers, the question is open-ended, so ask it in plain assistant text instead of calling this tool. Do not call this tool with a prose question and omit options. Keep options concise and distinct; there should be no 'Other' option, that will be provided automatically.`),
373481
- multiSelect: exports_external.boolean().default(false).describe("Set to true to allow the user to select multiple options instead of just one. Use when choices are not mutually exclusive.")
373482
- }));
373483
- annotationsSchema = lazySchema(() => {
373484
- const annotationSchema = exports_external.object({
373485
- preview: exports_external.string().optional().describe("The preview content of the selected option, if the question used previews."),
373486
- notes: exports_external.string().optional().describe("Free-text notes the user added to their selection.")
373487
- });
373488
- return exports_external.record(exports_external.string(), annotationSchema).optional().describe("Optional per-question annotations from the user (e.g., notes on preview selections). Keyed by question text.");
373489
- });
373415
+ MAX_PREVIEW_CHARS = 16 * 1024;
373416
+ MAX_TOTAL_INPUT_CHARS = 64 * 1024;
373417
+ RESERVED_RECORD_KEYS = new Set(["__proto__", "constructor", "prototype", "toString", "valueOf"]);
373418
+ QUESTION_TEXT_ALIASES = ["question", "questionText", "question_text", "prompt", "text"];
373419
+ CONTROL_OR_ANSI_RE = /[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]|\u001B\[/;
373490
373420
  UNIQUENESS_REFINE = {
373491
373421
  check: (data) => {
373492
- const questions = data.questions.map((q) => q.question);
373422
+ const questions = data.questions.map((q) => q.question.toLocaleLowerCase());
373493
373423
  if (questions.length !== new Set(questions).size) {
373494
373424
  return false;
373495
373425
  }
373496
373426
  for (const question of data.questions) {
373497
- const labels = question.options.map((opt) => opt.label);
373427
+ const labels = question.options.map((opt) => opt.label.toLocaleLowerCase());
373498
373428
  if (labels.length !== new Set(labels).size) {
373499
373429
  return false;
373500
373430
  }
373501
373431
  }
373502
373432
  return true;
373503
373433
  },
373504
- message: "Question texts must be unique, option labels must be unique within each question"
373434
+ message: "Question texts must be unique, and option labels must be unique within each question (ignoring case)"
373505
373435
  };
373506
- commonFields = lazySchema(() => ({
373507
- answers: exports_external.record(exports_external.string(), exports_external.string()).optional().describe("User answers collected by the permission component"),
373508
- annotations: annotationsSchema(),
373509
- metadata: exports_external.object({
373510
- source: exports_external.string().optional().describe('Optional identifier for the source of this question (e.g., "remember" for /remember command). Used for analytics tracking.')
373511
- }).optional().describe("Optional metadata for tracking and analytics purposes. Not displayed to user.")
373436
+ questionOptionSchema = lazySchema(() => exports_external.strictObject({
373437
+ label: boundedText(MAX_LABEL_CHARS, "Option label").refine((label) => {
373438
+ const normalized = label.trim().toLocaleLowerCase();
373439
+ return normalized !== "other" && normalized !== "__other__";
373440
+ }, "Do not provide an Other option; the UI supplies it automatically.").describe("The concise name of this choice, usually 1-5 words. It must be distinct from every other label in this question."),
373441
+ description: boundedText(MAX_DESCRIPTION_CHARS, "Option description").optional().describe("Optional consequence, trade-off, or limitation that adds information beyond the label. Omit it when there is nothing useful to add; never duplicate the label merely to fill this field."),
373442
+ preview: exports_external.string().max(MAX_PREVIEW_CHARS, `Option preview must be at most ${MAX_PREVIEW_CHARS} characters`).refine((value) => value.split(/\r?\n/).length <= MAX_PREVIEW_LINES, `Option preview must be at most ${MAX_PREVIEW_LINES} lines`).optional().describe("Optional bounded preview content rendered when this option is focused.")
373443
+ }));
373444
+ questionSchema = lazySchema(() => exports_external.strictObject({
373445
+ question: boundedText(MAX_QUESTION_CHARS, "Question").refine((question) => !RESERVED_RECORD_KEYS.has(question), "Question text uses a reserved record key; rephrase it.").describe("The complete, specific decision question shown to the user. Ask one decision per object."),
373446
+ header: boundedText(ASK_USER_QUESTION_TOOL_CHIP_WIDTH, "Question header").describe(`A short category chip naming the decision dimension, not a shortened question (max ${ASK_USER_QUESTION_TOOL_CHIP_WIDTH} characters; for \u201CWhich database?\u201D use \u201CDatabase\u201D).`),
373447
+ options: exports_external.array(questionOptionSchema()).min(2).max(MAX_OPTIONS).describe(`REQUIRED: 2-${MAX_OPTIONS} concrete choices nested inside this question object. Do not put option rows directly in the top-level questions array.`),
373448
+ multiSelect: exports_external.boolean().optional().describe("Set to true only when choices are not mutually exclusive. Omit it for ordinary single-select questions.")
373449
+ }).refine((question) => !(question.multiSelect && question.options.some((option) => option.preview !== undefined)), {
373450
+ message: "Preview choices are single-select only; remove previews or set multiSelect to false."
373451
+ }));
373452
+ annotationsSchema = lazySchema(() => {
373453
+ const annotationSchema = exports_external.strictObject({
373454
+ preview: exports_external.string().max(MAX_PREVIEW_CHARS).optional(),
373455
+ notes: exports_external.string().trim().max(MAX_ANSWER_CHARS).optional()
373456
+ });
373457
+ return exports_external.record(exports_external.string(), annotationSchema).optional();
373458
+ });
373459
+ responseFields = lazySchema(() => ({
373460
+ answers: exports_external.record(exports_external.string(), exports_external.string().trim().min(1).max(MAX_ANSWER_CHARS)).optional(),
373461
+ annotations: annotationsSchema()
373462
+ }));
373463
+ metadataSchema = lazySchema(() => exports_external.strictObject({
373464
+ source: exports_external.string().trim().min(1).max(100).optional()
373465
+ }).optional());
373466
+ requestObjectSchema = lazySchema(() => exports_external.strictObject({
373467
+ questions: exports_external.array(questionSchema()).min(1).max(MAX_QUESTIONS).describe(`Questions to ask the user (1-${MAX_QUESTIONS}). Ask only decisions that materially affect the result and cannot be inferred.`),
373468
+ metadata: metadataSchema()
373469
+ }).refine(UNIQUENESS_REFINE.check, {
373470
+ message: UNIQUENESS_REFINE.message
373471
+ }).refine((input) => JSON.stringify(input).length <= MAX_TOTAL_INPUT_CHARS, {
373472
+ message: `AskUserQuestion input must be at most ${MAX_TOTAL_INPUT_CHARS} characters`
373512
373473
  }));
373513
373474
  inputSchema32 = lazySchema(() => exports_external.preprocess(normalizeAskUserQuestionInput2, exports_external.strictObject({
373514
- questions: exports_external.array(questionSchema()).min(1).max(4).describe("Questions to ask the user (1-4 questions)"),
373515
- ...commonFields()
373475
+ questions: exports_external.array(questionSchema()).min(1).max(MAX_QUESTIONS),
373476
+ metadata: metadataSchema(),
373477
+ ...responseFields()
373516
373478
  }).refine(UNIQUENESS_REFINE.check, {
373517
373479
  message: UNIQUENESS_REFINE.message
373480
+ }).refine((input) => JSON.stringify(input).length <= MAX_TOTAL_INPUT_CHARS, {
373481
+ message: `AskUserQuestion input must be at most ${MAX_TOTAL_INPUT_CHARS} characters`
373518
373482
  })));
373519
- outputSchema27 = lazySchema(() => exports_external.object({
373483
+ modelInputJSONSchema = zodToJsonSchema3(requestObjectSchema());
373484
+ outputSchema27 = lazySchema(() => exports_external.strictObject({
373520
373485
  questions: exports_external.array(questionSchema()).describe("The questions that were asked"),
373521
- answers: exports_external.record(exports_external.string(), exports_external.string()).describe("The answers provided by the user (question text -> answer string; multi-select answers are comma-separated)"),
373486
+ answers: exports_external.record(exports_external.string(), exports_external.string().trim().min(1).max(MAX_ANSWER_CHARS)).describe("The answers provided by the user (question text -> answer string; multi-select answers are comma-separated)"),
373522
373487
  annotations: annotationsSchema()
373523
373488
  }));
373524
373489
  AskUserQuestionTool = buildTool({
@@ -373539,6 +373504,7 @@ var init_AskUserQuestionTool = __esm(() => {
373539
373504
  get inputSchema() {
373540
373505
  return inputSchema32();
373541
373506
  },
373507
+ inputJSONSchema: modelInputJSONSchema,
373542
373508
  get outputSchema() {
373543
373509
  return outputSchema27();
373544
373510
  },
@@ -373561,14 +373527,10 @@ var init_AskUserQuestionTool = __esm(() => {
373561
373527
  requiresUserInteraction() {
373562
373528
  return true;
373563
373529
  },
373564
- async validateInput({
373565
- questions
373566
- }) {
373567
- if (getQuestionPreviewFormat() !== "html") {
373568
- return {
373569
- result: true
373570
- };
373571
- }
373530
+ async validateInput(input, context5) {
373531
+ const {
373532
+ questions
373533
+ } = input;
373572
373534
  for (const q of questions) {
373573
373535
  for (const opt of q.options) {
373574
373536
  const err2 = validateHtmlPreview(opt.preview);
@@ -373581,6 +373543,45 @@ var init_AskUserQuestionTool = __esm(() => {
373581
373543
  }
373582
373544
  }
373583
373545
  }
373546
+ if (context5.validationPhase !== "post-permission") {
373547
+ if (Object.prototype.hasOwnProperty.call(input, "answers") || Object.prototype.hasOwnProperty.call(input, "annotations")) {
373548
+ return {
373549
+ result: false,
373550
+ message: "answers and annotations are response fields supplied only after trusted user interaction; omit them from the tool request",
373551
+ errorCode: 1
373552
+ };
373553
+ }
373554
+ return {
373555
+ result: true
373556
+ };
373557
+ }
373558
+ if (!Object.prototype.hasOwnProperty.call(input, "answers") || !input.answers) {
373559
+ return {
373560
+ result: false,
373561
+ message: "No verified user answers were collected. AskUserQuestion cannot complete from an unchanged permission approval.",
373562
+ errorCode: 1
373563
+ };
373564
+ }
373565
+ const expectedQuestions = new Set(questions.map((question) => question.question));
373566
+ const answerKeys = Object.keys(input.answers);
373567
+ const missingAnswers = questions.filter((question) => !Object.prototype.hasOwnProperty.call(input.answers, question.question)).map((question) => question.question);
373568
+ const unexpectedAnswers = answerKeys.filter((key) => !expectedQuestions.has(key));
373569
+ if (missingAnswers.length > 0 || unexpectedAnswers.length > 0) {
373570
+ const details = [...missingAnswers.length > 0 ? [`missing: ${missingAnswers.join(", ")}`] : [], ...unexpectedAnswers.length > 0 ? [`unexpected: ${unexpectedAnswers.join(", ")}`] : []].join("; ");
373571
+ return {
373572
+ result: false,
373573
+ message: `Verified answers must contain exactly one entry for every question (${details}).`,
373574
+ errorCode: 1
373575
+ };
373576
+ }
373577
+ const unexpectedAnnotations = Object.keys(input.annotations ?? {}).filter((key) => !expectedQuestions.has(key));
373578
+ if (unexpectedAnnotations.length > 0) {
373579
+ return {
373580
+ result: false,
373581
+ message: `User annotations contain unknown question keys: ${unexpectedAnnotations.join(", ")}`,
373582
+ errorCode: 1
373583
+ };
373584
+ }
373584
373585
  return {
373585
373586
  result: true
373586
373587
  };
@@ -373628,9 +373629,12 @@ var init_AskUserQuestionTool = __esm(() => {
373628
373629
  },
373629
373630
  async call({
373630
373631
  questions,
373631
- answers = {},
373632
+ answers,
373632
373633
  annotations
373633
373634
  }, _context) {
373635
+ if (!answers) {
373636
+ throw new Error("AskUserQuestion reached execution without verified user answers");
373637
+ }
373634
373638
  return {
373635
373639
  data: {
373636
373640
  questions,
@@ -375332,10 +375336,10 @@ function DANGEROUS_uncachedSystemPromptSection(name, compute, _reason) {
375332
375336
  return { name, compute, cacheBreak: true };
375333
375337
  }
375334
375338
  async function resolveSystemPromptSections(sections) {
375335
- const cache3 = getSystemPromptSectionCache();
375339
+ const cache4 = getSystemPromptSectionCache();
375336
375340
  return Promise.all(sections.map(async (s) => {
375337
- if (!s.cacheBreak && cache3.has(s.name)) {
375338
- return cache3.get(s.name) ?? null;
375341
+ if (!s.cacheBreak && cache4.has(s.name)) {
375342
+ return cache4.get(s.name) ?? null;
375339
375343
  }
375340
375344
  const value = await s.compute();
375341
375345
  setSystemPromptSectionCacheEntry(s.name, value);
@@ -387801,7 +387805,7 @@ function isAnyTracingEnabled() {
387801
387805
  return isTelemetryEnabled() || isEnhancedTelemetryEnabled() || isBetaTracingEnabled();
387802
387806
  }
387803
387807
  function getTracer() {
387804
- return import_api39.trace.getTracer("ur-agent.gen_ai", "1.65.10");
387808
+ return import_api39.trace.getTracer("ur-agent.gen_ai", "1.65.11");
387805
387809
  }
387806
387810
  function createSpanAttributes(spanType, customAttributes = {}) {
387807
387811
  const baseAttributes = getTelemetryAttributes();
@@ -388420,9 +388424,129 @@ function formatValidationPath(path14) {
388420
388424
  return index2 === 0 ? segmentStr : `${String(acc)}.${segmentStr}`;
388421
388425
  }, "");
388422
388426
  }
388427
+ function formatList(values2) {
388428
+ const quoted = values2.map((value) => `\`${value}\``);
388429
+ if (quoted.length <= 1)
388430
+ return quoted[0] ?? "";
388431
+ if (quoted.length === 2)
388432
+ return `${quoted[0]} and ${quoted[1]}`;
388433
+ return `${quoted.slice(0, -1).join(", ")}, and ${quoted.at(-1)}`;
388434
+ }
388435
+ function formatIndexSet(indexes) {
388436
+ const sorted = [...new Set(indexes)].sort((a2, b) => a2 - b);
388437
+ if (sorted.length === 0)
388438
+ return "";
388439
+ const contiguous = sorted.every((value, index2) => index2 === 0 || value === sorted[index2 - 1] + 1);
388440
+ if (contiguous && sorted.length > 1) {
388441
+ return `${sorted[0]}..${sorted.at(-1)}`;
388442
+ }
388443
+ return sorted.join(",");
388444
+ }
388445
+ function formatMissingParameterErrors(error40) {
388446
+ const missing = error40.issues.map((issue2, order) => ({ issue: issue2, order })).filter(({ issue: issue2 }) => issue2.code === "invalid_type" && issue2.message.includes("received undefined"));
388447
+ const byPathShape = new Map;
388448
+ for (const { issue: issue2, order } of missing) {
388449
+ const numericAt = issue2.path.findIndex((segment2) => typeof segment2 === "number");
388450
+ if (numericAt === -1 || numericAt === issue2.path.length - 1)
388451
+ continue;
388452
+ const prefix = issue2.path.slice(0, numericAt);
388453
+ const suffix = issue2.path.slice(numericAt + 1);
388454
+ const index2 = issue2.path[numericAt];
388455
+ if (typeof index2 !== "number")
388456
+ continue;
388457
+ const key = JSON.stringify([prefix, suffix]);
388458
+ const group = byPathShape.get(key) ?? {
388459
+ prefix,
388460
+ suffix,
388461
+ indexes: [],
388462
+ issueOrders: [],
388463
+ firstOrder: order
388464
+ };
388465
+ group.indexes.push(index2);
388466
+ group.issueOrders.push(order);
388467
+ byPathShape.set(key, group);
388468
+ }
388469
+ const combined = new Map;
388470
+ for (const group of byPathShape.values()) {
388471
+ const indexes = [...new Set(group.indexes)].sort((a2, b) => a2 - b);
388472
+ if (indexes.length < 2)
388473
+ continue;
388474
+ const key = JSON.stringify([group.prefix, indexes]);
388475
+ const entry = combined.get(key) ?? {
388476
+ prefix: group.prefix,
388477
+ indexes,
388478
+ fields: [],
388479
+ issueOrders: [],
388480
+ firstOrder: group.firstOrder
388481
+ };
388482
+ entry.fields.push(formatValidationPath(group.suffix));
388483
+ entry.issueOrders.push(...group.issueOrders);
388484
+ entry.firstOrder = Math.min(entry.firstOrder, group.firstOrder);
388485
+ combined.set(key, entry);
388486
+ }
388487
+ const lines = [];
388488
+ const consumed = new Set;
388489
+ for (const entry of combined.values()) {
388490
+ const base2 = `${formatValidationPath(entry.prefix)}[${formatIndexSet(entry.indexes)}]`;
388491
+ const fields = [...new Set(entry.fields)];
388492
+ lines.push({
388493
+ order: entry.firstOrder,
388494
+ text: fields.length === 1 ? `The required field ${formatList(fields)} is missing from \`${base2}\`` : `The required fields ${formatList(fields)} are missing from \`${base2}\``
388495
+ });
388496
+ for (const order of entry.issueOrders)
388497
+ consumed.add(order);
388498
+ }
388499
+ for (const { issue: issue2, order } of missing) {
388500
+ if (consumed.has(order))
388501
+ continue;
388502
+ lines.push({
388503
+ order,
388504
+ text: `The required parameter \`${formatValidationPath(issue2.path)}\` is missing`
388505
+ });
388506
+ }
388507
+ return lines.sort((a2, b) => a2.order - b.order).map((line) => line.text);
388508
+ }
388509
+ function formatSizeConstraintErrors(error40) {
388510
+ const result = [];
388511
+ for (const issue2 of error40.issues) {
388512
+ if (issue2.code !== "too_big" && issue2.code !== "too_small")
388513
+ continue;
388514
+ const detail = issue2;
388515
+ const limit = issue2.code === "too_big" ? detail.maximum : detail.minimum;
388516
+ if (limit === undefined) {
388517
+ result.push(issue2.message);
388518
+ continue;
388519
+ }
388520
+ const path14 = formatValidationPath(issue2.path) || "input";
388521
+ const inclusive = detail.inclusive !== false;
388522
+ const comparison = issue2.code === "too_big" ? inclusive ? "at most" : "fewer than" : inclusive ? "at least" : "more than";
388523
+ const unit = detail.origin === "array" ? "items" : detail.origin === "string" ? "characters" : null;
388524
+ result.push(unit ? `The parameter \`${path14}\` must contain ${comparison} ${String(limit)} ${unit}` : `The parameter \`${path14}\` must be ${comparison} ${String(limit)}`);
388525
+ }
388526
+ return [...new Set(result)];
388527
+ }
388528
+ function getAskUserQuestionCorrection(error40) {
388529
+ if (!error40.issues.some((issue2) => issue2.path[0] === "questions"))
388530
+ return null;
388531
+ const inferredCount = error40.issues.reduce((count3, issue2) => {
388532
+ const index2 = issue2.path[0] === "questions" ? issue2.path[1] : undefined;
388533
+ return typeof index2 === "number" ? Math.max(count3, index2 + 1) : count3;
388534
+ }, 0);
388535
+ const countNotice = inferredCount > 4 ? ` This call contains at least ${inferredCount} incomplete question entries.` : "";
388536
+ return "AskUserQuestion requires 1-4 complete question objects. Each object must " + "contain `question`, `header`, and an `options` array with 2-8 " + "objects containing `label`; include `description` only when it adds a " + "useful consequence or trade-off." + countNotice + " Do not invent missing choices or truncate entries. Retry with at most " + "four complete questions, ask remaining decisions in later rounds, and " + "do not repeat the unchanged call.";
388537
+ }
388538
+ function getWriteCorrection(error40) {
388539
+ const missingRequiredField = error40.issues.some((issue2) => issue2.code === "invalid_type" && issue2.message.includes("received undefined") && (issue2.path[0] === "file_path" || issue2.path[0] === "content"));
388540
+ if (!missingRequiredField)
388541
+ return null;
388542
+ return "No file was written. Write requires both `file_path` and `content` in " + "the same structured tool call. Assistant prose outside the call is not " + "file content and will not be copied into it. Retry only after supplying " + "the complete intended file text in `content`; do not repeat the " + "unchanged call or claim the file was created until Write returns success.";
388543
+ }
388423
388544
  function formatZodValidationError(toolName, error40) {
388424
- const missingParams = error40.issues.filter((err2) => err2.code === "invalid_type" && err2.message.includes("received undefined")).map((err2) => formatValidationPath(err2.path));
388425
- const unexpectedParams = error40.issues.filter((err2) => err2.code === "unrecognized_keys").flatMap((err2) => err2.keys);
388545
+ const missingParamErrors = formatMissingParameterErrors(error40);
388546
+ const sizeConstraintErrors = formatSizeConstraintErrors(error40);
388547
+ const unexpectedParams = [
388548
+ ...new Set(error40.issues.filter((err2) => err2.code === "unrecognized_keys").flatMap((err2) => err2.keys))
388549
+ ];
388426
388550
  const typeMismatchParams = error40.issues.filter((err2) => err2.code === "invalid_type" && !err2.message.includes("received undefined")).map((err2) => {
388427
388551
  const typeErr = err2;
388428
388552
  const receivedMatch = err2.message.match(/received (\w+)/);
@@ -388435,10 +388559,8 @@ function formatZodValidationError(toolName, error40) {
388435
388559
  });
388436
388560
  let errorContent = error40.message;
388437
388561
  const errorParts = [];
388438
- if (missingParams.length > 0) {
388439
- const missingParamErrors = missingParams.map((param) => `The required parameter \`${param}\` is missing`);
388440
- errorParts.push(...missingParamErrors);
388441
- }
388562
+ errorParts.push(...sizeConstraintErrors);
388563
+ errorParts.push(...missingParamErrors);
388442
388564
  if (unexpectedParams.length > 0) {
388443
388565
  const unexpectedParamErrors = unexpectedParams.map((param) => `An unexpected parameter \`${param}\` was provided`);
388444
388566
  errorParts.push(...unexpectedParamErrors);
@@ -388451,6 +388573,19 @@ function formatZodValidationError(toolName, error40) {
388451
388573
  errorContent = `${toolName} failed due to the following ${errorParts.length > 1 ? "issues" : "issue"}:
388452
388574
  ${errorParts.join(`
388453
388575
  `)}`;
388576
+ }
388577
+ if (toolName === "AskUserQuestion") {
388578
+ const correction = getAskUserQuestionCorrection(error40);
388579
+ if (correction)
388580
+ errorContent += `
388581
+
388582
+ ${correction}`;
388583
+ } else if (toolName === "Write") {
388584
+ const correction = getWriteCorrection(error40);
388585
+ if (correction)
388586
+ errorContent += `
388587
+
388588
+ ${correction}`;
388454
388589
  }
388455
388590
  return errorContent;
388456
388591
  }
@@ -388477,6 +388612,36 @@ function isPlanArtifactMutationForGate(input) {
388477
388612
  return false;
388478
388613
  }
388479
388614
  }
388615
+ function isLocalPreviewOpenForTaskGate(input) {
388616
+ if (input.toolName !== "Bash" || typeof input.toolInput !== "object" || input.toolInput === null) {
388617
+ return false;
388618
+ }
388619
+ const candidate = input.toolInput;
388620
+ if (typeof candidate.command !== "string" || candidate.command.trim() === "" || candidate.run_in_background === true || candidate.dangerouslyDisableSandbox === true || candidate._simulatedSedEdit !== undefined) {
388621
+ return false;
388622
+ }
388623
+ const command = candidate.command;
388624
+ if (command.includes("$") || command.includes("`") || command.includes("\\") || command.includes(`
388625
+ `) || command.includes("\r") || command.includes("\x00") || hasUnbalancedQuotes(command)) {
388626
+ return false;
388627
+ }
388628
+ const parsed = tryParseShellCommand(command);
388629
+ if (!parsed.success || parsed.tokens.length !== 2 || parsed.tokens.some((token) => typeof token !== "string") || parsed.tokens[0] !== "open") {
388630
+ return false;
388631
+ }
388632
+ try {
388633
+ const url3 = new URL(parsed.tokens[1]);
388634
+ return (url3.protocol === "http:" || url3.protocol === "https:") && LOOPBACK_PREVIEW_HOSTS.has(url3.hostname) && url3.username === "" && url3.password === "";
388635
+ } catch {
388636
+ return false;
388637
+ }
388638
+ }
388639
+ function isMutationRequiringTaskList(input) {
388640
+ return input.isMutating && !isLocalPreviewOpenForTaskGate({
388641
+ toolName: input.toolName,
388642
+ toolInput: input.toolInput
388643
+ });
388644
+ }
388480
388645
  function getTaskListGateConfig() {
388481
388646
  const configured = getInitialSettings()?.tasks?.requireBeforeChanges;
388482
388647
  if (!configured)
@@ -388521,23 +388686,28 @@ function checkTaskListGate(input) {
388521
388686
  }
388522
388687
  if (input.isSubagent || ALWAYS_REQUIRE_PLAN_TOOLS.has(input.toolName)) {
388523
388688
  const taskTool2 = input.taskPlanningToolName ?? "TaskCreate";
388689
+ const terminalContext = input.totalTaskCount !== null && input.totalTaskCount !== undefined && input.totalTaskCount > 0 ? " The existing task list contains only terminal tasks." : "";
388524
388690
  return {
388525
388691
  allowed: false,
388526
- reason: `No actionable parent task exists for ${input.toolName}. Call ` + `${taskTool2} before delegating or changing state, then retry this call. ` + `${TASK_DECOMPOSITION_RECOVERY} ` + `Disable with tasks.requireBeforeChanges.enabled=false in settings.`
388692
+ reason: `No actionable parent task exists for ${input.toolName}.` + `${terminalContext} Call ${taskTool2} before delegating or changing ` + `state, then retry this call. ` + `${TASK_DECOMPOSITION_RECOVERY} ` + `Disable with tasks.requireBeforeChanges.enabled=false in settings.`
388527
388693
  };
388528
388694
  }
388529
388695
  if (input.readsSoFar < config2.freeReads)
388530
388696
  return { allowed: true };
388531
388697
  const taskTool = input.taskPlanningToolName ?? "TaskCreate";
388698
+ const hasTerminalTaskList = input.totalTaskCount !== null && input.totalTaskCount !== undefined && input.totalTaskCount > 0;
388699
+ const taskState = hasTerminalTaskList ? "The task list exists, but every tracked task is terminal, so no actionable task remains" : "No actionable task exists";
388700
+ const recovery = taskTool === "TodoWrite" ? "Call TodoWrite first to add a cohesive remaining todo or move the relevant todo back to pending/in_progress" : taskTool === "TaskCreate" ? "Call TaskCreate first to add a cohesive remaining task, or call TaskUpdate to move the relevant task back to pending/in_progress" : `Use ${taskTool} first to add or reopen a cohesive pending/in_progress task`;
388532
388701
  return {
388533
388702
  allowed: false,
388534
- reason: `No task list exists, and ${input.toolName} changes the workspace. ` + `Call ${taskTool} first, then retry this call. ` + `${TASK_DECOMPOSITION_RECOVERY} Reads are unrestricted, so investigate ` + `as much as you need before writing the list. ` + `Disable with tasks.requireBeforeChanges.enabled=false in settings.`
388703
+ reason: `${taskState}, and ${input.toolName} changes workspace state. ` + `${recovery}, then retry this call. Keep preview, launch, and ` + `verification work actionable until its observable check has actually ` + `run; do not mark that task complete before the check. ` + `${TASK_DECOMPOSITION_RECOVERY} Reads are unrestricted, so investigate ` + `as much as you need before writing the list. ` + `Disable with tasks.requireBeforeChanges.enabled=false in settings.`
388535
388704
  };
388536
388705
  }
388537
- var TASK_LIST_GATE_DEFAULTS, KNOWN_MUTATING_TOOLS, GATE_EXEMPT_TOOLS, ALWAYS_REQUIRE_PLAN_TOOLS, TASK_DECOMPOSITION_RECOVERY, PLAN_ARTIFACT_MUTATING_TOOLS;
388706
+ var TASK_LIST_GATE_DEFAULTS, KNOWN_MUTATING_TOOLS, GATE_EXEMPT_TOOLS, ALWAYS_REQUIRE_PLAN_TOOLS, TASK_DECOMPOSITION_RECOVERY, PLAN_ARTIFACT_MUTATING_TOOLS, LOOPBACK_PREVIEW_HOSTS;
388538
388707
  var init_taskListGate = __esm(() => {
388539
388708
  init_settings2();
388540
388709
  init_path();
388710
+ init_shellQuote();
388541
388711
  TASK_LIST_GATE_DEFAULTS = {
388542
388712
  enabled: true,
388543
388713
  freeReads: 3
@@ -388560,7 +388730,8 @@ var init_taskListGate = __esm(() => {
388560
388730
  "TaskUpdate",
388561
388731
  "TaskList",
388562
388732
  "TaskGet",
388563
- "TodoWrite"
388733
+ "TodoWrite",
388734
+ "ExitPlanMode"
388564
388735
  ]);
388565
388736
  ALWAYS_REQUIRE_PLAN_TOOLS = new Set([
388566
388737
  "Agent",
@@ -388572,6 +388743,11 @@ var init_taskListGate = __esm(() => {
388572
388743
  "Edit",
388573
388744
  "MultiEdit"
388574
388745
  ]);
388746
+ LOOPBACK_PREVIEW_HOSTS = new Set([
388747
+ "localhost",
388748
+ "127.0.0.1",
388749
+ "[::1]"
388750
+ ]);
388575
388751
  });
388576
388752
 
388577
388753
  // src/services/tools/repeatedFailureGuard.ts
@@ -389623,10 +389799,18 @@ async function countTasksForGate(toolUseContext) {
389623
389799
  const { getTaskListId: getTaskListId2, inspectTaskListForGate: inspectTaskListForGate2, isTodoV2Enabled: isTodoV2Enabled2 } = await Promise.resolve().then(() => (init_tasks(), exports_tasks));
389624
389800
  if (!isTodoV2Enabled2()) {
389625
389801
  const todoKey = toolUseContext.agentId ?? getSessionId();
389626
- return countActionableTodosForGate(toolUseContext.getAppState().todos?.[todoKey]);
389802
+ const todos = toolUseContext.getAppState().todos?.[todoKey] ?? [];
389803
+ return {
389804
+ actionableCount: countActionableTodosForGate(todos),
389805
+ totalCount: todos.length
389806
+ };
389627
389807
  }
389628
389808
  const inspection = await inspectTaskListForGate2(getTaskListId2());
389629
- return countActionableTasksForGate(inspection.tasks);
389809
+ const userTasks = inspection.tasks.filter((task) => !task.metadata?._internal);
389810
+ return {
389811
+ actionableCount: countActionableTasksForGate(userTasks),
389812
+ totalCount: userTasks.length
389813
+ };
389630
389814
  } catch {
389631
389815
  return null;
389632
389816
  }
@@ -390144,6 +390328,11 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
390144
390328
  isMutating = true;
390145
390329
  }
390146
390330
  const isPlanArtifactMutation = isCurrentPlanArtifactMutation(tool.name, parsedInput.data, toolUseContext);
390331
+ const isTaskListGatedMutation = isMutationRequiringTaskList({
390332
+ toolName: tool.name,
390333
+ toolInput: parsedInput.data,
390334
+ isMutating
390335
+ });
390147
390336
  if (isMutating && isBuiltInReadOnlyPlanningSubagent(toolUseContext)) {
390148
390337
  recordCallFailure(callSig);
390149
390338
  return [
@@ -390161,12 +390350,14 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
390161
390350
  }
390162
390351
  ];
390163
390352
  }
390353
+ const taskCounts = await countTasksForGate(toolUseContext);
390164
390354
  const gate = checkTaskListGate({
390165
390355
  toolName: tool.name,
390166
- taskCount: await countTasksForGate(toolUseContext),
390356
+ taskCount: taskCounts?.actionableCount ?? null,
390357
+ totalTaskCount: taskCounts?.totalCount ?? null,
390167
390358
  readsSoFar: countToolCallsBeforeCurrent(toolUseContext.messages, assistantMessage, toolUseID),
390168
390359
  isSubagent: Boolean(toolUseContext.agentId),
390169
- isMutating,
390360
+ isMutating: isTaskListGatedMutation,
390170
390361
  isPlanArtifactMutation,
390171
390362
  taskPlanningToolName: getTaskPlanningToolName(toolUseContext)
390172
390363
  });
@@ -390492,7 +390683,7 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
390492
390683
  });
390493
390684
  return resultingMessages;
390494
390685
  }
390495
- if (callSig !== initiallyValidatedCallSig) {
390686
+ if (callSig !== initiallyValidatedCallSig || tool.requiresUserInteraction?.()) {
390496
390687
  const finalValidation = await tool.validateInput?.(finalParsedInput.data, {
390497
390688
  ...toolUseContext,
390498
390689
  validationPhase: "post-permission"
@@ -390524,6 +390715,11 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
390524
390715
  finalIsMutating = true;
390525
390716
  }
390526
390717
  const finalIsPlanArtifactMutation = isCurrentPlanArtifactMutation(tool.name, finalParsedInput.data, toolUseContext);
390718
+ const finalIsTaskListGatedMutation = isMutationRequiringTaskList({
390719
+ toolName: tool.name,
390720
+ toolInput: finalParsedInput.data,
390721
+ isMutating: finalIsMutating
390722
+ });
390527
390723
  if (finalIsMutating && isBuiltInReadOnlyPlanningSubagent(toolUseContext)) {
390528
390724
  recordCallFailure(callSig);
390529
390725
  finishPreExecutionRejection();
@@ -390542,14 +390738,16 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
390542
390738
  });
390543
390739
  return resultingMessages;
390544
390740
  }
390545
- const effectiveCallChanged = callSig !== initiallyValidatedCallSig || finalIsMutating !== isMutating || finalIsPlanArtifactMutation !== isPlanArtifactMutation;
390546
- if (finalIsMutating && !finalIsPlanArtifactMutation) {
390741
+ const effectiveCallChanged = callSig !== initiallyValidatedCallSig || finalIsMutating !== isMutating || finalIsTaskListGatedMutation !== isTaskListGatedMutation || finalIsPlanArtifactMutation !== isPlanArtifactMutation;
390742
+ if (finalIsTaskListGatedMutation && !finalIsPlanArtifactMutation) {
390743
+ const finalTaskCounts = await countTasksForGate(toolUseContext);
390547
390744
  const finalGate = checkTaskListGate({
390548
390745
  toolName: tool.name,
390549
- taskCount: await countTasksForGate(toolUseContext),
390746
+ taskCount: finalTaskCounts?.actionableCount ?? null,
390747
+ totalTaskCount: finalTaskCounts?.totalCount ?? null,
390550
390748
  readsSoFar: countToolCallsBeforeCurrent(toolUseContext.messages, assistantMessage, toolUseID),
390551
390749
  isSubagent: Boolean(toolUseContext.agentId),
390552
- isMutating: finalIsMutating,
390750
+ isMutating: finalIsTaskListGatedMutation,
390553
390751
  isPlanArtifactMutation: finalIsPlanArtifactMutation,
390554
390752
  taskPlanningToolName: getTaskPlanningToolName(toolUseContext)
390555
390753
  });
@@ -392527,7 +392725,7 @@ function projectStoreFile(cwd2, directory, name, create2) {
392527
392725
  }
392528
392726
  return create2 || existsSync30(target) ? target : undefined;
392529
392727
  }
392530
- function boundedText(text) {
392728
+ function boundedText2(text) {
392531
392729
  const normalized = text.trim();
392532
392730
  if (!normalized)
392533
392731
  throw new Error("note text cannot be empty");
@@ -392591,7 +392789,7 @@ function rememberInAutoMemory(memoryDir, text) {
392591
392789
  function remember(cwd2, text) {
392592
392790
  append2(memFile(cwd2, true), {
392593
392791
  ts: new Date().toISOString(),
392594
- text: boundedText(text),
392792
+ text: boundedText2(text),
392595
392793
  kind: "note"
392596
392794
  });
392597
392795
  }
@@ -392641,7 +392839,7 @@ function forgetInAutoMemory(memoryDir, texts) {
392641
392839
  function addResearch(cwd2, kind, text) {
392642
392840
  append2(researchFile(cwd2, kind, true), {
392643
392841
  ts: new Date().toISOString(),
392644
- text: boundedText(text),
392842
+ text: boundedText2(text),
392645
392843
  kind
392646
392844
  });
392647
392845
  }
@@ -397438,21 +397636,6 @@ var init_analyzeContext = __esm(() => {
397438
397636
  init_tokens();
397439
397637
  });
397440
397638
 
397441
- // src/utils/zodToJsonSchema.ts
397442
- function zodToJsonSchema3(schema) {
397443
- const hit = cache3.get(schema);
397444
- if (hit)
397445
- return hit;
397446
- const result = toJSONSchema(schema);
397447
- cache3.set(schema, result);
397448
- return result;
397449
- }
397450
- var cache3;
397451
- var init_zodToJsonSchema2 = __esm(() => {
397452
- init_v4();
397453
- cache3 = new WeakMap;
397454
- });
397455
-
397456
397639
  // src/utils/toolSearch.ts
397457
397640
  var exports_toolSearch = {};
397458
397641
  __export(exports_toolSearch, {
@@ -418319,7 +418502,7 @@ function Feedback({
418319
418502
  platform: env2.platform,
418320
418503
  gitRepo: envInfo.isGit,
418321
418504
  terminal: env2.terminal,
418322
- version: "1.65.10",
418505
+ version: "1.65.11",
418323
418506
  transcript: normalizeMessagesForAPI(messages),
418324
418507
  errors: sanitizedErrors,
418325
418508
  lastApiRequest: getLastAPIRequest(),
@@ -418511,7 +418694,7 @@ function Feedback({
418511
418694
  ", ",
418512
418695
  env2.terminal,
418513
418696
  ", v",
418514
- "1.65.10"
418697
+ "1.65.11"
418515
418698
  ]
418516
418699
  }, undefined, true, undefined, this)
418517
418700
  ]
@@ -418617,7 +418800,7 @@ ${sanitizedDescription}
418617
418800
  ` + `**Environment Info**
418618
418801
  ` + `- Platform: ${env2.platform}
418619
418802
  ` + `- Terminal: ${env2.terminal}
418620
- ` + `- Version: ${"1.65.10"}
418803
+ ` + `- Version: ${"1.65.11"}
418621
418804
  ` + `- Feedback ID: ${feedbackId}
418622
418805
  ` + `
418623
418806
  **Errors**
@@ -421727,7 +421910,7 @@ function buildPrimarySection() {
421727
421910
  }, undefined, false, undefined, this);
421728
421911
  return [{
421729
421912
  label: "Version",
421730
- value: "1.65.10"
421913
+ value: "1.65.11"
421731
421914
  }, {
421732
421915
  label: "Session name",
421733
421916
  value: nameValue
@@ -425057,7 +425240,7 @@ function Config({
425057
425240
  }
425058
425241
  }, undefined, false, undefined, this)
425059
425242
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime179.jsxDEV(ChannelDowngradeDialog, {
425060
- currentVersion: "1.65.10",
425243
+ currentVersion: "1.65.11",
425061
425244
  onChoice: (choice) => {
425062
425245
  setShowSubmenu(null);
425063
425246
  setTabsHidden(false);
@@ -425069,7 +425252,7 @@ function Config({
425069
425252
  autoUpdatesChannel: "stable"
425070
425253
  };
425071
425254
  if (choice === "stay") {
425072
- newSettings.minimumVersion = "1.65.10";
425255
+ newSettings.minimumVersion = "1.65.11";
425073
425256
  }
425074
425257
  updateSettingsForSource("userSettings", newSettings);
425075
425258
  setSettingsData((prev_27) => ({
@@ -433133,7 +433316,7 @@ function HelpV2(t0) {
433133
433316
  let t6;
433134
433317
  if ($2[31] !== tabs) {
433135
433318
  t6 = /* @__PURE__ */ jsx_dev_runtime206.jsxDEV(Tabs, {
433136
- title: `UR v${"1.65.10"}`,
433319
+ title: `UR v${"1.65.11"}`,
433137
433320
  color: "professionalBlue",
433138
433321
  defaultTab: "general",
433139
433322
  children: tabs
@@ -434066,7 +434249,7 @@ function buildToolUseContext(tools, readFileStateCache, toolPermissionContext, a
434066
434249
  async function handleInitialize(options2) {
434067
434250
  return {
434068
434251
  name: "UR",
434069
- version: "1.65.10",
434252
+ version: "1.65.11",
434070
434253
  protocolVersion: "0.1.0",
434071
434254
  workspaceRoot: options2.cwd,
434072
434255
  capabilities: {
@@ -451174,7 +451357,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
451174
451357
  return [];
451175
451358
  }
451176
451359
  }
451177
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.65.10") {
451360
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.65.11") {
451178
451361
  if (process.env.USER_TYPE === "ant") {
451179
451362
  const changelog = "";
451180
451363
  if (changelog) {
@@ -451201,7 +451384,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.65.10")
451201
451384
  releaseNotes
451202
451385
  };
451203
451386
  }
451204
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.65.10") {
451387
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.65.11") {
451205
451388
  if (process.env.USER_TYPE === "ant") {
451206
451389
  const changelog = "";
451207
451390
  if (changelog) {
@@ -454067,7 +454250,7 @@ function getRecentActivitySync() {
454067
454250
  return cachedActivity;
454068
454251
  }
454069
454252
  function getLogoDisplayData() {
454070
- const version2 = process.env.DEMO_VERSION ?? "1.65.10";
454253
+ const version2 = process.env.DEMO_VERSION ?? "1.65.11";
454071
454254
  const serverUrl = getDirectConnectServerUrl();
454072
454255
  const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd());
454073
454256
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -454934,7 +455117,7 @@ function LogoV2() {
454934
455117
  if ($2[2] === Symbol.for("react.memo_cache_sentinel")) {
454935
455118
  t2 = () => {
454936
455119
  const currentConfig2 = getGlobalConfig();
454937
- if (currentConfig2.lastReleaseNotesSeen === "1.65.10") {
455120
+ if (currentConfig2.lastReleaseNotesSeen === "1.65.11") {
454938
455121
  return;
454939
455122
  }
454940
455123
  saveGlobalConfig(_temp325);
@@ -455619,12 +455802,12 @@ function LogoV2() {
455619
455802
  return t41;
455620
455803
  }
455621
455804
  function _temp325(current) {
455622
- if (current.lastReleaseNotesSeen === "1.65.10") {
455805
+ if (current.lastReleaseNotesSeen === "1.65.11") {
455623
455806
  return current;
455624
455807
  }
455625
455808
  return {
455626
455809
  ...current,
455627
- lastReleaseNotesSeen: "1.65.10"
455810
+ lastReleaseNotesSeen: "1.65.11"
455628
455811
  };
455629
455812
  }
455630
455813
  function _temp241(s_0) {
@@ -472564,7 +472747,7 @@ function compileAgenticCiWorkflow(specName = "default", options2 = {}) {
472564
472747
  if (spec.name !== specName) {
472565
472748
  throw new Error("Agentic CI workflow spec name does not match");
472566
472749
  }
472567
- const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.65.10" : "1.65.10");
472750
+ const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.65.11" : "1.65.11");
472568
472751
  if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(packageVersion)) {
472569
472752
  throw new Error("invalid ur-agent package version");
472570
472753
  }
@@ -473557,7 +473740,7 @@ runner; \`ur trigger\` is the inbound parser that decides what to run.
473557
473740
  path: ".github/workflows/ur.yml",
473558
473741
  root: "project",
473559
473742
  content: compileAgenticCiWorkflow("default", {
473560
- packageVersion: typeof MACRO !== "undefined" ? "1.65.10" : "1.65.10"
473743
+ packageVersion: typeof MACRO !== "undefined" ? "1.65.11" : "1.65.11"
473561
473744
  })
473562
473745
  },
473563
473746
  {
@@ -473627,7 +473810,7 @@ function value(tokens, flag) {
473627
473810
  return index2 >= 0 ? tokens[index2 + 1] : undefined;
473628
473811
  }
473629
473812
  function cliVersion() {
473630
- return typeof MACRO !== "undefined" ? "1.65.10" : "1.65.10";
473813
+ return typeof MACRO !== "undefined" ? "1.65.11" : "1.65.11";
473631
473814
  }
473632
473815
  function workflowPath(cwd2) {
473633
473816
  return join159(cwd2, ".github", "workflows", "ur-agentic-ci.yml");
@@ -479492,7 +479675,7 @@ function createAcpStdioApp(deps) {
479492
479675
  }
479493
479676
  },
479494
479677
  authMethods: [],
479495
- agentInfo: { name: "UR-Nexus", version: "1.65.10" }
479678
+ agentInfo: { name: "UR-Nexus", version: "1.65.11" }
479496
479679
  })).onRequest("authenticate", () => ({})).onRequest("session/new", async (context6) => {
479497
479680
  const result = runtime2.newSession(context6.params.cwd, context6.params.mcpServers, context6.params.additionalDirectories);
479498
479681
  await runtime2.announce({
@@ -479589,7 +479772,7 @@ function createAcpStdioAgent(deps) {
479589
479772
  }
479590
479773
  },
479591
479774
  authMethods: [],
479592
- agentInfo: { name: "UR-Nexus", version: "1.65.10" }
479775
+ agentInfo: { name: "UR-Nexus", version: "1.65.11" }
479593
479776
  });
479594
479777
  return;
479595
479778
  case "authenticate":
@@ -482643,7 +482826,7 @@ function buildExecFinalReport(run3) {
482643
482826
  ]
482644
482827
  };
482645
482828
  }
482646
- function formatList(items, empty, render2) {
482829
+ function formatList2(items, empty, render2) {
482647
482830
  return items.length > 0 ? items.map(render2) : [`- ${empty}`];
482648
482831
  }
482649
482832
  function formatApprovalDecision(decision) {
@@ -482670,46 +482853,46 @@ function formatExecFinalReport(report) {
482670
482853
  `Agents used: ${report.activeAgentsUsed} active / ${report.maxAgentsAllowed} max`,
482671
482854
  "",
482672
482855
  "Finished tasks:",
482673
- ...formatList(report.finishedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482856
+ ...formatList2(report.finishedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482674
482857
  "",
482675
482858
  "Failed tasks:",
482676
- ...formatList(report.failedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482859
+ ...formatList2(report.failedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482677
482860
  "",
482678
482861
  "Waiting on prerequisite tasks:",
482679
- ...formatList(report.blockedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482862
+ ...formatList2(report.blockedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482680
482863
  "",
482681
482864
  "Waiting approval/input tasks:",
482682
- ...formatList(report.waitingApprovalTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482865
+ ...formatList2(report.waitingApprovalTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482683
482866
  "",
482684
482867
  "Skipped tasks:",
482685
- ...formatList(report.skippedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482868
+ ...formatList2(report.skippedTasks, "none", (task) => `- ${task.id} | ${task.agent} | ${task.title}`),
482686
482869
  "",
482687
482870
  "Actual changed files:",
482688
- ...formatList(report.actualChangedFiles, "none observed", (file2) => `- ${file2}`),
482871
+ ...formatList2(report.actualChangedFiles, "none observed", (file2) => `- ${file2}`),
482689
482872
  "",
482690
482873
  "Outside-workspace files accessed:",
482691
- ...formatList(report.outsideWorkspaceFilesAccessed, "none observed", (file2) => `- ${file2}`),
482874
+ ...formatList2(report.outsideWorkspaceFilesAccessed, "none observed", (file2) => `- ${file2}`),
482692
482875
  "",
482693
482876
  "Outside-workspace files modified:",
482694
- ...formatList(report.outsideWorkspaceFilesModified, "none observed", (file2) => `- ${file2}`),
482877
+ ...formatList2(report.outsideWorkspaceFilesModified, "none observed", (file2) => `- ${file2}`),
482695
482878
  "",
482696
482879
  "Unreported changed files:",
482697
- ...formatList(report.unreportedChangedFiles, "none", (file2) => `- ${file2}`),
482880
+ ...formatList2(report.unreportedChangedFiles, "none", (file2) => `- ${file2}`),
482698
482881
  "",
482699
482882
  "Verified commands:",
482700
- ...formatList(report.verifiedCommands, "none observed", (command5) => `- ${command5}`),
482883
+ ...formatList2(report.verifiedCommands, "none observed", (command5) => `- ${command5}`),
482701
482884
  "",
482702
482885
  "Unverified command claims:",
482703
- ...formatList(report.unverifiedCommandClaims, "none", (command5) => `- ${command5}`),
482886
+ ...formatList2(report.unverifiedCommandClaims, "none", (command5) => `- ${command5}`),
482704
482887
  "",
482705
482888
  "Approval decisions:",
482706
- ...formatList(report.approvalDecisions, "none", formatApprovalDecision),
482889
+ ...formatList2(report.approvalDecisions, "none", formatApprovalDecision),
482707
482890
  "",
482708
482891
  "Verification failures:",
482709
- ...formatList(report.verificationFailures, "none", (failure) => `- ${failure.taskId} | ${failure.code} | ${failure.message}`),
482892
+ ...formatList2(report.verificationFailures, "none", (failure) => `- ${failure.taskId} | ${failure.code} | ${failure.message}`),
482710
482893
  "",
482711
482894
  "Warnings:",
482712
- ...formatList(report.warnings, "none", (warning) => `- ${warning.taskId} | ${warning.code} | ${warning.message}`),
482895
+ ...formatList2(report.warnings, "none", (warning) => `- ${warning.taskId} | ${warning.code} | ${warning.message}`),
482713
482896
  "",
482714
482897
  "Remaining limitations:",
482715
482898
  ...report.remainingLimitations.map((item) => `- ${item}`)
@@ -676702,7 +676885,7 @@ __export(exports_role_mode, {
676702
676885
  });
676703
676886
  import { existsSync as existsSync94, mkdirSync as mkdirSync65, writeFileSync as writeFileSync65 } from "fs";
676704
676887
  import { join as join212 } from "path";
676705
- function formatList2() {
676888
+ function formatList3() {
676706
676889
  const lines = ["Built-in role modes:", ""];
676707
676890
  for (const mode2 of ROLE_MODES) {
676708
676891
  const scope = mode2.tools ? mode2.tools.join(", ") : "all tools";
@@ -676733,7 +676916,7 @@ var call127 = async (args) => {
676733
676916
  })), null, 2)
676734
676917
  };
676735
676918
  }
676736
- return { type: "text", value: formatList2() };
676919
+ return { type: "text", value: formatList3() };
676737
676920
  }
676738
676921
  if (command5 === "show") {
676739
676922
  const name = positional2[1];
@@ -690749,7 +690932,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
690749
690932
  smapsRollup,
690750
690933
  platform: process.platform,
690751
690934
  nodeVersion: process.version,
690752
- ccVersion: "1.65.10"
690935
+ ccVersion: "1.65.11"
690753
690936
  };
690754
690937
  }
690755
690938
  async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
@@ -691329,7 +691512,7 @@ var init_bridge_kick = __esm(() => {
691329
691512
  var call153 = async () => {
691330
691513
  return {
691331
691514
  type: "text",
691332
- value: "1.65.10"
691515
+ value: "1.65.11"
691333
691516
  };
691334
691517
  }, version2, version_default;
691335
691518
  var init_version = __esm(() => {
@@ -702509,7 +702692,7 @@ function generateHtmlReport(data, insights) {
702509
702692
  </html>`;
702510
702693
  }
702511
702694
  function buildExportData(data, insights, facets, remoteStats) {
702512
- const version3 = typeof MACRO !== "undefined" ? "1.65.10" : "unknown";
702695
+ const version3 = typeof MACRO !== "undefined" ? "1.65.11" : "unknown";
702513
702696
  const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
702514
702697
  const facets_summary = {
702515
702698
  total: facets.size,
@@ -706836,7 +707019,7 @@ var init_sessionStorage = __esm(() => {
706836
707019
  init_settings2();
706837
707020
  init_slowOperations();
706838
707021
  init_uuid();
706839
- VERSION7 = typeof MACRO !== "undefined" ? "1.65.10" : "unknown";
707022
+ VERSION7 = typeof MACRO !== "undefined" ? "1.65.11" : "unknown";
706840
707023
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
706841
707024
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
706842
707025
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -708051,7 +708234,7 @@ var init_filesystem = __esm(() => {
708051
708234
  });
708052
708235
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
708053
708236
  const nonce = randomBytes20(16).toString("hex");
708054
- return join230(getURTempDir(), "bundled-skills", "1.65.10", nonce);
708237
+ return join230(getURTempDir(), "bundled-skills", "1.65.11", nonce);
708055
708238
  });
708056
708239
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
708057
708240
  });
@@ -714379,7 +714562,7 @@ function computeFingerprint(messageText2, version3) {
714379
714562
  }
714380
714563
  function computeFingerprintFromMessages(messages) {
714381
714564
  const firstMessageText = extractFirstMessageText(messages);
714382
- return computeFingerprint(firstMessageText, "1.65.10");
714565
+ return computeFingerprint(firstMessageText, "1.65.11");
714383
714566
  }
714384
714567
  var FINGERPRINT_SALT = "59cf53e54c78";
714385
714568
  var init_fingerprint = () => {};
@@ -716275,7 +716458,7 @@ async function sideQuery(opts) {
716275
716458
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
716276
716459
  }
716277
716460
  const messageText2 = extractFirstUserMessageText(messages);
716278
- const fingerprint2 = computeFingerprint(messageText2, "1.65.10");
716461
+ const fingerprint2 = computeFingerprint(messageText2, "1.65.11");
716279
716462
  const attributionHeader = getAttributionHeader(fingerprint2);
716280
716463
  const systemBlocks = [
716281
716464
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -721062,7 +721245,7 @@ function buildSystemInitMessage(inputs) {
721062
721245
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
721063
721246
  apiKeySource: getURHQApiKeyWithSource().source,
721064
721247
  betas: getSdkBetas(),
721065
- ur_version: "1.65.10",
721248
+ ur_version: "1.65.11",
721066
721249
  output_style: outputStyle2,
721067
721250
  agents: inputs.agents.map((agent2) => agent2.agentType),
721068
721251
  skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill2) => skill2.name),
@@ -722243,6 +722426,29 @@ var init_useNotifyAfterTimeout = __esm(() => {
722243
722426
  import_react196 = __toESM(require_react(), 1);
722244
722427
  });
722245
722428
 
722429
+ // src/components/permissions/AskUserQuestionPermissionRequest/prototypeSafeRecord.ts
722430
+ function createPrototypeSafeRecord() {
722431
+ return Object.create(null);
722432
+ }
722433
+ function clonePrototypeSafeRecord(source) {
722434
+ return Object.assign(Object.create(null), source);
722435
+ }
722436
+ function hasOwnRecordKey(record4, key) {
722437
+ return record4 !== null && record4 !== undefined && hasOwn2.call(record4, key);
722438
+ }
722439
+ function getOwnRecordValue(record4, key) {
722440
+ return hasOwnRecordKey(record4, key) ? record4[key] : undefined;
722441
+ }
722442
+ function setPrototypeSafeRecordValue(record4, key, value2) {
722443
+ const next = Object.assign(createPrototypeSafeRecord(), record4);
722444
+ next[key] = value2;
722445
+ return next;
722446
+ }
722447
+ var hasOwn2;
722448
+ var init_prototypeSafeRecord = __esm(() => {
722449
+ hasOwn2 = Object.prototype.hasOwnProperty;
722450
+ });
722451
+
722246
722452
  // src/components/permissions/AskUserQuestionPermissionRequest/QuestionNavigationBar.tsx
722247
722453
  function QuestionNavigationBar(t0) {
722248
722454
  const $2 = import_compiler_runtime262.c(39);
@@ -722350,7 +722556,7 @@ function QuestionNavigationBar(t0) {
722350
722556
  if ($2[22] !== answers || $2[23] !== currentQuestionIndex || $2[24] !== tabDisplayTexts) {
722351
722557
  t52 = (q_1, index_2) => {
722352
722558
  const isSelected = index_2 === currentQuestionIndex;
722353
- const isAnswered = q_1?.question && !!answers[q_1.question];
722559
+ const isAnswered = q_1?.question && !!getOwnRecordValue(answers, q_1.question);
722354
722560
  const checkbox = isAnswered ? figures_default.checkboxOn : figures_default.checkboxOff;
722355
722561
  const displayText = tabDisplayTexts[index_2] || q_1?.header || `Q${index_2 + 1}`;
722356
722562
  return /* @__PURE__ */ jsx_dev_runtime357.jsxDEV(ThemedBox_default, {
@@ -722472,6 +722678,7 @@ var init_QuestionNavigationBar = __esm(() => {
722472
722678
  init_stringWidth();
722473
722679
  init_ink2();
722474
722680
  init_format2();
722681
+ init_prototypeSafeRecord();
722475
722682
  import_compiler_runtime262 = __toESM(require_compiler_runtime(), 1);
722476
722683
  jsx_dev_runtime357 = __toESM(require_jsx_dev_runtime(), 1);
722477
722684
  });
@@ -722772,20 +722979,34 @@ function PreviewQuestionView({
722772
722979
  const editor = getExternalEditor();
722773
722980
  const editorName = editor ? toIDEDisplayName(editor) : null;
722774
722981
  const questionText = question.question;
722775
- const questionState = questionStates[questionText];
722982
+ const questionState = getOwnRecordValue(questionStates, questionText);
722776
722983
  const allOptions = question.options;
722984
+ const otherIndex = allOptions.length;
722985
+ const optionRowCount = allOptions.length + 1;
722777
722986
  const [focusedIndex, setFocusedIndex] = import_react198.useState(0);
722778
722987
  const prevQuestionText = import_react198.useRef(questionText);
722779
722988
  if (prevQuestionText.current !== questionText) {
722780
722989
  prevQuestionText.current = questionText;
722781
722990
  const selected = questionState?.selectedValue;
722782
- const idx = selected ? allOptions.findIndex((opt) => opt.label === selected) : -1;
722991
+ const idx = selected === PREVIEW_OTHER_VALUE ? otherIndex : selected ? allOptions.findIndex((opt) => opt.label === selected) : -1;
722783
722992
  setFocusedIndex(idx >= 0 ? idx : 0);
722784
722993
  }
722785
722994
  const focusedOption = allOptions[focusedIndex];
722995
+ const isOtherFocused = focusedIndex === otherIndex;
722786
722996
  const selectedValue = questionState?.selectedValue;
722787
722997
  const notesValue = questionState?.textInputValue || "";
722998
+ const otherInputValue = questionState?.otherInputValue || "";
722788
722999
  const handleSelectOption = import_react198.useCallback((index2) => {
723000
+ if (index2 === otherIndex) {
723001
+ setFocusedIndex(index2);
723002
+ onUpdateQuestionState(questionText, {
723003
+ selectedValue: PREVIEW_OTHER_VALUE
723004
+ }, false);
723005
+ onAnswer(questionText, PREVIEW_OTHER_VALUE, "", false);
723006
+ setIsInNotesInput(true);
723007
+ onTextInputFocus(true);
723008
+ return;
723009
+ }
722789
723010
  const option27 = allOptions[index2];
722790
723011
  if (!option27)
722791
723012
  return;
@@ -722794,7 +723015,7 @@ function PreviewQuestionView({
722794
723015
  selectedValue: option27.label
722795
723016
  }, false);
722796
723017
  onAnswer(questionText, option27.label);
722797
- }, [allOptions, questionText, onUpdateQuestionState, onAnswer]);
723018
+ }, [allOptions, otherIndex, questionText, onUpdateQuestionState, onAnswer, onTextInputFocus]);
722798
723019
  const handleNavigate = import_react198.useCallback((direction) => {
722799
723020
  if (isInNotesInput)
722800
723021
  return;
@@ -722804,18 +723025,18 @@ function PreviewQuestionView({
722804
723025
  } else if (direction === "up") {
722805
723026
  newIndex = focusedIndex > 0 ? focusedIndex - 1 : focusedIndex;
722806
723027
  } else {
722807
- newIndex = focusedIndex < allOptions.length - 1 ? focusedIndex + 1 : focusedIndex;
723028
+ newIndex = focusedIndex < optionRowCount - 1 ? focusedIndex + 1 : focusedIndex;
722808
723029
  }
722809
- if (newIndex >= 0 && newIndex < allOptions.length) {
723030
+ if (newIndex >= 0 && newIndex < optionRowCount) {
722810
723031
  setFocusedIndex(newIndex);
722811
723032
  }
722812
- }, [focusedIndex, allOptions.length, isInNotesInput]);
723033
+ }, [focusedIndex, optionRowCount, isInNotesInput]);
722813
723034
  useKeybinding("chat:externalEditor", async () => {
722814
- const currentValue = questionState?.textInputValue || "";
723035
+ const currentValue = isOtherFocused ? otherInputValue : notesValue;
722815
723036
  const result = await editPromptInEditor(currentValue);
722816
723037
  if (result.content !== null && result.content !== currentValue) {
722817
723038
  onUpdateQuestionState(questionText, {
722818
- textInputValue: result.content
723039
+ ...isOtherFocused ? { otherInputValue: result.content } : { textInputValue: result.content }
722819
723040
  }, false);
722820
723041
  }
722821
723042
  }, {
@@ -722832,10 +723053,17 @@ function PreviewQuestionView({
722832
723053
  const handleNotesExit = import_react198.useCallback(() => {
722833
723054
  setIsInNotesInput(false);
722834
723055
  onTextInputFocus(false);
722835
- if (selectedValue) {
723056
+ if (isOtherFocused) {
723057
+ const customAnswer = otherInputValue.trim();
723058
+ if (customAnswer) {
723059
+ onAnswer(questionText, PREVIEW_OTHER_VALUE, customAnswer);
723060
+ }
723061
+ return;
723062
+ }
723063
+ if (selectedValue && selectedValue !== PREVIEW_OTHER_VALUE) {
722836
723064
  onAnswer(questionText, selectedValue);
722837
723065
  }
722838
- }, [selectedValue, questionText, onAnswer, onTextInputFocus]);
723066
+ }, [isOtherFocused, otherInputValue, selectedValue, questionText, onAnswer, onTextInputFocus]);
722839
723067
  const handleDownFromPreview = import_react198.useCallback(() => {
722840
723068
  setIsFooterFocused(true);
722841
723069
  }, []);
@@ -722889,7 +723117,7 @@ function PreviewQuestionView({
722889
723117
  }
722890
723118
  } else if (e.key === "down" || e.ctrl && e.key === "n") {
722891
723119
  e.preventDefault();
722892
- if (focusedIndex === allOptions.length - 1) {
723120
+ if (focusedIndex === optionRowCount - 1) {
722893
723121
  handleDownFromPreview();
722894
723122
  } else {
722895
723123
  handleNavigate("down");
@@ -722899,6 +723127,11 @@ function PreviewQuestionView({
722899
723127
  handleSelectOption(focusedIndex);
722900
723128
  } else if (e.key === "n" && !e.ctrl && !e.meta) {
722901
723129
  e.preventDefault();
723130
+ if (isOtherFocused && selectedValue !== PREVIEW_OTHER_VALUE) {
723131
+ onUpdateQuestionState(questionText, {
723132
+ selectedValue: PREVIEW_OTHER_VALUE
723133
+ }, false);
723134
+ }
722902
723135
  setIsInNotesInput(true);
722903
723136
  onTextInputFocus(true);
722904
723137
  } else if (e.key === "escape") {
@@ -722907,12 +723140,13 @@ function PreviewQuestionView({
722907
723140
  } else if (e.key.length === 1 && e.key >= "1" && e.key <= "9") {
722908
723141
  e.preventDefault();
722909
723142
  const idx_0 = parseInt(e.key, 10) - 1;
722910
- if (idx_0 < allOptions.length) {
723143
+ if (idx_0 < optionRowCount) {
722911
723144
  handleNavigate(idx_0);
722912
723145
  }
722913
723146
  }
722914
- }, [isFooterFocused, footerIndex, isInPlanMode, isInNotesInput, focusedIndex, allOptions.length, handleUpFromFooter, handleDownFromPreview, handleNavigate, handleSelectOption, handleNotesExit, onRespondToUR, onFinishPlanInterview, onCancel, onTextInputFocus]);
722915
- const previewContent = focusedOption?.preview || null;
723147
+ }, [isFooterFocused, footerIndex, isInPlanMode, isInNotesInput, focusedIndex, optionRowCount, isOtherFocused, selectedValue, questionText, handleUpFromFooter, handleDownFromPreview, handleNavigate, handleSelectOption, handleNotesExit, onRespondToUR, onFinishPlanInterview, onCancel, onTextInputFocus, onUpdateQuestionState]);
723148
+ const previewContent = isOtherFocused ? "Enter a custom answer below." : focusedOption?.preview || null;
723149
+ const currentInputValue = isOtherFocused ? otherInputValue : notesValue;
722916
723150
  const LEFT_PANEL_WIDTH = 30;
722917
723151
  const GAP = 4;
722918
723152
  const {
@@ -722951,13 +723185,49 @@ function PreviewQuestionView({
722951
723185
  /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedBox_default, {
722952
723186
  flexDirection: "column",
722953
723187
  width: 30,
722954
- children: allOptions.map((option_0, index_0) => {
722955
- const isFocused = focusedIndex === index_0;
722956
- const isSelected = selectedValue === option_0.label;
722957
- return /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedBox_default, {
723188
+ children: [
723189
+ allOptions.map((option_0, index_0) => {
723190
+ const isFocused = focusedIndex === index_0;
723191
+ const isSelected = selectedValue === option_0.label;
723192
+ return /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedBox_default, {
723193
+ flexDirection: "row",
723194
+ children: [
723195
+ isFocused ? /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723196
+ color: "suggestion",
723197
+ children: figures_default.pointer
723198
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723199
+ children: " "
723200
+ }, undefined, false, undefined, this),
723201
+ /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723202
+ dimColor: true,
723203
+ children: [
723204
+ " ",
723205
+ index_0 + 1,
723206
+ "."
723207
+ ]
723208
+ }, undefined, true, undefined, this),
723209
+ /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723210
+ color: isSelected ? "success" : isFocused ? "suggestion" : undefined,
723211
+ bold: isFocused,
723212
+ children: [
723213
+ " ",
723214
+ option_0.label
723215
+ ]
723216
+ }, undefined, true, undefined, this),
723217
+ isSelected && /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723218
+ color: "success",
723219
+ children: [
723220
+ " ",
723221
+ figures_default.tick
723222
+ ]
723223
+ }, undefined, true, undefined, this)
723224
+ ]
723225
+ }, option_0.label, true, undefined, this);
723226
+ }),
723227
+ /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedBox_default, {
722958
723228
  flexDirection: "row",
722959
723229
  children: [
722960
- isFocused ? /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723230
+ isOtherFocused ? /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
722961
723231
  color: "suggestion",
722962
723232
  children: figures_default.pointer
722963
723233
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
@@ -722967,19 +723237,19 @@ function PreviewQuestionView({
722967
723237
  dimColor: true,
722968
723238
  children: [
722969
723239
  " ",
722970
- index_0 + 1,
723240
+ otherIndex + 1,
722971
723241
  "."
722972
723242
  ]
722973
723243
  }, undefined, true, undefined, this),
722974
723244
  /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
722975
- color: isSelected ? "success" : isFocused ? "suggestion" : undefined,
722976
- bold: isFocused,
723245
+ color: selectedValue === PREVIEW_OTHER_VALUE ? "success" : isOtherFocused ? "suggestion" : undefined,
723246
+ bold: isOtherFocused,
722977
723247
  children: [
722978
723248
  " ",
722979
- option_0.label
723249
+ "Other"
722980
723250
  ]
722981
723251
  }, undefined, true, undefined, this),
722982
- isSelected && /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723252
+ selectedValue === PREVIEW_OTHER_VALUE && /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
722983
723253
  color: "success",
722984
723254
  children: [
722985
723255
  " ",
@@ -722987,9 +723257,9 @@ function PreviewQuestionView({
722987
723257
  ]
722988
723258
  }, undefined, true, undefined, this)
722989
723259
  ]
722990
- }, option_0.label, true, undefined, this);
722991
- })
722992
- }, undefined, false, undefined, this),
723260
+ }, PREVIEW_OTHER_VALUE, true, undefined, this)
723261
+ ]
723262
+ }, undefined, true, undefined, this),
722993
723263
  /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedBox_default, {
722994
723264
  flexDirection: "column",
722995
723265
  flexGrow: 1,
@@ -723007,14 +723277,14 @@ function PreviewQuestionView({
723007
723277
  children: [
723008
723278
  /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723009
723279
  color: "suggestion",
723010
- children: "Notes:"
723280
+ children: isOtherFocused ? "Answer:" : "Notes:"
723011
723281
  }, undefined, false, undefined, this),
723012
723282
  isInNotesInput ? /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(TextInput, {
723013
- value: notesValue,
723014
- placeholder: "Add notes on this design\u2026",
723283
+ value: currentInputValue,
723284
+ placeholder: isOtherFocused ? "Type a custom answer\u2026" : "Add notes on this design\u2026",
723015
723285
  onChange: (value2) => {
723016
723286
  onUpdateQuestionState(questionText, {
723017
- textInputValue: value2
723287
+ ...isOtherFocused ? { otherInputValue: value2 } : { textInputValue: value2 }
723018
723288
  }, false);
723019
723289
  },
723020
723290
  onSubmit: handleNotesExit,
@@ -723027,7 +723297,7 @@ function PreviewQuestionView({
723027
723297
  }, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(ThemedText, {
723028
723298
  dimColor: true,
723029
723299
  italic: true,
723030
- children: notesValue || "press n to add notes"
723300
+ children: currentInputValue || (isOtherFocused ? "press Enter to type a custom answer" : "press n to add notes")
723031
723301
  }, undefined, false, undefined, this)
723032
723302
  ]
723033
723303
  }, undefined, true, undefined, this)
@@ -723086,7 +723356,8 @@ function PreviewQuestionView({
723086
723356
  figures_default.arrowUp,
723087
723357
  "/",
723088
723358
  figures_default.arrowDown,
723089
- " to navigate \xB7 n to add notes",
723359
+ " to navigate \xB7 n to edit ",
723360
+ isOtherFocused ? "answer" : "notes",
723090
723361
  questions.length > 1 && /* @__PURE__ */ jsx_dev_runtime359.jsxDEV(jsx_dev_runtime359.Fragment, {
723091
723362
  children: " \xB7 Tab to switch questions"
723092
723363
  }, undefined, false, undefined, this),
@@ -723107,7 +723378,7 @@ function PreviewQuestionView({
723107
723378
  }, undefined, true, undefined, this)
723108
723379
  }, undefined, false, undefined, this);
723109
723380
  }
723110
- var import_react198, jsx_dev_runtime359;
723381
+ var import_react198, jsx_dev_runtime359, PREVIEW_OTHER_VALUE = "__other__";
723111
723382
  var init_PreviewQuestionView = __esm(() => {
723112
723383
  init_figures();
723113
723384
  init_useTerminalSize();
@@ -723120,6 +723391,7 @@ var init_PreviewQuestionView = __esm(() => {
723120
723391
  init_Divider();
723121
723392
  init_TextInput();
723122
723393
  init_PreviewBox();
723394
+ init_prototypeSafeRecord();
723123
723395
  init_QuestionNavigationBar();
723124
723396
  import_react198 = __toESM(require_react(), 1);
723125
723397
  jsx_dev_runtime359 = __toESM(require_jsx_dev_runtime(), 1);
@@ -723153,6 +723425,7 @@ function QuestionView({
723153
723425
  const [isFooterFocused, setIsFooterFocused] = import_react199.useState(false);
723154
723426
  const [footerIndex, setFooterIndex] = import_react199.useState(0);
723155
723427
  const [isOtherFocused, setIsOtherFocused] = import_react199.useState(false);
723428
+ const questionState = getOwnRecordValue(questionStates, question.question);
723156
723429
  const editorName = import_react199.useMemo(() => {
723157
723430
  const editor = getExternalEditor();
723158
723431
  return editor ? toIDEDisplayName(editor) : null;
@@ -723216,7 +723489,7 @@ function QuestionView({
723216
723489
  }
723217
723490
  };
723218
723491
  const placeholder = question.multiSelect ? "Type something" : "Type something.";
723219
- const textInputValue = questionStates[question.question]?.textInputValue ?? "";
723492
+ const textInputValue = questionState?.textInputValue ?? "";
723220
723493
  return [
723221
723494
  ...textOptions,
723222
723495
  {
@@ -723231,7 +723504,7 @@ function QuestionView({
723231
723504
  onOpenEditor: handleOpenEditor
723232
723505
  }
723233
723506
  ];
723234
- }, [question, questionStates, onUpdateQuestionState]);
723507
+ }, [question, questionState, onUpdateQuestionState]);
723235
723508
  const hasAnyPreview = !question.multiSelect && question.options.some((opt) => opt.preview);
723236
723509
  if (hasAnyPreview) {
723237
723510
  return /* @__PURE__ */ jsx_dev_runtime360.jsxDEV(PreviewQuestionView, {
@@ -723294,10 +723567,10 @@ function QuestionView({
723294
723567
  marginTop: 1,
723295
723568
  children: question.multiSelect ? /* @__PURE__ */ jsx_dev_runtime360.jsxDEV(SelectMulti, {
723296
723569
  options: options4,
723297
- defaultValue: questionStates[question.question]?.selectedValue,
723570
+ defaultValue: questionState?.selectedValue,
723298
723571
  onChange: (values2) => {
723299
723572
  onUpdateQuestionState(question.question, { selectedValue: values2 }, true);
723300
- const textInput = values2.includes("__other__") ? questionStates[question.question]?.textInputValue : undefined;
723573
+ const textInput = values2.includes("__other__") ? questionState?.textInputValue : undefined;
723301
723574
  const finalValues = values2.filter((v) => v !== "__other__").concat(textInput ? [textInput] : []);
723302
723575
  onAnswer(question.question, finalValues, undefined, false);
723303
723576
  },
@@ -723312,10 +723585,10 @@ function QuestionView({
723312
723585
  onRemoveImage
723313
723586
  }, question.question, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime360.jsxDEV(Select, {
723314
723587
  options: options4,
723315
- defaultValue: questionStates[question.question]?.selectedValue,
723588
+ defaultValue: questionState?.selectedValue,
723316
723589
  onChange: (value2) => {
723317
723590
  onUpdateQuestionState(question.question, { selectedValue: value2 }, false);
723318
- const textInput = value2 === "__other__" ? questionStates[question.question]?.textInputValue : undefined;
723591
+ const textInput = value2 === "__other__" ? questionState?.textInputValue : undefined;
723319
723592
  onAnswer(question.question, value2, textInput);
723320
723593
  },
723321
723594
  onFocus: handleFocus,
@@ -723419,6 +723692,7 @@ var init_QuestionView = __esm(() => {
723419
723692
  init_FilePathLink();
723420
723693
  init_QuestionNavigationBar();
723421
723694
  init_PreviewQuestionView();
723695
+ init_prototypeSafeRecord();
723422
723696
  import_react199 = __toESM(require_react(), 1);
723423
723697
  jsx_dev_runtime360 = __toESM(require_jsx_dev_runtime(), 1);
723424
723698
  });
@@ -723590,8 +723864,8 @@ function SubmitQuestionsView({
723590
723864
  Object.keys(answers).length > 0 && /* @__PURE__ */ jsx_dev_runtime362.jsxDEV(ThemedBox_default, {
723591
723865
  flexDirection: "column",
723592
723866
  marginBottom: 1,
723593
- children: questions.filter((q) => q?.question && answers[q.question]).map((q) => {
723594
- const answer = answers[q.question];
723867
+ children: questions.filter((q) => q?.question && getOwnRecordValue(answers, q.question)).map((q) => {
723868
+ const answer = getOwnRecordValue(answers, q.question);
723595
723869
  return /* @__PURE__ */ jsx_dev_runtime362.jsxDEV(ThemedBox_default, {
723596
723870
  flexDirection: "column",
723597
723871
  marginLeft: 1,
@@ -723648,12 +723922,13 @@ var init_SubmitQuestionsView = __esm(() => {
723648
723922
  init_CustomSelect();
723649
723923
  init_Divider();
723650
723924
  init_PermissionRuleExplanation();
723925
+ init_prototypeSafeRecord();
723651
723926
  init_QuestionNavigationBar();
723652
723927
  jsx_dev_runtime362 = __toESM(require_jsx_dev_runtime(), 1);
723653
723928
  });
723654
723929
 
723655
723930
  // src/components/permissions/AskUserQuestionPermissionRequest/use-multiple-choice-state.ts
723656
- function reducer2(state2, action3) {
723931
+ function multipleChoiceReducer(state2, action3) {
723657
723932
  switch (action3.type) {
723658
723933
  case "next-question":
723659
723934
  return {
@@ -723668,26 +723943,21 @@ function reducer2(state2, action3) {
723668
723943
  isInTextInput: false
723669
723944
  };
723670
723945
  case "update-question-state": {
723671
- const existing2 = state2.questionStates[action3.questionText];
723946
+ const existing2 = getOwnRecordValue(state2.questionStates, action3.questionText);
723672
723947
  const newState = {
723673
723948
  selectedValue: action3.updates.selectedValue ?? existing2?.selectedValue ?? (action3.isMultiSelect ? [] : undefined),
723674
- textInputValue: action3.updates.textInputValue ?? existing2?.textInputValue ?? ""
723949
+ textInputValue: action3.updates.textInputValue ?? existing2?.textInputValue ?? "",
723950
+ otherInputValue: action3.updates.otherInputValue ?? existing2?.otherInputValue ?? ""
723675
723951
  };
723676
723952
  return {
723677
723953
  ...state2,
723678
- questionStates: {
723679
- ...state2.questionStates,
723680
- [action3.questionText]: newState
723681
- }
723954
+ questionStates: setPrototypeSafeRecordValue(state2.questionStates, action3.questionText, newState)
723682
723955
  };
723683
723956
  }
723684
723957
  case "set-answer": {
723685
723958
  const newState = {
723686
723959
  ...state2,
723687
- answers: {
723688
- ...state2.answers,
723689
- [action3.questionText]: action3.answer
723690
- }
723960
+ answers: setPrototypeSafeRecordValue(state2.answers, action3.questionText, action3.answer)
723691
723961
  };
723692
723962
  if (action3.shouldAdvance) {
723693
723963
  return {
@@ -723705,8 +723975,16 @@ function reducer2(state2, action3) {
723705
723975
  };
723706
723976
  }
723707
723977
  }
723978
+ function createInitialMultipleChoiceState() {
723979
+ return {
723980
+ currentQuestionIndex: 0,
723981
+ answers: createPrototypeSafeRecord(),
723982
+ questionStates: createPrototypeSafeRecord(),
723983
+ isInTextInput: false
723984
+ };
723985
+ }
723708
723986
  function useMultipleChoiceState() {
723709
- const [state2, dispatch5] = import_react200.useReducer(reducer2, INITIAL_STATE2);
723987
+ const [state2, dispatch5] = import_react200.useReducer(multipleChoiceReducer, createInitialMultipleChoiceState());
723710
723988
  const nextQuestion = import_react200.useCallback(() => {
723711
723989
  dispatch5({ type: "next-question" });
723712
723990
  }, []);
@@ -723744,18 +724022,22 @@ function useMultipleChoiceState() {
723744
724022
  setTextInputMode
723745
724023
  };
723746
724024
  }
723747
- var import_react200, INITIAL_STATE2;
724025
+ var import_react200;
723748
724026
  var init_use_multiple_choice_state = __esm(() => {
724027
+ init_prototypeSafeRecord();
723749
724028
  import_react200 = __toESM(require_react(), 1);
723750
- INITIAL_STATE2 = {
723751
- currentQuestionIndex: 0,
723752
- answers: {},
723753
- questionStates: {},
723754
- isInTextInput: false
723755
- };
723756
724029
  });
723757
724030
 
723758
724031
  // src/components/permissions/AskUserQuestionPermissionRequest/AskUserQuestionPermissionRequest.tsx
724032
+ function resolveQuestionAnswer(label, textInput, hasImages) {
724033
+ if (Array.isArray(label))
724034
+ return label.join(", ");
724035
+ if (textInput)
724036
+ return hasImages ? `${textInput} (Image attached)` : textInput;
724037
+ if (label === "__other__")
724038
+ return hasImages ? "(Image attached)" : "";
724039
+ return label;
724040
+ }
723759
724041
  function AskUserQuestionPermissionRequest(props) {
723760
724042
  const settings = useSettings();
723761
724043
  if (settings.syntaxHighlightingDisabled) {
@@ -723818,7 +724100,7 @@ function AskUserQuestionPermissionRequestBody({
723818
724100
  }
723819
724101
  }
723820
724102
  const rightPanelHeight = maxPreviewBoxHeight + 2;
723821
- const leftPanelHeight = q.options.length + 2;
724103
+ const leftPanelHeight = q.options.length + 3;
723822
724104
  const sideByHeight = Math.max(leftPanelHeight, rightPanelHeight);
723823
724105
  maxHeight = Math.max(maxHeight, sideByHeight + 7);
723824
724106
  } else {
@@ -723827,7 +724109,7 @@ function AskUserQuestionPermissionRequestBody({
723827
724109
  }
723828
724110
  const globalContentHeight = Math.min(Math.max(maxHeight, MIN_CONTENT_HEIGHT), maxAllowedHeight);
723829
724111
  const globalContentWidth = Math.max(maxWidth, MIN_CONTENT_WIDTH);
723830
- const [pastedContentsByQuestion, setPastedContentsByQuestion] = import_react201.useState({});
724112
+ const [pastedContentsByQuestion, setPastedContentsByQuestion] = import_react201.useState(() => createPrototypeSafeRecord());
723831
724113
  const nextPasteIdRef = import_react201.useRef(0);
723832
724114
  const onImagePaste = import_react201.useCallback((questionText, base64Image, mediaType, filename, dimensions, _sourcePath) => {
723833
724115
  nextPasteIdRef.current += 1;
@@ -723842,22 +724124,19 @@ function AskUserQuestionPermissionRequestBody({
723842
724124
  };
723843
724125
  cacheImagePath(newContent);
723844
724126
  storeImage(newContent);
723845
- setPastedContentsByQuestion((prev) => ({
723846
- ...prev,
723847
- [questionText]: {
723848
- ...prev[questionText] ?? {},
723849
- [pasteId]: newContent
723850
- }
723851
- }));
724127
+ setPastedContentsByQuestion((prev) => {
724128
+ const previousQuestionContents = getOwnRecordValue(prev, questionText);
724129
+ const questionContents = previousQuestionContents ? clonePrototypeSafeRecord(previousQuestionContents) : Object.create(null);
724130
+ questionContents[pasteId] = newContent;
724131
+ return setPrototypeSafeRecordValue(prev, questionText, questionContents);
724132
+ });
723852
724133
  }, []);
723853
724134
  const onRemoveImage = import_react201.useCallback((questionText, id) => {
723854
724135
  setPastedContentsByQuestion((prev) => {
723855
- const questionContents = { ...prev[questionText] ?? {} };
724136
+ const previousQuestionContents = getOwnRecordValue(prev, questionText);
724137
+ const questionContents = previousQuestionContents ? clonePrototypeSafeRecord(previousQuestionContents) : Object.create(null);
723856
724138
  delete questionContents[id];
723857
- return {
723858
- ...prev,
723859
- [questionText]: questionContents
723860
- };
724139
+ return setPrototypeSafeRecordValue(prev, questionText, questionContents);
723861
724140
  });
723862
724141
  }, []);
723863
724142
  const allImageAttachments = import_react201.useMemo(() => Object.values(pastedContentsByQuestion).flatMap(Object.values).filter((c4) => c4.type === "image"), [pastedContentsByQuestion]);
@@ -723875,7 +724154,7 @@ function AskUserQuestionPermissionRequestBody({
723875
724154
  } = state2;
723876
724155
  const currentQuestion = currentQuestionIndex < (questions?.length || 0) ? questions?.[currentQuestionIndex] : null;
723877
724156
  const isInSubmitView = currentQuestionIndex === (questions?.length || 0);
723878
- const allQuestionsAnswered = questions?.every((q) => q?.question && !!answers[q.question]) ?? false;
724157
+ const allQuestionsAnswered = questions?.every((q) => q?.question && !!getOwnRecordValue(answers, q.question)) ?? false;
723879
724158
  const hideSubmitTab = questions.length === 1 && !questions[0]?.multiSelect;
723880
724159
  const handleCancel = import_react201.useCallback(() => {
723881
724160
  if (metadataSource) {
@@ -723892,7 +724171,7 @@ function AskUserQuestionPermissionRequestBody({
723892
724171
  }, [metadataSource, questions.length, isInPlanMode, onDone, onReject, toolUseConfirm]);
723893
724172
  const handleRespondToUR = import_react201.useCallback(async () => {
723894
724173
  const questionsWithAnswers = questions.map((q) => {
723895
- const answer = answers[q.question];
724174
+ const answer = getOwnRecordValue(answers, q.question);
723896
724175
  if (answer) {
723897
724176
  return `- "${q.question}"
723898
724177
  Answer: ${answer}`;
@@ -723922,7 +724201,7 @@ ${questionsWithAnswers}`;
723922
724201
  }, [allImageAttachments, answers, isInPlanMode, metadataSource, onDone, questions, toolUseConfirm]);
723923
724202
  const handleFinishPlanInterview = import_react201.useCallback(async () => {
723924
724203
  const questionsWithAnswers = questions.map((q) => {
723925
- const answer = answers[q.question];
724204
+ const answer = getOwnRecordValue(answers, q.question);
723926
724205
  if (answer) {
723927
724206
  return `- "${q.question}"
723928
724207
  Answer: ${answer}`;
@@ -723958,10 +724237,13 @@ ${questionsWithAnswers}`;
723958
724237
  interviewPhaseEnabled: isInPlanMode && isPlanModeInterviewPhaseEnabled()
723959
724238
  });
723960
724239
  }
723961
- const annotations = {};
724240
+ const annotations = createPrototypeSafeRecord();
723962
724241
  for (const q of questions) {
723963
- const answer = answersToSubmit[q.question];
723964
- const notes = questionStates[q.question]?.textInputValue;
724242
+ const answer = getOwnRecordValue(answersToSubmit, q.question);
724243
+ const questionState = getOwnRecordValue(questionStates, q.question);
724244
+ const selectedValue = questionState?.selectedValue;
724245
+ const selectedOther = selectedValue === "__other__" || Array.isArray(selectedValue) && selectedValue.includes("__other__");
724246
+ const notes = selectedOther ? undefined : questionState?.textInputValue;
723965
724247
  const selectedOption = answer ? q.options.find((opt) => opt.label === answer) : undefined;
723966
724248
  const preview6 = selectedOption?.preview;
723967
724249
  if (preview6 || notes?.trim()) {
@@ -723982,21 +724264,11 @@ ${questionsWithAnswers}`;
723982
724264
  }, [allImageAttachments, isInPlanMode, metadataSource, onDone, questionStates, questions, toolUseConfirm]);
723983
724265
  const handleQuestionAnswer = import_react201.useCallback((questionText, label, textInput, shouldAdvance = true) => {
723984
724266
  const isMultiSelect = Array.isArray(label);
723985
- let answer;
723986
- if (isMultiSelect) {
723987
- answer = label.join(", ");
723988
- } else if (textInput) {
723989
- const questionImages = Object.values(pastedContentsByQuestion[questionText] ?? {}).filter((c4) => c4.type === "image");
723990
- answer = questionImages.length > 0 ? `${textInput} (Image attached)` : textInput;
723991
- } else if (label === "__other__") {
723992
- const questionImages = Object.values(pastedContentsByQuestion[questionText] ?? {}).filter((c4) => c4.type === "image");
723993
- answer = questionImages.length > 0 ? "(Image attached)" : label;
723994
- } else {
723995
- answer = label;
723996
- }
724267
+ const hasImages = Object.values(getOwnRecordValue(pastedContentsByQuestion, questionText) ?? {}).some((content) => content.type === "image");
724268
+ const answer = resolveQuestionAnswer(label, textInput, hasImages);
723997
724269
  const isSingleQuestion = questions.length === 1;
723998
- if (!isMultiSelect && isSingleQuestion && shouldAdvance) {
723999
- const updatedAnswers = { ...answers, [questionText]: answer };
724270
+ if (!isMultiSelect && isSingleQuestion && shouldAdvance && answer) {
724271
+ const updatedAnswers = setPrototypeSafeRecordValue(answers, questionText, answer);
724000
724272
  submitAnswers(updatedAnswers).catch(logError2);
724001
724273
  return;
724002
724274
  }
@@ -724030,7 +724302,7 @@ ${questionsWithAnswers}`;
724030
724302
  isActive: !(isInTextInput && !isInSubmitView)
724031
724303
  });
724032
724304
  if (currentQuestion) {
724033
- const pastedContents = pastedContentsByQuestion[currentQuestion.question] ?? {};
724305
+ const pastedContents = getOwnRecordValue(pastedContentsByQuestion, currentQuestion.question) ?? Object.create(null);
724034
724306
  return /* @__PURE__ */ jsx_dev_runtime363.jsxDEV(PermissionDialog, {
724035
724307
  title: currentQuestion.question,
724036
724308
  onCancel: handleCancel,
@@ -724113,6 +724385,7 @@ var init_AskUserQuestionPermissionRequest = __esm(() => {
724113
724385
  init_planModeV2();
724114
724386
  init_plans();
724115
724387
  init_PermissionDialog();
724388
+ init_prototypeSafeRecord();
724116
724389
  init_QuestionView();
724117
724390
  init_SubmitQuestionsView();
724118
724391
  init_use_multiple_choice_state();
@@ -734923,7 +735196,7 @@ var init_useVoiceEnabled = __esm(() => {
734923
735196
  function getSemverPart(version3) {
734924
735197
  return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
734925
735198
  }
734926
- function useUpdateNotification(updatedVersion, initialVersion = "1.65.10") {
735199
+ function useUpdateNotification(updatedVersion, initialVersion = "1.65.11") {
734927
735200
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react222.useState(() => getSemverPart(initialVersion));
734928
735201
  if (!updatedVersion) {
734929
735202
  return null;
@@ -734972,7 +735245,7 @@ function AutoUpdater({
734972
735245
  return;
734973
735246
  }
734974
735247
  if (false) {}
734975
- const currentVersion = "1.65.10";
735248
+ const currentVersion = "1.65.11";
734976
735249
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
734977
735250
  let latestVersion = await getLatestVersion(channel);
734978
735251
  const isDisabled = isAutoUpdaterDisabled();
@@ -735201,12 +735474,12 @@ function NativeAutoUpdater({
735201
735474
  logEvent("tengu_native_auto_updater_start", {});
735202
735475
  try {
735203
735476
  const maxVersion = await getMaxVersion();
735204
- if (maxVersion && gt("1.65.10", maxVersion)) {
735477
+ if (maxVersion && gt("1.65.11", maxVersion)) {
735205
735478
  const msg = await getMaxVersionMessage();
735206
735479
  setMaxVersionIssue(msg ?? "affects your version");
735207
735480
  }
735208
735481
  const result = await installLatest(channel);
735209
- const currentVersion = "1.65.10";
735482
+ const currentVersion = "1.65.11";
735210
735483
  const latencyMs = Date.now() - startTime;
735211
735484
  if (result.lockFailed) {
735212
735485
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -735343,17 +735616,17 @@ function PackageManagerAutoUpdater(t0) {
735343
735616
  const maxVersion = await getMaxVersion();
735344
735617
  if (maxVersion && latest && gt(latest, maxVersion)) {
735345
735618
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
735346
- if (gte("1.65.10", maxVersion)) {
735347
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.65.10"} is already at or above maxVersion ${maxVersion}, skipping update`);
735619
+ if (gte("1.65.11", maxVersion)) {
735620
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.65.11"} is already at or above maxVersion ${maxVersion}, skipping update`);
735348
735621
  setUpdateAvailable(false);
735349
735622
  return;
735350
735623
  }
735351
735624
  latest = maxVersion;
735352
735625
  }
735353
- const hasUpdate = latest && !gte("1.65.10", latest) && !shouldSkipVersion(latest);
735626
+ const hasUpdate = latest && !gte("1.65.11", latest) && !shouldSkipVersion(latest);
735354
735627
  setUpdateAvailable(!!hasUpdate);
735355
735628
  if (hasUpdate) {
735356
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.65.10"} -> ${latest}`);
735629
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.65.11"} -> ${latest}`);
735357
735630
  }
735358
735631
  };
735359
735632
  $2[0] = t1;
@@ -735387,7 +735660,7 @@ function PackageManagerAutoUpdater(t0) {
735387
735660
  wrap: "truncate",
735388
735661
  children: [
735389
735662
  "currentVersion: ",
735390
- "1.65.10"
735663
+ "1.65.11"
735391
735664
  ]
735392
735665
  }, undefined, true, undefined, this);
735393
735666
  $2[3] = verbose;
@@ -746107,7 +746380,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
746107
746380
  project_dir: getOriginalCwd(),
746108
746381
  added_dirs: addedDirs
746109
746382
  },
746110
- version: "1.65.10",
746383
+ version: "1.65.11",
746111
746384
  output_style: {
746112
746385
  name: outputStyleName
746113
746386
  },
@@ -746185,7 +746458,7 @@ function StatusLineInner({
746185
746458
  const taskValues = Object.values(tasks2);
746186
746459
  const taskRunningCount = countActiveBackgroundTasks(taskValues);
746187
746460
  const defaultStatusLineText = buildDefaultStatusBar({
746188
- version: "1.65.10",
746461
+ version: "1.65.11",
746189
746462
  providerLabel: providerRuntime.providerLabel,
746190
746463
  authMode: providerRuntime.authLabel,
746191
746464
  model: renderModelName(mainLoopModel) || providerRuntime.model || "",
@@ -747208,7 +747481,7 @@ var init_ghPrStatus = __esm(() => {
747208
747481
 
747209
747482
  // src/hooks/usePrStatus.ts
747210
747483
  function usePrStatus(isLoading, enabled = true) {
747211
- const [prStatus, setPrStatus] = import_react248.useState(INITIAL_STATE3);
747484
+ const [prStatus, setPrStatus] = import_react248.useState(INITIAL_STATE2);
747212
747485
  const timeoutRef = import_react248.useRef(null);
747213
747486
  const disabledRef = import_react248.useRef(false);
747214
747487
  const lastFetchRef = import_react248.useRef(0);
@@ -747272,13 +747545,13 @@ function usePrStatus(isLoading, enabled = true) {
747272
747545
  }, [isLoading, enabled]);
747273
747546
  return prStatus;
747274
747547
  }
747275
- var import_react248, POLL_INTERVAL_MS3 = 60000, SLOW_GH_THRESHOLD_MS = 4000, IDLE_STOP_MS, INITIAL_STATE3;
747548
+ var import_react248, POLL_INTERVAL_MS3 = 60000, SLOW_GH_THRESHOLD_MS = 4000, IDLE_STOP_MS, INITIAL_STATE2;
747276
747549
  var init_usePrStatus = __esm(() => {
747277
747550
  init_state();
747278
747551
  init_ghPrStatus();
747279
747552
  import_react248 = __toESM(require_react(), 1);
747280
747553
  IDLE_STOP_MS = 60 * 60000;
747281
- INITIAL_STATE3 = {
747554
+ INITIAL_STATE2 = {
747282
747555
  number: null,
747283
747556
  url: null,
747284
747557
  reviewState: null,
@@ -758365,7 +758638,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
758365
758638
  } catch {}
758366
758639
  const data = {
758367
758640
  trigger: trigger2,
758368
- version: "1.65.10",
758641
+ version: "1.65.11",
758369
758642
  platform: process.platform,
758370
758643
  transcript,
758371
758644
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -770730,7 +771003,7 @@ function WelcomeV2() {
770730
771003
  dimColor: true,
770731
771004
  children: [
770732
771005
  "v",
770733
- "1.65.10"
771006
+ "1.65.11"
770734
771007
  ]
770735
771008
  }, undefined, true, undefined, this)
770736
771009
  ]
@@ -771990,7 +772263,7 @@ function completeOnboarding() {
771990
772263
  saveGlobalConfig((current) => ({
771991
772264
  ...current,
771992
772265
  hasCompletedOnboarding: true,
771993
- lastOnboardingVersion: "1.65.10"
772266
+ lastOnboardingVersion: "1.65.11"
771994
772267
  }));
771995
772268
  }
771996
772269
  function showDialog(root2, renderer) {
@@ -777034,7 +777307,7 @@ function appendToLog(path24, message) {
777034
777307
  cwd: getFsImplementation().cwd(),
777035
777308
  userType: process.env.USER_TYPE,
777036
777309
  sessionId: getSessionId(),
777037
- version: "1.65.10"
777310
+ version: "1.65.11"
777038
777311
  };
777039
777312
  getLogWriter(path24).write(messageWithTimestamp);
777040
777313
  }
@@ -781198,8 +781471,8 @@ async function getEnvLessBridgeConfig() {
781198
781471
  }
781199
781472
  async function checkEnvLessBridgeMinVersion() {
781200
781473
  const cfg = await getEnvLessBridgeConfig();
781201
- if (cfg.min_version && lt("1.65.10", cfg.min_version)) {
781202
- return `Your version of UR (${"1.65.10"}) is too old for Remote Control.
781474
+ if (cfg.min_version && lt("1.65.11", cfg.min_version)) {
781475
+ return `Your version of UR (${"1.65.11"}) is too old for Remote Control.
781203
781476
  Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
781204
781477
  }
781205
781478
  return null;
@@ -781673,7 +781946,7 @@ async function initBridgeCore(params) {
781673
781946
  const rawApi = createBridgeApiClient({
781674
781947
  baseUrl,
781675
781948
  getAccessToken,
781676
- runnerVersion: "1.65.10",
781949
+ runnerVersion: "1.65.11",
781677
781950
  onDebug: logForDebugging,
781678
781951
  onAuth401,
781679
781952
  getTrustedDeviceToken
@@ -791146,7 +791419,7 @@ function getAgUiCapabilities() {
791146
791419
  name: "UR-Nexus",
791147
791420
  type: "ur-nexus",
791148
791421
  description: "Provider-flexible, local-first autonomous engineering workflow agent.",
791149
- version: "1.65.10",
791422
+ version: "1.65.11",
791150
791423
  provider: "UR",
791151
791424
  documentationUrl: "https://github.com/Maitham16/UR/blob/master/docs/AG_UI.md"
791152
791425
  },
@@ -792286,7 +792559,7 @@ function createMCPServer(cwd4, debug2, verbose) {
792286
792559
  };
792287
792560
  const server2 = new Server({
792288
792561
  name: "ur-nexus",
792289
- version: "1.65.10"
792562
+ version: "1.65.11"
792290
792563
  }, {
792291
792564
  capabilities: {
792292
792565
  tools: {}
@@ -793444,7 +793717,7 @@ function thrownResponse(error40) {
793444
793717
  }
793445
793718
  async function createUrMcp2026Runtime(options4) {
793446
793719
  const server2 = createMCPServer(options4.cwd, options4.debug === true, options4.verbose === true);
793447
- const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.65.10" }, { capabilities: {} });
793720
+ const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.65.11" }, { capabilities: {} });
793448
793721
  const [clientTransport, serverTransport] = createLinkedTransportPair();
793449
793722
  try {
793450
793723
  await server2.connect(serverTransport);
@@ -793455,7 +793728,7 @@ async function createUrMcp2026Runtime(options4) {
793455
793728
  }
793456
793729
  const runtime2 = new Mcp2026Runtime({
793457
793730
  cwd: options4.cwd,
793458
- version: "1.65.10",
793731
+ version: "1.65.11",
793459
793732
  backend: {
793460
793733
  listTools: async () => {
793461
793734
  const listed = await client2.listTools();
@@ -795588,7 +795861,7 @@ async function update() {
795588
795861
  logEvent("tengu_update_check", {});
795589
795862
  const diagnostic2 = await getDoctorDiagnostic();
795590
795863
  const result = await checkUpgradeStatus({
795591
- currentVersion: "1.65.10",
795864
+ currentVersion: "1.65.11",
795592
795865
  packageName: UR_AGENT_PACKAGE_NAME,
795593
795866
  installationType: diagnostic2.installationType,
795594
795867
  latestVersion: () => getLatestNpmPackageVersion(UR_AGENT_PACKAGE_NAME)
@@ -796904,7 +797177,7 @@ ${customInstructions}` : customInstructions;
796904
797177
  }
796905
797178
  }
796906
797179
  logForDiagnosticsNoPII("info", "started", {
796907
- version: "1.65.10",
797180
+ version: "1.65.11",
796908
797181
  is_native_binary: isInBundledMode()
796909
797182
  });
796910
797183
  registerCleanup(async () => {
@@ -797690,7 +797963,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
797690
797963
  pendingHookMessages
797691
797964
  }, renderAndRun);
797692
797965
  }
797693
- }).version("1.65.10 (UR-Nexus)", "-v, --version", "Output the version number");
797966
+ }).version("1.65.11 (UR-Nexus)", "-v, --version", "Output the version number");
797694
797967
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
797695
797968
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
797696
797969
  if (canUserConfigureAdvisor()) {
@@ -798749,7 +799022,7 @@ if (false) {}
798749
799022
  async function main2() {
798750
799023
  const args = process.argv.slice(2);
798751
799024
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
798752
- console.log(`${"1.65.10"} (UR-Nexus)`);
799025
+ console.log(`${"1.65.11"} (UR-Nexus)`);
798753
799026
  return;
798754
799027
  }
798755
799028
  if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {