ur-agent 1.80.2 → 1.80.4

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
@@ -107784,7 +107784,7 @@ var init_auth = __esm(() => {
107784
107784
 
107785
107785
  // src/utils/userAgent.ts
107786
107786
  function getURCodeUserAgent() {
107787
- return `ur/${"1.80.2"}`;
107787
+ return `ur/${"1.80.4"}`;
107788
107788
  }
107789
107789
 
107790
107790
  // src/utils/workloadContext.ts
@@ -107806,7 +107806,7 @@ function getUserAgent() {
107806
107806
  const clientApp = process.env.UR_AGENT_SDK_CLIENT_APP ? `, client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}` : "";
107807
107807
  const workload = getWorkload();
107808
107808
  const workloadSuffix = workload ? `, workload/${workload}` : "";
107809
- return `ur-cli/${"1.80.2"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
107809
+ return `ur-cli/${"1.80.4"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
107810
107810
  }
107811
107811
  function getMCPUserAgent() {
107812
107812
  const parts = [];
@@ -107820,7 +107820,7 @@ function getMCPUserAgent() {
107820
107820
  parts.push(`client-app/${process.env.UR_AGENT_SDK_CLIENT_APP}`);
107821
107821
  }
107822
107822
  const suffix = parts.length > 0 ? ` (${parts.join(", ")})` : "";
107823
- return `ur/${"1.80.2"}${suffix}`;
107823
+ return `ur/${"1.80.4"}${suffix}`;
107824
107824
  }
107825
107825
  function getWebFetchUserAgent() {
107826
107826
  return `UR-User (${getURCodeUserAgent()})`;
@@ -107958,7 +107958,7 @@ var init_user = __esm(() => {
107958
107958
  deviceId,
107959
107959
  sessionId: getSessionId(),
107960
107960
  email: getEmail(),
107961
- appVersion: "1.80.2",
107961
+ appVersion: "1.80.4",
107962
107962
  platform: getHostPlatformForAnalytics(),
107963
107963
  organizationUuid,
107964
107964
  accountUuid,
@@ -115845,7 +115845,7 @@ var init_metadata = __esm(() => {
115845
115845
  COMPOUND_OPERATOR_REGEX = /\s*(?:&&|\|\||[;|])\s*/;
115846
115846
  WHITESPACE_REGEX = /\s+/;
115847
115847
  getVersionBase = memoize_default(() => {
115848
- const match = "1.80.2".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
115848
+ const match = "1.80.4".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
115849
115849
  return match ? match[0] : undefined;
115850
115850
  });
115851
115851
  buildEnvContext = memoize_default(async () => {
@@ -115885,7 +115885,7 @@ var init_metadata = __esm(() => {
115885
115885
  isGithubAction: isEnvTruthy(process.env.GITHUB_ACTIONS),
115886
115886
  isURCodeAction: isEnvTruthy(process.env.UR_CODE_ACTION),
115887
115887
  isURAiAuth: isURAISubscriber(),
115888
- version: "1.80.2",
115888
+ version: "1.80.4",
115889
115889
  versionBase: getVersionBase(),
115890
115890
  buildTime: "",
115891
115891
  deploymentEnvironment: env2.detectDeploymentEnvironment(),
@@ -116555,7 +116555,7 @@ function initialize1PEventLogging() {
116555
116555
  const platform2 = getPlatform();
116556
116556
  const attributes = {
116557
116557
  [import_semantic_conventions4.ATTR_SERVICE_NAME]: "ur",
116558
- [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.80.2"
116558
+ [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.80.4"
116559
116559
  };
116560
116560
  if (platform2 === "wsl") {
116561
116561
  const wslVersion = getWslVersion();
@@ -116583,7 +116583,7 @@ function initialize1PEventLogging() {
116583
116583
  })
116584
116584
  ]
116585
116585
  });
116586
- firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.80.2");
116586
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.80.4");
116587
116587
  }
116588
116588
  async function reinitialize1PEventLoggingIfConfigChanged() {
116589
116589
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -119068,7 +119068,7 @@ var init_types2 = __esm(() => {
119068
119068
  requireBeforeChanges: exports_external.object({
119069
119069
  enabled: exports_external.boolean().optional(),
119070
119070
  freeReads: exports_external.number().optional()
119071
- }).optional().describe("Require a task list before any tool that changes the workspace (Edit, Write, Bash, ...). " + "Reads are never blocked, so the agent can investigate before planning; freeReads is how many " + "tool calls may run before the gate applies at all. Set enabled=false to make the task list advisory again.")
119071
+ }).optional().describe("Require a task list before any tool that changes the workspace (Edit, Write, Bash, ...). " + "The default strict-hybrid policy enforces classified multi-step, risky, delegated, and release work " + "while allowing positively classified atomic changes to proceed directly. Reads are never blocked. " + "Set freeReads=0 to require a task before every mutation, or enabled=false to make task tracking advisory.")
119072
119072
  }).optional().describe("Task list behaviour."),
119073
119073
  context: exports_external.object({
119074
119074
  pruneToolResults: exports_external.object({
@@ -126304,6 +126304,7 @@ var init_a2aCardSignature = () => {};
126304
126304
  var exports_trends = {};
126305
126305
  __export(exports_trends, {
126306
126306
  formatAgentTrendReport: () => formatAgentTrendReport,
126307
+ formatA2AV1AgentCard: () => formatA2AV1AgentCard,
126307
126308
  formatA2AAgentCard: () => formatA2AAgentCard,
126308
126309
  buildAgentTrendReport: () => buildAgentTrendReport,
126309
126310
  buildA2AV1AgentCard: () => buildA2AV1AgentCard,
@@ -126542,7 +126543,10 @@ function formatAgentTrendReport(report = buildAgentTrendReport()) {
126542
126543
  function formatA2AAgentCard(options = {}, pretty = true) {
126543
126544
  return JSON.stringify(buildA2AAgentCard(options), null, pretty ? 2 : 0);
126544
126545
  }
126545
- var urVersion = "1.80.2", researchSnapshotDate = "2026-08-10", coverage, priorityRoadmap;
126546
+ function formatA2AV1AgentCard(options = {}, pretty = true) {
126547
+ return JSON.stringify(buildA2AV1AgentCard(options), null, pretty ? 2 : 0);
126548
+ }
126549
+ var urVersion = "1.80.4", researchSnapshotDate = "2026-08-10", coverage, priorityRoadmap;
126546
126550
  var init_trends = __esm(() => {
126547
126551
  init_a2aCardSignature();
126548
126552
  coverage = [
@@ -129432,7 +129436,7 @@ function getAttributionHeader(fingerprint) {
129432
129436
  if (!isAttributionHeaderEnabled()) {
129433
129437
  return "";
129434
129438
  }
129435
- const version2 = `${"1.80.2"}.${fingerprint}`;
129439
+ const version2 = `${"1.80.4"}.${fingerprint}`;
129436
129440
  const entrypoint = process.env.UR_CODE_ENTRYPOINT ?? "unknown";
129437
129441
  const cch = "";
129438
129442
  const workload = getWorkload();
@@ -168090,6 +168094,7 @@ Usage notes:
168090
168094
  - When using fetched content in your final answer, mention the fetched URL or domain as the source
168091
168095
  - Results may be summarized if the content is very large
168092
168096
  - Includes a self-cleaning 15-minute cache for faster responses when repeatedly accessing the same URL
168097
+ - A permanent HTTP 4xx response means the URL cannot be fetched as written. Do not retry that URL with the same or a different prompt; use WebSearch, fetch a parent/index page, or choose another source.
168093
168098
  - When a URL redirects to a different host, the tool will inform you and provide the redirect URL in a special format. You should then make a new WebFetch request with the redirect URL to fetch the content.
168094
168099
  - For GitHub URLs, prefer using the gh CLI via Bash instead (e.g., gh pr view, gh issue view, gh api).
168095
168100
  `;
@@ -184625,7 +184630,7 @@ var init_projectSafety = __esm(() => {
184625
184630
  function getInstruments() {
184626
184631
  if (instruments)
184627
184632
  return instruments;
184628
- const meter = import_api10.metrics.getMeter("ur-agent.gen_ai", "1.80.2");
184633
+ const meter = import_api10.metrics.getMeter("ur-agent.gen_ai", "1.80.4");
184629
184634
  instruments = {
184630
184635
  operationDuration: meter.createHistogram("gen_ai.client.operation.duration", {
184631
184636
  description: "GenAI operation duration.",
@@ -184723,7 +184728,7 @@ function genAiAgentAttributes() {
184723
184728
  "gen_ai.operation.name": GEN_AI_OPERATION_INVOKE_AGENT,
184724
184729
  "gen_ai.provider.name": "ur",
184725
184730
  "gen_ai.agent.name": "UR-Nexus",
184726
- "gen_ai.agent.version": "1.80.2"
184731
+ "gen_ai.agent.version": "1.80.4"
184727
184732
  };
184728
184733
  }
184729
184734
  function genAiWorkflowAttributes(workflowName, workflowRunId) {
@@ -184744,7 +184749,7 @@ function genAiWorkflowAttributes(workflowName, workflowRunId) {
184744
184749
  function startGenAiWorkflowSpan(workflowName, workflowRunId) {
184745
184750
  const attributes = genAiWorkflowAttributes(workflowName, workflowRunId);
184746
184751
  const name = typeof attributes["gen_ai.workflow.name"] === "string" ? `invoke_workflow ${attributes["gen_ai.workflow.name"]}` : GEN_AI_OPERATION_INVOKE_WORKFLOW;
184747
- return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.2").startSpan(name, { kind: import_api10.SpanKind.INTERNAL, attributes });
184752
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.4").startSpan(name, { kind: import_api10.SpanKind.INTERNAL, attributes });
184748
184753
  }
184749
184754
  function endGenAiWorkflowSpan(span, options2 = {}) {
184750
184755
  try {
@@ -184782,7 +184787,7 @@ function startGenAiMemorySpan(operation, options2 = {}) {
184782
184787
  if (options2.recordCount !== undefined && Number.isInteger(options2.recordCount) && options2.recordCount >= 0) {
184783
184788
  attributes["gen_ai.memory.record.count"] = options2.recordCount;
184784
184789
  }
184785
- return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.2").startSpan(operation, { kind: import_api10.SpanKind.INTERNAL, attributes });
184790
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.4").startSpan(operation, { kind: import_api10.SpanKind.INTERNAL, attributes });
184786
184791
  }
184787
184792
  function endGenAiMemorySpan(span, options2 = {}) {
184788
184793
  try {
@@ -278497,7 +278502,7 @@ function getTelemetryAttributes() {
278497
278502
  attributes["session.id"] = sessionId;
278498
278503
  }
278499
278504
  if (shouldIncludeAttribute("OTEL_METRICS_INCLUDE_VERSION")) {
278500
- attributes["app.version"] = "1.80.2";
278505
+ attributes["app.version"] = "1.80.4";
278501
278506
  }
278502
278507
  const oauthAccount = getOauthAccountInfo();
278503
278508
  if (oauthAccount) {
@@ -319488,7 +319493,7 @@ function getInstallationEnv() {
319488
319493
  return;
319489
319494
  }
319490
319495
  function getURCodeVersion() {
319491
- return "1.80.2";
319496
+ return "1.80.4";
319492
319497
  }
319493
319498
  async function getInstalledVSCodeExtensionVersion(command) {
319494
319499
  const { stdout } = await execFileNoThrow(command, ["--list-extensions", "--show-versions"], {
@@ -326858,7 +326863,7 @@ async function setupSdkMcpClients(sdkMcpConfigs, sendMcpMessage) {
326858
326863
  const client2 = new Client({
326859
326864
  name: "ur",
326860
326865
  title: "UR",
326861
- version: "1.80.2",
326866
+ version: "1.80.4",
326862
326867
  description: "UR-Nexus autonomous engineering workflow engine",
326863
326868
  websiteUrl: PRODUCT_URL
326864
326869
  }, {
@@ -327219,7 +327224,7 @@ var init_client5 = __esm(() => {
327219
327224
  const client2 = new Client({
327220
327225
  name: "ur",
327221
327226
  title: "UR",
327222
- version: "1.80.2",
327227
+ version: "1.80.4",
327223
327228
  description: "UR-Nexus autonomous engineering workflow engine",
327224
327229
  websiteUrl: PRODUCT_URL
327225
327230
  }, {
@@ -339957,7 +339962,7 @@ async function createRuntime() {
339957
339962
  bootstrapTelemetry();
339958
339963
  const resource = defaultResource().merge(detectResources({ detectors: [envDetector] })).merge(resourceFromAttributes({
339959
339964
  [import_semantic_conventions7.ATTR_SERVICE_NAME]: "ur-agent",
339960
- [import_semantic_conventions7.ATTR_SERVICE_VERSION]: "1.80.2"
339965
+ [import_semantic_conventions7.ATTR_SERVICE_VERSION]: "1.80.4"
339961
339966
  }));
339962
339967
  const tracerProvider = exporters.traces.length > 0 ? new BasicTracerProvider({
339963
339968
  resource,
@@ -339990,11 +339995,11 @@ async function createRuntime() {
339990
339995
  setMeterProvider(meterProvider);
339991
339996
  setLoggerProvider(loggerProvider);
339992
339997
  if (meterProvider) {
339993
- const meter = meterProvider.getMeter("ur-agent", "1.80.2");
339998
+ const meter = meterProvider.getMeter("ur-agent", "1.80.4");
339994
339999
  setMeter(meter, (name, options2) => meter.createCounter(name, options2));
339995
340000
  }
339996
340001
  if (loggerProvider) {
339997
- setEventLogger(loggerProvider.getLogger("ur-agent.events", "1.80.2"));
340002
+ setEventLogger(loggerProvider.getLogger("ur-agent.events", "1.80.4"));
339998
340003
  }
339999
340004
  if (!cleanupRegistered3) {
340000
340005
  cleanupRegistered3 = true;
@@ -340656,9 +340661,9 @@ async function assertMinVersion() {
340656
340661
  if (false) {}
340657
340662
  try {
340658
340663
  const versionConfig = await getDynamicConfig_BLOCKS_ON_INIT("tengu_version_config", { minVersion: "0.0.0" });
340659
- if (versionConfig.minVersion && lt("1.80.2", versionConfig.minVersion)) {
340664
+ if (versionConfig.minVersion && lt("1.80.4", versionConfig.minVersion)) {
340660
340665
  console.error(`
340661
- It looks like your version of UR (${"1.80.2"}) needs an update.
340666
+ It looks like your version of UR (${"1.80.4"}) needs an update.
340662
340667
  A newer version (${versionConfig.minVersion} or higher) is required to continue.
340663
340668
 
340664
340669
  To update, please run:
@@ -340874,7 +340879,7 @@ async function installGlobalPackage(specificVersion) {
340874
340879
  logError2(new AutoUpdaterError("Another process is currently installing an update"));
340875
340880
  logEvent("tengu_auto_updater_lock_contention", {
340876
340881
  pid: process.pid,
340877
- currentVersion: "1.80.2"
340882
+ currentVersion: "1.80.4"
340878
340883
  });
340879
340884
  return "in_progress";
340880
340885
  }
@@ -340883,7 +340888,7 @@ async function installGlobalPackage(specificVersion) {
340883
340888
  if (!env2.isRunningWithBun() && env2.isNpmFromWindowsPath()) {
340884
340889
  logError2(new Error("Windows NPM detected in WSL environment"));
340885
340890
  logEvent("tengu_auto_updater_windows_npm_in_wsl", {
340886
- currentVersion: "1.80.2"
340891
+ currentVersion: "1.80.4"
340887
340892
  });
340888
340893
  console.error(`
340889
340894
  Error: Windows NPM detected in WSL
@@ -341418,7 +341423,7 @@ function detectLinuxGlobPatternWarnings() {
341418
341423
  }
341419
341424
  async function getDoctorDiagnostic() {
341420
341425
  const installationType = await getCurrentInstallationType();
341421
- const version2 = typeof MACRO !== "undefined" ? "1.80.2" : "unknown";
341426
+ const version2 = typeof MACRO !== "undefined" ? "1.80.4" : "unknown";
341422
341427
  const installationPath = await getInstallationPath();
341423
341428
  const invokedBinary = getInvokedBinary();
341424
341429
  const multipleInstallations = await detectMultipleInstallations();
@@ -342353,8 +342358,8 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
342353
342358
  const maxVersion = await getMaxVersion();
342354
342359
  if (maxVersion && gt(version2, maxVersion)) {
342355
342360
  logForDebugging(`Native installer: maxVersion ${maxVersion} is set, capping update from ${version2} to ${maxVersion}`);
342356
- if (gte("1.80.2", maxVersion)) {
342357
- logForDebugging(`Native installer: current version ${"1.80.2"} is already at or above maxVersion ${maxVersion}, skipping update`);
342361
+ if (gte("1.80.4", maxVersion)) {
342362
+ logForDebugging(`Native installer: current version ${"1.80.4"} is already at or above maxVersion ${maxVersion}, skipping update`);
342358
342363
  logEvent("tengu_native_update_skipped_max_version", {
342359
342364
  latency_ms: Date.now() - startTime,
342360
342365
  max_version: maxVersion,
@@ -342365,7 +342370,7 @@ async function updateLatest(channelOrVersion, forceReinstall = false) {
342365
342370
  version2 = maxVersion;
342366
342371
  }
342367
342372
  }
342368
- if (!forceReinstall && version2 === "1.80.2" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
342373
+ if (!forceReinstall && version2 === "1.80.4" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
342369
342374
  logForDebugging(`Found ${version2} at ${executablePath}, skipping install`);
342370
342375
  logEvent("tengu_native_update_complete", {
342371
342376
  latency_ms: Date.now() - startTime,
@@ -391965,100 +391970,281 @@ var init_preapproved = __esm(() => {
391965
391970
  })());
391966
391971
  });
391967
391972
 
391968
- // src/tools/WebFetchTool/UI.tsx
391969
- function renderToolUseMessage15({
391970
- url: url3,
391971
- prompt
391972
- }, {
391973
- verbose
391974
- }) {
391975
- if (!url3) {
391976
- return null;
391973
+ // src/utils/messagePredicates.ts
391974
+ function isHumanTurn(m) {
391975
+ return m.type === "user" && !m.isMeta && m.toolUseResult === undefined;
391976
+ }
391977
+
391978
+ // src/services/tools/repeatedFailureGuard.ts
391979
+ import { createHash as createHash30 } from "crypto";
391980
+ function writeFramedText(hash3, value) {
391981
+ hash3.update(`${value.length}:`);
391982
+ for (let offset = 0;offset < value.length; ) {
391983
+ const end = Math.min(offset + HASH_CHUNK_CODE_UNITS, value.length);
391984
+ hash3.update(value.slice(offset, end), "utf16le");
391985
+ offset = end;
391977
391986
  }
391978
- if (verbose) {
391979
- return `url: "${url3}"${verbose && prompt ? `, prompt: "${prompt}"` : ""}`;
391987
+ }
391988
+ function writeToken(hash3, kind, value = "") {
391989
+ writeFramedText(hash3, kind);
391990
+ writeFramedText(hash3, value);
391991
+ }
391992
+ function visitCanonical(value, state, depth) {
391993
+ state.nodesVisited++;
391994
+ if (state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes || depth > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalDepth) {
391995
+ throw new CanonicalTraversalLimitError;
391996
+ }
391997
+ if (value === null) {
391998
+ writeToken(state.hash, "null");
391999
+ return;
392000
+ }
392001
+ switch (typeof value) {
392002
+ case "string":
392003
+ state.textCodeUnitsVisited += value.length;
392004
+ if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
392005
+ throw new CanonicalTraversalLimitError;
392006
+ }
392007
+ writeToken(state.hash, "string", value);
392008
+ return;
392009
+ case "number":
392010
+ writeToken(state.hash, "number", Object.is(value, -0) ? "-0" : String(value));
392011
+ return;
392012
+ case "boolean":
392013
+ writeToken(state.hash, "boolean", String(value));
392014
+ return;
392015
+ case "undefined":
392016
+ writeToken(state.hash, "undefined");
392017
+ return;
392018
+ case "bigint":
392019
+ writeToken(state.hash, "bigint", value.toString());
392020
+ return;
392021
+ case "symbol": {
392022
+ const description = String(value.description ?? "");
392023
+ state.textCodeUnitsVisited += description.length;
392024
+ if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
392025
+ throw new CanonicalTraversalLimitError;
392026
+ }
392027
+ writeToken(state.hash, "symbol", description);
392028
+ return;
392029
+ }
392030
+ case "function": {
392031
+ const name = value.name || "<anonymous>";
392032
+ state.textCodeUnitsVisited += name.length;
392033
+ if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
392034
+ throw new CanonicalTraversalLimitError;
392035
+ }
392036
+ writeToken(state.hash, "function", name);
392037
+ return;
392038
+ }
392039
+ case "object": {
392040
+ const object4 = value;
392041
+ const existingReference = state.seen.get(object4);
392042
+ if (existingReference !== undefined) {
392043
+ writeToken(state.hash, "reference", String(existingReference));
392044
+ return;
392045
+ }
392046
+ const reference = state.nextReference++;
392047
+ state.seen.set(object4, reference);
392048
+ if (Array.isArray(value)) {
392049
+ if (value.length + state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes) {
392050
+ throw new CanonicalTraversalLimitError;
392051
+ }
392052
+ writeToken(state.hash, "array", String(value.length));
392053
+ for (let index2 = 0;index2 < value.length; index2++) {
392054
+ if (!(index2 in value)) {
392055
+ writeToken(state.hash, "hole");
392056
+ continue;
392057
+ }
392058
+ visitCanonical(value[index2], state, depth + 1);
392059
+ }
392060
+ return;
392061
+ }
392062
+ const record3 = value;
392063
+ const keys2 = Object.keys(record3);
392064
+ if (keys2.length + state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes) {
392065
+ throw new CanonicalTraversalLimitError;
392066
+ }
392067
+ keys2.sort();
392068
+ writeToken(state.hash, "object", String(keys2.length));
392069
+ for (const key of keys2) {
392070
+ state.textCodeUnitsVisited += key.length;
392071
+ if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
392072
+ throw new CanonicalTraversalLimitError;
392073
+ }
392074
+ writeToken(state.hash, "key", key);
392075
+ visitCanonical(record3[key], state, depth + 1);
392076
+ }
392077
+ return;
392078
+ }
391980
392079
  }
391981
- return url3;
391982
392080
  }
391983
- function renderToolUseProgressMessage8() {
391984
- return /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(MessageResponse, {
391985
- height: 1,
391986
- children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
391987
- dimColor: true,
391988
- children: "Fetching\u2026"
391989
- }, undefined, false, undefined, this)
391990
- }, undefined, false, undefined, this);
392081
+ function digestText(domain2, value) {
392082
+ const hash3 = createHash30("sha256");
392083
+ writeToken(hash3, "domain", domain2);
392084
+ writeToken(hash3, "value", value);
392085
+ return hash3.digest("hex");
391991
392086
  }
391992
- function renderToolResultMessage14({
391993
- bytes,
391994
- code,
391995
- codeText,
391996
- result
391997
- }, _progressMessagesForMessage, {
391998
- verbose
391999
- }) {
392000
- const formattedSize = formatFileSize(bytes);
392001
- if (verbose) {
392002
- return /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedBox_default, {
392003
- flexDirection: "column",
392004
- children: [
392005
- /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(MessageResponse, {
392006
- height: 1,
392007
- children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392008
- children: [
392009
- "Received ",
392010
- /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392011
- bold: true,
392012
- children: formattedSize
392013
- }, undefined, false, undefined, this),
392014
- " (",
392015
- code,
392016
- " ",
392017
- codeText,
392018
- ")"
392019
- ]
392020
- }, undefined, true, undefined, this)
392021
- }, undefined, false, undefined, this),
392022
- /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedBox_default, {
392023
- flexDirection: "column",
392024
- children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392025
- children: result
392026
- }, undefined, false, undefined, this)
392027
- }, undefined, false, undefined, this)
392028
- ]
392029
- }, undefined, true, undefined, this);
392087
+ function canonicalInputDigest(input) {
392088
+ const hash3 = createHash30("sha256");
392089
+ writeToken(hash3, "domain", "repeated-failure-input-v2");
392090
+ visitCanonical(input, {
392091
+ hash: hash3,
392092
+ nextReference: 0,
392093
+ nodesVisited: 0,
392094
+ textCodeUnitsVisited: 0,
392095
+ seen: new WeakMap
392096
+ }, 0);
392097
+ return hash3.digest("hex");
392098
+ }
392099
+ function uniqueSerializationFailureDigest() {
392100
+ serializationFailureNonce++;
392101
+ return digestText("repeated-failure-unserializable-v2", serializationFailureNonce.toString());
392102
+ }
392103
+ function scopeDigest(scope) {
392104
+ return scope ? digestText("repeated-failure-scope-v2", scope) : UNSCOPED_DIGEST;
392105
+ }
392106
+ function callSignature(toolName, input, scope) {
392107
+ let inputDigest;
392108
+ try {
392109
+ inputDigest = canonicalInputDigest(input);
392110
+ } catch {
392111
+ inputDigest = uniqueSerializationFailureDigest();
392030
392112
  }
392031
- return /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(MessageResponse, {
392032
- height: 1,
392033
- children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392034
- children: [
392035
- "Received ",
392036
- /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392037
- bold: true,
392038
- children: formattedSize
392039
- }, undefined, false, undefined, this),
392040
- " (",
392041
- code,
392042
- " ",
392043
- codeText,
392044
- ")"
392045
- ]
392046
- }, undefined, true, undefined, this)
392047
- }, undefined, false, undefined, this);
392113
+ return [
392114
+ SIGNATURE_VERSION,
392115
+ scopeDigest(scope),
392116
+ digestText("repeated-failure-tool-v2", toolName),
392117
+ inputDigest
392118
+ ].join(":");
392048
392119
  }
392049
- function getToolUseSummary6(input) {
392050
- if (!input?.url) {
392051
- return null;
392120
+ function isSha256Digest(value) {
392121
+ return value?.length === SHA256_HEX_LENGTH && /^[0-9a-f]+$/.test(value);
392122
+ }
392123
+ function signatureStorageIdentity(signature) {
392124
+ if (signature.length === UNSCOPED_SIGNATURE_LENGTH || signature.length === SCOPED_SIGNATURE_LENGTH) {
392125
+ const parts = signature.split(":");
392126
+ if (parts.length === 4 && parts[0] === SIGNATURE_VERSION && (parts[1] === UNSCOPED_DIGEST || isSha256Digest(parts[1])) && isSha256Digest(parts[2]) && isSha256Digest(parts[3])) {
392127
+ return { key: signature, scope: parts[1] };
392128
+ }
392052
392129
  }
392053
- return truncate3(input.url, TOOL_SUMMARY_MAX_LENGTH);
392130
+ return {
392131
+ key: `${SIGNATURE_VERSION}:legacy:${digestText("repeated-failure-legacy-signature-v2", signature)}`,
392132
+ scope: UNSCOPED_DIGEST
392133
+ };
392054
392134
  }
392055
- var jsx_dev_runtime140;
392056
- var init_UI14 = __esm(() => {
392057
- init_MessageResponse();
392058
- init_toolLimits();
392059
- init_ink2();
392060
- init_format2();
392061
- jsx_dev_runtime140 = __toESM(require_jsx_dev_runtime(), 1);
392135
+ function pruneExpiredFailures(now5) {
392136
+ for (const [signature, record3] of failureCounts) {
392137
+ if (now5 >= record3.lastFailureAt && now5 - record3.lastFailureAt >= REPEATED_FAILURE_GUARD_LIMITS.entryTtlMs) {
392138
+ failureCounts.delete(signature);
392139
+ }
392140
+ }
392141
+ }
392142
+ function enforceFailureBounds(scope) {
392143
+ let entriesInScope = 0;
392144
+ for (const record3 of failureCounts.values()) {
392145
+ if (record3.scopeDigest === scope)
392146
+ entriesInScope++;
392147
+ }
392148
+ let scopeOverflow = entriesInScope - REPEATED_FAILURE_GUARD_LIMITS.maxEntriesPerScope;
392149
+ if (scopeOverflow > 0) {
392150
+ for (const [signature, record3] of failureCounts) {
392151
+ if (record3.scopeDigest !== scope)
392152
+ continue;
392153
+ failureCounts.delete(signature);
392154
+ scopeOverflow--;
392155
+ if (scopeOverflow === 0)
392156
+ break;
392157
+ }
392158
+ }
392159
+ while (failureCounts.size > REPEATED_FAILURE_GUARD_LIMITS.maxEntries) {
392160
+ const oldest = failureCounts.keys().next().value;
392161
+ if (oldest === undefined)
392162
+ break;
392163
+ failureCounts.delete(oldest);
392164
+ }
392165
+ }
392166
+ function recordCallFailure(signature) {
392167
+ const now5 = repeatedFailureNow();
392168
+ pruneExpiredFailures(now5);
392169
+ const identity5 = signatureStorageIdentity(signature);
392170
+ const existing2 = failureCounts.get(identity5.key);
392171
+ const next = (existing2?.failures ?? 0) + 1;
392172
+ const signatureScope = existing2?.scopeDigest ?? identity5.scope;
392173
+ failureCounts.delete(identity5.key);
392174
+ failureCounts.set(identity5.key, {
392175
+ failures: next,
392176
+ lastFailureAt: now5,
392177
+ scopeDigest: signatureScope
392178
+ });
392179
+ enforceFailureBounds(signatureScope);
392180
+ return next;
392181
+ }
392182
+ function recordCallSuccess(signature) {
392183
+ failureCounts.delete(signatureStorageIdentity(signature).key);
392184
+ }
392185
+ function clearRepeatedFailuresForScope(scope) {
392186
+ const target = scopeDigest(scope);
392187
+ let cleared = 0;
392188
+ for (const [signature, record3] of failureCounts) {
392189
+ if (record3.scopeDigest !== target)
392190
+ continue;
392191
+ failureCounts.delete(signature);
392192
+ cleared++;
392193
+ }
392194
+ return cleared;
392195
+ }
392196
+ function clearRepeatedFailuresForQuery(queryChainId) {
392197
+ return clearRepeatedFailuresForScope(`query:${queryChainId}`);
392198
+ }
392199
+ function checkRepeatedFailure(signature, config3 = REPEATED_FAILURE_DEFAULTS) {
392200
+ if (!config3.enabled)
392201
+ return { action: "allow" };
392202
+ const now5 = repeatedFailureNow();
392203
+ pruneExpiredFailures(now5);
392204
+ const failures = failureCounts.get(signatureStorageIdentity(signature).key)?.failures ?? 0;
392205
+ if (failures >= config3.abortAfter) {
392206
+ return {
392207
+ action: "abort",
392208
+ reason: `This exact call has failed ${failures} times and is still being ` + `repeated. Stopping the turn rather than continuing to loop.`
392209
+ };
392210
+ }
392211
+ if (failures >= config3.limit) {
392212
+ return {
392213
+ action: "refuse",
392214
+ reason: `This exact call has already failed ${failures} times with the same ` + `arguments, so it will fail again. Do not retry it unchanged. Either ` + `fix the arguments, use a different tool, or tell the user what is ` + `blocking you and stop.`
392215
+ };
392216
+ }
392217
+ return { action: "allow" };
392218
+ }
392219
+ var REPEATED_FAILURE_DEFAULTS, REPEATED_FAILURE_GUARD_LIMITS, SIGNATURE_VERSION = "rf2", UNSCOPED_DIGEST = "-", SHA256_HEX_LENGTH = 64, HASH_CHUNK_CODE_UNITS, UNSCOPED_SIGNATURE_LENGTH, SCOPED_SIGNATURE_LENGTH, failureCounts, serializationFailureNonce = 0n, repeatedFailureNow, CanonicalTraversalLimitError, RepeatedToolFailureAbort;
392220
+ var init_repeatedFailureGuard = __esm(() => {
392221
+ REPEATED_FAILURE_DEFAULTS = {
392222
+ enabled: false,
392223
+ limit: 3,
392224
+ abortAfter: 6
392225
+ };
392226
+ REPEATED_FAILURE_GUARD_LIMITS = {
392227
+ maxEntries: 2048,
392228
+ maxEntriesPerScope: 256,
392229
+ entryTtlMs: 30 * 60 * 1000,
392230
+ maxCanonicalNodes: 50000,
392231
+ maxCanonicalDepth: 128,
392232
+ maxCanonicalTextCodeUnits: 1e6
392233
+ };
392234
+ HASH_CHUNK_CODE_UNITS = 16 * 1024;
392235
+ UNSCOPED_SIGNATURE_LENGTH = SIGNATURE_VERSION.length + 3 + 1 + SHA256_HEX_LENGTH * 2;
392236
+ SCOPED_SIGNATURE_LENGTH = SIGNATURE_VERSION.length + 3 + SHA256_HEX_LENGTH * 3;
392237
+ failureCounts = new Map;
392238
+ repeatedFailureNow = Date.now;
392239
+ CanonicalTraversalLimitError = class CanonicalTraversalLimitError extends Error {
392240
+ };
392241
+ RepeatedToolFailureAbort = class RepeatedToolFailureAbort extends Error {
392242
+ constructor(message) {
392243
+ super(message);
392244
+ this.name = "RepeatedToolFailureAbort";
392245
+ Object.setPrototypeOf(this, new.target.prototype);
392246
+ }
392247
+ };
392062
392248
  });
392063
392249
 
392064
392250
  // src/tools/WebFetchTool/utils.ts
@@ -392068,6 +392254,7 @@ __export(exports_utils2, {
392068
392254
  isPrivateAddress: () => isPrivateAddress,
392069
392255
  isPreapprovedUrl: () => isPreapprovedUrl,
392070
392256
  isPermittedRedirect: () => isPermittedRedirect,
392257
+ isPermanentWebFetchStatus: () => isPermanentWebFetchStatus,
392071
392258
  getWithPermittedRedirects: () => getWithPermittedRedirects,
392072
392259
  getURLMarkdownContent: () => getURLMarkdownContent,
392073
392260
  clearWebFetchCache: () => clearWebFetchCache,
@@ -392075,10 +392262,14 @@ __export(exports_utils2, {
392075
392262
  assertPublicUrl: () => assertPublicUrl,
392076
392263
  applyPromptToMarkdown: () => applyPromptToMarkdown,
392077
392264
  UnsafeUrlError: () => UnsafeUrlError,
392265
+ PermanentWebFetchHttpError: () => PermanentWebFetchHttpError,
392078
392266
  MAX_MARKDOWN_LENGTH: () => MAX_MARKDOWN_LENGTH
392079
392267
  });
392080
392268
  import { lookup } from "dns/promises";
392081
392269
  import { isIP as isIP6 } from "net";
392270
+ function isPermanentWebFetchStatus(status) {
392271
+ return status >= 400 && status < 500 && ![408, 409, 425, 429].includes(status);
392272
+ }
392082
392273
  function clearWebFetchCache() {
392083
392274
  URL_CACHE.clear();
392084
392275
  DOMAIN_CHECK_CACHE.clear();
@@ -392273,6 +392464,9 @@ async function getWithPermittedRedirects(url3, signal, redirectChecker, depth =
392273
392464
  const hostname3 = new URL(url3).hostname;
392274
392465
  throw new EgressBlockedError(hostname3);
392275
392466
  }
392467
+ if (axios_default.isAxiosError(error40) && error40.response && isPermanentWebFetchStatus(error40.response.status)) {
392468
+ throw new PermanentWebFetchHttpError(error40.response.status);
392469
+ }
392276
392470
  throw error40;
392277
392471
  }
392278
392472
  }
@@ -392402,7 +392596,7 @@ async function applyPromptToMarkdown(prompt, markdownContent, signal, isNonInter
392402
392596
  }
392403
392597
  return "No response from model";
392404
392598
  }
392405
- var DomainBlockedError, DomainCheckFailedError, EgressBlockedError, UnsafeUrlError, CACHE_TTL_MS2, MAX_CACHE_SIZE_BYTES, URL_CACHE, DOMAIN_CHECK_CACHE, turndownServicePromise, MAX_URL_LENGTH = 2000, MAX_HTTP_CONTENT_LENGTH = 10485760, FETCH_TIMEOUT_MS3 = 60000, MAX_REDIRECTS = 10, MAX_MARKDOWN_LENGTH = 1e5;
392599
+ var DomainBlockedError, DomainCheckFailedError, EgressBlockedError, UnsafeUrlError, PermanentWebFetchHttpError, CACHE_TTL_MS2, MAX_CACHE_SIZE_BYTES, URL_CACHE, DOMAIN_CHECK_CACHE, turndownServicePromise, MAX_URL_LENGTH = 2000, MAX_HTTP_CONTENT_LENGTH = 10485760, FETCH_TIMEOUT_MS3 = 60000, MAX_REDIRECTS = 10, MAX_MARKDOWN_LENGTH = 1e5;
392406
392600
  var init_utils11 = __esm(() => {
392407
392601
  init_axios2();
392408
392602
  init_index_min();
@@ -392444,6 +392638,15 @@ var init_utils11 = __esm(() => {
392444
392638
  this.name = "UnsafeUrlError";
392445
392639
  }
392446
392640
  };
392641
+ PermanentWebFetchHttpError = class PermanentWebFetchHttpError extends Error {
392642
+ status;
392643
+ constructor(status) {
392644
+ super(`WebFetch received permanent HTTP ${status}. Do not retry this URL unchanged, even with a different prompt. Use WebSearch, fetch a parent/index page, or choose another source.`);
392645
+ this.status = status;
392646
+ this.name = "PermanentWebFetchHttpError";
392647
+ Object.setPrototypeOf(this, new.target.prototype);
392648
+ }
392649
+ };
392447
392650
  CACHE_TTL_MS2 = 15 * 60 * 1000;
392448
392651
  MAX_CACHE_SIZE_BYTES = 50 * 1024 * 1024;
392449
392652
  URL_CACHE = new I({
@@ -392456,6 +392659,164 @@ var init_utils11 = __esm(() => {
392456
392659
  });
392457
392660
  });
392458
392661
 
392662
+ // src/tools/WebFetchTool/permanentFailureCircuit.ts
392663
+ function normalizedFailureUrl(url3) {
392664
+ try {
392665
+ const parsed = new URL(url3);
392666
+ if (parsed.protocol === "http:")
392667
+ parsed.protocol = "https:";
392668
+ parsed.hash = "";
392669
+ return parsed.toString();
392670
+ } catch {
392671
+ return url3;
392672
+ }
392673
+ }
392674
+ function webFetchPermanentFailureScope(context5) {
392675
+ if (context5.queryTracking?.chainId) {
392676
+ return `query:${context5.queryTracking.chainId}`;
392677
+ }
392678
+ const latestHumanTurn = context5.messages.findLast(isHumanTurn)?.uuid;
392679
+ return `session:${getSessionId()}:agent:${context5.agentId ?? "main"}:` + `turn:${latestHumanTurn ?? "untracked"}`;
392680
+ }
392681
+ function webFetchPermanentFailureSignature(scope, url3) {
392682
+ return callSignature("WebFetchPermanentURL", { url: normalizedFailureUrl(url3) }, scope);
392683
+ }
392684
+ function circuitMessage(decision) {
392685
+ const recovery = "Do not fetch this URL again in this turn, even with a different prompt. " + "Use WebSearch, fetch a parent/index page, or choose another source.";
392686
+ if (decision.action === "abort") {
392687
+ return `Repeated permanent WebFetch failure. ${recovery} Stopping the turn instead of continuing the loop.`;
392688
+ }
392689
+ return `WebFetch circuit breaker: this URL already returned a permanent HTTP client error. ${recovery}`;
392690
+ }
392691
+ async function withWebFetchPermanentFailureCircuit(url3, scope, operation) {
392692
+ const signature = webFetchPermanentFailureSignature(scope, url3);
392693
+ const decision = checkRepeatedFailure(signature, WEB_FETCH_PERMANENT_FAILURE_POLICY);
392694
+ if (decision.action === "abort") {
392695
+ throw new RepeatedToolFailureAbort(circuitMessage(decision));
392696
+ }
392697
+ if (decision.action === "refuse") {
392698
+ recordCallFailure(signature);
392699
+ throw new Error(circuitMessage(decision));
392700
+ }
392701
+ try {
392702
+ const result = await operation();
392703
+ recordCallSuccess(signature);
392704
+ return result;
392705
+ } catch (error40) {
392706
+ if (error40 instanceof PermanentWebFetchHttpError) {
392707
+ recordCallFailure(signature);
392708
+ }
392709
+ throw error40;
392710
+ }
392711
+ }
392712
+ var WEB_FETCH_PERMANENT_FAILURE_POLICY;
392713
+ var init_permanentFailureCircuit = __esm(() => {
392714
+ init_state();
392715
+ init_repeatedFailureGuard();
392716
+ init_utils11();
392717
+ WEB_FETCH_PERMANENT_FAILURE_POLICY = {
392718
+ enabled: true,
392719
+ limit: 1,
392720
+ abortAfter: 2
392721
+ };
392722
+ });
392723
+
392724
+ // src/tools/WebFetchTool/UI.tsx
392725
+ function renderToolUseMessage15({
392726
+ url: url3,
392727
+ prompt
392728
+ }, {
392729
+ verbose
392730
+ }) {
392731
+ if (!url3) {
392732
+ return null;
392733
+ }
392734
+ if (verbose) {
392735
+ return `url: "${url3}"${verbose && prompt ? `, prompt: "${prompt}"` : ""}`;
392736
+ }
392737
+ return url3;
392738
+ }
392739
+ function renderToolUseProgressMessage8() {
392740
+ return /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(MessageResponse, {
392741
+ height: 1,
392742
+ children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392743
+ dimColor: true,
392744
+ children: "Fetching\u2026"
392745
+ }, undefined, false, undefined, this)
392746
+ }, undefined, false, undefined, this);
392747
+ }
392748
+ function renderToolResultMessage14({
392749
+ bytes,
392750
+ code,
392751
+ codeText,
392752
+ result
392753
+ }, _progressMessagesForMessage, {
392754
+ verbose
392755
+ }) {
392756
+ const formattedSize = formatFileSize(bytes);
392757
+ if (verbose) {
392758
+ return /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedBox_default, {
392759
+ flexDirection: "column",
392760
+ children: [
392761
+ /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(MessageResponse, {
392762
+ height: 1,
392763
+ children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392764
+ children: [
392765
+ "Received ",
392766
+ /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392767
+ bold: true,
392768
+ children: formattedSize
392769
+ }, undefined, false, undefined, this),
392770
+ " (",
392771
+ code,
392772
+ " ",
392773
+ codeText,
392774
+ ")"
392775
+ ]
392776
+ }, undefined, true, undefined, this)
392777
+ }, undefined, false, undefined, this),
392778
+ /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedBox_default, {
392779
+ flexDirection: "column",
392780
+ children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392781
+ children: result
392782
+ }, undefined, false, undefined, this)
392783
+ }, undefined, false, undefined, this)
392784
+ ]
392785
+ }, undefined, true, undefined, this);
392786
+ }
392787
+ return /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(MessageResponse, {
392788
+ height: 1,
392789
+ children: /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392790
+ children: [
392791
+ "Received ",
392792
+ /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(ThemedText, {
392793
+ bold: true,
392794
+ children: formattedSize
392795
+ }, undefined, false, undefined, this),
392796
+ " (",
392797
+ code,
392798
+ " ",
392799
+ codeText,
392800
+ ")"
392801
+ ]
392802
+ }, undefined, true, undefined, this)
392803
+ }, undefined, false, undefined, this);
392804
+ }
392805
+ function getToolUseSummary6(input) {
392806
+ if (!input?.url) {
392807
+ return null;
392808
+ }
392809
+ return truncate3(input.url, TOOL_SUMMARY_MAX_LENGTH);
392810
+ }
392811
+ var jsx_dev_runtime140;
392812
+ var init_UI14 = __esm(() => {
392813
+ init_MessageResponse();
392814
+ init_toolLimits();
392815
+ init_ink2();
392816
+ init_format2();
392817
+ jsx_dev_runtime140 = __toESM(require_jsx_dev_runtime(), 1);
392818
+ });
392819
+
392459
392820
  // src/tools/WebFetchTool/WebFetchTool.ts
392460
392821
  function webFetchToolInputToPermissionRuleContent(input) {
392461
392822
  try {
@@ -392488,6 +392849,7 @@ var init_WebFetchTool = __esm(() => {
392488
392849
  init_format2();
392489
392850
  init_permissions2();
392490
392851
  init_preapproved();
392852
+ init_permanentFailureCircuit();
392491
392853
  init_UI14();
392492
392854
  init_utils11();
392493
392855
  inputSchema18 = lazySchema(() => exports_external.strictObject({
@@ -392618,9 +392980,10 @@ ${DESCRIPTION5}`;
392618
392980
  renderToolUseMessage: renderToolUseMessage15,
392619
392981
  renderToolUseProgressMessage: renderToolUseProgressMessage8,
392620
392982
  renderToolResultMessage: renderToolResultMessage14,
392621
- async call({ url: url3, prompt }, { abortController, options: { isNonInteractiveSession } }) {
392983
+ async call({ url: url3, prompt }, context5) {
392622
392984
  const start = Date.now();
392623
- const response = await getURLMarkdownContent(url3, abortController);
392985
+ const { abortController, options: { isNonInteractiveSession } } = context5;
392986
+ const response = await withWebFetchPermanentFailureCircuit(url3, webFetchPermanentFailureScope(context5), () => getURLMarkdownContent(url3, abortController));
392624
392987
  if ("type" in response && response.type === "redirect") {
392625
392988
  const statusText = response.statusCode === 301 ? "Moved Permanently" : response.statusCode === 308 ? "Permanent Redirect" : response.statusCode === 307 ? "Temporary Redirect" : "Found";
392626
392989
  const message = `REDIRECT DETECTED: The URL redirects to a different host.
@@ -396801,7 +397164,7 @@ var init_embeddings = __esm(() => {
396801
397164
  });
396802
397165
 
396803
397166
  // src/utils/codeIndex/store.ts
396804
- import { createHash as createHash30 } from "crypto";
397167
+ import { createHash as createHash31 } from "crypto";
396805
397168
  import { mkdir as mkdir22, readFile as readFile26, writeFile as writeFile22 } from "fs/promises";
396806
397169
  import { dirname as dirname49, join as join113 } from "path";
396807
397170
  function codeIndexDir(root2) {
@@ -396811,7 +397174,7 @@ function indexPath(root2) {
396811
397174
  return join113(codeIndexDir(root2), "index.json");
396812
397175
  }
396813
397176
  function sha1(content) {
396814
- return createHash30("sha1").update(content).digest("hex");
397177
+ return createHash31("sha1").update(content).digest("hex");
396815
397178
  }
396816
397179
  function cosineSimilarity(a2, b) {
396817
397180
  if (a2.length === 0 || a2.length !== b.length) {
@@ -397360,11 +397723,11 @@ var init_graph = __esm(() => {
397360
397723
  });
397361
397724
 
397362
397725
  // src/utils/codeIndex/repoIndex.ts
397363
- import { createHash as createHash31 } from "crypto";
397726
+ import { createHash as createHash32 } from "crypto";
397364
397727
  import { existsSync as existsSync29, mkdirSync as mkdirSync19, readFileSync as readFileSync34, writeFileSync as writeFileSync22 } from "fs";
397365
397728
  import { join as join115, posix as posix8 } from "path";
397366
397729
  function sha12(content) {
397367
- return createHash31("sha1").update(content).digest("hex");
397730
+ return createHash32("sha1").update(content).digest("hex");
397368
397731
  }
397369
397732
  function posixExt(file2) {
397370
397733
  const dot = file2.lastIndexOf(".");
@@ -399602,7 +399965,8 @@ In plan mode, you'll:
399602
399965
  3. Design an implementation approach
399603
399966
  4. Present your plan to the user for approval
399604
399967
  5. Use ${ASK_USER_QUESTION_TOOL_NAME} if you need to clarify approaches
399605
- 6. Exit plan mode with ExitPlanMode when ready to implement
399968
+ 6. Create the visible implementation tasks with TaskCreate when that tool is available; updating a plan is not a substitute for the task list
399969
+ 7. Exit plan mode with ExitPlanMode when ready to implement
399606
399970
 
399607
399971
  `;
399608
399972
  });
@@ -399721,7 +400085,7 @@ var init_EnterPlanModeTool = __esm(() => {
399721
400085
  }));
399722
400086
  return {
399723
400087
  data: {
399724
- message: "Entered plan mode. You should now focus on exploring the codebase and designing an implementation approach."
400088
+ message: "Entered plan mode. Explore the codebase, design the approach, and create the visible implementation tasks with TaskCreate before attempting any workspace changes."
399725
400089
  }
399726
400090
  };
399727
400091
  },
@@ -399736,7 +400100,8 @@ In plan mode, you should:
399736
400100
  3. Consider multiple approaches and their trade-offs
399737
400101
  4. Use AskUserQuestion if you need to clarify the approach
399738
400102
  5. Design a concrete implementation strategy
399739
- 6. When ready, use ExitPlanMode to present your plan for approval
400103
+ 6. If TaskCreate is available, create the visible implementation tasks before ExitPlanMode; updating a plan does not create the task list
400104
+ 7. When ready, use ExitPlanMode to present your plan for approval
399740
400105
 
399741
400106
  Remember: DO NOT write or edit any files yet. This is a read-only exploration and planning phase.`;
399742
400107
  return {
@@ -402049,11 +402414,6 @@ var init_ConfigTool = __esm(() => {
402049
402414
  });
402050
402415
  });
402051
402416
 
402052
- // src/utils/messagePredicates.ts
402053
- function isHumanTurn(m) {
402054
- return m.type === "user" && !m.isMeta && m.toolUseResult === undefined;
402055
- }
402056
-
402057
402417
  // src/utils/taskListRunContext.ts
402058
402418
  import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
402059
402419
  import { randomUUID as randomUUID40 } from "crypto";
@@ -402101,6 +402461,52 @@ function requestsRevisionOfCurrentTaskList(input) {
402101
402461
  function shouldKeepCurrentTaskList(input) {
402102
402462
  return requestsAppendToCurrentTaskList(input) || requestsContinueCurrentTaskList(input) || requestsRevisionOfCurrentTaskList(input);
402103
402463
  }
402464
+ function withoutCode(input) {
402465
+ return input.replace(/```[\s\S]*?```/gu, " ").replace(/`[^`\n]*`/gu, " ");
402466
+ }
402467
+ function proseOnly(input) {
402468
+ return withoutCode(input).replace(/\s+/gu, " ").trim();
402469
+ }
402470
+ function taskListRequirementReason(input) {
402471
+ const text2 = proseOnly(input);
402472
+ if (!text2)
402473
+ return;
402474
+ const optsOut = /\b(?:do not|don't)\s+(?:(?:create|make|maintain|show|start|use)\s+)?(?:a\s+)?(?:task|todo)(?:\s+(?:list|board))?\b/iu.test(text2) || /\bwithout\s+(?:(?:creating|making|maintaining|showing|starting|using)\s+)?(?:a\s+)?(?:task|todo)(?:\s+(?:list|board))?\b/iu.test(text2) || /\b(?:skip|no)\s+(?:the\s+|a\s+)?(?:task|todo)(?:\s+(?:list|board))?\b/iu.test(text2);
402475
+ if (optsOut)
402476
+ return;
402477
+ if (/\b(?:create|make|maintain|show|start|use|keep|track|add|append|put|queue)\b[^.!?]{0,100}\b(?:task|todo)\s+(?:list|board)\b/iu.test(text2) || /\b(?:add|append|put|queue)\s+(?:this|it)?\s*(?:to|on)?\s*(?:my|the|your)?\s*(?:tasks?|todos?)\b/iu.test(text2) || /\b(?:add|append|put|queue)\s+(?:this|it)\s+(?:to|on)\s+(?:the\s+|your\s+|my\s+)?(?:current|existing)\s+list\b/iu.test(text2) || /\b(?:create|make|use|track)\s+(?:the\s+|a\s+|your\s+)?(?:tasks?|todos?)\b/iu.test(text2) || /\b(?:tasks?|todos?)\s+first\b/iu.test(text2)) {
402478
+ return "explicit task tracking request";
402479
+ }
402480
+ if (/^\/plan(?:\s|$)/iu.test(text2) || /\b(?:enter|start|use|switch\s+to)\s+plan\s+mode\b/iu.test(text2) || /\bplan\s+(?:this|the\s+work|first)\b/iu.test(text2)) {
402481
+ return "planning workflow";
402482
+ }
402483
+ if (/\b(?:delegate|delegation|sub[ -]?agents?|parallel\s+agents?|agent\s+team|team\s+of\s+agents?|fan[ -]?out)\b/iu.test(text2)) {
402484
+ return "delegation or parallel agent work";
402485
+ }
402486
+ const hasAction = new RegExp(String.raw`\b${ACTION_WORD}\b`, "iu").test(text2);
402487
+ if (hasAction && /\b(?:publish|release|deploy|production|migrat(?:e|ion)|database\s+schema|credentials?|secrets?|permissions?|sandbox|security|authentication|authorization|payments?|billing|version\s+bump|git\s+tag)\b/iu.test(text2)) {
402488
+ return "release, security, migration, or production risk";
402489
+ }
402490
+ const structuralText = withoutCode(input);
402491
+ const enumeratedItems = structuralText.match(/(?:^|\n)\s*(?:[-*+]\s+|\d+[.)]\s+)\S/gu);
402492
+ const actionLines = structuralText.split(/\r?\n/gu).filter((line) => new RegExp(String.raw`\b${ACTION_WORD}\b`, "iu").test(line));
402493
+ if ((enumeratedItems?.length ?? 0) >= 2 || actionLines.length >= 2 || SEQUENCED_ACTION_RE.test(text2)) {
402494
+ return "multiple requested outcomes";
402495
+ }
402496
+ const targetList = new RegExp(String.raw`\b${ACTION_WORD}\b[^.!?]{0,120}\b(?:docs?|tests?|code|implementation|configuration|config|workflow|release notes?|technical docs?|readme|ui|api|cli|database|schema|sandbox|permissions?)\b[^.!?]{0,80}(?:,|\band\b|\bplus\b)[^.!?]{0,80}\b(?:docs?|tests?|code|implementation|configuration|config|workflow|release notes?|technical docs?|readme|ui|api|cli|database|schema|sandbox|permissions?)\b`, "iu");
402497
+ if (targetList.test(text2))
402498
+ return "multiple requested outcomes";
402499
+ const projectScope = /\b(?:app|application|agent|system|platform|website|dashboard|service|integration|workflow|codebase|project|plugin|extension|3d\s+(?:scene|design|pipeline))\b/iu;
402500
+ const projectAction = /\b(?:build(?:ing|s)?|built|creat(?:e|ed|es|ing)|design(?:ed|ing|s)?|implement(?:ed|ing|s)?|integrat(?:e|ed|es|ing)|refactor(?:ed|ing|s)?|rewrit(?:e|ing|ten)|overhaul(?:ed|ing|s)?|audit(?:ed|ing|s)?|research(?:ed|es|ing)?)\b/iu;
402501
+ if (projectScope.test(text2) && projectAction.test(text2)) {
402502
+ return "large project scope";
402503
+ }
402504
+ ACTION_RE.lastIndex = 0;
402505
+ if (text2.length >= 600 && ACTION_RE.test(text2)) {
402506
+ return "detailed multi-step request";
402507
+ }
402508
+ return;
402509
+ }
402104
402510
  function getTaskListRunForCommand(command, options2 = {}) {
402105
402511
  if (!command || command.mode !== "prompt" || command.isMeta)
402106
402512
  return;
@@ -402108,9 +402514,12 @@ function getTaskListRunForCommand(command, options2 = {}) {
402108
402514
  if (!options2.allowSlashCommand && !command.skipSlashCommands && text2.trimStart().startsWith("/")) {
402109
402515
  return;
402110
402516
  }
402517
+ const requirementReason = taskListRequirementReason(text2);
402111
402518
  return {
402112
402519
  generationId: String(command.uuid ?? randomUUID40()),
402113
- appendToCurrent: shouldKeepCurrentTaskList(text2)
402520
+ appendToCurrent: shouldKeepCurrentTaskList(text2),
402521
+ requiresTaskList: requirementReason !== undefined,
402522
+ ...requirementReason ? { requirementReason } : {}
402114
402523
  };
402115
402524
  }
402116
402525
  function getTaskListRunFromMessages(messages) {
@@ -402118,14 +402527,21 @@ function getTaskListRunFromMessages(messages) {
402118
402527
  if (!message || typeof message.uuid !== "string" || !message.uuid) {
402119
402528
  return;
402120
402529
  }
402530
+ const text2 = textFromMessage(message);
402531
+ const requirementReason = taskListRequirementReason(text2);
402121
402532
  return {
402122
402533
  generationId: message.uuid,
402123
- appendToCurrent: shouldKeepCurrentTaskList(textFromMessage(message))
402534
+ appendToCurrent: shouldKeepCurrentTaskList(text2),
402535
+ requiresTaskList: requirementReason !== undefined,
402536
+ ...requirementReason ? { requirementReason } : {}
402124
402537
  };
402125
402538
  }
402126
- var taskListRunStorage;
402539
+ var taskListRunStorage, ACTION_WORD, ACTION_RE, SEQUENCED_ACTION_RE;
402127
402540
  var init_taskListRunContext = __esm(() => {
402128
402541
  taskListRunStorage = new AsyncLocalStorage5;
402542
+ ACTION_WORD = String.raw`(?:add(?:ed|ing|s)?|audit(?:ed|ing|s)?|build(?:ing|s)?|built|bump(?:ed|ing|s)?|chang(?:e|ed|es|ing)|clean(?:ed|ing|s)?|creat(?:e|ed|es|ing)|debug(?:ged|ging|s)?|delet(?:e|ed|es|ing)|deploy(?:ed|ing|s)?|design(?:ed|ing|s)?|document(?:ed|ing|s)?|fix(?:ed|es|ing)?|implement(?:ed|ing|s)?|integrat(?:e|ed|es|ing)|migrat(?:e|ed|es|ing)|publish(?:ed|es|ing)?|push(?:ed|es|ing)?|refactor(?:ed|ing|s)?|releas(?:e|ed|es|ing)|remov(?:e|ed|es|ing)|renam(?:e|ed|es|ing)|repair(?:ed|ing|s)?|research(?:ed|es|ing)?|review(?:ed|ing|s)?|secur(?:e|ed|es|ing)|test(?:ed|ing|s)?|updat(?:e|ed|es|ing)|upgrad(?:e|ed|es|ing)|verif(?:y|ied|ies|ying)|writ(?:e|es|ing)|wrote)`;
402543
+ ACTION_RE = new RegExp(String.raw`\b${ACTION_WORD}\b`, "giu");
402544
+ SEQUENCED_ACTION_RE = new RegExp(String.raw`\b${ACTION_WORD}\b[^.!?\n]{0,180}(?:\band\b|\bthen\b|\balso\b|\bplus\b|;|\n)[^.!?\n]{0,100}\b${ACTION_WORD}\b`, "iu");
402129
402545
  });
402130
402546
 
402131
402547
  // src/tools/TaskCreateTool/prompt.ts
@@ -402141,9 +402557,11 @@ It also helps the user understand the progress of the task and overall progress
402141
402557
 
402142
402558
  Use this tool proactively in these scenarios:
402143
402559
 
402144
- - Complex multi-step tasks - When a request requires 3 or more distinct steps or actions
402560
+ - Multi-outcome work - When a request has 2 or more distinct requested outcomes, deliverables, or sequenced actions
402145
402561
  - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations${teammateContext}
402146
402562
  - Multiple independently verifiable outcomes, dependency ordering, delegation, or parallel work
402563
+ - High-risk lifecycle work - Releases, publishing, deployment, migrations, security, credentials, permissions, sandboxing, or production changes
402564
+ - Project-sized builds, integrations, workflows, refactors, and audits
402147
402565
  - Plan mode - When using plan mode, create a task list to track the work
402148
402566
  - User explicitly requests todo list - When the user directly asks you to use the todo list
402149
402567
  - User asks to queue work - When the user says "add to your tasks", "add this to your task list", "put this on the list", "queue this up", or anything similar, IMMEDIATELY call this tool with that request \u2014 even if you are in the middle of other work and even if the item sounds small. The user is watching the live task panel and expects the item to appear there right away. Acknowledge briefly and continue what you were doing unless asked to switch.
@@ -402154,7 +402572,7 @@ Use this tool proactively in these scenarios:
402154
402572
 
402155
402573
  Skip using this tool when:
402156
402574
  - The task is purely conversational or informational
402157
- - The request is one direct, low-risk action that can be completed and verified as one operation
402575
+ - The request is one genuinely atomic, low-risk action with one outcome that can be completed and verified directly
402158
402576
  - The user sends a short acknowledgement, correction, or clarification that does not add a distinct outcome to an existing board
402159
402577
 
402160
402578
  Do not create a task merely because a user sent a message or because the request is actionable. Task subjects must describe concrete outcomes chosen after understanding the work; never copy the raw prompt into a task title.
@@ -412082,7 +412500,7 @@ var init_stream3 = __esm(() => {
412082
412500
  });
412083
412501
 
412084
412502
  // src/utils/telemetry/betaSessionTracing.ts
412085
- import { createHash as createHash32 } from "crypto";
412503
+ import { createHash as createHash33 } from "crypto";
412086
412504
  function clearBetaTracingState() {
412087
412505
  seenHashes.clear();
412088
412506
  lastReportedMessageHash.clear();
@@ -412109,7 +412527,7 @@ function truncateContent(content, maxSize = MAX_CONTENT_SIZE) {
412109
412527
  };
412110
412528
  }
412111
412529
  function shortHash(content) {
412112
- return createHash32("sha256").update(content).digest("hex").slice(0, 12);
412530
+ return createHash33("sha256").update(content).digest("hex").slice(0, 12);
412113
412531
  }
412114
412532
  function hashSystemPrompt(systemPrompt) {
412115
412533
  return `sp_${shortHash(systemPrompt)}`;
@@ -412385,7 +412803,7 @@ function isAnyTracingEnabled() {
412385
412803
  return isTelemetryEnabled() || isEnhancedTelemetryEnabled() || isBetaTracingEnabled();
412386
412804
  }
412387
412805
  function getTracer() {
412388
- return import_api39.trace.getTracer("ur-agent.gen_ai", "1.80.2");
412806
+ return import_api39.trace.getTracer("ur-agent.gen_ai", "1.80.4");
412389
412807
  }
412390
412808
  function createSpanAttributes(spanType, customAttributes = {}) {
412391
412809
  const baseAttributes = getTelemetryAttributes();
@@ -413066,6 +413484,8 @@ function checkTaskListGate(input) {
413066
413484
  const config3 = input.config ?? getTaskListGateConfig();
413067
413485
  if (!config3.enabled)
413068
413486
  return { allowed: true };
413487
+ if (input.taskListWriterAvailable === false)
413488
+ return { allowed: true };
413069
413489
  if (isTaskListGateExempt(input.toolName))
413070
413490
  return { allowed: true };
413071
413491
  const isMutating = input.isMutating ?? isMutatingTool2(input.toolName);
@@ -413074,23 +413494,30 @@ function checkTaskListGate(input) {
413074
413494
  if (input.taskCount !== null && input.taskCount > 0) {
413075
413495
  return { allowed: true };
413076
413496
  }
413497
+ const inherentlyRequiresTaskList = input.isSubagent || ALWAYS_REQUIRE_PLAN_TOOLS.has(input.toolName);
413498
+ const classifiedRequirement = input.requiresTaskList === true;
413499
+ const forceEveryMutation = config3.freeReads === 0;
413500
+ const unclassifiedAllowanceExpired = input.requiresTaskList === undefined && input.readsSoFar >= config3.freeReads;
413501
+ const gateRequired = inherentlyRequiresTaskList || classifiedRequirement || forceEveryMutation || unclassifiedAllowanceExpired;
413502
+ const requirementContext = input.requirementReason ? ` This turn requires task tracking because it contains ${input.requirementReason}.` : "";
413503
+ const planningRecovery = input.requirementReason === "planning workflow" ? " EnterPlanMode and plan updates do not create the visible task list." : "";
413077
413504
  if (input.taskCount === null) {
413078
413505
  return {
413079
413506
  allowed: false,
413080
- reason: `The task list could not be read, so ${input.toolName} was not allowed ` + `to change state without a verifiable plan. Retry TaskList or ` + `TaskCreate, then retry this call. Disable with ` + `tasks.requireBeforeChanges.enabled=false in settings.`
413507
+ reason: `The task list could not be read, so ${input.toolName} was not allowed ` + `to change state without a verifiable plan.${requirementContext}${planningRecovery} Retry TaskList or ` + `TaskCreate, then retry this call. Disable with ` + `tasks.requireBeforeChanges.enabled=false in settings.`
413081
413508
  };
413082
413509
  }
413083
- if (input.isSubagent || ALWAYS_REQUIRE_PLAN_TOOLS.has(input.toolName)) {
413510
+ if (!gateRequired)
413511
+ return { allowed: true };
413512
+ if (inherentlyRequiresTaskList) {
413084
413513
  return {
413085
413514
  allowed: false,
413086
413515
  reason: `No actionable parent task exists for ${input.toolName}. Call ` + `TaskCreate before delegating or changing state, then retry this call. ` + `Disable with tasks.requireBeforeChanges.enabled=false in settings.`
413087
413516
  };
413088
413517
  }
413089
- if (input.readsSoFar < config3.freeReads)
413090
- return { allowed: true };
413091
413518
  return {
413092
413519
  allowed: false,
413093
- reason: `No task list exists, and ${input.toolName} changes the workspace. ` + `Call TaskCreate first with the steps you intend to take, then retry ` + `this call. Reads are unrestricted, so investigate as much as you need ` + `before writing the list. ` + `Disable with tasks.requireBeforeChanges.enabled=false in settings.`
413520
+ reason: `No task list exists, and ${input.toolName} changes the workspace. ` + `${requirementContext.trim()}${requirementContext ? " " : ""}` + `${planningRecovery.trim()}${planningRecovery ? " " : ""}` + `Call TaskCreate first with the steps you intend to take, then retry ` + `this call. Reads are unrestricted, so investigate as much as you need ` + `before writing the list. ` + `Disable with tasks.requireBeforeChanges.enabled=false in settings.`
413094
413521
  };
413095
413522
  }
413096
413523
  var TASK_LIST_GATE_DEFAULTS, KNOWN_MUTATING_TOOLS, GATE_EXEMPT_TOOLS, ALWAYS_REQUIRE_PLAN_TOOLS;
@@ -413098,7 +413525,7 @@ var init_taskListGate = __esm(() => {
413098
413525
  init_settings2();
413099
413526
  init_tasks();
413100
413527
  TASK_LIST_GATE_DEFAULTS = {
413101
- enabled: false,
413528
+ enabled: true,
413102
413529
  freeReads: 3
413103
413530
  };
413104
413531
  KNOWN_MUTATING_TOOLS = new Set([
@@ -413127,278 +413554,6 @@ var init_taskListGate = __esm(() => {
413127
413554
  ]);
413128
413555
  });
413129
413556
 
413130
- // src/services/tools/repeatedFailureGuard.ts
413131
- import { createHash as createHash33 } from "crypto";
413132
- function writeFramedText(hash3, value) {
413133
- hash3.update(`${value.length}:`);
413134
- for (let offset = 0;offset < value.length; ) {
413135
- const end = Math.min(offset + HASH_CHUNK_CODE_UNITS, value.length);
413136
- hash3.update(value.slice(offset, end), "utf16le");
413137
- offset = end;
413138
- }
413139
- }
413140
- function writeToken(hash3, kind, value = "") {
413141
- writeFramedText(hash3, kind);
413142
- writeFramedText(hash3, value);
413143
- }
413144
- function visitCanonical(value, state, depth) {
413145
- state.nodesVisited++;
413146
- if (state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes || depth > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalDepth) {
413147
- throw new CanonicalTraversalLimitError;
413148
- }
413149
- if (value === null) {
413150
- writeToken(state.hash, "null");
413151
- return;
413152
- }
413153
- switch (typeof value) {
413154
- case "string":
413155
- state.textCodeUnitsVisited += value.length;
413156
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413157
- throw new CanonicalTraversalLimitError;
413158
- }
413159
- writeToken(state.hash, "string", value);
413160
- return;
413161
- case "number":
413162
- writeToken(state.hash, "number", Object.is(value, -0) ? "-0" : String(value));
413163
- return;
413164
- case "boolean":
413165
- writeToken(state.hash, "boolean", String(value));
413166
- return;
413167
- case "undefined":
413168
- writeToken(state.hash, "undefined");
413169
- return;
413170
- case "bigint":
413171
- writeToken(state.hash, "bigint", value.toString());
413172
- return;
413173
- case "symbol": {
413174
- const description = String(value.description ?? "");
413175
- state.textCodeUnitsVisited += description.length;
413176
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413177
- throw new CanonicalTraversalLimitError;
413178
- }
413179
- writeToken(state.hash, "symbol", description);
413180
- return;
413181
- }
413182
- case "function": {
413183
- const name = value.name || "<anonymous>";
413184
- state.textCodeUnitsVisited += name.length;
413185
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413186
- throw new CanonicalTraversalLimitError;
413187
- }
413188
- writeToken(state.hash, "function", name);
413189
- return;
413190
- }
413191
- case "object": {
413192
- const object4 = value;
413193
- const existingReference = state.seen.get(object4);
413194
- if (existingReference !== undefined) {
413195
- writeToken(state.hash, "reference", String(existingReference));
413196
- return;
413197
- }
413198
- const reference = state.nextReference++;
413199
- state.seen.set(object4, reference);
413200
- if (Array.isArray(value)) {
413201
- if (value.length + state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes) {
413202
- throw new CanonicalTraversalLimitError;
413203
- }
413204
- writeToken(state.hash, "array", String(value.length));
413205
- for (let index2 = 0;index2 < value.length; index2++) {
413206
- if (!(index2 in value)) {
413207
- writeToken(state.hash, "hole");
413208
- continue;
413209
- }
413210
- visitCanonical(value[index2], state, depth + 1);
413211
- }
413212
- return;
413213
- }
413214
- const record3 = value;
413215
- const keys2 = Object.keys(record3);
413216
- if (keys2.length + state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes) {
413217
- throw new CanonicalTraversalLimitError;
413218
- }
413219
- keys2.sort();
413220
- writeToken(state.hash, "object", String(keys2.length));
413221
- for (const key of keys2) {
413222
- state.textCodeUnitsVisited += key.length;
413223
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413224
- throw new CanonicalTraversalLimitError;
413225
- }
413226
- writeToken(state.hash, "key", key);
413227
- visitCanonical(record3[key], state, depth + 1);
413228
- }
413229
- return;
413230
- }
413231
- }
413232
- }
413233
- function digestText(domain2, value) {
413234
- const hash3 = createHash33("sha256");
413235
- writeToken(hash3, "domain", domain2);
413236
- writeToken(hash3, "value", value);
413237
- return hash3.digest("hex");
413238
- }
413239
- function canonicalInputDigest(input) {
413240
- const hash3 = createHash33("sha256");
413241
- writeToken(hash3, "domain", "repeated-failure-input-v2");
413242
- visitCanonical(input, {
413243
- hash: hash3,
413244
- nextReference: 0,
413245
- nodesVisited: 0,
413246
- textCodeUnitsVisited: 0,
413247
- seen: new WeakMap
413248
- }, 0);
413249
- return hash3.digest("hex");
413250
- }
413251
- function uniqueSerializationFailureDigest() {
413252
- serializationFailureNonce++;
413253
- return digestText("repeated-failure-unserializable-v2", serializationFailureNonce.toString());
413254
- }
413255
- function scopeDigest(scope) {
413256
- return scope ? digestText("repeated-failure-scope-v2", scope) : UNSCOPED_DIGEST;
413257
- }
413258
- function callSignature(toolName, input, scope) {
413259
- let inputDigest;
413260
- try {
413261
- inputDigest = canonicalInputDigest(input);
413262
- } catch {
413263
- inputDigest = uniqueSerializationFailureDigest();
413264
- }
413265
- return [
413266
- SIGNATURE_VERSION,
413267
- scopeDigest(scope),
413268
- digestText("repeated-failure-tool-v2", toolName),
413269
- inputDigest
413270
- ].join(":");
413271
- }
413272
- function isSha256Digest(value) {
413273
- return value?.length === SHA256_HEX_LENGTH && /^[0-9a-f]+$/.test(value);
413274
- }
413275
- function signatureStorageIdentity(signature) {
413276
- if (signature.length === UNSCOPED_SIGNATURE_LENGTH || signature.length === SCOPED_SIGNATURE_LENGTH) {
413277
- const parts = signature.split(":");
413278
- if (parts.length === 4 && parts[0] === SIGNATURE_VERSION && (parts[1] === UNSCOPED_DIGEST || isSha256Digest(parts[1])) && isSha256Digest(parts[2]) && isSha256Digest(parts[3])) {
413279
- return { key: signature, scope: parts[1] };
413280
- }
413281
- }
413282
- return {
413283
- key: `${SIGNATURE_VERSION}:legacy:${digestText("repeated-failure-legacy-signature-v2", signature)}`,
413284
- scope: UNSCOPED_DIGEST
413285
- };
413286
- }
413287
- function pruneExpiredFailures(now5) {
413288
- for (const [signature, record3] of failureCounts) {
413289
- if (now5 >= record3.lastFailureAt && now5 - record3.lastFailureAt >= REPEATED_FAILURE_GUARD_LIMITS.entryTtlMs) {
413290
- failureCounts.delete(signature);
413291
- }
413292
- }
413293
- }
413294
- function enforceFailureBounds(scope) {
413295
- let entriesInScope = 0;
413296
- for (const record3 of failureCounts.values()) {
413297
- if (record3.scopeDigest === scope)
413298
- entriesInScope++;
413299
- }
413300
- let scopeOverflow = entriesInScope - REPEATED_FAILURE_GUARD_LIMITS.maxEntriesPerScope;
413301
- if (scopeOverflow > 0) {
413302
- for (const [signature, record3] of failureCounts) {
413303
- if (record3.scopeDigest !== scope)
413304
- continue;
413305
- failureCounts.delete(signature);
413306
- scopeOverflow--;
413307
- if (scopeOverflow === 0)
413308
- break;
413309
- }
413310
- }
413311
- while (failureCounts.size > REPEATED_FAILURE_GUARD_LIMITS.maxEntries) {
413312
- const oldest = failureCounts.keys().next().value;
413313
- if (oldest === undefined)
413314
- break;
413315
- failureCounts.delete(oldest);
413316
- }
413317
- }
413318
- function recordCallFailure(signature) {
413319
- const now5 = repeatedFailureNow();
413320
- pruneExpiredFailures(now5);
413321
- const identity5 = signatureStorageIdentity(signature);
413322
- const existing2 = failureCounts.get(identity5.key);
413323
- const next = (existing2?.failures ?? 0) + 1;
413324
- const signatureScope = existing2?.scopeDigest ?? identity5.scope;
413325
- failureCounts.delete(identity5.key);
413326
- failureCounts.set(identity5.key, {
413327
- failures: next,
413328
- lastFailureAt: now5,
413329
- scopeDigest: signatureScope
413330
- });
413331
- enforceFailureBounds(signatureScope);
413332
- return next;
413333
- }
413334
- function recordCallSuccess(signature) {
413335
- failureCounts.delete(signatureStorageIdentity(signature).key);
413336
- }
413337
- function clearRepeatedFailuresForScope(scope) {
413338
- const target = scopeDigest(scope);
413339
- let cleared = 0;
413340
- for (const [signature, record3] of failureCounts) {
413341
- if (record3.scopeDigest !== target)
413342
- continue;
413343
- failureCounts.delete(signature);
413344
- cleared++;
413345
- }
413346
- return cleared;
413347
- }
413348
- function clearRepeatedFailuresForQuery(queryChainId) {
413349
- return clearRepeatedFailuresForScope(`query:${queryChainId}`);
413350
- }
413351
- function checkRepeatedFailure(signature, config3 = REPEATED_FAILURE_DEFAULTS) {
413352
- if (!config3.enabled)
413353
- return { action: "allow" };
413354
- const now5 = repeatedFailureNow();
413355
- pruneExpiredFailures(now5);
413356
- const failures = failureCounts.get(signatureStorageIdentity(signature).key)?.failures ?? 0;
413357
- if (failures >= config3.abortAfter) {
413358
- return {
413359
- action: "abort",
413360
- reason: `This exact call has failed ${failures} times and is still being ` + `repeated. Stopping the turn rather than continuing to loop.`
413361
- };
413362
- }
413363
- if (failures >= config3.limit) {
413364
- return {
413365
- action: "refuse",
413366
- reason: `This exact call has already failed ${failures} times with the same ` + `arguments, so it will fail again. Do not retry it unchanged. Either ` + `fix the arguments, use a different tool, or tell the user what is ` + `blocking you and stop.`
413367
- };
413368
- }
413369
- return { action: "allow" };
413370
- }
413371
- var REPEATED_FAILURE_DEFAULTS, REPEATED_FAILURE_GUARD_LIMITS, SIGNATURE_VERSION = "rf2", UNSCOPED_DIGEST = "-", SHA256_HEX_LENGTH = 64, HASH_CHUNK_CODE_UNITS, UNSCOPED_SIGNATURE_LENGTH, SCOPED_SIGNATURE_LENGTH, failureCounts, serializationFailureNonce = 0n, repeatedFailureNow, CanonicalTraversalLimitError, RepeatedToolFailureAbort;
413372
- var init_repeatedFailureGuard = __esm(() => {
413373
- REPEATED_FAILURE_DEFAULTS = {
413374
- enabled: false,
413375
- limit: 3,
413376
- abortAfter: 6
413377
- };
413378
- REPEATED_FAILURE_GUARD_LIMITS = {
413379
- maxEntries: 2048,
413380
- maxEntriesPerScope: 256,
413381
- entryTtlMs: 30 * 60 * 1000,
413382
- maxCanonicalNodes: 50000,
413383
- maxCanonicalDepth: 128,
413384
- maxCanonicalTextCodeUnits: 1e6
413385
- };
413386
- HASH_CHUNK_CODE_UNITS = 16 * 1024;
413387
- UNSCOPED_SIGNATURE_LENGTH = SIGNATURE_VERSION.length + 3 + 1 + SHA256_HEX_LENGTH * 2;
413388
- SCOPED_SIGNATURE_LENGTH = SIGNATURE_VERSION.length + 3 + SHA256_HEX_LENGTH * 3;
413389
- failureCounts = new Map;
413390
- repeatedFailureNow = Date.now;
413391
- CanonicalTraversalLimitError = class CanonicalTraversalLimitError extends Error {
413392
- };
413393
- RepeatedToolFailureAbort = class RepeatedToolFailureAbort extends Error {
413394
- constructor(message) {
413395
- super(message);
413396
- this.name = "RepeatedToolFailureAbort";
413397
- Object.setPrototypeOf(this, new.target.prototype);
413398
- }
413399
- };
413400
- });
413401
-
413402
413557
  // src/stability/types.ts
413403
413558
  var DEFAULT_LIMITS;
413404
413559
  var init_types12 = __esm(() => {
@@ -414638,12 +414793,16 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
414638
414793
  } catch {
414639
414794
  isMutating = true;
414640
414795
  }
414796
+ const taskListRun = getTaskListRunContext() ?? (toolUseContext.agentId ? undefined : getTaskListRunFromMessages(toolUseContext.messages ?? []));
414641
414797
  const gate = checkTaskListGate({
414642
414798
  toolName: tool.name,
414643
414799
  taskCount: await countTasksForGate(),
414644
414800
  readsSoFar: countToolCallsBeforeCurrent(toolUseContext.messages, assistantMessage, toolUseID),
414645
414801
  isSubagent: Boolean(toolUseContext.agentId),
414646
- isMutating
414802
+ isMutating,
414803
+ requiresTaskList: taskListRun?.requiresTaskList,
414804
+ requirementReason: taskListRun?.requirementReason,
414805
+ taskListWriterAvailable: toolUseContext.options.tools.some((candidate) => candidate.name === "TaskCreate")
414647
414806
  });
414648
414807
  if (gate.allowed === false) {
414649
414808
  recordCallFailure(callSig);
@@ -415000,7 +415159,10 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
415000
415159
  taskCount: await countTasksForGate(),
415001
415160
  readsSoFar: countToolCallsBeforeCurrent(toolUseContext.messages, assistantMessage, toolUseID),
415002
415161
  isSubagent: Boolean(toolUseContext.agentId),
415003
- isMutating: finalIsMutating
415162
+ isMutating: finalIsMutating,
415163
+ requiresTaskList: taskListRun?.requiresTaskList,
415164
+ requirementReason: taskListRun?.requirementReason,
415165
+ taskListWriterAvailable: toolUseContext.options.tools.some((candidate) => candidate.name === "TaskCreate")
415004
415166
  });
415005
415167
  if (finalGate.allowed === false) {
415006
415168
  recordCallFailure(callSig);
@@ -415287,6 +415449,8 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
415287
415449
  error: errorMessage2(error40)
415288
415450
  });
415289
415451
  endToolSpan();
415452
+ if (error40 instanceof RepeatedToolFailureAbort)
415453
+ throw error40;
415290
415454
  if (error40 instanceof McpAuthError) {
415291
415455
  toolUseContext.setAppState((prevState) => {
415292
415456
  const serverName = error40.serverName;
@@ -415438,6 +415602,7 @@ var init_toolExecution = __esm(() => {
415438
415602
  init_genAiSemantics();
415439
415603
  init_toolErrors();
415440
415604
  init_toolResultStorage();
415605
+ init_taskListRunContext();
415441
415606
  init_toolSearch();
415442
415607
  init_taskListGate();
415443
415608
  init_repeatedFailureGuard();
@@ -442817,7 +442982,7 @@ function Feedback({
442817
442982
  platform: env2.platform,
442818
442983
  gitRepo: envInfo.isGit,
442819
442984
  terminal: env2.terminal,
442820
- version: "1.80.2",
442985
+ version: "1.80.4",
442821
442986
  transcript: normalizeMessagesForAPI(messages),
442822
442987
  errors: sanitizedErrors,
442823
442988
  lastApiRequest: getLastAPIRequest(),
@@ -443009,7 +443174,7 @@ function Feedback({
443009
443174
  ", ",
443010
443175
  env2.terminal,
443011
443176
  ", v",
443012
- "1.80.2"
443177
+ "1.80.4"
443013
443178
  ]
443014
443179
  }, undefined, true, undefined, this)
443015
443180
  ]
@@ -443115,7 +443280,7 @@ ${sanitizedDescription}
443115
443280
  ` + `**Environment Info**
443116
443281
  ` + `- Platform: ${env2.platform}
443117
443282
  ` + `- Terminal: ${env2.terminal}
443118
- ` + `- Version: ${"1.80.2"}
443283
+ ` + `- Version: ${"1.80.4"}
443119
443284
  ` + `- Feedback ID: ${feedbackId}
443120
443285
  ` + `
443121
443286
  **Errors**
@@ -446225,7 +446390,7 @@ function buildPrimarySection() {
446225
446390
  }, undefined, false, undefined, this);
446226
446391
  return [{
446227
446392
  label: "Version",
446228
- value: "1.80.2"
446393
+ value: "1.80.4"
446229
446394
  }, {
446230
446395
  label: "Session name",
446231
446396
  value: nameValue
@@ -449607,7 +449772,7 @@ function Config({
449607
449772
  }
449608
449773
  }, undefined, false, undefined, this)
449609
449774
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime179.jsxDEV(ChannelDowngradeDialog, {
449610
- currentVersion: "1.80.2",
449775
+ currentVersion: "1.80.4",
449611
449776
  onChoice: (choice) => {
449612
449777
  setShowSubmenu(null);
449613
449778
  setTabsHidden(false);
@@ -449619,7 +449784,7 @@ function Config({
449619
449784
  autoUpdatesChannel: "stable"
449620
449785
  };
449621
449786
  if (choice === "stay") {
449622
- newSettings.minimumVersion = "1.80.2";
449787
+ newSettings.minimumVersion = "1.80.4";
449623
449788
  }
449624
449789
  updateSettingsForSource("userSettings", newSettings);
449625
449790
  setSettingsData((prev_27) => ({
@@ -450796,6 +450961,9 @@ var init_Settings = __esm(() => {
450796
450961
  });
450797
450962
 
450798
450963
  // src/commands/config/configAssignments.ts
450964
+ function resolveConfigAssignmentKey(rawKey) {
450965
+ return KEY_ALIASES[rawKey.replaceAll("-", "").toLowerCase()];
450966
+ }
450799
450967
  function booleanValue(value) {
450800
450968
  if (value === "true" || value === "on" || value === "enabled")
450801
450969
  return true;
@@ -450811,9 +450979,9 @@ function parseConfigAssignments(input) {
450811
450979
  if (separator <= 0 || separator === token.length - 1) {
450812
450980
  return { error: `Invalid assignment '${token}'. Expected key=value.` };
450813
450981
  }
450814
- const rawKey = token.slice(0, separator).replaceAll("-", "").toLowerCase();
450982
+ const rawKey = token.slice(0, separator);
450815
450983
  const rawValue = token.slice(separator + 1).toLowerCase();
450816
- const key = KEY_ALIASES[rawKey];
450984
+ const key = resolveConfigAssignmentKey(rawKey);
450817
450985
  if (!key)
450818
450986
  return { error: `Unknown setting '${token.slice(0, separator)}'.` };
450819
450987
  if (key === "editor") {
@@ -450841,10 +451009,115 @@ function parseConfigAssignments(input) {
450841
451009
  }
450842
451010
  return { assignments };
450843
451011
  }
451012
+ function applyConfigAssignments(assignments, effects2 = {}) {
451013
+ const applied = [];
451014
+ for (const assignment of assignments) {
451015
+ switch (assignment.key) {
451016
+ case "thinking": {
451017
+ const value = assignment.value;
451018
+ const result = updateSettingsForSource("userSettings", {
451019
+ alwaysThinkingEnabled: value ? undefined : false
451020
+ });
451021
+ if (result.error) {
451022
+ return { error: `Could not update thinking: ${result.error.message}` };
451023
+ }
451024
+ effects2.thinking?.(value);
451025
+ applied.push(`thinking=${value}`);
451026
+ break;
451027
+ }
451028
+ case "screenReader": {
451029
+ const value = assignment.value;
451030
+ const result = updateSettingsForSource("localSettings", {
451031
+ screenReaderMode: value
451032
+ });
451033
+ if (result.error) {
451034
+ return {
451035
+ error: `Could not update screen reader mode: ${result.error.message}`
451036
+ };
451037
+ }
451038
+ effects2.screenReader?.(value);
451039
+ applied.push(`screenReader=${value}`);
451040
+ break;
451041
+ }
451042
+ case "reducedMotion": {
451043
+ const value = assignment.value;
451044
+ const result = updateSettingsForSource("localSettings", {
451045
+ prefersReducedMotion: value
451046
+ });
451047
+ if (result.error) {
451048
+ return {
451049
+ error: `Could not update reduced motion: ${result.error.message}`
451050
+ };
451051
+ }
451052
+ effects2.reducedMotion?.(value);
451053
+ applied.push(`reducedMotion=${value}`);
451054
+ break;
451055
+ }
451056
+ case "verbose": {
451057
+ const value = assignment.value;
451058
+ const result = updateSettingsForSource("userSettings", {
451059
+ verbose: value
451060
+ });
451061
+ if (result.error) {
451062
+ return {
451063
+ error: `Could not update verbose output: ${result.error.message}`
451064
+ };
451065
+ }
451066
+ effects2.verbose?.(value);
451067
+ applied.push(`verbose=${value}`);
451068
+ break;
451069
+ }
451070
+ case "autoCompact": {
451071
+ const value = assignment.value;
451072
+ saveGlobalConfig((previous) => ({
451073
+ ...previous,
451074
+ autoCompactEnabled: value
451075
+ }));
451076
+ applied.push(`autoCompact=${value}`);
451077
+ break;
451078
+ }
451079
+ case "editor": {
451080
+ const value = assignment.value;
451081
+ saveGlobalConfig((previous) => ({ ...previous, editorMode: value }));
451082
+ applied.push(`editor=${value}`);
451083
+ break;
451084
+ }
451085
+ case "vimEscape": {
451086
+ const value = assignment.value;
451087
+ saveGlobalConfig((previous) => ({
451088
+ ...previous,
451089
+ vimInsertModeEscapeSequence: value || undefined
451090
+ }));
451091
+ applied.push(`vimEscape=${value || "off"}`);
451092
+ break;
451093
+ }
451094
+ }
451095
+ }
451096
+ return { applied };
451097
+ }
451098
+ function getConfigAssignmentValues() {
451099
+ const settings = getInitialSettings();
451100
+ const global3 = getGlobalConfig();
451101
+ return [
451102
+ { key: "thinking", value: settings.alwaysThinkingEnabled !== false },
451103
+ { key: "screenReader", value: settings.screenReaderMode === true },
451104
+ { key: "reducedMotion", value: settings.prefersReducedMotion === true },
451105
+ { key: "verbose", value: settings.verbose === true },
451106
+ { key: "autoCompact", value: global3.autoCompactEnabled },
451107
+ { key: "editor", value: global3.editorMode ?? "normal" },
451108
+ {
451109
+ key: "vimEscape",
451110
+ value: global3.vimInsertModeEscapeSequence || "off"
451111
+ }
451112
+ ];
451113
+ }
450844
451114
  var CONFIG_ASSIGNMENT_HELP, KEY_ALIASES;
450845
451115
  var init_configAssignments = __esm(() => {
451116
+ init_config();
451117
+ init_settings2();
450846
451118
  CONFIG_ASSIGNMENT_HELP = [
450847
451119
  "Usage: /config <key>=<value> [key=value ...]",
451120
+ "CLI: ur config set <key> <value>",
450848
451121
  "",
450849
451122
  "Supported settings:",
450850
451123
  " thinking=true|false Enable or disable model thinking",
@@ -450906,90 +451179,35 @@ ${CONFIG_ASSIGNMENT_HELP}`,
450906
451179
  onDone
450907
451180
  }, undefined, false, undefined, this);
450908
451181
  }
450909
- const applied = [];
450910
- for (const assignment of parsed.assignments) {
450911
- switch (assignment.key) {
450912
- case "thinking": {
450913
- const value = assignment.value;
450914
- const result = updateSettingsForSource("userSettings", { alwaysThinkingEnabled: value ? undefined : false });
450915
- if (result.error)
450916
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
450917
- message: `Could not update thinking: ${result.error.message}`,
450918
- onDone
450919
- }, undefined, false, undefined, this);
450920
- context5.setAppState((previous) => ({ ...previous, thinkingEnabled: value }));
450921
- applied.push(`thinking=${value}`);
450922
- break;
450923
- }
450924
- case "screenReader": {
450925
- const value = assignment.value;
450926
- const result = updateSettingsForSource("localSettings", { screenReaderMode: value });
450927
- if (result.error)
450928
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
450929
- message: `Could not update screen reader mode: ${result.error.message}`,
450930
- onDone
450931
- }, undefined, false, undefined, this);
450932
- if (value)
450933
- enableScreenReaderMode();
450934
- else
450935
- disableScreenReaderMode();
450936
- setScreenReaderRendering(value);
450937
- context5.setAppState((previous) => ({
450938
- ...previous,
450939
- settings: { ...previous.settings, screenReaderMode: value }
450940
- }));
450941
- applied.push(`screenReader=${value}`);
450942
- break;
450943
- }
450944
- case "reducedMotion": {
450945
- const value = assignment.value;
450946
- const result = updateSettingsForSource("localSettings", { prefersReducedMotion: value });
450947
- if (result.error)
450948
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
450949
- message: `Could not update reduced motion: ${result.error.message}`,
450950
- onDone
450951
- }, undefined, false, undefined, this);
450952
- context5.setAppState((previous) => ({ ...previous, settings: { ...previous.settings, prefersReducedMotion: value } }));
450953
- applied.push(`reducedMotion=${value}`);
450954
- break;
450955
- }
450956
- case "verbose": {
450957
- const value = assignment.value;
450958
- const result = updateSettingsForSource("userSettings", { verbose: value });
450959
- if (result.error)
450960
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
450961
- message: `Could not update verbose output: ${result.error.message}`,
450962
- onDone
450963
- }, undefined, false, undefined, this);
450964
- context5.setAppState((previous) => ({ ...previous, verbose: value }));
450965
- applied.push(`verbose=${value}`);
450966
- break;
450967
- }
450968
- case "autoCompact": {
450969
- const value = assignment.value;
450970
- saveGlobalConfig((previous) => ({ ...previous, autoCompactEnabled: value }));
450971
- applied.push(`autoCompact=${value}`);
450972
- break;
450973
- }
450974
- case "editor": {
450975
- const value = assignment.value;
450976
- saveGlobalConfig((previous) => ({ ...previous, editorMode: value }));
450977
- applied.push(`editor=${value}`);
450978
- break;
450979
- }
450980
- case "vimEscape": {
450981
- const value = assignment.value;
450982
- saveGlobalConfig((previous) => ({
450983
- ...previous,
450984
- vimInsertModeEscapeSequence: value || undefined
450985
- }));
450986
- applied.push(`vimEscape=${value || "off"}`);
450987
- break;
450988
- }
451182
+ const result = applyConfigAssignments(parsed.assignments, {
451183
+ thinking(value) {
451184
+ context5.setAppState((previous) => ({ ...previous, thinkingEnabled: value }));
451185
+ },
451186
+ screenReader(value) {
451187
+ if (value)
451188
+ enableScreenReaderMode();
451189
+ else
451190
+ disableScreenReaderMode();
451191
+ setScreenReaderRendering(value);
451192
+ context5.setAppState((previous) => ({
451193
+ ...previous,
451194
+ settings: { ...previous.settings, screenReaderMode: value }
451195
+ }));
451196
+ },
451197
+ reducedMotion(value) {
451198
+ context5.setAppState((previous) => ({ ...previous, settings: { ...previous.settings, prefersReducedMotion: value } }));
451199
+ },
451200
+ verbose(value) {
451201
+ context5.setAppState((previous) => ({ ...previous, verbose: value }));
450989
451202
  }
450990
- }
451203
+ });
451204
+ if (result.error)
451205
+ return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
451206
+ message: result.error,
451207
+ onDone
451208
+ }, undefined, false, undefined, this);
450991
451209
  return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
450992
- message: `Updated ${applied.join(", ")}.`,
451210
+ message: `Updated ${result.applied.join(", ")}.`,
450993
451211
  onDone
450994
451212
  }, undefined, false, undefined, this);
450995
451213
  };
@@ -450997,9 +451215,7 @@ var init_config8 = __esm(() => {
450997
451215
  init_Settings();
450998
451216
  init_ink2();
450999
451217
  init_root();
451000
- init_config();
451001
451218
  init_screenReader();
451002
- init_settings2();
451003
451219
  init_configAssignments();
451004
451220
  import_react110 = __toESM(require_react(), 1);
451005
451221
  jsx_dev_runtime183 = __toESM(require_jsx_dev_runtime(), 1);
@@ -457877,7 +458093,7 @@ function HelpV2(t0) {
457877
458093
  let t6;
457878
458094
  if ($2[31] !== tabs) {
457879
458095
  t6 = /* @__PURE__ */ jsx_dev_runtime206.jsxDEV(Tabs, {
457880
- title: `UR v${"1.80.2"}`,
458096
+ title: `UR v${"1.80.4"}`,
457881
458097
  color: "professionalBlue",
457882
458098
  defaultTab: "general",
457883
458099
  children: tabs
@@ -458810,7 +459026,7 @@ function buildToolUseContext(tools, readFileStateCache, toolPermissionContext, a
458810
459026
  async function handleInitialize(options2) {
458811
459027
  return {
458812
459028
  name: "UR",
458813
- version: "1.80.2",
459029
+ version: "1.80.4",
458814
459030
  protocolVersion: "0.1.0",
458815
459031
  workspaceRoot: options2.cwd,
458816
459032
  capabilities: {
@@ -475918,7 +476134,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
475918
476134
  return [];
475919
476135
  }
475920
476136
  }
475921
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.2") {
476137
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.4") {
475922
476138
  if (process.env.USER_TYPE === "ant") {
475923
476139
  const changelog = "";
475924
476140
  if (changelog) {
@@ -475945,7 +476161,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.2")
475945
476161
  releaseNotes
475946
476162
  };
475947
476163
  }
475948
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.80.2") {
476164
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.80.4") {
475949
476165
  if (process.env.USER_TYPE === "ant") {
475950
476166
  const changelog = "";
475951
476167
  if (changelog) {
@@ -478850,7 +479066,7 @@ function getRecentActivitySync() {
478850
479066
  return cachedActivity;
478851
479067
  }
478852
479068
  function getLogoDisplayData() {
478853
- const version2 = process.env.DEMO_VERSION ?? "1.80.2";
479069
+ const version2 = process.env.DEMO_VERSION ?? "1.80.4";
478854
479070
  const serverUrl = getDirectConnectServerUrl();
478855
479071
  const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd());
478856
479072
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -479718,7 +479934,7 @@ function LogoV2() {
479718
479934
  if ($2[2] === Symbol.for("react.memo_cache_sentinel")) {
479719
479935
  t2 = () => {
479720
479936
  const currentConfig = getGlobalConfig();
479721
- if (currentConfig.lastReleaseNotesSeen === "1.80.2") {
479937
+ if (currentConfig.lastReleaseNotesSeen === "1.80.4") {
479722
479938
  return;
479723
479939
  }
479724
479940
  saveGlobalConfig(_temp325);
@@ -480403,12 +480619,12 @@ function LogoV2() {
480403
480619
  return t41;
480404
480620
  }
480405
480621
  function _temp325(current) {
480406
- if (current.lastReleaseNotesSeen === "1.80.2") {
480622
+ if (current.lastReleaseNotesSeen === "1.80.4") {
480407
480623
  return current;
480408
480624
  }
480409
480625
  return {
480410
480626
  ...current,
480411
- lastReleaseNotesSeen: "1.80.2"
480627
+ lastReleaseNotesSeen: "1.80.4"
480412
480628
  };
480413
480629
  }
480414
480630
  function _temp241(s_0) {
@@ -491857,7 +492073,7 @@ function ShellDetailDialog(t0) {
491857
492073
  const isMonitor = shell.kind === "monitor";
491858
492074
  let t8;
491859
492075
  if ($2[17] !== shell.command) {
491860
- t8 = truncateToWidth(shell.command, 280);
492076
+ t8 = truncateToWidth(formatCommandForDisplay(shell.command), 280);
491861
492077
  $2[17] = shell.command;
491862
492078
  $2[18] = t8;
491863
492079
  } else {
@@ -496500,7 +496716,7 @@ function compileAgenticCiWorkflow(specName = "default", options2 = {}) {
496500
496716
  if (spec.name !== specName) {
496501
496717
  throw new Error("Agentic CI workflow spec name does not match");
496502
496718
  }
496503
- const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.80.2" : "1.80.2");
496719
+ const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.80.4" : "1.80.4");
496504
496720
  if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(packageVersion)) {
496505
496721
  throw new Error("invalid ur-agent package version");
496506
496722
  }
@@ -497493,7 +497709,7 @@ runner; \`ur trigger\` is the inbound parser that decides what to run.
497493
497709
  path: ".github/workflows/ur.yml",
497494
497710
  root: "project",
497495
497711
  content: compileAgenticCiWorkflow("default", {
497496
- packageVersion: typeof MACRO !== "undefined" ? "1.80.2" : "1.80.2"
497712
+ packageVersion: typeof MACRO !== "undefined" ? "1.80.4" : "1.80.4"
497497
497713
  })
497498
497714
  },
497499
497715
  {
@@ -497556,7 +497772,7 @@ function value(tokens, flag) {
497556
497772
  return index2 >= 0 ? tokens[index2 + 1] : undefined;
497557
497773
  }
497558
497774
  function cliVersion() {
497559
- return typeof MACRO !== "undefined" ? "1.80.2" : "1.80.2";
497775
+ return typeof MACRO !== "undefined" ? "1.80.4" : "1.80.4";
497560
497776
  }
497561
497777
  function workflowPath(cwd2) {
497562
497778
  return join168(cwd2, ".github", "workflows", "ur-agentic-ci.yml");
@@ -503412,7 +503628,7 @@ function createAcpStdioApp(deps) {
503412
503628
  }
503413
503629
  },
503414
503630
  authMethods: [],
503415
- agentInfo: { name: "UR-Nexus", version: "1.80.2" }
503631
+ agentInfo: { name: "UR-Nexus", version: "1.80.4" }
503416
503632
  })).onRequest("authenticate", () => ({})).onRequest("session/new", async (context6) => {
503417
503633
  const result = runtime2.newSession(context6.params.cwd, context6.params.mcpServers, context6.params.additionalDirectories);
503418
503634
  await runtime2.announce({
@@ -503509,7 +503725,7 @@ function createAcpStdioAgent(deps) {
503509
503725
  }
503510
503726
  },
503511
503727
  authMethods: [],
503512
- agentInfo: { name: "UR-Nexus", version: "1.80.2" }
503728
+ agentInfo: { name: "UR-Nexus", version: "1.80.4" }
503513
503729
  });
503514
503730
  return;
503515
503731
  case "authenticate":
@@ -714735,7 +714951,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
714735
714951
  smapsRollup,
714736
714952
  platform: process.platform,
714737
714953
  nodeVersion: process.version,
714738
- ccVersion: "1.80.2"
714954
+ ccVersion: "1.80.4"
714739
714955
  };
714740
714956
  }
714741
714957
  async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
@@ -715324,7 +715540,7 @@ var init_bridge_kick = __esm(() => {
715324
715540
  var call154 = async () => {
715325
715541
  return {
715326
715542
  type: "text",
715327
- value: "1.80.2"
715543
+ value: "1.80.4"
715328
715544
  };
715329
715545
  }, version2, version_default;
715330
715546
  var init_version = __esm(() => {
@@ -726567,7 +726783,7 @@ function generateHtmlReport(data, insights) {
726567
726783
  </html>`;
726568
726784
  }
726569
726785
  function buildExportData(data, insights, facets, remoteStats) {
726570
- const version3 = typeof MACRO !== "undefined" ? "1.80.2" : "unknown";
726786
+ const version3 = typeof MACRO !== "undefined" ? "1.80.4" : "unknown";
726571
726787
  const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
726572
726788
  const facets_summary = {
726573
726789
  total: facets.size,
@@ -730880,7 +731096,7 @@ var init_sessionStorage = __esm(() => {
730880
731096
  init_settings2();
730881
731097
  init_slowOperations();
730882
731098
  init_uuid();
730883
- VERSION7 = typeof MACRO !== "undefined" ? "1.80.2" : "unknown";
731099
+ VERSION7 = typeof MACRO !== "undefined" ? "1.80.4" : "unknown";
730884
731100
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
730885
731101
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
730886
731102
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -732095,7 +732311,7 @@ var init_filesystem = __esm(() => {
732095
732311
  });
732096
732312
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
732097
732313
  const nonce = randomBytes24(16).toString("hex");
732098
- return join243(getURTempDir(), "bundled-skills", "1.80.2", nonce);
732314
+ return join243(getURTempDir(), "bundled-skills", "1.80.4", nonce);
732099
732315
  });
732100
732316
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
732101
732317
  });
@@ -737551,13 +737767,13 @@ function getTaskToolGuidance(enabledTools) {
737551
737767
  const canUpdate = enabledTools.has(TASK_UPDATE_TOOL_NAME);
737552
737768
  const canList = enabledTools.has(TASK_LIST_TOOL_NAME);
737553
737769
  if (canCreate && canUpdate) {
737554
- return `For a request with 3+ distinct steps, multiple independently verifiable outcomes, delegation, dependency ordering, or an explicit user request for a task list, you MUST use ${TASK_CREATE_TOOL_NAME} to maintain the visible task list. Do not create a task merely because a message is actionable: a direct one-step change, informational answer, acknowledgement, or small correction can proceed without a board. Decompose a large request into 2-8 bounded outcomes (never more than 12), each with one observable result, likely file scope, and acceptance evidence; never copy the raw user prompt as a task title. Create tasks first without guessed or forward dependency IDs. After each real ID is returned, use ${TASK_UPDATE_TOOL_NAME} to add dependencies only to tasks that already exist; never reference a future task, and never create a self-dependency. Keep the final graph dependency-ordered; independent branches stay dependency-free. If the user interrupts while tasks are pending or in progress, inspect the active list, preserve still-relevant work, update the affected task, add a task only for a genuinely distinct new outcome, and mark superseded work skipped rather than starting from an empty list. Mark each unblocked task in_progress when work starts and completed immediately after implementation and relevant verification succeed; use failed for attempted work that did not finish, skipped only for explicitly inapplicable work, and leave dependency-blocked work open with its blocker recorded.${canList ? ` Use ${TASK_LIST_TOOL_NAME} after every interruption and to select the next unblocked task; when all work succeeds, show the final list with every task completed before finishing.` : ""}`;
737770
+ return `UR uses a strict-hybrid task policy. Before the first mutation, you MUST use ${TASK_CREATE_TOOL_NAME} for 2+ distinct requested outcomes, enumerated or sequenced work, multiple independently verifiable deliverables, plan-mode implementation, delegation or parallel agents, dependency ordering, project-sized builds/refactors, and release, publishing, deployment, migration, security, credential, permission, sandbox, production, or other high-risk work. An explicit user request for tasks always wins. Only a genuinely atomic, low-risk change with one outcome may proceed directly; informational answers, acknowledgements, and small corrections need no board. Read-only investigation is always allowed before planning. Decompose tracked work into 2-8 bounded outcomes (never more than 12), each with one observable result, likely file scope, and acceptance evidence; never copy the raw user prompt as a task title. Create tasks first without guessed or forward dependency IDs. After each real ID is returned, use ${TASK_UPDATE_TOOL_NAME} to add dependencies only to tasks that already exist; never reference a future task, and never create a self-dependency. Keep the final graph dependency-ordered; independent branches stay dependency-free. If the user interrupts while tasks are pending or in progress, inspect the active list, preserve still-relevant work, update the affected task, add a task only for a genuinely distinct new outcome, and mark superseded work skipped rather than starting from an empty list. Mark each unblocked task in_progress when work starts and completed immediately after implementation and relevant verification succeed; use failed for attempted work that did not finish, skipped only for explicitly inapplicable work, and leave dependency-blocked work open with its blocker recorded.${canList ? ` Use ${TASK_LIST_TOOL_NAME} after every interruption and to select the next unblocked task; when all work succeeds, show the final list with every task completed before finishing.` : ""}`;
737555
737771
  }
737556
737772
  if (canUpdate) {
737557
737773
  return `Keep assigned tasks current with ${TASK_UPDATE_TOOL_NAME}: mark the task in_progress when starting, completed only after implementation and relevant verification succeed, and leave blocked or partial work open with its blocker recorded.${canList ? ` Use ${TASK_LIST_TOOL_NAME} to select the next unblocked task.` : ""}`;
737558
737774
  }
737559
737775
  if (canCreate) {
737560
- return `Use ${TASK_CREATE_TOOL_NAME} for 3+ distinct steps, multiple independently verifiable outcomes, delegation, dependency ordering, or an explicit user request for a task list. A large request should have 2-8 bounded outcomes (never more than 12). Do not create a task merely because a message is actionable; skip a board for direct one-step work, informational answers, acknowledgements, and small corrections. Never copy the raw prompt as a task title. Create tasks without guessed or forward IDs; dependencies may name only tasks whose real IDs have already been returned. Preserve pending or in-progress work after an interruption, update affected work, and add only genuinely distinct new outcomes.`;
737776
+ return `Use ${TASK_CREATE_TOOL_NAME} before mutation for 2+ distinct outcomes, sequenced work, project-sized changes, delegation, dependencies, releases/deployments/migrations, security-sensitive work, or an explicit task-list request. Only a genuinely atomic low-risk change may proceed directly. A tracked request should have 2-8 bounded outcomes (never more than 12). Never copy the raw prompt as a task title. Create tasks without guessed or forward IDs; dependencies may name only tasks whose real IDs have already been returned. Preserve pending or in-progress work after an interruption, update affected work, and add only genuinely distinct new outcomes.`;
737561
737777
  }
737562
737778
  if (enabledTools.has(TODO_WRITE_TOOL_NAME)) {
737563
737779
  return `Track multi-step work with ${TODO_WRITE_TOOL_NAME}. Keep items dependency-ordered and mark each item completed immediately after its implementation and relevant verification succeed.`;
@@ -738484,7 +738700,7 @@ function computeFingerprint(messageText2, version3) {
738484
738700
  }
738485
738701
  function computeFingerprintFromMessages(messages) {
738486
738702
  const firstMessageText = extractFirstMessageText(messages);
738487
- return computeFingerprint(firstMessageText, "1.80.2");
738703
+ return computeFingerprint(firstMessageText, "1.80.4");
738488
738704
  }
738489
738705
  var FINGERPRINT_SALT = "59cf53e54c78";
738490
738706
  var init_fingerprint = () => {};
@@ -740409,7 +740625,7 @@ async function sideQuery(opts) {
740409
740625
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
740410
740626
  }
740411
740627
  const messageText2 = extractFirstUserMessageText(messages);
740412
- const fingerprint2 = computeFingerprint(messageText2, "1.80.2");
740628
+ const fingerprint2 = computeFingerprint(messageText2, "1.80.4");
740413
740629
  const attributionHeader = getAttributionHeader(fingerprint2);
740414
740630
  const systemBlocks = [
740415
740631
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -745243,7 +745459,7 @@ function buildSystemInitMessage(inputs) {
745243
745459
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
745244
745460
  apiKeySource: getURHQApiKeyWithSource().source,
745245
745461
  betas: getSdkBetas(),
745246
- ur_version: "1.80.2",
745462
+ ur_version: "1.80.4",
745247
745463
  output_style: outputStyle,
745248
745464
  agents: inputs.agents.map((agent2) => agent2.agentType),
745249
745465
  skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill2) => skill2.name),
@@ -759079,7 +759295,7 @@ var init_useVoiceEnabled = __esm(() => {
759079
759295
  function getSemverPart(version3) {
759080
759296
  return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
759081
759297
  }
759082
- function useUpdateNotification(updatedVersion, initialVersion = "1.80.2") {
759298
+ function useUpdateNotification(updatedVersion, initialVersion = "1.80.4") {
759083
759299
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react225.useState(() => getSemverPart(initialVersion));
759084
759300
  if (!updatedVersion) {
759085
759301
  return null;
@@ -759128,7 +759344,7 @@ function AutoUpdater({
759128
759344
  return;
759129
759345
  }
759130
759346
  if (false) {}
759131
- const currentVersion = "1.80.2";
759347
+ const currentVersion = "1.80.4";
759132
759348
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
759133
759349
  let latestVersion = await getLatestVersion(channel);
759134
759350
  const isDisabled = isAutoUpdaterDisabled();
@@ -759357,12 +759573,12 @@ function NativeAutoUpdater({
759357
759573
  logEvent("tengu_native_auto_updater_start", {});
759358
759574
  try {
759359
759575
  const maxVersion = await getMaxVersion();
759360
- if (maxVersion && gt("1.80.2", maxVersion)) {
759576
+ if (maxVersion && gt("1.80.4", maxVersion)) {
759361
759577
  const msg = await getMaxVersionMessage();
759362
759578
  setMaxVersionIssue(msg ?? "affects your version");
759363
759579
  }
759364
759580
  const result = await installLatest(channel);
759365
- const currentVersion = "1.80.2";
759581
+ const currentVersion = "1.80.4";
759366
759582
  const latencyMs = Date.now() - startTime;
759367
759583
  if (result.lockFailed) {
759368
759584
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -759499,17 +759715,17 @@ function PackageManagerAutoUpdater(t0) {
759499
759715
  const maxVersion = await getMaxVersion();
759500
759716
  if (maxVersion && latest && gt(latest, maxVersion)) {
759501
759717
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
759502
- if (gte("1.80.2", maxVersion)) {
759503
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.80.2"} is already at or above maxVersion ${maxVersion}, skipping update`);
759718
+ if (gte("1.80.4", maxVersion)) {
759719
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.80.4"} is already at or above maxVersion ${maxVersion}, skipping update`);
759504
759720
  setUpdateAvailable(false);
759505
759721
  return;
759506
759722
  }
759507
759723
  latest = maxVersion;
759508
759724
  }
759509
- const hasUpdate = latest && !gte("1.80.2", latest) && !shouldSkipVersion(latest);
759725
+ const hasUpdate = latest && !gte("1.80.4", latest) && !shouldSkipVersion(latest);
759510
759726
  setUpdateAvailable(!!hasUpdate);
759511
759727
  if (hasUpdate) {
759512
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.80.2"} -> ${latest}`);
759728
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.80.4"} -> ${latest}`);
759513
759729
  }
759514
759730
  };
759515
759731
  $2[0] = t1;
@@ -759543,7 +759759,7 @@ function PackageManagerAutoUpdater(t0) {
759543
759759
  wrap: "truncate",
759544
759760
  children: [
759545
759761
  "currentVersion: ",
759546
- "1.80.2"
759762
+ "1.80.4"
759547
759763
  ]
759548
759764
  }, undefined, true, undefined, this);
759549
759765
  $2[3] = verbose;
@@ -770396,7 +770612,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
770396
770612
  project_dir: getOriginalCwd(),
770397
770613
  added_dirs: addedDirs
770398
770614
  },
770399
- version: "1.80.2",
770615
+ version: "1.80.4",
770400
770616
  output_style: {
770401
770617
  name: outputStyleName
770402
770618
  },
@@ -770531,7 +770747,7 @@ function StatusLineInner({
770531
770747
  const attention = customStatusError ?? taskAttention;
770532
770748
  const terminalSize = React133.useContext(TerminalSizeContext);
770533
770749
  const defaultStatusLineText = buildDefaultStatusBar({
770534
- version: "1.80.2",
770750
+ version: "1.80.4",
770535
770751
  providerLabel: providerRuntime.providerLabel,
770536
770752
  authMode: providerRuntime.authLabel,
770537
770753
  model: renderModelName(mainLoopModel) || providerRuntime.model || "",
@@ -782786,7 +783002,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
782786
783002
  } catch {}
782787
783003
  const data = {
782788
783004
  trigger: trigger2,
782789
- version: "1.80.2",
783005
+ version: "1.80.4",
782790
783006
  platform: process.platform,
782791
783007
  transcript,
782792
783008
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -795155,7 +795371,7 @@ function WelcomeV2() {
795155
795371
  dimColor: true,
795156
795372
  children: [
795157
795373
  "v",
795158
- "1.80.2"
795374
+ "1.80.4"
795159
795375
  ]
795160
795376
  }, undefined, true, undefined, this)
795161
795377
  ]
@@ -796415,7 +796631,7 @@ function completeOnboarding() {
796415
796631
  saveGlobalConfig((current) => ({
796416
796632
  ...current,
796417
796633
  hasCompletedOnboarding: true,
796418
- lastOnboardingVersion: "1.80.2"
796634
+ lastOnboardingVersion: "1.80.4"
796419
796635
  }));
796420
796636
  }
796421
796637
  function showDialog(root2, renderer) {
@@ -801561,7 +801777,7 @@ function appendToLog(path28, message) {
801561
801777
  cwd: getFsImplementation().cwd(),
801562
801778
  userType: process.env.USER_TYPE,
801563
801779
  sessionId: getSessionId(),
801564
- version: "1.80.2"
801780
+ version: "1.80.4"
801565
801781
  };
801566
801782
  getLogWriter(path28).write(messageWithTimestamp);
801567
801783
  }
@@ -805725,8 +805941,8 @@ async function getEnvLessBridgeConfig() {
805725
805941
  }
805726
805942
  async function checkEnvLessBridgeMinVersion() {
805727
805943
  const cfg = await getEnvLessBridgeConfig();
805728
- if (cfg.min_version && lt("1.80.2", cfg.min_version)) {
805729
- return `Your version of UR (${"1.80.2"}) is too old for Remote Control.
805944
+ if (cfg.min_version && lt("1.80.4", cfg.min_version)) {
805945
+ return `Your version of UR (${"1.80.4"}) is too old for Remote Control.
805730
805946
  Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
805731
805947
  }
805732
805948
  return null;
@@ -806200,7 +806416,7 @@ async function initBridgeCore(params) {
806200
806416
  const rawApi = createBridgeApiClient({
806201
806417
  baseUrl,
806202
806418
  getAccessToken,
806203
- runnerVersion: "1.80.2",
806419
+ runnerVersion: "1.80.4",
806204
806420
  onDebug: logForDebugging,
806205
806421
  onAuth401,
806206
806422
  getTrustedDeviceToken
@@ -815673,7 +815889,7 @@ function getAgUiCapabilities() {
815673
815889
  name: "UR-Nexus",
815674
815890
  type: "ur-nexus",
815675
815891
  description: "Provider-flexible, local-first autonomous engineering workflow agent.",
815676
- version: "1.80.2",
815892
+ version: "1.80.4",
815677
815893
  provider: "UR",
815678
815894
  documentationUrl: "https://github.com/Maitham16/UR/blob/master/docs/AG_UI.md"
815679
815895
  },
@@ -816110,6 +816326,102 @@ var init_agUi3 = __esm(() => {
816110
816326
  init_errors();
816111
816327
  });
816112
816328
 
816329
+ // src/cli/handlers/session.ts
816330
+ var exports_session2 = {};
816331
+ __export(exports_session2, {
816332
+ sessionStatusHandler: () => sessionStatusHandler,
816333
+ selectCliSessionStatus: () => selectCliSessionStatus
816334
+ });
816335
+ import { writeSync as writeSync6 } from "fs";
816336
+ import { join as join261, resolve as resolve79 } from "path";
816337
+ function activeStatus(log2) {
816338
+ const sessionId = getSessionIdFromLog(log2);
816339
+ if (!sessionId || !log2.projectPath || !log2.fullPath)
816340
+ return;
816341
+ return {
816342
+ sessionId,
816343
+ status: "resumable",
816344
+ title: log2.customTitle || log2.summary || log2.firstPrompt || null,
816345
+ projectPath: log2.projectPath,
816346
+ storagePath: null,
816347
+ transcriptPath: log2.fullPath,
816348
+ createdAt: log2.created.toISOString(),
816349
+ modifiedAt: log2.modified.toISOString(),
816350
+ archivedAt: null
816351
+ };
816352
+ }
816353
+ function archivedStatus(session2) {
816354
+ return {
816355
+ sessionId: session2.sessionId,
816356
+ status: "archived",
816357
+ title: null,
816358
+ projectPath: null,
816359
+ storagePath: join261(session2.projectDir, ".session-archive", session2.sessionId),
816360
+ transcriptPath: join261(session2.projectDir, ".session-archive", session2.sessionId, "transcript.jsonl"),
816361
+ createdAt: null,
816362
+ modifiedAt: null,
816363
+ archivedAt: session2.archivedAt
816364
+ };
816365
+ }
816366
+ function selectCliSessionStatus(active3, archived, sessionId, cwd4) {
816367
+ if (sessionId) {
816368
+ const activeMatch = active3.find((log2) => getSessionIdFromLog(log2) === sessionId);
816369
+ if (activeMatch)
816370
+ return activeStatus(activeMatch);
816371
+ const archivedMatch = archived.find((item) => item.sessionId === sessionId);
816372
+ return archivedMatch ? archivedStatus(archivedMatch) : undefined;
816373
+ }
816374
+ const projectRoot2 = resolve79(cwd4);
816375
+ const latest = active3.find((log2) => log2.projectPath && resolve79(log2.projectPath) === projectRoot2);
816376
+ return latest ? activeStatus(latest) : undefined;
816377
+ }
816378
+ function writeOutput(text2) {
816379
+ writeSync6(1, text2.endsWith(`
816380
+ `) ? text2 : `${text2}
816381
+ `);
816382
+ }
816383
+ function writeError(text2) {
816384
+ writeSync6(2, text2.endsWith(`
816385
+ `) ? text2 : `${text2}
816386
+ `);
816387
+ }
816388
+ function formatSessionStatus(status2) {
816389
+ const lines = [
816390
+ `Session: ${status2.sessionId}`,
816391
+ `Status: ${status2.status}`
816392
+ ];
816393
+ if (status2.projectPath)
816394
+ lines.push(`Project: ${status2.projectPath}`);
816395
+ if (status2.storagePath)
816396
+ lines.push(`Archive storage: ${status2.storagePath}`);
816397
+ lines.push(`Transcript: ${status2.transcriptPath}`);
816398
+ if (status2.title)
816399
+ lines.push(`Title: ${status2.title.replace(/\s+/gu, " ").slice(0, 120)}`);
816400
+ if (status2.modifiedAt)
816401
+ lines.push(`Last updated: ${status2.modifiedAt}`);
816402
+ if (status2.archivedAt)
816403
+ lines.push(`Archived: ${status2.archivedAt}`);
816404
+ return lines.join(`
816405
+ `);
816406
+ }
816407
+ async function sessionStatusHandler(sessionId, options5 = {}) {
816408
+ const [active3, archived] = await Promise.all([
816409
+ loadAllProjectsMessageLogs(),
816410
+ listArchivedSessions()
816411
+ ]);
816412
+ const status2 = selectCliSessionStatus(active3, archived, sessionId, process.cwd());
816413
+ if (!status2) {
816414
+ writeError(sessionId ? `Session ${sessionId} was not found.` : 'No resumable session was found for the current project. Run "ur session list" to inspect all sessions.');
816415
+ process.exit(1);
816416
+ }
816417
+ writeOutput(options5.json ? JSON.stringify(status2, null, 2) : formatSessionStatus(status2));
816418
+ process.exit(0);
816419
+ }
816420
+ var init_session3 = __esm(() => {
816421
+ init_sessionArchive();
816422
+ init_sessionStorage();
816423
+ });
816424
+
816113
816425
  // src/components/MCPServerDesktopImportDialog.tsx
816114
816426
  function MCPServerDesktopImportDialog(t0) {
816115
816427
  const $2 = import_compiler_runtime359.c(36);
@@ -816804,7 +817116,7 @@ function createMCPServer(cwd4, debug2, verbose) {
816804
817116
  };
816805
817117
  const server2 = new Server({
816806
817118
  name: "ur-nexus",
816807
- version: "1.80.2"
817119
+ version: "1.80.4"
816808
817120
  }, {
816809
817121
  capabilities: {
816810
817122
  tools: {}
@@ -816964,7 +817276,7 @@ import {
816964
817276
  unlinkSync as unlinkSync17,
816965
817277
  writeFileSync as writeFileSync75
816966
817278
  } from "fs";
816967
- import { join as join261 } from "path";
817279
+ import { join as join262 } from "path";
816968
817280
  function isRecord8(value2) {
816969
817281
  return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
816970
817282
  }
@@ -816997,7 +817309,7 @@ function isTask2(value2) {
816997
817309
  return typeof value2.taskId === "string" && ["working", "input_required", "completed", "failed", "cancelled"].includes(String(value2.status)) && typeof value2.createdAt === "string" && typeof value2.lastUpdatedAt === "string" && Number.isFinite(createdAt) && Number.isFinite(lastUpdatedAt) && (value2.ttlMs === null || typeof value2.ttlMs === "number" && Number.isSafeInteger(value2.ttlMs) && value2.ttlMs >= 0);
816998
817310
  }
816999
817311
  function taskManifestPath(cwd4) {
817000
- return join261(cwd4, ".ur", "mcp-2026", "tasks.json");
817312
+ return join262(cwd4, ".ur", "mcp-2026", "tasks.json");
817001
817313
  }
817002
817314
  function quarantineTaskManifest(path28) {
817003
817315
  const destination = `${path28}.corrupt.${new Date().toISOString().replaceAll(/[:.]/g, "-")}.${randomUUID96()}`;
@@ -817011,8 +817323,8 @@ function assertNotSymlink(path28) {
817011
817323
  }
817012
817324
  }
817013
817325
  function prepareTaskDirectory(cwd4) {
817014
- const urDir = join261(cwd4, ".ur");
817015
- const mcpDir = join261(urDir, "mcp-2026");
817326
+ const urDir = join262(cwd4, ".ur");
817327
+ const mcpDir = join262(urDir, "mcp-2026");
817016
817328
  assertNotSymlink(urDir);
817017
817329
  mkdirSync73(urDir, { recursive: true, mode: 448 });
817018
817330
  assertNotSymlink(urDir);
@@ -817140,8 +817452,8 @@ class DurableMcp2026TaskStore {
817140
817452
  async#mutate(operation) {
817141
817453
  const previous = this.#mutationTail;
817142
817454
  let release4;
817143
- this.#mutationTail = new Promise((resolve79) => {
817144
- release4 = resolve79;
817455
+ this.#mutationTail = new Promise((resolve80) => {
817456
+ release4 = resolve80;
817145
817457
  });
817146
817458
  await previous;
817147
817459
  try {
@@ -818008,7 +818320,7 @@ function thrownResponse(error40) {
818008
818320
  }
818009
818321
  async function createUrMcp2026Runtime(options5) {
818010
818322
  const server2 = createMCPServer(options5.cwd, options5.debug === true, options5.verbose === true);
818011
- const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.80.2" }, { capabilities: {} });
818323
+ const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.80.4" }, { capabilities: {} });
818012
818324
  const [clientTransport, serverTransport] = createLinkedTransportPair();
818013
818325
  try {
818014
818326
  await server2.connect(serverTransport);
@@ -818019,7 +818331,7 @@ async function createUrMcp2026Runtime(options5) {
818019
818331
  }
818020
818332
  const runtime2 = new Mcp2026Runtime({
818021
818333
  cwd: options5.cwd,
818022
- version: "1.80.2",
818334
+ version: "1.80.4",
818023
818335
  backend: {
818024
818336
  listTools: async () => {
818025
818337
  const listed = await client2.listTools();
@@ -818175,10 +818487,10 @@ async function serveMcp2026(options5) {
818175
818487
  fetch: handler
818176
818488
  });
818177
818489
  console.log(`MCP ${MCP_2026_PROTOCOL_VERSION} server listening on http://${options5.host}:${server2.port}/mcp`);
818178
- await new Promise((resolve79) => {
818179
- shutdown = resolve79;
818490
+ await new Promise((resolve80) => {
818491
+ shutdown = resolve80;
818180
818492
  for (const signal of signals2)
818181
- process.once(signal, resolve79);
818493
+ process.once(signal, resolve80);
818182
818494
  });
818183
818495
  } finally {
818184
818496
  if (shutdown) {
@@ -818206,14 +818518,14 @@ __export(exports_urDesktop, {
818206
818518
  });
818207
818519
  import { readdir as readdir34, readFile as readFile60, stat as stat54 } from "fs/promises";
818208
818520
  import { homedir as homedir45 } from "os";
818209
- import { join as join262 } from "path";
818521
+ import { join as join263 } from "path";
818210
818522
  async function getURDesktopConfigPath() {
818211
818523
  const platform7 = getPlatform();
818212
818524
  if (!SUPPORTED_PLATFORMS.includes(platform7)) {
818213
818525
  throw new Error(`Unsupported platform: ${platform7} - UR Desktop integration only works on macOS and WSL.`);
818214
818526
  }
818215
818527
  if (platform7 === "macos") {
818216
- return join262(homedir45(), "Library", "Application Support", "UR", "ur_desktop_config.json");
818528
+ return join263(homedir45(), "Library", "Application Support", "UR", "ur_desktop_config.json");
818217
818529
  }
818218
818530
  const windowsHome = process.env.USERPROFILE ? process.env.USERPROFILE.replace(/\\/g, "/") : null;
818219
818531
  if (windowsHome) {
@@ -818232,7 +818544,7 @@ async function getURDesktopConfigPath() {
818232
818544
  if (user.name === "Public" || user.name === "Default" || user.name === "Default User" || user.name === "All Users") {
818233
818545
  continue;
818234
818546
  }
818235
- const potentialConfigPath = join262(usersDir, user.name, "AppData", "Roaming", "UR", "ur_desktop_config.json");
818547
+ const potentialConfigPath = join263(usersDir, user.name, "AppData", "Roaming", "UR", "ur_desktop_config.json");
818236
818548
  try {
818237
818549
  await stat54(potentialConfigPath);
818238
818550
  return potentialConfigPath;
@@ -818658,29 +818970,30 @@ __export(exports_providers, {
818658
818970
  providerModelsHandler: () => providerModelsHandler,
818659
818971
  providerListHandler: () => providerListHandler,
818660
818972
  providerDoctorHandler: () => providerDoctorHandler,
818973
+ providerConfigSetHandler: () => providerConfigSetHandler,
818661
818974
  providerAuthHandler: () => providerAuthHandler,
818662
- configSetHandler: () => configSetHandler
818975
+ PROVIDER_CONFIG_KEYS: () => PROVIDER_CONFIG_KEYS
818663
818976
  });
818664
- import { writeSync as writeSync6 } from "fs";
818665
- function writeOutput(text2) {
818666
- writeSync6(1, text2.endsWith(`
818977
+ import { writeSync as writeSync7 } from "fs";
818978
+ function writeOutput2(text2) {
818979
+ writeSync7(1, text2.endsWith(`
818667
818980
  `) ? text2 : `${text2}
818668
818981
  `);
818669
818982
  }
818670
- function writeError(text2) {
818671
- writeSync6(2, text2.endsWith(`
818983
+ function writeError2(text2) {
818984
+ writeSync7(2, text2.endsWith(`
818672
818985
  `) ? text2 : `${text2}
818673
818986
  `);
818674
818987
  }
818675
818988
  async function providerListHandler(options5 = {}) {
818676
- writeOutput(formatProviderList(Boolean(options5.json)));
818989
+ writeOutput2(formatProviderList(Boolean(options5.json)));
818677
818990
  process.exit(0);
818678
818991
  }
818679
818992
  async function providerStatusHandler(options5 = {}) {
818680
818993
  const settings = getInitialSettings();
818681
818994
  const active3 = getActiveProviderSettings(settings).active ?? "ollama";
818682
818995
  const result = await doctorProvider(active3, { settings });
818683
- writeOutput(formatProviderStatus(result, Boolean(options5.json)));
818996
+ writeOutput2(formatProviderStatus(result, Boolean(options5.json)));
818684
818997
  process.exit(result.ok ? 0 : 1);
818685
818998
  }
818686
818999
  async function providerDoctorHandler(providerArg, options5 = {}) {
@@ -818688,7 +819001,7 @@ async function providerDoctorHandler(providerArg, options5 = {}) {
818688
819001
  if (providerArg) {
818689
819002
  const resolved = resolveProviderId(providerArg);
818690
819003
  if (!resolved) {
818691
- writeError(`Unknown provider "${providerArg}". Run: ur provider list`);
819004
+ writeError2(`Unknown provider "${providerArg}". Run: ur provider list`);
818692
819005
  process.exit(1);
818693
819006
  }
818694
819007
  provider = resolved;
@@ -818696,7 +819009,7 @@ async function providerDoctorHandler(providerArg, options5 = {}) {
818696
819009
  const settings = getInitialSettings();
818697
819010
  const active3 = getActiveProviderSettings(settings).active ?? "ollama";
818698
819011
  const result = await doctorProvider(provider ?? active3, { settings });
818699
- writeOutput(formatProviderDoctor(result, Boolean(options5.json)));
819012
+ writeOutput2(formatProviderDoctor(result, Boolean(options5.json)));
818700
819013
  process.exit(result.ok ? 0 : 1);
818701
819014
  }
818702
819015
  async function providerModelsHandler(providerArg, options5 = {}) {
@@ -818704,7 +819017,7 @@ async function providerModelsHandler(providerArg, options5 = {}) {
818704
819017
  const active3 = getActiveProviderSettings(settings).active ?? "ollama";
818705
819018
  const provider = providerArg ? resolveProviderId(providerArg) : active3;
818706
819019
  if (!provider) {
818707
- writeError(`Unknown provider "${providerArg}". Run: ur provider list`);
819020
+ writeError2(`Unknown provider "${providerArg}". Run: ur provider list`);
818708
819021
  process.exit(1);
818709
819022
  }
818710
819023
  const result = await listModelsForProviderWithSource(provider, { settings });
@@ -818717,10 +819030,10 @@ async function providerModelsHandler(providerArg, options5 = {}) {
818717
819030
  models: result.models
818718
819031
  };
818719
819032
  if (options5.json) {
818720
- writeOutput(JSON.stringify(payload, null, 2));
819033
+ writeOutput2(JSON.stringify(payload, null, 2));
818721
819034
  } else {
818722
819035
  const warning = result.warning ? [`Warning: ${result.warning}`] : [];
818723
- writeOutput([
819036
+ writeOutput2([
818724
819037
  `Provider: ${definition.displayName} (${provider})`,
818725
819038
  `Model source: ${result.source}`,
818726
819039
  ...warning,
@@ -818736,9 +819049,9 @@ async function providerSelectModelHandler(providerArg, values2, options5 = {}) {
818736
819049
  if (!provider) {
818737
819050
  const message = `Unknown provider "${providerArg}". Run: ur provider list`;
818738
819051
  if (options5.json)
818739
- writeOutput(JSON.stringify({ ok: false, message }, null, 2));
819052
+ writeOutput2(JSON.stringify({ ok: false, message }, null, 2));
818740
819053
  else
818741
- writeError(message);
819054
+ writeError2(message);
818742
819055
  process.exit(1);
818743
819056
  }
818744
819057
  const settings = getInitialSettings();
@@ -818748,16 +819061,16 @@ async function providerSelectModelHandler(providerArg, values2, options5 = {}) {
818748
819061
  modelSource: discovered.source
818749
819062
  });
818750
819063
  if (options5.json) {
818751
- writeOutput(JSON.stringify({
819064
+ writeOutput2(JSON.stringify({
818752
819065
  ...result,
818753
819066
  warning: discovered.warning
818754
819067
  }, null, 2));
818755
819068
  } else if (result.ok) {
818756
- writeOutput(result.message);
819069
+ writeOutput2(result.message);
818757
819070
  if (discovered.warning)
818758
- writeError(`Warning: ${discovered.warning}`);
819071
+ writeError2(`Warning: ${discovered.warning}`);
818759
819072
  } else {
818760
- writeError(result.message);
819073
+ writeError2(result.message);
818761
819074
  }
818762
819075
  process.exit(result.ok ? 0 : 1);
818763
819076
  }
@@ -818767,18 +819080,18 @@ async function providerAuthHandler(alias2, options5 = {}) {
818767
819080
  dryRun: options5.dryRun
818768
819081
  });
818769
819082
  if (options5.json) {
818770
- writeOutput(JSON.stringify(result, null, 2));
819083
+ writeOutput2(JSON.stringify(result, null, 2));
818771
819084
  } else if (result.ok) {
818772
- writeOutput(result.message);
819085
+ writeOutput2(result.message);
818773
819086
  } else {
818774
- writeError(result.message);
819087
+ writeError2(result.message);
818775
819088
  }
818776
819089
  process.exit(result.ok ? 0 : 1);
818777
819090
  }
818778
- async function configSetHandler(key, values2) {
819091
+ async function providerConfigSetHandler(key, values2) {
818779
819092
  const value2 = Array.isArray(values2) ? values2.join(" ") : values2;
818780
- if (key !== "provider" && key !== "provider.fallback" && key !== "provider.command_path" && key !== "openai_transport" && key !== "responses.store" && key !== "responses.compact_threshold" && key !== "responses.tool_search" && key !== "model" && key !== "base_url") {
818781
- writeError(`Unsupported config key "${key}". Supported: provider, provider.fallback, provider.command_path, openai_transport, responses.store, responses.compact_threshold, responses.tool_search, model, base_url`);
819093
+ if (!PROVIDER_CONFIG_KEYS.includes(key)) {
819094
+ writeError2(`Unsupported provider config key "${key}". Supported: ${PROVIDER_CONFIG_KEYS.join(", ")}`);
818782
819095
  process.exit(1);
818783
819096
  }
818784
819097
  if (key === "model") {
@@ -818790,7 +819103,7 @@ async function configSetHandler(key, values2) {
818790
819103
  settings
818791
819104
  });
818792
819105
  if (validation.valid === false) {
818793
- writeError(`Invalid model for current provider:
819106
+ writeError2(`Invalid model for current provider:
818794
819107
  Selected provider: ${currentProvider}
818795
819108
  Selected model: ${value2}
818796
819109
  Valid models for ${currentProvider}: ${validation.validModels.join(", ") || "(no models discovered)"}
@@ -818813,7 +819126,7 @@ async function configSetHandler(key, values2) {
818813
819126
  if (validation.valid === false) {
818814
819127
  const validModelsStr = validation.validModels.join(", ") || "(uses dynamic discovery)";
818815
819128
  const suggestedModel = validation.suggestedModel ?? "<model-name>";
818816
- writeError(`Warning: Current model "${currentModel}" is not available for provider "${newProvider}" and will be cleared.
819129
+ writeError2(`Warning: Current model "${currentModel}" is not available for provider "${newProvider}" and will be cleared.
818817
819130
  Valid models for ${newProvider}: ${validModelsStr}
818818
819131
  After changing provider, run /model or: ur config set model ${suggestedModel}`);
818819
819132
  }
@@ -818822,15 +819135,147 @@ async function configSetHandler(key, values2) {
818822
819135
  }
818823
819136
  const result = setSafeProviderConfig(key, value2);
818824
819137
  if (result.ok) {
818825
- writeOutput(result.message);
819138
+ writeOutput2(result.message);
818826
819139
  process.exit(0);
818827
819140
  }
818828
- writeError(result.message);
819141
+ writeError2(result.message);
818829
819142
  process.exit(1);
818830
819143
  }
819144
+ var PROVIDER_CONFIG_KEYS;
818831
819145
  var init_providers2 = __esm(() => {
818832
819146
  init_providerRegistry();
818833
819147
  init_settings2();
819148
+ PROVIDER_CONFIG_KEYS = [
819149
+ "provider",
819150
+ "provider.fallback",
819151
+ "provider.command_path",
819152
+ "openai_transport",
819153
+ "responses.store",
819154
+ "responses.compact_threshold",
819155
+ "responses.tool_search",
819156
+ "model",
819157
+ "base_url"
819158
+ ];
819159
+ });
819160
+
819161
+ // src/cli/handlers/config.ts
819162
+ var exports_config3 = {};
819163
+ __export(exports_config3, {
819164
+ listCliConfigEntries: () => listCliConfigEntries,
819165
+ configSetHandler: () => configSetHandler,
819166
+ configListHandler: () => configListHandler,
819167
+ configGetHandler: () => configGetHandler
819168
+ });
819169
+ import { writeSync as writeSync8 } from "fs";
819170
+ function writeOutput3(text2) {
819171
+ writeSync8(1, text2.endsWith(`
819172
+ `) ? text2 : `${text2}
819173
+ `);
819174
+ }
819175
+ function writeError3(text2) {
819176
+ writeSync8(2, text2.endsWith(`
819177
+ `) ? text2 : `${text2}
819178
+ `);
819179
+ }
819180
+ function providerConfigEntries() {
819181
+ const settings = getInitialSettings();
819182
+ const active3 = getActiveProviderSettings(settings);
819183
+ const configured = settings.provider ?? {};
819184
+ return [
819185
+ { key: "provider", value: active3.active ?? "ollama", category: "provider" },
819186
+ {
819187
+ key: "provider.fallback",
819188
+ value: active3.fallback ?? null,
819189
+ category: "provider"
819190
+ },
819191
+ {
819192
+ key: "provider.command_path",
819193
+ value: active3.commandPath ?? null,
819194
+ category: "provider"
819195
+ },
819196
+ {
819197
+ key: "openai_transport",
819198
+ value: configured.openaiTransport ?? null,
819199
+ category: "provider"
819200
+ },
819201
+ {
819202
+ key: "responses.store",
819203
+ value: configured.responses?.store ?? null,
819204
+ category: "provider"
819205
+ },
819206
+ {
819207
+ key: "responses.compact_threshold",
819208
+ value: configured.responses?.compactThreshold ?? null,
819209
+ category: "provider"
819210
+ },
819211
+ {
819212
+ key: "responses.tool_search",
819213
+ value: configured.responses?.toolSearch ?? null,
819214
+ category: "provider"
819215
+ },
819216
+ { key: "model", value: active3.model ?? null, category: "provider" },
819217
+ { key: "base_url", value: active3.baseUrl ?? null, category: "provider" }
819218
+ ];
819219
+ }
819220
+ function listCliConfigEntries() {
819221
+ return [
819222
+ ...getConfigAssignmentValues().map((entry) => ({
819223
+ ...entry,
819224
+ category: "agent"
819225
+ })),
819226
+ ...providerConfigEntries()
819227
+ ];
819228
+ }
819229
+ function textValue(value2) {
819230
+ return value2 === null ? "(not set)" : String(value2);
819231
+ }
819232
+ function findEntry(key) {
819233
+ const assignmentKey = resolveConfigAssignmentKey(key);
819234
+ const canonical = assignmentKey ?? key.toLowerCase();
819235
+ return listCliConfigEntries().find((entry) => entry.key === canonical);
819236
+ }
819237
+ async function configSetHandler(key, values2) {
819238
+ const value2 = Array.isArray(values2) ? values2.join(" ") : values2;
819239
+ if (resolveConfigAssignmentKey(key)) {
819240
+ const parsed = parseConfigAssignments(`${key}=${value2}`);
819241
+ if (parsed.error) {
819242
+ writeError3(parsed.error);
819243
+ process.exit(1);
819244
+ }
819245
+ const result = applyConfigAssignments(parsed.assignments);
819246
+ if (result.error) {
819247
+ writeError3(result.error);
819248
+ process.exit(1);
819249
+ }
819250
+ writeOutput3(`Updated ${result.applied.join(", ")}.`);
819251
+ process.exit(0);
819252
+ }
819253
+ if (!PROVIDER_CONFIG_KEYS.includes(key)) {
819254
+ writeError3(`Unsupported config key "${key}". Run "ur config list" to see supported settings.`);
819255
+ process.exit(1);
819256
+ }
819257
+ await providerConfigSetHandler(key, value2);
819258
+ }
819259
+ function configGetHandler(key, options5 = {}) {
819260
+ const entry = findEntry(key);
819261
+ if (!entry) {
819262
+ writeError3(`Unknown config key "${key}". Run "ur config list" to see supported settings.`);
819263
+ process.exit(1);
819264
+ }
819265
+ writeOutput3(options5.json ? JSON.stringify(entry, null, 2) : `${entry.key}=${textValue(entry.value)}`);
819266
+ process.exit(0);
819267
+ }
819268
+ function configListHandler(options5 = {}) {
819269
+ const entries = listCliConfigEntries();
819270
+ writeOutput3(options5.json ? JSON.stringify(entries, null, 2) : entries.map((entry) => `${entry.key}=${textValue(entry.value)}`).join(`
819271
+ `));
819272
+ process.exit(0);
819273
+ }
819274
+ var init_config11 = __esm(() => {
819275
+ init_configAssignments();
819276
+ init_providerRegistry();
819277
+ init_settings2();
819278
+ init_providers2();
818834
819279
  });
818835
819280
 
818836
819281
  // src/utils/plugins/pluginDiscovery.ts
@@ -819193,9 +819638,9 @@ var init_pluginDiscovery = __esm(() => {
819193
819638
 
819194
819639
  // src/utils/plugins/pluginDoctor.ts
819195
819640
  import { existsSync as existsSync105, readdirSync as readdirSync42, readFileSync as readFileSync95, statSync as statSync39 } from "fs";
819196
- import { basename as basename68, join as join263 } from "path";
819641
+ import { basename as basename68, join as join264 } from "path";
819197
819642
  function manifestPathFor3(dir) {
819198
- const p2 = join263(dir, ".ur-plugin", "plugin.json");
819643
+ const p2 = join264(dir, ".ur-plugin", "plugin.json");
819199
819644
  return existsSync105(p2) ? p2 : null;
819200
819645
  }
819201
819646
  function discoverPluginDirs(roots) {
@@ -819221,7 +819666,7 @@ function discoverPluginDirs(roots) {
819221
819666
  continue;
819222
819667
  }
819223
819668
  for (const entry of entries) {
819224
- const full = join263(root2, entry);
819669
+ const full = join264(root2, entry);
819225
819670
  try {
819226
819671
  if (statSync39(full).isDirectory() && manifestPathFor3(full))
819227
819672
  add(full);
@@ -819354,7 +819799,7 @@ __export(exports_plugins, {
819354
819799
  VALID_UPDATE_SCOPES: () => VALID_UPDATE_SCOPES,
819355
819800
  VALID_INSTALLABLE_SCOPES: () => VALID_INSTALLABLE_SCOPES
819356
819801
  });
819357
- import { basename as basename69, dirname as dirname103, join as join264, resolve as resolve79 } from "path";
819802
+ import { basename as basename69, dirname as dirname103, join as join265, resolve as resolve80 } from "path";
819358
819803
  function handleMarketplaceError(error40, action3) {
819359
819804
  logError2(error40);
819360
819805
  cliError(`${figures_default.cross} Failed to ${action3}: ${errorMessage2(error40)}`);
@@ -819435,8 +819880,8 @@ function printValidationResult(result) {
819435
819880
  async function pluginDoctorHandler(options5) {
819436
819881
  const roots = [];
819437
819882
  if (options5.path)
819438
- roots.push(resolve79(options5.path));
819439
- roots.push(join264(process.cwd(), ".ur", "plugins"));
819883
+ roots.push(resolve80(options5.path));
819884
+ roots.push(join265(process.cwd(), ".ur", "plugins"));
819440
819885
  try {
819441
819886
  const data = loadInstalledPluginsV2();
819442
819887
  for (const installations of Object.values(data.plugins ?? {})) {
@@ -819985,12 +820430,12 @@ __export(exports_install, {
819985
820430
  install: () => install
819986
820431
  });
819987
820432
  import { homedir as homedir46 } from "os";
819988
- import { join as join265 } from "path";
820433
+ import { join as join266 } from "path";
819989
820434
  function getInstallationPath2() {
819990
820435
  const isWindows2 = env2.platform === "win32";
819991
820436
  const homeDir = homedir46();
819992
820437
  if (isWindows2) {
819993
- const windowsPath = join265(homeDir, ".local", "bin", "ur.exe");
820438
+ const windowsPath = join266(homeDir, ".local", "bin", "ur.exe");
819994
820439
  return windowsPath.replace(/\//g, "\\");
819995
820440
  }
819996
820441
  return "~/.local/bin/ur";
@@ -820351,7 +820796,7 @@ async function setupTokenHandler(root2) {
820351
820796
  const {
820352
820797
  ConsoleOAuthFlow: ConsoleOAuthFlow2
820353
820798
  } = await Promise.resolve().then(() => (init_ConsoleOAuthFlow(), exports_ConsoleOAuthFlow));
820354
- await new Promise((resolve80) => {
820799
+ await new Promise((resolve81) => {
820355
820800
  root2.render(/* @__PURE__ */ jsx_dev_runtime483.jsxDEV(AppStateProvider, {
820356
820801
  onChangeAppState,
820357
820802
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(KeybindingSetup, {
@@ -820375,7 +820820,7 @@ async function setupTokenHandler(root2) {
820375
820820
  }, undefined, true, undefined, this),
820376
820821
  /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(ConsoleOAuthFlow2, {
820377
820822
  onDone: () => {
820378
- resolve80();
820823
+ resolve81();
820379
820824
  },
820380
820825
  mode: "setup-token",
820381
820826
  startingMessage: "This will guide you through long-lived (1-year) auth token setup for your UR account. UR subscription required."
@@ -820411,7 +820856,7 @@ function DoctorWithPlugins(t0) {
820411
820856
  }
820412
820857
  async function doctorHandler(root2) {
820413
820858
  logEvent("tengu_doctor_command", {});
820414
- await new Promise((resolve80) => {
820859
+ await new Promise((resolve81) => {
820415
820860
  root2.render(/* @__PURE__ */ jsx_dev_runtime483.jsxDEV(AppStateProvider, {
820416
820861
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(KeybindingSetup, {
820417
820862
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(MCPConnectionManager, {
@@ -820419,7 +820864,7 @@ async function doctorHandler(root2) {
820419
820864
  isStrictMcpConfig: false,
820420
820865
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(DoctorWithPlugins, {
820421
820866
  onDone: () => {
820422
- resolve80();
820867
+ resolve81();
820423
820868
  }
820424
820869
  }, undefined, false, undefined, this)
820425
820870
  }, undefined, false, undefined, this)
@@ -820437,14 +820882,14 @@ async function installHandler(target, options5) {
820437
820882
  const {
820438
820883
  install: install2
820439
820884
  } = await Promise.resolve().then(() => (init_install(), exports_install));
820440
- await new Promise((resolve80) => {
820885
+ await new Promise((resolve81) => {
820441
820886
  const args = [];
820442
820887
  if (target)
820443
820888
  args.push(target);
820444
820889
  if (options5.force)
820445
820890
  args.push("--force");
820446
820891
  install2.call((result) => {
820447
- resolve80();
820892
+ resolve81();
820448
820893
  process.exit(result.includes("failed") ? 1 : 0);
820449
820894
  }, {}, args);
820450
820895
  });
@@ -820621,7 +821066,7 @@ async function update() {
820621
821066
  logEvent("tengu_update_check", {});
820622
821067
  const diagnostic2 = await getDoctorDiagnostic();
820623
821068
  const result = await checkUpgradeStatus({
820624
- currentVersion: "1.80.2",
821069
+ currentVersion: "1.80.4",
820625
821070
  packageName: UR_AGENT_PACKAGE_NAME,
820626
821071
  installationType: diagnostic2.installationType,
820627
821072
  latestVersion: () => getLatestNpmPackageVersion(UR_AGENT_PACKAGE_NAME)
@@ -820649,7 +821094,7 @@ __export(exports_main, {
820649
821094
  main: () => main
820650
821095
  });
820651
821096
  import { readFileSync as readFileSync96 } from "fs";
820652
- import { resolve as resolve80 } from "path";
821097
+ import { resolve as resolve81 } from "path";
820653
821098
  function logManagedSettings() {
820654
821099
  try {
820655
821100
  const policySettings = getSettingsForSource("policySettings");
@@ -821228,12 +821673,12 @@ ${getTmuxInstallInstructions2()}
821228
821673
  process.exit(1);
821229
821674
  }
821230
821675
  try {
821231
- const filePath = resolve80(options5.systemPromptFile);
821676
+ const filePath = resolve81(options5.systemPromptFile);
821232
821677
  systemPrompt = readFileSync96(filePath, "utf8");
821233
821678
  } catch (error40) {
821234
821679
  const code = getErrnoCode(error40);
821235
821680
  if (code === "ENOENT") {
821236
- process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve80(options5.systemPromptFile)}
821681
+ process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve81(options5.systemPromptFile)}
821237
821682
  `));
821238
821683
  process.exit(1);
821239
821684
  }
@@ -821250,12 +821695,12 @@ ${getTmuxInstallInstructions2()}
821250
821695
  process.exit(1);
821251
821696
  }
821252
821697
  try {
821253
- const filePath = resolve80(options5.appendSystemPromptFile);
821698
+ const filePath = resolve81(options5.appendSystemPromptFile);
821254
821699
  appendSystemPrompt = readFileSync96(filePath, "utf8");
821255
821700
  } catch (error40) {
821256
821701
  const code = getErrnoCode(error40);
821257
821702
  if (code === "ENOENT") {
821258
- process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve80(options5.appendSystemPromptFile)}
821703
+ process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve81(options5.appendSystemPromptFile)}
821259
821704
  `));
821260
821705
  process.exit(1);
821261
821706
  }
@@ -821301,7 +821746,7 @@ ${addendum}` : addendum;
821301
821746
  errors4 = result.errors;
821302
821747
  }
821303
821748
  } else {
821304
- const configPath2 = resolve80(configItem);
821749
+ const configPath2 = resolve81(configItem);
821305
821750
  const result = parseMcpConfigFromFilePath({
821306
821751
  filePath: configPath2,
821307
821752
  expandVars: true,
@@ -821949,7 +822394,7 @@ ${customInstructions}` : customInstructions;
821949
822394
  }
821950
822395
  }
821951
822396
  logForDiagnosticsNoPII("info", "started", {
821952
- version: "1.80.2",
822397
+ version: "1.80.4",
821953
822398
  is_native_binary: isInBundledMode()
821954
822399
  });
821955
822400
  registerCleanup(async () => {
@@ -822154,8 +822599,8 @@ ${customInstructions}` : customInstructions;
822154
822599
  return connectMcpBatch(dedupedURAi, "urai");
822155
822600
  });
822156
822601
  let uraiTimer;
822157
- const uraiTimedOut = await Promise.race([uraiConnect.then(() => false), new Promise((resolve81) => {
822158
- uraiTimer = setTimeout((r) => r(true), UR_AI_MCP_TIMEOUT_MS, resolve81);
822602
+ const uraiTimedOut = await Promise.race([uraiConnect.then(() => false), new Promise((resolve82) => {
822603
+ uraiTimer = setTimeout((r) => r(true), UR_AI_MCP_TIMEOUT_MS, resolve82);
822159
822604
  })]);
822160
822605
  if (uraiTimer)
822161
822606
  clearTimeout(uraiTimer);
@@ -822736,7 +823181,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
822736
823181
  pendingHookMessages
822737
823182
  }, renderAndRun);
822738
823183
  }
822739
- }).version("1.80.2 (UR-Nexus)", "-v, --version", "Output the version number");
823184
+ }).version("1.80.4 (UR-Nexus)", "-v, --version", "Output the version number");
822740
823185
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
822741
823186
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
822742
823187
  if (canUserConfigureAdvisor()) {
@@ -822788,7 +823233,13 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
822788
823233
  permissionMode
822789
823234
  });
822790
823235
  });
822791
- const sessionCli = program2.command("session").description("List, archive, and restore local conversation sessions").configureHelp(createSortedHelpConfig());
823236
+ const sessionCli = program2.command("session").description("Inspect, list, archive, and restore local conversation sessions").configureHelp(createSortedHelpConfig());
823237
+ sessionCli.command("status [session-id]").description("Show a session, or the latest resumable session for this project").option("--json", "Output structured JSON").action(async (sessionId, options5) => {
823238
+ const {
823239
+ sessionStatusHandler: sessionStatusHandler2
823240
+ } = await Promise.resolve().then(() => (init_session3(), exports_session2));
823241
+ await sessionStatusHandler2(sessionId, options5);
823242
+ });
822792
823243
  sessionCli.command("list").description("List resumable and archived conversations").option("--json", "Output structured JSON").action(async ({
822793
823244
  json: json2
822794
823245
  }) => {
@@ -822987,12 +823438,24 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
822987
823438
  await providerSelectModelHandler2(providerArg, model, options5);
822988
823439
  });
822989
823440
  const configCmd = program2.command("config").description("Manage safe UR-Nexus settings").configureHelp(createSortedHelpConfig());
822990
- configCmd.command("set <key> <value...>").description("Set a safe non-secret setting: provider, provider.fallback, provider.command_path, model, or base_url").action(async (key, value2) => {
823441
+ configCmd.command("set <key> <value...>").description("Set a validated agent, accessibility, editor, or provider setting").action(async (key, value2) => {
822991
823442
  const {
822992
823443
  configSetHandler: configSetHandler2
822993
- } = await Promise.resolve().then(() => (init_providers2(), exports_providers));
823444
+ } = await Promise.resolve().then(() => (init_config11(), exports_config3));
822994
823445
  await configSetHandler2(key, value2);
822995
823446
  });
823447
+ configCmd.command("get <key>").description("Show one effective safe setting").option("--json", "Output structured JSON").action(async (key, options5) => {
823448
+ const {
823449
+ configGetHandler: configGetHandler2
823450
+ } = await Promise.resolve().then(() => (init_config11(), exports_config3));
823451
+ configGetHandler2(key, options5);
823452
+ });
823453
+ configCmd.command("list").description("List effective safe settings and their current values").option("--json", "Output structured JSON").action(async (options5) => {
823454
+ const {
823455
+ configListHandler: configListHandler2
823456
+ } = await Promise.resolve().then(() => (init_config11(), exports_config3));
823457
+ configListHandler2(options5);
823458
+ });
822996
823459
  program2.command("connect [action] [provider]").description("Connect a provider account: subscription login (Codex, Claude, Gemini) or store an API key").option("--key <key>", "API key to store for an API provider").option("--json", "Output as JSON").action(async (action3, providerArg, opts) => {
822997
823460
  const args = [action3 ? quoteLocalCommandArg(action3) : undefined, providerArg ? quoteLocalCommandArg(providerArg) : undefined, opts.key ? `--key ${quoteLocalCommandArg(opts.key)}` : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
822998
823461
  await runLocalTextCommand(() => Promise.resolve().then(() => (init_connect(), exports_connect)), args);
@@ -823400,11 +823863,12 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
823400
823863
  await runLocalTextCommand(() => Promise.resolve().then(() => (init_role_mode(), exports_role_mode)), args);
823401
823864
  });
823402
823865
  const a2a = program2.command("a2a").description("Agent-to-Agent interoperability, discovery, and delegation utilities").configureHelp(createSortedHelpConfig());
823403
- a2a.command("card").description("Print an A2A Agent Card preview").option("--base-url <url>", "Base URL to use for the Agent Card endpoint").option("--compact", "Output compact JSON").action(async (opts) => {
823866
+ a2a.command("card").description("Print an A2A Agent Card preview").option("--base-url <url>", "Base URL to use for the Agent Card endpoint").option("--v1", "Print the current A2A 1.0 Agent Card instead of the legacy 0.3 card").option("--compact", "Output compact JSON").action(async (opts) => {
823404
823867
  const {
823405
- formatA2AAgentCard: formatA2AAgentCard2
823868
+ formatA2AAgentCard: formatA2AAgentCard2,
823869
+ formatA2AV1AgentCard: formatA2AV1AgentCard2
823406
823870
  } = await Promise.resolve().then(() => (init_trends(), exports_trends));
823407
- console.log(formatA2AAgentCard2({
823871
+ console.log((opts.v1 ? formatA2AV1AgentCard2 : formatA2AAgentCard2)({
823408
823872
  baseUrl: opts.baseUrl
823409
823873
  }, !opts.compact));
823410
823874
  process.exit(0);
@@ -823844,7 +824308,7 @@ if (false) {}
823844
824308
  async function main2() {
823845
824309
  const args = process.argv.slice(2);
823846
824310
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
823847
- console.log(`${"1.80.2"} (UR-Nexus)`);
824311
+ console.log(`${"1.80.4"} (UR-Nexus)`);
823848
824312
  return;
823849
824313
  }
823850
824314
  if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {