ur-agent 1.80.3 → 1.80.5

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.3"}`;
107787
+ return `ur/${"1.80.5"}`;
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.3"} (${process.env.USER_TYPE}, ${process.env.UR_CODE_ENTRYPOINT ?? "cli"}${agentSdkVersion}${clientApp}${workloadSuffix})`;
107809
+ return `ur-cli/${"1.80.5"} (${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.3"}${suffix}`;
107823
+ return `ur/${"1.80.5"}${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.3",
107961
+ appVersion: "1.80.5",
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.3".match(/^\d+\.\d+\.\d+(?:-[a-z]+)?/);
115848
+ const match = "1.80.5".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.3",
115888
+ version: "1.80.5",
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.3"
116558
+ [import_semantic_conventions4.ATTR_SERVICE_VERSION]: "1.80.5"
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.3");
116586
+ firstPartyEventLogger = firstPartyEventLoggerProvider.getLogger("com.urhq.ur.events", "1.80.5");
116587
116587
  }
116588
116588
  async function reinitialize1PEventLoggingIfConfigChanged() {
116589
116589
  if (!is1PEventLoggingEnabled() || !firstPartyEventLoggerProvider) {
@@ -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.3", 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.5", 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.3"}.${fingerprint}`;
129439
+ const version2 = `${"1.80.5"}.${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.3");
184633
+ const meter = import_api10.metrics.getMeter("ur-agent.gen_ai", "1.80.5");
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.3"
184731
+ "gen_ai.agent.version": "1.80.5"
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.3").startSpan(name, { kind: import_api10.SpanKind.INTERNAL, attributes });
184752
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.5").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.3").startSpan(operation, { kind: import_api10.SpanKind.INTERNAL, attributes });
184790
+ return import_api10.trace.getTracer("ur-agent.gen_ai", "1.80.5").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.3";
278505
+ attributes["app.version"] = "1.80.5";
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.3";
319496
+ return "1.80.5";
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.3",
326866
+ version: "1.80.5",
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.3",
327227
+ version: "1.80.5",
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.3"
339965
+ [import_semantic_conventions7.ATTR_SERVICE_VERSION]: "1.80.5"
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.3");
339998
+ const meter = meterProvider.getMeter("ur-agent", "1.80.5");
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.3"));
340002
+ setEventLogger(loggerProvider.getLogger("ur-agent.events", "1.80.5"));
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.3", versionConfig.minVersion)) {
340664
+ if (versionConfig.minVersion && lt("1.80.5", versionConfig.minVersion)) {
340660
340665
  console.error(`
340661
- It looks like your version of UR (${"1.80.3"}) needs an update.
340666
+ It looks like your version of UR (${"1.80.5"}) 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.3"
340882
+ currentVersion: "1.80.5"
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.3"
340891
+ currentVersion: "1.80.5"
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.3" : "unknown";
341426
+ const version2 = typeof MACRO !== "undefined" ? "1.80.5" : "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.3", maxVersion)) {
342357
- logForDebugging(`Native installer: current version ${"1.80.3"} is already at or above maxVersion ${maxVersion}, skipping update`);
342361
+ if (gte("1.80.5", maxVersion)) {
342362
+ logForDebugging(`Native installer: current version ${"1.80.5"} 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.3" && await versionIsAvailable(version2) && await isPossibleURBinary(executablePath)) {
342373
+ if (!forceReinstall && version2 === "1.80.5" && 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.
@@ -395809,9 +396172,12 @@ var init_prompt15 = __esm(() => {
395809
396172
 
395810
396173
  ## How This Tool Works
395811
396174
  - You should have already written your plan to the plan file specified in the plan mode system message
396175
+ - Writing or editing that exact plan file is allowed without an existing task list
396176
+ - TaskCreate, TaskUpdate, TaskList, and TaskGet remain available during planning
395812
396177
  - This tool does NOT take the plan content as a parameter - it will read the plan from the file you wrote
395813
396178
  - This tool simply signals that you're done planning and ready for the user to review and approve
395814
396179
  - The user will see the contents of your plan file when they review it
396180
+ - After approval, this tool preserves any existing visible tasks or creates a bounded implementation and verification task list before coding begins
395815
396181
 
395816
396182
  ## When to Use This Tool
395817
396183
  IMPORTANT: Only use this tool when the task requires planning the implementation steps of a task that requires writing code. For research tasks where you're gathering information, searching files, reading files or in general trying to understand the codebase - do NOT use this tool.
@@ -395831,6 +396197,551 @@ Ensure your plan is complete and unambiguous:
395831
396197
  `;
395832
396198
  });
395833
396199
 
396200
+ // src/services/tools/taskListGate.ts
396201
+ function getTaskListGateConfig() {
396202
+ const configured = getInitialSettings()?.tasks?.requireBeforeChanges;
396203
+ if (!configured)
396204
+ return TASK_LIST_GATE_DEFAULTS;
396205
+ return {
396206
+ enabled: typeof configured.enabled === "boolean" ? configured.enabled : TASK_LIST_GATE_DEFAULTS.enabled,
396207
+ freeReads: typeof configured.freeReads === "number" && Number.isInteger(configured.freeReads) && configured.freeReads >= 0 ? configured.freeReads : TASK_LIST_GATE_DEFAULTS.freeReads
396208
+ };
396209
+ }
396210
+ function isMutatingTool2(toolName) {
396211
+ return !GATE_EXEMPT_TOOLS.has(toolName) && KNOWN_MUTATING_TOOLS.has(toolName);
396212
+ }
396213
+ function isTaskListGateExempt(toolName) {
396214
+ return GATE_EXEMPT_TOOLS.has(toolName);
396215
+ }
396216
+ function countActionableTasksForGate(tasks) {
396217
+ return tasks.filter((task) => !task.metadata?._internal && !isAutomaticPromptTask(task) && (task.status === "pending" || task.status === "in_progress")).length;
396218
+ }
396219
+ function checkTaskListGate(input) {
396220
+ const config3 = input.config ?? getTaskListGateConfig();
396221
+ if (!config3.enabled)
396222
+ return { allowed: true };
396223
+ if (input.taskListWriterAvailable === false)
396224
+ return { allowed: true };
396225
+ if (isTaskListGateExempt(input.toolName))
396226
+ return { allowed: true };
396227
+ if (input.isPlanningArtifact === true)
396228
+ return { allowed: true };
396229
+ const isMutating = input.isMutating ?? isMutatingTool2(input.toolName);
396230
+ if (!isMutating)
396231
+ return { allowed: true };
396232
+ if (input.taskCount !== null && input.taskCount > 0) {
396233
+ return { allowed: true };
396234
+ }
396235
+ const inherentlyRequiresTaskList = input.isSubagent || ALWAYS_REQUIRE_PLAN_TOOLS.has(input.toolName);
396236
+ const classifiedRequirement = input.requiresTaskList === true;
396237
+ const forceEveryMutation = config3.freeReads === 0;
396238
+ const unclassifiedAllowanceExpired = input.requiresTaskList === undefined && input.readsSoFar >= config3.freeReads;
396239
+ const gateRequired = inherentlyRequiresTaskList || classifiedRequirement || forceEveryMutation || unclassifiedAllowanceExpired;
396240
+ const requirementContext = input.requirementReason ? ` This turn requires task tracking because it contains ${input.requirementReason}.` : "";
396241
+ const planningRecovery = input.requirementReason === "planning workflow" ? " EnterPlanMode and plan updates do not create the visible task list." : "";
396242
+ if (input.taskCount === null) {
396243
+ return {
396244
+ allowed: false,
396245
+ 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.`
396246
+ };
396247
+ }
396248
+ if (!gateRequired)
396249
+ return { allowed: true };
396250
+ if (inherentlyRequiresTaskList) {
396251
+ return {
396252
+ allowed: false,
396253
+ 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.`
396254
+ };
396255
+ }
396256
+ return {
396257
+ allowed: false,
396258
+ 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.`
396259
+ };
396260
+ }
396261
+ var TASK_LIST_GATE_DEFAULTS, KNOWN_MUTATING_TOOLS, GATE_EXEMPT_TOOLS, ALWAYS_REQUIRE_PLAN_TOOLS;
396262
+ var init_taskListGate = __esm(() => {
396263
+ init_settings2();
396264
+ init_tasks();
396265
+ TASK_LIST_GATE_DEFAULTS = {
396266
+ enabled: true,
396267
+ freeReads: 3
396268
+ };
396269
+ KNOWN_MUTATING_TOOLS = new Set([
396270
+ "Edit",
396271
+ "MultiEdit",
396272
+ "Write",
396273
+ "NotebookEdit",
396274
+ "Bash",
396275
+ "Shell",
396276
+ "PowerShell",
396277
+ "Computer",
396278
+ "Agent",
396279
+ "Task",
396280
+ "REPL"
396281
+ ]);
396282
+ GATE_EXEMPT_TOOLS = new Set([
396283
+ "TaskCreate",
396284
+ "TaskUpdate",
396285
+ "TaskList",
396286
+ "TaskGet",
396287
+ "TodoWrite",
396288
+ "ExitPlanMode"
396289
+ ]);
396290
+ ALWAYS_REQUIRE_PLAN_TOOLS = new Set([
396291
+ "Agent",
396292
+ "Task"
396293
+ ]);
396294
+ });
396295
+
396296
+ // src/utils/taskListRunContext.ts
396297
+ import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
396298
+ import { randomUUID as randomUUID40 } from "crypto";
396299
+ function runWithTaskListRun(run2, fn) {
396300
+ return taskListRunStorage.run({ run: run2 }, fn);
396301
+ }
396302
+ function getTaskListRunContext() {
396303
+ return taskListRunStorage.getStore()?.run;
396304
+ }
396305
+ function textFromQueuedCommand(command) {
396306
+ if (command.preExpansionValue)
396307
+ return command.preExpansionValue;
396308
+ if (typeof command.value === "string")
396309
+ return command.value;
396310
+ return command.value.filter((block2) => block2.type === "text").map((block2) => ("text" in block2) ? block2.text : "").join(`
396311
+ `);
396312
+ }
396313
+ function textFromMessage(message) {
396314
+ const content = message.message?.content;
396315
+ if (typeof content === "string")
396316
+ return content;
396317
+ if (!Array.isArray(content))
396318
+ return "";
396319
+ return content.filter((block2) => block2.type === "text").map((block2) => ("text" in block2) ? block2.text : "").join(`
396320
+ `);
396321
+ }
396322
+ function requestsAppendToCurrentTaskList(input) {
396323
+ const normalized = input.replace(/\s+/gu, " ").trim().toLowerCase();
396324
+ if (!normalized)
396325
+ return false;
396326
+ return /\b(?:add|append|put|queue)\b.{0,100}\b(?:current|existing|active|same)\s+(?:task\s+)?list\b/u.test(normalized) || /\b(?:add|append|put|queue)\b.{0,100}\b(?:current|existing|active)\s+tasks\b/u.test(normalized) || /\b(?:add|append|put|queue)\s+(?:this|it)\s+(?:to|on)\s+(?:my|the|your)\s+(?:current\s+)?(?:task\s+)?list\b/u.test(normalized) || /\b(?:current|existing|active|same)\s+(?:task\s+)?list\b.{0,100}\b(?:add|append|put|queue)\b/u.test(normalized) || /\b(?:keep|continue|use)\b.{0,100}\b(?:current|existing|active|same)\s+(?:task\s+)?list\b/u.test(normalized);
396327
+ }
396328
+ function requestsContinueCurrentTaskList(input) {
396329
+ const normalized = input.replace(/\s+/gu, " ").trim().toLowerCase().replace(/[.!?]+$/gu, "").trim();
396330
+ if (!normalized || normalized.length > 80)
396331
+ return false;
396332
+ return /^(?:ok(?:ay)?|yes|yep|yup|sure|approved|i approve|looks good|sounds good)$/u.test(normalized) || /^(?:please\s+)?(?:continue|proceed|go ahead|carry on|do it|start(?: now)?|begin implementation|start implementation)$/u.test(normalized) || /^(?:ok(?:ay)?|yes|sure|approved|i approve)[, ]+(?:please\s+)?(?:continue|proceed|go ahead|carry on|do it|start(?: now)?|begin implementation|start implementation)$/u.test(normalized);
396333
+ }
396334
+ function requestsRevisionOfCurrentTaskList(input) {
396335
+ const normalized = input.replace(/\s+/gu, " ").trim().toLowerCase();
396336
+ if (!normalized || normalized.length > 500)
396337
+ return false;
396338
+ return /^(?:no|also|and|but|actually|instead|still|again|not yet|(?:it|this|that)\s+still)\b/u.test(normalized) || /\b(?:why did (?:you|u)|i (?:said|asked|meant)|you (?:removed|deleted|changed|forgot|missed))\b/u.test(normalized) || /^(?:please\s+)?(?:fix|change|update|restore|keep|remove|add)\s+(?:it|that|this)\b/u.test(normalized) || /^(?:please\s+)?(?:do not|don't)\s+(?:remove|delete|change|replace|forget)\b/u.test(normalized);
396339
+ }
396340
+ function shouldKeepCurrentTaskList(input) {
396341
+ return requestsAppendToCurrentTaskList(input) || requestsContinueCurrentTaskList(input) || requestsRevisionOfCurrentTaskList(input);
396342
+ }
396343
+ function withoutCode(input) {
396344
+ return input.replace(/```[\s\S]*?```/gu, " ").replace(/`[^`\n]*`/gu, " ");
396345
+ }
396346
+ function proseOnly(input) {
396347
+ return withoutCode(input).replace(/\s+/gu, " ").trim();
396348
+ }
396349
+ function taskListRequirementReason(input) {
396350
+ const text2 = proseOnly(input);
396351
+ if (!text2)
396352
+ return;
396353
+ 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);
396354
+ if (optsOut)
396355
+ return;
396356
+ 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)) {
396357
+ return "explicit task tracking request";
396358
+ }
396359
+ 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)) {
396360
+ return "planning workflow";
396361
+ }
396362
+ if (/\b(?:delegate|delegation|sub[ -]?agents?|parallel\s+agents?|agent\s+team|team\s+of\s+agents?|fan[ -]?out)\b/iu.test(text2)) {
396363
+ return "delegation or parallel agent work";
396364
+ }
396365
+ const hasAction = new RegExp(String.raw`\b${ACTION_WORD}\b`, "iu").test(text2);
396366
+ 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)) {
396367
+ return "release, security, migration, or production risk";
396368
+ }
396369
+ const structuralText = withoutCode(input);
396370
+ const enumeratedItems = structuralText.match(/(?:^|\n)\s*(?:[-*+]\s+|\d+[.)]\s+)\S/gu);
396371
+ const actionLines = structuralText.split(/\r?\n/gu).filter((line) => new RegExp(String.raw`\b${ACTION_WORD}\b`, "iu").test(line));
396372
+ if ((enumeratedItems?.length ?? 0) >= 2 || actionLines.length >= 2 || SEQUENCED_ACTION_RE.test(text2)) {
396373
+ return "multiple requested outcomes";
396374
+ }
396375
+ 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");
396376
+ if (targetList.test(text2))
396377
+ return "multiple requested outcomes";
396378
+ const projectScope = /\b(?:app|application|agent|system|platform|website|dashboard|service|integration|workflow|codebase|project|plugin|extension|3d\s+(?:scene|design|pipeline))\b/iu;
396379
+ 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;
396380
+ if (projectScope.test(text2) && projectAction.test(text2)) {
396381
+ return "large project scope";
396382
+ }
396383
+ ACTION_RE.lastIndex = 0;
396384
+ if (text2.length >= 600 && ACTION_RE.test(text2)) {
396385
+ return "detailed multi-step request";
396386
+ }
396387
+ return;
396388
+ }
396389
+ function getTaskListRunForCommand(command, options2 = {}) {
396390
+ if (!command || command.mode !== "prompt" || command.isMeta)
396391
+ return;
396392
+ const text2 = textFromQueuedCommand(command);
396393
+ if (!options2.allowSlashCommand && !command.skipSlashCommands && text2.trimStart().startsWith("/")) {
396394
+ return;
396395
+ }
396396
+ const requirementReason = taskListRequirementReason(text2);
396397
+ return {
396398
+ generationId: String(command.uuid ?? randomUUID40()),
396399
+ appendToCurrent: shouldKeepCurrentTaskList(text2),
396400
+ requiresTaskList: requirementReason !== undefined,
396401
+ ...requirementReason ? { requirementReason } : {}
396402
+ };
396403
+ }
396404
+ function getTaskListRunFromMessages(messages) {
396405
+ const message = messages.findLast(isHumanTurn);
396406
+ if (!message || typeof message.uuid !== "string" || !message.uuid) {
396407
+ return;
396408
+ }
396409
+ const text2 = textFromMessage(message);
396410
+ const requirementReason = taskListRequirementReason(text2);
396411
+ return {
396412
+ generationId: message.uuid,
396413
+ appendToCurrent: shouldKeepCurrentTaskList(text2),
396414
+ requiresTaskList: requirementReason !== undefined,
396415
+ ...requirementReason ? { requirementReason } : {}
396416
+ };
396417
+ }
396418
+ var taskListRunStorage, ACTION_WORD, ACTION_RE, SEQUENCED_ACTION_RE;
396419
+ var init_taskListRunContext = __esm(() => {
396420
+ taskListRunStorage = new AsyncLocalStorage5;
396421
+ 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)`;
396422
+ ACTION_RE = new RegExp(String.raw`\b${ACTION_WORD}\b`, "giu");
396423
+ 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");
396424
+ });
396425
+
396426
+ // src/tools/TaskCreateTool/prompt.ts
396427
+ function getPrompt4() {
396428
+ const teammateContext = isAgentSwarmsEnabled() ? " and potentially assigned to teammates" : "";
396429
+ const teammateTips = isAgentSwarmsEnabled() ? `- Include enough detail in the description for another agent to understand and complete the task
396430
+ - New tasks are created with status 'pending' and no owner - use TaskUpdate with the \`owner\` parameter to assign them
396431
+ ` : "";
396432
+ return `Use this tool to create a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
396433
+ It also helps the user understand the progress of the task and overall progress of their requests.
396434
+
396435
+ ## When to Use This Tool
396436
+
396437
+ Use this tool proactively in these scenarios:
396438
+
396439
+ - Multi-outcome work - When a request has 2 or more distinct requested outcomes, deliverables, or sequenced actions
396440
+ - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations${teammateContext}
396441
+ - Multiple independently verifiable outcomes, dependency ordering, delegation, or parallel work
396442
+ - High-risk lifecycle work - Releases, publishing, deployment, migrations, security, credentials, permissions, sandboxing, or production changes
396443
+ - Project-sized builds, integrations, workflows, refactors, and audits
396444
+ - Plan mode - When using plan mode, create a task list to track the work
396445
+ - User explicitly requests todo list - When the user directly asks you to use the todo list
396446
+ - 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.
396447
+ - User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
396448
+ - When new instructions materially change multi-step work - update the plan before continuing
396449
+
396450
+ ## When NOT to Use This Tool
396451
+
396452
+ Skip using this tool when:
396453
+ - The task is purely conversational or informational
396454
+ - The request is one genuinely atomic, low-risk action with one outcome that can be completed and verified directly
396455
+ - The user sends a short acknowledgement, correction, or clarification that does not add a distinct outcome to an existing board
396456
+
396457
+ 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.
396458
+
396459
+ EXCEPTION: none of the "skip" rules apply when the user explicitly asks for an item to be added to the task list ("add to your tasks \u2026"). An explicit request always wins \u2014 create the task.
396460
+
396461
+ ## Task Fields
396462
+
396463
+ - **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
396464
+ - **description**: What needs to be done
396465
+ - **activeForm** (optional): Present continuous form shown in the spinner when the task is in_progress (e.g., "Fixing authentication bug"). If omitted, the spinner shows the subject instead.
396466
+ - **blocks** / **addBlocks** (optional): Existing task IDs this task blocks
396467
+ - **blockedBy** / **addBlockedBy** (optional): Existing task IDs that block this task
396468
+ - **addToCurrentList** (optional): Set to \`true\` when the user explicitly asks to append to the current/existing task list. A new prompt archives the previous list only when it has no pending or in-progress work; an interruption preserves active work for reconciliation.
396469
+
396470
+ All tasks are created with status \`pending\`.
396471
+
396472
+ ## Tips
396473
+
396474
+ - Create tasks with clear, specific subjects that describe the outcome
396475
+ - Never guess task IDs or reference a task that has not been created yet. For a multi-task plan, create tasks without forward edges, wait for their real IDs, then use TaskUpdate to add dependency edges.
396476
+ - A task can depend only on an existing different task; never add a self-dependency.
396477
+ ${teammateTips}- Check TaskList first to avoid creating duplicate tasks
396478
+ - Use TaskUpdate, not TaskCreate, for status or ownership changes
396479
+ - After an interruption, call TaskList, keep relevant active work, update the affected task, add a task only for a genuinely distinct new outcome, and mark superseded work skipped
396480
+ - Do not set \`addToCurrentList\` merely because earlier tasks exist; runtime already preserves interrupted work, while this flag is reserved for explicit user intent such as "add this to the current list"
396481
+ `;
396482
+ }
396483
+ var DESCRIPTION12 = "Create a new task in the task list";
396484
+ var init_prompt16 = __esm(() => {
396485
+ init_agentSwarmsEnabled();
396486
+ });
396487
+
396488
+ // src/tools/TaskCreateTool/TaskCreateTool.ts
396489
+ async function createTaskFromInput({
396490
+ subject,
396491
+ description,
396492
+ activeForm,
396493
+ metadata,
396494
+ blocks,
396495
+ blockedBy,
396496
+ addBlocks,
396497
+ addBlockedBy,
396498
+ addToCurrentList
396499
+ }, context5) {
396500
+ const initialBlocks = [...new Set([...blocks ?? [], ...addBlocks ?? []])];
396501
+ const initialBlockedBy = [
396502
+ ...new Set([...blockedBy ?? [], ...addBlockedBy ?? []])
396503
+ ];
396504
+ const taskListId = getTaskListId();
396505
+ const run2 = getTaskListRunContext() ?? (context5.agentId ? undefined : getTaskListRunFromMessages(context5.messages ?? []));
396506
+ const taskData = {
396507
+ subject,
396508
+ description,
396509
+ activeForm,
396510
+ status: "pending",
396511
+ owner: undefined,
396512
+ blocks: [],
396513
+ blockedBy: [],
396514
+ metadata
396515
+ };
396516
+ const taskId = run2 ? await createTaskForRun(taskListId, run2.generationId, taskData, {
396517
+ appendToCurrent: run2.appendToCurrent || addToCurrentList === true
396518
+ }) : await createTask(taskListId, taskData);
396519
+ const dependencies = [
396520
+ ...initialBlocks.map((targetId) => ({
396521
+ fromTaskId: taskId,
396522
+ toTaskId: targetId,
396523
+ field: "blocks"
396524
+ })),
396525
+ ...initialBlockedBy.map((blockerId) => ({
396526
+ fromTaskId: blockerId,
396527
+ toTaskId: taskId,
396528
+ field: "blockedBy"
396529
+ }))
396530
+ ].filter((edge) => edge.fromTaskId !== edge.toTaskId);
396531
+ const dependencyResult = await updateTaskWithDependencies(taskListId, taskId, {}, dependencies);
396532
+ if (dependencyResult.success === false) {
396533
+ const dependency = dependencyResult.dependency;
396534
+ await deleteTask(taskListId, taskId);
396535
+ if (dependency) {
396536
+ const field = dependencies.find((candidate) => candidate.fromTaskId === dependency.fromTaskId && candidate.toTaskId === dependency.toTaskId)?.field ?? "dependency";
396537
+ throw new Error(`Invalid ${field} dependency ` + `#${dependency.fromTaskId} -> #${dependency.toTaskId}: ` + dependencyResult.reason);
396538
+ }
396539
+ throw new Error(`Failed to create task dependencies: ${dependencyResult.reason}`);
396540
+ }
396541
+ const blockingErrors = [];
396542
+ const generator = executeTaskCreatedHooks(taskId, subject, description, getAgentName(), getTeamName(), undefined, context5?.abortController?.signal, undefined, context5);
396543
+ for await (const result of generator) {
396544
+ if (result.blockingError) {
396545
+ blockingErrors.push(getTaskCreatedHookMessage(result.blockingError));
396546
+ }
396547
+ }
396548
+ if (blockingErrors.length > 0) {
396549
+ await deleteTask(taskListId, taskId);
396550
+ throw new Error(blockingErrors.join(`
396551
+ `));
396552
+ }
396553
+ context5.setAppState((prev) => prev.expandedView === "tasks" ? prev : { ...prev, expandedView: "tasks" });
396554
+ return { id: taskId, subject };
396555
+ }
396556
+ var inputSchema29, outputSchema25, TaskCreateTool;
396557
+ var init_TaskCreateTool = __esm(() => {
396558
+ init_v4();
396559
+ init_Tool();
396560
+ init_hooks5();
396561
+ init_tasks();
396562
+ init_taskListRunContext();
396563
+ init_teammate();
396564
+ init_prompt16();
396565
+ inputSchema29 = lazySchema(() => exports_external.strictObject({
396566
+ subject: exports_external.string().describe("A brief title for the task"),
396567
+ description: exports_external.string().describe("What needs to be done"),
396568
+ activeForm: exports_external.string().optional().describe('Present continuous form shown in spinner when in_progress (e.g., "Running tests")'),
396569
+ metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional().describe("Arbitrary metadata to attach to the task"),
396570
+ blocks: exports_external.array(exports_external.string()).optional().describe("Task IDs that this task blocks at creation time"),
396571
+ blockedBy: exports_external.array(exports_external.string()).optional().describe("Task IDs that block this task at creation time"),
396572
+ addBlocks: exports_external.array(exports_external.string()).optional().describe("Alias for blocks, accepted for compatibility with TaskUpdate"),
396573
+ addBlockedBy: exports_external.array(exports_external.string()).optional().describe("Alias for blockedBy, accepted for compatibility with TaskUpdate"),
396574
+ addToCurrentList: exports_external.boolean().optional().describe("Set true only when the user explicitly asks to append to the current task list")
396575
+ }));
396576
+ outputSchema25 = lazySchema(() => exports_external.object({
396577
+ task: exports_external.object({
396578
+ id: exports_external.string(),
396579
+ subject: exports_external.string()
396580
+ })
396581
+ }));
396582
+ TaskCreateTool = buildTool({
396583
+ name: TASK_CREATE_TOOL_NAME,
396584
+ searchHint: "create a task in the task list",
396585
+ maxResultSizeChars: 1e5,
396586
+ async description() {
396587
+ return DESCRIPTION12;
396588
+ },
396589
+ async prompt() {
396590
+ return getPrompt4();
396591
+ },
396592
+ get inputSchema() {
396593
+ return inputSchema29();
396594
+ },
396595
+ get outputSchema() {
396596
+ return outputSchema25();
396597
+ },
396598
+ userFacingName() {
396599
+ return "TaskCreate";
396600
+ },
396601
+ shouldDefer: false,
396602
+ isEnabled() {
396603
+ return isTodoV2Enabled();
396604
+ },
396605
+ isConcurrencySafe() {
396606
+ return false;
396607
+ },
396608
+ toAutoClassifierInput(input) {
396609
+ return input.subject;
396610
+ },
396611
+ renderToolUseMessage() {
396612
+ return null;
396613
+ },
396614
+ async call(input, context5) {
396615
+ const task = await createTaskFromInput(input, context5);
396616
+ return {
396617
+ data: {
396618
+ task
396619
+ }
396620
+ };
396621
+ },
396622
+ mapToolResultToToolResultBlockParam(content, toolUseID) {
396623
+ const { task } = content;
396624
+ return {
396625
+ tool_use_id: toolUseID,
396626
+ type: "tool_result",
396627
+ content: `Task #${task.id} created successfully: ${task.subject}`
396628
+ };
396629
+ }
396630
+ });
396631
+ });
396632
+
396633
+ // src/tools/ExitPlanModeTool/planTaskSync.ts
396634
+ function plainText(value) {
396635
+ return value.replace(/^\s*(?:[-*+]\s+|\d+[.)]\s+)(?:\[[ xX]\]\s*)?/u, "").replace(/\[([^\]]+)\]\([^)]*\)/gu, "$1").replace(/[*_`~#]/gu, "").replace(/\s+/gu, " ").trim();
396636
+ }
396637
+ function boundedDescription(value) {
396638
+ const normalized = value.trim();
396639
+ return normalized.length <= 4000 ? normalized : `${normalized.slice(0, 3999)}\u2026`;
396640
+ }
396641
+ function taskSubject(value) {
396642
+ const cleaned = plainText(value).replace(/[.;:,]+$/u, "");
396643
+ const pathStep = cleaned.match(/^([^:]{1,100}\.[A-Za-z0-9]+):\s*(.+)$/u);
396644
+ const candidate = pathStep ? `${pathStep[2]} in ${pathStep[1]}` : cleaned;
396645
+ const actionable = ACTION_PREFIX.test(candidate) ? candidate : `Implement ${candidate.charAt(0).toLowerCase()}${candidate.slice(1)}`;
396646
+ return (actionable.charAt(0).toUpperCase() + actionable.slice(1)).slice(0, 120);
396647
+ }
396648
+ function extractCandidates(plan) {
396649
+ let section = "unknown";
396650
+ const candidates = [];
396651
+ for (const rawLine of plan.split(/\r?\n/gu)) {
396652
+ const heading2 = rawLine.match(/^\s{0,3}#{1,6}\s+(.+?)\s*#*\s*$/u);
396653
+ if (heading2) {
396654
+ const title = plainText(heading2[1] ?? "");
396655
+ section = VERIFICATION_SECTION.test(title) ? "verification" : NON_EXECUTION_SECTION.test(title) ? "ignored" : IMPLEMENTATION_SECTION.test(title) ? "implementation" : "unknown";
396656
+ continue;
396657
+ }
396658
+ if (!/^\s*(?:[-*+]\s+|\d+[.)]\s+)\S/u.test(rawLine))
396659
+ continue;
396660
+ const line = plainText(rawLine);
396661
+ if (line.length < 8 || section === "ignored")
396662
+ continue;
396663
+ const kind = section === "verification" || VERIFICATION_STEP.test(line) ? "verification" : "implementation";
396664
+ const subject = taskSubject(line);
396665
+ if (subject.length < 8)
396666
+ continue;
396667
+ candidates.push({ line, subject, kind });
396668
+ }
396669
+ return candidates;
396670
+ }
396671
+ function derivePlanTaskBlueprints(plan) {
396672
+ const unique = [];
396673
+ const seen = new Set;
396674
+ for (const candidate of extractCandidates(plan)) {
396675
+ const key = candidate.subject.toLocaleLowerCase();
396676
+ if (seen.has(key))
396677
+ continue;
396678
+ seen.add(key);
396679
+ unique.push(candidate);
396680
+ if (unique.length >= 8)
396681
+ break;
396682
+ }
396683
+ const implementation = unique.filter((item) => item.kind === "implementation").slice(0, 5);
396684
+ const verification = unique.find((item) => item.kind === "verification");
396685
+ const blueprints = implementation.map((item) => ({
396686
+ subject: item.subject,
396687
+ description: boundedDescription(`Approved plan step: ${item.line}`)
396688
+ }));
396689
+ if (blueprints.length === 0) {
396690
+ blueprints.push({
396691
+ subject: "Implement the approved plan",
396692
+ description: boundedDescription(plan.trim() || "Implement the work approved in plan mode."),
396693
+ activeForm: "Implementing the approved plan"
396694
+ });
396695
+ }
396696
+ blueprints.push({
396697
+ subject: verification?.subject ?? "Verify the completed implementation",
396698
+ description: boundedDescription(verification?.line ?? "Run the relevant tests and checks, then confirm the approved plan is complete."),
396699
+ activeForm: "Verifying the completed implementation"
396700
+ });
396701
+ return blueprints;
396702
+ }
396703
+ async function ensureApprovedPlanTasks(plan, planFilePath, context5) {
396704
+ const inspection = await inspectTaskListForGate(getTaskListId());
396705
+ if (countActionableTasksForGate(inspection.tasks) > 0)
396706
+ return [];
396707
+ const created = [];
396708
+ const implementationIds = [];
396709
+ const blueprints = derivePlanTaskBlueprints(plan ?? "");
396710
+ try {
396711
+ for (const [index2, blueprint] of blueprints.entries()) {
396712
+ const isVerification = index2 === blueprints.length - 1;
396713
+ const task = await createTaskFromInput({
396714
+ ...blueprint,
396715
+ ...isVerification && implementationIds.length > 0 ? { blockedBy: implementationIds } : {},
396716
+ metadata: {
396717
+ source: "approved-plan",
396718
+ planFilePath
396719
+ }
396720
+ }, context5);
396721
+ created.push(task.id);
396722
+ if (!isVerification)
396723
+ implementationIds.push(task.id);
396724
+ }
396725
+ return created;
396726
+ } catch (error40) {
396727
+ for (const taskId of created.reverse()) {
396728
+ await deleteTask(getTaskListId(), taskId).catch(() => false);
396729
+ }
396730
+ throw error40;
396731
+ }
396732
+ }
396733
+ var ACTION_PREFIX, IMPLEMENTATION_SECTION, VERIFICATION_SECTION, NON_EXECUTION_SECTION, VERIFICATION_STEP;
396734
+ var init_planTaskSync = __esm(() => {
396735
+ init_taskListGate();
396736
+ init_tasks();
396737
+ init_TaskCreateTool();
396738
+ ACTION_PREFIX = /^(?:add|allow|build|change|clean|configure|create|debug|delete|design|document|enable|ensure|expose|fix|implement|integrate|migrate|prevent|publish|refactor|remove|rename|repair|replace|research|restore|review|run|secure|synchronize|test|update|upgrade|validate|verify)\b/iu;
396739
+ IMPLEMENTATION_SECTION = /\b(?:approach|changes?|execution|implementation|migration|plan|steps?|tasks?|work)\b/iu;
396740
+ VERIFICATION_SECTION = /\b(?:acceptance|checks?|quality|tests?|validation|verification)\b/iu;
396741
+ NON_EXECUTION_SECTION = /\b(?:alternatives?|assumptions?|context|decisions?|goals?|notes?|out of scope|requirements?|risks?|scope)\b/iu;
396742
+ VERIFICATION_STEP = /\b(?:check|test|validate|verify)\b/iu;
396743
+ });
396744
+
395834
396745
  // src/tools/ExitPlanModeTool/UI.tsx
395835
396746
  function renderToolUseMessage19() {
395836
396747
  return null;
@@ -396023,7 +396934,7 @@ function normalizeExitPlanModeInput(value) {
396023
396934
  allowedPrompts: normalizeAllowedPromptsValue(rawAllowedPrompts)
396024
396935
  };
396025
396936
  }
396026
- var permissionSetupModule = null, allowedPromptSchema, allowedPromptsSchema, inputObjectSchema, inputSchema29, _sdkInputSchema, outputSchema25, ExitPlanModeV2Tool;
396937
+ var permissionSetupModule = null, allowedPromptSchema, allowedPromptsSchema, inputObjectSchema, inputSchema30, _sdkInputSchema, outputSchema26, ExitPlanModeV2Tool;
396027
396938
  var init_ExitPlanModeV2Tool = __esm(() => {
396028
396939
  init_v4();
396029
396940
  init_state();
@@ -396039,6 +396950,7 @@ var init_ExitPlanModeV2Tool = __esm(() => {
396039
396950
  init_teammateMailbox();
396040
396951
  init_constants2();
396041
396952
  init_prompt15();
396953
+ init_planTaskSync();
396042
396954
  init_UI18();
396043
396955
  allowedPromptSchema = lazySchema(() => exports_external.object({
396044
396956
  tool: exports_external.enum(["Bash"]).describe("The tool this prompt applies to"),
@@ -396048,12 +396960,12 @@ var init_ExitPlanModeV2Tool = __esm(() => {
396048
396960
  inputObjectSchema = lazySchema(() => exports_external.strictObject({
396049
396961
  allowedPrompts: allowedPromptsSchema().describe("Prompt-based permissions needed to implement the plan. These describe categories of actions rather than specific commands.")
396050
396962
  }).passthrough());
396051
- inputSchema29 = lazySchema(() => exports_external.preprocess(normalizeExitPlanModeInput, inputObjectSchema()));
396963
+ inputSchema30 = lazySchema(() => exports_external.preprocess(normalizeExitPlanModeInput, inputObjectSchema()));
396052
396964
  _sdkInputSchema = lazySchema(() => exports_external.preprocess(normalizeExitPlanModeInput, inputObjectSchema().extend({
396053
396965
  plan: exports_external.string().optional().describe("The plan content (injected by normalizeToolInput from disk)"),
396054
396966
  planFilePath: exports_external.string().optional().describe("The plan file path (injected by normalizeToolInput)")
396055
396967
  })));
396056
- outputSchema25 = lazySchema(() => exports_external.object({
396968
+ outputSchema26 = lazySchema(() => exports_external.object({
396057
396969
  plan: exports_external.string().nullable().describe("The plan that was presented to the user"),
396058
396970
  isAgent: exports_external.boolean(),
396059
396971
  filePath: exports_external.string().optional().describe("The file path where the plan was saved"),
@@ -396061,7 +396973,8 @@ var init_ExitPlanModeV2Tool = __esm(() => {
396061
396973
  planWasEdited: exports_external.boolean().optional().describe("True when the user edited the plan (CCR web UI or Ctrl+G); determines whether the plan is echoed back in tool_result"),
396062
396974
  awaitingLeaderApproval: exports_external.boolean().optional().describe("When true, the teammate has sent a plan approval request to the team leader"),
396063
396975
  alreadyExited: exports_external.boolean().optional().describe("When true, plan mode had already been exited and this call was a no-op"),
396064
- requestId: exports_external.string().optional().describe("Unique identifier for the plan approval request")
396976
+ requestId: exports_external.string().optional().describe("Unique identifier for the plan approval request"),
396977
+ synchronizedTaskIds: exports_external.array(exports_external.string()).optional().describe("Visible task IDs created from the approved plan when none existed")
396065
396978
  }));
396066
396979
  ExitPlanModeV2Tool = buildTool({
396067
396980
  name: EXIT_PLAN_MODE_V2_TOOL_NAME,
@@ -396074,10 +396987,10 @@ var init_ExitPlanModeV2Tool = __esm(() => {
396074
396987
  return EXIT_PLAN_MODE_V2_TOOL_PROMPT;
396075
396988
  },
396076
396989
  get inputSchema() {
396077
- return inputSchema29();
396990
+ return inputSchema30();
396078
396991
  },
396079
396992
  get outputSchema() {
396080
- return outputSchema25();
396993
+ return outputSchema26();
396081
396994
  },
396082
396995
  userFacingName() {
396083
396996
  return "";
@@ -396190,6 +397103,7 @@ var init_ExitPlanModeV2Tool = __esm(() => {
396190
397103
  }
396191
397104
  };
396192
397105
  }
397106
+ const synchronizedTaskIds = isAgent ? [] : await ensureApprovedPlanTasks(plan, filePath, context5);
396193
397107
  const appState = context5.getAppState();
396194
397108
  let gateFallbackNotification = null;
396195
397109
  if (false) {}
@@ -396232,7 +397146,8 @@ var init_ExitPlanModeV2Tool = __esm(() => {
396232
397146
  isAgent,
396233
397147
  filePath,
396234
397148
  hasTaskTool: hasTaskTool || undefined,
396235
- planWasEdited: inputPlan !== undefined || undefined
397149
+ planWasEdited: inputPlan !== undefined || undefined,
397150
+ synchronizedTaskIds
396236
397151
  }
396237
397152
  };
396238
397153
  },
@@ -396244,7 +397159,8 @@ var init_ExitPlanModeV2Tool = __esm(() => {
396244
397159
  planWasEdited,
396245
397160
  awaitingLeaderApproval,
396246
397161
  requestId,
396247
- alreadyExited
397162
+ alreadyExited,
397163
+ synchronizedTaskIds
396248
397164
  }, toolUseID) {
396249
397165
  if (alreadyExited) {
396250
397166
  return {
@@ -396289,10 +397205,15 @@ Request ID: ${requestId}`,
396289
397205
  const teamHint = hasTaskTool ? `
396290
397206
 
396291
397207
  If this plan can be broken down into multiple independent tasks, consider using the ${TEAM_CREATE_TOOL_NAME} tool to create a team and parallelize the work.` : "";
397208
+ const taskHint = synchronizedTaskIds && synchronizedTaskIds.length > 0 ? `
397209
+
397210
+ Visible implementation tasks are ready: ${synchronizedTaskIds.map((id) => `#${id}`).join(", ")}. Start the first unblocked task and keep their statuses current.` : `
397211
+
397212
+ Use the existing visible task list and keep its statuses current while implementing.`;
396292
397213
  const planLabel = planWasEdited ? "Approved Plan (edited by user)" : "Approved Plan";
396293
397214
  return {
396294
397215
  type: "tool_result",
396295
- content: `User has approved your plan. You can now start coding. Start with updating your todo list if applicable
397216
+ content: `User has approved your plan. You can now start coding.${taskHint}
396296
397217
 
396297
397218
  Your plan has been saved to: ${filePath}
396298
397219
  You can refer back to it if needed during implementation.${teamHint}
@@ -396306,11 +397227,11 @@ ${plan}`,
396306
397227
  });
396307
397228
 
396308
397229
  // src/tools/testing/TestingPermissionTool.tsx
396309
- var NAME = "TestingPermission", inputSchema30, TestingPermissionTool;
397230
+ var NAME = "TestingPermission", inputSchema31, TestingPermissionTool;
396310
397231
  var init_TestingPermissionTool = __esm(() => {
396311
397232
  init_v4();
396312
397233
  init_Tool();
396313
- inputSchema30 = lazySchema(() => exports_external.strictObject({}));
397234
+ inputSchema31 = lazySchema(() => exports_external.strictObject({}));
396314
397235
  TestingPermissionTool = buildTool({
396315
397236
  name: NAME,
396316
397237
  maxResultSizeChars: 1e5,
@@ -396321,7 +397242,7 @@ var init_TestingPermissionTool = __esm(() => {
396321
397242
  return "Test tool that always asks for permission before executing. Used for end-to-end testing.";
396322
397243
  },
396323
397244
  get inputSchema() {
396324
- return inputSchema30();
397245
+ return inputSchema31();
396325
397246
  },
396326
397247
  userFacingName() {
396327
397248
  return "TestingPermission";
@@ -396395,7 +397316,7 @@ function formatLimitInfo(appliedLimit, appliedOffset) {
396395
397316
  parts.push(`offset: ${appliedOffset}`);
396396
397317
  return parts.join(", ");
396397
397318
  }
396398
- var inputSchema31, VCS_DIRECTORIES_TO_EXCLUDE2, DEFAULT_HEAD_LIMIT = 250, outputSchema26, GrepTool;
397319
+ var inputSchema32, VCS_DIRECTORIES_TO_EXCLUDE2, DEFAULT_HEAD_LIMIT = 250, outputSchema27, GrepTool;
396399
397320
  var init_GrepTool = __esm(() => {
396400
397321
  init_v4();
396401
397322
  init_Tool();
@@ -396413,7 +397334,7 @@ var init_GrepTool = __esm(() => {
396413
397334
  init_stringUtils();
396414
397335
  init_prompt2();
396415
397336
  init_UI10();
396416
- inputSchema31 = lazySchema(() => exports_external.strictObject({
397337
+ inputSchema32 = lazySchema(() => exports_external.strictObject({
396417
397338
  pattern: exports_external.string().describe("The regular expression pattern to search for in file contents"),
396418
397339
  path: exports_external.string().optional().describe("File or directory to search in (rg PATH). Defaults to current working directory."),
396419
397340
  glob: exports_external.string().optional().describe('Glob pattern to filter files (e.g. "*.js", "*.{ts,tsx}") - maps to rg --glob'),
@@ -396437,7 +397358,7 @@ var init_GrepTool = __esm(() => {
396437
397358
  ".jj",
396438
397359
  ".sl"
396439
397360
  ];
396440
- outputSchema26 = lazySchema(() => exports_external.object({
397361
+ outputSchema27 = lazySchema(() => exports_external.object({
396441
397362
  mode: exports_external.enum(["content", "files_with_matches", "count"]).optional(),
396442
397363
  numFiles: exports_external.number(),
396443
397364
  filenames: exports_external.array(exports_external.string()),
@@ -396464,10 +397385,10 @@ var init_GrepTool = __esm(() => {
396464
397385
  return summary ? `Searching for ${summary}` : "Searching";
396465
397386
  },
396466
397387
  get inputSchema() {
396467
- return inputSchema31();
397388
+ return inputSchema32();
396468
397389
  },
396469
397390
  get outputSchema() {
396470
- return outputSchema26();
397391
+ return outputSchema27();
396471
397392
  },
396472
397393
  isConcurrencySafe() {
396473
397394
  return true;
@@ -396801,7 +397722,7 @@ var init_embeddings = __esm(() => {
396801
397722
  });
396802
397723
 
396803
397724
  // src/utils/codeIndex/store.ts
396804
- import { createHash as createHash30 } from "crypto";
397725
+ import { createHash as createHash31 } from "crypto";
396805
397726
  import { mkdir as mkdir22, readFile as readFile26, writeFile as writeFile22 } from "fs/promises";
396806
397727
  import { dirname as dirname49, join as join113 } from "path";
396807
397728
  function codeIndexDir(root2) {
@@ -396811,7 +397732,7 @@ function indexPath(root2) {
396811
397732
  return join113(codeIndexDir(root2), "index.json");
396812
397733
  }
396813
397734
  function sha1(content) {
396814
- return createHash30("sha1").update(content).digest("hex");
397735
+ return createHash31("sha1").update(content).digest("hex");
396815
397736
  }
396816
397737
  function cosineSimilarity(a2, b) {
396817
397738
  if (a2.length === 0 || a2.length !== b.length) {
@@ -397360,11 +398281,11 @@ var init_graph = __esm(() => {
397360
398281
  });
397361
398282
 
397362
398283
  // src/utils/codeIndex/repoIndex.ts
397363
- import { createHash as createHash31 } from "crypto";
398284
+ import { createHash as createHash32 } from "crypto";
397364
398285
  import { existsSync as existsSync29, mkdirSync as mkdirSync19, readFileSync as readFileSync34, writeFileSync as writeFileSync22 } from "fs";
397365
398286
  import { join as join115, posix as posix8 } from "path";
397366
398287
  function sha12(content) {
397367
- return createHash31("sha1").update(content).digest("hex");
398288
+ return createHash32("sha1").update(content).digest("hex");
397368
398289
  }
397369
398290
  function posixExt(file2) {
397370
398291
  const dot = file2.lastIndexOf(".");
@@ -397938,7 +398859,7 @@ Notes:
397938
398859
  - Returns file paths with line ranges and a short preview for each hit.`;
397939
398860
  }
397940
398861
  var CODE_SEARCH_TOOL_NAME = "CodeSearch";
397941
- var init_prompt16 = __esm(() => {
398862
+ var init_prompt17 = __esm(() => {
397942
398863
  init_prompt2();
397943
398864
  });
397944
398865
 
@@ -397951,20 +398872,20 @@ function formatHit(hit) {
397951
398872
  return `${hit.file}:${hit.startLine}-${hit.endLine} (score ${score})
397952
398873
  ${indentedPreview}`;
397953
398874
  }
397954
- var inputSchema32, outputSchema27, DEFAULT_LIMIT = 10, CodeSearchTool;
398875
+ var inputSchema33, outputSchema28, DEFAULT_LIMIT = 10, CodeSearchTool;
397955
398876
  var init_CodeSearchTool = __esm(() => {
397956
398877
  init_v4();
397957
398878
  init_Tool();
397958
398879
  init_cwd2();
397959
398880
  init_codeIndex();
397960
398881
  init_semanticNumber();
397961
- init_prompt16();
397962
- inputSchema32 = lazySchema(() => exports_external.strictObject({
398882
+ init_prompt17();
398883
+ inputSchema33 = lazySchema(() => exports_external.strictObject({
397963
398884
  query: exports_external.string().describe('Natural-language description of the code you are looking for (e.g. "retry logic for failed network requests").'),
397964
398885
  limit: semanticNumber(exports_external.number().optional()).describe("Maximum number of results to return. Defaults to 10."),
397965
398886
  path: exports_external.string().optional().describe('Optional project-relative path prefix to restrict results to (e.g. "src/tools").')
397966
398887
  }));
397967
- outputSchema27 = lazySchema(() => exports_external.object({
398888
+ outputSchema28 = lazySchema(() => exports_external.object({
397968
398889
  status: exports_external.enum(["ok", "no_index", "empty"]),
397969
398890
  message: exports_external.string().optional(),
397970
398891
  builtAt: exports_external.string().optional(),
@@ -397994,10 +398915,10 @@ var init_CodeSearchTool = __esm(() => {
397994
398915
  return input?.query ? `Searching code for ${input.query}` : "Searching code";
397995
398916
  },
397996
398917
  get inputSchema() {
397997
- return inputSchema32();
398918
+ return inputSchema33();
397998
398919
  },
397999
398920
  get outputSchema() {
398000
- return outputSchema27();
398921
+ return outputSchema28();
398001
398922
  },
398002
398923
  isEnabled() {
398003
398924
  return isCodeIndexEnabled();
@@ -398455,7 +399376,7 @@ var init_formatters = __esm(() => {
398455
399376
  });
398456
399377
 
398457
399378
  // src/tools/LSPTool/prompt.ts
398458
- var LSP_TOOL_NAME = "LSP", DESCRIPTION12 = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
399379
+ var LSP_TOOL_NAME = "LSP", DESCRIPTION13 = `Interact with Language Server Protocol (LSP) servers to get code intelligence features.
398459
399380
 
398460
399381
  Supported operations:
398461
399382
  - goToDefinition: Find where a symbol is defined
@@ -399147,7 +400068,7 @@ function countUniqueFilesFromOutgoingCalls(calls) {
399147
400068
  const validUris = calls.map((call6) => call6.to?.uri).filter((uri) => uri);
399148
400069
  return new Set(validUris).size;
399149
400070
  }
399150
- var MAX_LSP_FILE_SIZE_BYTES = 1e7, inputSchema33, outputSchema28, LSPTool;
400071
+ var MAX_LSP_FILE_SIZE_BYTES = 1e7, inputSchema34, outputSchema29, LSPTool;
399151
400072
  var init_LSPTool = __esm(() => {
399152
400073
  init_v4();
399153
400074
  init_manager();
@@ -399163,7 +400084,7 @@ var init_LSPTool = __esm(() => {
399163
400084
  init_formatters();
399164
400085
  init_schemas5();
399165
400086
  init_UI19();
399166
- inputSchema33 = lazySchema(() => exports_external.strictObject({
400087
+ inputSchema34 = lazySchema(() => exports_external.strictObject({
399167
400088
  operation: exports_external.enum([
399168
400089
  "goToDefinition",
399169
400090
  "findReferences",
@@ -399179,7 +400100,7 @@ var init_LSPTool = __esm(() => {
399179
400100
  line: exports_external.number().int().positive().describe("The line number (1-based, as shown in editors)"),
399180
400101
  character: exports_external.number().int().positive().describe("The character offset (1-based, as shown in editors)")
399181
400102
  }));
399182
- outputSchema28 = lazySchema(() => exports_external.object({
400103
+ outputSchema29 = lazySchema(() => exports_external.object({
399183
400104
  operation: exports_external.enum([
399184
400105
  "goToDefinition",
399185
400106
  "findReferences",
@@ -399202,7 +400123,7 @@ var init_LSPTool = __esm(() => {
399202
400123
  maxResultSizeChars: 1e5,
399203
400124
  isLsp: true,
399204
400125
  async description() {
399205
- return DESCRIPTION12;
400126
+ return DESCRIPTION13;
399206
400127
  },
399207
400128
  userFacingName: userFacingName6,
399208
400129
  shouldDefer: true,
@@ -399210,10 +400131,10 @@ var init_LSPTool = __esm(() => {
399210
400131
  return isLspConnected();
399211
400132
  },
399212
400133
  get inputSchema() {
399213
- return inputSchema33();
400134
+ return inputSchema34();
399214
400135
  },
399215
400136
  get outputSchema() {
399216
- return outputSchema28();
400137
+ return outputSchema29();
399217
400138
  },
399218
400139
  isConcurrencySafe() {
399219
400140
  return true;
@@ -399271,7 +400192,7 @@ var init_LSPTool = __esm(() => {
399271
400192
  return checkReadPermissionForTool(LSPTool, input, appState.toolPermissionContext);
399272
400193
  },
399273
400194
  async prompt() {
399274
- return DESCRIPTION12;
400195
+ return DESCRIPTION13;
399275
400196
  },
399276
400197
  renderToolUseMessage: renderToolUseMessage20,
399277
400198
  renderToolUseErrorMessage: renderToolUseErrorMessage10,
@@ -399591,7 +400512,7 @@ function getEnterPlanModeToolPrompt() {
399591
400512
  return process.env.USER_TYPE === "ant" ? getEnterPlanModeToolPromptAnt() : getEnterPlanModeToolPromptExternal();
399592
400513
  }
399593
400514
  var WHAT_HAPPENS_SECTION;
399594
- var init_prompt17 = __esm(() => {
400515
+ var init_prompt18 = __esm(() => {
399595
400516
  init_planModeV2();
399596
400517
  init_prompt();
399597
400518
  WHAT_HAPPENS_SECTION = `## What Happens in Plan Mode
@@ -399602,7 +400523,8 @@ In plan mode, you'll:
399602
400523
  3. Design an implementation approach
399603
400524
  4. Present your plan to the user for approval
399604
400525
  5. Use ${ASK_USER_QUESTION_TOOL_NAME} if you need to clarify approaches
399605
- 6. Exit plan mode with ExitPlanMode when ready to implement
400526
+ 6. Use TaskCreate for manual task decomposition when useful; plan-file writes are allowed while planning
400527
+ 7. Exit plan mode with ExitPlanMode when ready. After approval, ExitPlanMode guarantees that visible implementation tasks exist before coding begins
399606
400528
 
399607
400529
  `;
399608
400530
  });
@@ -399662,7 +400584,7 @@ var init_UI20 = __esm(() => {
399662
400584
  });
399663
400585
 
399664
400586
  // src/tools/EnterPlanModeTool/EnterPlanModeTool.ts
399665
- var inputSchema34, outputSchema29, EnterPlanModeTool;
400587
+ var inputSchema35, outputSchema30, EnterPlanModeTool;
399666
400588
  var init_EnterPlanModeTool = __esm(() => {
399667
400589
  init_v4();
399668
400590
  init_state();
@@ -399670,10 +400592,10 @@ var init_EnterPlanModeTool = __esm(() => {
399670
400592
  init_PermissionUpdate();
399671
400593
  init_permissionSetup();
399672
400594
  init_planModeV2();
399673
- init_prompt17();
400595
+ init_prompt18();
399674
400596
  init_UI20();
399675
- inputSchema34 = lazySchema(() => exports_external.strictObject({}));
399676
- outputSchema29 = lazySchema(() => exports_external.object({
400597
+ inputSchema35 = lazySchema(() => exports_external.strictObject({}));
400598
+ outputSchema30 = lazySchema(() => exports_external.object({
399677
400599
  message: exports_external.string().describe("Confirmation that plan mode was entered")
399678
400600
  }));
399679
400601
  EnterPlanModeTool = buildTool({
@@ -399687,10 +400609,10 @@ var init_EnterPlanModeTool = __esm(() => {
399687
400609
  return getEnterPlanModeToolPrompt();
399688
400610
  },
399689
400611
  get inputSchema() {
399690
- return inputSchema34();
400612
+ return inputSchema35();
399691
400613
  },
399692
400614
  get outputSchema() {
399693
- return outputSchema29();
400615
+ return outputSchema30();
399694
400616
  },
399695
400617
  userFacingName() {
399696
400618
  return "";
@@ -399721,7 +400643,7 @@ var init_EnterPlanModeTool = __esm(() => {
399721
400643
  }));
399722
400644
  return {
399723
400645
  data: {
399724
- message: "Entered plan mode. You should now focus on exploring the codebase and designing an implementation approach."
400646
+ message: "Entered plan mode. Explore the codebase and write the plan file. TaskCreate remains available for manual decomposition; after approval, ExitPlanMode guarantees visible implementation tasks before coding begins."
399725
400647
  }
399726
400648
  };
399727
400649
  },
@@ -399736,7 +400658,8 @@ In plan mode, you should:
399736
400658
  3. Consider multiple approaches and their trade-offs
399737
400659
  4. Use AskUserQuestion if you need to clarify the approach
399738
400660
  5. Design a concrete implementation strategy
399739
- 6. When ready, use ExitPlanMode to present your plan for approval
400661
+ 6. If useful, use TaskCreate to decompose the work manually; plan-file writes remain allowed while planning
400662
+ 7. When ready, use ExitPlanMode to present your plan for approval. After approval, it guarantees visible implementation tasks before coding begins
399740
400663
 
399741
400664
  Remember: DO NOT write or edit any files yet. This is a read-only exploration and planning phase.`;
399742
400665
  return {
@@ -399844,7 +400767,7 @@ var init_UI21 = __esm(() => {
399844
400767
  });
399845
400768
 
399846
400769
  // src/tools/EnterWorktreeTool/EnterWorktreeTool.ts
399847
- var inputSchema35, outputSchema30, EnterWorktreeTool;
400770
+ var inputSchema36, outputSchema31, EnterWorktreeTool;
399848
400771
  var init_EnterWorktreeTool = __esm(() => {
399849
400772
  init_v4();
399850
400773
  init_state();
@@ -399859,7 +400782,7 @@ var init_EnterWorktreeTool = __esm(() => {
399859
400782
  init_sessionStorage();
399860
400783
  init_worktree3();
399861
400784
  init_UI21();
399862
- inputSchema35 = lazySchema(() => exports_external.strictObject({
400785
+ inputSchema36 = lazySchema(() => exports_external.strictObject({
399863
400786
  name: exports_external.string().superRefine((s, ctx) => {
399864
400787
  try {
399865
400788
  validateWorktreeSlug(s);
@@ -399868,7 +400791,7 @@ var init_EnterWorktreeTool = __esm(() => {
399868
400791
  }
399869
400792
  }).optional().describe('Optional name for the worktree. Each "/"-separated segment may contain only letters, digits, dots, underscores, and dashes; max 64 chars total. A random name is generated if not provided.')
399870
400793
  }));
399871
- outputSchema30 = lazySchema(() => exports_external.object({
400794
+ outputSchema31 = lazySchema(() => exports_external.object({
399872
400795
  worktreePath: exports_external.string(),
399873
400796
  worktreeBranch: exports_external.string().optional(),
399874
400797
  message: exports_external.string()
@@ -399884,10 +400807,10 @@ var init_EnterWorktreeTool = __esm(() => {
399884
400807
  return getEnterWorktreeToolPrompt();
399885
400808
  },
399886
400809
  get inputSchema() {
399887
- return inputSchema35();
400810
+ return inputSchema36();
399888
400811
  },
399889
400812
  get outputSchema() {
399890
- return outputSchema30();
400813
+ return outputSchema31();
399891
400814
  },
399892
400815
  userFacingName() {
399893
400816
  return "Creating worktree";
@@ -400054,7 +400977,7 @@ function restoreSessionToOriginalCwd(originalCwd, projectRootIsWorktree) {
400054
400977
  clearMemoryFileCaches();
400055
400978
  getPlansDirectory.cache.clear?.();
400056
400979
  }
400057
- var inputSchema36, outputSchema31, ExitWorktreeTool;
400980
+ var inputSchema37, outputSchema32, ExitWorktreeTool;
400058
400981
  var init_ExitWorktreeTool = __esm(() => {
400059
400982
  init_v4();
400060
400983
  init_state();
@@ -400069,11 +400992,11 @@ var init_ExitWorktreeTool = __esm(() => {
400069
400992
  init_sessionStorage();
400070
400993
  init_worktree3();
400071
400994
  init_UI22();
400072
- inputSchema36 = lazySchema(() => exports_external.strictObject({
400995
+ inputSchema37 = lazySchema(() => exports_external.strictObject({
400073
400996
  action: exports_external.enum(["keep", "remove"]).describe('"keep" leaves the worktree and branch on disk; "remove" deletes both.'),
400074
400997
  discard_changes: exports_external.boolean().optional().describe('Required true when action is "remove" and the worktree has uncommitted files or unmerged commits. The tool will refuse and list them otherwise.')
400075
400998
  }));
400076
- outputSchema31 = lazySchema(() => exports_external.object({
400999
+ outputSchema32 = lazySchema(() => exports_external.object({
400077
401000
  action: exports_external.enum(["keep", "remove"]),
400078
401001
  originalCwd: exports_external.string(),
400079
401002
  worktreePath: exports_external.string(),
@@ -400094,10 +401017,10 @@ var init_ExitWorktreeTool = __esm(() => {
400094
401017
  return getExitWorktreeToolPrompt();
400095
401018
  },
400096
401019
  get inputSchema() {
400097
- return inputSchema36();
401020
+ return inputSchema37();
400098
401021
  },
400099
401022
  get outputSchema() {
400100
- return outputSchema31();
401023
+ return outputSchema32();
400101
401024
  },
400102
401025
  userFacingName() {
400103
401026
  return "Exiting worktree";
@@ -401000,8 +401923,8 @@ ${lines.join(`
401000
401923
  - model - Override the default model (modelS, modelO, modelH, best, or full model ID)`;
401001
401924
  }
401002
401925
  }
401003
- var DESCRIPTION13 = "Get or set UR configuration settings.";
401004
- var init_prompt18 = __esm(() => {
401926
+ var DESCRIPTION14 = "Get or set UR configuration settings.";
401927
+ var init_prompt19 = __esm(() => {
401005
401928
  init_modelOptions();
401006
401929
  init_voiceModeEnabled();
401007
401930
  init_supportedSettings();
@@ -401706,7 +402629,7 @@ function buildNestedObject(path18, value) {
401706
402629
  }
401707
402630
  return { [key]: buildNestedObject(path18.slice(1), value) };
401708
402631
  }
401709
- var inputSchema37, outputSchema32, ConfigTool;
402632
+ var inputSchema38, outputSchema33, ConfigTool;
401710
402633
  var init_ConfigTool = __esm(() => {
401711
402634
  init_v4();
401712
402635
  init_analytics();
@@ -401716,14 +402639,14 @@ var init_ConfigTool = __esm(() => {
401716
402639
  init_log2();
401717
402640
  init_settings2();
401718
402641
  init_slowOperations();
401719
- init_prompt18();
402642
+ init_prompt19();
401720
402643
  init_supportedSettings();
401721
402644
  init_UI23();
401722
- inputSchema37 = lazySchema(() => exports_external.strictObject({
402645
+ inputSchema38 = lazySchema(() => exports_external.strictObject({
401723
402646
  setting: exports_external.string().describe('The setting key (e.g., "theme", "model", "permissions.defaultMode")'),
401724
402647
  value: exports_external.union([exports_external.string(), exports_external.boolean(), exports_external.number()]).optional().describe("The new value. Omit to get current value.")
401725
402648
  }));
401726
- outputSchema32 = lazySchema(() => exports_external.object({
402649
+ outputSchema33 = lazySchema(() => exports_external.object({
401727
402650
  success: exports_external.boolean(),
401728
402651
  operation: exports_external.enum(["get", "set"]).optional(),
401729
402652
  setting: exports_external.string().optional(),
@@ -401737,16 +402660,16 @@ var init_ConfigTool = __esm(() => {
401737
402660
  searchHint: "get or set UR settings (theme, model)",
401738
402661
  maxResultSizeChars: 1e5,
401739
402662
  async description() {
401740
- return DESCRIPTION13;
402663
+ return DESCRIPTION14;
401741
402664
  },
401742
402665
  async prompt() {
401743
402666
  return generatePrompt();
401744
402667
  },
401745
402668
  get inputSchema() {
401746
- return inputSchema37();
402669
+ return inputSchema38();
401747
402670
  },
401748
402671
  get outputSchema() {
401749
- return outputSchema32();
402672
+ return outputSchema33();
401750
402673
  },
401751
402674
  userFacingName() {
401752
402675
  return "Config";
@@ -402049,351 +402972,6 @@ var init_ConfigTool = __esm(() => {
402049
402972
  });
402050
402973
  });
402051
402974
 
402052
- // src/utils/messagePredicates.ts
402053
- function isHumanTurn(m) {
402054
- return m.type === "user" && !m.isMeta && m.toolUseResult === undefined;
402055
- }
402056
-
402057
- // src/utils/taskListRunContext.ts
402058
- import { AsyncLocalStorage as AsyncLocalStorage5 } from "async_hooks";
402059
- import { randomUUID as randomUUID40 } from "crypto";
402060
- function runWithTaskListRun(run2, fn) {
402061
- return taskListRunStorage.run({ run: run2 }, fn);
402062
- }
402063
- function getTaskListRunContext() {
402064
- return taskListRunStorage.getStore()?.run;
402065
- }
402066
- function textFromQueuedCommand(command) {
402067
- if (command.preExpansionValue)
402068
- return command.preExpansionValue;
402069
- if (typeof command.value === "string")
402070
- return command.value;
402071
- return command.value.filter((block2) => block2.type === "text").map((block2) => ("text" in block2) ? block2.text : "").join(`
402072
- `);
402073
- }
402074
- function textFromMessage(message) {
402075
- const content = message.message?.content;
402076
- if (typeof content === "string")
402077
- return content;
402078
- if (!Array.isArray(content))
402079
- return "";
402080
- return content.filter((block2) => block2.type === "text").map((block2) => ("text" in block2) ? block2.text : "").join(`
402081
- `);
402082
- }
402083
- function requestsAppendToCurrentTaskList(input) {
402084
- const normalized = input.replace(/\s+/gu, " ").trim().toLowerCase();
402085
- if (!normalized)
402086
- return false;
402087
- return /\b(?:add|append|put|queue)\b.{0,100}\b(?:current|existing|active|same)\s+(?:task\s+)?list\b/u.test(normalized) || /\b(?:add|append|put|queue)\b.{0,100}\b(?:current|existing|active)\s+tasks\b/u.test(normalized) || /\b(?:add|append|put|queue)\s+(?:this|it)\s+(?:to|on)\s+(?:my|the|your)\s+(?:current\s+)?(?:task\s+)?list\b/u.test(normalized) || /\b(?:current|existing|active|same)\s+(?:task\s+)?list\b.{0,100}\b(?:add|append|put|queue)\b/u.test(normalized) || /\b(?:keep|continue|use)\b.{0,100}\b(?:current|existing|active|same)\s+(?:task\s+)?list\b/u.test(normalized);
402088
- }
402089
- function requestsContinueCurrentTaskList(input) {
402090
- const normalized = input.replace(/\s+/gu, " ").trim().toLowerCase().replace(/[.!?]+$/gu, "").trim();
402091
- if (!normalized || normalized.length > 80)
402092
- return false;
402093
- return /^(?:ok(?:ay)?|yes|yep|yup|sure|approved|i approve|looks good|sounds good)$/u.test(normalized) || /^(?:please\s+)?(?:continue|proceed|go ahead|carry on|do it|start(?: now)?|begin implementation|start implementation)$/u.test(normalized) || /^(?:ok(?:ay)?|yes|sure|approved|i approve)[, ]+(?:please\s+)?(?:continue|proceed|go ahead|carry on|do it|start(?: now)?|begin implementation|start implementation)$/u.test(normalized);
402094
- }
402095
- function requestsRevisionOfCurrentTaskList(input) {
402096
- const normalized = input.replace(/\s+/gu, " ").trim().toLowerCase();
402097
- if (!normalized || normalized.length > 500)
402098
- return false;
402099
- return /^(?:no|also|and|but|actually|instead|still|again|not yet|(?:it|this|that)\s+still)\b/u.test(normalized) || /\b(?:why did (?:you|u)|i (?:said|asked|meant)|you (?:removed|deleted|changed|forgot|missed))\b/u.test(normalized) || /^(?:please\s+)?(?:fix|change|update|restore|keep|remove|add)\s+(?:it|that|this)\b/u.test(normalized) || /^(?:please\s+)?(?:do not|don't)\s+(?:remove|delete|change|replace|forget)\b/u.test(normalized);
402100
- }
402101
- function shouldKeepCurrentTaskList(input) {
402102
- return requestsAppendToCurrentTaskList(input) || requestsContinueCurrentTaskList(input) || requestsRevisionOfCurrentTaskList(input);
402103
- }
402104
- function withoutCode(input) {
402105
- return input.replace(/```[\s\S]*?```/gu, " ").replace(/`[^`\n]*`/gu, " ");
402106
- }
402107
- function proseOnly(input) {
402108
- return withoutCode(input).replace(/\s+/gu, " ").trim();
402109
- }
402110
- function taskListRequirementReason(input) {
402111
- const text2 = proseOnly(input);
402112
- if (!text2)
402113
- return;
402114
- 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);
402115
- if (optsOut)
402116
- return;
402117
- 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)) {
402118
- return "explicit task tracking request";
402119
- }
402120
- 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)) {
402121
- return "planning workflow";
402122
- }
402123
- if (/\b(?:delegate|delegation|sub[ -]?agents?|parallel\s+agents?|agent\s+team|team\s+of\s+agents?|fan[ -]?out)\b/iu.test(text2)) {
402124
- return "delegation or parallel agent work";
402125
- }
402126
- const hasAction = new RegExp(String.raw`\b${ACTION_WORD}\b`, "iu").test(text2);
402127
- 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)) {
402128
- return "release, security, migration, or production risk";
402129
- }
402130
- const structuralText = withoutCode(input);
402131
- const enumeratedItems = structuralText.match(/(?:^|\n)\s*(?:[-*+]\s+|\d+[.)]\s+)\S/gu);
402132
- const actionLines = structuralText.split(/\r?\n/gu).filter((line) => new RegExp(String.raw`\b${ACTION_WORD}\b`, "iu").test(line));
402133
- if ((enumeratedItems?.length ?? 0) >= 2 || actionLines.length >= 2 || SEQUENCED_ACTION_RE.test(text2)) {
402134
- return "multiple requested outcomes";
402135
- }
402136
- 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");
402137
- if (targetList.test(text2))
402138
- return "multiple requested outcomes";
402139
- const projectScope = /\b(?:app|application|agent|system|platform|website|dashboard|service|integration|workflow|codebase|project|plugin|extension|3d\s+(?:scene|design|pipeline))\b/iu;
402140
- 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;
402141
- if (projectScope.test(text2) && projectAction.test(text2)) {
402142
- return "large project scope";
402143
- }
402144
- ACTION_RE.lastIndex = 0;
402145
- if (text2.length >= 600 && ACTION_RE.test(text2)) {
402146
- return "detailed multi-step request";
402147
- }
402148
- return;
402149
- }
402150
- function getTaskListRunForCommand(command, options2 = {}) {
402151
- if (!command || command.mode !== "prompt" || command.isMeta)
402152
- return;
402153
- const text2 = textFromQueuedCommand(command);
402154
- if (!options2.allowSlashCommand && !command.skipSlashCommands && text2.trimStart().startsWith("/")) {
402155
- return;
402156
- }
402157
- const requirementReason = taskListRequirementReason(text2);
402158
- return {
402159
- generationId: String(command.uuid ?? randomUUID40()),
402160
- appendToCurrent: shouldKeepCurrentTaskList(text2),
402161
- requiresTaskList: requirementReason !== undefined,
402162
- ...requirementReason ? { requirementReason } : {}
402163
- };
402164
- }
402165
- function getTaskListRunFromMessages(messages) {
402166
- const message = messages.findLast(isHumanTurn);
402167
- if (!message || typeof message.uuid !== "string" || !message.uuid) {
402168
- return;
402169
- }
402170
- const text2 = textFromMessage(message);
402171
- const requirementReason = taskListRequirementReason(text2);
402172
- return {
402173
- generationId: message.uuid,
402174
- appendToCurrent: shouldKeepCurrentTaskList(text2),
402175
- requiresTaskList: requirementReason !== undefined,
402176
- ...requirementReason ? { requirementReason } : {}
402177
- };
402178
- }
402179
- var taskListRunStorage, ACTION_WORD, ACTION_RE, SEQUENCED_ACTION_RE;
402180
- var init_taskListRunContext = __esm(() => {
402181
- taskListRunStorage = new AsyncLocalStorage5;
402182
- 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)`;
402183
- ACTION_RE = new RegExp(String.raw`\b${ACTION_WORD}\b`, "giu");
402184
- 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");
402185
- });
402186
-
402187
- // src/tools/TaskCreateTool/prompt.ts
402188
- function getPrompt4() {
402189
- const teammateContext = isAgentSwarmsEnabled() ? " and potentially assigned to teammates" : "";
402190
- const teammateTips = isAgentSwarmsEnabled() ? `- Include enough detail in the description for another agent to understand and complete the task
402191
- - New tasks are created with status 'pending' and no owner - use TaskUpdate with the \`owner\` parameter to assign them
402192
- ` : "";
402193
- return `Use this tool to create a structured task list for your current coding session. This helps you track progress, organize complex tasks, and demonstrate thoroughness to the user.
402194
- It also helps the user understand the progress of the task and overall progress of their requests.
402195
-
402196
- ## When to Use This Tool
402197
-
402198
- Use this tool proactively in these scenarios:
402199
-
402200
- - Multi-outcome work - When a request has 2 or more distinct requested outcomes, deliverables, or sequenced actions
402201
- - Non-trivial and complex tasks - Tasks that require careful planning or multiple operations${teammateContext}
402202
- - Multiple independently verifiable outcomes, dependency ordering, delegation, or parallel work
402203
- - High-risk lifecycle work - Releases, publishing, deployment, migrations, security, credentials, permissions, sandboxing, or production changes
402204
- - Project-sized builds, integrations, workflows, refactors, and audits
402205
- - Plan mode - When using plan mode, create a task list to track the work
402206
- - User explicitly requests todo list - When the user directly asks you to use the todo list
402207
- - 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.
402208
- - User provides multiple tasks - When users provide a list of things to be done (numbered or comma-separated)
402209
- - When new instructions materially change multi-step work - update the plan before continuing
402210
-
402211
- ## When NOT to Use This Tool
402212
-
402213
- Skip using this tool when:
402214
- - The task is purely conversational or informational
402215
- - The request is one genuinely atomic, low-risk action with one outcome that can be completed and verified directly
402216
- - The user sends a short acknowledgement, correction, or clarification that does not add a distinct outcome to an existing board
402217
-
402218
- 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.
402219
-
402220
- EXCEPTION: none of the "skip" rules apply when the user explicitly asks for an item to be added to the task list ("add to your tasks \u2026"). An explicit request always wins \u2014 create the task.
402221
-
402222
- ## Task Fields
402223
-
402224
- - **subject**: A brief, actionable title in imperative form (e.g., "Fix authentication bug in login flow")
402225
- - **description**: What needs to be done
402226
- - **activeForm** (optional): Present continuous form shown in the spinner when the task is in_progress (e.g., "Fixing authentication bug"). If omitted, the spinner shows the subject instead.
402227
- - **blocks** / **addBlocks** (optional): Existing task IDs this task blocks
402228
- - **blockedBy** / **addBlockedBy** (optional): Existing task IDs that block this task
402229
- - **addToCurrentList** (optional): Set to \`true\` when the user explicitly asks to append to the current/existing task list. A new prompt archives the previous list only when it has no pending or in-progress work; an interruption preserves active work for reconciliation.
402230
-
402231
- All tasks are created with status \`pending\`.
402232
-
402233
- ## Tips
402234
-
402235
- - Create tasks with clear, specific subjects that describe the outcome
402236
- - Never guess task IDs or reference a task that has not been created yet. For a multi-task plan, create tasks without forward edges, wait for their real IDs, then use TaskUpdate to add dependency edges.
402237
- - A task can depend only on an existing different task; never add a self-dependency.
402238
- ${teammateTips}- Check TaskList first to avoid creating duplicate tasks
402239
- - Use TaskUpdate, not TaskCreate, for status or ownership changes
402240
- - After an interruption, call TaskList, keep relevant active work, update the affected task, add a task only for a genuinely distinct new outcome, and mark superseded work skipped
402241
- - Do not set \`addToCurrentList\` merely because earlier tasks exist; runtime already preserves interrupted work, while this flag is reserved for explicit user intent such as "add this to the current list"
402242
- `;
402243
- }
402244
- var DESCRIPTION14 = "Create a new task in the task list";
402245
- var init_prompt19 = __esm(() => {
402246
- init_agentSwarmsEnabled();
402247
- });
402248
-
402249
- // src/tools/TaskCreateTool/TaskCreateTool.ts
402250
- var inputSchema38, outputSchema33, TaskCreateTool;
402251
- var init_TaskCreateTool = __esm(() => {
402252
- init_v4();
402253
- init_Tool();
402254
- init_hooks5();
402255
- init_tasks();
402256
- init_taskListRunContext();
402257
- init_teammate();
402258
- init_prompt19();
402259
- inputSchema38 = lazySchema(() => exports_external.strictObject({
402260
- subject: exports_external.string().describe("A brief title for the task"),
402261
- description: exports_external.string().describe("What needs to be done"),
402262
- activeForm: exports_external.string().optional().describe('Present continuous form shown in spinner when in_progress (e.g., "Running tests")'),
402263
- metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional().describe("Arbitrary metadata to attach to the task"),
402264
- blocks: exports_external.array(exports_external.string()).optional().describe("Task IDs that this task blocks at creation time"),
402265
- blockedBy: exports_external.array(exports_external.string()).optional().describe("Task IDs that block this task at creation time"),
402266
- addBlocks: exports_external.array(exports_external.string()).optional().describe("Alias for blocks, accepted for compatibility with TaskUpdate"),
402267
- addBlockedBy: exports_external.array(exports_external.string()).optional().describe("Alias for blockedBy, accepted for compatibility with TaskUpdate"),
402268
- addToCurrentList: exports_external.boolean().optional().describe("Set true only when the user explicitly asks to append to the current task list")
402269
- }));
402270
- outputSchema33 = lazySchema(() => exports_external.object({
402271
- task: exports_external.object({
402272
- id: exports_external.string(),
402273
- subject: exports_external.string()
402274
- })
402275
- }));
402276
- TaskCreateTool = buildTool({
402277
- name: TASK_CREATE_TOOL_NAME,
402278
- searchHint: "create a task in the task list",
402279
- maxResultSizeChars: 1e5,
402280
- async description() {
402281
- return DESCRIPTION14;
402282
- },
402283
- async prompt() {
402284
- return getPrompt4();
402285
- },
402286
- get inputSchema() {
402287
- return inputSchema38();
402288
- },
402289
- get outputSchema() {
402290
- return outputSchema33();
402291
- },
402292
- userFacingName() {
402293
- return "TaskCreate";
402294
- },
402295
- shouldDefer: false,
402296
- isEnabled() {
402297
- return isTodoV2Enabled();
402298
- },
402299
- isConcurrencySafe() {
402300
- return false;
402301
- },
402302
- toAutoClassifierInput(input) {
402303
- return input.subject;
402304
- },
402305
- renderToolUseMessage() {
402306
- return null;
402307
- },
402308
- async call({
402309
- subject,
402310
- description,
402311
- activeForm,
402312
- metadata,
402313
- blocks,
402314
- blockedBy,
402315
- addBlocks,
402316
- addBlockedBy,
402317
- addToCurrentList
402318
- }, context5) {
402319
- const initialBlocks = [...new Set([...blocks ?? [], ...addBlocks ?? []])];
402320
- const initialBlockedBy = [
402321
- ...new Set([...blockedBy ?? [], ...addBlockedBy ?? []])
402322
- ];
402323
- const taskListId = getTaskListId();
402324
- const run2 = getTaskListRunContext() ?? (context5.agentId ? undefined : getTaskListRunFromMessages(context5.messages ?? []));
402325
- const taskData = {
402326
- subject,
402327
- description,
402328
- activeForm,
402329
- status: "pending",
402330
- owner: undefined,
402331
- blocks: [],
402332
- blockedBy: [],
402333
- metadata
402334
- };
402335
- const taskId = run2 ? await createTaskForRun(taskListId, run2.generationId, taskData, {
402336
- appendToCurrent: run2.appendToCurrent || addToCurrentList === true
402337
- }) : await createTask(taskListId, taskData);
402338
- const dependencies = [
402339
- ...initialBlocks.map((targetId) => ({
402340
- fromTaskId: taskId,
402341
- toTaskId: targetId,
402342
- field: "blocks"
402343
- })),
402344
- ...initialBlockedBy.map((blockerId) => ({
402345
- fromTaskId: blockerId,
402346
- toTaskId: taskId,
402347
- field: "blockedBy"
402348
- }))
402349
- ].filter((edge) => edge.fromTaskId !== edge.toTaskId);
402350
- const dependencyResult = await updateTaskWithDependencies(taskListId, taskId, {}, dependencies);
402351
- if (dependencyResult.success === false) {
402352
- const dependency = dependencyResult.dependency;
402353
- await deleteTask(taskListId, taskId);
402354
- if (dependency) {
402355
- const field = dependencies.find((candidate) => candidate.fromTaskId === dependency.fromTaskId && candidate.toTaskId === dependency.toTaskId)?.field ?? "dependency";
402356
- throw new Error(`Invalid ${field} dependency ` + `#${dependency.fromTaskId} -> #${dependency.toTaskId}: ` + dependencyResult.reason);
402357
- }
402358
- throw new Error(`Failed to create task dependencies: ${dependencyResult.reason}`);
402359
- }
402360
- const blockingErrors = [];
402361
- const generator = executeTaskCreatedHooks(taskId, subject, description, getAgentName(), getTeamName(), undefined, context5?.abortController?.signal, undefined, context5);
402362
- for await (const result of generator) {
402363
- if (result.blockingError) {
402364
- blockingErrors.push(getTaskCreatedHookMessage(result.blockingError));
402365
- }
402366
- }
402367
- if (blockingErrors.length > 0) {
402368
- await deleteTask(taskListId, taskId);
402369
- throw new Error(blockingErrors.join(`
402370
- `));
402371
- }
402372
- context5.setAppState((prev) => {
402373
- if (prev.expandedView === "tasks")
402374
- return prev;
402375
- return { ...prev, expandedView: "tasks" };
402376
- });
402377
- return {
402378
- data: {
402379
- task: {
402380
- id: taskId,
402381
- subject
402382
- }
402383
- }
402384
- };
402385
- },
402386
- mapToolResultToToolResultBlockParam(content, toolUseID) {
402387
- const { task } = content;
402388
- return {
402389
- tool_use_id: toolUseID,
402390
- type: "tool_result",
402391
- content: `Task #${task.id} created successfully: ${task.subject}`
402392
- };
402393
- }
402394
- });
402395
- });
402396
-
402397
402975
  // src/tools/TaskGetTool/prompt.ts
402398
402976
  var DESCRIPTION15 = "Get a task by ID from the task list", PROMPT6 = `Use this tool to retrieve a task by its ID from the task list.
402399
402977
 
@@ -412140,7 +412718,7 @@ var init_stream3 = __esm(() => {
412140
412718
  });
412141
412719
 
412142
412720
  // src/utils/telemetry/betaSessionTracing.ts
412143
- import { createHash as createHash32 } from "crypto";
412721
+ import { createHash as createHash33 } from "crypto";
412144
412722
  function clearBetaTracingState() {
412145
412723
  seenHashes.clear();
412146
412724
  lastReportedMessageHash.clear();
@@ -412167,7 +412745,7 @@ function truncateContent(content, maxSize = MAX_CONTENT_SIZE) {
412167
412745
  };
412168
412746
  }
412169
412747
  function shortHash(content) {
412170
- return createHash32("sha256").update(content).digest("hex").slice(0, 12);
412748
+ return createHash33("sha256").update(content).digest("hex").slice(0, 12);
412171
412749
  }
412172
412750
  function hashSystemPrompt(systemPrompt) {
412173
412751
  return `sp_${shortHash(systemPrompt)}`;
@@ -412443,7 +413021,7 @@ function isAnyTracingEnabled() {
412443
413021
  return isTelemetryEnabled() || isEnhancedTelemetryEnabled() || isBetaTracingEnabled();
412444
413022
  }
412445
413023
  function getTracer() {
412446
- return import_api39.trace.getTracer("ur-agent.gen_ai", "1.80.3");
413024
+ return import_api39.trace.getTracer("ur-agent.gen_ai", "1.80.5");
412447
413025
  }
412448
413026
  function createSpanAttributes(spanType, customAttributes = {}) {
412449
413027
  const baseAttributes = getTelemetryAttributes();
@@ -413101,370 +413679,6 @@ var init_toolErrors = __esm(() => {
413101
413679
  init_messages();
413102
413680
  });
413103
413681
 
413104
- // src/services/tools/taskListGate.ts
413105
- function getTaskListGateConfig() {
413106
- const configured = getInitialSettings()?.tasks?.requireBeforeChanges;
413107
- if (!configured)
413108
- return TASK_LIST_GATE_DEFAULTS;
413109
- return {
413110
- enabled: typeof configured.enabled === "boolean" ? configured.enabled : TASK_LIST_GATE_DEFAULTS.enabled,
413111
- freeReads: typeof configured.freeReads === "number" && Number.isInteger(configured.freeReads) && configured.freeReads >= 0 ? configured.freeReads : TASK_LIST_GATE_DEFAULTS.freeReads
413112
- };
413113
- }
413114
- function isMutatingTool2(toolName) {
413115
- return !GATE_EXEMPT_TOOLS.has(toolName) && KNOWN_MUTATING_TOOLS.has(toolName);
413116
- }
413117
- function isTaskListGateExempt(toolName) {
413118
- return GATE_EXEMPT_TOOLS.has(toolName);
413119
- }
413120
- function countActionableTasksForGate(tasks) {
413121
- return tasks.filter((task) => !task.metadata?._internal && !isAutomaticPromptTask(task) && (task.status === "pending" || task.status === "in_progress")).length;
413122
- }
413123
- function checkTaskListGate(input) {
413124
- const config3 = input.config ?? getTaskListGateConfig();
413125
- if (!config3.enabled)
413126
- return { allowed: true };
413127
- if (input.taskListWriterAvailable === false)
413128
- return { allowed: true };
413129
- if (isTaskListGateExempt(input.toolName))
413130
- return { allowed: true };
413131
- const isMutating = input.isMutating ?? isMutatingTool2(input.toolName);
413132
- if (!isMutating)
413133
- return { allowed: true };
413134
- if (input.taskCount !== null && input.taskCount > 0) {
413135
- return { allowed: true };
413136
- }
413137
- const inherentlyRequiresTaskList = input.isSubagent || ALWAYS_REQUIRE_PLAN_TOOLS.has(input.toolName);
413138
- const classifiedRequirement = input.requiresTaskList === true;
413139
- const forceEveryMutation = config3.freeReads === 0;
413140
- const unclassifiedAllowanceExpired = input.requiresTaskList === undefined && input.readsSoFar >= config3.freeReads;
413141
- const gateRequired = inherentlyRequiresTaskList || classifiedRequirement || forceEveryMutation || unclassifiedAllowanceExpired;
413142
- const requirementContext = input.requirementReason ? ` This turn requires task tracking because it contains ${input.requirementReason}.` : "";
413143
- if (input.taskCount === null) {
413144
- return {
413145
- allowed: false,
413146
- reason: `The task list could not be read, so ${input.toolName} was not allowed ` + `to change state without a verifiable plan.${requirementContext} Retry TaskList or ` + `TaskCreate, then retry this call. Disable with ` + `tasks.requireBeforeChanges.enabled=false in settings.`
413147
- };
413148
- }
413149
- if (!gateRequired)
413150
- return { allowed: true };
413151
- if (inherentlyRequiresTaskList) {
413152
- return {
413153
- allowed: false,
413154
- 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.`
413155
- };
413156
- }
413157
- return {
413158
- allowed: false,
413159
- reason: `No task list exists, and ${input.toolName} changes the workspace. ` + `${requirementContext.trim()}${requirementContext ? " " : ""}` + `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.`
413160
- };
413161
- }
413162
- var TASK_LIST_GATE_DEFAULTS, KNOWN_MUTATING_TOOLS, GATE_EXEMPT_TOOLS, ALWAYS_REQUIRE_PLAN_TOOLS;
413163
- var init_taskListGate = __esm(() => {
413164
- init_settings2();
413165
- init_tasks();
413166
- TASK_LIST_GATE_DEFAULTS = {
413167
- enabled: true,
413168
- freeReads: 3
413169
- };
413170
- KNOWN_MUTATING_TOOLS = new Set([
413171
- "Edit",
413172
- "MultiEdit",
413173
- "Write",
413174
- "NotebookEdit",
413175
- "Bash",
413176
- "Shell",
413177
- "PowerShell",
413178
- "Computer",
413179
- "Agent",
413180
- "Task",
413181
- "REPL"
413182
- ]);
413183
- GATE_EXEMPT_TOOLS = new Set([
413184
- "TaskCreate",
413185
- "TaskUpdate",
413186
- "TaskList",
413187
- "TaskGet",
413188
- "TodoWrite"
413189
- ]);
413190
- ALWAYS_REQUIRE_PLAN_TOOLS = new Set([
413191
- "Agent",
413192
- "Task"
413193
- ]);
413194
- });
413195
-
413196
- // src/services/tools/repeatedFailureGuard.ts
413197
- import { createHash as createHash33 } from "crypto";
413198
- function writeFramedText(hash3, value) {
413199
- hash3.update(`${value.length}:`);
413200
- for (let offset = 0;offset < value.length; ) {
413201
- const end = Math.min(offset + HASH_CHUNK_CODE_UNITS, value.length);
413202
- hash3.update(value.slice(offset, end), "utf16le");
413203
- offset = end;
413204
- }
413205
- }
413206
- function writeToken(hash3, kind, value = "") {
413207
- writeFramedText(hash3, kind);
413208
- writeFramedText(hash3, value);
413209
- }
413210
- function visitCanonical(value, state, depth) {
413211
- state.nodesVisited++;
413212
- if (state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes || depth > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalDepth) {
413213
- throw new CanonicalTraversalLimitError;
413214
- }
413215
- if (value === null) {
413216
- writeToken(state.hash, "null");
413217
- return;
413218
- }
413219
- switch (typeof value) {
413220
- case "string":
413221
- state.textCodeUnitsVisited += value.length;
413222
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413223
- throw new CanonicalTraversalLimitError;
413224
- }
413225
- writeToken(state.hash, "string", value);
413226
- return;
413227
- case "number":
413228
- writeToken(state.hash, "number", Object.is(value, -0) ? "-0" : String(value));
413229
- return;
413230
- case "boolean":
413231
- writeToken(state.hash, "boolean", String(value));
413232
- return;
413233
- case "undefined":
413234
- writeToken(state.hash, "undefined");
413235
- return;
413236
- case "bigint":
413237
- writeToken(state.hash, "bigint", value.toString());
413238
- return;
413239
- case "symbol": {
413240
- const description = String(value.description ?? "");
413241
- state.textCodeUnitsVisited += description.length;
413242
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413243
- throw new CanonicalTraversalLimitError;
413244
- }
413245
- writeToken(state.hash, "symbol", description);
413246
- return;
413247
- }
413248
- case "function": {
413249
- const name = value.name || "<anonymous>";
413250
- state.textCodeUnitsVisited += name.length;
413251
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413252
- throw new CanonicalTraversalLimitError;
413253
- }
413254
- writeToken(state.hash, "function", name);
413255
- return;
413256
- }
413257
- case "object": {
413258
- const object4 = value;
413259
- const existingReference = state.seen.get(object4);
413260
- if (existingReference !== undefined) {
413261
- writeToken(state.hash, "reference", String(existingReference));
413262
- return;
413263
- }
413264
- const reference = state.nextReference++;
413265
- state.seen.set(object4, reference);
413266
- if (Array.isArray(value)) {
413267
- if (value.length + state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes) {
413268
- throw new CanonicalTraversalLimitError;
413269
- }
413270
- writeToken(state.hash, "array", String(value.length));
413271
- for (let index2 = 0;index2 < value.length; index2++) {
413272
- if (!(index2 in value)) {
413273
- writeToken(state.hash, "hole");
413274
- continue;
413275
- }
413276
- visitCanonical(value[index2], state, depth + 1);
413277
- }
413278
- return;
413279
- }
413280
- const record3 = value;
413281
- const keys2 = Object.keys(record3);
413282
- if (keys2.length + state.nodesVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalNodes) {
413283
- throw new CanonicalTraversalLimitError;
413284
- }
413285
- keys2.sort();
413286
- writeToken(state.hash, "object", String(keys2.length));
413287
- for (const key of keys2) {
413288
- state.textCodeUnitsVisited += key.length;
413289
- if (state.textCodeUnitsVisited > REPEATED_FAILURE_GUARD_LIMITS.maxCanonicalTextCodeUnits) {
413290
- throw new CanonicalTraversalLimitError;
413291
- }
413292
- writeToken(state.hash, "key", key);
413293
- visitCanonical(record3[key], state, depth + 1);
413294
- }
413295
- return;
413296
- }
413297
- }
413298
- }
413299
- function digestText(domain2, value) {
413300
- const hash3 = createHash33("sha256");
413301
- writeToken(hash3, "domain", domain2);
413302
- writeToken(hash3, "value", value);
413303
- return hash3.digest("hex");
413304
- }
413305
- function canonicalInputDigest(input) {
413306
- const hash3 = createHash33("sha256");
413307
- writeToken(hash3, "domain", "repeated-failure-input-v2");
413308
- visitCanonical(input, {
413309
- hash: hash3,
413310
- nextReference: 0,
413311
- nodesVisited: 0,
413312
- textCodeUnitsVisited: 0,
413313
- seen: new WeakMap
413314
- }, 0);
413315
- return hash3.digest("hex");
413316
- }
413317
- function uniqueSerializationFailureDigest() {
413318
- serializationFailureNonce++;
413319
- return digestText("repeated-failure-unserializable-v2", serializationFailureNonce.toString());
413320
- }
413321
- function scopeDigest(scope) {
413322
- return scope ? digestText("repeated-failure-scope-v2", scope) : UNSCOPED_DIGEST;
413323
- }
413324
- function callSignature(toolName, input, scope) {
413325
- let inputDigest;
413326
- try {
413327
- inputDigest = canonicalInputDigest(input);
413328
- } catch {
413329
- inputDigest = uniqueSerializationFailureDigest();
413330
- }
413331
- return [
413332
- SIGNATURE_VERSION,
413333
- scopeDigest(scope),
413334
- digestText("repeated-failure-tool-v2", toolName),
413335
- inputDigest
413336
- ].join(":");
413337
- }
413338
- function isSha256Digest(value) {
413339
- return value?.length === SHA256_HEX_LENGTH && /^[0-9a-f]+$/.test(value);
413340
- }
413341
- function signatureStorageIdentity(signature) {
413342
- if (signature.length === UNSCOPED_SIGNATURE_LENGTH || signature.length === SCOPED_SIGNATURE_LENGTH) {
413343
- const parts = signature.split(":");
413344
- if (parts.length === 4 && parts[0] === SIGNATURE_VERSION && (parts[1] === UNSCOPED_DIGEST || isSha256Digest(parts[1])) && isSha256Digest(parts[2]) && isSha256Digest(parts[3])) {
413345
- return { key: signature, scope: parts[1] };
413346
- }
413347
- }
413348
- return {
413349
- key: `${SIGNATURE_VERSION}:legacy:${digestText("repeated-failure-legacy-signature-v2", signature)}`,
413350
- scope: UNSCOPED_DIGEST
413351
- };
413352
- }
413353
- function pruneExpiredFailures(now5) {
413354
- for (const [signature, record3] of failureCounts) {
413355
- if (now5 >= record3.lastFailureAt && now5 - record3.lastFailureAt >= REPEATED_FAILURE_GUARD_LIMITS.entryTtlMs) {
413356
- failureCounts.delete(signature);
413357
- }
413358
- }
413359
- }
413360
- function enforceFailureBounds(scope) {
413361
- let entriesInScope = 0;
413362
- for (const record3 of failureCounts.values()) {
413363
- if (record3.scopeDigest === scope)
413364
- entriesInScope++;
413365
- }
413366
- let scopeOverflow = entriesInScope - REPEATED_FAILURE_GUARD_LIMITS.maxEntriesPerScope;
413367
- if (scopeOverflow > 0) {
413368
- for (const [signature, record3] of failureCounts) {
413369
- if (record3.scopeDigest !== scope)
413370
- continue;
413371
- failureCounts.delete(signature);
413372
- scopeOverflow--;
413373
- if (scopeOverflow === 0)
413374
- break;
413375
- }
413376
- }
413377
- while (failureCounts.size > REPEATED_FAILURE_GUARD_LIMITS.maxEntries) {
413378
- const oldest = failureCounts.keys().next().value;
413379
- if (oldest === undefined)
413380
- break;
413381
- failureCounts.delete(oldest);
413382
- }
413383
- }
413384
- function recordCallFailure(signature) {
413385
- const now5 = repeatedFailureNow();
413386
- pruneExpiredFailures(now5);
413387
- const identity5 = signatureStorageIdentity(signature);
413388
- const existing2 = failureCounts.get(identity5.key);
413389
- const next = (existing2?.failures ?? 0) + 1;
413390
- const signatureScope = existing2?.scopeDigest ?? identity5.scope;
413391
- failureCounts.delete(identity5.key);
413392
- failureCounts.set(identity5.key, {
413393
- failures: next,
413394
- lastFailureAt: now5,
413395
- scopeDigest: signatureScope
413396
- });
413397
- enforceFailureBounds(signatureScope);
413398
- return next;
413399
- }
413400
- function recordCallSuccess(signature) {
413401
- failureCounts.delete(signatureStorageIdentity(signature).key);
413402
- }
413403
- function clearRepeatedFailuresForScope(scope) {
413404
- const target = scopeDigest(scope);
413405
- let cleared = 0;
413406
- for (const [signature, record3] of failureCounts) {
413407
- if (record3.scopeDigest !== target)
413408
- continue;
413409
- failureCounts.delete(signature);
413410
- cleared++;
413411
- }
413412
- return cleared;
413413
- }
413414
- function clearRepeatedFailuresForQuery(queryChainId) {
413415
- return clearRepeatedFailuresForScope(`query:${queryChainId}`);
413416
- }
413417
- function checkRepeatedFailure(signature, config3 = REPEATED_FAILURE_DEFAULTS) {
413418
- if (!config3.enabled)
413419
- return { action: "allow" };
413420
- const now5 = repeatedFailureNow();
413421
- pruneExpiredFailures(now5);
413422
- const failures = failureCounts.get(signatureStorageIdentity(signature).key)?.failures ?? 0;
413423
- if (failures >= config3.abortAfter) {
413424
- return {
413425
- action: "abort",
413426
- reason: `This exact call has failed ${failures} times and is still being ` + `repeated. Stopping the turn rather than continuing to loop.`
413427
- };
413428
- }
413429
- if (failures >= config3.limit) {
413430
- return {
413431
- action: "refuse",
413432
- 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.`
413433
- };
413434
- }
413435
- return { action: "allow" };
413436
- }
413437
- 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;
413438
- var init_repeatedFailureGuard = __esm(() => {
413439
- REPEATED_FAILURE_DEFAULTS = {
413440
- enabled: false,
413441
- limit: 3,
413442
- abortAfter: 6
413443
- };
413444
- REPEATED_FAILURE_GUARD_LIMITS = {
413445
- maxEntries: 2048,
413446
- maxEntriesPerScope: 256,
413447
- entryTtlMs: 30 * 60 * 1000,
413448
- maxCanonicalNodes: 50000,
413449
- maxCanonicalDepth: 128,
413450
- maxCanonicalTextCodeUnits: 1e6
413451
- };
413452
- HASH_CHUNK_CODE_UNITS = 16 * 1024;
413453
- UNSCOPED_SIGNATURE_LENGTH = SIGNATURE_VERSION.length + 3 + 1 + SHA256_HEX_LENGTH * 2;
413454
- SCOPED_SIGNATURE_LENGTH = SIGNATURE_VERSION.length + 3 + SHA256_HEX_LENGTH * 3;
413455
- failureCounts = new Map;
413456
- repeatedFailureNow = Date.now;
413457
- CanonicalTraversalLimitError = class CanonicalTraversalLimitError extends Error {
413458
- };
413459
- RepeatedToolFailureAbort = class RepeatedToolFailureAbort extends Error {
413460
- constructor(message) {
413461
- super(message);
413462
- this.name = "RepeatedToolFailureAbort";
413463
- Object.setPrototypeOf(this, new.target.prototype);
413464
- }
413465
- };
413466
- });
413467
-
413468
413682
  // src/stability/types.ts
413469
413683
  var DEFAULT_LIMITS;
413470
413684
  var init_types12 = __esm(() => {
@@ -414249,6 +414463,19 @@ async function countTasksForGate() {
414249
414463
  return null;
414250
414464
  }
414251
414465
  }
414466
+ function isCurrentPlanFileMutation(toolName, input, context5) {
414467
+ if (context5.getAppState().toolPermissionContext.mode !== "plan" || toolName !== FILE_WRITE_TOOL_NAME && toolName !== FILE_EDIT_TOOL_NAME || !input || typeof input !== "object" || Array.isArray(input)) {
414468
+ return false;
414469
+ }
414470
+ const filePath = input.file_path;
414471
+ if (typeof filePath !== "string")
414472
+ return false;
414473
+ try {
414474
+ return expandPath(filePath) === expandPath(getPlanFilePath(context5.agentId));
414475
+ } catch {
414476
+ return false;
414477
+ }
414478
+ }
414252
414479
  function getStopHookInfo(attachment) {
414253
414480
  if (typeof attachment !== "object" || attachment === null || !("command" in attachment) || typeof attachment.command !== "string" || !("durationMs" in attachment) || typeof attachment.durationMs !== "number") {
414254
414481
  return null;
@@ -414713,6 +414940,7 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
414713
414940
  isMutating,
414714
414941
  requiresTaskList: taskListRun?.requiresTaskList,
414715
414942
  requirementReason: taskListRun?.requirementReason,
414943
+ isPlanningArtifact: isCurrentPlanFileMutation(tool.name, parsedInput.data, toolUseContext),
414716
414944
  taskListWriterAvailable: toolUseContext.options.tools.some((candidate) => candidate.name === "TaskCreate")
414717
414945
  });
414718
414946
  if (gate.allowed === false) {
@@ -415073,6 +415301,7 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
415073
415301
  isMutating: finalIsMutating,
415074
415302
  requiresTaskList: taskListRun?.requiresTaskList,
415075
415303
  requirementReason: taskListRun?.requirementReason,
415304
+ isPlanningArtifact: isCurrentPlanFileMutation(tool.name, finalParsedInput.data, toolUseContext),
415076
415305
  taskListWriterAvailable: toolUseContext.options.tools.some((candidate) => candidate.name === "TaskCreate")
415077
415306
  });
415078
415307
  if (finalGate.allowed === false) {
@@ -415360,6 +415589,8 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input, toolUseContex
415360
415589
  error: errorMessage2(error40)
415361
415590
  });
415362
415591
  endToolSpan();
415592
+ if (error40 instanceof RepeatedToolFailureAbort)
415593
+ throw error40;
415363
415594
  if (error40 instanceof McpAuthError) {
415364
415595
  toolUseContext.setAppState((prevState) => {
415365
415596
  const serverName = error40.serverName;
@@ -415505,6 +415736,8 @@ var init_toolExecution = __esm(() => {
415505
415736
  init_messages();
415506
415737
  init_sessionActivity();
415507
415738
  init_slowOperations();
415739
+ init_plans();
415740
+ init_path();
415508
415741
  init_stream3();
415509
415742
  init_events();
415510
415743
  init_sessionTracing();
@@ -433170,7 +433403,7 @@ function getPlanModeV2Instructions(attachment) {
433170
433403
  const agentCount = getPlanModeV2AgentCount();
433171
433404
  const exploreAgentCount = getPlanModeV2ExploreAgentCount();
433172
433405
  const planFileInfo = attachment.planExists ? `A plan file already exists at ${attachment.planFilePath}. You can read it and make incremental edits using the ${FileEditTool.name} tool.` : `No plan file exists yet. You should create your plan at ${attachment.planFilePath} using the ${FileWriteTool.name} tool.`;
433173
- const content = `Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supercedes any other instructions you have received.
433406
+ const content = `Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. TaskCreate, TaskUpdate, TaskList, and TaskGet are also allowed for visible task tracking. This supercedes any other instructions you have received.
433174
433407
 
433175
433408
  ## Plan File Info:
433176
433409
  ${planFileInfo}
@@ -433227,6 +433460,7 @@ ${getPlanPhase4Section()}
433227
433460
 
433228
433461
  ### Phase 5: Call ${ExitPlanModeV2Tool.name}
433229
433462
  At the very end of your turn, once you have asked the user questions and are happy with your final plan file - you should always call ${ExitPlanModeV2Tool.name} to indicate to the user that you are done planning.
433463
+ Plan-file writes do not require an existing task list. You may create semantic tasks manually with TaskCreate, but do not block on that: after user approval, ${ExitPlanModeV2Tool.name} guarantees visible implementation and verification tasks exist before coding starts.
433230
433464
  This is critical - your turn should only end with either using the ${ASK_USER_QUESTION_TOOL_NAME} tool OR calling ${ExitPlanModeV2Tool.name}. Do not stop unless it's for these 2 reasons
433231
433465
 
433232
433466
  **Important:** Use ${ASK_USER_QUESTION_TOOL_NAME} ONLY to clarify requirements or choose between approaches. Use ${ExitPlanModeV2Tool.name} to request plan approval. Do NOT ask about plan approval in any other way - no text questions, no AskUserQuestion. Phrases like "Is this plan okay?", "Should I proceed?", "How does this plan look?", "Any changes before we start?", or similar MUST use ${ExitPlanModeV2Tool.name}.
@@ -433244,7 +433478,7 @@ function getReadOnlyToolNames() {
433244
433478
  }
433245
433479
  function getPlanModeInterviewInstructions(attachment) {
433246
433480
  const planFileInfo = attachment.planExists ? `A plan file already exists at ${attachment.planFilePath}. You can read it and make incremental edits using the ${FileEditTool.name} tool.` : `No plan file exists yet. You should create your plan at ${attachment.planFilePath} using the ${FileWriteTool.name} tool.`;
433247
- const content = `Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. This supercedes any other instructions you have received.
433481
+ const content = `Plan mode is active. The user indicated that they do not want you to execute yet -- you MUST NOT make any edits (with the exception of the plan file mentioned below), run any non-readonly tools (including changing configs or making commits), or otherwise make any changes to the system. TaskCreate, TaskUpdate, TaskList, and TaskGet are also allowed for visible task tracking. This supercedes any other instructions you have received.
433248
433482
 
433249
433483
  ## Plan File Info:
433250
433484
  ${planFileInfo}
@@ -433283,7 +433517,7 @@ Your plan file should be divided into clear sections using markdown headers, bas
433283
433517
 
433284
433518
  ### When to Converge
433285
433519
 
433286
- Your plan is ready when you've addressed all ambiguities and it covers: what to change, which files to modify, what existing code to reuse (with file paths), and how to verify the changes. Call ${ExitPlanModeV2Tool.name} when the plan is ready for approval.
433520
+ Your plan is ready when you've addressed all ambiguities and it covers: what to change, which files to modify, what existing code to reuse (with file paths), and how to verify the changes. Plan-file writes do not require an existing task list. You may use TaskCreate for manual decomposition; after approval, ${ExitPlanModeV2Tool.name} guarantees visible implementation and verification tasks before coding begins. Call ${ExitPlanModeV2Tool.name} when the plan is ready for approval.
433287
433521
 
433288
433522
  ### Ending Your Turn
433289
433523
 
@@ -433298,7 +433532,7 @@ Your turn should only end by either:
433298
433532
  }
433299
433533
  function getPlanModeV2SparseInstructions(attachment) {
433300
433534
  const workflowDescription = isPlanModeInterviewPhaseEnabled() ? "Follow iterative workflow: explore codebase, interview user, write to plan incrementally." : "Follow 5-phase workflow.";
433301
- const content = `Plan mode still active (see full instructions earlier in conversation). Read-only except plan file (${attachment.planFilePath}). ${workflowDescription} End turns with ${ASK_USER_QUESTION_TOOL_NAME} (for clarifications) or ${ExitPlanModeV2Tool.name} (for plan approval). Never ask about plan approval via text or AskUserQuestion.`;
433535
+ const content = `Plan mode still active (see full instructions earlier in conversation). Read-only except plan file (${attachment.planFilePath}) and visible task tracking tools. Plan-file writes do not require existing tasks; after approval, ${ExitPlanModeV2Tool.name} guarantees tasks exist before implementation. ${workflowDescription} End turns with ${ASK_USER_QUESTION_TOOL_NAME} (for clarifications) or ${ExitPlanModeV2Tool.name} (for plan approval). Never ask about plan approval via text or AskUserQuestion.`;
433302
433536
  return wrapMessagesInSystemReminder([
433303
433537
  createUserMessage({ content, isMeta: true })
433304
433538
  ]);
@@ -433677,6 +433911,8 @@ You are returning to plan mode after having previously exited it. A plan file ex
433677
433911
  - **Same task, continuing**: If this is explicitly a continuation or refinement of the exact same task, modify the existing plan while cleaning up outdated or irrelevant sections
433678
433912
  4. Continue on with the plan process and most importantly you should always edit the plan file one way or the other before calling ${ExitPlanModeV2Tool.name}
433679
433913
 
433914
+ Writing the exact plan file is allowed without an existing task list. After approval, ${ExitPlanModeV2Tool.name} guarantees visible implementation tasks exist before workspace implementation begins.
433915
+
433680
433916
  Treat this as a fresh planning session. Do not assume the existing plan is relevant without evaluating it first.`;
433681
433917
  return wrapMessagesInSystemReminder([
433682
433918
  createUserMessage({ content, isMeta: true })
@@ -433686,7 +433922,7 @@ Treat this as a fresh planning session. Do not assume the existing plan is relev
433686
433922
  const planReference = attachment.planExists ? ` The plan file is located at ${attachment.planFilePath} if you need to reference it.` : "";
433687
433923
  const content = `## Exited Plan Mode
433688
433924
 
433689
- You have exited plan mode. You can now make edits, run tools, and take actions.${planReference}`;
433925
+ You have exited plan mode. The visible task list is ready; begin with the first unblocked task and keep statuses current. You can now make edits, run tools, and take actions.${planReference}`;
433690
433926
  return wrapMessagesInSystemReminder([
433691
433927
  createUserMessage({ content, isMeta: true })
433692
433928
  ]);
@@ -442891,7 +443127,7 @@ function Feedback({
442891
443127
  platform: env2.platform,
442892
443128
  gitRepo: envInfo.isGit,
442893
443129
  terminal: env2.terminal,
442894
- version: "1.80.3",
443130
+ version: "1.80.5",
442895
443131
  transcript: normalizeMessagesForAPI(messages),
442896
443132
  errors: sanitizedErrors,
442897
443133
  lastApiRequest: getLastAPIRequest(),
@@ -443083,7 +443319,7 @@ function Feedback({
443083
443319
  ", ",
443084
443320
  env2.terminal,
443085
443321
  ", v",
443086
- "1.80.3"
443322
+ "1.80.5"
443087
443323
  ]
443088
443324
  }, undefined, true, undefined, this)
443089
443325
  ]
@@ -443189,7 +443425,7 @@ ${sanitizedDescription}
443189
443425
  ` + `**Environment Info**
443190
443426
  ` + `- Platform: ${env2.platform}
443191
443427
  ` + `- Terminal: ${env2.terminal}
443192
- ` + `- Version: ${"1.80.3"}
443428
+ ` + `- Version: ${"1.80.5"}
443193
443429
  ` + `- Feedback ID: ${feedbackId}
443194
443430
  ` + `
443195
443431
  **Errors**
@@ -446299,7 +446535,7 @@ function buildPrimarySection() {
446299
446535
  }, undefined, false, undefined, this);
446300
446536
  return [{
446301
446537
  label: "Version",
446302
- value: "1.80.3"
446538
+ value: "1.80.5"
446303
446539
  }, {
446304
446540
  label: "Session name",
446305
446541
  value: nameValue
@@ -449681,7 +449917,7 @@ function Config({
449681
449917
  }
449682
449918
  }, undefined, false, undefined, this)
449683
449919
  }, undefined, false, undefined, this) : showSubmenu === "ChannelDowngrade" ? /* @__PURE__ */ jsx_dev_runtime179.jsxDEV(ChannelDowngradeDialog, {
449684
- currentVersion: "1.80.3",
449920
+ currentVersion: "1.80.5",
449685
449921
  onChoice: (choice) => {
449686
449922
  setShowSubmenu(null);
449687
449923
  setTabsHidden(false);
@@ -449693,7 +449929,7 @@ function Config({
449693
449929
  autoUpdatesChannel: "stable"
449694
449930
  };
449695
449931
  if (choice === "stay") {
449696
- newSettings.minimumVersion = "1.80.3";
449932
+ newSettings.minimumVersion = "1.80.5";
449697
449933
  }
449698
449934
  updateSettingsForSource("userSettings", newSettings);
449699
449935
  setSettingsData((prev_27) => ({
@@ -450870,6 +451106,9 @@ var init_Settings = __esm(() => {
450870
451106
  });
450871
451107
 
450872
451108
  // src/commands/config/configAssignments.ts
451109
+ function resolveConfigAssignmentKey(rawKey) {
451110
+ return KEY_ALIASES[rawKey.replaceAll("-", "").toLowerCase()];
451111
+ }
450873
451112
  function booleanValue(value) {
450874
451113
  if (value === "true" || value === "on" || value === "enabled")
450875
451114
  return true;
@@ -450885,9 +451124,9 @@ function parseConfigAssignments(input) {
450885
451124
  if (separator <= 0 || separator === token.length - 1) {
450886
451125
  return { error: `Invalid assignment '${token}'. Expected key=value.` };
450887
451126
  }
450888
- const rawKey = token.slice(0, separator).replaceAll("-", "").toLowerCase();
451127
+ const rawKey = token.slice(0, separator);
450889
451128
  const rawValue = token.slice(separator + 1).toLowerCase();
450890
- const key = KEY_ALIASES[rawKey];
451129
+ const key = resolveConfigAssignmentKey(rawKey);
450891
451130
  if (!key)
450892
451131
  return { error: `Unknown setting '${token.slice(0, separator)}'.` };
450893
451132
  if (key === "editor") {
@@ -450915,10 +451154,115 @@ function parseConfigAssignments(input) {
450915
451154
  }
450916
451155
  return { assignments };
450917
451156
  }
451157
+ function applyConfigAssignments(assignments, effects2 = {}) {
451158
+ const applied = [];
451159
+ for (const assignment of assignments) {
451160
+ switch (assignment.key) {
451161
+ case "thinking": {
451162
+ const value = assignment.value;
451163
+ const result = updateSettingsForSource("userSettings", {
451164
+ alwaysThinkingEnabled: value ? undefined : false
451165
+ });
451166
+ if (result.error) {
451167
+ return { error: `Could not update thinking: ${result.error.message}` };
451168
+ }
451169
+ effects2.thinking?.(value);
451170
+ applied.push(`thinking=${value}`);
451171
+ break;
451172
+ }
451173
+ case "screenReader": {
451174
+ const value = assignment.value;
451175
+ const result = updateSettingsForSource("localSettings", {
451176
+ screenReaderMode: value
451177
+ });
451178
+ if (result.error) {
451179
+ return {
451180
+ error: `Could not update screen reader mode: ${result.error.message}`
451181
+ };
451182
+ }
451183
+ effects2.screenReader?.(value);
451184
+ applied.push(`screenReader=${value}`);
451185
+ break;
451186
+ }
451187
+ case "reducedMotion": {
451188
+ const value = assignment.value;
451189
+ const result = updateSettingsForSource("localSettings", {
451190
+ prefersReducedMotion: value
451191
+ });
451192
+ if (result.error) {
451193
+ return {
451194
+ error: `Could not update reduced motion: ${result.error.message}`
451195
+ };
451196
+ }
451197
+ effects2.reducedMotion?.(value);
451198
+ applied.push(`reducedMotion=${value}`);
451199
+ break;
451200
+ }
451201
+ case "verbose": {
451202
+ const value = assignment.value;
451203
+ const result = updateSettingsForSource("userSettings", {
451204
+ verbose: value
451205
+ });
451206
+ if (result.error) {
451207
+ return {
451208
+ error: `Could not update verbose output: ${result.error.message}`
451209
+ };
451210
+ }
451211
+ effects2.verbose?.(value);
451212
+ applied.push(`verbose=${value}`);
451213
+ break;
451214
+ }
451215
+ case "autoCompact": {
451216
+ const value = assignment.value;
451217
+ saveGlobalConfig((previous) => ({
451218
+ ...previous,
451219
+ autoCompactEnabled: value
451220
+ }));
451221
+ applied.push(`autoCompact=${value}`);
451222
+ break;
451223
+ }
451224
+ case "editor": {
451225
+ const value = assignment.value;
451226
+ saveGlobalConfig((previous) => ({ ...previous, editorMode: value }));
451227
+ applied.push(`editor=${value}`);
451228
+ break;
451229
+ }
451230
+ case "vimEscape": {
451231
+ const value = assignment.value;
451232
+ saveGlobalConfig((previous) => ({
451233
+ ...previous,
451234
+ vimInsertModeEscapeSequence: value || undefined
451235
+ }));
451236
+ applied.push(`vimEscape=${value || "off"}`);
451237
+ break;
451238
+ }
451239
+ }
451240
+ }
451241
+ return { applied };
451242
+ }
451243
+ function getConfigAssignmentValues() {
451244
+ const settings = getInitialSettings();
451245
+ const global3 = getGlobalConfig();
451246
+ return [
451247
+ { key: "thinking", value: settings.alwaysThinkingEnabled !== false },
451248
+ { key: "screenReader", value: settings.screenReaderMode === true },
451249
+ { key: "reducedMotion", value: settings.prefersReducedMotion === true },
451250
+ { key: "verbose", value: settings.verbose === true },
451251
+ { key: "autoCompact", value: global3.autoCompactEnabled },
451252
+ { key: "editor", value: global3.editorMode ?? "normal" },
451253
+ {
451254
+ key: "vimEscape",
451255
+ value: global3.vimInsertModeEscapeSequence || "off"
451256
+ }
451257
+ ];
451258
+ }
450918
451259
  var CONFIG_ASSIGNMENT_HELP, KEY_ALIASES;
450919
451260
  var init_configAssignments = __esm(() => {
451261
+ init_config();
451262
+ init_settings2();
450920
451263
  CONFIG_ASSIGNMENT_HELP = [
450921
451264
  "Usage: /config <key>=<value> [key=value ...]",
451265
+ "CLI: ur config set <key> <value>",
450922
451266
  "",
450923
451267
  "Supported settings:",
450924
451268
  " thinking=true|false Enable or disable model thinking",
@@ -450980,90 +451324,35 @@ ${CONFIG_ASSIGNMENT_HELP}`,
450980
451324
  onDone
450981
451325
  }, undefined, false, undefined, this);
450982
451326
  }
450983
- const applied = [];
450984
- for (const assignment of parsed.assignments) {
450985
- switch (assignment.key) {
450986
- case "thinking": {
450987
- const value = assignment.value;
450988
- const result = updateSettingsForSource("userSettings", { alwaysThinkingEnabled: value ? undefined : false });
450989
- if (result.error)
450990
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
450991
- message: `Could not update thinking: ${result.error.message}`,
450992
- onDone
450993
- }, undefined, false, undefined, this);
450994
- context5.setAppState((previous) => ({ ...previous, thinkingEnabled: value }));
450995
- applied.push(`thinking=${value}`);
450996
- break;
450997
- }
450998
- case "screenReader": {
450999
- const value = assignment.value;
451000
- const result = updateSettingsForSource("localSettings", { screenReaderMode: value });
451001
- if (result.error)
451002
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
451003
- message: `Could not update screen reader mode: ${result.error.message}`,
451004
- onDone
451005
- }, undefined, false, undefined, this);
451006
- if (value)
451007
- enableScreenReaderMode();
451008
- else
451009
- disableScreenReaderMode();
451010
- setScreenReaderRendering(value);
451011
- context5.setAppState((previous) => ({
451012
- ...previous,
451013
- settings: { ...previous.settings, screenReaderMode: value }
451014
- }));
451015
- applied.push(`screenReader=${value}`);
451016
- break;
451017
- }
451018
- case "reducedMotion": {
451019
- const value = assignment.value;
451020
- const result = updateSettingsForSource("localSettings", { prefersReducedMotion: value });
451021
- if (result.error)
451022
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
451023
- message: `Could not update reduced motion: ${result.error.message}`,
451024
- onDone
451025
- }, undefined, false, undefined, this);
451026
- context5.setAppState((previous) => ({ ...previous, settings: { ...previous.settings, prefersReducedMotion: value } }));
451027
- applied.push(`reducedMotion=${value}`);
451028
- break;
451029
- }
451030
- case "verbose": {
451031
- const value = assignment.value;
451032
- const result = updateSettingsForSource("userSettings", { verbose: value });
451033
- if (result.error)
451034
- return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
451035
- message: `Could not update verbose output: ${result.error.message}`,
451036
- onDone
451037
- }, undefined, false, undefined, this);
451038
- context5.setAppState((previous) => ({ ...previous, verbose: value }));
451039
- applied.push(`verbose=${value}`);
451040
- break;
451041
- }
451042
- case "autoCompact": {
451043
- const value = assignment.value;
451044
- saveGlobalConfig((previous) => ({ ...previous, autoCompactEnabled: value }));
451045
- applied.push(`autoCompact=${value}`);
451046
- break;
451047
- }
451048
- case "editor": {
451049
- const value = assignment.value;
451050
- saveGlobalConfig((previous) => ({ ...previous, editorMode: value }));
451051
- applied.push(`editor=${value}`);
451052
- break;
451053
- }
451054
- case "vimEscape": {
451055
- const value = assignment.value;
451056
- saveGlobalConfig((previous) => ({
451057
- ...previous,
451058
- vimInsertModeEscapeSequence: value || undefined
451059
- }));
451060
- applied.push(`vimEscape=${value || "off"}`);
451061
- break;
451062
- }
451327
+ const result = applyConfigAssignments(parsed.assignments, {
451328
+ thinking(value) {
451329
+ context5.setAppState((previous) => ({ ...previous, thinkingEnabled: value }));
451330
+ },
451331
+ screenReader(value) {
451332
+ if (value)
451333
+ enableScreenReaderMode();
451334
+ else
451335
+ disableScreenReaderMode();
451336
+ setScreenReaderRendering(value);
451337
+ context5.setAppState((previous) => ({
451338
+ ...previous,
451339
+ settings: { ...previous.settings, screenReaderMode: value }
451340
+ }));
451341
+ },
451342
+ reducedMotion(value) {
451343
+ context5.setAppState((previous) => ({ ...previous, settings: { ...previous.settings, prefersReducedMotion: value } }));
451344
+ },
451345
+ verbose(value) {
451346
+ context5.setAppState((previous) => ({ ...previous, verbose: value }));
451063
451347
  }
451064
- }
451348
+ });
451349
+ if (result.error)
451350
+ return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
451351
+ message: result.error,
451352
+ onDone
451353
+ }, undefined, false, undefined, this);
451065
451354
  return /* @__PURE__ */ jsx_dev_runtime183.jsxDEV(ConfigResult, {
451066
- message: `Updated ${applied.join(", ")}.`,
451355
+ message: `Updated ${result.applied.join(", ")}.`,
451067
451356
  onDone
451068
451357
  }, undefined, false, undefined, this);
451069
451358
  };
@@ -451071,9 +451360,7 @@ var init_config8 = __esm(() => {
451071
451360
  init_Settings();
451072
451361
  init_ink2();
451073
451362
  init_root();
451074
- init_config();
451075
451363
  init_screenReader();
451076
- init_settings2();
451077
451364
  init_configAssignments();
451078
451365
  import_react110 = __toESM(require_react(), 1);
451079
451366
  jsx_dev_runtime183 = __toESM(require_jsx_dev_runtime(), 1);
@@ -457951,7 +458238,7 @@ function HelpV2(t0) {
457951
458238
  let t6;
457952
458239
  if ($2[31] !== tabs) {
457953
458240
  t6 = /* @__PURE__ */ jsx_dev_runtime206.jsxDEV(Tabs, {
457954
- title: `UR v${"1.80.3"}`,
458241
+ title: `UR v${"1.80.5"}`,
457955
458242
  color: "professionalBlue",
457956
458243
  defaultTab: "general",
457957
458244
  children: tabs
@@ -458884,7 +459171,7 @@ function buildToolUseContext(tools, readFileStateCache, toolPermissionContext, a
458884
459171
  async function handleInitialize(options2) {
458885
459172
  return {
458886
459173
  name: "UR",
458887
- version: "1.80.3",
459174
+ version: "1.80.5",
458888
459175
  protocolVersion: "0.1.0",
458889
459176
  workspaceRoot: options2.cwd,
458890
459177
  capabilities: {
@@ -475992,7 +476279,7 @@ function getAllReleaseNotes(changelogContent = getStoredChangelogFromMemory()) {
475992
476279
  return [];
475993
476280
  }
475994
476281
  }
475995
- async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.3") {
476282
+ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.5") {
475996
476283
  if (process.env.USER_TYPE === "ant") {
475997
476284
  const changelog = "";
475998
476285
  if (changelog) {
@@ -476019,7 +476306,7 @@ async function checkForReleaseNotes(lastSeenVersion, currentVersion = "1.80.3")
476019
476306
  releaseNotes
476020
476307
  };
476021
476308
  }
476022
- function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.80.3") {
476309
+ function checkForReleaseNotesSync(lastSeenVersion, currentVersion = "1.80.5") {
476023
476310
  if (process.env.USER_TYPE === "ant") {
476024
476311
  const changelog = "";
476025
476312
  if (changelog) {
@@ -478924,7 +479211,7 @@ function getRecentActivitySync() {
478924
479211
  return cachedActivity;
478925
479212
  }
478926
479213
  function getLogoDisplayData() {
478927
- const version2 = process.env.DEMO_VERSION ?? "1.80.3";
479214
+ const version2 = process.env.DEMO_VERSION ?? "1.80.5";
478928
479215
  const serverUrl = getDirectConnectServerUrl();
478929
479216
  const displayPath = process.env.DEMO_VERSION ? "/code/ur" : getDisplayPath(getCwd());
478930
479217
  const cwd2 = serverUrl ? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, "")}` : displayPath;
@@ -479792,7 +480079,7 @@ function LogoV2() {
479792
480079
  if ($2[2] === Symbol.for("react.memo_cache_sentinel")) {
479793
480080
  t2 = () => {
479794
480081
  const currentConfig = getGlobalConfig();
479795
- if (currentConfig.lastReleaseNotesSeen === "1.80.3") {
480082
+ if (currentConfig.lastReleaseNotesSeen === "1.80.5") {
479796
480083
  return;
479797
480084
  }
479798
480085
  saveGlobalConfig(_temp325);
@@ -480477,12 +480764,12 @@ function LogoV2() {
480477
480764
  return t41;
480478
480765
  }
480479
480766
  function _temp325(current) {
480480
- if (current.lastReleaseNotesSeen === "1.80.3") {
480767
+ if (current.lastReleaseNotesSeen === "1.80.5") {
480481
480768
  return current;
480482
480769
  }
480483
480770
  return {
480484
480771
  ...current,
480485
- lastReleaseNotesSeen: "1.80.3"
480772
+ lastReleaseNotesSeen: "1.80.5"
480486
480773
  };
480487
480774
  }
480488
480775
  function _temp241(s_0) {
@@ -491931,7 +492218,7 @@ function ShellDetailDialog(t0) {
491931
492218
  const isMonitor = shell.kind === "monitor";
491932
492219
  let t8;
491933
492220
  if ($2[17] !== shell.command) {
491934
- t8 = truncateToWidth(shell.command, 280);
492221
+ t8 = truncateToWidth(formatCommandForDisplay(shell.command), 280);
491935
492222
  $2[17] = shell.command;
491936
492223
  $2[18] = t8;
491937
492224
  } else {
@@ -496574,7 +496861,7 @@ function compileAgenticCiWorkflow(specName = "default", options2 = {}) {
496574
496861
  if (spec.name !== specName) {
496575
496862
  throw new Error("Agentic CI workflow spec name does not match");
496576
496863
  }
496577
- const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.80.3" : "1.80.3");
496864
+ const packageVersion = options2.packageVersion ?? (typeof MACRO !== "undefined" ? "1.80.5" : "1.80.5");
496578
496865
  if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(packageVersion)) {
496579
496866
  throw new Error("invalid ur-agent package version");
496580
496867
  }
@@ -497567,7 +497854,7 @@ runner; \`ur trigger\` is the inbound parser that decides what to run.
497567
497854
  path: ".github/workflows/ur.yml",
497568
497855
  root: "project",
497569
497856
  content: compileAgenticCiWorkflow("default", {
497570
- packageVersion: typeof MACRO !== "undefined" ? "1.80.3" : "1.80.3"
497857
+ packageVersion: typeof MACRO !== "undefined" ? "1.80.5" : "1.80.5"
497571
497858
  })
497572
497859
  },
497573
497860
  {
@@ -497630,7 +497917,7 @@ function value(tokens, flag) {
497630
497917
  return index2 >= 0 ? tokens[index2 + 1] : undefined;
497631
497918
  }
497632
497919
  function cliVersion() {
497633
- return typeof MACRO !== "undefined" ? "1.80.3" : "1.80.3";
497920
+ return typeof MACRO !== "undefined" ? "1.80.5" : "1.80.5";
497634
497921
  }
497635
497922
  function workflowPath(cwd2) {
497636
497923
  return join168(cwd2, ".github", "workflows", "ur-agentic-ci.yml");
@@ -503486,7 +503773,7 @@ function createAcpStdioApp(deps) {
503486
503773
  }
503487
503774
  },
503488
503775
  authMethods: [],
503489
- agentInfo: { name: "UR-Nexus", version: "1.80.3" }
503776
+ agentInfo: { name: "UR-Nexus", version: "1.80.5" }
503490
503777
  })).onRequest("authenticate", () => ({})).onRequest("session/new", async (context6) => {
503491
503778
  const result = runtime2.newSession(context6.params.cwd, context6.params.mcpServers, context6.params.additionalDirectories);
503492
503779
  await runtime2.announce({
@@ -503583,7 +503870,7 @@ function createAcpStdioAgent(deps) {
503583
503870
  }
503584
503871
  },
503585
503872
  authMethods: [],
503586
- agentInfo: { name: "UR-Nexus", version: "1.80.3" }
503873
+ agentInfo: { name: "UR-Nexus", version: "1.80.5" }
503587
503874
  });
503588
503875
  return;
503589
503876
  case "authenticate":
@@ -714809,7 +715096,7 @@ async function captureMemoryDiagnostics(trigger2, dumpNumber = 0) {
714809
715096
  smapsRollup,
714810
715097
  platform: process.platform,
714811
715098
  nodeVersion: process.version,
714812
- ccVersion: "1.80.3"
715099
+ ccVersion: "1.80.5"
714813
715100
  };
714814
715101
  }
714815
715102
  async function performHeapDump(trigger2 = "manual", dumpNumber = 0) {
@@ -715398,7 +715685,7 @@ var init_bridge_kick = __esm(() => {
715398
715685
  var call154 = async () => {
715399
715686
  return {
715400
715687
  type: "text",
715401
- value: "1.80.3"
715688
+ value: "1.80.5"
715402
715689
  };
715403
715690
  }, version2, version_default;
715404
715691
  var init_version = __esm(() => {
@@ -726641,7 +726928,7 @@ function generateHtmlReport(data, insights) {
726641
726928
  </html>`;
726642
726929
  }
726643
726930
  function buildExportData(data, insights, facets, remoteStats) {
726644
- const version3 = typeof MACRO !== "undefined" ? "1.80.3" : "unknown";
726931
+ const version3 = typeof MACRO !== "undefined" ? "1.80.5" : "unknown";
726645
726932
  const remote_hosts_collected = remoteStats?.hosts.filter((h2) => h2.sessionCount > 0).map((h2) => h2.name);
726646
726933
  const facets_summary = {
726647
726934
  total: facets.size,
@@ -730954,7 +731241,7 @@ var init_sessionStorage = __esm(() => {
730954
731241
  init_settings2();
730955
731242
  init_slowOperations();
730956
731243
  init_uuid();
730957
- VERSION7 = typeof MACRO !== "undefined" ? "1.80.3" : "unknown";
731244
+ VERSION7 = typeof MACRO !== "undefined" ? "1.80.5" : "unknown";
730958
731245
  MAX_TOMBSTONE_REWRITE_BYTES = 50 * 1024 * 1024;
730959
731246
  SKIP_FIRST_PROMPT_PATTERN = /^(?:\s*<[a-z][\w-]*[\s>]|\[Request interrupted by user[^\]]*\])/;
730960
731247
  EPHEMERAL_PROGRESS_TYPES = new Set([
@@ -732169,7 +732456,7 @@ var init_filesystem = __esm(() => {
732169
732456
  });
732170
732457
  getBundledSkillsRoot = memoize_default(function getBundledSkillsRoot2() {
732171
732458
  const nonce = randomBytes24(16).toString("hex");
732172
- return join243(getURTempDir(), "bundled-skills", "1.80.3", nonce);
732459
+ return join243(getURTempDir(), "bundled-skills", "1.80.5", nonce);
732173
732460
  });
732174
732461
  getResolvedWorkingDirPaths = memoize_default(getPathsForPermissionCheck);
732175
732462
  });
@@ -734978,7 +735265,7 @@ async function* executeHooks({
734978
735265
  };
734979
735266
  return;
734980
735267
  }
734981
- const { json: json2, plainText, validationError } = parseHookOutput(result.stdout);
735268
+ const { json: json2, plainText: plainText2, validationError } = parseHookOutput(result.stdout);
734982
735269
  if (validationError) {
734983
735270
  emitHookResponse({
734984
735271
  hookId,
@@ -735027,7 +735314,7 @@ async function* executeHooks({
735027
735314
  exitCode: result.status,
735028
735315
  durationMs
735029
735316
  });
735030
- if (isSyncHookJSONOutput(json2) && !json2.suppressOutput && plainText && result.status === 0) {
735317
+ if (isSyncHookJSONOutput(json2) && !json2.suppressOutput && plainText2 && result.status === 0) {
735031
735318
  const content = `${source_default.bold(hookName)} completed`;
735032
735319
  emitHookResponse({
735033
735320
  hookId,
@@ -735737,12 +736024,12 @@ async function* executeTeammateIdleHooks(teammateName, teamName, permissionMode,
735737
736024
  timeoutMs
735738
736025
  });
735739
736026
  }
735740
- async function* executeTaskCreatedHooks(taskId, taskSubject, taskDescription, teammateName, teamName, permissionMode, signal, timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS, toolUseContext) {
736027
+ async function* executeTaskCreatedHooks(taskId, taskSubject2, taskDescription, teammateName, teamName, permissionMode, signal, timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS, toolUseContext) {
735741
736028
  const hookInput = {
735742
736029
  ...createBaseHookInput(permissionMode),
735743
736030
  hook_event_name: "TaskCreated",
735744
736031
  task_id: taskId,
735745
- task_subject: taskSubject,
736032
+ task_subject: taskSubject2,
735746
736033
  task_description: taskDescription,
735747
736034
  teammate_name: teammateName,
735748
736035
  team_name: teamName
@@ -735755,12 +736042,12 @@ async function* executeTaskCreatedHooks(taskId, taskSubject, taskDescription, te
735755
736042
  toolUseContext
735756
736043
  });
735757
736044
  }
735758
- async function* executeTaskCompletedHooks(taskId, taskSubject, taskDescription, teammateName, teamName, permissionMode, signal, timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS, toolUseContext) {
736045
+ async function* executeTaskCompletedHooks(taskId, taskSubject2, taskDescription, teammateName, teamName, permissionMode, signal, timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS, toolUseContext) {
735759
736046
  const hookInput = {
735760
736047
  ...createBaseHookInput(permissionMode),
735761
736048
  hook_event_name: "TaskCompleted",
735762
736049
  task_id: taskId,
735763
- task_subject: taskSubject,
736050
+ task_subject: taskSubject2,
735764
736051
  task_description: taskDescription,
735765
736052
  teammate_name: teammateName,
735766
736053
  team_name: teamName
@@ -738558,7 +738845,7 @@ function computeFingerprint(messageText2, version3) {
738558
738845
  }
738559
738846
  function computeFingerprintFromMessages(messages) {
738560
738847
  const firstMessageText = extractFirstMessageText(messages);
738561
- return computeFingerprint(firstMessageText, "1.80.3");
738848
+ return computeFingerprint(firstMessageText, "1.80.5");
738562
738849
  }
738563
738850
  var FINGERPRINT_SALT = "59cf53e54c78";
738564
738851
  var init_fingerprint = () => {};
@@ -740483,7 +740770,7 @@ async function sideQuery(opts) {
740483
740770
  betas.push(STRUCTURED_OUTPUTS_BETA_HEADER);
740484
740771
  }
740485
740772
  const messageText2 = extractFirstUserMessageText(messages);
740486
- const fingerprint2 = computeFingerprint(messageText2, "1.80.3");
740773
+ const fingerprint2 = computeFingerprint(messageText2, "1.80.5");
740487
740774
  const attributionHeader = getAttributionHeader(fingerprint2);
740488
740775
  const systemBlocks = [
740489
740776
  attributionHeader ? { type: "text", text: attributionHeader } : null,
@@ -745317,7 +745604,7 @@ function buildSystemInitMessage(inputs) {
745317
745604
  slash_commands: inputs.commands.filter((c4) => c4.userInvocable !== false).map((c4) => c4.name),
745318
745605
  apiKeySource: getURHQApiKeyWithSource().source,
745319
745606
  betas: getSdkBetas(),
745320
- ur_version: "1.80.3",
745607
+ ur_version: "1.80.5",
745321
745608
  output_style: outputStyle,
745322
745609
  agents: inputs.agents.map((agent2) => agent2.agentType),
745323
745610
  skills: inputs.skills.filter((s) => s.userInvocable !== false).map((skill2) => skill2.name),
@@ -751946,8 +752233,8 @@ function commandListDisplay(commands) {
751946
752233
  }
751947
752234
  }
751948
752235
  function commandListDisplayTruncated(commands) {
751949
- const plainText = commands.join(", ");
751950
- if (plainText.length > 50) {
752236
+ const plainText2 = commands.join(", ");
752237
+ if (plainText2.length > 50) {
751951
752238
  return "similar";
751952
752239
  }
751953
752240
  return commandListDisplay(commands);
@@ -759153,7 +759440,7 @@ var init_useVoiceEnabled = __esm(() => {
759153
759440
  function getSemverPart(version3) {
759154
759441
  return `${import_semver13.major(version3, { loose: true })}.${import_semver13.minor(version3, { loose: true })}.${import_semver13.patch(version3, { loose: true })}`;
759155
759442
  }
759156
- function useUpdateNotification(updatedVersion, initialVersion = "1.80.3") {
759443
+ function useUpdateNotification(updatedVersion, initialVersion = "1.80.5") {
759157
759444
  const [lastNotifiedSemver, setLastNotifiedSemver] = import_react225.useState(() => getSemverPart(initialVersion));
759158
759445
  if (!updatedVersion) {
759159
759446
  return null;
@@ -759202,7 +759489,7 @@ function AutoUpdater({
759202
759489
  return;
759203
759490
  }
759204
759491
  if (false) {}
759205
- const currentVersion = "1.80.3";
759492
+ const currentVersion = "1.80.5";
759206
759493
  const channel = getInitialSettings()?.autoUpdatesChannel ?? "latest";
759207
759494
  let latestVersion = await getLatestVersion(channel);
759208
759495
  const isDisabled = isAutoUpdaterDisabled();
@@ -759431,12 +759718,12 @@ function NativeAutoUpdater({
759431
759718
  logEvent("tengu_native_auto_updater_start", {});
759432
759719
  try {
759433
759720
  const maxVersion = await getMaxVersion();
759434
- if (maxVersion && gt("1.80.3", maxVersion)) {
759721
+ if (maxVersion && gt("1.80.5", maxVersion)) {
759435
759722
  const msg = await getMaxVersionMessage();
759436
759723
  setMaxVersionIssue(msg ?? "affects your version");
759437
759724
  }
759438
759725
  const result = await installLatest(channel);
759439
- const currentVersion = "1.80.3";
759726
+ const currentVersion = "1.80.5";
759440
759727
  const latencyMs = Date.now() - startTime;
759441
759728
  if (result.lockFailed) {
759442
759729
  logEvent("tengu_native_auto_updater_lock_contention", {
@@ -759573,17 +759860,17 @@ function PackageManagerAutoUpdater(t0) {
759573
759860
  const maxVersion = await getMaxVersion();
759574
759861
  if (maxVersion && latest && gt(latest, maxVersion)) {
759575
759862
  logForDebugging(`PackageManagerAutoUpdater: maxVersion ${maxVersion} is set, capping update from ${latest} to ${maxVersion}`);
759576
- if (gte("1.80.3", maxVersion)) {
759577
- logForDebugging(`PackageManagerAutoUpdater: current version ${"1.80.3"} is already at or above maxVersion ${maxVersion}, skipping update`);
759863
+ if (gte("1.80.5", maxVersion)) {
759864
+ logForDebugging(`PackageManagerAutoUpdater: current version ${"1.80.5"} is already at or above maxVersion ${maxVersion}, skipping update`);
759578
759865
  setUpdateAvailable(false);
759579
759866
  return;
759580
759867
  }
759581
759868
  latest = maxVersion;
759582
759869
  }
759583
- const hasUpdate = latest && !gte("1.80.3", latest) && !shouldSkipVersion(latest);
759870
+ const hasUpdate = latest && !gte("1.80.5", latest) && !shouldSkipVersion(latest);
759584
759871
  setUpdateAvailable(!!hasUpdate);
759585
759872
  if (hasUpdate) {
759586
- logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.80.3"} -> ${latest}`);
759873
+ logForDebugging(`PackageManagerAutoUpdater: Update available ${"1.80.5"} -> ${latest}`);
759587
759874
  }
759588
759875
  };
759589
759876
  $2[0] = t1;
@@ -759617,7 +759904,7 @@ function PackageManagerAutoUpdater(t0) {
759617
759904
  wrap: "truncate",
759618
759905
  children: [
759619
759906
  "currentVersion: ",
759620
- "1.80.3"
759907
+ "1.80.5"
759621
759908
  ]
759622
759909
  }, undefined, true, undefined, this);
759623
759910
  $2[3] = verbose;
@@ -770470,7 +770757,7 @@ function buildStatusLineCommandInput(permissionMode, exceeds200kTokens, settings
770470
770757
  project_dir: getOriginalCwd(),
770471
770758
  added_dirs: addedDirs
770472
770759
  },
770473
- version: "1.80.3",
770760
+ version: "1.80.5",
770474
770761
  output_style: {
770475
770762
  name: outputStyleName
770476
770763
  },
@@ -770605,7 +770892,7 @@ function StatusLineInner({
770605
770892
  const attention = customStatusError ?? taskAttention;
770606
770893
  const terminalSize = React133.useContext(TerminalSizeContext);
770607
770894
  const defaultStatusLineText = buildDefaultStatusBar({
770608
- version: "1.80.3",
770895
+ version: "1.80.5",
770609
770896
  providerLabel: providerRuntime.providerLabel,
770610
770897
  authMode: providerRuntime.authLabel,
770611
770898
  model: renderModelName(mainLoopModel) || providerRuntime.model || "",
@@ -782860,7 +783147,7 @@ async function submitTranscriptShare(messages, trigger2, appearanceId) {
782860
783147
  } catch {}
782861
783148
  const data = {
782862
783149
  trigger: trigger2,
782863
- version: "1.80.3",
783150
+ version: "1.80.5",
782864
783151
  platform: process.platform,
782865
783152
  transcript,
782866
783153
  subagentTranscripts: Object.keys(subagentTranscripts).length > 0 ? subagentTranscripts : undefined,
@@ -795229,7 +795516,7 @@ function WelcomeV2() {
795229
795516
  dimColor: true,
795230
795517
  children: [
795231
795518
  "v",
795232
- "1.80.3"
795519
+ "1.80.5"
795233
795520
  ]
795234
795521
  }, undefined, true, undefined, this)
795235
795522
  ]
@@ -796489,7 +796776,7 @@ function completeOnboarding() {
796489
796776
  saveGlobalConfig((current) => ({
796490
796777
  ...current,
796491
796778
  hasCompletedOnboarding: true,
796492
- lastOnboardingVersion: "1.80.3"
796779
+ lastOnboardingVersion: "1.80.5"
796493
796780
  }));
796494
796781
  }
796495
796782
  function showDialog(root2, renderer) {
@@ -801635,7 +801922,7 @@ function appendToLog(path28, message) {
801635
801922
  cwd: getFsImplementation().cwd(),
801636
801923
  userType: process.env.USER_TYPE,
801637
801924
  sessionId: getSessionId(),
801638
- version: "1.80.3"
801925
+ version: "1.80.5"
801639
801926
  };
801640
801927
  getLogWriter(path28).write(messageWithTimestamp);
801641
801928
  }
@@ -805799,8 +806086,8 @@ async function getEnvLessBridgeConfig() {
805799
806086
  }
805800
806087
  async function checkEnvLessBridgeMinVersion() {
805801
806088
  const cfg = await getEnvLessBridgeConfig();
805802
- if (cfg.min_version && lt("1.80.3", cfg.min_version)) {
805803
- return `Your version of UR (${"1.80.3"}) is too old for Remote Control.
806089
+ if (cfg.min_version && lt("1.80.5", cfg.min_version)) {
806090
+ return `Your version of UR (${"1.80.5"}) is too old for Remote Control.
805804
806091
  Version ${cfg.min_version} or higher is required. Run \`ur update\` to update.`;
805805
806092
  }
805806
806093
  return null;
@@ -806274,7 +806561,7 @@ async function initBridgeCore(params) {
806274
806561
  const rawApi = createBridgeApiClient({
806275
806562
  baseUrl,
806276
806563
  getAccessToken,
806277
- runnerVersion: "1.80.3",
806564
+ runnerVersion: "1.80.5",
806278
806565
  onDebug: logForDebugging,
806279
806566
  onAuth401,
806280
806567
  getTrustedDeviceToken
@@ -815747,7 +816034,7 @@ function getAgUiCapabilities() {
815747
816034
  name: "UR-Nexus",
815748
816035
  type: "ur-nexus",
815749
816036
  description: "Provider-flexible, local-first autonomous engineering workflow agent.",
815750
- version: "1.80.3",
816037
+ version: "1.80.5",
815751
816038
  provider: "UR",
815752
816039
  documentationUrl: "https://github.com/Maitham16/UR/blob/master/docs/AG_UI.md"
815753
816040
  },
@@ -816184,6 +816471,102 @@ var init_agUi3 = __esm(() => {
816184
816471
  init_errors();
816185
816472
  });
816186
816473
 
816474
+ // src/cli/handlers/session.ts
816475
+ var exports_session2 = {};
816476
+ __export(exports_session2, {
816477
+ sessionStatusHandler: () => sessionStatusHandler,
816478
+ selectCliSessionStatus: () => selectCliSessionStatus
816479
+ });
816480
+ import { writeSync as writeSync6 } from "fs";
816481
+ import { join as join261, resolve as resolve79 } from "path";
816482
+ function activeStatus(log2) {
816483
+ const sessionId = getSessionIdFromLog(log2);
816484
+ if (!sessionId || !log2.projectPath || !log2.fullPath)
816485
+ return;
816486
+ return {
816487
+ sessionId,
816488
+ status: "resumable",
816489
+ title: log2.customTitle || log2.summary || log2.firstPrompt || null,
816490
+ projectPath: log2.projectPath,
816491
+ storagePath: null,
816492
+ transcriptPath: log2.fullPath,
816493
+ createdAt: log2.created.toISOString(),
816494
+ modifiedAt: log2.modified.toISOString(),
816495
+ archivedAt: null
816496
+ };
816497
+ }
816498
+ function archivedStatus(session2) {
816499
+ return {
816500
+ sessionId: session2.sessionId,
816501
+ status: "archived",
816502
+ title: null,
816503
+ projectPath: null,
816504
+ storagePath: join261(session2.projectDir, ".session-archive", session2.sessionId),
816505
+ transcriptPath: join261(session2.projectDir, ".session-archive", session2.sessionId, "transcript.jsonl"),
816506
+ createdAt: null,
816507
+ modifiedAt: null,
816508
+ archivedAt: session2.archivedAt
816509
+ };
816510
+ }
816511
+ function selectCliSessionStatus(active3, archived, sessionId, cwd4) {
816512
+ if (sessionId) {
816513
+ const activeMatch = active3.find((log2) => getSessionIdFromLog(log2) === sessionId);
816514
+ if (activeMatch)
816515
+ return activeStatus(activeMatch);
816516
+ const archivedMatch = archived.find((item) => item.sessionId === sessionId);
816517
+ return archivedMatch ? archivedStatus(archivedMatch) : undefined;
816518
+ }
816519
+ const projectRoot2 = resolve79(cwd4);
816520
+ const latest = active3.find((log2) => log2.projectPath && resolve79(log2.projectPath) === projectRoot2);
816521
+ return latest ? activeStatus(latest) : undefined;
816522
+ }
816523
+ function writeOutput(text2) {
816524
+ writeSync6(1, text2.endsWith(`
816525
+ `) ? text2 : `${text2}
816526
+ `);
816527
+ }
816528
+ function writeError(text2) {
816529
+ writeSync6(2, text2.endsWith(`
816530
+ `) ? text2 : `${text2}
816531
+ `);
816532
+ }
816533
+ function formatSessionStatus(status2) {
816534
+ const lines = [
816535
+ `Session: ${status2.sessionId}`,
816536
+ `Status: ${status2.status}`
816537
+ ];
816538
+ if (status2.projectPath)
816539
+ lines.push(`Project: ${status2.projectPath}`);
816540
+ if (status2.storagePath)
816541
+ lines.push(`Archive storage: ${status2.storagePath}`);
816542
+ lines.push(`Transcript: ${status2.transcriptPath}`);
816543
+ if (status2.title)
816544
+ lines.push(`Title: ${status2.title.replace(/\s+/gu, " ").slice(0, 120)}`);
816545
+ if (status2.modifiedAt)
816546
+ lines.push(`Last updated: ${status2.modifiedAt}`);
816547
+ if (status2.archivedAt)
816548
+ lines.push(`Archived: ${status2.archivedAt}`);
816549
+ return lines.join(`
816550
+ `);
816551
+ }
816552
+ async function sessionStatusHandler(sessionId, options5 = {}) {
816553
+ const [active3, archived] = await Promise.all([
816554
+ loadAllProjectsMessageLogs(),
816555
+ listArchivedSessions()
816556
+ ]);
816557
+ const status2 = selectCliSessionStatus(active3, archived, sessionId, process.cwd());
816558
+ if (!status2) {
816559
+ writeError(sessionId ? `Session ${sessionId} was not found.` : 'No resumable session was found for the current project. Run "ur session list" to inspect all sessions.');
816560
+ process.exit(1);
816561
+ }
816562
+ writeOutput(options5.json ? JSON.stringify(status2, null, 2) : formatSessionStatus(status2));
816563
+ process.exit(0);
816564
+ }
816565
+ var init_session3 = __esm(() => {
816566
+ init_sessionArchive();
816567
+ init_sessionStorage();
816568
+ });
816569
+
816187
816570
  // src/components/MCPServerDesktopImportDialog.tsx
816188
816571
  function MCPServerDesktopImportDialog(t0) {
816189
816572
  const $2 = import_compiler_runtime359.c(36);
@@ -816878,7 +817261,7 @@ function createMCPServer(cwd4, debug2, verbose) {
816878
817261
  };
816879
817262
  const server2 = new Server({
816880
817263
  name: "ur-nexus",
816881
- version: "1.80.3"
817264
+ version: "1.80.5"
816882
817265
  }, {
816883
817266
  capabilities: {
816884
817267
  tools: {}
@@ -817038,7 +817421,7 @@ import {
817038
817421
  unlinkSync as unlinkSync17,
817039
817422
  writeFileSync as writeFileSync75
817040
817423
  } from "fs";
817041
- import { join as join261 } from "path";
817424
+ import { join as join262 } from "path";
817042
817425
  function isRecord8(value2) {
817043
817426
  return Boolean(value2) && typeof value2 === "object" && !Array.isArray(value2);
817044
817427
  }
@@ -817071,7 +817454,7 @@ function isTask2(value2) {
817071
817454
  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);
817072
817455
  }
817073
817456
  function taskManifestPath(cwd4) {
817074
- return join261(cwd4, ".ur", "mcp-2026", "tasks.json");
817457
+ return join262(cwd4, ".ur", "mcp-2026", "tasks.json");
817075
817458
  }
817076
817459
  function quarantineTaskManifest(path28) {
817077
817460
  const destination = `${path28}.corrupt.${new Date().toISOString().replaceAll(/[:.]/g, "-")}.${randomUUID96()}`;
@@ -817085,8 +817468,8 @@ function assertNotSymlink(path28) {
817085
817468
  }
817086
817469
  }
817087
817470
  function prepareTaskDirectory(cwd4) {
817088
- const urDir = join261(cwd4, ".ur");
817089
- const mcpDir = join261(urDir, "mcp-2026");
817471
+ const urDir = join262(cwd4, ".ur");
817472
+ const mcpDir = join262(urDir, "mcp-2026");
817090
817473
  assertNotSymlink(urDir);
817091
817474
  mkdirSync73(urDir, { recursive: true, mode: 448 });
817092
817475
  assertNotSymlink(urDir);
@@ -817214,8 +817597,8 @@ class DurableMcp2026TaskStore {
817214
817597
  async#mutate(operation) {
817215
817598
  const previous = this.#mutationTail;
817216
817599
  let release4;
817217
- this.#mutationTail = new Promise((resolve79) => {
817218
- release4 = resolve79;
817600
+ this.#mutationTail = new Promise((resolve80) => {
817601
+ release4 = resolve80;
817219
817602
  });
817220
817603
  await previous;
817221
817604
  try {
@@ -818082,7 +818465,7 @@ function thrownResponse(error40) {
818082
818465
  }
818083
818466
  async function createUrMcp2026Runtime(options5) {
818084
818467
  const server2 = createMCPServer(options5.cwd, options5.debug === true, options5.verbose === true);
818085
- const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.80.3" }, { capabilities: {} });
818468
+ const client2 = new Client({ name: "ur-mcp-2026-adapter", version: "1.80.5" }, { capabilities: {} });
818086
818469
  const [clientTransport, serverTransport] = createLinkedTransportPair();
818087
818470
  try {
818088
818471
  await server2.connect(serverTransport);
@@ -818093,7 +818476,7 @@ async function createUrMcp2026Runtime(options5) {
818093
818476
  }
818094
818477
  const runtime2 = new Mcp2026Runtime({
818095
818478
  cwd: options5.cwd,
818096
- version: "1.80.3",
818479
+ version: "1.80.5",
818097
818480
  backend: {
818098
818481
  listTools: async () => {
818099
818482
  const listed = await client2.listTools();
@@ -818249,10 +818632,10 @@ async function serveMcp2026(options5) {
818249
818632
  fetch: handler
818250
818633
  });
818251
818634
  console.log(`MCP ${MCP_2026_PROTOCOL_VERSION} server listening on http://${options5.host}:${server2.port}/mcp`);
818252
- await new Promise((resolve79) => {
818253
- shutdown = resolve79;
818635
+ await new Promise((resolve80) => {
818636
+ shutdown = resolve80;
818254
818637
  for (const signal of signals2)
818255
- process.once(signal, resolve79);
818638
+ process.once(signal, resolve80);
818256
818639
  });
818257
818640
  } finally {
818258
818641
  if (shutdown) {
@@ -818280,14 +818663,14 @@ __export(exports_urDesktop, {
818280
818663
  });
818281
818664
  import { readdir as readdir34, readFile as readFile60, stat as stat54 } from "fs/promises";
818282
818665
  import { homedir as homedir45 } from "os";
818283
- import { join as join262 } from "path";
818666
+ import { join as join263 } from "path";
818284
818667
  async function getURDesktopConfigPath() {
818285
818668
  const platform7 = getPlatform();
818286
818669
  if (!SUPPORTED_PLATFORMS.includes(platform7)) {
818287
818670
  throw new Error(`Unsupported platform: ${platform7} - UR Desktop integration only works on macOS and WSL.`);
818288
818671
  }
818289
818672
  if (platform7 === "macos") {
818290
- return join262(homedir45(), "Library", "Application Support", "UR", "ur_desktop_config.json");
818673
+ return join263(homedir45(), "Library", "Application Support", "UR", "ur_desktop_config.json");
818291
818674
  }
818292
818675
  const windowsHome = process.env.USERPROFILE ? process.env.USERPROFILE.replace(/\\/g, "/") : null;
818293
818676
  if (windowsHome) {
@@ -818306,7 +818689,7 @@ async function getURDesktopConfigPath() {
818306
818689
  if (user.name === "Public" || user.name === "Default" || user.name === "Default User" || user.name === "All Users") {
818307
818690
  continue;
818308
818691
  }
818309
- const potentialConfigPath = join262(usersDir, user.name, "AppData", "Roaming", "UR", "ur_desktop_config.json");
818692
+ const potentialConfigPath = join263(usersDir, user.name, "AppData", "Roaming", "UR", "ur_desktop_config.json");
818310
818693
  try {
818311
818694
  await stat54(potentialConfigPath);
818312
818695
  return potentialConfigPath;
@@ -818732,29 +819115,30 @@ __export(exports_providers, {
818732
819115
  providerModelsHandler: () => providerModelsHandler,
818733
819116
  providerListHandler: () => providerListHandler,
818734
819117
  providerDoctorHandler: () => providerDoctorHandler,
819118
+ providerConfigSetHandler: () => providerConfigSetHandler,
818735
819119
  providerAuthHandler: () => providerAuthHandler,
818736
- configSetHandler: () => configSetHandler
819120
+ PROVIDER_CONFIG_KEYS: () => PROVIDER_CONFIG_KEYS
818737
819121
  });
818738
- import { writeSync as writeSync6 } from "fs";
818739
- function writeOutput(text2) {
818740
- writeSync6(1, text2.endsWith(`
819122
+ import { writeSync as writeSync7 } from "fs";
819123
+ function writeOutput2(text2) {
819124
+ writeSync7(1, text2.endsWith(`
818741
819125
  `) ? text2 : `${text2}
818742
819126
  `);
818743
819127
  }
818744
- function writeError(text2) {
818745
- writeSync6(2, text2.endsWith(`
819128
+ function writeError2(text2) {
819129
+ writeSync7(2, text2.endsWith(`
818746
819130
  `) ? text2 : `${text2}
818747
819131
  `);
818748
819132
  }
818749
819133
  async function providerListHandler(options5 = {}) {
818750
- writeOutput(formatProviderList(Boolean(options5.json)));
819134
+ writeOutput2(formatProviderList(Boolean(options5.json)));
818751
819135
  process.exit(0);
818752
819136
  }
818753
819137
  async function providerStatusHandler(options5 = {}) {
818754
819138
  const settings = getInitialSettings();
818755
819139
  const active3 = getActiveProviderSettings(settings).active ?? "ollama";
818756
819140
  const result = await doctorProvider(active3, { settings });
818757
- writeOutput(formatProviderStatus(result, Boolean(options5.json)));
819141
+ writeOutput2(formatProviderStatus(result, Boolean(options5.json)));
818758
819142
  process.exit(result.ok ? 0 : 1);
818759
819143
  }
818760
819144
  async function providerDoctorHandler(providerArg, options5 = {}) {
@@ -818762,7 +819146,7 @@ async function providerDoctorHandler(providerArg, options5 = {}) {
818762
819146
  if (providerArg) {
818763
819147
  const resolved = resolveProviderId(providerArg);
818764
819148
  if (!resolved) {
818765
- writeError(`Unknown provider "${providerArg}". Run: ur provider list`);
819149
+ writeError2(`Unknown provider "${providerArg}". Run: ur provider list`);
818766
819150
  process.exit(1);
818767
819151
  }
818768
819152
  provider = resolved;
@@ -818770,7 +819154,7 @@ async function providerDoctorHandler(providerArg, options5 = {}) {
818770
819154
  const settings = getInitialSettings();
818771
819155
  const active3 = getActiveProviderSettings(settings).active ?? "ollama";
818772
819156
  const result = await doctorProvider(provider ?? active3, { settings });
818773
- writeOutput(formatProviderDoctor(result, Boolean(options5.json)));
819157
+ writeOutput2(formatProviderDoctor(result, Boolean(options5.json)));
818774
819158
  process.exit(result.ok ? 0 : 1);
818775
819159
  }
818776
819160
  async function providerModelsHandler(providerArg, options5 = {}) {
@@ -818778,7 +819162,7 @@ async function providerModelsHandler(providerArg, options5 = {}) {
818778
819162
  const active3 = getActiveProviderSettings(settings).active ?? "ollama";
818779
819163
  const provider = providerArg ? resolveProviderId(providerArg) : active3;
818780
819164
  if (!provider) {
818781
- writeError(`Unknown provider "${providerArg}". Run: ur provider list`);
819165
+ writeError2(`Unknown provider "${providerArg}". Run: ur provider list`);
818782
819166
  process.exit(1);
818783
819167
  }
818784
819168
  const result = await listModelsForProviderWithSource(provider, { settings });
@@ -818791,10 +819175,10 @@ async function providerModelsHandler(providerArg, options5 = {}) {
818791
819175
  models: result.models
818792
819176
  };
818793
819177
  if (options5.json) {
818794
- writeOutput(JSON.stringify(payload, null, 2));
819178
+ writeOutput2(JSON.stringify(payload, null, 2));
818795
819179
  } else {
818796
819180
  const warning = result.warning ? [`Warning: ${result.warning}`] : [];
818797
- writeOutput([
819181
+ writeOutput2([
818798
819182
  `Provider: ${definition.displayName} (${provider})`,
818799
819183
  `Model source: ${result.source}`,
818800
819184
  ...warning,
@@ -818810,9 +819194,9 @@ async function providerSelectModelHandler(providerArg, values2, options5 = {}) {
818810
819194
  if (!provider) {
818811
819195
  const message = `Unknown provider "${providerArg}". Run: ur provider list`;
818812
819196
  if (options5.json)
818813
- writeOutput(JSON.stringify({ ok: false, message }, null, 2));
819197
+ writeOutput2(JSON.stringify({ ok: false, message }, null, 2));
818814
819198
  else
818815
- writeError(message);
819199
+ writeError2(message);
818816
819200
  process.exit(1);
818817
819201
  }
818818
819202
  const settings = getInitialSettings();
@@ -818822,16 +819206,16 @@ async function providerSelectModelHandler(providerArg, values2, options5 = {}) {
818822
819206
  modelSource: discovered.source
818823
819207
  });
818824
819208
  if (options5.json) {
818825
- writeOutput(JSON.stringify({
819209
+ writeOutput2(JSON.stringify({
818826
819210
  ...result,
818827
819211
  warning: discovered.warning
818828
819212
  }, null, 2));
818829
819213
  } else if (result.ok) {
818830
- writeOutput(result.message);
819214
+ writeOutput2(result.message);
818831
819215
  if (discovered.warning)
818832
- writeError(`Warning: ${discovered.warning}`);
819216
+ writeError2(`Warning: ${discovered.warning}`);
818833
819217
  } else {
818834
- writeError(result.message);
819218
+ writeError2(result.message);
818835
819219
  }
818836
819220
  process.exit(result.ok ? 0 : 1);
818837
819221
  }
@@ -818841,18 +819225,18 @@ async function providerAuthHandler(alias2, options5 = {}) {
818841
819225
  dryRun: options5.dryRun
818842
819226
  });
818843
819227
  if (options5.json) {
818844
- writeOutput(JSON.stringify(result, null, 2));
819228
+ writeOutput2(JSON.stringify(result, null, 2));
818845
819229
  } else if (result.ok) {
818846
- writeOutput(result.message);
819230
+ writeOutput2(result.message);
818847
819231
  } else {
818848
- writeError(result.message);
819232
+ writeError2(result.message);
818849
819233
  }
818850
819234
  process.exit(result.ok ? 0 : 1);
818851
819235
  }
818852
- async function configSetHandler(key, values2) {
819236
+ async function providerConfigSetHandler(key, values2) {
818853
819237
  const value2 = Array.isArray(values2) ? values2.join(" ") : values2;
818854
- 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") {
818855
- 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`);
819238
+ if (!PROVIDER_CONFIG_KEYS.includes(key)) {
819239
+ writeError2(`Unsupported provider config key "${key}". Supported: ${PROVIDER_CONFIG_KEYS.join(", ")}`);
818856
819240
  process.exit(1);
818857
819241
  }
818858
819242
  if (key === "model") {
@@ -818864,7 +819248,7 @@ async function configSetHandler(key, values2) {
818864
819248
  settings
818865
819249
  });
818866
819250
  if (validation.valid === false) {
818867
- writeError(`Invalid model for current provider:
819251
+ writeError2(`Invalid model for current provider:
818868
819252
  Selected provider: ${currentProvider}
818869
819253
  Selected model: ${value2}
818870
819254
  Valid models for ${currentProvider}: ${validation.validModels.join(", ") || "(no models discovered)"}
@@ -818887,7 +819271,7 @@ async function configSetHandler(key, values2) {
818887
819271
  if (validation.valid === false) {
818888
819272
  const validModelsStr = validation.validModels.join(", ") || "(uses dynamic discovery)";
818889
819273
  const suggestedModel = validation.suggestedModel ?? "<model-name>";
818890
- writeError(`Warning: Current model "${currentModel}" is not available for provider "${newProvider}" and will be cleared.
819274
+ writeError2(`Warning: Current model "${currentModel}" is not available for provider "${newProvider}" and will be cleared.
818891
819275
  Valid models for ${newProvider}: ${validModelsStr}
818892
819276
  After changing provider, run /model or: ur config set model ${suggestedModel}`);
818893
819277
  }
@@ -818896,15 +819280,147 @@ async function configSetHandler(key, values2) {
818896
819280
  }
818897
819281
  const result = setSafeProviderConfig(key, value2);
818898
819282
  if (result.ok) {
818899
- writeOutput(result.message);
819283
+ writeOutput2(result.message);
818900
819284
  process.exit(0);
818901
819285
  }
818902
- writeError(result.message);
819286
+ writeError2(result.message);
818903
819287
  process.exit(1);
818904
819288
  }
819289
+ var PROVIDER_CONFIG_KEYS;
818905
819290
  var init_providers2 = __esm(() => {
818906
819291
  init_providerRegistry();
818907
819292
  init_settings2();
819293
+ PROVIDER_CONFIG_KEYS = [
819294
+ "provider",
819295
+ "provider.fallback",
819296
+ "provider.command_path",
819297
+ "openai_transport",
819298
+ "responses.store",
819299
+ "responses.compact_threshold",
819300
+ "responses.tool_search",
819301
+ "model",
819302
+ "base_url"
819303
+ ];
819304
+ });
819305
+
819306
+ // src/cli/handlers/config.ts
819307
+ var exports_config3 = {};
819308
+ __export(exports_config3, {
819309
+ listCliConfigEntries: () => listCliConfigEntries,
819310
+ configSetHandler: () => configSetHandler,
819311
+ configListHandler: () => configListHandler,
819312
+ configGetHandler: () => configGetHandler
819313
+ });
819314
+ import { writeSync as writeSync8 } from "fs";
819315
+ function writeOutput3(text2) {
819316
+ writeSync8(1, text2.endsWith(`
819317
+ `) ? text2 : `${text2}
819318
+ `);
819319
+ }
819320
+ function writeError3(text2) {
819321
+ writeSync8(2, text2.endsWith(`
819322
+ `) ? text2 : `${text2}
819323
+ `);
819324
+ }
819325
+ function providerConfigEntries() {
819326
+ const settings = getInitialSettings();
819327
+ const active3 = getActiveProviderSettings(settings);
819328
+ const configured = settings.provider ?? {};
819329
+ return [
819330
+ { key: "provider", value: active3.active ?? "ollama", category: "provider" },
819331
+ {
819332
+ key: "provider.fallback",
819333
+ value: active3.fallback ?? null,
819334
+ category: "provider"
819335
+ },
819336
+ {
819337
+ key: "provider.command_path",
819338
+ value: active3.commandPath ?? null,
819339
+ category: "provider"
819340
+ },
819341
+ {
819342
+ key: "openai_transport",
819343
+ value: configured.openaiTransport ?? null,
819344
+ category: "provider"
819345
+ },
819346
+ {
819347
+ key: "responses.store",
819348
+ value: configured.responses?.store ?? null,
819349
+ category: "provider"
819350
+ },
819351
+ {
819352
+ key: "responses.compact_threshold",
819353
+ value: configured.responses?.compactThreshold ?? null,
819354
+ category: "provider"
819355
+ },
819356
+ {
819357
+ key: "responses.tool_search",
819358
+ value: configured.responses?.toolSearch ?? null,
819359
+ category: "provider"
819360
+ },
819361
+ { key: "model", value: active3.model ?? null, category: "provider" },
819362
+ { key: "base_url", value: active3.baseUrl ?? null, category: "provider" }
819363
+ ];
819364
+ }
819365
+ function listCliConfigEntries() {
819366
+ return [
819367
+ ...getConfigAssignmentValues().map((entry) => ({
819368
+ ...entry,
819369
+ category: "agent"
819370
+ })),
819371
+ ...providerConfigEntries()
819372
+ ];
819373
+ }
819374
+ function textValue(value2) {
819375
+ return value2 === null ? "(not set)" : String(value2);
819376
+ }
819377
+ function findEntry(key) {
819378
+ const assignmentKey = resolveConfigAssignmentKey(key);
819379
+ const canonical = assignmentKey ?? key.toLowerCase();
819380
+ return listCliConfigEntries().find((entry) => entry.key === canonical);
819381
+ }
819382
+ async function configSetHandler(key, values2) {
819383
+ const value2 = Array.isArray(values2) ? values2.join(" ") : values2;
819384
+ if (resolveConfigAssignmentKey(key)) {
819385
+ const parsed = parseConfigAssignments(`${key}=${value2}`);
819386
+ if (parsed.error) {
819387
+ writeError3(parsed.error);
819388
+ process.exit(1);
819389
+ }
819390
+ const result = applyConfigAssignments(parsed.assignments);
819391
+ if (result.error) {
819392
+ writeError3(result.error);
819393
+ process.exit(1);
819394
+ }
819395
+ writeOutput3(`Updated ${result.applied.join(", ")}.`);
819396
+ process.exit(0);
819397
+ }
819398
+ if (!PROVIDER_CONFIG_KEYS.includes(key)) {
819399
+ writeError3(`Unsupported config key "${key}". Run "ur config list" to see supported settings.`);
819400
+ process.exit(1);
819401
+ }
819402
+ await providerConfigSetHandler(key, value2);
819403
+ }
819404
+ function configGetHandler(key, options5 = {}) {
819405
+ const entry = findEntry(key);
819406
+ if (!entry) {
819407
+ writeError3(`Unknown config key "${key}". Run "ur config list" to see supported settings.`);
819408
+ process.exit(1);
819409
+ }
819410
+ writeOutput3(options5.json ? JSON.stringify(entry, null, 2) : `${entry.key}=${textValue(entry.value)}`);
819411
+ process.exit(0);
819412
+ }
819413
+ function configListHandler(options5 = {}) {
819414
+ const entries = listCliConfigEntries();
819415
+ writeOutput3(options5.json ? JSON.stringify(entries, null, 2) : entries.map((entry) => `${entry.key}=${textValue(entry.value)}`).join(`
819416
+ `));
819417
+ process.exit(0);
819418
+ }
819419
+ var init_config11 = __esm(() => {
819420
+ init_configAssignments();
819421
+ init_providerRegistry();
819422
+ init_settings2();
819423
+ init_providers2();
818908
819424
  });
818909
819425
 
818910
819426
  // src/utils/plugins/pluginDiscovery.ts
@@ -819267,9 +819783,9 @@ var init_pluginDiscovery = __esm(() => {
819267
819783
 
819268
819784
  // src/utils/plugins/pluginDoctor.ts
819269
819785
  import { existsSync as existsSync105, readdirSync as readdirSync42, readFileSync as readFileSync95, statSync as statSync39 } from "fs";
819270
- import { basename as basename68, join as join263 } from "path";
819786
+ import { basename as basename68, join as join264 } from "path";
819271
819787
  function manifestPathFor3(dir) {
819272
- const p2 = join263(dir, ".ur-plugin", "plugin.json");
819788
+ const p2 = join264(dir, ".ur-plugin", "plugin.json");
819273
819789
  return existsSync105(p2) ? p2 : null;
819274
819790
  }
819275
819791
  function discoverPluginDirs(roots) {
@@ -819295,7 +819811,7 @@ function discoverPluginDirs(roots) {
819295
819811
  continue;
819296
819812
  }
819297
819813
  for (const entry of entries) {
819298
- const full = join263(root2, entry);
819814
+ const full = join264(root2, entry);
819299
819815
  try {
819300
819816
  if (statSync39(full).isDirectory() && manifestPathFor3(full))
819301
819817
  add(full);
@@ -819428,7 +819944,7 @@ __export(exports_plugins, {
819428
819944
  VALID_UPDATE_SCOPES: () => VALID_UPDATE_SCOPES,
819429
819945
  VALID_INSTALLABLE_SCOPES: () => VALID_INSTALLABLE_SCOPES
819430
819946
  });
819431
- import { basename as basename69, dirname as dirname103, join as join264, resolve as resolve79 } from "path";
819947
+ import { basename as basename69, dirname as dirname103, join as join265, resolve as resolve80 } from "path";
819432
819948
  function handleMarketplaceError(error40, action3) {
819433
819949
  logError2(error40);
819434
819950
  cliError(`${figures_default.cross} Failed to ${action3}: ${errorMessage2(error40)}`);
@@ -819509,8 +820025,8 @@ function printValidationResult(result) {
819509
820025
  async function pluginDoctorHandler(options5) {
819510
820026
  const roots = [];
819511
820027
  if (options5.path)
819512
- roots.push(resolve79(options5.path));
819513
- roots.push(join264(process.cwd(), ".ur", "plugins"));
820028
+ roots.push(resolve80(options5.path));
820029
+ roots.push(join265(process.cwd(), ".ur", "plugins"));
819514
820030
  try {
819515
820031
  const data = loadInstalledPluginsV2();
819516
820032
  for (const installations of Object.values(data.plugins ?? {})) {
@@ -820059,12 +820575,12 @@ __export(exports_install, {
820059
820575
  install: () => install
820060
820576
  });
820061
820577
  import { homedir as homedir46 } from "os";
820062
- import { join as join265 } from "path";
820578
+ import { join as join266 } from "path";
820063
820579
  function getInstallationPath2() {
820064
820580
  const isWindows2 = env2.platform === "win32";
820065
820581
  const homeDir = homedir46();
820066
820582
  if (isWindows2) {
820067
- const windowsPath = join265(homeDir, ".local", "bin", "ur.exe");
820583
+ const windowsPath = join266(homeDir, ".local", "bin", "ur.exe");
820068
820584
  return windowsPath.replace(/\//g, "\\");
820069
820585
  }
820070
820586
  return "~/.local/bin/ur";
@@ -820425,7 +820941,7 @@ async function setupTokenHandler(root2) {
820425
820941
  const {
820426
820942
  ConsoleOAuthFlow: ConsoleOAuthFlow2
820427
820943
  } = await Promise.resolve().then(() => (init_ConsoleOAuthFlow(), exports_ConsoleOAuthFlow));
820428
- await new Promise((resolve80) => {
820944
+ await new Promise((resolve81) => {
820429
820945
  root2.render(/* @__PURE__ */ jsx_dev_runtime483.jsxDEV(AppStateProvider, {
820430
820946
  onChangeAppState,
820431
820947
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(KeybindingSetup, {
@@ -820449,7 +820965,7 @@ async function setupTokenHandler(root2) {
820449
820965
  }, undefined, true, undefined, this),
820450
820966
  /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(ConsoleOAuthFlow2, {
820451
820967
  onDone: () => {
820452
- resolve80();
820968
+ resolve81();
820453
820969
  },
820454
820970
  mode: "setup-token",
820455
820971
  startingMessage: "This will guide you through long-lived (1-year) auth token setup for your UR account. UR subscription required."
@@ -820485,7 +821001,7 @@ function DoctorWithPlugins(t0) {
820485
821001
  }
820486
821002
  async function doctorHandler(root2) {
820487
821003
  logEvent("tengu_doctor_command", {});
820488
- await new Promise((resolve80) => {
821004
+ await new Promise((resolve81) => {
820489
821005
  root2.render(/* @__PURE__ */ jsx_dev_runtime483.jsxDEV(AppStateProvider, {
820490
821006
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(KeybindingSetup, {
820491
821007
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(MCPConnectionManager, {
@@ -820493,7 +821009,7 @@ async function doctorHandler(root2) {
820493
821009
  isStrictMcpConfig: false,
820494
821010
  children: /* @__PURE__ */ jsx_dev_runtime483.jsxDEV(DoctorWithPlugins, {
820495
821011
  onDone: () => {
820496
- resolve80();
821012
+ resolve81();
820497
821013
  }
820498
821014
  }, undefined, false, undefined, this)
820499
821015
  }, undefined, false, undefined, this)
@@ -820511,14 +821027,14 @@ async function installHandler(target, options5) {
820511
821027
  const {
820512
821028
  install: install2
820513
821029
  } = await Promise.resolve().then(() => (init_install(), exports_install));
820514
- await new Promise((resolve80) => {
821030
+ await new Promise((resolve81) => {
820515
821031
  const args = [];
820516
821032
  if (target)
820517
821033
  args.push(target);
820518
821034
  if (options5.force)
820519
821035
  args.push("--force");
820520
821036
  install2.call((result) => {
820521
- resolve80();
821037
+ resolve81();
820522
821038
  process.exit(result.includes("failed") ? 1 : 0);
820523
821039
  }, {}, args);
820524
821040
  });
@@ -820695,7 +821211,7 @@ async function update() {
820695
821211
  logEvent("tengu_update_check", {});
820696
821212
  const diagnostic2 = await getDoctorDiagnostic();
820697
821213
  const result = await checkUpgradeStatus({
820698
- currentVersion: "1.80.3",
821214
+ currentVersion: "1.80.5",
820699
821215
  packageName: UR_AGENT_PACKAGE_NAME,
820700
821216
  installationType: diagnostic2.installationType,
820701
821217
  latestVersion: () => getLatestNpmPackageVersion(UR_AGENT_PACKAGE_NAME)
@@ -820723,7 +821239,7 @@ __export(exports_main, {
820723
821239
  main: () => main
820724
821240
  });
820725
821241
  import { readFileSync as readFileSync96 } from "fs";
820726
- import { resolve as resolve80 } from "path";
821242
+ import { resolve as resolve81 } from "path";
820727
821243
  function logManagedSettings() {
820728
821244
  try {
820729
821245
  const policySettings = getSettingsForSource("policySettings");
@@ -821302,12 +821818,12 @@ ${getTmuxInstallInstructions2()}
821302
821818
  process.exit(1);
821303
821819
  }
821304
821820
  try {
821305
- const filePath = resolve80(options5.systemPromptFile);
821821
+ const filePath = resolve81(options5.systemPromptFile);
821306
821822
  systemPrompt = readFileSync96(filePath, "utf8");
821307
821823
  } catch (error40) {
821308
821824
  const code = getErrnoCode(error40);
821309
821825
  if (code === "ENOENT") {
821310
- process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve80(options5.systemPromptFile)}
821826
+ process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve81(options5.systemPromptFile)}
821311
821827
  `));
821312
821828
  process.exit(1);
821313
821829
  }
@@ -821324,12 +821840,12 @@ ${getTmuxInstallInstructions2()}
821324
821840
  process.exit(1);
821325
821841
  }
821326
821842
  try {
821327
- const filePath = resolve80(options5.appendSystemPromptFile);
821843
+ const filePath = resolve81(options5.appendSystemPromptFile);
821328
821844
  appendSystemPrompt = readFileSync96(filePath, "utf8");
821329
821845
  } catch (error40) {
821330
821846
  const code = getErrnoCode(error40);
821331
821847
  if (code === "ENOENT") {
821332
- process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve80(options5.appendSystemPromptFile)}
821848
+ process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve81(options5.appendSystemPromptFile)}
821333
821849
  `));
821334
821850
  process.exit(1);
821335
821851
  }
@@ -821375,7 +821891,7 @@ ${addendum}` : addendum;
821375
821891
  errors4 = result.errors;
821376
821892
  }
821377
821893
  } else {
821378
- const configPath2 = resolve80(configItem);
821894
+ const configPath2 = resolve81(configItem);
821379
821895
  const result = parseMcpConfigFromFilePath({
821380
821896
  filePath: configPath2,
821381
821897
  expandVars: true,
@@ -822023,7 +822539,7 @@ ${customInstructions}` : customInstructions;
822023
822539
  }
822024
822540
  }
822025
822541
  logForDiagnosticsNoPII("info", "started", {
822026
- version: "1.80.3",
822542
+ version: "1.80.5",
822027
822543
  is_native_binary: isInBundledMode()
822028
822544
  });
822029
822545
  registerCleanup(async () => {
@@ -822228,8 +822744,8 @@ ${customInstructions}` : customInstructions;
822228
822744
  return connectMcpBatch(dedupedURAi, "urai");
822229
822745
  });
822230
822746
  let uraiTimer;
822231
- const uraiTimedOut = await Promise.race([uraiConnect.then(() => false), new Promise((resolve81) => {
822232
- uraiTimer = setTimeout((r) => r(true), UR_AI_MCP_TIMEOUT_MS, resolve81);
822747
+ const uraiTimedOut = await Promise.race([uraiConnect.then(() => false), new Promise((resolve82) => {
822748
+ uraiTimer = setTimeout((r) => r(true), UR_AI_MCP_TIMEOUT_MS, resolve82);
822233
822749
  })]);
822234
822750
  if (uraiTimer)
822235
822751
  clearTimeout(uraiTimer);
@@ -822810,7 +823326,7 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
822810
823326
  pendingHookMessages
822811
823327
  }, renderAndRun);
822812
823328
  }
822813
- }).version("1.80.3 (UR-Nexus)", "-v, --version", "Output the version number");
823329
+ }).version("1.80.5 (UR-Nexus)", "-v, --version", "Output the version number");
822814
823330
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
822815
823331
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
822816
823332
  if (canUserConfigureAdvisor()) {
@@ -822862,7 +823378,13 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
822862
823378
  permissionMode
822863
823379
  });
822864
823380
  });
822865
- const sessionCli = program2.command("session").description("List, archive, and restore local conversation sessions").configureHelp(createSortedHelpConfig());
823381
+ const sessionCli = program2.command("session").description("Inspect, list, archive, and restore local conversation sessions").configureHelp(createSortedHelpConfig());
823382
+ 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) => {
823383
+ const {
823384
+ sessionStatusHandler: sessionStatusHandler2
823385
+ } = await Promise.resolve().then(() => (init_session3(), exports_session2));
823386
+ await sessionStatusHandler2(sessionId, options5);
823387
+ });
822866
823388
  sessionCli.command("list").description("List resumable and archived conversations").option("--json", "Output structured JSON").action(async ({
822867
823389
  json: json2
822868
823390
  }) => {
@@ -823061,12 +823583,24 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
823061
823583
  await providerSelectModelHandler2(providerArg, model, options5);
823062
823584
  });
823063
823585
  const configCmd = program2.command("config").description("Manage safe UR-Nexus settings").configureHelp(createSortedHelpConfig());
823064
- 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) => {
823586
+ configCmd.command("set <key> <value...>").description("Set a validated agent, accessibility, editor, or provider setting").action(async (key, value2) => {
823065
823587
  const {
823066
823588
  configSetHandler: configSetHandler2
823067
- } = await Promise.resolve().then(() => (init_providers2(), exports_providers));
823589
+ } = await Promise.resolve().then(() => (init_config11(), exports_config3));
823068
823590
  await configSetHandler2(key, value2);
823069
823591
  });
823592
+ configCmd.command("get <key>").description("Show one effective safe setting").option("--json", "Output structured JSON").action(async (key, options5) => {
823593
+ const {
823594
+ configGetHandler: configGetHandler2
823595
+ } = await Promise.resolve().then(() => (init_config11(), exports_config3));
823596
+ configGetHandler2(key, options5);
823597
+ });
823598
+ configCmd.command("list").description("List effective safe settings and their current values").option("--json", "Output structured JSON").action(async (options5) => {
823599
+ const {
823600
+ configListHandler: configListHandler2
823601
+ } = await Promise.resolve().then(() => (init_config11(), exports_config3));
823602
+ configListHandler2(options5);
823603
+ });
823070
823604
  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) => {
823071
823605
  const args = [action3 ? quoteLocalCommandArg(action3) : undefined, providerArg ? quoteLocalCommandArg(providerArg) : undefined, opts.key ? `--key ${quoteLocalCommandArg(opts.key)}` : undefined, opts.json ? "--json" : undefined].filter(Boolean).join(" ");
823072
823606
  await runLocalTextCommand(() => Promise.resolve().then(() => (init_connect(), exports_connect)), args);
@@ -823474,11 +824008,12 @@ Usage: ur --remote "your task description"`, () => gracefulShutdown(1));
823474
824008
  await runLocalTextCommand(() => Promise.resolve().then(() => (init_role_mode(), exports_role_mode)), args);
823475
824009
  });
823476
824010
  const a2a = program2.command("a2a").description("Agent-to-Agent interoperability, discovery, and delegation utilities").configureHelp(createSortedHelpConfig());
823477
- 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) => {
824011
+ 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) => {
823478
824012
  const {
823479
- formatA2AAgentCard: formatA2AAgentCard2
824013
+ formatA2AAgentCard: formatA2AAgentCard2,
824014
+ formatA2AV1AgentCard: formatA2AV1AgentCard2
823480
824015
  } = await Promise.resolve().then(() => (init_trends(), exports_trends));
823481
- console.log(formatA2AAgentCard2({
824016
+ console.log((opts.v1 ? formatA2AV1AgentCard2 : formatA2AAgentCard2)({
823482
824017
  baseUrl: opts.baseUrl
823483
824018
  }, !opts.compact));
823484
824019
  process.exit(0);
@@ -823918,7 +824453,7 @@ if (false) {}
823918
824453
  async function main2() {
823919
824454
  const args = process.argv.slice(2);
823920
824455
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
823921
- console.log(`${"1.80.3"} (UR-Nexus)`);
824456
+ console.log(`${"1.80.5"} (UR-Nexus)`);
823922
824457
  return;
823923
824458
  }
823924
824459
  if (args[0] === "a2a" && args[1] === "serve" && !args.includes("--help") && !args.includes("-h")) {