deepcode-ai 1.2.13 → 1.2.17

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/index.js CHANGED
@@ -1652,7 +1652,7 @@ var require_cli_spinners = __commonJS({
1652
1652
 
1653
1653
  // ../../packages/cli/dist/index.js
1654
1654
  import { render as render3 } from "ink";
1655
- import React40 from "react";
1655
+ import React42 from "react";
1656
1656
  import { Command as Command2 } from "commander";
1657
1657
 
1658
1658
  // ../../packages/core/dist/index.js
@@ -6579,43 +6579,43 @@ var PermissionGateway = class _PermissionGateway {
6579
6579
  }
6580
6580
  this.pendingApprovals.clear();
6581
6581
  }
6582
- async ensure(check) {
6583
- const decision = await this.check(check);
6582
+ async ensure(check2) {
6583
+ const decision = await this.check(check2);
6584
6584
  if (!decision.allowed) {
6585
- throw new PermissionDeniedError(decision.reason ?? `Operation denied: ${check.operation}`);
6585
+ throw new PermissionDeniedError(decision.reason ?? `Operation denied: ${check2.operation}`);
6586
6586
  }
6587
6587
  }
6588
- async check(check) {
6589
- const pathAccess = check.path ? this.pathSecurity.classify(check.path) : "allowed";
6588
+ async check(check2) {
6589
+ const pathAccess = check2.path ? this.pathSecurity.classify(check2.path) : "allowed";
6590
6590
  if (pathAccess === "blacklisted") {
6591
- await this.audit.log({ operation: check.operation, path: check.path, result: "denied", reason: "path_blacklist" });
6591
+ await this.audit.log({ operation: check2.operation, path: check2.path, result: "denied", reason: "path_blacklist" });
6592
6592
  return { allowed: false, reason: "Path blocked by blacklist (paths.blacklist)." };
6593
6593
  }
6594
- const mode = this.resolveMode(check);
6594
+ const mode = this.resolveMode(check2);
6595
6595
  if (mode === "deny") {
6596
- await this.audit.log({ operation: check.operation, path: check.path, result: "denied", reason: "config" });
6596
+ await this.audit.log({ operation: check2.operation, path: check2.path, result: "denied", reason: "config" });
6597
6597
  this.eventBus.emit("activity", {
6598
6598
  id: createId("activity"),
6599
6599
  type: "permission_denied",
6600
- message: `Permission denied by configuration: ${check.operation} (${check.kind})`,
6601
- metadata: { operation: check.operation, kind: check.kind, reason: "config_deny" },
6600
+ message: `Permission denied by configuration: ${check2.operation} (${check2.kind})`,
6601
+ metadata: { operation: check2.operation, kind: check2.kind, reason: "config_deny" },
6602
6602
  createdAt: nowIso()
6603
6603
  });
6604
- return { allowed: false, reason: configDeniedReason(check) };
6604
+ return { allowed: false, reason: configDeniedReason(check2) };
6605
6605
  }
6606
- const sessionKey = check.path ? `${check.operation}:${check.path}` : `${check.operation}`;
6606
+ const sessionKey = check2.path ? `${check2.operation}:${check2.path}` : `${check2.operation}`;
6607
6607
  if (this.alwaysAllowSet.has(sessionKey)) {
6608
- await this.audit.log({ operation: check.operation, path: check.path, result: "allowed", reason: "always_allow" });
6608
+ await this.audit.log({ operation: check2.operation, path: check2.path, result: "allowed", reason: "always_allow" });
6609
6609
  return { allowed: true };
6610
6610
  }
6611
6611
  if (this.sessionAllowSet.has(sessionKey)) {
6612
- await this.audit.log({ operation: check.operation, path: check.path, result: "allowed", reason: "session_allow" });
6612
+ await this.audit.log({ operation: check2.operation, path: check2.path, result: "allowed", reason: "session_allow" });
6613
6613
  return { allowed: true };
6614
6614
  }
6615
6615
  if (mode === "allow" && pathAccess === "allowed") {
6616
6616
  await this.audit.log({
6617
- operation: check.operation,
6618
- path: check.path,
6617
+ operation: check2.operation,
6618
+ path: check2.path,
6619
6619
  result: "allowed"
6620
6620
  });
6621
6621
  return { allowed: true };
@@ -6623,56 +6623,56 @@ var PermissionGateway = class _PermissionGateway {
6623
6623
  if (mode === "allow" && pathAccess === "outside_whitelist") {
6624
6624
  if (!this.interactive) {
6625
6625
  await this.audit.log({
6626
- operation: check.operation,
6627
- path: check.path,
6626
+ operation: check2.operation,
6627
+ path: check2.path,
6628
6628
  result: "denied",
6629
6629
  reason: "path_outside_whitelist"
6630
6630
  });
6631
6631
  this.eventBus.emit("activity", {
6632
6632
  id: createId("activity"),
6633
6633
  type: "permission_denied",
6634
- message: `Permission denied (path outside whitelist, non-interactive): ${check.operation} (${check.kind})`,
6635
- metadata: { operation: check.operation, kind: check.kind, reason: "path_outside_whitelist" },
6634
+ message: `Permission denied (path outside whitelist, non-interactive): ${check2.operation} (${check2.kind})`,
6635
+ metadata: { operation: check2.operation, kind: check2.kind, reason: "path_outside_whitelist" },
6636
6636
  createdAt: nowIso()
6637
6637
  });
6638
6638
  return {
6639
6639
  allowed: false,
6640
- reason: outsideWhitelistReason(check)
6640
+ reason: outsideWhitelistReason(check2)
6641
6641
  };
6642
6642
  }
6643
6643
  }
6644
6644
  if (!this.interactive) {
6645
6645
  await this.audit.log({
6646
- operation: check.operation,
6647
- path: check.path,
6646
+ operation: check2.operation,
6647
+ path: check2.path,
6648
6648
  result: "denied",
6649
6649
  reason: pathAccess === "outside_whitelist" ? "path_outside_whitelist" : "non_interactive"
6650
6650
  });
6651
6651
  this.eventBus.emit("activity", {
6652
6652
  id: createId("activity"),
6653
6653
  type: "permission_denied",
6654
- message: `Permission denied (non-interactive): ${check.operation} (${check.kind})`,
6655
- metadata: { operation: check.operation, kind: check.kind, reason: pathAccess === "outside_whitelist" ? "path_outside_whitelist" : "non_interactive" },
6654
+ message: `Permission denied (non-interactive): ${check2.operation} (${check2.kind})`,
6655
+ metadata: { operation: check2.operation, kind: check2.kind, reason: pathAccess === "outside_whitelist" ? "path_outside_whitelist" : "non_interactive" },
6656
6656
  createdAt: nowIso()
6657
6657
  });
6658
6658
  return {
6659
6659
  allowed: false,
6660
- reason: pathAccess === "outside_whitelist" ? outsideWhitelistReason(check) : nonInteractiveApprovalReason(check)
6660
+ reason: pathAccess === "outside_whitelist" ? outsideWhitelistReason(check2) : nonInteractiveApprovalReason(check2)
6661
6661
  };
6662
6662
  }
6663
6663
  const request = {
6664
6664
  id: createId("approval"),
6665
- operation: check.operation,
6666
- level: check.kind,
6667
- path: check.path,
6665
+ operation: check2.operation,
6666
+ level: check2.kind,
6667
+ path: check2.path,
6668
6668
  details: {
6669
- ...check.details,
6669
+ ...check2.details,
6670
6670
  ...pathAccess === "outside_whitelist" ? {
6671
6671
  pathPolicy: "outside_whitelist",
6672
6672
  pathMessage: "Path is outside the configured whitelist for this workspace"
6673
6673
  } : {}
6674
6674
  },
6675
- preview: buildApprovalPreview(check),
6675
+ preview: buildApprovalPreview(check2),
6676
6676
  createdAt: nowIso()
6677
6677
  };
6678
6678
  const APPROVAL_TIMEOUT_MS = 5 * 60 * 1e3;
@@ -6688,11 +6688,11 @@ var PermissionGateway = class _PermissionGateway {
6688
6688
  this.pendingApprovals.delete(request.id);
6689
6689
  reject(new Error("Approval check aborted"));
6690
6690
  };
6691
- check.signal?.addEventListener("abort", onAbort, { once: true });
6691
+ check2.signal?.addEventListener("abort", onAbort, { once: true });
6692
6692
  const cleanup = this.eventBus.on("approval:decision", (payload) => {
6693
6693
  if (payload.requestId === request.id) {
6694
6694
  clearTimeout(timeoutId);
6695
- check.signal?.removeEventListener("abort", onAbort);
6695
+ check2.signal?.removeEventListener("abort", onAbort);
6696
6696
  cleanup();
6697
6697
  this.pendingApprovals.delete(request.id);
6698
6698
  resolve3(payload.decision);
@@ -6712,66 +6712,66 @@ var PermissionGateway = class _PermissionGateway {
6712
6712
  this.alwaysAllowSet.add(sessionKey);
6713
6713
  }
6714
6714
  await this.audit.log({
6715
- operation: check.operation,
6716
- path: check.path,
6715
+ operation: check2.operation,
6716
+ path: check2.path,
6717
6717
  result: decision.allowed ? "approved" : "denied",
6718
6718
  reason: decision.reason,
6719
6719
  details: { requestId: request.id }
6720
6720
  });
6721
6721
  return decision;
6722
6722
  }
6723
- resolveMode(check) {
6724
- const agentMode = check.agentMode ?? this.config.agentMode;
6723
+ resolveMode(check2) {
6724
+ const agentMode = check2.agentMode ?? this.config.agentMode;
6725
6725
  const agentPermissions = this.config.agentPermissions?.[agentMode];
6726
6726
  if (agentPermissions) {
6727
- if (agentPermissions.askBeforeExecute && (check.kind === "shell" || check.kind === "dangerous")) {
6727
+ if (agentPermissions.askBeforeExecute && (check2.kind === "shell" || check2.kind === "dangerous")) {
6728
6728
  return "ask";
6729
6729
  }
6730
- if (check.kind === "shell" && agentPermissions.shell) {
6730
+ if (check2.kind === "shell" && agentPermissions.shell) {
6731
6731
  return agentPermissions.shell;
6732
6732
  }
6733
- if (check.kind === "dangerous" && agentPermissions.dangerous) {
6733
+ if (check2.kind === "dangerous" && agentPermissions.dangerous) {
6734
6734
  return agentPermissions.dangerous;
6735
6735
  }
6736
- if (check.kind === "write" && agentPermissions.write) {
6736
+ if (check2.kind === "write" && agentPermissions.write) {
6737
6737
  return agentPermissions.write;
6738
6738
  }
6739
- if (check.kind === "read" && agentPermissions.read) {
6739
+ if (check2.kind === "read" && agentPermissions.read) {
6740
6740
  return agentPermissions.read;
6741
6741
  }
6742
- if (check.kind === "git_local" && agentPermissions.gitLocal) {
6742
+ if (check2.kind === "git_local" && agentPermissions.gitLocal) {
6743
6743
  return agentPermissions.gitLocal;
6744
6744
  }
6745
6745
  }
6746
- if (check.kind === "shell" && isShellWhitelisted(this.config.permissions.allowShell, check.operation)) {
6746
+ if (check2.kind === "shell" && isShellWhitelisted(this.config.permissions.allowShell, check2.operation)) {
6747
6747
  return "allow";
6748
6748
  }
6749
- if (check.kind === "read") return this.config.permissions.read;
6750
- if (check.kind === "write") return this.config.permissions.write;
6751
- if (check.kind === "git_local") return this.config.permissions.gitLocal;
6752
- if (check.kind === "shell") return this.config.permissions.shell;
6749
+ if (check2.kind === "read") return this.config.permissions.read;
6750
+ if (check2.kind === "write") return this.config.permissions.write;
6751
+ if (check2.kind === "git_local") return this.config.permissions.gitLocal;
6752
+ if (check2.kind === "shell") return this.config.permissions.shell;
6753
6753
  return this.config.permissions.dangerous;
6754
6754
  }
6755
6755
  };
6756
- function buildApprovalPreview(check) {
6757
- if (check.kind === "shell" || check.kind === "dangerous") {
6756
+ function buildApprovalPreview(check2) {
6757
+ if (check2.kind === "shell" || check2.kind === "dangerous") {
6758
6758
  return {
6759
6759
  type: "shell_command",
6760
- command: check.operation,
6761
- args: typeof check.details?.command === "string" ? splitCommandPreview(check.details.command) : []
6760
+ command: check2.operation,
6761
+ args: typeof check2.details?.command === "string" ? splitCommandPreview(check2.details.command) : []
6762
6762
  };
6763
6763
  }
6764
- if (check.kind === "git_local") {
6764
+ if (check2.kind === "git_local") {
6765
6765
  return {
6766
6766
  type: "git_operation",
6767
- command: check.operation,
6768
- affectedFiles: typeof check.path === "string" ? [check.path] : []
6767
+ command: check2.operation,
6768
+ affectedFiles: typeof check2.path === "string" ? [check2.path] : []
6769
6769
  };
6770
6770
  }
6771
- if (check.kind === "write") {
6771
+ if (check2.kind === "write") {
6772
6772
  return {
6773
- type: check.operation === "edit_file" ? "file_edit" : "file_write",
6774
- affectedFiles: typeof check.path === "string" ? [check.path] : []
6773
+ type: check2.operation === "edit_file" ? "file_edit" : "file_write",
6774
+ affectedFiles: typeof check2.path === "string" ? [check2.path] : []
6775
6775
  };
6776
6776
  }
6777
6777
  return void 0;
@@ -6788,8 +6788,8 @@ function isShellWhitelisted(allowList, operation) {
6788
6788
  (allowedOperation) => normalizeShellPermissionOperation(allowedOperation) === normalizedOperation
6789
6789
  );
6790
6790
  }
6791
- function configDeniedReason(check) {
6792
- switch (check.kind) {
6791
+ function configDeniedReason(check2) {
6792
+ switch (check2.kind) {
6793
6793
  case "read":
6794
6794
  return 'Denied by configuration (permissions.read=deny). Set `permissions.read` to `"allow"` in `.deepcode/config.json`, for example: `{"permissions":{"read":"allow"}}`.';
6795
6795
  case "write":
@@ -6797,13 +6797,13 @@ function configDeniedReason(check) {
6797
6797
  case "git_local":
6798
6798
  return 'Denied by configuration (permissions.gitLocal=deny). Set `permissions.gitLocal` to `"allow"` in `.deepcode/config.json`, for example: `{"permissions":{"gitLocal":"allow"}}`.';
6799
6799
  case "shell":
6800
- return `Denied by configuration (permissions.shell=deny). Set \`permissions.shell\` to \`"allow"\` in \`.deepcode/config.json\`, or add the exact command to \`permissions.allowShell\`, for example: \`{"permissions":{"allowShell":["${normalizeShellPermissionOperation(check.operation)}"]}}\`.`;
6800
+ return `Denied by configuration (permissions.shell=deny). Set \`permissions.shell\` to \`"allow"\` in \`.deepcode/config.json\`, or add the exact command to \`permissions.allowShell\`, for example: \`{"permissions":{"allowShell":["${normalizeShellPermissionOperation(check2.operation)}"]}}\`.`;
6801
6801
  case "dangerous":
6802
6802
  return 'Denied by configuration (permissions.dangerous=deny). Re-run with `--yes` or set `permissions.dangerous` to `"ask"` in `.deepcode/config.json`, for example: `{"permissions":{"dangerous":"ask"}}`.';
6803
6803
  }
6804
6804
  }
6805
- function nonInteractiveApprovalReason(check) {
6806
- switch (check.kind) {
6805
+ function nonInteractiveApprovalReason(check2) {
6806
+ switch (check2.kind) {
6807
6807
  case "read":
6808
6808
  return 'Read operation requires approval in non-interactive mode. Use the interactive TUI/chat flow or set `permissions.read` to `"allow"` in `.deepcode/config.json`, for example: `{"permissions":{"read":"allow"}}`.';
6809
6809
  case "write":
@@ -6811,18 +6811,18 @@ function nonInteractiveApprovalReason(check) {
6811
6811
  case "git_local":
6812
6812
  return 'Git operation requires approval in non-interactive mode. Re-run with `--yes`, use the interactive TUI/chat flow, or set `permissions.gitLocal` to `"allow"` in `.deepcode/config.json`, for example: `{"permissions":{"gitLocal":"allow"}}`.';
6813
6813
  case "shell":
6814
- return `Shell command requires approval in non-interactive mode. Re-run with \`--yes\`, use the interactive TUI/chat flow, or add the exact command to \`permissions.allowShell\` in \`.deepcode/config.json\`, for example: \`{"permissions":{"allowShell":["${normalizeShellPermissionOperation(check.operation)}"]}}\`.`;
6814
+ return `Shell command requires approval in non-interactive mode. Re-run with \`--yes\`, use the interactive TUI/chat flow, or add the exact command to \`permissions.allowShell\` in \`.deepcode/config.json\`, for example: \`{"permissions":{"allowShell":["${normalizeShellPermissionOperation(check2.operation)}"]}}\`.`;
6815
6815
  case "dangerous":
6816
6816
  return "Dangerous operation requires approval in non-interactive mode. Re-run with `--yes` or use the interactive TUI/chat flow.";
6817
6817
  }
6818
6818
  }
6819
- function outsideWhitelistReason(check) {
6820
- const example = whitelistExampleForPath(check.path);
6819
+ function outsideWhitelistReason(check2) {
6820
+ const example = whitelistExampleForPath(check2.path);
6821
6821
  const base = `Path is outside the configured whitelist (\`paths.whitelist\`) and requires approval. Add a matching entry to \`.deepcode/config.json\`, for example: \`{"paths":{"whitelist":["${example}"]}}\`.`;
6822
- if (check.kind === "read") {
6822
+ if (check2.kind === "read") {
6823
6823
  return `${base} Use the interactive TUI/chat flow or extend the whitelist.`;
6824
6824
  }
6825
- if (check.kind === "shell" || check.kind === "dangerous" || check.kind === "write" || check.kind === "git_local") {
6825
+ if (check2.kind === "shell" || check2.kind === "dangerous" || check2.kind === "write" || check2.kind === "git_local") {
6826
6826
  return `${base} Re-run with \`--yes\`, use the interactive TUI/chat flow, or extend the whitelist.`;
6827
6827
  }
6828
6828
  return `${base} Use the interactive TUI/chat flow or extend the whitelist.`;
@@ -7861,10 +7861,10 @@ import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
7861
7861
  import fs2 from "fs";
7862
7862
  import os4 from "os";
7863
7863
  import path62 from "path";
7864
- import fs9 from "fs";
7865
- import path16 from "path";
7866
- import { isValidElement, useCallback as useCallback27, useEffect as useEffect28, useMemo as useMemo19, useRef as useRef18, useState as useState30 } from "react";
7867
- import { Box as Box47, Text as Text55, useInput as useInput6, useStdin as useStdin3 } from "ink";
7864
+ import fs12 from "fs";
7865
+ import path19 from "path";
7866
+ import { isValidElement, useCallback as useCallback28, useEffect as useEffect32, useMemo as useMemo19, useRef as useRef21, useState as useState34 } from "react";
7867
+ import { Box as Box52, Text as Text60, useInput as useInput6, useStdin as useStdin3 } from "ink";
7868
7868
  import os22 from "os";
7869
7869
  import path92 from "path";
7870
7870
  import fs22 from "fs";
@@ -8836,9 +8836,9 @@ import { access as access2, lstat as lstat4, open, readFile as readFile4, stat a
8836
8836
  import * as path82 from "path";
8837
8837
  import { promisify } from "util";
8838
8838
  import { useState as useState3, useRef, useCallback as useCallback3, useMemo as useMemo2 } from "react";
8839
- import { useCallback as useCallback8, useEffect as useEffect14, useMemo as useMemo6, useRef as useRef6, useState as useState12 } from "react";
8840
- import { Box as Box26, Static } from "ink";
8841
- import { Box as Box25, Text as Text28 } from "ink";
8839
+ import { useCallback as useCallback8, useEffect as useEffect15, useMemo as useMemo6, useRef as useRef6, useState as useState13 } from "react";
8840
+ import { Box as Box30, Static } from "ink";
8841
+ import { Box as Box29, Text as Text32 } from "ink";
8842
8842
  import { Box as Box8, Text as Text9 } from "ink";
8843
8843
 
8844
8844
  // ../../node_modules/.pnpm/ansi-regex@6.2.2/node_modules/ansi-regex/index.js
@@ -9787,25 +9787,35 @@ import { Box as Box23, Text as Text26 } from "ink";
9787
9787
  import { jsx as jsx28, jsxs as jsxs22 } from "react/jsx-runtime";
9788
9788
  import { Box as Box24, Text as Text27 } from "ink";
9789
9789
  import { Fragment as Fragment7, jsx as jsx29, jsxs as jsxs23 } from "react/jsx-runtime";
9790
- import { jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
9791
- import { createContext as createContext5, useContext as useContext6 } from "react";
9790
+ import { Box as Box25, Text as Text28 } from "ink";
9791
+ import { Fragment as Fragment8, jsx as jsx30, jsxs as jsxs24 } from "react/jsx-runtime";
9792
+ import React23 from "react";
9793
+ import { Box as Box26, Text as Text29 } from "ink";
9794
+ import { useEffect as useEffect14, useState as useState12 } from "react";
9792
9795
  import { jsx as jsx31, jsxs as jsxs25 } from "react/jsx-runtime";
9793
- import { Box as Box27, Text as Text29 } from "ink";
9794
- import { jsx as jsx32 } from "react/jsx-runtime";
9795
- import { Box as Box35, Text as Text43, useIsScreenReaderEnabled as useIsScreenReaderEnabled3 } from "ink";
9796
+ import { Box as Box27, Text as Text30 } from "ink";
9797
+ import { jsx as jsx32, jsxs as jsxs26 } from "react/jsx-runtime";
9798
+ import React24 from "react";
9799
+ import { Box as Box28, Text as Text31 } from "ink";
9800
+ import { jsx as jsx33, jsxs as jsxs27 } from "react/jsx-runtime";
9801
+ import { jsx as jsx34, jsxs as jsxs28 } from "react/jsx-runtime";
9802
+ import { createContext as createContext5, useContext as useContext6 } from "react";
9803
+ import { jsx as jsx35, jsxs as jsxs29 } from "react/jsx-runtime";
9804
+ import { Box as Box31, Text as Text33 } from "ink";
9805
+ import { jsx as jsx36 } from "react/jsx-runtime";
9806
+ import { Box as Box39, Text as Text47, useIsScreenReaderEnabled as useIsScreenReaderEnabled3 } from "ink";
9796
9807
  import { useCallback as useCallback19, useState as useState24 } from "react";
9797
9808
  import { useRef as useRef8 } from "react";
9798
- import { Box as Box28, Text as Text30 } from "ink";
9799
- import { useEffect as useEffect15, useState as useState13 } from "react";
9809
+ import { Box as Box32, Text as Text34 } from "ink";
9800
9810
  import { useEffect as useEffect16, useRef as useRef7, useState as useState14 } from "react";
9801
- import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
9811
+ import { jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
9802
9812
  import { useCallback as useCallback17, useEffect as useEffect23, useMemo as useMemo11, useState as useState21, useRef as useRef13 } from "react";
9803
- import { Box as Box31, Text as Text34 } from "ink";
9804
- import { Box as Box29, Text as Text32 } from "ink";
9805
- import React25 from "react";
9806
- import { Text as Text31 } from "ink";
9807
- import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
9808
- import { jsx as jsx35, jsxs as jsxs28 } from "react/jsx-runtime";
9813
+ import { Box as Box35, Text as Text38 } from "ink";
9814
+ import { Box as Box33, Text as Text36 } from "ink";
9815
+ import React27 from "react";
9816
+ import { Text as Text35 } from "ink";
9817
+ import { jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
9818
+ import { jsx as jsx39, jsxs as jsxs32 } from "react/jsx-runtime";
9809
9819
  import { useState as useState15, useCallback as useCallback9 } from "react";
9810
9820
  import chalk3 from "chalk";
9811
9821
  import { useState as useState16, useEffect as useEffect17, useCallback as useCallback10 } from "react";
@@ -9822,21 +9832,21 @@ import * as path132 from "path";
9822
9832
  import { createContext as createContext6, useContext as useContext7 } from "react";
9823
9833
  import { createContext as createContext7, useContext as useContext8 } from "react";
9824
9834
  import { useCallback as useCallback16 } from "react";
9825
- import { Box as Box30, Text as Text33 } from "ink";
9835
+ import { Box as Box34, Text as Text37 } from "ink";
9826
9836
  import chalk2 from "chalk";
9827
- import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
9828
- import { Fragment as Fragment8, jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
9829
- import { Box as Box32, Text as Text40 } from "ink";
9830
- import { Text as Text35 } from "ink";
9831
- import { Fragment as Fragment9, jsx as jsx38, jsxs as jsxs31 } from "react/jsx-runtime";
9832
- import { Text as Text36 } from "ink";
9833
- import { jsx as jsx39, jsxs as jsxs32 } from "react/jsx-runtime";
9834
- import { Text as Text37 } from "ink";
9835
9837
  import { jsx as jsx40, jsxs as jsxs33 } from "react/jsx-runtime";
9836
- import { Text as Text38 } from "ink";
9837
- import { jsxs as jsxs34 } from "react/jsx-runtime";
9838
+ import { Fragment as Fragment9, jsx as jsx41, jsxs as jsxs34 } from "react/jsx-runtime";
9839
+ import { Box as Box36, Text as Text44 } from "ink";
9838
9840
  import { Text as Text39 } from "ink";
9839
- import { jsxs as jsxs35 } from "react/jsx-runtime";
9841
+ import { Fragment as Fragment10, jsx as jsx42, jsxs as jsxs35 } from "react/jsx-runtime";
9842
+ import { Text as Text40 } from "ink";
9843
+ import { jsx as jsx43, jsxs as jsxs36 } from "react/jsx-runtime";
9844
+ import { Text as Text41 } from "ink";
9845
+ import { jsx as jsx44, jsxs as jsxs37 } from "react/jsx-runtime";
9846
+ import { Text as Text42 } from "ink";
9847
+ import { jsxs as jsxs38 } from "react/jsx-runtime";
9848
+ import { Text as Text43 } from "ink";
9849
+ import { jsxs as jsxs39 } from "react/jsx-runtime";
9840
9850
  import { useState as useState222, useEffect as useEffect24 } from "react";
9841
9851
  import { execFile as execFile22 } from "child_process";
9842
9852
  import os5 from "os";
@@ -9846,53 +9856,70 @@ import {
9846
9856
  useContext as useContext9,
9847
9857
  useState as useState23
9848
9858
  } from "react";
9849
- import { jsx as jsx41 } from "react/jsx-runtime";
9850
- import { jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
9851
- import { useRef as useRef14 } from "react";
9852
- import { Box as Box33, Text as Text41 } from "ink";
9853
- import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
9854
- import { Box as Box34, Text as Text42 } from "ink";
9855
- import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
9856
- import { jsx as jsx45, jsxs as jsxs39 } from "react/jsx-runtime";
9857
- import { createContext as createContext9, useContext as useContext10 } from "react";
9858
- import { Box as Box36, Text as Text44 } from "ink";
9859
- import { useContext as useContext11 } from "react";
9859
+ import { jsx as jsx45 } from "react/jsx-runtime";
9860
9860
  import { jsx as jsx46, jsxs as jsxs40 } from "react/jsx-runtime";
9861
+ import { useRef as useRef14 } from "react";
9861
9862
  import { Box as Box37, Text as Text45 } from "ink";
9862
- import os6 from "os";
9863
- import { Fragment as Fragment10, jsx as jsx47, jsxs as jsxs41 } from "react/jsx-runtime";
9864
- import os7 from "os";
9865
- import path142 from "path";
9866
- import fs7 from "fs/promises";
9863
+ import { jsx as jsx47, jsxs as jsxs41 } from "react/jsx-runtime";
9867
9864
  import { Box as Box38, Text as Text46 } from "ink";
9868
9865
  import { jsx as jsx48, jsxs as jsxs42 } from "react/jsx-runtime";
9869
- import { useCallback as useCallback20, useMemo as useMemo12, useRef as useRef15 } from "react";
9870
- import { Box as Box39, Text as Text47 } from "ink";
9871
9866
  import { jsx as jsx49, jsxs as jsxs43 } from "react/jsx-runtime";
9872
- import { useCallback as useCallback21, useMemo as useMemo13, useState as useState25 } from "react";
9873
- import { Box as Box40, Text as Text48, useInput as useInput3 } from "ink";
9874
- import { Fragment as Fragment11, jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
9875
- import { useCallback as useCallback22, useMemo as useMemo14, useState as useState26 } from "react";
9867
+ import { createContext as createContext9, useContext as useContext10 } from "react";
9868
+ import { Box as Box40, Text as Text48 } from "ink";
9869
+ import { useContext as useContext11 } from "react";
9870
+ import { jsx as jsx50, jsxs as jsxs44 } from "react/jsx-runtime";
9876
9871
  import { Box as Box41, Text as Text49 } from "ink";
9877
- import { jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
9878
- import { useCallback as useCallback23, useEffect as useEffect25, useMemo as useMemo15, useRef as useRef16, useState as useState27 } from "react";
9872
+ import os6 from "os";
9873
+ import { useState as useState25, useEffect as useEffect25, useCallback as useCallback20 } from "react";
9874
+ import { execFile as execFile32 } from "child_process";
9875
+ import fs7 from "fs";
9876
+ import fsPromises from "fs/promises";
9877
+ import path142 from "path";
9878
+ import { Fragment as Fragment11, jsx as jsx51, jsxs as jsxs45 } from "react/jsx-runtime";
9879
+ import { memo, useMemo as useMemo12 } from "react";
9879
9880
  import { Box as Box42, Text as Text50 } from "ink";
9880
9881
  import { jsx as jsx52, jsxs as jsxs46 } from "react/jsx-runtime";
9881
- import { useCallback as useCallback24, useEffect as useEffect26, useMemo as useMemo16, useRef as useRef17, useState as useState28 } from "react";
9882
- import { Box as Box43, Text as Text51, useInput as useInput4 } from "ink";
9883
- import { jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
9884
- import fs8 from "fs";
9882
+ import { useState as useState28, useEffect as useEffect28, useRef as useRef17 } from "react";
9883
+ import { useState as useState26, useEffect as useEffect26, useRef as useRef15 } from "react";
9884
+ import { useState as useState27, useEffect as useEffect27, useRef as useRef16 } from "react";
9885
+ import os7 from "os";
9885
9886
  import path15 from "path";
9886
- import { useCallback as useCallback25, useMemo as useMemo17 } from "react";
9887
+ import fs8 from "fs/promises";
9888
+ import fs9 from "fs";
9889
+ import path16 from "path";
9890
+ import process4 from "process";
9891
+ import fs10 from "fs";
9892
+ import os8 from "os";
9893
+ import path17 from "path";
9894
+ import { Box as Box43, Text as Text51 } from "ink";
9895
+ import { jsx as jsx53, jsxs as jsxs47 } from "react/jsx-runtime";
9896
+ import { useCallback as useCallback21, useMemo as useMemo13, useRef as useRef18 } from "react";
9887
9897
  import { Box as Box44, Text as Text52 } from "ink";
9888
9898
  import { jsx as jsx54, jsxs as jsxs48 } from "react/jsx-runtime";
9889
- import { useCallback as useCallback26, useEffect as useEffect27, useMemo as useMemo18, useState as useState29 } from "react";
9890
- import { Box as Box45, Text as Text53, useInput as useInput5 } from "ink";
9891
- import { jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
9899
+ import { useCallback as useCallback22, useMemo as useMemo14, useState as useState29 } from "react";
9900
+ import { Box as Box45, Text as Text53, useInput as useInput3 } from "ink";
9901
+ import { Fragment as Fragment12, jsx as jsx55, jsxs as jsxs49 } from "react/jsx-runtime";
9902
+ import { useCallback as useCallback23, useState as useState30 } from "react";
9892
9903
  import { Box as Box46, Text as Text54 } from "ink";
9893
9904
  import { jsx as jsx56, jsxs as jsxs50 } from "react/jsx-runtime";
9905
+ import { useCallback as useCallback24, useEffect as useEffect29, useMemo as useMemo15, useRef as useRef19, useState as useState31 } from "react";
9906
+ import { Box as Box47, Text as Text55 } from "ink";
9894
9907
  import { jsx as jsx57, jsxs as jsxs51 } from "react/jsx-runtime";
9895
- import { jsx as jsx58 } from "react/jsx-runtime";
9908
+ import { useCallback as useCallback25, useEffect as useEffect30, useMemo as useMemo16, useRef as useRef20, useState as useState32 } from "react";
9909
+ import { Box as Box48, Text as Text56, useInput as useInput4 } from "ink";
9910
+ import { jsx as jsx58, jsxs as jsxs52 } from "react/jsx-runtime";
9911
+ import fs11 from "fs";
9912
+ import path18 from "path";
9913
+ import { useCallback as useCallback26, useMemo as useMemo17 } from "react";
9914
+ import { Box as Box49, Text as Text57 } from "ink";
9915
+ import { jsx as jsx59, jsxs as jsxs53 } from "react/jsx-runtime";
9916
+ import { useCallback as useCallback27, useEffect as useEffect31, useMemo as useMemo18, useState as useState33 } from "react";
9917
+ import { Box as Box50, Text as Text58, useInput as useInput5 } from "ink";
9918
+ import { jsx as jsx60, jsxs as jsxs54 } from "react/jsx-runtime";
9919
+ import { Box as Box51, Text as Text59 } from "ink";
9920
+ import { jsx as jsx61, jsxs as jsxs55 } from "react/jsx-runtime";
9921
+ import { jsx as jsx62, jsxs as jsxs56 } from "react/jsx-runtime";
9922
+ import { jsx as jsx63 } from "react/jsx-runtime";
9896
9923
  async function createRuntime(options) {
9897
9924
  const worktree = path10.resolve(options.cwd);
9898
9925
  const config = await new ConfigLoader().load({ cwd: worktree, configPath: options.configPath });
@@ -10175,10 +10202,10 @@ async function doctorCommand(options) {
10175
10202
  for (const server of runtime.config.lsp.servers) {
10176
10203
  checks.push(await lspCommandCheck(server.command));
10177
10204
  }
10178
- for (const check of checks) {
10179
- await writeStdoutLine(`${check.ok ? "ok" : "fail"} ${check.name}: ${check.detail}`);
10205
+ for (const check2 of checks) {
10206
+ await writeStdoutLine(`${check2.ok ? "ok" : "fail"} ${check2.name}: ${check2.detail}`);
10180
10207
  }
10181
- const failed = checks.filter((check) => !check.ok);
10208
+ const failed = checks.filter((check2) => !check2.ok);
10182
10209
  if (failed.length > 0) {
10183
10210
  process.exitCode = 1;
10184
10211
  }
@@ -10295,10 +10322,10 @@ async function lspCommandCheck(command) {
10295
10322
  ];
10296
10323
  let lastFailure;
10297
10324
  for (const args of attempts) {
10298
- const check = await commandCheck(`lsp:${command}`, args, command);
10299
- if (check.ok) return check;
10300
- if (check.detail.includes("ENOENT")) return check;
10301
- lastFailure = check;
10325
+ const check2 = await commandCheck(`lsp:${command}`, args, command);
10326
+ if (check2.ok) return check2;
10327
+ if (check2.detail.includes("ENOENT")) return check2;
10328
+ lastFailure = check2;
10302
10329
  }
10303
10330
  return lastFailure ?? {
10304
10331
  name: `lsp:${command}`,
@@ -11485,7 +11512,7 @@ function parseVersion(version) {
11485
11512
  if (!match) return null;
11486
11513
  return [Number(match[1]), Number(match[2]), Number(match[3])];
11487
11514
  }
11488
- var VERSION = "1.2.13".length > 0 ? "1.2.13" : "0.0.0-dev";
11515
+ var VERSION = "1.2.17".length > 0 ? "1.2.17" : "0.0.0-dev";
11489
11516
  async function updateCommand() {
11490
11517
  writeStdoutLine(`Current version: ${VERSION}`);
11491
11518
  const update = await checkForUpdate(VERSION, { force: true });
@@ -12066,6 +12093,9 @@ function useHistory() {
12066
12093
  [history, addItem, updateItem, clearItems, loadHistory, truncateToItem]
12067
12094
  );
12068
12095
  }
12096
+ function isTerminalGoalStatusKind(kind) {
12097
+ return kind === "achieved" || kind === "cleared" || kind === "failed" || kind === "aborted";
12098
+ }
12069
12099
  var CSS_NAME_TO_HEX_MAP = {
12070
12100
  aliceblue: "#f0f8ff",
12071
12101
  antiquewhite: "#faebd7",
@@ -20692,13 +20722,13 @@ var getLineRangeOffsets = (startRow, lineCount, lines) => {
20692
20722
  var replaceRangeInternal = (state, startRow, startCol, endRow, endCol, text) => {
20693
20723
  const currentLine = (row) => state.lines[row] || "";
20694
20724
  const currentLineLen = (row) => cpLen(currentLine(row));
20695
- const clamp2 = (value, min, max) => Math.min(Math.max(value, min), max);
20725
+ const clamp3 = (value, min, max) => Math.min(Math.max(value, min), max);
20696
20726
  if (startRow > endRow || startRow === endRow && startCol > endCol || startRow < 0 || startCol < 0 || endRow >= state.lines.length || endRow < state.lines.length && endCol > currentLineLen(endRow)) {
20697
20727
  return state;
20698
20728
  }
20699
20729
  const newLines = [...state.lines];
20700
- const sCol = clamp2(startCol, 0, currentLineLen(startRow));
20701
- const eCol = clamp2(endCol, 0, currentLineLen(endRow));
20730
+ const sCol = clamp3(startCol, 0, currentLineLen(startRow));
20731
+ const eCol = clamp3(endCol, 0, currentLineLen(endRow));
20702
20732
  const prefix = cpSlice(currentLine(startRow), 0, sCol);
20703
20733
  const suffix = cpSlice(currentLine(endRow), eCol);
20704
20734
  const normalisedReplacement = text.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
@@ -24295,6 +24325,259 @@ var ContextUsage = ({
24295
24325
  }
24296
24326
  );
24297
24327
  };
24328
+ var STATUS_ICONS2 = {
24329
+ pass: "\u2713",
24330
+ warn: "\u26A0",
24331
+ fail: "\u2717"
24332
+ };
24333
+ var STATUS_COLORS = {
24334
+ pass: theme.status.success,
24335
+ warn: theme.status.warning,
24336
+ fail: theme.status.error
24337
+ };
24338
+ function groupByCategory(checks) {
24339
+ const groups = /* @__PURE__ */ new Map();
24340
+ for (const check2 of checks) {
24341
+ const arr = groups.get(check2.category) ?? [];
24342
+ arr.push(check2);
24343
+ groups.set(check2.category, arr);
24344
+ }
24345
+ return groups;
24346
+ }
24347
+ var DoctorReport = ({ checks, summary }) => {
24348
+ const groups = groupByCategory(checks);
24349
+ const hasIssues = summary.fail > 0 || summary.warn > 0;
24350
+ return /* @__PURE__ */ jsxs24(Box25, { flexDirection: "column", marginLeft: 2, children: [
24351
+ /* @__PURE__ */ jsx30(Text28, { color: theme.text.secondary, bold: true, children: "DeepCode Doctor" }),
24352
+ Array.from(groups.entries()).map(([category, items]) => /* @__PURE__ */ jsxs24(Box25, { flexDirection: "column", marginTop: 1, children: [
24353
+ /* @__PURE__ */ jsx30(Text28, { color: theme.text.secondary, dimColor: true, children: category }),
24354
+ items.map((check2) => /* @__PURE__ */ jsxs24(Box25, { flexDirection: "column", children: [
24355
+ /* @__PURE__ */ jsxs24(Box25, { flexDirection: "row", children: [
24356
+ /* @__PURE__ */ jsx30(Box25, { width: 2, children: /* @__PURE__ */ jsx30(Text28, { color: STATUS_COLORS[check2.status], children: STATUS_ICONS2[check2.status] }) }),
24357
+ /* @__PURE__ */ jsxs24(Text28, { children: [
24358
+ check2.name,
24359
+ ": ",
24360
+ /* @__PURE__ */ jsx30(Text28, { color: STATUS_COLORS[check2.status], children: check2.message })
24361
+ ] })
24362
+ ] }),
24363
+ check2.detail && /* @__PURE__ */ jsx30(Box25, { marginLeft: 2, children: /* @__PURE__ */ jsx30(Text28, { color: theme.text.secondary, dimColor: true, children: check2.detail }) })
24364
+ ] }, check2.name))
24365
+ ] }, category)),
24366
+ /* @__PURE__ */ jsxs24(Box25, { marginTop: 1, flexDirection: "row", children: [
24367
+ /* @__PURE__ */ jsxs24(Text28, { color: theme.status.success, children: [
24368
+ "\u2713 ",
24369
+ summary.pass,
24370
+ " pass"
24371
+ ] }),
24372
+ summary.warn > 0 && /* @__PURE__ */ jsxs24(Fragment8, { children: [
24373
+ /* @__PURE__ */ jsx30(Text28, { children: " " }),
24374
+ /* @__PURE__ */ jsxs24(Text28, { color: theme.status.warning, children: [
24375
+ "\u26A0 ",
24376
+ summary.warn,
24377
+ " warn"
24378
+ ] })
24379
+ ] }),
24380
+ summary.fail > 0 && /* @__PURE__ */ jsxs24(Fragment8, { children: [
24381
+ /* @__PURE__ */ jsx30(Text28, { children: " " }),
24382
+ /* @__PURE__ */ jsxs24(Text28, { color: theme.status.error, children: [
24383
+ "\u2717 ",
24384
+ summary.fail,
24385
+ " fail"
24386
+ ] })
24387
+ ] }),
24388
+ !hasIssues && /* @__PURE__ */ jsx30(Text28, { color: theme.text.secondary, children: " \u2014 all checks passed" })
24389
+ ] })
24390
+ ] });
24391
+ };
24392
+ function useTerminalSize() {
24393
+ const [size, setSize] = useState12({
24394
+ columns: process.stdout.columns || 80,
24395
+ rows: process.stdout.rows || 24
24396
+ });
24397
+ useEffect14(() => {
24398
+ function updateSize() {
24399
+ setSize({
24400
+ columns: process.stdout.columns || 80,
24401
+ rows: process.stdout.rows || 24
24402
+ });
24403
+ }
24404
+ process.stdout.on("resize", updateSize);
24405
+ return () => {
24406
+ process.stdout.off("resize", updateSize);
24407
+ };
24408
+ }, []);
24409
+ return size;
24410
+ }
24411
+ var BTW_SELF_CHROME = 4;
24412
+ function normalizeCodeFences(text) {
24413
+ return text.replace(/([^\n])(```|~~~)/g, "$1\n$2");
24414
+ }
24415
+ var BtwMessageInternal = ({ btw, containerWidth }) => {
24416
+ const { columns: terminalWidth } = useTerminalSize();
24417
+ const baseWidth = containerWidth ?? terminalWidth;
24418
+ const contentWidth = Math.max(2, baseWidth - BTW_SELF_CHROME);
24419
+ return /* @__PURE__ */ jsxs25(
24420
+ Box26,
24421
+ {
24422
+ flexDirection: "column",
24423
+ borderStyle: "round",
24424
+ borderColor: theme.status.warning,
24425
+ paddingX: 1,
24426
+ width: "100%",
24427
+ children: [
24428
+ /* @__PURE__ */ jsxs25(Box26, { flexDirection: "row", children: [
24429
+ /* @__PURE__ */ jsx31(Text29, { color: theme.status.warning, bold: true, children: "/btw " }),
24430
+ /* @__PURE__ */ jsx31(Text29, { wrap: "wrap", color: theme.status.warning, children: btw.question })
24431
+ ] }),
24432
+ btw.isPending ? /* @__PURE__ */ jsxs25(Box26, { flexDirection: "column", marginTop: 1, children: [
24433
+ /* @__PURE__ */ jsxs25(Box26, { children: [
24434
+ /* @__PURE__ */ jsx31(Text29, { color: theme.status.warning, children: "+ " }),
24435
+ /* @__PURE__ */ jsx31(Text29, { color: theme.status.warning, children: "Respondendo..." })
24436
+ ] }),
24437
+ /* @__PURE__ */ jsx31(Box26, { marginTop: 1, children: /* @__PURE__ */ jsx31(Text29, { dimColor: true, children: "Pressione Esc, Ctrl+C ou Ctrl+D para cancelar" }) })
24438
+ ] }) : /* @__PURE__ */ jsxs25(Box26, { flexDirection: "column", marginTop: 1, children: [
24439
+ /* @__PURE__ */ jsx31(
24440
+ MarkdownDisplay,
24441
+ {
24442
+ text: normalizeCodeFences(btw.answer),
24443
+ isPending: false,
24444
+ contentWidth
24445
+ }
24446
+ ),
24447
+ /* @__PURE__ */ jsx31(Box26, { marginTop: 1, children: /* @__PURE__ */ jsx31(Text29, { dimColor: true, children: "Pressione Espa\xE7o, Enter ou Esc para fechar" }) })
24448
+ ] })
24449
+ ]
24450
+ }
24451
+ );
24452
+ };
24453
+ var BtwMessage = React23.memo(BtwMessageInternal);
24454
+ function fmtTokens2(n) {
24455
+ if (n >= 1e6) return `${(n / 1e6).toFixed(2)}M`;
24456
+ if (n >= 1e3) return `${(n / 1e3).toFixed(1)}k`;
24457
+ return n.toLocaleString("pt-BR");
24458
+ }
24459
+ var StatRow = ({ label, value, valueColor }) => /* @__PURE__ */ jsxs26(Box27, { children: [
24460
+ /* @__PURE__ */ jsx32(Box27, { width: 26, children: /* @__PURE__ */ jsx32(Text30, { color: theme.text.secondary, children: label }) }),
24461
+ /* @__PURE__ */ jsx32(Text30, { color: valueColor ?? theme.text.primary, children: value })
24462
+ ] });
24463
+ var StatsDisplay = ({
24464
+ duration,
24465
+ promptTokens,
24466
+ outputTokens,
24467
+ messageCount
24468
+ }) => /* @__PURE__ */ jsxs26(
24469
+ Box27,
24470
+ {
24471
+ borderStyle: "round",
24472
+ borderColor: theme.border.default,
24473
+ flexDirection: "column",
24474
+ paddingY: 1,
24475
+ paddingX: 2,
24476
+ children: [
24477
+ /* @__PURE__ */ jsx32(Text30, { bold: true, color: theme.text.accent, children: "Estat\xEDsticas da Sess\xE3o" }),
24478
+ /* @__PURE__ */ jsx32(Box27, { height: 1 }),
24479
+ /* @__PURE__ */ jsx32(StatRow, { label: "Tempo de sess\xE3o:", value: duration }),
24480
+ messageCount !== void 0 && /* @__PURE__ */ jsx32(StatRow, { label: "Mensagens:", value: String(messageCount) }),
24481
+ promptTokens !== void 0 && promptTokens > 0 && /* @__PURE__ */ jsx32(
24482
+ StatRow,
24483
+ {
24484
+ label: "\xDAltimo prompt (tokens):",
24485
+ value: fmtTokens2(promptTokens),
24486
+ valueColor: theme.status.warning
24487
+ }
24488
+ ),
24489
+ outputTokens !== void 0 && outputTokens > 0 && /* @__PURE__ */ jsx32(
24490
+ StatRow,
24491
+ {
24492
+ label: "\xDAltima resposta (tokens):",
24493
+ value: fmtTokens2(outputTokens),
24494
+ valueColor: theme.status.warning
24495
+ }
24496
+ )
24497
+ ]
24498
+ }
24499
+ );
24500
+ function pluralTurns(n) {
24501
+ return n === 1 ? "turno" : "turnos";
24502
+ }
24503
+ function assertNever(kind) {
24504
+ throw new Error(`Unexpected goal status kind: ${kind}`);
24505
+ }
24506
+ var GoalStatusMessageInternal = ({
24507
+ kind,
24508
+ condition,
24509
+ iterations,
24510
+ durationMs,
24511
+ lastReason
24512
+ }) => {
24513
+ if (kind === "checking") {
24514
+ const reason = lastReason?.trim();
24515
+ return /* @__PURE__ */ jsxs27(Box28, { flexDirection: "row", children: [
24516
+ /* @__PURE__ */ jsx33(Box28, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx33(Text31, { color: theme.text.secondary, children: "\u25CB" }) }),
24517
+ /* @__PURE__ */ jsxs27(Box28, { flexGrow: 1, flexDirection: "column", children: [
24518
+ /* @__PURE__ */ jsxs27(Text31, { color: theme.text.secondary, children: [
24519
+ "Verificando goal",
24520
+ typeof iterations === "number" && iterations > 0 ? ` \xB7 turno ${iterations}` : "",
24521
+ " ",
24522
+ "\xB7 ainda n\xE3o atingido"
24523
+ ] }),
24524
+ /* @__PURE__ */ jsxs27(Text31, { color: theme.text.secondary, wrap: "wrap", children: [
24525
+ "Goal: ",
24526
+ condition
24527
+ ] }),
24528
+ reason ? /* @__PURE__ */ jsxs27(Text31, { color: theme.text.secondary, wrap: "wrap", children: [
24529
+ "Avalia\xE7\xE3o: ",
24530
+ reason
24531
+ ] }) : null
24532
+ ] })
24533
+ ] });
24534
+ }
24535
+ const { prefix, prefixColor, title } = (() => {
24536
+ switch (kind) {
24537
+ case "set":
24538
+ return { prefix: "\u25CE", prefixColor: theme.text.accent, title: "Goal definido" };
24539
+ case "achieved":
24540
+ return { prefix: "\u2713", prefixColor: theme.status.success, title: "Goal atingido" };
24541
+ case "cleared":
24542
+ return { prefix: "\u25CB", prefixColor: theme.text.secondary, title: "Goal removido" };
24543
+ case "failed":
24544
+ return { prefix: "\u2716", prefixColor: theme.status.error, title: "Goal n\xE3o atingido" };
24545
+ case "aborted":
24546
+ return { prefix: "!", prefixColor: theme.status.warning, title: "Goal abortado" };
24547
+ default:
24548
+ return assertNever(kind);
24549
+ }
24550
+ })();
24551
+ const stats = [];
24552
+ if (typeof iterations === "number" && iterations > 0) {
24553
+ stats.push(`${iterations} ${pluralTurns(iterations)}`);
24554
+ }
24555
+ if (typeof durationMs === "number") {
24556
+ stats.push(formatDuration(durationMs, { hideTrailingZeros: true }));
24557
+ }
24558
+ const subtitle = stats.length > 0 ? stats.join(" \xB7 ") : null;
24559
+ return /* @__PURE__ */ jsxs27(Box28, { flexDirection: "row", children: [
24560
+ /* @__PURE__ */ jsx33(Box28, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx33(Text31, { color: prefixColor, children: prefix }) }),
24561
+ /* @__PURE__ */ jsxs27(Box28, { flexGrow: 1, flexDirection: "column", children: [
24562
+ /* @__PURE__ */ jsxs27(Text31, { color: prefixColor, children: [
24563
+ title,
24564
+ subtitle ? /* @__PURE__ */ jsxs27(Text31, { color: theme.text.secondary, children: [
24565
+ " \xB7 ",
24566
+ subtitle
24567
+ ] }) : null
24568
+ ] }),
24569
+ /* @__PURE__ */ jsxs27(Box28, { flexDirection: "row", children: [
24570
+ /* @__PURE__ */ jsx33(Box28, { flexShrink: 0, marginRight: 1, children: /* @__PURE__ */ jsx33(Text31, { color: theme.text.secondary, children: "Goal:" }) }),
24571
+ /* @__PURE__ */ jsx33(Box28, { flexGrow: 1, children: /* @__PURE__ */ jsx33(Text31, { wrap: "wrap", children: condition }) })
24572
+ ] }),
24573
+ isTerminalGoalStatusKind(kind) && lastReason?.trim() ? /* @__PURE__ */ jsxs27(Text31, { color: theme.text.secondary, wrap: "wrap", children: [
24574
+ "\xDAltima avalia\xE7\xE3o: ",
24575
+ lastReason.trim()
24576
+ ] }) : null
24577
+ ] })
24578
+ ] });
24579
+ };
24580
+ var GoalStatusMessage = React24.memo(GoalStatusMessageInternal);
24298
24581
  var HistoryItemDisplay = ({
24299
24582
  item,
24300
24583
  availableTerminalHeight,
@@ -24312,10 +24595,10 @@ var HistoryItemDisplay = ({
24312
24595
  const contentWidth = terminalWidth - 4;
24313
24596
  const boxWidth = mainAreaWidth ?? contentWidth;
24314
24597
  const marginTop = safeItem.type === "gemini_content" || safeItem.type === "gemini_thought_content" ? 0 : 1;
24315
- return /* @__PURE__ */ jsxs24(Box25, { flexDirection: "column", marginTop, marginLeft: 2, marginRight: 2, children: [
24316
- safeItem.type === "user" && /* @__PURE__ */ jsx30(UserMessage, { text: safeItem.text }),
24317
- safeItem.type === "user_shell" && /* @__PURE__ */ jsx30(UserShellMessage, { text: safeItem.text }),
24318
- safeItem.type === "gemini" && /* @__PURE__ */ jsx30(
24598
+ return /* @__PURE__ */ jsxs28(Box29, { flexDirection: "column", marginTop, marginLeft: 2, marginRight: 2, children: [
24599
+ safeItem.type === "user" && /* @__PURE__ */ jsx34(UserMessage, { text: safeItem.text }),
24600
+ safeItem.type === "user_shell" && /* @__PURE__ */ jsx34(UserShellMessage, { text: safeItem.text }),
24601
+ safeItem.type === "gemini" && /* @__PURE__ */ jsx34(
24319
24602
  AssistantMessage,
24320
24603
  {
24321
24604
  text: safeItem.text,
@@ -24324,7 +24607,7 @@ var HistoryItemDisplay = ({
24324
24607
  contentWidth
24325
24608
  }
24326
24609
  ),
24327
- safeItem.type === "gemini_content" && /* @__PURE__ */ jsx30(
24610
+ safeItem.type === "gemini_content" && /* @__PURE__ */ jsx34(
24328
24611
  AssistantMessageContent,
24329
24612
  {
24330
24613
  text: safeItem.text,
@@ -24333,7 +24616,7 @@ var HistoryItemDisplay = ({
24333
24616
  contentWidth
24334
24617
  }
24335
24618
  ),
24336
- !compactMode && safeItem.type === "gemini_thought" && /* @__PURE__ */ jsx30(
24619
+ !compactMode && safeItem.type === "gemini_thought" && /* @__PURE__ */ jsx34(
24337
24620
  ThinkMessage,
24338
24621
  {
24339
24622
  text: safeItem.text,
@@ -24342,7 +24625,7 @@ var HistoryItemDisplay = ({
24342
24625
  contentWidth
24343
24626
  }
24344
24627
  ),
24345
- !compactMode && safeItem.type === "gemini_thought_content" && /* @__PURE__ */ jsx30(
24628
+ !compactMode && safeItem.type === "gemini_thought_content" && /* @__PURE__ */ jsx34(
24346
24629
  ThinkMessageContent,
24347
24630
  {
24348
24631
  text: safeItem.text,
@@ -24351,11 +24634,11 @@ var HistoryItemDisplay = ({
24351
24634
  contentWidth
24352
24635
  }
24353
24636
  ),
24354
- safeItem.type === "info" && /* @__PURE__ */ jsx30(InfoMessage, { text: safeItem.text }),
24355
- safeItem.type === "success" && /* @__PURE__ */ jsx30(SuccessMessage, { text: safeItem.text }),
24356
- safeItem.type === "warning" && /* @__PURE__ */ jsx30(WarningMessage, { text: safeItem.text }),
24357
- safeItem.type === "error" && /* @__PURE__ */ jsx30(ErrorMessage, { text: safeItem.text }),
24358
- safeItem.type === "tool_group" && /* @__PURE__ */ jsx30(
24637
+ safeItem.type === "info" && /* @__PURE__ */ jsx34(InfoMessage, { text: safeItem.text }),
24638
+ safeItem.type === "success" && /* @__PURE__ */ jsx34(SuccessMessage, { text: safeItem.text }),
24639
+ safeItem.type === "warning" && /* @__PURE__ */ jsx34(WarningMessage, { text: safeItem.text }),
24640
+ safeItem.type === "error" && /* @__PURE__ */ jsx34(ErrorMessage, { text: safeItem.text }),
24641
+ safeItem.type === "tool_group" && /* @__PURE__ */ jsx34(
24359
24642
  ToolGroupMessage,
24360
24643
  {
24361
24644
  toolCalls: safeItem.tools,
@@ -24372,7 +24655,7 @@ var HistoryItemDisplay = ({
24372
24655
  compactLabel
24373
24656
  }
24374
24657
  ),
24375
- safeItem.type === "context_usage" && /* @__PURE__ */ jsx30(
24658
+ safeItem.type === "context_usage" && /* @__PURE__ */ jsx34(
24376
24659
  ContextUsage,
24377
24660
  {
24378
24661
  modelName: safeItem.modelName,
@@ -24387,40 +24670,61 @@ var HistoryItemDisplay = ({
24387
24670
  showDetails: safeItem.showDetails
24388
24671
  }
24389
24672
  ),
24390
- safeItem.type === "compression" && /* @__PURE__ */ jsx30(CompressionMessage, { compression: safeItem.compression }),
24391
- safeItem.type === "summary" && /* @__PURE__ */ jsx30(SummaryMessage, { summary: safeItem.summary }),
24392
- safeItem.type === "tool_use_summary" && (!compactMode || !summaryAbsorbed) && /* @__PURE__ */ jsx30(Box25, { paddingLeft: 1, children: /* @__PURE__ */ jsxs24(Text28, { dimColor: true, children: [
24673
+ safeItem.type === "doctor" && /* @__PURE__ */ jsx34(DoctorReport, { checks: safeItem.checks, summary: safeItem.summary }),
24674
+ safeItem.type === "stats" && /* @__PURE__ */ jsx34(
24675
+ StatsDisplay,
24676
+ {
24677
+ duration: safeItem.duration,
24678
+ promptTokens: safeItem.promptTokens,
24679
+ outputTokens: safeItem.outputTokens,
24680
+ messageCount: safeItem.messageCount
24681
+ }
24682
+ ),
24683
+ safeItem.type === "btw" && /* @__PURE__ */ jsx34(BtwMessage, { btw: safeItem.btw, containerWidth: boxWidth }),
24684
+ safeItem.type === "goal_status" && /* @__PURE__ */ jsx34(
24685
+ GoalStatusMessage,
24686
+ {
24687
+ kind: safeItem.kind,
24688
+ condition: safeItem.condition,
24689
+ iterations: safeItem.iterations,
24690
+ durationMs: safeItem.durationMs,
24691
+ lastReason: safeItem.lastReason
24692
+ }
24693
+ ),
24694
+ safeItem.type === "compression" && /* @__PURE__ */ jsx34(CompressionMessage, { compression: safeItem.compression }),
24695
+ safeItem.type === "summary" && /* @__PURE__ */ jsx34(SummaryMessage, { summary: safeItem.summary }),
24696
+ safeItem.type === "tool_use_summary" && (!compactMode || !summaryAbsorbed) && /* @__PURE__ */ jsx34(Box29, { paddingLeft: 1, children: /* @__PURE__ */ jsxs28(Text32, { dimColor: true, children: [
24393
24697
  "\u25CF ",
24394
24698
  safeItem.summary
24395
24699
  ] }) }),
24396
- safeItem.type === "retry_countdown" && /* @__PURE__ */ jsx30(WarningMessage, { text: safeItem.text }),
24397
- safeItem.type === "away_recap" && /* @__PURE__ */ jsx30(InfoMessage, { text: safeItem.text }),
24398
- safeItem.type === "memory_saved" && /* @__PURE__ */ jsx30(
24700
+ safeItem.type === "retry_countdown" && /* @__PURE__ */ jsx34(WarningMessage, { text: safeItem.text }),
24701
+ safeItem.type === "away_recap" && /* @__PURE__ */ jsx34(InfoMessage, { text: safeItem.text }),
24702
+ safeItem.type === "memory_saved" && /* @__PURE__ */ jsx34(
24399
24703
  InfoMessage,
24400
24704
  {
24401
24705
  text: `${safeItem.verb ?? "Saved"} ${safeItem.writtenCount} ${safeItem.writtenCount === 1 ? "memory file" : "memory files"}.`
24402
24706
  }
24403
24707
  ),
24404
- shouldRenderFallback(safeItem.type) && safeItem.text && /* @__PURE__ */ jsx30(InfoMessage, { text: safeItem.text }),
24405
- safeItem.type === "quit" && /* @__PURE__ */ jsx30(InfoMessage, { text: `Session ended. Duration: ${safeItem.duration}`, width: boxWidth })
24708
+ shouldRenderFallback(safeItem.type) && safeItem.text && /* @__PURE__ */ jsx34(InfoMessage, { text: safeItem.text }),
24709
+ safeItem.type === "quit" && /* @__PURE__ */ jsx34(InfoMessage, { text: `Session ended. Duration: ${safeItem.duration}`, width: boxWidth })
24406
24710
  ] });
24407
24711
  };
24408
24712
  function shouldRenderFallback(type) {
24409
- return type === "notification" || type === "extensions_list" || type === "model_stats" || type === "tool_stats" || type === "stats";
24713
+ return type === "notification" || type === "extensions_list" || type === "model_stats" || type === "tool_stats";
24410
24714
  }
24411
- var InfoMessage = ({ text }) => /* @__PURE__ */ jsxs24(Text28, { color: theme.text.secondary, children: [
24715
+ var InfoMessage = ({ text }) => /* @__PURE__ */ jsxs28(Text32, { color: theme.text.secondary, children: [
24412
24716
  "\u2139 ",
24413
24717
  text
24414
24718
  ] });
24415
- var SuccessMessage = ({ text }) => /* @__PURE__ */ jsxs24(Text28, { color: theme.status.success, children: [
24719
+ var SuccessMessage = ({ text }) => /* @__PURE__ */ jsxs28(Text32, { color: theme.status.success, children: [
24416
24720
  "\u2713 ",
24417
24721
  text
24418
24722
  ] });
24419
- var WarningMessage = ({ text }) => /* @__PURE__ */ jsxs24(Text28, { color: theme.status.warning, children: [
24723
+ var WarningMessage = ({ text }) => /* @__PURE__ */ jsxs28(Text32, { color: theme.status.warning, children: [
24420
24724
  "\u26A0 ",
24421
24725
  text
24422
24726
  ] });
24423
- var ErrorMessage = ({ text }) => /* @__PURE__ */ jsxs24(Text28, { color: theme.status.error, children: [
24727
+ var ErrorMessage = ({ text }) => /* @__PURE__ */ jsxs28(Text32, { color: theme.status.error, children: [
24424
24728
  "\u2717 ",
24425
24729
  text
24426
24730
  ] });
@@ -24579,7 +24883,7 @@ var MainContent = ({
24579
24883
  );
24580
24884
  const prevHistoryLengthRef = useRef6(history.length);
24581
24885
  const prevMergedLengthRef = useRef6(mergedHistory.length);
24582
- useEffect14(() => {
24886
+ useEffect15(() => {
24583
24887
  if (!compactMode) {
24584
24888
  prevHistoryLengthRef.current = history.length;
24585
24889
  prevMergedLengthRef.current = mergedHistory.length;
@@ -24595,17 +24899,17 @@ var MainContent = ({
24595
24899
  prevHistoryLengthRef.current = currH;
24596
24900
  prevMergedLengthRef.current = currM;
24597
24901
  }, [compactMode, history, mergedHistory, refreshStatic]);
24598
- const [replayCount, setReplayCount] = useState12(
24902
+ const [replayCount, setReplayCount] = useState13(
24599
24903
  () => initialReplayCount(mergedHistory.length)
24600
24904
  );
24601
24905
  const mergedLengthRef = useRef6(mergedHistory.length);
24602
24906
  mergedLengthRef.current = mergedHistory.length;
24603
- const [lastRemountKey, setLastRemountKey] = useState12(historyRemountKey);
24907
+ const [lastRemountKey, setLastRemountKey] = useState13(historyRemountKey);
24604
24908
  if (lastRemountKey !== historyRemountKey) {
24605
24909
  setLastRemountKey(historyRemountKey);
24606
24910
  setReplayCount(initialReplayCount(mergedLengthRef.current));
24607
24911
  }
24608
- useEffect14(() => {
24912
+ useEffect15(() => {
24609
24913
  if (replayCount >= mergedHistory.length) return;
24610
24914
  const remaining = mergedHistory.length - replayCount;
24611
24915
  if (remaining <= PROGRESSIVE_REPLAY_CHUNK_SIZE) {
@@ -24618,8 +24922,8 @@ var MainContent = ({
24618
24922
  return () => clearImmediate(handle);
24619
24923
  }, [replayCount, mergedHistory.length]);
24620
24924
  const visibleHistory = mergedHistory.length - replayCount <= PROGRESSIVE_REPLAY_CHUNK_SIZE ? mergedHistory : mergedHistory.slice(0, replayCount);
24621
- return /* @__PURE__ */ jsxs25(Box26, { flexDirection: "column", flexGrow: 1, children: [
24622
- /* @__PURE__ */ jsx31(Static, { items: visibleHistory, children: (item) => /* @__PURE__ */ jsx31(
24925
+ return /* @__PURE__ */ jsxs29(Box30, { flexDirection: "column", flexGrow: 1, children: [
24926
+ /* @__PURE__ */ jsx35(Static, { items: visibleHistory, children: (item) => /* @__PURE__ */ jsx35(
24623
24927
  HistoryItemDisplay,
24624
24928
  {
24625
24929
  item,
@@ -24632,7 +24936,7 @@ var MainContent = ({
24632
24936
  },
24633
24937
  item.id
24634
24938
  ) }, historyRemountKey),
24635
- pendingAssistantText.trim().length > 0 && /* @__PURE__ */ jsx31(
24939
+ pendingAssistantText.trim().length > 0 && /* @__PURE__ */ jsx35(
24636
24940
  HistoryItemDisplay,
24637
24941
  {
24638
24942
  item: { id: -1, type: "gemini", text: pendingAssistantText },
@@ -24642,7 +24946,7 @@ var MainContent = ({
24642
24946
  isFocused
24643
24947
  }
24644
24948
  ),
24645
- liveToolCalls.length > 0 && /* @__PURE__ */ jsx31(
24949
+ liveToolCalls.length > 0 && /* @__PURE__ */ jsx35(
24646
24950
  HistoryItemDisplay,
24647
24951
  {
24648
24952
  item: { id: -2, type: "tool_group", tools: liveToolCalls },
@@ -24661,27 +24965,8 @@ var ShowMoreLines = ({ constrainHeight }) => {
24661
24965
  if (overflowState === void 0 || overflowState.overflowingIds.size === 0 || !constrainHeight || !(streamingState === "idle" || streamingState === "waiting_for_confirmation")) {
24662
24966
  return null;
24663
24967
  }
24664
- return /* @__PURE__ */ jsx32(Box27, { children: /* @__PURE__ */ jsx32(Text29, { color: theme.text.secondary, wrap: "truncate", children: "Press ctrl-s to show more lines" }) });
24968
+ return /* @__PURE__ */ jsx36(Box31, { children: /* @__PURE__ */ jsx36(Text33, { color: theme.text.secondary, wrap: "truncate", children: "Press ctrl-s to show more lines" }) });
24665
24969
  };
24666
- function useTerminalSize() {
24667
- const [size, setSize] = useState13({
24668
- columns: process.stdout.columns || 80,
24669
- rows: process.stdout.rows || 24
24670
- });
24671
- useEffect15(() => {
24672
- function updateSize() {
24673
- setSize({
24674
- columns: process.stdout.columns || 80,
24675
- rows: process.stdout.rows || 24
24676
- });
24677
- }
24678
- process.stdout.on("resize", updateSize);
24679
- return () => {
24680
- process.stdout.off("resize", updateSize);
24681
- };
24682
- }, []);
24683
- return size;
24684
- }
24685
24970
  function useAnimationFrame(watchRef, intervalMs = 50) {
24686
24971
  const [displayValue, setDisplayValue] = useState14(() => watchRef.current);
24687
24972
  const displayRef = useRef7(watchRef.current);
@@ -24762,34 +25047,34 @@ var LoadingIndicator = ({
24762
25047
  time: timeStr,
24763
25048
  tokens: tokenStr
24764
25049
  }) : null;
24765
- return /* @__PURE__ */ jsxs26(Box28, { paddingLeft: 2, flexDirection: "column", children: [
24766
- /* @__PURE__ */ jsxs26(
24767
- Box28,
25050
+ return /* @__PURE__ */ jsxs30(Box32, { paddingLeft: 2, flexDirection: "column", children: [
25051
+ /* @__PURE__ */ jsxs30(
25052
+ Box32,
24768
25053
  {
24769
25054
  width: "100%",
24770
25055
  flexDirection: isNarrow ? "column" : "row",
24771
25056
  alignItems: isNarrow ? "flex-start" : "center",
24772
25057
  children: [
24773
- /* @__PURE__ */ jsxs26(Box28, { children: [
24774
- /* @__PURE__ */ jsx33(Box28, { marginRight: 1, children: /* @__PURE__ */ jsx33(
25058
+ /* @__PURE__ */ jsxs30(Box32, { children: [
25059
+ /* @__PURE__ */ jsx37(Box32, { marginRight: 1, children: /* @__PURE__ */ jsx37(
24775
25060
  GeminiRespondingSpinner,
24776
25061
  {
24777
25062
  nonRespondingDisplay: streamingState === "waiting_for_confirmation" ? "\u280F" : ""
24778
25063
  }
24779
25064
  ) }),
24780
- primaryText && /* @__PURE__ */ jsx33(Text30, { color: theme.text.accent, wrap: "truncate-end", children: primaryText }),
24781
- !isNarrow && cancelAndTimerContent && /* @__PURE__ */ jsxs26(Text30, { color: theme.text.secondary, children: [
25065
+ primaryText && /* @__PURE__ */ jsx37(Text34, { color: theme.text.accent, wrap: "truncate-end", children: primaryText }),
25066
+ !isNarrow && cancelAndTimerContent && /* @__PURE__ */ jsxs30(Text34, { color: theme.text.secondary, children: [
24782
25067
  " ",
24783
25068
  cancelAndTimerContent
24784
25069
  ] })
24785
25070
  ] }),
24786
- !isNarrow && /* @__PURE__ */ jsx33(Box28, { flexGrow: 1 }),
24787
- !isNarrow && rightContent && /* @__PURE__ */ jsx33(Box28, { children: rightContent })
25071
+ !isNarrow && /* @__PURE__ */ jsx37(Box32, { flexGrow: 1 }),
25072
+ !isNarrow && rightContent && /* @__PURE__ */ jsx37(Box32, { children: rightContent })
24788
25073
  ]
24789
25074
  }
24790
25075
  ),
24791
- isNarrow && cancelAndTimerContent && /* @__PURE__ */ jsx33(Box28, { children: /* @__PURE__ */ jsx33(Text30, { color: theme.text.secondary, children: cancelAndTimerContent }) }),
24792
- isNarrow && rightContent && /* @__PURE__ */ jsx33(Box28, { children: rightContent })
25076
+ isNarrow && cancelAndTimerContent && /* @__PURE__ */ jsx37(Box32, { children: /* @__PURE__ */ jsx37(Text34, { color: theme.text.secondary, children: cancelAndTimerContent }) }),
25077
+ isNarrow && rightContent && /* @__PURE__ */ jsx37(Box32, { children: rightContent })
24793
25078
  ] });
24794
25079
  };
24795
25080
  var MAX_WIDTH = 150;
@@ -24803,7 +25088,7 @@ var _PrepareLabel = ({
24803
25088
  const hasMatch = matchedIndex !== void 0 && matchedIndex >= 0 && matchedIndex < label.length && userInput.length > 0;
24804
25089
  if (!hasMatch) {
24805
25090
  const display = isExpanded ? label : label.length > MAX_WIDTH ? label.slice(0, MAX_WIDTH) + "..." : label;
24806
- return /* @__PURE__ */ jsx34(Text31, { wrap: "wrap", color: textColor, children: display });
25091
+ return /* @__PURE__ */ jsx38(Text35, { wrap: "wrap", color: textColor, children: display });
24807
25092
  }
24808
25093
  const matchLength = userInput.length;
24809
25094
  let before = "";
@@ -24842,10 +25127,10 @@ var _PrepareLabel = ({
24842
25127
  after = after.length >= 3 ? after.slice(0, -3) + "..." : "...";
24843
25128
  }
24844
25129
  }
24845
- return /* @__PURE__ */ jsxs27(Text31, { color: textColor, wrap: "wrap", children: [
25130
+ return /* @__PURE__ */ jsxs31(Text35, { color: textColor, wrap: "wrap", children: [
24846
25131
  before,
24847
- match ? match.split(/(\s+)/).map((part, index) => /* @__PURE__ */ jsx34(
24848
- Text31,
25132
+ match ? match.split(/(\s+)/).map((part, index) => /* @__PURE__ */ jsx38(
25133
+ Text35,
24849
25134
  {
24850
25135
  color: theme.background.primary,
24851
25136
  backgroundColor: theme.text.primary,
@@ -24856,7 +25141,7 @@ var _PrepareLabel = ({
24856
25141
  after
24857
25142
  ] });
24858
25143
  };
24859
- var PrepareLabel = React25.memo(_PrepareLabel);
25144
+ var PrepareLabel = React27.memo(_PrepareLabel);
24860
25145
  var MAX_SUGGESTIONS_TO_SHOW = 8;
24861
25146
  function SuggestionsDisplay({
24862
25147
  suggestions,
@@ -24869,7 +25154,7 @@ function SuggestionsDisplay({
24869
25154
  expandedIndex
24870
25155
  }) {
24871
25156
  if (isLoading) {
24872
- return /* @__PURE__ */ jsx35(Box29, { width, children: /* @__PURE__ */ jsx35(Text32, { color: "gray", children: t("Loading suggestions...") }) });
25157
+ return /* @__PURE__ */ jsx39(Box33, { width, children: /* @__PURE__ */ jsx39(Text36, { color: "gray", children: t("Loading suggestions...") }) });
24873
25158
  }
24874
25159
  if (suggestions.length === 0) {
24875
25160
  return null;
@@ -24885,8 +25170,8 @@ function SuggestionsDisplay({
24885
25170
  ...suggestions.map((s) => getFullLabel(s).length)
24886
25171
  );
24887
25172
  const commandColumnWidth = mode === "slash" ? Math.min(maxLabelLength, Math.floor(width * 0.5)) : 0;
24888
- return /* @__PURE__ */ jsxs28(Box29, { flexDirection: "column", width, children: [
24889
- scrollOffset > 0 && /* @__PURE__ */ jsx35(Text32, { color: theme.text.primary, children: "\u25B2" }),
25173
+ return /* @__PURE__ */ jsxs32(Box33, { flexDirection: "column", width, children: [
25174
+ scrollOffset > 0 && /* @__PURE__ */ jsx39(Text36, { color: theme.text.primary, children: "\u25B2" }),
24890
25175
  visibleSuggestions.map((suggestion, index) => {
24891
25176
  const originalIndex = startIndex + index;
24892
25177
  const isActive = originalIndex === activeIndex;
@@ -24899,7 +25184,7 @@ function SuggestionsDisplay({
24899
25184
  width - commandColumnWidth - 2 - expansionIndicatorWidth,
24900
25185
  1
24901
25186
  );
24902
- const labelElement = /* @__PURE__ */ jsx35(
25187
+ const labelElement = /* @__PURE__ */ jsx39(
24903
25188
  PrepareLabel,
24904
25189
  {
24905
25190
  label: displayLabel,
@@ -24909,39 +25194,39 @@ function SuggestionsDisplay({
24909
25194
  isExpanded
24910
25195
  }
24911
25196
  );
24912
- return /* @__PURE__ */ jsxs28(Box29, { flexDirection: "row", children: [
24913
- /* @__PURE__ */ jsx35(
24914
- Box29,
25197
+ return /* @__PURE__ */ jsxs32(Box33, { flexDirection: "row", children: [
25198
+ /* @__PURE__ */ jsx39(
25199
+ Box33,
24915
25200
  {
24916
25201
  ...mode === "slash" ? { width: commandColumnWidth, flexShrink: 0 } : { flexShrink: 1 },
24917
- children: /* @__PURE__ */ jsxs28(Box29, { children: [
25202
+ children: /* @__PURE__ */ jsxs32(Box33, { children: [
24918
25203
  labelElement,
24919
- suggestion.argumentHint && /* @__PURE__ */ jsxs28(Text32, { color: theme.text.secondary, children: [
25204
+ suggestion.argumentHint && /* @__PURE__ */ jsxs32(Text36, { color: theme.text.secondary, children: [
24920
25205
  " ",
24921
25206
  suggestion.argumentHint
24922
25207
  ] }),
24923
- suggestion.sourceBadge && /* @__PURE__ */ jsxs28(Text32, { color: textColor, children: [
25208
+ suggestion.sourceBadge && /* @__PURE__ */ jsxs32(Text36, { color: textColor, children: [
24924
25209
  " ",
24925
25210
  suggestion.sourceBadge
24926
25211
  ] })
24927
25212
  ] })
24928
25213
  }
24929
25214
  ),
24930
- suggestion.description && /* @__PURE__ */ jsx35(
24931
- Box29,
25215
+ suggestion.description && /* @__PURE__ */ jsx39(
25216
+ Box33,
24932
25217
  {
24933
25218
  width: descriptionColumnWidth,
24934
25219
  flexGrow: 1,
24935
25220
  flexShrink: 1,
24936
25221
  paddingLeft: 2,
24937
- children: /* @__PURE__ */ jsx35(Text32, { color: textColor, wrap: "wrap", children: suggestion.description })
25222
+ children: /* @__PURE__ */ jsx39(Text36, { color: textColor, wrap: "wrap", children: suggestion.description })
24938
25223
  }
24939
25224
  ),
24940
- isActive && isLong && /* @__PURE__ */ jsx35(Box29, { children: /* @__PURE__ */ jsx35(Text32, { color: Colors.Gray, children: isExpanded ? " \u2190 " : " \u2192 " }) })
25225
+ isActive && isLong && /* @__PURE__ */ jsx39(Box33, { children: /* @__PURE__ */ jsx39(Text36, { color: Colors.Gray, children: isExpanded ? " \u2190 " : " \u2192 " }) })
24941
25226
  ] }, `${suggestion.value}-${originalIndex}`);
24942
25227
  }),
24943
- endIndex < suggestions.length && /* @__PURE__ */ jsx35(Text32, { color: "gray", children: "\u25BC" }),
24944
- suggestions.length > MAX_SUGGESTIONS_TO_SHOW && /* @__PURE__ */ jsxs28(Text32, { color: "gray", children: [
25228
+ endIndex < suggestions.length && /* @__PURE__ */ jsx39(Text36, { color: "gray", children: "\u25BC" }),
25229
+ suggestions.length > MAX_SUGGESTIONS_TO_SHOW && /* @__PURE__ */ jsxs32(Text36, { color: "gray", children: [
24945
25230
  "(",
24946
25231
  activeIndex + 1,
24947
25232
  "/",
@@ -26691,11 +26976,11 @@ function defaultRenderLine({
26691
26976
  showCursor
26692
26977
  }) {
26693
26978
  if (!isOnCursorLine || !showCursor) {
26694
- return /* @__PURE__ */ jsx36(Text33, { children: lineText || " " });
26979
+ return /* @__PURE__ */ jsx40(Text37, { children: lineText || " " });
26695
26980
  }
26696
26981
  const len = cpLen(lineText);
26697
26982
  if (cursorCol >= len) {
26698
- return /* @__PURE__ */ jsxs29(Text33, { children: [
26983
+ return /* @__PURE__ */ jsxs33(Text37, { children: [
26699
26984
  lineText,
26700
26985
  chalk2.inverse(" ") + "\u200B"
26701
26986
  ] });
@@ -26703,7 +26988,7 @@ function defaultRenderLine({
26703
26988
  const before = cpSlice(lineText, 0, cursorCol);
26704
26989
  const cursorChar = cpSlice(lineText, cursorCol, cursorCol + 1);
26705
26990
  const after = cpSlice(lineText, cursorCol + 1);
26706
- return /* @__PURE__ */ jsxs29(Text33, { children: [
26991
+ return /* @__PURE__ */ jsxs33(Text37, { children: [
26707
26992
  before,
26708
26993
  chalk2.inverse(cursorChar),
26709
26994
  after
@@ -26826,15 +27111,15 @@ var BaseTextInput = ({
26826
27111
  const [cursorVisualRow, cursorVisualCol] = buffer.visualCursor;
26827
27112
  const scrollVisualRow = buffer.visualScrollRow;
26828
27113
  const resolvedBorderColor = borderColor ?? theme.border.focused;
26829
- const resolvedPrefix = prefix ?? /* @__PURE__ */ jsx36(Text33, { color: theme.text.accent, children: "> " });
27114
+ const resolvedPrefix = prefix ?? /* @__PURE__ */ jsx40(Text37, { color: theme.text.accent, children: "> " });
26830
27115
  const columns = process.stdout.columns || 80;
26831
27116
  const labelWidth = topRightLabel ? stringWidth(topRightLabel) + 4 : 0;
26832
27117
  const dashCount = Math.max(1, columns - labelWidth);
26833
27118
  const topBorderLine = topRightLabel ? `${"\u2500".repeat(dashCount)} ${topRightLabel} ${"\u2500".repeat(2)}` : "\u2500".repeat(columns);
26834
- return /* @__PURE__ */ jsxs29(Box30, { flexDirection: "column", children: [
26835
- /* @__PURE__ */ jsx36(Text33, { color: resolvedBorderColor, wrap: "truncate-end", children: topBorderLine }),
26836
- /* @__PURE__ */ jsxs29(
26837
- Box30,
27119
+ return /* @__PURE__ */ jsxs33(Box34, { flexDirection: "column", children: [
27120
+ /* @__PURE__ */ jsx40(Text37, { color: resolvedBorderColor, wrap: "truncate-end", children: topBorderLine }),
27121
+ /* @__PURE__ */ jsxs33(
27122
+ Box34,
26838
27123
  {
26839
27124
  borderStyle: "single",
26840
27125
  borderTop: false,
@@ -26844,13 +27129,13 @@ var BaseTextInput = ({
26844
27129
  borderColor: resolvedBorderColor,
26845
27130
  children: [
26846
27131
  resolvedPrefix,
26847
- /* @__PURE__ */ jsx36(Box30, { flexGrow: 1, flexDirection: "column", children: buffer.text.length === 0 && placeholder ? showCursor ? /* @__PURE__ */ jsxs29(Text33, { children: [
27132
+ /* @__PURE__ */ jsx40(Box34, { flexGrow: 1, flexDirection: "column", children: buffer.text.length === 0 && placeholder ? showCursor ? /* @__PURE__ */ jsxs33(Text37, { children: [
26848
27133
  chalk2.inverse(placeholder.slice(0, 1)),
26849
- /* @__PURE__ */ jsx36(Text33, { color: theme.text.secondary, children: placeholder.slice(1) })
26850
- ] }) : /* @__PURE__ */ jsx36(Text33, { color: theme.text.secondary, children: placeholder }) : linesToRender.map((lineText, idx) => {
27134
+ /* @__PURE__ */ jsx40(Text37, { color: theme.text.secondary, children: placeholder.slice(1) })
27135
+ ] }) : /* @__PURE__ */ jsx40(Text37, { color: theme.text.secondary, children: placeholder }) : linesToRender.map((lineText, idx) => {
26851
27136
  const absoluteVisualIndex = scrollVisualRow + idx;
26852
27137
  const isOnCursorLine = absoluteVisualIndex === cursorVisualRow;
26853
- return /* @__PURE__ */ jsx36(Box30, { height: 1, children: renderLine({
27138
+ return /* @__PURE__ */ jsx40(Box34, { height: 1, children: renderLine({
26854
27139
  lineText,
26855
27140
  isOnCursorLine,
26856
27141
  cursorCol: cursorVisualCol,
@@ -27814,7 +28099,7 @@ ${currentText}`);
27814
28099
  }
27815
28100
  const color = seg.type === "command" || seg.type === "file" ? theme.text.accent : theme.text.primary;
27816
28101
  renderedLine.push(
27817
- /* @__PURE__ */ jsx37(Text34, { color, children: display }, `token-${segIdx}`)
28102
+ /* @__PURE__ */ jsx41(Text38, { color, children: display }, `token-${segIdx}`)
27818
28103
  );
27819
28104
  });
27820
28105
  if (isOnCursorLine && cursorVisualColAbsolute === cpLen(lineText)) {
@@ -27822,31 +28107,31 @@ ${currentText}`);
27822
28107
  if (ghostText && showCursorOpt && ghostText.text.length > 0) {
27823
28108
  if (ghostText.showCursorBeforeText) {
27824
28109
  renderedLine.push(
27825
- /* @__PURE__ */ jsx37(Text34, { children: chalk3.inverse(" ") }, "ghost-cursor")
28110
+ /* @__PURE__ */ jsx41(Text38, { children: chalk3.inverse(" ") }, "ghost-cursor")
27826
28111
  );
27827
28112
  renderedLine.push(
27828
- /* @__PURE__ */ jsx37(Text34, { color: theme.text.secondary, children: ghostText.text }, "ghost-rest")
28113
+ /* @__PURE__ */ jsx41(Text38, { color: theme.text.secondary, children: ghostText.text }, "ghost-rest")
27829
28114
  );
27830
28115
  } else {
27831
28116
  const firstChar = ghostText.text[0];
27832
28117
  const rest = ghostText.text.slice(firstChar.length);
27833
28118
  renderedLine.push(
27834
- /* @__PURE__ */ jsx37(Text34, { children: chalk3.inverse(firstChar) }, "ghost-cursor")
28119
+ /* @__PURE__ */ jsx41(Text38, { children: chalk3.inverse(firstChar) }, "ghost-cursor")
27835
28120
  );
27836
28121
  if (rest.length > 0) {
27837
28122
  renderedLine.push(
27838
- /* @__PURE__ */ jsx37(Text34, { color: theme.text.secondary, children: rest }, "ghost-rest")
28123
+ /* @__PURE__ */ jsx41(Text38, { color: theme.text.secondary, children: rest }, "ghost-rest")
27839
28124
  );
27840
28125
  }
27841
28126
  }
27842
- renderedLine.push(/* @__PURE__ */ jsx37(Text34, { children: `\u200B` }, "ghost-zwsp"));
28127
+ renderedLine.push(/* @__PURE__ */ jsx41(Text38, { children: `\u200B` }, "ghost-zwsp"));
27843
28128
  } else {
27844
28129
  renderedLine.push(
27845
- /* @__PURE__ */ jsx37(Text34, { children: showCursorOpt ? chalk3.inverse(" ") + "\u200B" : " \u200B" }, `cursor-end-${cursorVisualColAbsolute}`)
28130
+ /* @__PURE__ */ jsx41(Text38, { children: showCursorOpt ? chalk3.inverse(" ") + "\u200B" : " \u200B" }, `cursor-end-${cursorVisualColAbsolute}`)
27846
28131
  );
27847
28132
  }
27848
28133
  }
27849
- return /* @__PURE__ */ jsx37(Text34, { children: renderedLine });
28134
+ return /* @__PURE__ */ jsx41(Text38, { children: renderedLine });
27850
28135
  },
27851
28136
  [slashCommands]
27852
28137
  );
@@ -27887,25 +28172,25 @@ ${currentText}`);
27887
28172
  statusText = t("Accepting edits");
27888
28173
  }
27889
28174
  const borderColor = isShellFocused && !isEmbeddedShellFocused && !agentTabBarFocused ? statusColor2 ?? theme.border.focused : theme.border.default;
27890
- const prefixNode = /* @__PURE__ */ jsxs30(
27891
- Text34,
28175
+ const prefixNode = /* @__PURE__ */ jsxs34(
28176
+ Text38,
27892
28177
  {
27893
28178
  color: statusColor2 ?? theme.text.accent,
27894
28179
  "aria-label": statusText || void 0,
27895
28180
  children: [
27896
- shellModeActive ? reverseSearchActive ? /* @__PURE__ */ jsxs30(Text34, { color: theme.text.link, "aria-label": SCREEN_READER_USER_PREFIX, children: [
28181
+ shellModeActive ? reverseSearchActive ? /* @__PURE__ */ jsxs34(Text38, { color: theme.text.link, "aria-label": SCREEN_READER_USER_PREFIX, children: [
27897
28182
  "(r:)",
27898
28183
  " "
27899
- ] }) : "!" : commandSearchActive ? /* @__PURE__ */ jsx37(Text34, { color: theme.text.accent, children: "(r:) " }) : showYoloStyling ? "*" : ">",
28184
+ ] }) : "!" : commandSearchActive ? /* @__PURE__ */ jsx41(Text38, { color: theme.text.accent, children: "(r:) " }) : showYoloStyling ? "*" : ">",
27900
28185
  " "
27901
28186
  ]
27902
28187
  }
27903
28188
  );
27904
- return /* @__PURE__ */ jsxs30(Fragment8, { children: [
27905
- attachments.length > 0 && /* @__PURE__ */ jsxs30(Box31, { marginLeft: 2, marginBottom: 0, children: [
27906
- /* @__PURE__ */ jsx37(Text34, { color: theme.text.secondary, children: t("Attachments: ") }),
27907
- attachments.map((att, idx) => /* @__PURE__ */ jsxs30(
27908
- Text34,
28189
+ return /* @__PURE__ */ jsxs34(Fragment9, { children: [
28190
+ attachments.length > 0 && /* @__PURE__ */ jsxs34(Box35, { marginLeft: 2, marginBottom: 0, children: [
28191
+ /* @__PURE__ */ jsx41(Text38, { color: theme.text.secondary, children: t("Attachments: ") }),
28192
+ attachments.map((att, idx) => /* @__PURE__ */ jsxs34(
28193
+ Text38,
27909
28194
  {
27910
28195
  color: isAttachmentMode && idx === selectedAttachmentIndex ? theme.status.success : theme.text.secondary,
27911
28196
  children: [
@@ -27918,7 +28203,7 @@ ${currentText}`);
27918
28203
  att.id
27919
28204
  ))
27920
28205
  ] }),
27921
- /* @__PURE__ */ jsx37(
28206
+ /* @__PURE__ */ jsx41(
27922
28207
  BaseTextInput,
27923
28208
  {
27924
28209
  buffer,
@@ -27933,7 +28218,7 @@ ${currentText}`);
27933
28218
  renderLine: renderLineWithHighlighting
27934
28219
  }
27935
28220
  ),
27936
- shouldShowSuggestions && /* @__PURE__ */ jsx37(Box31, { marginLeft: 2, marginRight: 2, children: /* @__PURE__ */ jsx37(
28221
+ shouldShowSuggestions && /* @__PURE__ */ jsx41(Box35, { marginLeft: 2, marginRight: 2, children: /* @__PURE__ */ jsx41(
27937
28222
  SuggestionsDisplay,
27938
28223
  {
27939
28224
  suggestions: suggestionDisplayProps.suggestions,
@@ -27946,7 +28231,7 @@ ${currentText}`);
27946
28231
  expandedIndex: expandedSuggestionIndex
27947
28232
  }
27948
28233
  ) }),
27949
- attachments.length > 0 && !shouldShowSuggestions && /* @__PURE__ */ jsx37(Box31, { marginLeft: 2, marginRight: 2, children: /* @__PURE__ */ jsx37(Text34, { color: theme.text.secondary, children: isAttachmentMode ? t("\u2190 \u2192 select, Delete to remove, \u2193 to exit") : t("\u2191 to manage attachments") }) })
28234
+ attachments.length > 0 && !shouldShowSuggestions && /* @__PURE__ */ jsx41(Box35, { marginLeft: 2, marginRight: 2, children: /* @__PURE__ */ jsx41(Text38, { color: theme.text.secondary, children: isAttachmentMode ? t("\u2190 \u2192 select, Delete to remove, \u2193 to exit") : t("\u2191 to manage attachments") }) })
27950
28235
  ] });
27951
28236
  };
27952
28237
  function formatPercentageUsed(percentage) {
@@ -27968,12 +28253,12 @@ var ContextUsageDisplay = ({
27968
28253
  const isOverLimit = percentage > 1;
27969
28254
  const label = terminalWidth < 100 ? t("% used") : t("% context used");
27970
28255
  if (isOverLimit) {
27971
- return /* @__PURE__ */ jsx38(Fragment9, { children: /* @__PURE__ */ jsxs31(Text35, { color: theme.status.error, children: [
28256
+ return /* @__PURE__ */ jsx42(Fragment10, { children: /* @__PURE__ */ jsxs35(Text39, { color: theme.status.error, children: [
27972
28257
  percentageUsed,
27973
28258
  label
27974
28259
  ] }) });
27975
28260
  }
27976
- return /* @__PURE__ */ jsxs31(Text35, { color: theme.text.secondary, children: [
28261
+ return /* @__PURE__ */ jsxs35(Text39, { color: theme.text.secondary, children: [
27977
28262
  percentageUsed,
27978
28263
  label
27979
28264
  ] });
@@ -28005,20 +28290,20 @@ var AutoAcceptIndicator = ({
28005
28290
  default:
28006
28291
  break;
28007
28292
  }
28008
- return /* @__PURE__ */ jsxs32(Text36, { color: textColor, children: [
28293
+ return /* @__PURE__ */ jsxs36(Text40, { color: textColor, children: [
28009
28294
  textContent,
28010
- subText && /* @__PURE__ */ jsx39(Text36, { color: theme.text.secondary, children: subText })
28295
+ subText && /* @__PURE__ */ jsx43(Text40, { color: theme.text.secondary, children: subText })
28011
28296
  ] });
28012
28297
  };
28013
- var ShellModeIndicator = () => /* @__PURE__ */ jsxs33(Text37, { color: theme.ui.symbol, children: [
28298
+ var ShellModeIndicator = () => /* @__PURE__ */ jsxs37(Text41, { color: theme.ui.symbol, children: [
28014
28299
  "shell mode enabled",
28015
- /* @__PURE__ */ jsx40(Text37, { color: theme.text.secondary, children: " (esc to disable)" })
28300
+ /* @__PURE__ */ jsx44(Text41, { color: theme.text.secondary, children: " (esc to disable)" })
28016
28301
  ] });
28017
28302
  function BackgroundTasksPill() {
28018
28303
  const { activeSubagents } = useUIState();
28019
28304
  const running = activeSubagents.filter((s) => s.status === "running").length;
28020
28305
  if (running <= 0) return null;
28021
- return /* @__PURE__ */ jsxs34(Text38, { color: theme.text.accent, children: [
28306
+ return /* @__PURE__ */ jsxs38(Text42, { color: theme.text.accent, children: [
28022
28307
  " ",
28023
28308
  running,
28024
28309
  " task",
@@ -28029,7 +28314,7 @@ function MCPHealthPill() {
28029
28314
  const { mcpConnected, mcpTotal } = useUIState();
28030
28315
  if (mcpTotal === 0) return null;
28031
28316
  const color = mcpConnected === mcpTotal ? theme.status.success : theme.status.warning;
28032
- return /* @__PURE__ */ jsxs35(Text39, { color, children: [
28317
+ return /* @__PURE__ */ jsxs39(Text43, { color, children: [
28033
28318
  " MCP ",
28034
28319
  mcpConnected,
28035
28320
  "/",
@@ -28078,7 +28363,7 @@ var VimModeProvider = ({
28078
28363
  setVimMode(next ? "NORMAL" : "INSERT");
28079
28364
  return next;
28080
28365
  }, [vimEnabled]);
28081
- return /* @__PURE__ */ jsx41(
28366
+ return /* @__PURE__ */ jsx45(
28082
28367
  VimModeContext.Provider,
28083
28368
  {
28084
28369
  value: { vimEnabled, vimMode, toggleVimEnabled, setVimMode },
@@ -28110,16 +28395,16 @@ var Footer = () => {
28110
28395
  const debugMode = config.getDebugMode();
28111
28396
  const contextWindowSize = config.getContentGeneratorConfig()?.contextWindowSize;
28112
28397
  const suppressHint = statusLineLines.length > 0;
28113
- const leftBottomContent = uiState.ctrlCPressedOnce ? /* @__PURE__ */ jsx42(Text40, { color: theme.status.warning, children: t("Press Ctrl+C again to exit.") }) : uiState.ctrlDPressedOnce ? /* @__PURE__ */ jsx42(Text40, { color: theme.status.warning, children: t("Press Ctrl+D again to exit.") }) : uiState.showEscapePrompt ? /* @__PURE__ */ jsx42(Text40, { color: theme.text.secondary, children: t("Press Esc again to clear.") }) : uiState.rewindEscPending ? /* @__PURE__ */ jsx42(Text40, { color: theme.text.secondary, children: t("Press Esc again to rewind conversation.") }) : vimEnabled && vimMode === "INSERT" ? /* @__PURE__ */ jsx42(Text40, { color: theme.text.secondary, children: "-- INSERT --" }) : uiState.shellModeActive ? /* @__PURE__ */ jsx42(ShellModeIndicator, {}) : configInitMessage ? /* @__PURE__ */ jsxs36(Text40, { color: theme.text.secondary, children: [
28114
- /* @__PURE__ */ jsx42(GeminiSpinner, {}),
28398
+ const leftBottomContent = uiState.ctrlCPressedOnce ? /* @__PURE__ */ jsx46(Text44, { color: theme.status.warning, children: t("Press Ctrl+C again to exit.") }) : uiState.ctrlDPressedOnce ? /* @__PURE__ */ jsx46(Text44, { color: theme.status.warning, children: t("Press Ctrl+D again to exit.") }) : uiState.showEscapePrompt ? /* @__PURE__ */ jsx46(Text44, { color: theme.text.secondary, children: t("Press Esc again to clear.") }) : uiState.rewindEscPending ? /* @__PURE__ */ jsx46(Text44, { color: theme.text.secondary, children: t("Press Esc again to rewind conversation.") }) : vimEnabled && vimMode === "INSERT" ? /* @__PURE__ */ jsx46(Text44, { color: theme.text.secondary, children: "-- INSERT --" }) : uiState.shellModeActive ? /* @__PURE__ */ jsx46(ShellModeIndicator, {}) : configInitMessage ? /* @__PURE__ */ jsxs40(Text44, { color: theme.text.secondary, children: [
28399
+ /* @__PURE__ */ jsx46(GeminiSpinner, {}),
28115
28400
  " ",
28116
28401
  configInitMessage
28117
- ] }) : showAutoAcceptIndicator !== void 0 && showAutoAcceptIndicator !== "default" ? /* @__PURE__ */ jsx42(AutoAcceptIndicator, { approvalMode: showAutoAcceptIndicator }) : suppressHint ? null : /* @__PURE__ */ jsx42(Text40, { color: theme.text.secondary, children: t("? for shortcuts") });
28402
+ ] }) : showAutoAcceptIndicator !== void 0 && showAutoAcceptIndicator !== "default" ? /* @__PURE__ */ jsx46(AutoAcceptIndicator, { approvalMode: showAutoAcceptIndicator }) : suppressHint ? null : /* @__PURE__ */ jsx46(Text44, { color: theme.text.secondary, children: t("? for shortcuts") });
28118
28403
  const rightItems = [];
28119
28404
  if (sandboxInfo) {
28120
28405
  rightItems.push({
28121
28406
  key: "sandbox",
28122
- node: /* @__PURE__ */ jsxs36(Text40, { color: theme.status.success, children: [
28407
+ node: /* @__PURE__ */ jsxs40(Text44, { color: theme.status.success, children: [
28123
28408
  "\u{1F512} ",
28124
28409
  sandboxInfo
28125
28410
  ] })
@@ -28128,13 +28413,13 @@ var Footer = () => {
28128
28413
  if (debugMode) {
28129
28414
  rightItems.push({
28130
28415
  key: "debug",
28131
- node: /* @__PURE__ */ jsx42(Text40, { color: theme.status.warning, children: "Debug Mode" })
28416
+ node: /* @__PURE__ */ jsx46(Text44, { color: theme.status.warning, children: "Debug Mode" })
28132
28417
  });
28133
28418
  }
28134
28419
  if (promptTokenCount > 0 && contextWindowSize) {
28135
28420
  rightItems.push({
28136
28421
  key: "context",
28137
- node: /* @__PURE__ */ jsx42(Text40, { color: theme.text.accent, children: /* @__PURE__ */ jsx42(
28422
+ node: /* @__PURE__ */ jsx46(Text44, { color: theme.text.accent, children: /* @__PURE__ */ jsx46(
28138
28423
  ContextUsageDisplay,
28139
28424
  {
28140
28425
  promptTokenCount,
@@ -28144,8 +28429,8 @@ var Footer = () => {
28144
28429
  ) })
28145
28430
  });
28146
28431
  }
28147
- return /* @__PURE__ */ jsxs36(
28148
- Box32,
28432
+ return /* @__PURE__ */ jsxs40(
28433
+ Box36,
28149
28434
  {
28150
28435
  flexDirection: isNarrow ? "column" : "row",
28151
28436
  justifyContent: isNarrow ? "flex-start" : "space-between",
@@ -28153,16 +28438,16 @@ var Footer = () => {
28153
28438
  paddingX: 2,
28154
28439
  gap: isNarrow ? 0 : 1,
28155
28440
  children: [
28156
- /* @__PURE__ */ jsxs36(Box32, { flexDirection: "column", flexShrink: isNarrow ? 0 : 1, children: [
28157
- statusLineLines.length > 0 && !uiState.ctrlCPressedOnce && !uiState.ctrlDPressedOnce && statusLineLines.map((line, i) => /* @__PURE__ */ jsx42(Text40, { dimColor: true, wrap: "truncate", children: line }, `status-line-${i}`)),
28158
- /* @__PURE__ */ jsxs36(Box32, { flexDirection: "row", flexShrink: 1, children: [
28159
- /* @__PURE__ */ jsx42(Text40, { wrap: "truncate", children: leftBottomContent }),
28160
- /* @__PURE__ */ jsx42(BackgroundTasksPill, {}),
28161
- /* @__PURE__ */ jsx42(MCPHealthPill, {})
28441
+ /* @__PURE__ */ jsxs40(Box36, { flexDirection: "column", flexShrink: isNarrow ? 0 : 1, children: [
28442
+ statusLineLines.length > 0 && !uiState.ctrlCPressedOnce && !uiState.ctrlDPressedOnce && statusLineLines.map((line, i) => /* @__PURE__ */ jsx46(Text44, { dimColor: true, wrap: "truncate", children: line }, `status-line-${i}`)),
28443
+ /* @__PURE__ */ jsxs40(Box36, { flexDirection: "row", flexShrink: 1, children: [
28444
+ /* @__PURE__ */ jsx46(Text44, { wrap: "truncate", children: leftBottomContent }),
28445
+ /* @__PURE__ */ jsx46(BackgroundTasksPill, {}),
28446
+ /* @__PURE__ */ jsx46(MCPHealthPill, {})
28162
28447
  ] })
28163
28448
  ] }),
28164
- /* @__PURE__ */ jsx42(Box32, { flexShrink: 0, gap: 1, alignItems: "flex-start", children: rightItems.map(({ key, node }, index) => /* @__PURE__ */ jsxs36(Box32, { alignItems: "center", children: [
28165
- index > 0 && /* @__PURE__ */ jsx42(Text40, { color: theme.text.secondary, children: " | " }),
28449
+ /* @__PURE__ */ jsx46(Box36, { flexShrink: 0, gap: 1, alignItems: "flex-start", children: rightItems.map(({ key, node }, index) => /* @__PURE__ */ jsxs40(Box36, { alignItems: "center", children: [
28450
+ index > 0 && /* @__PURE__ */ jsx46(Text44, { color: theme.text.secondary, children: " | " }),
28166
28451
  node
28167
28452
  ] }, key)) })
28168
28453
  ]
@@ -28185,17 +28470,17 @@ var QueuedMessageDisplay = ({
28185
28470
  wasEmptyRef.current = false;
28186
28471
  }
28187
28472
  const showHint = hintSeenCountRef.current <= NUM_TIMES_QUEUE_HINT_SHOWN;
28188
- return /* @__PURE__ */ jsxs37(Box33, { flexDirection: "column", marginTop: 1, children: [
28473
+ return /* @__PURE__ */ jsxs41(Box37, { flexDirection: "column", marginTop: 1, children: [
28189
28474
  messageQueue.slice(0, MAX_DISPLAYED_QUEUED_MESSAGES).map((message, index) => {
28190
28475
  const preview = message.replace(/\s+/g, " ");
28191
- return /* @__PURE__ */ jsx43(Box33, { paddingLeft: 2, width: "100%", children: /* @__PURE__ */ jsx43(Text41, { dimColor: true, wrap: "truncate", children: preview }) }, index);
28476
+ return /* @__PURE__ */ jsx47(Box37, { paddingLeft: 2, width: "100%", children: /* @__PURE__ */ jsx47(Text45, { dimColor: true, wrap: "truncate", children: preview }) }, index);
28192
28477
  }),
28193
- messageQueue.length > MAX_DISPLAYED_QUEUED_MESSAGES && /* @__PURE__ */ jsx43(Box33, { paddingLeft: 2, children: /* @__PURE__ */ jsxs37(Text41, { dimColor: true, children: [
28478
+ messageQueue.length > MAX_DISPLAYED_QUEUED_MESSAGES && /* @__PURE__ */ jsx47(Box37, { paddingLeft: 2, children: /* @__PURE__ */ jsxs41(Text45, { dimColor: true, children: [
28194
28479
  "... (+",
28195
28480
  messageQueue.length - MAX_DISPLAYED_QUEUED_MESSAGES,
28196
28481
  " more)"
28197
28482
  ] }) }),
28198
- showHint && /* @__PURE__ */ jsx43(Box33, { paddingLeft: 2, children: /* @__PURE__ */ jsx43(Text41, { dimColor: true, italic: true, children: t("Press \u2191 to edit queued messages") }) })
28483
+ showHint && /* @__PURE__ */ jsx47(Box37, { paddingLeft: 2, children: /* @__PURE__ */ jsx47(Text45, { dimColor: true, italic: true, children: t("Press \u2191 to edit queued messages") }) })
28199
28484
  ] });
28200
28485
  };
28201
28486
  var getNewlineKey = () => process.platform === "win32" ? "ctrl+enter" : "ctrl+j";
@@ -28223,8 +28508,8 @@ var getShortcuts = () => [
28223
28508
  { key: getExternalEditorKey(), description: t("for external editor") },
28224
28509
  { key: "ctrl+o", description: t("to toggle compact mode") }
28225
28510
  ];
28226
- var ShortcutItem = ({ shortcut }) => /* @__PURE__ */ jsxs38(Text42, { color: theme.text.secondary, children: [
28227
- /* @__PURE__ */ jsx44(Text42, { color: theme.text.accent, children: shortcut.key }),
28511
+ var ShortcutItem = ({ shortcut }) => /* @__PURE__ */ jsxs42(Text46, { color: theme.text.secondary, children: [
28512
+ /* @__PURE__ */ jsx48(Text46, { color: theme.text.accent, children: shortcut.key }),
28228
28513
  " ",
28229
28514
  shortcut.description
28230
28515
  ] });
@@ -28265,18 +28550,18 @@ var KeyboardShortcuts = () => {
28265
28550
  columns.push(shortcuts.slice(startIndex, startIndex + count));
28266
28551
  startIndex += count;
28267
28552
  }
28268
- return /* @__PURE__ */ jsx44(
28269
- Box34,
28553
+ return /* @__PURE__ */ jsx48(
28554
+ Box38,
28270
28555
  {
28271
28556
  flexDirection: "row",
28272
28557
  marginLeft: MARGIN_LEFT,
28273
28558
  marginRight: MARGIN_RIGHT,
28274
- children: columns.map((column, colIndex) => /* @__PURE__ */ jsx44(
28275
- Box34,
28559
+ children: columns.map((column, colIndex) => /* @__PURE__ */ jsx48(
28560
+ Box38,
28276
28561
  {
28277
28562
  flexDirection: "column",
28278
28563
  marginRight: colIndex < numColumns - 1 ? COLUMN_GAP : 0,
28279
- children: column.map((shortcut) => /* @__PURE__ */ jsx44(ShortcutItem, { shortcut }, shortcut.key))
28564
+ children: column.map((shortcut) => /* @__PURE__ */ jsx48(ShortcutItem, { shortcut }, shortcut.key))
28280
28565
  },
28281
28566
  colIndex
28282
28567
  ))
@@ -28320,8 +28605,8 @@ var Composer = () => {
28320
28605
  },
28321
28606
  [uiActions]
28322
28607
  );
28323
- return /* @__PURE__ */ jsxs39(Box35, { flexDirection: "column", marginTop: 1, children: [
28324
- !uiState.embeddedShellFocused && !suppressBottomLoadingIndicator && /* @__PURE__ */ jsx45(
28608
+ return /* @__PURE__ */ jsxs43(Box39, { flexDirection: "column", marginTop: 1, children: [
28609
+ !uiState.embeddedShellFocused && !suppressBottomLoadingIndicator && /* @__PURE__ */ jsx49(
28325
28610
  LoadingIndicator,
28326
28611
  {
28327
28612
  thought: uiState.streamingState === "waiting_for_confirmation" || config.getAccessibility()?.enableLoadingPhrases === false ? void 0 : uiState.thought,
@@ -28333,13 +28618,13 @@ var Composer = () => {
28333
28618
  isReceivingContent
28334
28619
  }
28335
28620
  ),
28336
- !uiState.embeddedShellFocused && suppressBottomLoadingIndicator && /* @__PURE__ */ jsx45(Box35, { paddingLeft: 2, children: /* @__PURE__ */ jsxs39(Text43, { color: theme.text.secondary, children: [
28621
+ !uiState.embeddedShellFocused && suppressBottomLoadingIndicator && /* @__PURE__ */ jsx49(Box39, { paddingLeft: 2, children: /* @__PURE__ */ jsxs43(Text47, { color: theme.text.secondary, children: [
28337
28622
  "(",
28338
28623
  t("Esc to cancel"),
28339
28624
  ")"
28340
28625
  ] }) }),
28341
- /* @__PURE__ */ jsx45(QueuedMessageDisplay, { messageQueue: uiState.messageQueue }),
28342
- uiState.isInputActive && /* @__PURE__ */ jsx45(
28626
+ /* @__PURE__ */ jsx49(QueuedMessageDisplay, { messageQueue: uiState.messageQueue }),
28627
+ uiState.isInputActive && /* @__PURE__ */ jsx49(
28343
28628
  InputPrompt,
28344
28629
  {
28345
28630
  buffer: uiState.buffer,
@@ -28367,7 +28652,7 @@ var Composer = () => {
28367
28652
  onPromptSuggestionDismiss: uiState.dismissPromptSuggestion
28368
28653
  }
28369
28654
  ),
28370
- uiState.isInputActive && !showSuggestions && (showShortcuts ? /* @__PURE__ */ jsx45(KeyboardShortcuts, {}) : !isScreenReaderEnabled && /* @__PURE__ */ jsx45(Footer, {}))
28655
+ uiState.isInputActive && !showSuggestions && (showShortcuts ? /* @__PURE__ */ jsx49(KeyboardShortcuts, {}) : !isScreenReaderEnabled && /* @__PURE__ */ jsx49(Footer, {}))
28371
28656
  ] });
28372
28657
  };
28373
28658
  var AppContext = createContext9(null);
@@ -28375,21 +28660,21 @@ var Notifications = () => {
28375
28660
  const appCtx = useContext11(AppContext);
28376
28661
  const warnings = appCtx?.startupWarnings ?? [];
28377
28662
  if (warnings.length === 0) return null;
28378
- return /* @__PURE__ */ jsx46(
28379
- Box36,
28663
+ return /* @__PURE__ */ jsx50(
28664
+ Box40,
28380
28665
  {
28381
28666
  flexDirection: "column",
28382
28667
  marginLeft: 2,
28383
28668
  marginRight: 2,
28384
28669
  marginBottom: 1,
28385
- children: /* @__PURE__ */ jsx46(
28386
- Box36,
28670
+ children: /* @__PURE__ */ jsx50(
28671
+ Box40,
28387
28672
  {
28388
28673
  borderStyle: "round",
28389
28674
  borderColor: theme.status.warning,
28390
28675
  paddingX: 1,
28391
28676
  flexDirection: "column",
28392
- children: warnings.map((w, i) => /* @__PURE__ */ jsxs40(Text44, { color: theme.status.warning, children: [
28677
+ children: warnings.map((w, i) => /* @__PURE__ */ jsxs44(Text48, { color: theme.status.warning, children: [
28393
28678
  "\u26A0 ",
28394
28679
  w
28395
28680
  ] }, i))
@@ -28398,6 +28683,47 @@ var Notifications = () => {
28398
28683
  }
28399
28684
  );
28400
28685
  };
28686
+ function gitExec(args, cwd) {
28687
+ return new Promise((resolve3, reject) => {
28688
+ execFile32("git", args, { cwd }, (err, stdout) => {
28689
+ if (err) reject(err);
28690
+ else resolve3(stdout.toString().trim());
28691
+ });
28692
+ });
28693
+ }
28694
+ function useGitBranchName(cwd) {
28695
+ const [branchName, setBranchName] = useState25(void 0);
28696
+ const fetchBranchName = useCallback20(async () => {
28697
+ try {
28698
+ const branch = await gitExec(["rev-parse", "--abbrev-ref", "HEAD"], cwd);
28699
+ if (branch && branch !== "HEAD") {
28700
+ setBranchName(branch);
28701
+ } else {
28702
+ const hash = await gitExec(["rev-parse", "--short", "HEAD"], cwd);
28703
+ setBranchName(hash || void 0);
28704
+ }
28705
+ } catch {
28706
+ setBranchName(void 0);
28707
+ }
28708
+ }, [cwd]);
28709
+ useEffect25(() => {
28710
+ void fetchBranchName();
28711
+ const gitLogsHeadPath = path142.join(cwd, ".git", "logs", "HEAD");
28712
+ let watcher;
28713
+ void fsPromises.access(gitLogsHeadPath, fs7.constants.F_OK).then(() => {
28714
+ watcher = fs7.watch(gitLogsHeadPath, (eventType) => {
28715
+ if (eventType === "change" || eventType === "rename") {
28716
+ void fetchBranchName();
28717
+ }
28718
+ });
28719
+ }).catch(() => {
28720
+ });
28721
+ return () => {
28722
+ watcher?.close();
28723
+ };
28724
+ }, [cwd, fetchBranchName]);
28725
+ return branchName;
28726
+ }
28401
28727
  function tildeify(p) {
28402
28728
  const home = os6.homedir();
28403
28729
  return p.startsWith(home) ? `~${p.slice(home.length)}` : p;
@@ -28426,14 +28752,17 @@ var AppHeader = ({
28426
28752
  }) => {
28427
28753
  const {
28428
28754
  streamingState,
28429
- sessionStats: { lastPromptTokenCount, lastOutputTokenCount },
28755
+ sessionStats: { lastPromptTokenCount, lastOutputTokenCount, totalPromptTokenCount, totalOutputTokenCount },
28756
+ elapsedTime,
28430
28757
  terminalWidth
28431
28758
  } = useUIState();
28759
+ const branchName = useGitBranchName(cwd);
28432
28760
  const status = statusLabel(streamingState);
28433
28761
  const displayDir = tildeify(cwd);
28434
28762
  const hasTokens = lastPromptTokenCount > 0;
28435
- return /* @__PURE__ */ jsxs41(
28436
- Box37,
28763
+ const hasSessionTokens = totalPromptTokenCount > 0;
28764
+ return /* @__PURE__ */ jsxs45(
28765
+ Box41,
28437
28766
  {
28438
28767
  flexDirection: "column",
28439
28768
  marginLeft: 2,
@@ -28441,32 +28770,35 @@ var AppHeader = ({
28441
28770
  marginTop: 1,
28442
28771
  marginBottom: 1,
28443
28772
  children: [
28444
- /* @__PURE__ */ jsxs41(Box37, { flexDirection: "row", flexWrap: "nowrap", width: terminalWidth - 4, children: [
28445
- /* @__PURE__ */ jsx47(Text45, { bold: true, color: theme.text.accent, children: "DeepCode" }),
28446
- /* @__PURE__ */ jsx47(Text45, { color: theme.text.secondary, children: ` v${version}` }),
28447
- providerLabel && /* @__PURE__ */ jsxs41(Fragment10, { children: [
28448
- /* @__PURE__ */ jsx47(Text45, { color: theme.text.secondary, children: " " }),
28449
- /* @__PURE__ */ jsx47(Text45, { color: theme.text.primary, children: providerLabel })
28773
+ /* @__PURE__ */ jsxs45(Box41, { flexDirection: "row", flexWrap: "nowrap", width: terminalWidth - 4, children: [
28774
+ /* @__PURE__ */ jsx51(Text49, { bold: true, color: theme.text.accent, children: "DeepCode" }),
28775
+ /* @__PURE__ */ jsx51(Text49, { color: theme.text.secondary, children: ` v${version}` }),
28776
+ providerLabel && /* @__PURE__ */ jsxs45(Fragment11, { children: [
28777
+ /* @__PURE__ */ jsx51(Text49, { color: theme.text.secondary, children: " " }),
28778
+ /* @__PURE__ */ jsx51(Text49, { color: theme.text.primary, children: providerLabel })
28450
28779
  ] }),
28451
- /* @__PURE__ */ jsx47(Text45, { color: theme.text.secondary, children: " " }),
28452
- /* @__PURE__ */ jsx47(
28453
- Text45,
28780
+ /* @__PURE__ */ jsx51(Text49, { color: theme.text.secondary, children: " " }),
28781
+ /* @__PURE__ */ jsx51(
28782
+ Text49,
28454
28783
  {
28455
28784
  bold: true,
28456
28785
  color: mode === "build" ? theme.status.success : theme.status.warning,
28457
28786
  children: mode.toUpperCase()
28458
28787
  }
28459
28788
  ),
28460
- /* @__PURE__ */ jsx47(Text45, { color: theme.text.secondary, children: " " }),
28461
- /* @__PURE__ */ jsx47(Text45, { color: status.color, children: status.text }),
28462
- iterationInfo && /* @__PURE__ */ jsxs41(Text45, { color: theme.text.secondary, children: [
28789
+ /* @__PURE__ */ jsx51(Text49, { color: theme.text.secondary, children: " " }),
28790
+ /* @__PURE__ */ jsxs45(Text49, { color: status.color, children: [
28791
+ status.text,
28792
+ streamingState === "responding" && elapsedTime > 0 ? ` ${elapsedTime}s` : ""
28793
+ ] }),
28794
+ iterationInfo && /* @__PURE__ */ jsxs45(Text49, { color: theme.text.secondary, children: [
28463
28795
  " ",
28464
28796
  "iter ",
28465
28797
  iterationInfo.round,
28466
28798
  "/",
28467
28799
  iterationInfo.max
28468
28800
  ] }),
28469
- hasTokens && /* @__PURE__ */ jsxs41(Text45, { color: theme.text.secondary, children: [
28801
+ hasTokens && /* @__PURE__ */ jsxs45(Text49, { color: theme.text.secondary, children: [
28470
28802
  " ",
28471
28803
  "\u2191",
28472
28804
  fmt(lastPromptTokenCount),
@@ -28474,11 +28806,270 @@ var AppHeader = ({
28474
28806
  fmt(lastOutputTokenCount)
28475
28807
  ] })
28476
28808
  ] }),
28477
- /* @__PURE__ */ jsx47(Text45, { color: theme.text.secondary, dimColor: true, children: displayDir })
28809
+ /* @__PURE__ */ jsxs45(Box41, { flexDirection: "row", children: [
28810
+ /* @__PURE__ */ jsx51(Text49, { color: theme.text.secondary, dimColor: true, children: displayDir }),
28811
+ branchName && /* @__PURE__ */ jsxs45(Text49, { color: theme.text.accent, dimColor: true, children: [
28812
+ " ",
28813
+ "(",
28814
+ branchName,
28815
+ ")"
28816
+ ] }),
28817
+ hasSessionTokens && /* @__PURE__ */ jsxs45(Text49, { color: theme.text.secondary, dimColor: true, children: [
28818
+ " ",
28819
+ "sess\xE3o \u2191",
28820
+ fmt(totalPromptTokenCount),
28821
+ " \u2193",
28822
+ fmt(totalOutputTokenCount)
28823
+ ] })
28824
+ ] })
28478
28825
  ]
28479
28826
  }
28480
28827
  );
28481
28828
  };
28829
+ var STICKY_TODO_MAX_VISIBLE_ITEMS = 5;
28830
+ var MIN_HISTORY_ITEMS_AFTER_TODO_BEFORE_STICKY = 2;
28831
+ var STICKY_TODO_ROWS_PER_VISIBLE_ITEM = 5;
28832
+ var STATUS_PRIORITY = {
28833
+ in_progress: 0,
28834
+ pending: 1,
28835
+ completed: 2
28836
+ };
28837
+ function extractTodosFromResultDisplay(resultDisplay) {
28838
+ if (!resultDisplay) return null;
28839
+ if (typeof resultDisplay === "object") {
28840
+ const candidate = resultDisplay;
28841
+ if (candidate["type"] === "todo_list" && Array.isArray(candidate["todos"])) {
28842
+ return candidate["todos"];
28843
+ }
28844
+ }
28845
+ if (typeof resultDisplay === "string") {
28846
+ try {
28847
+ const parsed = JSON.parse(resultDisplay);
28848
+ if (parsed["type"] === "todo_list" && Array.isArray(parsed["todos"])) {
28849
+ return parsed["todos"];
28850
+ }
28851
+ } catch {
28852
+ return null;
28853
+ }
28854
+ }
28855
+ return null;
28856
+ }
28857
+ function findLatestTodoSnapshot(items) {
28858
+ for (let i = items.length - 1; i >= 0; i--) {
28859
+ const item = items[i];
28860
+ if (item.type !== "tool_group") continue;
28861
+ for (let j = item.tools.length - 1; j >= 0; j--) {
28862
+ const tool = item.tools[j];
28863
+ const todos = extractTodosFromResultDisplay(tool.resultDisplay);
28864
+ if (todos) return { itemIndex: i, todos: todos.length > 0 ? todos : null };
28865
+ }
28866
+ }
28867
+ return void 0;
28868
+ }
28869
+ function getStickyTodos(history, pendingHistoryItems) {
28870
+ if (findLatestTodoSnapshot(pendingHistoryItems) !== void 0) return null;
28871
+ const snap = findLatestTodoSnapshot(history);
28872
+ if (!snap || !snap.todos) return null;
28873
+ const itemsAfter = history.length - snap.itemIndex - 1;
28874
+ if (itemsAfter < MIN_HISTORY_ITEMS_AFTER_TODO_BEFORE_STICKY) return null;
28875
+ if (snap.todos.every((t2) => t2.status === "completed")) return null;
28876
+ return snap.todos;
28877
+ }
28878
+ function getOrderedStickyTodos(todos) {
28879
+ return todos.map((todo, index) => ({ todo, index })).sort(
28880
+ (a, b) => STATUS_PRIORITY[a.todo.status] - STATUS_PRIORITY[b.todo.status] || a.index - b.index
28881
+ ).map(({ todo }) => todo);
28882
+ }
28883
+ function getStickyTodosRenderKey(todos) {
28884
+ if (!todos) return "null";
28885
+ return JSON.stringify(todos.map((t2) => [t2.id, t2.content, t2.status]));
28886
+ }
28887
+ function getStickyTodoMaxVisibleItems(terminalHeight) {
28888
+ if (!Number.isFinite(terminalHeight) || terminalHeight <= 0) {
28889
+ return STICKY_TODO_MAX_VISIBLE_ITEMS;
28890
+ }
28891
+ return Math.max(
28892
+ 1,
28893
+ Math.min(
28894
+ STICKY_TODO_MAX_VISIBLE_ITEMS,
28895
+ Math.floor(terminalHeight / STICKY_TODO_ROWS_PER_VISIBLE_ITEM)
28896
+ )
28897
+ );
28898
+ }
28899
+ var STATUS_ICONS3 = {
28900
+ pending: "\u25CB",
28901
+ in_progress: "\u25D0",
28902
+ completed: "\u25CF"
28903
+ };
28904
+ function clamp2(value) {
28905
+ if (!Number.isFinite(value)) return STICKY_TODO_MAX_VISIBLE_ITEMS;
28906
+ return Math.max(1, Math.min(STICKY_TODO_MAX_VISIBLE_ITEMS, Math.floor(value)));
28907
+ }
28908
+ var StickyTodoListComponent = ({
28909
+ todos,
28910
+ width,
28911
+ maxVisibleItems = STICKY_TODO_MAX_VISIBLE_ITEMS
28912
+ }) => {
28913
+ const ordered = useMemo12(() => getOrderedStickyTodos(todos), [todos]);
28914
+ const numberById = useMemo12(
28915
+ () => new Map(todos.map((todo, i) => [todo.id, `${i + 1}.`])),
28916
+ [todos]
28917
+ );
28918
+ if (todos.length === 0) return null;
28919
+ const visibleCount = clamp2(maxVisibleItems);
28920
+ const visible = ordered.slice(0, visibleCount);
28921
+ const hidden = ordered.length - visible.length;
28922
+ const numColWidth = Math.max(...visible.map((t2, i) => (numberById.get(t2.id) ?? `${i + 1}.`).length)) + 1;
28923
+ const contentColWidth = Math.max(1, width - numColWidth - 6);
28924
+ return /* @__PURE__ */ jsxs46(
28925
+ Box42,
28926
+ {
28927
+ marginX: 2,
28928
+ width,
28929
+ flexDirection: "column",
28930
+ borderStyle: "round",
28931
+ borderColor: theme.border.default,
28932
+ paddingX: 1,
28933
+ children: [
28934
+ /* @__PURE__ */ jsx52(Text50, { color: theme.text.secondary, bold: true, children: "Tarefas em andamento" }),
28935
+ visible.map((todo, i) => {
28936
+ const num = numberById.get(todo.id) ?? `${i + 1}.`;
28937
+ const color = todo.status === "in_progress" ? theme.status.success : theme.text.primary;
28938
+ return /* @__PURE__ */ jsxs46(Box42, { flexDirection: "row", height: 1, children: [
28939
+ /* @__PURE__ */ jsx52(Box42, { width: numColWidth, children: /* @__PURE__ */ jsx52(Text50, { color: theme.text.secondary, children: num }) }),
28940
+ /* @__PURE__ */ jsx52(Box42, { width: 2, children: /* @__PURE__ */ jsx52(Text50, { color, children: STATUS_ICONS3[todo.status] }) }),
28941
+ /* @__PURE__ */ jsx52(Box42, { width: contentColWidth, children: /* @__PURE__ */ jsx52(
28942
+ Text50,
28943
+ {
28944
+ color,
28945
+ strikethrough: todo.status === "completed",
28946
+ wrap: "truncate-end",
28947
+ children: todo.content
28948
+ }
28949
+ ) })
28950
+ ] }, todo.id);
28951
+ }),
28952
+ hidden > 0 && /* @__PURE__ */ jsxs46(Box42, { flexDirection: "row", height: 1, children: [
28953
+ /* @__PURE__ */ jsx52(Box42, { width: numColWidth }),
28954
+ /* @__PURE__ */ jsx52(Box42, { width: 2 }),
28955
+ /* @__PURE__ */ jsx52(Box42, { width: contentColWidth, children: /* @__PURE__ */ jsxs46(Text50, { color: theme.text.secondary, wrap: "truncate-end", children: [
28956
+ "... e mais ",
28957
+ hidden
28958
+ ] }) })
28959
+ ] })
28960
+ ]
28961
+ }
28962
+ );
28963
+ };
28964
+ var StickyTodoList = memo(
28965
+ StickyTodoListComponent,
28966
+ (prev, next) => prev.width === next.width && prev.maxVisibleItems === next.maxVisibleItems && getStickyTodosRenderKey(prev.todos) === getStickyTodosRenderKey(next.todos)
28967
+ );
28968
+ var useTimer = (isActive, resetKey) => {
28969
+ const [elapsedTime, setElapsedTime] = useState26(0);
28970
+ const timerRef = useRef15(null);
28971
+ const prevResetKeyRef = useRef15(resetKey);
28972
+ const prevIsActiveRef = useRef15(isActive);
28973
+ useEffect26(() => {
28974
+ let shouldReset = false;
28975
+ if (prevResetKeyRef.current !== resetKey) {
28976
+ shouldReset = true;
28977
+ prevResetKeyRef.current = resetKey;
28978
+ }
28979
+ if (!prevIsActiveRef.current && isActive) {
28980
+ shouldReset = true;
28981
+ }
28982
+ if (shouldReset) setElapsedTime(0);
28983
+ prevIsActiveRef.current = isActive;
28984
+ if (isActive) {
28985
+ if (timerRef.current) clearInterval(timerRef.current);
28986
+ timerRef.current = setInterval(() => {
28987
+ setElapsedTime((prev) => prev + 1);
28988
+ }, 1e3);
28989
+ } else {
28990
+ if (timerRef.current) {
28991
+ clearInterval(timerRef.current);
28992
+ timerRef.current = null;
28993
+ }
28994
+ }
28995
+ return () => {
28996
+ if (timerRef.current) clearInterval(timerRef.current);
28997
+ };
28998
+ }, [isActive, resetKey]);
28999
+ return elapsedTime;
29000
+ };
29001
+ var PHRASE_CHANGE_INTERVAL_MS = 15e3;
29002
+ var DEFAULT_PHRASES = [
29003
+ "Processando...",
29004
+ "Analisando o c\xF3digo...",
29005
+ "Pensando nisso...",
29006
+ "Verificando depend\xEAncias...",
29007
+ "Elaborando solu\xE7\xE3o...",
29008
+ "Checando o contexto...",
29009
+ "Refinando a resposta...",
29010
+ "Quase l\xE1...",
29011
+ "Conectando os pontos...",
29012
+ "Revisando..."
29013
+ ];
29014
+ var usePhraseCycler = (isActive, isWaiting, customPhrases) => {
29015
+ const phrases = customPhrases && customPhrases.length > 0 ? customPhrases : DEFAULT_PHRASES;
29016
+ const [phrase, setPhrase] = useState27(phrases[0] ?? "");
29017
+ const intervalRef = useRef16(null);
29018
+ useEffect27(() => {
29019
+ if (isWaiting) {
29020
+ setPhrase("Aguardando confirma\xE7\xE3o...");
29021
+ if (intervalRef.current) {
29022
+ clearInterval(intervalRef.current);
29023
+ intervalRef.current = null;
29024
+ }
29025
+ return;
29026
+ }
29027
+ if (isActive) {
29028
+ if (intervalRef.current) clearInterval(intervalRef.current);
29029
+ setPhrase(phrases[Math.floor(Math.random() * phrases.length)] ?? "");
29030
+ intervalRef.current = setInterval(() => {
29031
+ setPhrase(phrases[Math.floor(Math.random() * phrases.length)] ?? "");
29032
+ }, PHRASE_CHANGE_INTERVAL_MS);
29033
+ } else {
29034
+ if (intervalRef.current) {
29035
+ clearInterval(intervalRef.current);
29036
+ intervalRef.current = null;
29037
+ }
29038
+ setPhrase(phrases[0] ?? "");
29039
+ }
29040
+ return () => {
29041
+ if (intervalRef.current) clearInterval(intervalRef.current);
29042
+ };
29043
+ }, [isActive, isWaiting]);
29044
+ return phrase;
29045
+ };
29046
+ var useLoadingIndicator = (streamingState, customPhrases) => {
29047
+ const [timerResetKey, setTimerResetKey] = useState28(0);
29048
+ const isTimerActive = streamingState === "responding";
29049
+ const elapsedTimeFromTimer = useTimer(isTimerActive, timerResetKey);
29050
+ const isPhraseCyclingActive = streamingState === "responding";
29051
+ const isWaiting = streamingState === "waiting_for_confirmation";
29052
+ const currentLoadingPhrase = usePhraseCycler(isPhraseCyclingActive, isWaiting, customPhrases);
29053
+ const [retainedElapsedTime, setRetainedElapsedTime] = useState28(0);
29054
+ const prevStateRef = useRef17(null);
29055
+ useEffect28(() => {
29056
+ const prev = prevStateRef.current;
29057
+ if (prev === "waiting_for_confirmation" && streamingState === "responding") {
29058
+ setTimerResetKey((k) => k + 1);
29059
+ setRetainedElapsedTime(0);
29060
+ } else if (streamingState === "idle" && prev === "responding") {
29061
+ setTimerResetKey((k) => k + 1);
29062
+ setRetainedElapsedTime(0);
29063
+ } else if (streamingState === "waiting_for_confirmation") {
29064
+ setRetainedElapsedTime(elapsedTimeFromTimer);
29065
+ }
29066
+ prevStateRef.current = streamingState;
29067
+ }, [streamingState, elapsedTimeFromTimer]);
29068
+ return {
29069
+ elapsedTime: streamingState === "waiting_for_confirmation" ? retainedElapsedTime : elapsedTimeFromTimer,
29070
+ currentLoadingPhrase
29071
+ };
29072
+ };
28482
29073
  async function diffAction(context) {
28483
29074
  const { config } = context.services;
28484
29075
  if (!config) {
@@ -28750,23 +29341,23 @@ function toJson({ messages, cwd, model }) {
28750
29341
  );
28751
29342
  }
28752
29343
  function generateFilename(format, cwd) {
28753
- const dirName = path142.basename(cwd);
29344
+ const dirName = path15.basename(cwd);
28754
29345
  const ts = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
28755
29346
  const ext = format === "markdown" ? "md" : "json";
28756
29347
  return `deepcode-${dirName}-${ts}.${ext}`;
28757
29348
  }
28758
29349
  async function exportSession(opts) {
28759
29350
  const content = opts.format === "markdown" ? toMarkdown(opts) : toJson(opts);
28760
- const downloadsDir = path142.join(os7.homedir(), "Downloads");
29351
+ const downloadsDir = path15.join(os7.homedir(), "Downloads");
28761
29352
  let outputDir = opts.cwd;
28762
29353
  try {
28763
- await fs7.access(downloadsDir);
29354
+ await fs8.access(downloadsDir);
28764
29355
  outputDir = downloadsDir;
28765
29356
  } catch {
28766
29357
  }
28767
29358
  const filename = generateFilename(opts.format, opts.cwd);
28768
- const outPath = path142.join(outputDir, filename);
28769
- await fs7.writeFile(outPath, content, "utf8");
29359
+ const outPath = path15.join(outputDir, filename);
29360
+ await fs8.writeFile(outPath, content, "utf8");
28770
29361
  return outPath;
28771
29362
  }
28772
29363
  var exportCommand = {
@@ -28943,6 +29534,138 @@ var compactCommand = {
28943
29534
  await context.ui.compact();
28944
29535
  }
28945
29536
  };
29537
+ function check(category, name, status, message, detail) {
29538
+ return { category, name, status, message, detail };
29539
+ }
29540
+ function semverAtLeast(version, major) {
29541
+ const [maj] = version.replace(/^v/, "").split(".").map(Number);
29542
+ return (maj ?? 0) >= major;
29543
+ }
29544
+ function runEnvironmentChecks(cwd) {
29545
+ const results = [];
29546
+ const nodeVersion = process4.versions.node ?? "0.0.0";
29547
+ results.push(
29548
+ semverAtLeast(nodeVersion, 22) ? check("Ambiente", "Node.js", "pass", `v${nodeVersion}`) : check("Ambiente", "Node.js", "fail", `v${nodeVersion} \u2014 requer \u2265 22`, "Instale Node.js 22 ou superior")
29549
+ );
29550
+ try {
29551
+ fs9.accessSync(cwd, fs9.constants.R_OK | fs9.constants.W_OK);
29552
+ results.push(check("Ambiente", "Diret\xF3rio de trabalho", "pass", "acess\xEDvel e grav\xE1vel"));
29553
+ } catch {
29554
+ results.push(check("Ambiente", "Diret\xF3rio de trabalho", "fail", "sem acesso de leitura/escrita", cwd));
29555
+ }
29556
+ const gitDir = path16.join(cwd, ".git");
29557
+ results.push(
29558
+ fs9.existsSync(gitDir) ? check("Workspace", "Reposit\xF3rio Git", "pass", "encontrado") : check("Workspace", "Reposit\xF3rio Git", "warn", "n\xE3o encontrado", "Algumas funcionalidades requerem um reposit\xF3rio git")
29559
+ );
29560
+ const deepcodeDir = path16.join(cwd, ".deepcode");
29561
+ results.push(
29562
+ fs9.existsSync(deepcodeDir) ? check("Workspace", "Config DeepCode", "pass", ".deepcode encontrado") : check("Workspace", "Config DeepCode", "warn", ".deepcode ausente", "Execute deepcode para criar")
29563
+ );
29564
+ return results;
29565
+ }
29566
+ function runRuntimeChecks(diagnostics) {
29567
+ const results = [];
29568
+ results.push(check("Runtime", "Provider", "pass", diagnostics.provider));
29569
+ results.push(
29570
+ diagnostics.model ? check("Runtime", "Modelo", "pass", diagnostics.model) : check("Runtime", "Modelo", "warn", "n\xE3o configurado", `Execute /model para configurar um modelo para ${diagnostics.provider}`)
29571
+ );
29572
+ results.push(
29573
+ diagnostics.hasApiKey ? check("Runtime", "API Key", "pass", "configurada") : check("Runtime", "API Key", "fail", "n\xE3o configurada", `Defina a chave em /provider ou na configura\xE7\xE3o`)
29574
+ );
29575
+ if (diagnostics.mcpTotal > 0) {
29576
+ const allConnected = diagnostics.mcpConnected === diagnostics.mcpTotal;
29577
+ results.push(
29578
+ allConnected ? check("Runtime", "MCP", "pass", `${diagnostics.mcpConnected}/${diagnostics.mcpTotal} conectados`) : check("Runtime", "MCP", "warn", `${diagnostics.mcpConnected}/${diagnostics.mcpTotal} conectados`, "Alguns servidores MCP n\xE3o est\xE3o dispon\xEDveis")
29579
+ );
29580
+ }
29581
+ results.push(check("Runtime", "Modo", "pass", diagnostics.agentMode));
29582
+ return results;
29583
+ }
29584
+ var doctorCommand2 = {
29585
+ name: "doctor",
29586
+ description: "Diagn\xF3stico de ambiente e configura\xE7\xE3o do DeepCode",
29587
+ kind: "built-in",
29588
+ supportedModes: ["interactive"],
29589
+ action: (context) => {
29590
+ const cwd = context.ui.getCwd?.() ?? process4.cwd();
29591
+ const diagnostics = context.ui.getRuntimeDiagnostics?.() ?? null;
29592
+ const checks = [
29593
+ ...runEnvironmentChecks(cwd),
29594
+ ...diagnostics ? runRuntimeChecks(diagnostics) : []
29595
+ ];
29596
+ const summary = {
29597
+ pass: checks.filter((c) => c.status === "pass").length,
29598
+ warn: checks.filter((c) => c.status === "warn").length,
29599
+ fail: checks.filter((c) => c.status === "fail").length
29600
+ };
29601
+ context.ui.addItem({ type: "doctor", checks, summary }, Date.now());
29602
+ }
29603
+ };
29604
+ var DEFAULT_SHOW = 5;
29605
+ var historyCommand = {
29606
+ name: "history",
29607
+ description: "Mostra o resumo e \xFAltimos prompts da sess\xE3o atual",
29608
+ kind: "built-in",
29609
+ supportedModes: ["interactive"],
29610
+ action: (context, args) => {
29611
+ const messages = context.ui.getMessages?.() ?? [];
29612
+ const userMessages = messages.filter((m) => m.role === "user");
29613
+ const assistantMessages = messages.filter((m) => m.role === "assistant");
29614
+ const total = messages.length;
29615
+ const showN = Math.min(Number.parseInt(args?.trim() || String(DEFAULT_SHOW), 10) || DEFAULT_SHOW, userMessages.length);
29616
+ const lines = [
29617
+ `Sess\xE3o: ${total} mensagens (${userMessages.length} do usu\xE1rio, ${assistantMessages.length} do assistente)`,
29618
+ ""
29619
+ ];
29620
+ if (userMessages.length === 0) {
29621
+ lines.push("Nenhuma mensagem ainda.");
29622
+ } else {
29623
+ lines.push(`\xDAltimos ${showN} prompt${showN !== 1 ? "s" : ""}:`);
29624
+ const slice = userMessages.slice(-showN);
29625
+ for (let i = 0; i < slice.length; i++) {
29626
+ const msg = slice[i];
29627
+ const raw = msg.content;
29628
+ const content = typeof raw === "string" ? raw : Array.isArray(raw) ? raw.filter((p) => typeof p === "object" && p !== null && p["type"] === "text").map((p) => p.text).join(" ") : String(raw);
29629
+ const preview = content.replace(/\n+/g, " ").trim().slice(0, 80);
29630
+ const n = userMessages.length - showN + i + 1;
29631
+ lines.push(` ${n}. ${preview}${content.length > 80 ? "\u2026" : ""}`);
29632
+ }
29633
+ }
29634
+ context.ui.addItem({ type: "info", text: lines.join("\n") }, Date.now());
29635
+ }
29636
+ };
29637
+ function formatDurationSecs(ms) {
29638
+ const totalSecs = Math.floor(ms / 1e3);
29639
+ if (totalSecs < 60) return `${totalSecs}s`;
29640
+ const mins = Math.floor(totalSecs / 60);
29641
+ const secs = totalSecs % 60;
29642
+ if (mins < 60) return `${mins}m ${secs}s`;
29643
+ const hrs = Math.floor(mins / 60);
29644
+ return `${hrs}h ${mins % 60}m`;
29645
+ }
29646
+ var statsCommand = {
29647
+ name: "stats",
29648
+ description: "Exibe estat\xEDsticas da sess\xE3o atual (tokens, mensagens, tempo)",
29649
+ kind: "built-in",
29650
+ supportedModes: ["interactive"],
29651
+ action: (context) => {
29652
+ const messages = context.ui.getMessages?.() ?? [];
29653
+ const tokenStats = context.ui.getTokenStats?.();
29654
+ const now = Date.now();
29655
+ const startedAt = tokenStats?.sessionStartedAt ?? now;
29656
+ const duration = formatDurationSecs(now - startedAt);
29657
+ context.ui.addItem(
29658
+ {
29659
+ type: "stats",
29660
+ duration,
29661
+ promptTokens: tokenStats?.lastPromptTokens,
29662
+ outputTokens: tokenStats?.lastOutputTokens,
29663
+ messageCount: messages.length
29664
+ },
29665
+ now
29666
+ );
29667
+ }
29668
+ };
28946
29669
  var updateCommand2 = {
28947
29670
  name: "update",
28948
29671
  description: "Check published DeepCode versions",
@@ -28969,6 +29692,84 @@ var updateCommand2 = {
28969
29692
  return { type: "message", messageType: "info", content: lines.join("\n") };
28970
29693
  }
28971
29694
  };
29695
+ function memoryIndexPath(cwd) {
29696
+ const slug = cwd.replace(/\//g, "-");
29697
+ return path17.join(os8.homedir(), ".claude", "projects", slug, "memory", "MEMORY.md");
29698
+ }
29699
+ function memoryDirPath(cwd) {
29700
+ const slug = cwd.replace(/\//g, "-");
29701
+ return path17.join(os8.homedir(), ".claude", "projects", slug, "memory");
29702
+ }
29703
+ var memoryCommand = {
29704
+ name: "memory",
29705
+ description: "Mostra o \xEDndice de mem\xF3ria do projeto atual",
29706
+ kind: "built-in",
29707
+ supportedModes: ["interactive"],
29708
+ action: (context) => {
29709
+ const cwd = context.ui.getCwd?.() ?? process.cwd();
29710
+ const indexPath = memoryIndexPath(cwd);
29711
+ const memDir = memoryDirPath(cwd);
29712
+ let content;
29713
+ try {
29714
+ content = fs10.readFileSync(indexPath, "utf8").trim();
29715
+ } catch {
29716
+ const dirExists = fs10.existsSync(memDir);
29717
+ const msg = dirExists ? `Mem\xF3ria existe mas MEMORY.md n\xE3o foi encontrado em:
29718
+ ${indexPath}` : `Nenhuma mem\xF3ria encontrada para este projeto.
29719
+ Esperado em: ${indexPath}`;
29720
+ context.ui.addItem({ type: "info", text: msg }, Date.now());
29721
+ return;
29722
+ }
29723
+ if (!content) {
29724
+ context.ui.addItem({ type: "info", text: "MEMORY.md est\xE1 vazio." }, Date.now());
29725
+ return;
29726
+ }
29727
+ const fileRefs = (content.match(/\[.*?\]\(.*?\.md\)/g) ?? []).length;
29728
+ const header = `Mem\xF3ria do projeto (${fileRefs} entr${fileRefs !== 1 ? "adas" : "ada"}):
29729
+ `;
29730
+ context.ui.addItem({ type: "info", text: header + content }, Date.now());
29731
+ }
29732
+ };
29733
+ var YOLO_MODES = {
29734
+ read: "allow",
29735
+ write: "allow",
29736
+ gitLocal: "allow",
29737
+ shell: "allow",
29738
+ dangerous: "allow"
29739
+ };
29740
+ var SAFE_MODES = {
29741
+ read: "allow",
29742
+ write: "ask",
29743
+ gitLocal: "allow",
29744
+ shell: "ask",
29745
+ dangerous: "ask"
29746
+ };
29747
+ var yoloCommand = {
29748
+ name: "yolo",
29749
+ description: "Define todas as permiss\xF5es como 'allow' (sem confirma\xE7\xF5es)",
29750
+ kind: "built-in",
29751
+ supportedModes: ["interactive"],
29752
+ action: (context) => {
29753
+ context.ui.setPermissions?.(YOLO_MODES);
29754
+ context.ui.addItem(
29755
+ { type: "info", text: "Modo YOLO ativado: todas as ferramentas aprovadas automaticamente." },
29756
+ Date.now()
29757
+ );
29758
+ }
29759
+ };
29760
+ var safeCommand = {
29761
+ name: "safe",
29762
+ description: "Restaura permiss\xF5es padr\xE3o (write e shell pedem confirma\xE7\xE3o)",
29763
+ kind: "built-in",
29764
+ supportedModes: ["interactive"],
29765
+ action: (context) => {
29766
+ context.ui.setPermissions?.(SAFE_MODES);
29767
+ context.ui.addItem(
29768
+ { type: "info", text: "Permiss\xF5es restauradas: escrita e shell voltam a pedir confirma\xE7\xE3o." },
29769
+ Date.now()
29770
+ );
29771
+ }
29772
+ };
28972
29773
  function sessionNotReady() {
28973
29774
  return {
28974
29775
  type: "message",
@@ -29172,15 +29973,15 @@ var CommandDialog = ({
29172
29973
  title,
29173
29974
  lines,
29174
29975
  footerText = "Press Esc or Enter to close."
29175
- }) => /* @__PURE__ */ jsx48(Box38, { marginLeft: 2, marginRight: 2, marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsxs42(Box38, { borderStyle: "round", borderColor: theme.border.default, padding: 1, flexDirection: "column", children: [
29176
- /* @__PURE__ */ jsx48(Text46, { bold: true, color: theme.text.accent, children: title }),
29177
- /* @__PURE__ */ jsx48(Box38, { marginTop: 1, flexDirection: "column", children: lines.map((line, index) => /* @__PURE__ */ jsx48(Text46, { color: theme.text.primary, children: line }, index)) }),
29178
- /* @__PURE__ */ jsx48(Box38, { marginTop: 1, children: /* @__PURE__ */ jsx48(Text46, { color: theme.text.secondary, children: footerText }) })
29976
+ }) => /* @__PURE__ */ jsx53(Box43, { marginLeft: 2, marginRight: 2, marginTop: 1, flexDirection: "column", children: /* @__PURE__ */ jsxs47(Box43, { borderStyle: "round", borderColor: theme.border.default, padding: 1, flexDirection: "column", children: [
29977
+ /* @__PURE__ */ jsx53(Text51, { bold: true, color: theme.text.accent, children: title }),
29978
+ /* @__PURE__ */ jsx53(Box43, { marginTop: 1, flexDirection: "column", children: lines.map((line, index) => /* @__PURE__ */ jsx53(Text51, { color: theme.text.primary, children: line }, index)) }),
29979
+ /* @__PURE__ */ jsx53(Box43, { marginTop: 1, children: /* @__PURE__ */ jsx53(Text51, { color: theme.text.secondary, children: footerText }) })
29179
29980
  ] }) });
29180
29981
  var ThemeDialog = ({ onSelect, onClose, onPreview }) => {
29181
- const originalTheme = useRef15(themeManager.getActiveTheme().name);
29182
- const available = useMemo12(() => themeManager.getAvailableThemes(), []);
29183
- const items = useMemo12(
29982
+ const originalTheme = useRef18(themeManager.getActiveTheme().name);
29983
+ const available = useMemo13(() => themeManager.getAvailableThemes(), []);
29984
+ const items = useMemo13(
29184
29985
  () => available.map((entry) => ({
29185
29986
  key: entry.name,
29186
29987
  value: entry.name,
@@ -29194,7 +29995,7 @@ var ThemeDialog = ({ onSelect, onClose, onPreview }) => {
29194
29995
  0,
29195
29996
  available.findIndex((entry) => entry.name === originalTheme.current)
29196
29997
  );
29197
- const handleEscape = useCallback20(
29998
+ const handleEscape = useCallback21(
29198
29999
  (key) => {
29199
30000
  if (key.name === "escape") {
29200
30001
  themeManager.setActiveTheme(originalTheme.current);
@@ -29205,15 +30006,15 @@ var ThemeDialog = ({ onSelect, onClose, onPreview }) => {
29205
30006
  [onClose, onPreview]
29206
30007
  );
29207
30008
  useKeypress(handleEscape, { isActive: true });
29208
- const handleHighlight = useCallback20(
30009
+ const handleHighlight = useCallback21(
29209
30010
  (themeName) => {
29210
30011
  themeManager.setActiveTheme(themeName);
29211
30012
  onPreview();
29212
30013
  },
29213
30014
  [onPreview]
29214
30015
  );
29215
- return /* @__PURE__ */ jsxs43(
29216
- Box39,
30016
+ return /* @__PURE__ */ jsxs48(
30017
+ Box44,
29217
30018
  {
29218
30019
  flexDirection: "column",
29219
30020
  borderStyle: "round",
@@ -29222,8 +30023,8 @@ var ThemeDialog = ({ onSelect, onClose, onPreview }) => {
29222
30023
  marginLeft: 2,
29223
30024
  marginRight: 2,
29224
30025
  children: [
29225
- /* @__PURE__ */ jsx49(Text47, { bold: true, color: theme.text.accent, children: "Select theme" }),
29226
- /* @__PURE__ */ jsx49(
30026
+ /* @__PURE__ */ jsx54(Text52, { bold: true, color: theme.text.accent, children: "Select theme" }),
30027
+ /* @__PURE__ */ jsx54(
29227
30028
  RadioButtonSelect,
29228
30029
  {
29229
30030
  items,
@@ -29233,7 +30034,7 @@ var ThemeDialog = ({ onSelect, onClose, onPreview }) => {
29233
30034
  isFocused: true
29234
30035
  }
29235
30036
  ),
29236
- /* @__PURE__ */ jsx49(Text47, { color: theme.text.secondary, children: "\u2191\u2193 navigate \xB7 Enter apply \xB7 Esc cancel" })
30037
+ /* @__PURE__ */ jsx54(Text52, { color: theme.text.secondary, children: "\u2191\u2193 navigate \xB7 Enter apply \xB7 Esc cancel" })
29237
30038
  ]
29238
30039
  }
29239
30040
  );
@@ -29270,17 +30071,17 @@ var ProviderDialog = ({
29270
30071
  onTestProvider,
29271
30072
  onClose
29272
30073
  }) => {
29273
- const [phase, setPhase] = useState25("providers");
29274
- const [selectedProvider, setSelectedProvider] = useState25(currentProvider);
29275
- const [apiKeyInput, setApiKeyInput] = useState25("");
29276
- const [isBusy, setIsBusy] = useState25(false);
29277
- const [status, setStatus] = useState25(null);
29278
- const [testLatencyMs, setTestLatencyMs] = useState25(void 0);
30074
+ const [phase, setPhase] = useState29("providers");
30075
+ const [selectedProvider, setSelectedProvider] = useState29(currentProvider);
30076
+ const [apiKeyInput, setApiKeyInput] = useState29("");
30077
+ const [isBusy, setIsBusy] = useState29(false);
30078
+ const [status, setStatus] = useState29(null);
30079
+ const [testLatencyMs, setTestLatencyMs] = useState29(void 0);
29279
30080
  const isLocal = CREDENTIAL_FREE_PROVIDERS.has(selectedProvider);
29280
30081
  const keyIsSet = hasApiKey(selectedProvider);
29281
30082
  const keyHint = getProviderKeyHint(selectedProvider);
29282
30083
  const canTest = keyIsSet || isLocal;
29283
- const providerItems = useMemo13(
30084
+ const providerItems = useMemo14(
29284
30085
  () => providers.map((p) => ({
29285
30086
  key: p,
29286
30087
  value: p,
@@ -29291,7 +30092,7 @@ var ProviderDialog = ({
29291
30092
  })),
29292
30093
  [currentProvider, hasApiKey, providers]
29293
30094
  );
29294
- const actionItems = useMemo13(
30095
+ const actionItems = useMemo14(
29295
30096
  () => [
29296
30097
  {
29297
30098
  key: "use",
@@ -29334,7 +30135,7 @@ var ProviderDialog = ({
29334
30135
  ],
29335
30136
  [canTest, currentProvider, isLocal, selectedProvider]
29336
30137
  );
29337
- const selectProvider = useCallback21(
30138
+ const selectProvider = useCallback22(
29338
30139
  (provider) => {
29339
30140
  setSelectedProvider(provider);
29340
30141
  setStatus(null);
@@ -29343,7 +30144,7 @@ var ProviderDialog = ({
29343
30144
  },
29344
30145
  []
29345
30146
  );
29346
- const runTest = useCallback21(async () => {
30147
+ const runTest = useCallback22(async () => {
29347
30148
  setIsBusy(true);
29348
30149
  setTestLatencyMs(void 0);
29349
30150
  setStatus({ text: `Testing ${selectedProvider}\u2026`, ok: true });
@@ -29365,7 +30166,7 @@ var ProviderDialog = ({
29365
30166
  setIsBusy(false);
29366
30167
  }
29367
30168
  }, [onTestProvider, selectedProvider]);
29368
- const selectAction = useCallback21(
30169
+ const selectAction = useCallback22(
29369
30170
  (action) => {
29370
30171
  if (isBusy) return;
29371
30172
  if (action === "editKey") {
@@ -29406,7 +30207,7 @@ var ProviderDialog = ({
29406
30207
  },
29407
30208
  [isBusy, onClose, onSelectProvider, onSetDefaultProvider, runTest, selectedProvider]
29408
30209
  );
29409
- const saveApiKey = useCallback21(async () => {
30210
+ const saveApiKey = useCallback22(async () => {
29410
30211
  const normalized2 = apiKeyInput.trim();
29411
30212
  if (!normalized2) {
29412
30213
  setStatus({ text: "Type a key before saving.", ok: false });
@@ -29463,8 +30264,8 @@ var ProviderDialog = ({
29463
30264
  );
29464
30265
  const statusColor2 = status ? status.ok ? status.text.startsWith("\u2713") ? theme.status.success : theme.text.secondary : theme.status.error : void 0;
29465
30266
  const footer = phase === "apiKey" ? "Enter save Ctrl+U clear Esc cancel" : phase === "providers" ? "\u2191\u2193 navigate Enter select Esc close" : "\u2191\u2193 navigate Enter confirm Esc back";
29466
- return /* @__PURE__ */ jsxs44(
29467
- Box40,
30267
+ return /* @__PURE__ */ jsxs49(
30268
+ Box45,
29468
30269
  {
29469
30270
  flexDirection: "column",
29470
30271
  borderStyle: "round",
@@ -29475,19 +30276,19 @@ var ProviderDialog = ({
29475
30276
  marginRight: 2,
29476
30277
  minWidth: 44,
29477
30278
  children: [
29478
- /* @__PURE__ */ jsxs44(Box40, { marginBottom: 1, gap: 1, children: [
29479
- /* @__PURE__ */ jsx50(Text48, { bold: true, color: theme.text.accent, children: "Providers" }),
29480
- phase !== "providers" && /* @__PURE__ */ jsxs44(Fragment11, { children: [
29481
- /* @__PURE__ */ jsx50(Text48, { color: theme.text.secondary, children: "\u203A" }),
29482
- /* @__PURE__ */ jsx50(Text48, { bold: true, color: theme.text.primary, children: selectedProvider })
30279
+ /* @__PURE__ */ jsxs49(Box45, { marginBottom: 1, gap: 1, children: [
30280
+ /* @__PURE__ */ jsx55(Text53, { bold: true, color: theme.text.accent, children: "Providers" }),
30281
+ phase !== "providers" && /* @__PURE__ */ jsxs49(Fragment12, { children: [
30282
+ /* @__PURE__ */ jsx55(Text53, { color: theme.text.secondary, children: "\u203A" }),
30283
+ /* @__PURE__ */ jsx55(Text53, { bold: true, color: theme.text.primary, children: selectedProvider })
29483
30284
  ] }),
29484
- phase === "providers" && currentModel && /* @__PURE__ */ jsxs44(Text48, { color: theme.text.secondary, children: [
30285
+ phase === "providers" && currentModel && /* @__PURE__ */ jsxs49(Text53, { color: theme.text.secondary, children: [
29485
30286
  " (",
29486
30287
  currentModel,
29487
30288
  ")"
29488
30289
  ] })
29489
30290
  ] }),
29490
- phase === "providers" && /* @__PURE__ */ jsx50(
30291
+ phase === "providers" && /* @__PURE__ */ jsx55(
29491
30292
  BaseSelectionList,
29492
30293
  {
29493
30294
  items: providerItems,
@@ -29497,25 +30298,25 @@ var ProviderDialog = ({
29497
30298
  maxItemsToShow: 8,
29498
30299
  renderItem: (item, { titleColor }) => {
29499
30300
  const { icon, color, label } = getStatusMark(item.provider, item.keyIsSet);
29500
- return /* @__PURE__ */ jsxs44(Box40, { gap: 1, children: [
29501
- /* @__PURE__ */ jsx50(Text48, { color, children: icon }),
29502
- /* @__PURE__ */ jsx50(Text48, { color: titleColor, bold: item.isCurrent, children: item.provider.padEnd(12) }),
29503
- /* @__PURE__ */ jsx50(Text48, { color, dimColor: !item.keyIsSet && !item.isLocal, children: label }),
29504
- item.isCurrent && /* @__PURE__ */ jsx50(Text48, { color: theme.text.accent, children: "\u25B6" })
30301
+ return /* @__PURE__ */ jsxs49(Box45, { gap: 1, children: [
30302
+ /* @__PURE__ */ jsx55(Text53, { color, children: icon }),
30303
+ /* @__PURE__ */ jsx55(Text53, { color: titleColor, bold: item.isCurrent, children: item.provider.padEnd(12) }),
30304
+ /* @__PURE__ */ jsx55(Text53, { color, dimColor: !item.keyIsSet && !item.isLocal, children: label }),
30305
+ item.isCurrent && /* @__PURE__ */ jsx55(Text53, { color: theme.text.accent, children: "\u25B6" })
29505
30306
  ] });
29506
30307
  }
29507
30308
  }
29508
30309
  ),
29509
- phase === "actions" && /* @__PURE__ */ jsxs44(Fragment11, { children: [
29510
- /* @__PURE__ */ jsxs44(Box40, { marginBottom: 1, gap: 1, children: [
29511
- /* @__PURE__ */ jsx50(Text48, { color: theme.ui.comment, children: "session" }),
29512
- /* @__PURE__ */ jsx50(Text48, { color: selectedProvider === currentProvider ? theme.text.accent : theme.text.secondary, children: selectedProvider === currentProvider ? "active" : `still using ${currentProvider}` })
30310
+ phase === "actions" && /* @__PURE__ */ jsxs49(Fragment12, { children: [
30311
+ /* @__PURE__ */ jsxs49(Box45, { marginBottom: 1, gap: 1, children: [
30312
+ /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, children: "session" }),
30313
+ /* @__PURE__ */ jsx55(Text53, { color: selectedProvider === currentProvider ? theme.text.accent : theme.text.secondary, children: selectedProvider === currentProvider ? "active" : `still using ${currentProvider}` })
29513
30314
  ] }),
29514
- /* @__PURE__ */ jsxs44(Box40, { marginBottom: 1, gap: 1, children: [
29515
- /* @__PURE__ */ jsx50(Text48, { color: theme.ui.comment, children: "key" }),
29516
- isLocal ? /* @__PURE__ */ jsx50(Text48, { color: theme.text.accent, children: "no key required" }) : keyHint ? /* @__PURE__ */ jsx50(Text48, { color: theme.text.secondary, children: keyHint }) : /* @__PURE__ */ jsx50(Text48, { color: theme.ui.comment, dimColor: true, children: "not configured" })
30315
+ /* @__PURE__ */ jsxs49(Box45, { marginBottom: 1, gap: 1, children: [
30316
+ /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, children: "key" }),
30317
+ isLocal ? /* @__PURE__ */ jsx55(Text53, { color: theme.text.accent, children: "no key required" }) : keyHint ? /* @__PURE__ */ jsx55(Text53, { color: theme.text.secondary, children: keyHint }) : /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: "not configured" })
29517
30318
  ] }),
29518
- /* @__PURE__ */ jsx50(
30319
+ /* @__PURE__ */ jsx55(
29519
30320
  BaseSelectionList,
29520
30321
  {
29521
30322
  items: actionItems,
@@ -29523,10 +30324,10 @@ var ProviderDialog = ({
29523
30324
  isFocused: !isBusy,
29524
30325
  showNumbers: false,
29525
30326
  maxItemsToShow: 6,
29526
- renderItem: (item, { titleColor }) => /* @__PURE__ */ jsxs44(Box40, { gap: 1, children: [
29527
- /* @__PURE__ */ jsx50(Text48, { color: titleColor, children: item.icon }),
29528
- /* @__PURE__ */ jsx50(Text48, { color: titleColor, children: item.label }),
29529
- item.hint && /* @__PURE__ */ jsxs44(Text48, { color: theme.ui.comment, dimColor: true, children: [
30327
+ renderItem: (item, { titleColor }) => /* @__PURE__ */ jsxs49(Box45, { gap: 1, children: [
30328
+ /* @__PURE__ */ jsx55(Text53, { color: titleColor, children: item.icon }),
30329
+ /* @__PURE__ */ jsx55(Text53, { color: titleColor, children: item.label }),
30330
+ item.hint && /* @__PURE__ */ jsxs49(Text53, { color: theme.ui.comment, dimColor: true, children: [
29530
30331
  "(",
29531
30332
  item.hint,
29532
30333
  ")"
@@ -29535,26 +30336,26 @@ var ProviderDialog = ({
29535
30336
  }
29536
30337
  )
29537
30338
  ] }),
29538
- phase === "apiKey" && /* @__PURE__ */ jsxs44(Box40, { flexDirection: "column", gap: 1, marginBottom: 1, children: [
29539
- /* @__PURE__ */ jsxs44(Box40, { gap: 1, children: [
29540
- /* @__PURE__ */ jsx50(Text48, { color: theme.ui.comment, children: "current" }),
29541
- isLocal ? /* @__PURE__ */ jsx50(Text48, { color: theme.text.accent, children: "no key required" }) : keyHint ? /* @__PURE__ */ jsx50(Text48, { color: theme.text.secondary, children: keyHint }) : /* @__PURE__ */ jsx50(Text48, { color: theme.ui.comment, dimColor: true, children: "not set" })
30339
+ phase === "apiKey" && /* @__PURE__ */ jsxs49(Box45, { flexDirection: "column", gap: 1, marginBottom: 1, children: [
30340
+ /* @__PURE__ */ jsxs49(Box45, { gap: 1, children: [
30341
+ /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, children: "current" }),
30342
+ isLocal ? /* @__PURE__ */ jsx55(Text53, { color: theme.text.accent, children: "no key required" }) : keyHint ? /* @__PURE__ */ jsx55(Text53, { color: theme.text.secondary, children: keyHint }) : /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: "not set" })
29542
30343
  ] }),
29543
- /* @__PURE__ */ jsxs44(Box40, { gap: 1, children: [
29544
- /* @__PURE__ */ jsx50(Text48, { color: theme.ui.comment, children: "new key" }),
29545
- /* @__PURE__ */ jsx50(Box40, { borderStyle: "single", borderColor: theme.border.focused, paddingX: 1, children: /* @__PURE__ */ jsx50(Text48, { color: theme.text.accent, children: apiKeyInput.length > 0 ? maskApiKeyInput(apiKeyInput.length) : /* @__PURE__ */ jsx50(Text48, { color: theme.ui.comment, dimColor: true, children: "paste or type\u2026" }) }) })
30344
+ /* @__PURE__ */ jsxs49(Box45, { gap: 1, children: [
30345
+ /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, children: "new key" }),
30346
+ /* @__PURE__ */ jsx55(Box45, { borderStyle: "single", borderColor: theme.border.focused, paddingX: 1, children: /* @__PURE__ */ jsx55(Text53, { color: theme.text.accent, children: apiKeyInput.length > 0 ? maskApiKeyInput(apiKeyInput.length) : /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: "paste or type\u2026" }) }) })
29546
30347
  ] })
29547
30348
  ] }),
29548
- status && /* @__PURE__ */ jsx50(Box40, { marginTop: 1, children: /* @__PURE__ */ jsx50(Text48, { color: statusColor2, children: status.text }) }),
29549
- phase === "actions" && testLatencyMs !== void 0 && /* @__PURE__ */ jsxs44(Box40, { marginTop: 0, gap: 1, children: [
29550
- /* @__PURE__ */ jsxs44(Text48, { color: getLatencyColor(testLatencyMs), bold: true, children: [
30349
+ status && /* @__PURE__ */ jsx55(Box45, { marginTop: 1, children: /* @__PURE__ */ jsx55(Text53, { color: statusColor2, children: status.text }) }),
30350
+ phase === "actions" && testLatencyMs !== void 0 && /* @__PURE__ */ jsxs49(Box45, { marginTop: 0, gap: 1, children: [
30351
+ /* @__PURE__ */ jsxs49(Text53, { color: getLatencyColor(testLatencyMs), bold: true, children: [
29551
30352
  testLatencyMs,
29552
30353
  "ms"
29553
30354
  ] }),
29554
- /* @__PURE__ */ jsx50(Text48, { color: theme.text.secondary, children: testLatencyMs < 300 ? "excellent" : testLatencyMs < 800 ? "good" : "slow" })
30355
+ /* @__PURE__ */ jsx55(Text53, { color: theme.text.secondary, children: testLatencyMs < 300 ? "excellent" : testLatencyMs < 800 ? "good" : "slow" })
29555
30356
  ] }),
29556
- /* @__PURE__ */ jsx50(
29557
- Box40,
30357
+ /* @__PURE__ */ jsx55(
30358
+ Box45,
29558
30359
  {
29559
30360
  marginTop: 1,
29560
30361
  borderStyle: "single",
@@ -29563,7 +30364,7 @@ var ProviderDialog = ({
29563
30364
  borderLeft: false,
29564
30365
  borderRight: false,
29565
30366
  borderColor: theme.ui.comment,
29566
- children: /* @__PURE__ */ jsxs44(Text48, { color: theme.ui.comment, dimColor: true, children: [
30367
+ children: /* @__PURE__ */ jsxs49(Text53, { color: theme.ui.comment, dimColor: true, children: [
29567
30368
  footer,
29568
30369
  phase === "actions" && " Test does not change the session."
29569
30370
  ] })
@@ -29581,58 +30382,64 @@ var PERMISSION_KEYS = [
29581
30382
  "dangerous"
29582
30383
  ];
29583
30384
  var MODE_CYCLE = ["allow", "ask", "deny"];
29584
- var SAVE_VALUE = "__save__";
29585
- var CANCEL_VALUE = "__cancel__";
30385
+ var ACTIONS3 = ["save", "cancel"];
30386
+ var ALL_ROWS = [...PERMISSION_KEYS, ...ACTIONS3];
29586
30387
  function nextMode(mode) {
29587
30388
  const index = MODE_CYCLE.indexOf(mode);
29588
30389
  return MODE_CYCLE[(index + 1) % MODE_CYCLE.length];
29589
30390
  }
30391
+ function modeColor(mode) {
30392
+ if (mode === "allow") return theme.status.success;
30393
+ if (mode === "deny") return theme.status.error;
30394
+ return theme.status.warning;
30395
+ }
30396
+ var KEY_LABEL = {
30397
+ read: "read",
30398
+ write: "write",
30399
+ gitLocal: "git local",
30400
+ shell: "shell",
30401
+ dangerous: "dangerous"
30402
+ };
29590
30403
  var PermissionsDialog = ({
29591
30404
  current,
29592
30405
  onSave,
29593
30406
  onClose
29594
30407
  }) => {
29595
- const [modes, setModes] = useState26(current);
29596
- const dirty = useMemo14(
29597
- () => PERMISSION_KEYS.some((key) => modes[key] !== current[key]),
29598
- [modes, current]
29599
- );
29600
- const items = useMemo14(() => {
29601
- const rows = PERMISSION_KEYS.map((key) => ({
29602
- key,
29603
- value: key,
29604
- label: `${key.padEnd(10)} ${modes[key]}`
29605
- }));
29606
- rows.push({ key: SAVE_VALUE, value: SAVE_VALUE, label: dirty ? "Save changes" : "Save changes (no edits)" });
29607
- rows.push({ key: CANCEL_VALUE, value: CANCEL_VALUE, label: "Cancel" });
29608
- return rows;
29609
- }, [modes, dirty]);
29610
- const handleSelect = useCallback22(
29611
- (value) => {
29612
- if (value === SAVE_VALUE) {
29613
- onSave(modes);
30408
+ const [modes, setModes] = useState30(current);
30409
+ const [focusIndex, setFocusIndex] = useState30(0);
30410
+ const dirty = PERMISSION_KEYS.some((k) => modes[k] !== current[k]);
30411
+ const handleKey = useCallback23(
30412
+ (key) => {
30413
+ if (key.name === "escape") {
30414
+ onClose();
29614
30415
  return;
29615
30416
  }
29616
- if (value === CANCEL_VALUE) {
29617
- onClose();
30417
+ if (key.name === "up" || key.ctrl && key.name === "p") {
30418
+ setFocusIndex((i) => (i - 1 + ALL_ROWS.length) % ALL_ROWS.length);
29618
30419
  return;
29619
30420
  }
29620
- const key = value;
29621
- setModes((prev) => ({ ...prev, [key]: nextMode(prev[key]) }));
29622
- },
29623
- [modes, onClose, onSave]
29624
- );
29625
- const handleEscape = useCallback22(
29626
- (key) => {
29627
- if (key.name === "escape") {
29628
- onClose();
30421
+ if (key.name === "down" || key.ctrl && key.name === "n") {
30422
+ setFocusIndex((i) => (i + 1) % ALL_ROWS.length);
30423
+ return;
30424
+ }
30425
+ if (key.name === "return") {
30426
+ const row = ALL_ROWS[focusIndex];
30427
+ if (row === "save") {
30428
+ onSave(modes);
30429
+ return;
30430
+ }
30431
+ if (row === "cancel") {
30432
+ onClose();
30433
+ return;
30434
+ }
30435
+ setModes((prev) => ({ ...prev, [row]: nextMode(prev[row]) }));
29629
30436
  }
29630
30437
  },
29631
- [onClose]
30438
+ [focusIndex, modes, onClose, onSave]
29632
30439
  );
29633
- useKeypress(handleEscape, { isActive: true });
29634
- return /* @__PURE__ */ jsxs45(
29635
- Box41,
30440
+ useKeypress(handleKey, { isActive: true });
30441
+ return /* @__PURE__ */ jsxs50(
30442
+ Box46,
29636
30443
  {
29637
30444
  flexDirection: "column",
29638
30445
  borderStyle: "round",
@@ -29641,9 +30448,25 @@ var PermissionsDialog = ({
29641
30448
  marginLeft: 2,
29642
30449
  marginRight: 2,
29643
30450
  children: [
29644
- /* @__PURE__ */ jsx51(Text49, { bold: true, color: theme.text.accent, children: "Permission policy" }),
29645
- /* @__PURE__ */ jsx51(RadioButtonSelect, { items, onSelect: handleSelect, isFocused: true, showNumbers: false }),
29646
- /* @__PURE__ */ jsx51(Text49, { color: theme.text.secondary, children: "\u2191\u2193 navigate \xB7 Enter cycles allow/ask/deny \xB7 Esc cancel" })
30451
+ /* @__PURE__ */ jsx56(Text54, { bold: true, color: theme.text.accent, children: "Permission policy" }),
30452
+ PERMISSION_KEYS.map((key, i) => {
30453
+ const focused = focusIndex === i;
30454
+ const mode = modes[key];
30455
+ return /* @__PURE__ */ jsxs50(Box46, { flexDirection: "row", gap: 1, children: [
30456
+ /* @__PURE__ */ jsx56(Text54, { color: focused ? theme.text.accent : theme.text.secondary, children: focused ? "\u203A" : " " }),
30457
+ /* @__PURE__ */ jsx56(Text54, { color: focused ? theme.text.primary : theme.text.secondary, bold: focused, children: KEY_LABEL[key].padEnd(10) }),
30458
+ /* @__PURE__ */ jsx56(Text54, { color: modeColor(mode), bold: focused, children: mode })
30459
+ ] }, key);
30460
+ }),
30461
+ /* @__PURE__ */ jsx56(Box46, { marginTop: 1, flexDirection: "column", children: ACTIONS3.map((action, i) => {
30462
+ const focused = focusIndex === PERMISSION_KEYS.length + i;
30463
+ const label = action === "save" ? dirty ? "Save changes" : "Save changes (no edits)" : "Cancel";
30464
+ return /* @__PURE__ */ jsxs50(Box46, { flexDirection: "row", gap: 1, children: [
30465
+ /* @__PURE__ */ jsx56(Text54, { color: focused ? theme.text.accent : theme.text.secondary, children: focused ? "\u203A" : " " }),
30466
+ /* @__PURE__ */ jsx56(Text54, { color: focused ? theme.text.primary : theme.text.secondary, bold: focused, children: label })
30467
+ ] }, action);
30468
+ }) }),
30469
+ /* @__PURE__ */ jsx56(Text54, { color: theme.text.secondary, dimColor: true, children: "\u2191\u2193 navigate \xB7 Enter cycles allow/ask/deny or selects action \xB7 Esc cancel" })
29647
30470
  ]
29648
30471
  }
29649
30472
  );
@@ -29658,10 +30481,10 @@ var AuthDialog = ({
29658
30481
  onPersistToken,
29659
30482
  onClose
29660
30483
  }) => {
29661
- const [phase, setPhase] = useState27("menu");
29662
- const [deviceCode, setDeviceCode] = useState27(null);
29663
- const [message, setMessage] = useState27("");
29664
- const abortRef = useRef16(null);
30484
+ const [phase, setPhase] = useState31("menu");
30485
+ const [deviceCode, setDeviceCode] = useState31(null);
30486
+ const [message, setMessage] = useState31("");
30487
+ const abortRef = useRef19(null);
29665
30488
  const items = useMemo15(
29666
30489
  () => [
29667
30490
  { key: "login", value: "login", label: "Login with GitHub" },
@@ -29670,7 +30493,7 @@ var AuthDialog = ({
29670
30493
  ],
29671
30494
  [hasToken]
29672
30495
  );
29673
- const startLogin = useCallback23(async () => {
30496
+ const startLogin = useCallback24(async () => {
29674
30497
  if (!clientId) {
29675
30498
  setMessage(
29676
30499
  "No OAuth client configured. Set github.oauthClientId in .deepcode/config.json, or run `deepcode github login` in a terminal."
@@ -29714,7 +30537,7 @@ var AuthDialog = ({
29714
30537
  abortRef.current = null;
29715
30538
  }
29716
30539
  }, [clientId, enterpriseUrl, onPersistToken, scopes, worktree]);
29717
- const clearToken = useCallback23(async () => {
30540
+ const clearToken = useCallback24(async () => {
29718
30541
  try {
29719
30542
  await onPersistToken(void 0);
29720
30543
  setPhase("done");
@@ -29724,7 +30547,7 @@ var AuthDialog = ({
29724
30547
  setMessage(error instanceof Error ? error.message : String(error));
29725
30548
  }
29726
30549
  }, [onPersistToken]);
29727
- const handleSelect = useCallback23(
30550
+ const handleSelect = useCallback24(
29728
30551
  (value) => {
29729
30552
  if (value === "login") {
29730
30553
  void startLogin();
@@ -29736,10 +30559,10 @@ var AuthDialog = ({
29736
30559
  },
29737
30560
  [clearToken, onClose, startLogin]
29738
30561
  );
29739
- useEffect25(() => () => {
30562
+ useEffect29(() => () => {
29740
30563
  abortRef.current?.abort();
29741
30564
  }, []);
29742
- const handleEscape = useCallback23(
30565
+ const handleEscape = useCallback24(
29743
30566
  (key) => {
29744
30567
  if (key.name !== "escape") return;
29745
30568
  if (phase === "running") {
@@ -29751,8 +30574,8 @@ var AuthDialog = ({
29751
30574
  [onClose, phase]
29752
30575
  );
29753
30576
  useKeypress(handleEscape, { isActive: true });
29754
- return /* @__PURE__ */ jsxs46(
29755
- Box42,
30577
+ return /* @__PURE__ */ jsxs51(
30578
+ Box47,
29756
30579
  {
29757
30580
  flexDirection: "column",
29758
30581
  borderStyle: "round",
@@ -29761,32 +30584,32 @@ var AuthDialog = ({
29761
30584
  marginLeft: 2,
29762
30585
  marginRight: 2,
29763
30586
  children: [
29764
- /* @__PURE__ */ jsx52(Text50, { bold: true, color: theme.text.accent, children: "GitHub authentication" }),
29765
- /* @__PURE__ */ jsx52(Text50, { color: theme.text.secondary, children: statusSummary }),
29766
- phase === "menu" && /* @__PURE__ */ jsx52(RadioButtonSelect, { items, onSelect: handleSelect, isFocused: true, showNumbers: false }),
29767
- deviceCode && phase === "running" && /* @__PURE__ */ jsxs46(Box42, { flexDirection: "column", marginTop: 1, children: [
29768
- /* @__PURE__ */ jsxs46(Text50, { children: [
30587
+ /* @__PURE__ */ jsx57(Text55, { bold: true, color: theme.text.accent, children: "GitHub authentication" }),
30588
+ /* @__PURE__ */ jsx57(Text55, { color: theme.text.secondary, children: statusSummary }),
30589
+ phase === "menu" && /* @__PURE__ */ jsx57(RadioButtonSelect, { items, onSelect: handleSelect, isFocused: true, showNumbers: false }),
30590
+ deviceCode && phase === "running" && /* @__PURE__ */ jsxs51(Box47, { flexDirection: "column", marginTop: 1, children: [
30591
+ /* @__PURE__ */ jsxs51(Text55, { children: [
29769
30592
  "Open: ",
29770
- /* @__PURE__ */ jsx52(Text50, { color: theme.text.accent, children: deviceCode.verificationUri })
30593
+ /* @__PURE__ */ jsx57(Text55, { color: theme.text.accent, children: deviceCode.verificationUri })
29771
30594
  ] }),
29772
- /* @__PURE__ */ jsxs46(Text50, { children: [
30595
+ /* @__PURE__ */ jsxs51(Text55, { children: [
29773
30596
  "Code: ",
29774
- /* @__PURE__ */ jsx52(Text50, { bold: true, color: theme.text.accent, children: deviceCode.userCode })
30597
+ /* @__PURE__ */ jsx57(Text55, { bold: true, color: theme.text.accent, children: deviceCode.userCode })
29775
30598
  ] }),
29776
- /* @__PURE__ */ jsxs46(Text50, { color: theme.text.secondary, children: [
30599
+ /* @__PURE__ */ jsxs51(Text55, { color: theme.text.secondary, children: [
29777
30600
  "Expires in ",
29778
30601
  Math.round(deviceCode.expiresIn / 60),
29779
30602
  " minutes."
29780
30603
  ] })
29781
30604
  ] }),
29782
- message && /* @__PURE__ */ jsx52(
29783
- Text50,
30605
+ message && /* @__PURE__ */ jsx57(
30606
+ Text55,
29784
30607
  {
29785
30608
  color: phase === "error" ? theme.status.error : phase === "done" ? theme.status.success : theme.text.secondary,
29786
30609
  children: message
29787
30610
  }
29788
30611
  ),
29789
- /* @__PURE__ */ jsx52(Text50, { color: theme.text.secondary, children: phase === "running" ? "Esc cancel login" : phase === "menu" ? "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc close" : "Esc close" })
30612
+ /* @__PURE__ */ jsx57(Text55, { color: theme.text.secondary, children: phase === "running" ? "Esc cancel login" : phase === "menu" ? "\u2191\u2193 navigate \xB7 Enter select \xB7 Esc close" : "Esc close" })
29790
30613
  ]
29791
30614
  }
29792
30615
  );
@@ -29832,13 +30655,13 @@ var ModelDialog = ({
29832
30655
  onSelectModel,
29833
30656
  onClose
29834
30657
  }) => {
29835
- const [loadState, setLoadState] = useState28("loading");
29836
- const [models, setModels] = useState28([]);
29837
- const [errorMsg, setErrorMsg] = useState28("");
29838
- const [search, setSearch] = useState28("");
29839
- const [activeSelIndex, setActiveSelIndex] = useState28(0);
29840
- const abortRef = useRef17(null);
29841
- useEffect26(() => {
30658
+ const [loadState, setLoadState] = useState32("loading");
30659
+ const [models, setModels] = useState32([]);
30660
+ const [errorMsg, setErrorMsg] = useState32("");
30661
+ const [search, setSearch] = useState32("");
30662
+ const [activeSelIndex, setActiveSelIndex] = useState32(0);
30663
+ const abortRef = useRef20(null);
30664
+ useEffect30(() => {
29842
30665
  const ctrl = new AbortController();
29843
30666
  abortRef.current = ctrl;
29844
30667
  onFetchModels(currentProvider, ctrl.signal).then((fetched) => {
@@ -29858,7 +30681,7 @@ var ModelDialog = ({
29858
30681
  );
29859
30682
  const selectableCount = rows.filter((r) => r.kind === "item").length;
29860
30683
  const clampedIndex = Math.min(activeSelIndex, Math.max(0, selectableCount - 1));
29861
- useEffect26(() => {
30684
+ useEffect30(() => {
29862
30685
  setActiveSelIndex(0);
29863
30686
  }, [search]);
29864
30687
  const activeRowPos = useMemo16(
@@ -29870,7 +30693,7 @@ var ModelDialog = ({
29870
30693
  [activeRowPos, rows.length]
29871
30694
  );
29872
30695
  const visibleRows = rows.slice(scrollTop, scrollTop + MAX_VISIBLE);
29873
- const confirm = useCallback24(() => {
30696
+ const confirm = useCallback25(() => {
29874
30697
  const row = rows.find((r) => r.kind === "item" && r.selIndex === clampedIndex);
29875
30698
  if (row?.kind === "item") onSelectModel(row.model.id);
29876
30699
  }, [rows, clampedIndex, onSelectModel]);
@@ -29913,8 +30736,8 @@ var ModelDialog = ({
29913
30736
  }, { isActive: true });
29914
30737
  const canScrollUp = scrollTop > 0;
29915
30738
  const canScrollDown = scrollTop + MAX_VISIBLE < rows.length;
29916
- return /* @__PURE__ */ jsxs47(
29917
- Box43,
30739
+ return /* @__PURE__ */ jsxs52(
30740
+ Box48,
29918
30741
  {
29919
30742
  flexDirection: "column",
29920
30743
  borderStyle: "round",
@@ -29925,80 +30748,80 @@ var ModelDialog = ({
29925
30748
  marginRight: 1,
29926
30749
  minWidth: 58,
29927
30750
  children: [
29928
- /* @__PURE__ */ jsxs47(Box43, { justifyContent: "space-between", marginBottom: 1, children: [
29929
- /* @__PURE__ */ jsxs47(Box43, { gap: 1, children: [
29930
- /* @__PURE__ */ jsx53(Text51, { bold: true, color: theme.text.primary, children: "Select model" }),
29931
- /* @__PURE__ */ jsx53(Text51, { color: theme.text.secondary, children: "for" }),
29932
- /* @__PURE__ */ jsx53(Text51, { color: theme.text.accent, children: currentProvider })
30751
+ /* @__PURE__ */ jsxs52(Box48, { justifyContent: "space-between", marginBottom: 1, children: [
30752
+ /* @__PURE__ */ jsxs52(Box48, { gap: 1, children: [
30753
+ /* @__PURE__ */ jsx58(Text56, { bold: true, color: theme.text.primary, children: "Select model" }),
30754
+ /* @__PURE__ */ jsx58(Text56, { color: theme.text.secondary, children: "for" }),
30755
+ /* @__PURE__ */ jsx58(Text56, { color: theme.text.accent, children: currentProvider })
29933
30756
  ] }),
29934
- /* @__PURE__ */ jsx53(Text51, { color: theme.ui.comment, dimColor: true, children: "esc" })
30757
+ /* @__PURE__ */ jsx58(Text56, { color: theme.ui.comment, dimColor: true, children: "esc" })
29935
30758
  ] }),
29936
- /* @__PURE__ */ jsxs47(
29937
- Box43,
30759
+ /* @__PURE__ */ jsxs52(
30760
+ Box48,
29938
30761
  {
29939
30762
  borderStyle: "single",
29940
30763
  borderColor: search ? theme.border.focused : theme.ui.comment,
29941
30764
  paddingX: 1,
29942
30765
  marginBottom: 1,
29943
30766
  children: [
29944
- /* @__PURE__ */ jsx53(Text51, { color: theme.ui.comment, children: "\u2315 " }),
29945
- search ? /* @__PURE__ */ jsxs47(Text51, { color: theme.text.primary, children: [
30767
+ /* @__PURE__ */ jsx58(Text56, { color: theme.ui.comment, children: "\u2315 " }),
30768
+ search ? /* @__PURE__ */ jsxs52(Text56, { color: theme.text.primary, children: [
29946
30769
  search,
29947
- /* @__PURE__ */ jsx53(Text51, { color: theme.text.accent, children: "\u258C" })
29948
- ] }) : /* @__PURE__ */ jsxs47(Text51, { color: theme.ui.comment, dimColor: true, children: [
30770
+ /* @__PURE__ */ jsx58(Text56, { color: theme.text.accent, children: "\u258C" })
30771
+ ] }) : /* @__PURE__ */ jsxs52(Text56, { color: theme.ui.comment, dimColor: true, children: [
29949
30772
  "Search",
29950
- /* @__PURE__ */ jsx53(Text51, { color: theme.text.accent, children: "\u258C" })
30773
+ /* @__PURE__ */ jsx58(Text56, { color: theme.text.accent, children: "\u258C" })
29951
30774
  ] })
29952
30775
  ]
29953
30776
  }
29954
30777
  ),
29955
- loadState === "loading" && /* @__PURE__ */ jsx53(Box43, { marginY: 1, children: /* @__PURE__ */ jsx53(Text51, { color: theme.text.secondary, children: "Loading models\u2026" }) }),
29956
- loadState === "error" && /* @__PURE__ */ jsxs47(Box43, { flexDirection: "column", marginY: 1, children: [
29957
- /* @__PURE__ */ jsx53(Text51, { color: theme.status.error, children: "\u2717 Could not load models" }),
29958
- /* @__PURE__ */ jsx53(Text51, { color: theme.ui.comment, dimColor: true, children: errorMsg })
30778
+ loadState === "loading" && /* @__PURE__ */ jsx58(Box48, { marginY: 1, children: /* @__PURE__ */ jsx58(Text56, { color: theme.text.secondary, children: "Loading models\u2026" }) }),
30779
+ loadState === "error" && /* @__PURE__ */ jsxs52(Box48, { flexDirection: "column", marginY: 1, children: [
30780
+ /* @__PURE__ */ jsx58(Text56, { color: theme.status.error, children: "\u2717 Could not load models" }),
30781
+ /* @__PURE__ */ jsx58(Text56, { color: theme.ui.comment, dimColor: true, children: errorMsg })
29959
30782
  ] }),
29960
- loadState === "ready" && selectableCount === 0 && /* @__PURE__ */ jsx53(Box43, { marginY: 1, children: /* @__PURE__ */ jsxs47(Text51, { color: theme.ui.comment, dimColor: true, children: [
30783
+ loadState === "ready" && selectableCount === 0 && /* @__PURE__ */ jsx58(Box48, { marginY: 1, children: /* @__PURE__ */ jsxs52(Text56, { color: theme.ui.comment, dimColor: true, children: [
29961
30784
  'No models match "',
29962
30785
  search,
29963
30786
  '"'
29964
30787
  ] }) }),
29965
- loadState === "ready" && selectableCount > 0 && /* @__PURE__ */ jsxs47(Box43, { flexDirection: "column", children: [
29966
- canScrollUp && /* @__PURE__ */ jsx53(Text51, { color: theme.ui.comment, dimColor: true, children: " \u2191" }),
30788
+ loadState === "ready" && selectableCount > 0 && /* @__PURE__ */ jsxs52(Box48, { flexDirection: "column", children: [
30789
+ canScrollUp && /* @__PURE__ */ jsx58(Text56, { color: theme.ui.comment, dimColor: true, children: " \u2191" }),
29967
30790
  visibleRows.map((row, i) => {
29968
30791
  if (row.kind === "header") {
29969
- return /* @__PURE__ */ jsx53(Box43, { marginTop: i === 0 ? 0 : 1, children: /* @__PURE__ */ jsx53(Text51, { color: theme.text.accent, bold: true, children: row.label }) }, `h${i}`);
30792
+ return /* @__PURE__ */ jsx58(Box48, { marginTop: i === 0 ? 0 : 1, children: /* @__PURE__ */ jsx58(Text56, { color: theme.text.accent, bold: true, children: row.label }) }, `h${i}`);
29970
30793
  }
29971
30794
  const { model, selIndex } = row;
29972
30795
  const isActive = selIndex === clampedIndex;
29973
30796
  const isCurrent = model.id === currentModel;
29974
30797
  const free = isFree(model);
29975
30798
  const group = providerGroup(model);
29976
- return /* @__PURE__ */ jsxs47(Box43, { gap: 1, children: [
29977
- /* @__PURE__ */ jsx53(Text51, { color: isActive ? theme.text.accent : theme.ui.comment, children: isCurrent ? "\u25CF" : isActive ? "\u203A" : " " }),
29978
- /* @__PURE__ */ jsxs47(Box43, { flexGrow: 1, gap: 1, children: [
29979
- /* @__PURE__ */ jsx53(
29980
- Text51,
30799
+ return /* @__PURE__ */ jsxs52(Box48, { gap: 1, children: [
30800
+ /* @__PURE__ */ jsx58(Text56, { color: isActive ? theme.text.accent : theme.ui.comment, children: isCurrent ? "\u25CF" : isActive ? "\u203A" : " " }),
30801
+ /* @__PURE__ */ jsxs52(Box48, { flexGrow: 1, gap: 1, children: [
30802
+ /* @__PURE__ */ jsx58(
30803
+ Text56,
29981
30804
  {
29982
30805
  color: isActive ? theme.text.primary : theme.text.secondary,
29983
30806
  bold: isActive,
29984
30807
  children: model.name
29985
30808
  }
29986
30809
  ),
29987
- /* @__PURE__ */ jsx53(Text51, { color: theme.text.accent, dimColor: true, children: group })
30810
+ /* @__PURE__ */ jsx58(Text56, { color: theme.text.accent, dimColor: true, children: group })
29988
30811
  ] }),
29989
- free && /* @__PURE__ */ jsx53(Text51, { color: theme.status.success, dimColor: !isActive, children: "Free" })
30812
+ free && /* @__PURE__ */ jsx58(Text56, { color: theme.status.success, dimColor: !isActive, children: "Free" })
29990
30813
  ] }, model.id);
29991
30814
  }),
29992
- canScrollDown && /* @__PURE__ */ jsx53(Text51, { color: theme.ui.comment, dimColor: true, children: " \u2193" })
30815
+ canScrollDown && /* @__PURE__ */ jsx58(Text56, { color: theme.ui.comment, dimColor: true, children: " \u2193" })
29993
30816
  ] }),
29994
- loadState === "ready" && /* @__PURE__ */ jsx53(Box43, { marginTop: 1, children: /* @__PURE__ */ jsxs47(Text51, { color: theme.ui.comment, dimColor: true, children: [
30817
+ loadState === "ready" && /* @__PURE__ */ jsx58(Box48, { marginTop: 1, children: /* @__PURE__ */ jsxs52(Text56, { color: theme.ui.comment, dimColor: true, children: [
29995
30818
  selectableCount,
29996
30819
  " model",
29997
30820
  selectableCount !== 1 ? "s" : "",
29998
30821
  search ? ` \xB7 "${search}"` : ""
29999
30822
  ] }) }),
30000
- /* @__PURE__ */ jsx53(
30001
- Box43,
30823
+ /* @__PURE__ */ jsx58(
30824
+ Box48,
30002
30825
  {
30003
30826
  marginTop: 1,
30004
30827
  borderStyle: "single",
@@ -30007,7 +30830,7 @@ var ModelDialog = ({
30007
30830
  borderLeft: false,
30008
30831
  borderRight: false,
30009
30832
  borderColor: theme.ui.comment,
30010
- children: /* @__PURE__ */ jsx53(Text51, { color: theme.ui.comment, dimColor: true, children: "\u2191\u2193 navigate type to search Enter use for session Esc close" })
30833
+ children: /* @__PURE__ */ jsx58(Text56, { color: theme.ui.comment, dimColor: true, children: "\u2191\u2193 navigate type to search Enter use for session Esc close" })
30011
30834
  }
30012
30835
  )
30013
30836
  ]
@@ -30021,13 +30844,13 @@ var RATINGS = [
30021
30844
  { rating: 2, label: "Poor" },
30022
30845
  { rating: 1, label: "Very poor" }
30023
30846
  ];
30024
- var CANCEL_VALUE2 = "__cancel__";
30847
+ var CANCEL_VALUE = "__cancel__";
30025
30848
  function appendFeedbackEntry(cwd, rating, label) {
30026
- const file = path15.join(cwd, ".deepcode", "feedback.log");
30849
+ const file = path18.join(cwd, ".deepcode", "feedback.log");
30027
30850
  const entry = JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), rating, label });
30028
30851
  try {
30029
- fs8.mkdirSync(path15.dirname(file), { recursive: true });
30030
- fs8.appendFileSync(file, `${entry}
30852
+ fs11.mkdirSync(path18.dirname(file), { recursive: true });
30853
+ fs11.appendFileSync(file, `${entry}
30031
30854
  `, "utf8");
30032
30855
  } catch {
30033
30856
  }
@@ -30040,13 +30863,13 @@ var FeedbackDialog = ({ cwd, onClose }) => {
30040
30863
  value: String(rating),
30041
30864
  label: `${rating} ${label}`
30042
30865
  })),
30043
- { key: CANCEL_VALUE2, value: CANCEL_VALUE2, label: "Cancel" }
30866
+ { key: CANCEL_VALUE, value: CANCEL_VALUE, label: "Cancel" }
30044
30867
  ],
30045
30868
  []
30046
30869
  );
30047
- const handleSelect = useCallback25(
30870
+ const handleSelect = useCallback26(
30048
30871
  (value) => {
30049
- if (value !== CANCEL_VALUE2) {
30872
+ if (value !== CANCEL_VALUE) {
30050
30873
  const opt = RATINGS.find((r) => String(r.rating) === value);
30051
30874
  if (opt) appendFeedbackEntry(cwd, opt.rating, opt.label);
30052
30875
  }
@@ -30054,15 +30877,15 @@ var FeedbackDialog = ({ cwd, onClose }) => {
30054
30877
  },
30055
30878
  [cwd, onClose]
30056
30879
  );
30057
- const handleEscape = useCallback25(
30880
+ const handleEscape = useCallback26(
30058
30881
  (key) => {
30059
30882
  if (key.name === "escape") onClose();
30060
30883
  },
30061
30884
  [onClose]
30062
30885
  );
30063
30886
  useKeypress(handleEscape, { isActive: true });
30064
- return /* @__PURE__ */ jsxs48(
30065
- Box44,
30887
+ return /* @__PURE__ */ jsxs53(
30888
+ Box49,
30066
30889
  {
30067
30890
  flexDirection: "column",
30068
30891
  borderStyle: "round",
@@ -30071,25 +30894,42 @@ var FeedbackDialog = ({ cwd, onClose }) => {
30071
30894
  marginLeft: 2,
30072
30895
  marginRight: 2,
30073
30896
  children: [
30074
- /* @__PURE__ */ jsx54(Text52, { bold: true, color: theme.text.accent, children: "How useful was DeepCode in this session?" }),
30075
- /* @__PURE__ */ jsx54(RadioButtonSelect, { items, onSelect: handleSelect, isFocused: true, showNumbers: false }),
30076
- /* @__PURE__ */ jsx54(Text52, { color: theme.text.secondary, children: "\u2191\u2193 navigate \xB7 Enter submit \xB7 Esc cancel" })
30897
+ /* @__PURE__ */ jsx59(Text57, { bold: true, color: theme.text.accent, children: "How useful was DeepCode in this session?" }),
30898
+ /* @__PURE__ */ jsx59(RadioButtonSelect, { items, onSelect: handleSelect, isFocused: true, showNumbers: false }),
30899
+ /* @__PURE__ */ jsx59(Text57, { color: theme.text.secondary, children: "\u2191\u2193 navigate \xB7 Enter submit \xB7 Esc cancel" })
30077
30900
  ]
30078
30901
  }
30079
30902
  );
30080
30903
  };
30081
30904
  var MAX_VISIBLE2 = 12;
30905
+ function relativeTime(iso) {
30906
+ const diffMs = Date.now() - new Date(iso).getTime();
30907
+ const diffSecs = Math.floor(diffMs / 1e3);
30908
+ if (diffSecs < 60) return "agora";
30909
+ const diffMins = Math.floor(diffSecs / 60);
30910
+ if (diffMins < 60) return `h\xE1 ${diffMins} min`;
30911
+ const diffHours = Math.floor(diffMins / 60);
30912
+ if (diffHours < 24) return `h\xE1 ${diffHours}h`;
30913
+ const diffDays = Math.floor(diffHours / 24);
30914
+ if (diffDays === 1) return "ontem";
30915
+ if (diffDays < 7) return `h\xE1 ${diffDays} dias`;
30916
+ const diffWeeks = Math.floor(diffDays / 7);
30917
+ if (diffWeeks === 1) return "h\xE1 1 semana";
30918
+ if (diffWeeks < 5) return `h\xE1 ${diffWeeks} semanas`;
30919
+ const diffMonths = Math.floor(diffDays / 30);
30920
+ return `h\xE1 ${diffMonths} m\xEAs${diffMonths !== 1 ? "es" : ""}`;
30921
+ }
30082
30922
  function sessionLabel2(session) {
30083
30923
  const name = typeof session.metadata["name"] === "string" ? session.metadata["name"] : void 0;
30084
30924
  const firstUser = session.messages.find((m) => m.role === "user");
30085
30925
  return name ?? firstUser?.content?.slice(0, 55) ?? "(no messages)";
30086
30926
  }
30087
30927
  var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30088
- const [loadState, setLoadState] = useState29("loading");
30089
- const [allSessions, setAllSessions] = useState29([]);
30090
- const [search, setSearch] = useState29("");
30091
- const [activeIndex, setActiveIndex] = useState29(0);
30092
- useEffect27(() => {
30928
+ const [loadState, setLoadState] = useState33("loading");
30929
+ const [allSessions, setAllSessions] = useState33([]);
30930
+ const [search, setSearch] = useState33("");
30931
+ const [activeIndex, setActiveIndex] = useState33(0);
30932
+ useEffect31(() => {
30093
30933
  const manager = new SessionManager(cwd);
30094
30934
  manager.loadAll().then((loaded) => {
30095
30935
  const sorted = [...loaded].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
@@ -30097,7 +30937,7 @@ var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30097
30937
  setLoadState("ready");
30098
30938
  }).catch(() => setLoadState("error"));
30099
30939
  }, [cwd]);
30100
- useEffect27(() => {
30940
+ useEffect31(() => {
30101
30941
  setActiveIndex(0);
30102
30942
  }, [search]);
30103
30943
  const sessions = useMemo18(() => {
@@ -30111,7 +30951,7 @@ var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30111
30951
  [clampedIndex, sessions.length]
30112
30952
  );
30113
30953
  const visibleSessions = sessions.slice(scrollTop, scrollTop + MAX_VISIBLE2);
30114
- const confirm = useCallback26(() => {
30954
+ const confirm = useCallback27(() => {
30115
30955
  const session = sessions[clampedIndex];
30116
30956
  if (session) onSelect(session.id);
30117
30957
  }, [sessions, clampedIndex, onSelect]);
@@ -30154,8 +30994,8 @@ var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30154
30994
  }, { isActive: true });
30155
30995
  const canScrollUp = scrollTop > 0;
30156
30996
  const canScrollDown = scrollTop + MAX_VISIBLE2 < sessions.length;
30157
- return /* @__PURE__ */ jsxs49(
30158
- Box45,
30997
+ return /* @__PURE__ */ jsxs54(
30998
+ Box50,
30159
30999
  {
30160
31000
  flexDirection: "column",
30161
31001
  borderStyle: "round",
@@ -30166,47 +31006,47 @@ var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30166
31006
  marginRight: 1,
30167
31007
  minWidth: 60,
30168
31008
  children: [
30169
- /* @__PURE__ */ jsxs49(Box45, { justifyContent: "space-between", marginBottom: 1, children: [
30170
- /* @__PURE__ */ jsx55(Text53, { bold: true, color: theme.text.primary, children: "Resume session" }),
30171
- /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: "esc" })
31009
+ /* @__PURE__ */ jsxs54(Box50, { justifyContent: "space-between", marginBottom: 1, children: [
31010
+ /* @__PURE__ */ jsx60(Text58, { bold: true, color: theme.text.primary, children: "Resume session" }),
31011
+ /* @__PURE__ */ jsx60(Text58, { color: theme.ui.comment, dimColor: true, children: "esc" })
30172
31012
  ] }),
30173
- /* @__PURE__ */ jsxs49(
30174
- Box45,
31013
+ /* @__PURE__ */ jsxs54(
31014
+ Box50,
30175
31015
  {
30176
31016
  borderStyle: "single",
30177
31017
  borderColor: search ? theme.border.focused : theme.ui.comment,
30178
31018
  paddingX: 1,
30179
31019
  marginBottom: 1,
30180
31020
  children: [
30181
- /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, children: "\u2315 " }),
30182
- search ? /* @__PURE__ */ jsxs49(Text53, { color: theme.text.primary, children: [
31021
+ /* @__PURE__ */ jsx60(Text58, { color: theme.ui.comment, children: "\u2315 " }),
31022
+ search ? /* @__PURE__ */ jsxs54(Text58, { color: theme.text.primary, children: [
30183
31023
  search,
30184
- /* @__PURE__ */ jsx55(Text53, { color: theme.text.accent, children: "\u258C" })
30185
- ] }) : /* @__PURE__ */ jsxs49(Text53, { color: theme.ui.comment, dimColor: true, children: [
31024
+ /* @__PURE__ */ jsx60(Text58, { color: theme.text.accent, children: "\u258C" })
31025
+ ] }) : /* @__PURE__ */ jsxs54(Text58, { color: theme.ui.comment, dimColor: true, children: [
30186
31026
  "Search",
30187
- /* @__PURE__ */ jsx55(Text53, { color: theme.text.accent, children: "\u258C" })
31027
+ /* @__PURE__ */ jsx60(Text58, { color: theme.text.accent, children: "\u258C" })
30188
31028
  ] })
30189
31029
  ]
30190
31030
  }
30191
31031
  ),
30192
- loadState === "loading" && /* @__PURE__ */ jsx55(Box45, { marginY: 1, children: /* @__PURE__ */ jsx55(Text53, { color: theme.text.secondary, children: "Loading sessions\u2026" }) }),
30193
- loadState === "error" && /* @__PURE__ */ jsx55(Box45, { marginY: 1, children: /* @__PURE__ */ jsx55(Text53, { color: theme.status.error, children: "\u2717 Could not load sessions" }) }),
30194
- loadState === "ready" && sessions.length === 0 && /* @__PURE__ */ jsx55(Box45, { marginY: 1, children: /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: search ? `No sessions match "${search}"` : "No sessions found in .deepcode/sessions/" }) }),
30195
- loadState === "ready" && sessions.length > 0 && /* @__PURE__ */ jsxs49(Box45, { flexDirection: "column", children: [
30196
- canScrollUp && /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: " \u2191" }),
31032
+ loadState === "loading" && /* @__PURE__ */ jsx60(Box50, { marginY: 1, children: /* @__PURE__ */ jsx60(Text58, { color: theme.text.secondary, children: "Loading sessions\u2026" }) }),
31033
+ loadState === "error" && /* @__PURE__ */ jsx60(Box50, { marginY: 1, children: /* @__PURE__ */ jsx60(Text58, { color: theme.status.error, children: "\u2717 Could not load sessions" }) }),
31034
+ loadState === "ready" && sessions.length === 0 && /* @__PURE__ */ jsx60(Box50, { marginY: 1, children: /* @__PURE__ */ jsx60(Text58, { color: theme.ui.comment, dimColor: true, children: search ? `No sessions match "${search}"` : "No sessions found in .deepcode/sessions/" }) }),
31035
+ loadState === "ready" && sessions.length > 0 && /* @__PURE__ */ jsxs54(Box50, { flexDirection: "column", children: [
31036
+ canScrollUp && /* @__PURE__ */ jsx60(Text58, { color: theme.ui.comment, dimColor: true, children: " \u2191" }),
30197
31037
  visibleSessions.map((session, visIdx) => {
30198
31038
  const globalIdx = scrollTop + visIdx;
30199
31039
  const isActive = globalIdx === clampedIndex;
30200
31040
  const shortId = session.id.slice(-8);
30201
- const date = new Date(session.updatedAt).toLocaleString();
31041
+ const date = relativeTime(session.updatedAt);
30202
31042
  const target = session.model ? `${session.provider}/${session.model}` : session.provider;
30203
31043
  const msgCount = session.messages.length;
30204
31044
  const preview = sessionLabel2(session);
30205
- return /* @__PURE__ */ jsxs49(Box45, { flexDirection: "column", children: [
30206
- /* @__PURE__ */ jsxs49(Box45, { gap: 1, children: [
30207
- /* @__PURE__ */ jsx55(Text53, { color: isActive ? theme.text.accent : theme.ui.comment, children: isActive ? "\u203A" : " " }),
30208
- /* @__PURE__ */ jsx55(
30209
- Text53,
31045
+ return /* @__PURE__ */ jsxs54(Box50, { flexDirection: "column", children: [
31046
+ /* @__PURE__ */ jsxs54(Box50, { gap: 1, children: [
31047
+ /* @__PURE__ */ jsx60(Text58, { color: isActive ? theme.text.accent : theme.ui.comment, children: isActive ? "\u203A" : " " }),
31048
+ /* @__PURE__ */ jsx60(
31049
+ Text58,
30210
31050
  {
30211
31051
  color: isActive ? theme.text.primary : theme.text.secondary,
30212
31052
  bold: isActive,
@@ -30215,7 +31055,7 @@ var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30215
31055
  }
30216
31056
  )
30217
31057
  ] }),
30218
- isActive && /* @__PURE__ */ jsx55(Box45, { paddingLeft: 2, children: /* @__PURE__ */ jsxs49(Text53, { color: theme.ui.comment, dimColor: true, children: [
31058
+ isActive && /* @__PURE__ */ jsx60(Box50, { paddingLeft: 2, children: /* @__PURE__ */ jsxs54(Text58, { color: theme.ui.comment, dimColor: true, children: [
30219
31059
  shortId,
30220
31060
  " ",
30221
31061
  target,
@@ -30226,16 +31066,16 @@ var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30226
31066
  ] }) })
30227
31067
  ] }, session.id);
30228
31068
  }),
30229
- canScrollDown && /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: " \u2193" }),
30230
- /* @__PURE__ */ jsx55(Box45, { marginTop: 1, children: /* @__PURE__ */ jsxs49(Text53, { color: theme.ui.comment, dimColor: true, children: [
31069
+ canScrollDown && /* @__PURE__ */ jsx60(Text58, { color: theme.ui.comment, dimColor: true, children: " \u2193" }),
31070
+ /* @__PURE__ */ jsx60(Box50, { marginTop: 1, children: /* @__PURE__ */ jsxs54(Text58, { color: theme.ui.comment, dimColor: true, children: [
30231
31071
  sessions.length,
30232
31072
  " session",
30233
31073
  sessions.length !== 1 ? "s" : "",
30234
31074
  search ? ` \xB7 "${search}"` : ""
30235
31075
  ] }) })
30236
31076
  ] }),
30237
- /* @__PURE__ */ jsx55(
30238
- Box45,
31077
+ /* @__PURE__ */ jsx60(
31078
+ Box50,
30239
31079
  {
30240
31080
  marginTop: 1,
30241
31081
  borderStyle: "single",
@@ -30244,7 +31084,7 @@ var SessionsDialog = ({ cwd, onSelect, onClose }) => {
30244
31084
  borderLeft: false,
30245
31085
  borderRight: false,
30246
31086
  borderColor: theme.ui.comment,
30247
- children: /* @__PURE__ */ jsx55(Text53, { color: theme.ui.comment, dimColor: true, children: "\u2191\u2193 navigate type to search Enter resume Esc close" })
31087
+ children: /* @__PURE__ */ jsx60(Text58, { color: theme.ui.comment, dimColor: true, children: "\u2191\u2193 navigate type to search Enter resume Esc close" })
30248
31088
  }
30249
31089
  )
30250
31090
  ]
@@ -30265,8 +31105,8 @@ var SubagentsPanel = ({ subagents, mainAreaWidth }) => {
30265
31105
  if (subagents.length === 0) return null;
30266
31106
  const running = subagents.filter((s) => s.status === "running").length;
30267
31107
  const title = running > 0 ? `Subagents (${running} running)` : `Subagents (${subagents.length} finishing\u2026)`;
30268
- return /* @__PURE__ */ jsxs50(
30269
- Box46,
31108
+ return /* @__PURE__ */ jsxs55(
31109
+ Box51,
30270
31110
  {
30271
31111
  flexDirection: "column",
30272
31112
  borderStyle: "round",
@@ -30276,25 +31116,25 @@ var SubagentsPanel = ({ subagents, mainAreaWidth }) => {
30276
31116
  marginTop: 1,
30277
31117
  width: Math.min(mainAreaWidth, 80),
30278
31118
  children: [
30279
- /* @__PURE__ */ jsx56(Box46, { paddingX: 1, children: /* @__PURE__ */ jsx56(Text54, { bold: true, color: theme.text.accent, children: title }) }),
30280
- subagents.map((entry) => /* @__PURE__ */ jsxs50(Box46, { flexDirection: "column", paddingX: 1, children: [
30281
- /* @__PURE__ */ jsxs50(Box46, { flexDirection: "row", gap: 1, children: [
30282
- /* @__PURE__ */ jsx56(Text54, { color: statusColor(entry), children: statusIcon(entry) }),
30283
- /* @__PURE__ */ jsxs50(Text54, { wrap: "truncate", color: theme.text.primary, children: [
31119
+ /* @__PURE__ */ jsx61(Box51, { paddingX: 1, children: /* @__PURE__ */ jsx61(Text59, { bold: true, color: theme.text.accent, children: title }) }),
31120
+ subagents.map((entry) => /* @__PURE__ */ jsxs55(Box51, { flexDirection: "column", paddingX: 1, children: [
31121
+ /* @__PURE__ */ jsxs55(Box51, { flexDirection: "row", gap: 1, children: [
31122
+ /* @__PURE__ */ jsx61(Text59, { color: statusColor(entry), children: statusIcon(entry) }),
31123
+ /* @__PURE__ */ jsxs55(Text59, { wrap: "truncate", color: theme.text.primary, children: [
30284
31124
  entry.prompt,
30285
31125
  entry.prompt.length >= 50 ? "\u2026" : ""
30286
31126
  ] })
30287
31127
  ] }),
30288
- entry.status === "running" && entry.currentTool && /* @__PURE__ */ jsxs50(Text54, { color: theme.text.secondary, dimColor: true, children: [
31128
+ entry.status === "running" && entry.currentTool && /* @__PURE__ */ jsxs55(Text59, { color: theme.text.secondary, dimColor: true, children: [
30289
31129
  " ",
30290
31130
  "using ",
30291
31131
  entry.currentTool
30292
31132
  ] }),
30293
- entry.status === "running" && !entry.currentTool && entry.currentOutput && /* @__PURE__ */ jsxs50(Text54, { color: theme.text.secondary, dimColor: true, wrap: "truncate", children: [
31133
+ entry.status === "running" && !entry.currentTool && entry.currentOutput && /* @__PURE__ */ jsxs55(Text59, { color: theme.text.secondary, dimColor: true, wrap: "truncate", children: [
30294
31134
  " ",
30295
31135
  entry.currentOutput.trimStart()
30296
31136
  ] }),
30297
- entry.status === "failed" && entry.error && /* @__PURE__ */ jsxs50(Text54, { color: theme.status.error, dimColor: true, wrap: "truncate", children: [
31137
+ entry.status === "failed" && entry.error && /* @__PURE__ */ jsxs55(Text59, { color: theme.status.error, dimColor: true, wrap: "truncate", children: [
30298
31138
  " ",
30299
31139
  entry.error.slice(0, 60)
30300
31140
  ] })
@@ -30534,72 +31374,75 @@ var APPROVAL_ENTER_ARM_DELAY_MS = 350;
30534
31374
  var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarnings = [] }) => {
30535
31375
  const historyManager = useHistory();
30536
31376
  const addHistoryItem = historyManager.addItem;
30537
- const [initError, setInitError] = useState30(null);
30538
- const [isInitializing, setIsInitializing] = useState30(true);
30539
- const [isRunning, setIsRunning] = useState30(false);
30540
- const [pendingAssistantText, setPendingAssistantText] = useState30("");
30541
- const [approvalQueue, setApprovalQueue] = useState30([]);
30542
- const [providerLabel, setProviderLabel] = useState30("(unconfigured)");
30543
- const [targetSource, setTargetSource] = useState30("config");
30544
- const [currentModel, setCurrentModel] = useState30("(unconfigured)");
30545
- const [agentMode, setAgentMode] = useState30("build");
30546
- const [streamingState, setStreamingState] = useState30(
31377
+ const [initError, setInitError] = useState34(null);
31378
+ const [isInitializing, setIsInitializing] = useState34(true);
31379
+ const [isRunning, setIsRunning] = useState34(false);
31380
+ const [pendingAssistantText, setPendingAssistantText] = useState34("");
31381
+ const [approvalQueue, setApprovalQueue] = useState34([]);
31382
+ const [providerLabel, setProviderLabel] = useState34("(unconfigured)");
31383
+ const [targetSource, setTargetSource] = useState34("config");
31384
+ const [currentModel, setCurrentModel] = useState34("(unconfigured)");
31385
+ const [agentMode, setAgentMode] = useState34("build");
31386
+ const [streamingState, setStreamingState] = useState34(
30547
31387
  "idle"
30548
31388
  /* Idle */
30549
31389
  );
30550
- const [compactMode, setCompactMode] = useState30(true);
30551
- const [constrainHeight, setConstrainHeight] = useState30(true);
30552
- const [shellModeActive, setShellModeActive] = useState30(false);
30553
- const [showEscapePrompt, setShowEscapePrompt] = useState30(false);
30554
- const [messageQueue, setMessageQueue] = useState30([]);
30555
- const [historyRemountKey, setHistoryRemountKey] = useState30(0);
30556
- const [pendingItem, setPendingItem] = useState30(null);
30557
- const [lastPromptTokenCount, setLastPromptTokenCount] = useState30(0);
30558
- const [lastOutputTokenCount, setLastOutputTokenCount] = useState30(0);
30559
- const [elapsedTime, setElapsedTime] = useState30(0);
30560
- const [isReceivingContent, setIsReceivingContent] = useState30(false);
30561
- const [iterationInfo, setIterationInfo] = useState30(null);
30562
- const [liveToolCalls, setLiveToolCalls] = useState30([]);
30563
- const [recentSlashCommandsState, setRecentSlashCommandsState] = useState30(/* @__PURE__ */ new Map());
30564
- const [activeDialog, setActiveDialog] = useState30(null);
30565
- const [themeName, setThemeName] = useState30("(unknown)");
30566
- const [permissionSummary, setPermissionSummary] = useState30("(unknown)");
30567
- const [authSummary, setAuthSummary] = useState30("(unknown)");
30568
- const [permissionModes, setPermissionModes] = useState30({
31390
+ const [compactMode, setCompactMode] = useState34(true);
31391
+ const [constrainHeight, setConstrainHeight] = useState34(true);
31392
+ const [shellModeActive, setShellModeActive] = useState34(false);
31393
+ const [showEscapePrompt, setShowEscapePrompt] = useState34(false);
31394
+ const [messageQueue, setMessageQueue] = useState34([]);
31395
+ const [historyRemountKey, setHistoryRemountKey] = useState34(0);
31396
+ const [pendingItem, setPendingItem] = useState34(null);
31397
+ const [lastPromptTokenCount, setLastPromptTokenCount] = useState34(0);
31398
+ const [lastOutputTokenCount, setLastOutputTokenCount] = useState34(0);
31399
+ const [totalPromptTokenCount, setTotalPromptTokenCount] = useState34(0);
31400
+ const [totalOutputTokenCount, setTotalOutputTokenCount] = useState34(0);
31401
+ const [isReceivingContent, setIsReceivingContent] = useState34(false);
31402
+ const [iterationInfo, setIterationInfo] = useState34(null);
31403
+ const [liveToolCalls, setLiveToolCalls] = useState34([]);
31404
+ const [recentSlashCommandsState, setRecentSlashCommandsState] = useState34(/* @__PURE__ */ new Map());
31405
+ const [activeDialog, setActiveDialog] = useState34(null);
31406
+ const [themeName, setThemeName] = useState34("(unknown)");
31407
+ const [permissionSummary, setPermissionSummary] = useState34("(unknown)");
31408
+ const [authSummary, setAuthSummary] = useState34("(unknown)");
31409
+ const [permissionModes, setPermissionModes] = useState34({
30569
31410
  read: "allow",
30570
31411
  write: "ask",
30571
31412
  gitLocal: "allow",
30572
31413
  shell: "ask",
30573
31414
  dangerous: "ask"
30574
31415
  });
30575
- const [providerConfigVersion, setProviderConfigVersion] = useState30(0);
30576
- const [, setThemeVersion] = useState30(0);
30577
- const [mcpConnected, setMcpConnected] = useState30(0);
30578
- const [mcpTotal, setMcpTotal] = useState30(0);
30579
- const [subagentMap, setSubagentMap] = useState30(/* @__PURE__ */ new Map());
30580
- const [, setDrainTick] = useState30(0);
30581
- const [pendingCommandConfirmation, setPendingCommandConfirmation] = useState30(null);
31416
+ const [sessionDisplayName, setSessionDisplayName] = useState34("");
31417
+ const [providerConfigVersion, setProviderConfigVersion] = useState34(0);
31418
+ const [, setThemeVersion] = useState34(0);
31419
+ const [mcpConnected, setMcpConnected] = useState34(0);
31420
+ const [mcpTotal, setMcpTotal] = useState34(0);
31421
+ const [subagentMap, setSubagentMap] = useState34(/* @__PURE__ */ new Map());
31422
+ const [, setDrainTick] = useState34(0);
31423
+ const [pendingCommandConfirmation, setPendingCommandConfirmation] = useState34(null);
30582
31424
  const appContextValue = useMemo19(
30583
31425
  () => ({ version: VERSION, startupWarnings }),
30584
31426
  [startupWarnings]
30585
31427
  );
30586
- const runtimeRef = useRef18(null);
30587
- const sessionRef = useRef18(null);
30588
- const configAdapterRef = useRef18(null);
30589
- const abortRef = useRef18(null);
30590
- const unsubscribeRef = useRef18([]);
30591
- const lastSubmittedPromptRef = useRef18(null);
30592
- const runStartedAtRef = useRef18(null);
30593
- const streamingResponseLengthRef = useRef18(0);
30594
- const pendingTextBufferRef = useRef18("");
30595
- const liveToolCallsBufferRef = useRef18([]);
30596
- const subagentChunkBufferRef = useRef18(/* @__PURE__ */ new Map());
30597
- const subagentToolBufferRef = useRef18([]);
30598
- const drainingQueueRef = useRef18(false);
30599
- const messageQueueRef = useRef18([]);
30600
- const sessionShellAllowlistRef = useRef18(/* @__PURE__ */ new Set());
30601
- const mainControlsRef = useRef18(null);
30602
- const approvalPromptVisibleAtRef = useRef18(null);
31428
+ const sessionStartedAtRef = useRef21(Date.now());
31429
+ const runtimeRef = useRef21(null);
31430
+ const sessionRef = useRef21(null);
31431
+ const configAdapterRef = useRef21(null);
31432
+ const abortRef = useRef21(null);
31433
+ const unsubscribeRef = useRef21([]);
31434
+ const lastSubmittedPromptRef = useRef21(null);
31435
+ const runStartedAtRef = useRef21(null);
31436
+ const streamingResponseLengthRef = useRef21(0);
31437
+ const pendingTextBufferRef = useRef21("");
31438
+ const liveToolCallsBufferRef = useRef21([]);
31439
+ const subagentChunkBufferRef = useRef21(/* @__PURE__ */ new Map());
31440
+ const subagentToolBufferRef = useRef21([]);
31441
+ const drainingQueueRef = useRef21(false);
31442
+ const messageQueueRef = useRef21([]);
31443
+ const sessionShellAllowlistRef = useRef21(/* @__PURE__ */ new Set());
31444
+ const mainControlsRef = useRef21(null);
31445
+ const approvalPromptVisibleAtRef = useRef21(null);
30603
31446
  const { stdin, setRawMode } = useStdin3();
30604
31447
  const { columns: terminalWidth, rows: terminalHeight } = useTerminalSize();
30605
31448
  const mainAreaWidth = Math.min(Math.max(terminalWidth - 4, 20), 120);
@@ -30620,14 +31463,14 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30620
31463
  []
30621
31464
  );
30622
31465
  const configAdapter = configAdapterRef.current ?? new DeepCodeConfigAdapter(cwd);
30623
- const isValidPath = useCallback27(
31466
+ const isValidPath = useCallback28(
30624
31467
  (candidate) => {
30625
- const resolved = path16.resolve(cwd, candidate);
30626
- const relative2 = path16.relative(cwd, resolved);
30627
- if (relative2.startsWith("..") || path16.isAbsolute(relative2)) {
31468
+ const resolved = path19.resolve(cwd, candidate);
31469
+ const relative2 = path19.relative(cwd, resolved);
31470
+ if (relative2.startsWith("..") || path19.isAbsolute(relative2)) {
30628
31471
  return false;
30629
31472
  }
30630
- return fs9.existsSync(resolved);
31473
+ return fs12.existsSync(resolved);
30631
31474
  },
30632
31475
  [cwd]
30633
31476
  );
@@ -30646,6 +31489,14 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30646
31489
  () => historyManager.history.filter((item) => item.type === "user").map((item) => item.text),
30647
31490
  [historyManager.history]
30648
31491
  );
31492
+ const approvalMode = useMemo19(() => {
31493
+ const vals = Object.values(permissionModes);
31494
+ if (vals.every((m) => m === "allow")) return "yolo";
31495
+ if (permissionModes.write === "allow" && permissionModes.read === "allow" && permissionModes.gitLocal === "allow") {
31496
+ return "auto-edit";
31497
+ }
31498
+ return "default";
31499
+ }, [permissionModes]);
30649
31500
  const slashCommands = useMemo19(
30650
31501
  () => [
30651
31502
  helpCommand,
@@ -30655,6 +31506,12 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30655
31506
  diffCommand,
30656
31507
  exportCommand,
30657
31508
  contextCommand,
31509
+ doctorCommand2,
31510
+ historyCommand,
31511
+ statsCommand,
31512
+ memoryCommand,
31513
+ yoloCommand,
31514
+ safeCommand,
30658
31515
  providerCommand,
30659
31516
  modelCommand,
30660
31517
  modeCommand,
@@ -30673,9 +31530,9 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30673
31530
  () => recentSlashCommandsState,
30674
31531
  [recentSlashCommandsState]
30675
31532
  );
30676
- const [promptSuggestion, setPromptSuggestion] = useState30(null);
30677
- const dismissPromptSuggestion = useCallback27(() => setPromptSuggestion(null), []);
30678
- const registerSlashCommandUsage = useCallback27((name) => {
31533
+ const [promptSuggestion, setPromptSuggestion] = useState34(null);
31534
+ const dismissPromptSuggestion = useCallback28(() => setPromptSuggestion(null), []);
31535
+ const registerSlashCommandUsage = useCallback28((name) => {
30679
31536
  setRecentSlashCommandsState((prev) => {
30680
31537
  const next = new Map(prev);
30681
31538
  const existing = next.get(name);
@@ -30687,8 +31544,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30687
31544
  return next;
30688
31545
  });
30689
31546
  }, []);
30690
- const listAvailableProviders = useCallback27(() => PROVIDER_IDS, []);
30691
- const getSessionCommandState = useCallback27(() => {
31547
+ const listAvailableProviders = useCallback28(() => PROVIDER_IDS, []);
31548
+ const getSessionCommandState = useCallback28(() => {
30692
31549
  const runtime = runtimeRef.current;
30693
31550
  const session = sessionRef.current;
30694
31551
  const fallbackProvider = runtime?.config.defaultProvider ?? PROVIDER_IDS[0];
@@ -30700,7 +31557,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30700
31557
  mode: agentMode
30701
31558
  };
30702
31559
  }, [agentMode]);
30703
- const setSessionProvider = useCallback27((provider2) => {
31560
+ const setSessionProvider = useCallback28((provider2) => {
30704
31561
  const runtime = runtimeRef.current;
30705
31562
  const session = sessionRef.current;
30706
31563
  if (!runtime || !session) return;
@@ -30722,7 +31579,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30722
31579
  );
30723
31580
  }
30724
31581
  }, [cwd, historyManager]);
30725
- const setSessionModel = useCallback27((model2) => {
31582
+ const setSessionModel = useCallback28((model2) => {
30726
31583
  const runtime = runtimeRef.current;
30727
31584
  const session = sessionRef.current;
30728
31585
  if (!runtime || !session) return;
@@ -30735,7 +31592,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30735
31592
  setCurrentModel(session.model ?? "(unconfigured)");
30736
31593
  setProviderLabel(formatProviderLabel(session.provider, session.model));
30737
31594
  }, [cwd]);
30738
- const setSessionMode = useCallback27((mode) => {
31595
+ const setSessionMode = useCallback28((mode) => {
30739
31596
  setAgentMode(mode);
30740
31597
  const runtime = runtimeRef.current;
30741
31598
  const session = sessionRef.current;
@@ -30746,7 +31603,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30746
31603
  });
30747
31604
  }
30748
31605
  }, []);
30749
- const setSessionName = useCallback27((name) => {
31606
+ const setSessionName = useCallback28((name) => {
30750
31607
  const runtime = runtimeRef.current;
30751
31608
  const session = sessionRef.current;
30752
31609
  if (!runtime || !session) return;
@@ -30773,13 +31630,13 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30773
31630
  setSessionProvider
30774
31631
  ]
30775
31632
  );
30776
- const handleUndo = useCallback27(async () => {
31633
+ const handleUndo = useCallback28(async () => {
30777
31634
  const runtime = runtimeRef.current;
30778
31635
  const session = sessionRef.current;
30779
31636
  if (!runtime || !session) return null;
30780
31637
  return runtime.agent.undo(session.id);
30781
31638
  }, []);
30782
- const handleCompact = useCallback27(async () => {
31639
+ const handleCompact = useCallback28(async () => {
30783
31640
  const runtime = runtimeRef.current;
30784
31641
  const session = sessionRef.current;
30785
31642
  if (!runtime || !session) return;
@@ -30830,18 +31687,37 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30830
31687
  undo: handleUndo,
30831
31688
  compact: handleCompact,
30832
31689
  getMessages: () => sessionRef.current?.messages ?? [],
30833
- getCwd: () => cwd
31690
+ getCwd: () => cwd,
31691
+ getRuntimeDiagnostics: () => {
31692
+ const runtime = runtimeRef.current;
31693
+ const session = sessionRef.current;
31694
+ if (!runtime || !session) return null;
31695
+ return {
31696
+ provider: session.provider,
31697
+ model: session.model,
31698
+ hasApiKey: Boolean(runtime.config.providers[session.provider]?.apiKey?.trim()),
31699
+ mcpConnected,
31700
+ mcpTotal,
31701
+ agentMode
31702
+ };
31703
+ },
31704
+ getTokenStats: () => ({
31705
+ lastPromptTokens: lastPromptTokenCount,
31706
+ lastOutputTokens: lastOutputTokenCount,
31707
+ sessionStartedAt: sessionStartedAtRef.current
31708
+ }),
31709
+ setPermissions: (modes) => setPermissionModes((prev) => ({ ...prev, ...modes }))
30834
31710
  },
30835
31711
  session: {
30836
31712
  sessionShellAllowlist: sessionShellAllowlistRef.current
30837
31713
  }
30838
31714
  }),
30839
- [configAdapter, handleCompact, handleUndo, historyManager, pendingItem, sessionCommandServices]
31715
+ [agentMode, configAdapter, cwd, handleCompact, handleUndo, historyManager, lastOutputTokenCount, lastPromptTokenCount, mcpConnected, mcpTotal, pendingItem, sessionCommandServices, setPermissionModes]
30840
31716
  );
30841
- useEffect28(() => {
31717
+ useEffect32(() => {
30842
31718
  messageQueueRef.current = messageQueue;
30843
31719
  }, [messageQueue]);
30844
- useEffect28(() => {
31720
+ useEffect32(() => {
30845
31721
  if (approvalQueue.length > 0) {
30846
31722
  approvalPromptVisibleAtRef.current ??= Date.now();
30847
31723
  setStreamingState(
@@ -30863,23 +31739,24 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30863
31739
  /* Idle */
30864
31740
  );
30865
31741
  }, [approvalQueue.length, isRunning]);
30866
- useEffect28(() => {
31742
+ useEffect32(() => {
30867
31743
  if (!isRunning) {
30868
31744
  runStartedAtRef.current = null;
30869
- setElapsedTime(0);
30870
31745
  setIsReceivingContent(false);
30871
- return;
31746
+ } else {
31747
+ runStartedAtRef.current = Date.now();
30872
31748
  }
30873
- runStartedAtRef.current = Date.now();
30874
- setElapsedTime(0);
30875
- const interval = setInterval(() => {
30876
- if (!runStartedAtRef.current) return;
30877
- const seconds = Math.floor((Date.now() - runStartedAtRef.current) / 1e3);
30878
- setElapsedTime(seconds);
30879
- }, 250);
30880
- return () => clearInterval(interval);
30881
31749
  }, [isRunning]);
30882
- useEffect28(() => {
31750
+ const { elapsedTime, currentLoadingPhrase: hookPhrase } = useLoadingIndicator(streamingState);
31751
+ const stickyTodos = useMemo19(
31752
+ () => getStickyTodos(historyManager.history, pendingGeminiHistoryItems),
31753
+ [historyManager.history, pendingGeminiHistoryItems]
31754
+ );
31755
+ const stickyTodoMaxItems = useMemo19(
31756
+ () => getStickyTodoMaxVisibleItems(terminalHeight),
31757
+ [terminalHeight]
31758
+ );
31759
+ useEffect32(() => {
30883
31760
  const id = setInterval(() => {
30884
31761
  const text = pendingTextBufferRef.current;
30885
31762
  if (text) {
@@ -30912,7 +31789,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
30912
31789
  }, 50);
30913
31790
  return () => clearInterval(id);
30914
31791
  }, []);
30915
- useEffect28(() => {
31792
+ useEffect32(() => {
30916
31793
  let mounted = true;
30917
31794
  const initialize = async () => {
30918
31795
  try {
@@ -31076,6 +31953,9 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31076
31953
  })
31077
31954
  );
31078
31955
  unsubscribeRef.current = unsubscribers;
31956
+ if (typeof session.metadata["name"] === "string" && session.metadata["name"]) {
31957
+ setSessionDisplayName(session.metadata["name"]);
31958
+ }
31079
31959
  if (resumed) {
31080
31960
  restoreHistoryFromSession(session, (item) => addHistoryItem(item, Date.now()));
31081
31961
  addHistoryItem(
@@ -31132,7 +32012,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31132
32012
  unsubscribeRef.current = [];
31133
32013
  };
31134
32014
  }, [addHistoryItem, config, cwd, model, provider, resumeSessionId]);
31135
- const resolveApproval = useCallback27(
32015
+ const resolveApproval = useCallback28(
31136
32016
  (decision) => {
31137
32017
  const runtime = runtimeRef.current;
31138
32018
  const current = approvalQueue[0];
@@ -31145,7 +32025,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31145
32025
  },
31146
32026
  [approvalQueue]
31147
32027
  );
31148
- const appendTurnItems = useCallback27(
32028
+ const appendTurnItems = useCallback28(
31149
32029
  (items) => {
31150
32030
  const base = Date.now();
31151
32031
  for (const item of items) {
@@ -31154,7 +32034,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31154
32034
  },
31155
32035
  [historyManager]
31156
32036
  );
31157
- const runPrompt = useCallback27(
32037
+ const runPrompt = useCallback28(
31158
32038
  async (rawPrompt) => {
31159
32039
  const runtime = runtimeRef.current;
31160
32040
  const session = sessionRef.current;
@@ -31191,6 +32071,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31191
32071
  onUsage: (inputTokens, outputTokens) => {
31192
32072
  setLastPromptTokenCount(inputTokens);
31193
32073
  setLastOutputTokenCount(outputTokens);
32074
+ setTotalPromptTokenCount((prev) => prev + inputTokens);
32075
+ setTotalOutputTokenCount((prev) => prev + outputTokens);
31194
32076
  },
31195
32077
  onIteration: (round, max) => {
31196
32078
  setIterationInfo({ round, max });
@@ -31220,6 +32102,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31220
32102
  rt.sessions.save(sess);
31221
32103
  rt.sessions.persist(sess.id).catch(() => {
31222
32104
  });
32105
+ setSessionDisplayName(name);
31223
32106
  }
31224
32107
  }).catch(() => {
31225
32108
  });
@@ -31256,7 +32139,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31256
32139
  },
31257
32140
  [agentMode, appendTurnItems, historyManager]
31258
32141
  );
31259
- const executeClientToolCommand = useCallback27(
32142
+ const executeClientToolCommand = useCallback28(
31260
32143
  async (toolName, toolArgs) => {
31261
32144
  const runtime = runtimeRef.current;
31262
32145
  const session = sessionRef.current;
@@ -31351,7 +32234,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31351
32234
  },
31352
32235
  [agentMode, historyManager]
31353
32236
  );
31354
- const applySlashCommandResult = useCallback27(
32237
+ const applySlashCommandResult = useCallback28(
31355
32238
  async (result, _rawInvocation) => {
31356
32239
  if (!result) return;
31357
32240
  switch (result.type) {
@@ -31412,7 +32295,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31412
32295
  },
31413
32296
  [appendTurnItems, executeClientToolCommand, historyManager, runPrompt]
31414
32297
  );
31415
- const executeSlashCommand = useCallback27(
32298
+ const executeSlashCommand = useCallback28(
31416
32299
  async (rawInput, overwriteConfirmed = false) => {
31417
32300
  const trimmed = rawInput.trim();
31418
32301
  if (!trimmed.startsWith("/")) return false;
@@ -31485,7 +32368,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31485
32368
  slashCommands
31486
32369
  ]
31487
32370
  );
31488
- const executeSubmission = useCallback27(
32371
+ const executeSubmission = useCallback28(
31489
32372
  async (value) => {
31490
32373
  const trimmed = value.trim();
31491
32374
  if (!trimmed) return;
@@ -31495,7 +32378,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31495
32378
  },
31496
32379
  [executeSlashCommand, runPrompt]
31497
32380
  );
31498
- const handleFinalSubmit = useCallback27(
32381
+ const handleFinalSubmit = useCallback28(
31499
32382
  (value) => {
31500
32383
  const prompt = value.trim();
31501
32384
  if (!prompt) return;
@@ -31521,7 +32404,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31521
32404
  isRunning
31522
32405
  ]
31523
32406
  );
31524
- const handleRetryLastPrompt = useCallback27(() => {
32407
+ const handleRetryLastPrompt = useCallback28(() => {
31525
32408
  const lastPrompt = lastSubmittedPromptRef.current;
31526
32409
  if (!lastPrompt) {
31527
32410
  historyManager.addItem(
@@ -31536,7 +32419,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31536
32419
  }
31537
32420
  void runPrompt(lastPrompt);
31538
32421
  }, [approvalQueue.length, historyManager, isInitializing, isRunning, runPrompt]);
31539
- const resolveCommandConfirmation = useCallback27(
32422
+ const resolveCommandConfirmation = useCallback28(
31540
32423
  (confirmed) => {
31541
32424
  const pending = pendingCommandConfirmation;
31542
32425
  if (!pending) return;
@@ -31567,7 +32450,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31567
32450
  pendingCommandConfirmation
31568
32451
  ]
31569
32452
  );
31570
- const persistConfig = useCallback27(
32453
+ const persistConfig = useCallback28(
31571
32454
  async (mutate) => {
31572
32455
  const loader = new ConfigLoader();
31573
32456
  const options = { cwd, configPath: config };
@@ -31576,7 +32459,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31576
32459
  },
31577
32460
  [config, cwd]
31578
32461
  );
31579
- const handleSelectTheme = useCallback27(
32462
+ const handleSelectTheme = useCallback28(
31580
32463
  (nextThemeName) => {
31581
32464
  themeManager.setActiveTheme(nextThemeName);
31582
32465
  setThemeName(themeManager.getActiveTheme().name);
@@ -31597,7 +32480,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31597
32480
  },
31598
32481
  [cwd, historyManager]
31599
32482
  );
31600
- const handleSavePermissions = useCallback27(
32483
+ const handleSavePermissions = useCallback28(
31601
32484
  (modes) => {
31602
32485
  setPermissionModes(modes);
31603
32486
  setPermissionSummary(formatPermissionSummary(modes));
@@ -31626,7 +32509,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31626
32509
  },
31627
32510
  [historyManager, persistConfig]
31628
32511
  );
31629
- const handlePersistToken = useCallback27(
32512
+ const handlePersistToken = useCallback28(
31630
32513
  async (token) => {
31631
32514
  await persistConfig((cfg) => ({
31632
32515
  ...cfg,
@@ -31640,12 +32523,12 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31640
32523
  },
31641
32524
  [persistConfig]
31642
32525
  );
31643
- const providerHasApiKey = useCallback27((provider2) => {
32526
+ const providerHasApiKey = useCallback28((provider2) => {
31644
32527
  const runtime = runtimeRef.current;
31645
32528
  void providerConfigVersion;
31646
32529
  return Boolean(runtime?.config.providers[provider2]?.apiKey?.trim());
31647
32530
  }, [providerConfigVersion]);
31648
- const getProviderKeyHint = useCallback27((provider2) => {
32531
+ const getProviderKeyHint = useCallback28((provider2) => {
31649
32532
  const runtime = runtimeRef.current;
31650
32533
  void providerConfigVersion;
31651
32534
  const key = runtime?.config.providers[provider2]?.apiKey?.trim();
@@ -31653,7 +32536,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31653
32536
  if (key.length <= 8) return "\u25CF".repeat(key.length);
31654
32537
  return `${key.slice(0, 6)}\u25CF\u25CF\u25CF\u25CF${key.slice(-4)}`;
31655
32538
  }, [providerConfigVersion]);
31656
- const handleSaveProviderApiKey = useCallback27(
32539
+ const handleSaveProviderApiKey = useCallback28(
31657
32540
  async (provider2, apiKey) => {
31658
32541
  await persistConfig((cfg) => ({
31659
32542
  ...cfg,
@@ -31678,7 +32561,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31678
32561
  },
31679
32562
  [historyManager, persistConfig]
31680
32563
  );
31681
- const handleSetDefaultProvider = useCallback27(
32564
+ const handleSetDefaultProvider = useCallback28(
31682
32565
  async (provider2) => {
31683
32566
  const runtime = runtimeRef.current;
31684
32567
  const session = sessionRef.current;
@@ -31722,7 +32605,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31722
32605
  },
31723
32606
  [cwd, historyManager, persistConfig]
31724
32607
  );
31725
- const handleTestProvider = useCallback27(
32608
+ const handleTestProvider = useCallback28(
31726
32609
  async (provider2) => {
31727
32610
  const runtime = runtimeRef.current;
31728
32611
  const session = sessionRef.current;
@@ -31770,7 +32653,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31770
32653
  },
31771
32654
  []
31772
32655
  );
31773
- const handleFetchModels = useCallback27(
32656
+ const handleFetchModels = useCallback28(
31774
32657
  async (provider2, signal) => {
31775
32658
  const runtime = runtimeRef.current;
31776
32659
  if (!runtime) throw new Error("Runtime not ready.");
@@ -31778,14 +32661,14 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31778
32661
  },
31779
32662
  []
31780
32663
  );
31781
- const handleSelectModel = useCallback27(
32664
+ const handleSelectModel = useCallback28(
31782
32665
  (modelId) => {
31783
32666
  setSessionModel(modelId);
31784
32667
  setActiveDialog(null);
31785
32668
  },
31786
32669
  [setSessionModel]
31787
32670
  );
31788
- const handleSelectSession = useCallback27(
32671
+ const handleSelectSession = useCallback28(
31789
32672
  async (sessionId) => {
31790
32673
  const runtime = runtimeRef.current;
31791
32674
  if (!runtime) return;
@@ -31803,6 +32686,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31803
32686
  setCurrentModel(existing.model ?? "(unconfigured)");
31804
32687
  setProviderLabel(formatProviderLabel(existing.provider, existing.model));
31805
32688
  setTargetSource("session");
32689
+ setSessionDisplayName(typeof existing.metadata["name"] === "string" ? existing.metadata["name"] : "");
31806
32690
  historyManager.clearItems();
31807
32691
  setHistoryRemountKey((k) => k + 1);
31808
32692
  restoreHistoryFromSession(existing, (item) => historyManager.addItem(item, Date.now()));
@@ -31814,9 +32698,9 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31814
32698
  },
31815
32699
  [historyManager]
31816
32700
  );
31817
- const closeDialog = useCallback27(() => setActiveDialog(null), []);
31818
- const previewTheme = useCallback27(() => setThemeVersion((version) => version + 1), []);
31819
- useEffect28(() => {
32701
+ const closeDialog = useCallback28(() => setActiveDialog(null), []);
32702
+ const previewTheme = useCallback28(() => setThemeVersion((version) => version + 1), []);
32703
+ useEffect32(() => {
31820
32704
  if (drainingQueueRef.current || isRunning || isInitializing || Boolean(initError) || approvalQueue.length > 0 || messageQueue.length === 0) {
31821
32705
  return;
31822
32706
  }
@@ -31938,7 +32822,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31938
32822
  themeName,
31939
32823
  permissionSummary,
31940
32824
  authSummary,
31941
- commandNames: slashCommands.map((command) => `/${command.name}`)
32825
+ commandNames: slashCommands.map((command) => `/${command.name}`),
32826
+ commands: slashCommands.map((command) => ({ name: command.name, description: command.description }))
31942
32827
  }),
31943
32828
  [
31944
32829
  activeDialog,
@@ -31965,7 +32850,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31965
32850
  quittingMessages: null,
31966
32851
  streamingState,
31967
32852
  thought: null,
31968
- currentLoadingPhrase: iterationInfo ? `Iteration ${iterationInfo.round}/${iterationInfo.max}` : "",
32853
+ currentLoadingPhrase: iterationInfo ? `Iteration ${iterationInfo.round}/${iterationInfo.max}` : hookPhrase,
31969
32854
  elapsedTime,
31970
32855
  streamingResponseLengthRef,
31971
32856
  isReceivingContent,
@@ -31995,11 +32880,13 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
31995
32880
  mainControlsRef,
31996
32881
  constrainHeight,
31997
32882
  currentModel,
31998
- sessionName: path16.basename(cwd),
32883
+ sessionName: sessionDisplayName || path19.basename(cwd),
31999
32884
  isConfigInitialized: !isInitializing && !initError,
32000
32885
  sessionStats: {
32001
32886
  lastPromptTokenCount,
32002
- lastOutputTokenCount
32887
+ lastOutputTokenCount,
32888
+ totalPromptTokenCount,
32889
+ totalOutputTokenCount
32003
32890
  },
32004
32891
  dialogsVisible: activeDialog !== null || pendingCommandConfirmation !== null,
32005
32892
  isHelpDialogOpen: activeDialog === "help",
@@ -32009,12 +32896,13 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32009
32896
  isProviderDialogOpen: activeDialog === "provider",
32010
32897
  isPermissionsDialogOpen: activeDialog === "permissions",
32011
32898
  isFeedbackDialogOpen: false,
32012
- showAutoAcceptIndicator: "default",
32899
+ showAutoAcceptIndicator: approvalMode,
32013
32900
  mcpConnected,
32014
32901
  mcpTotal,
32015
32902
  activeSubagents
32016
32903
  }),
32017
32904
  [
32905
+ approvalMode,
32018
32906
  approvalQueue.length,
32019
32907
  subagentMap,
32020
32908
  activeDialog,
@@ -32027,6 +32915,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32027
32915
  dismissPromptSuggestion,
32028
32916
  promptSuggestion,
32029
32917
  elapsedTime,
32918
+ sessionDisplayName,
32030
32919
  historyManager,
32031
32920
  historyRemountKey,
32032
32921
  initError,
@@ -32035,6 +32924,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32035
32924
  iterationInfo,
32036
32925
  lastOutputTokenCount,
32037
32926
  lastPromptTokenCount,
32927
+ totalOutputTokenCount,
32928
+ totalPromptTokenCount,
32038
32929
  mainAreaWidth,
32039
32930
  mcpConnected,
32040
32931
  mcpTotal,
@@ -32053,8 +32944,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32053
32944
  userMessages
32054
32945
  ]
32055
32946
  );
32056
- return /* @__PURE__ */ jsx57(AppContext.Provider, { value: appContextValue, children: /* @__PURE__ */ jsx57(CompactModeProvider, { value: { compactMode }, children: /* @__PURE__ */ jsx57(ConfigContext.Provider, { value: configAdapter, children: /* @__PURE__ */ jsx57(SettingsContext.Provider, { value: loadedSettings, children: /* @__PURE__ */ jsx57(StreamingContext.Provider, { value: streamingState, children: /* @__PURE__ */ jsx57(VimModeProvider, { initialVimEnabled: loadedSettings.merged.general?.vimMode ?? false, children: /* @__PURE__ */ jsx57(KeypressProvider, { kittyProtocolEnabled: false, config: configAdapter, children: /* @__PURE__ */ jsx57(ShellFocusContext.Provider, { value: true, children: /* @__PURE__ */ jsx57(AgentViewProvider, { children: /* @__PURE__ */ jsx57(BackgroundTaskViewProvider, { children: /* @__PURE__ */ jsx57(UIStateContext.Provider, { value: uiState, children: /* @__PURE__ */ jsx57(UIActionsContext.Provider, { value: uiActions, children: /* @__PURE__ */ jsxs51(Box47, { flexDirection: "column", flexGrow: 1, children: [
32057
- /* @__PURE__ */ jsx57(
32947
+ return /* @__PURE__ */ jsx62(AppContext.Provider, { value: appContextValue, children: /* @__PURE__ */ jsx62(CompactModeProvider, { value: { compactMode }, children: /* @__PURE__ */ jsx62(ConfigContext.Provider, { value: configAdapter, children: /* @__PURE__ */ jsx62(SettingsContext.Provider, { value: loadedSettings, children: /* @__PURE__ */ jsx62(StreamingContext.Provider, { value: streamingState, children: /* @__PURE__ */ jsx62(VimModeProvider, { initialVimEnabled: loadedSettings.merged.general?.vimMode ?? false, children: /* @__PURE__ */ jsx62(KeypressProvider, { kittyProtocolEnabled: false, config: configAdapter, children: /* @__PURE__ */ jsx62(ShellFocusContext.Provider, { value: true, children: /* @__PURE__ */ jsx62(AgentViewProvider, { children: /* @__PURE__ */ jsx62(BackgroundTaskViewProvider, { children: /* @__PURE__ */ jsx62(UIStateContext.Provider, { value: uiState, children: /* @__PURE__ */ jsx62(UIActionsContext.Provider, { value: uiActions, children: /* @__PURE__ */ jsxs56(Box52, { flexDirection: "column", flexGrow: 1, children: [
32948
+ /* @__PURE__ */ jsx62(
32058
32949
  AppHeader,
32059
32950
  {
32060
32951
  version: VERSION,
@@ -32064,11 +32955,11 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32064
32955
  iterationInfo
32065
32956
  }
32066
32957
  ),
32067
- initError ? /* @__PURE__ */ jsx57(Box47, { marginLeft: 2, marginRight: 2, children: /* @__PURE__ */ jsxs51(Text55, { color: theme.status.error, children: [
32958
+ initError ? /* @__PURE__ */ jsx62(Box52, { marginLeft: 2, marginRight: 2, children: /* @__PURE__ */ jsxs56(Text60, { color: theme.status.error, children: [
32068
32959
  "Failed to initialize runtime: ",
32069
32960
  initError
32070
- ] }) }) : /* @__PURE__ */ jsxs51(Box47, { flexDirection: "column", flexGrow: 1, children: [
32071
- /* @__PURE__ */ jsx57(
32961
+ ] }) }) : /* @__PURE__ */ jsxs56(Box52, { flexDirection: "column", flexGrow: 1, children: [
32962
+ /* @__PURE__ */ jsx62(
32072
32963
  MainContent,
32073
32964
  {
32074
32965
  history: historyManager.history,
@@ -32080,11 +32971,11 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32080
32971
  isFocused: approvalQueue.length === 0
32081
32972
  }
32082
32973
  ),
32083
- /* @__PURE__ */ jsx57(ShowMoreLines, { constrainHeight })
32974
+ /* @__PURE__ */ jsx62(ShowMoreLines, { constrainHeight })
32084
32975
  ] }),
32085
- approvalQueue.length > 0 && /* @__PURE__ */ jsx57(Box47, { marginLeft: 2, marginRight: 2, marginTop: 1, children: /* @__PURE__ */ jsx57(ApprovalPrompt, { request: approvalQueue[0] }) }),
32086
- dialogModel && /* @__PURE__ */ jsx57(CommandDialog, { title: dialogModel.title, lines: dialogModel.lines }),
32087
- activeDialog === "provider" && /* @__PURE__ */ jsx57(
32976
+ approvalQueue.length > 0 && /* @__PURE__ */ jsx62(Box52, { marginLeft: 2, marginRight: 2, marginTop: 1, children: /* @__PURE__ */ jsx62(ApprovalPrompt, { request: approvalQueue[0] }) }),
32977
+ dialogModel && /* @__PURE__ */ jsx62(CommandDialog, { title: dialogModel.title, lines: dialogModel.lines }),
32978
+ activeDialog === "provider" && /* @__PURE__ */ jsx62(
32088
32979
  ProviderDialog,
32089
32980
  {
32090
32981
  providers: listAvailableProviders(),
@@ -32099,7 +32990,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32099
32990
  onClose: closeDialog
32100
32991
  }
32101
32992
  ),
32102
- activeDialog === "model" && /* @__PURE__ */ jsx57(
32993
+ activeDialog === "model" && /* @__PURE__ */ jsx62(
32103
32994
  ModelDialog,
32104
32995
  {
32105
32996
  currentProvider: getSessionCommandState().provider,
@@ -32109,7 +33000,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32109
33000
  onClose: closeDialog
32110
33001
  }
32111
33002
  ),
32112
- activeDialog === "theme" && /* @__PURE__ */ jsx57(
33003
+ activeDialog === "theme" && /* @__PURE__ */ jsx62(
32113
33004
  ThemeDialog,
32114
33005
  {
32115
33006
  onSelect: handleSelectTheme,
@@ -32117,7 +33008,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32117
33008
  onPreview: previewTheme
32118
33009
  }
32119
33010
  ),
32120
- activeDialog === "permissions" && /* @__PURE__ */ jsx57(
33011
+ activeDialog === "permissions" && /* @__PURE__ */ jsx62(
32121
33012
  PermissionsDialog,
32122
33013
  {
32123
33014
  current: permissionModes,
@@ -32125,7 +33016,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32125
33016
  onClose: closeDialog
32126
33017
  }
32127
33018
  ),
32128
- activeDialog === "auth" && runtimeRef.current && /* @__PURE__ */ jsx57(
33019
+ activeDialog === "auth" && runtimeRef.current && /* @__PURE__ */ jsx62(
32129
33020
  AuthDialog,
32130
33021
  {
32131
33022
  clientId: runtimeRef.current.config.github.oauthClientId,
@@ -32138,8 +33029,8 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32138
33029
  onClose: closeDialog
32139
33030
  }
32140
33031
  ),
32141
- activeDialog === "feedback" && /* @__PURE__ */ jsx57(FeedbackDialog, { cwd, onClose: closeDialog }),
32142
- activeDialog === "sessions" && /* @__PURE__ */ jsx57(
33032
+ activeDialog === "feedback" && /* @__PURE__ */ jsx62(FeedbackDialog, { cwd, onClose: closeDialog }),
33033
+ activeDialog === "sessions" && /* @__PURE__ */ jsx62(
32143
33034
  SessionsDialog,
32144
33035
  {
32145
33036
  cwd,
@@ -32147,7 +33038,7 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32147
33038
  onClose: closeDialog
32148
33039
  }
32149
33040
  ),
32150
- pendingCommandConfirmation && /* @__PURE__ */ jsx57(
33041
+ pendingCommandConfirmation && /* @__PURE__ */ jsx62(
32151
33042
  CommandDialog,
32152
33043
  {
32153
33044
  title: "Confirm action",
@@ -32159,15 +33050,23 @@ var AppContainer = ({ cwd, config, provider, model, resumeSessionId, startupWarn
32159
33050
  footerText: "Press y or Enter to confirm. Press n or Esc to cancel."
32160
33051
  }
32161
33052
  ),
32162
- /* @__PURE__ */ jsx57(
33053
+ /* @__PURE__ */ jsx62(
32163
33054
  SubagentsPanel,
32164
33055
  {
32165
33056
  subagents: Array.from(subagentMap.values()),
32166
33057
  mainAreaWidth
32167
33058
  }
32168
33059
  ),
32169
- /* @__PURE__ */ jsx57(Notifications, {}),
32170
- /* @__PURE__ */ jsx57(Composer, {})
33060
+ stickyTodos && /* @__PURE__ */ jsx62(
33061
+ StickyTodoList,
33062
+ {
33063
+ todos: stickyTodos,
33064
+ width: mainAreaWidth,
33065
+ maxVisibleItems: stickyTodoMaxItems
33066
+ }
33067
+ ),
33068
+ /* @__PURE__ */ jsx62(Notifications, {}),
33069
+ /* @__PURE__ */ jsx62(Composer, {})
32171
33070
  ] }) }) }) }) }) }) }) }) }) }) }) }) });
32172
33071
  };
32173
33072
  function formatProviderLabel(provider, model) {
@@ -32210,11 +33109,11 @@ function isInteractiveDialog(dialog) {
32210
33109
  return dialog === "theme" || dialog === "permissions" || dialog === "auth" || dialog === "provider" || dialog === "model" || dialog === "feedback" || dialog === "sessions";
32211
33110
  }
32212
33111
  function tuiThemeFilePath(cwd) {
32213
- return path16.join(cwd, ".deepcode", "tui-theme.json");
33112
+ return path19.join(cwd, ".deepcode", "tui-theme.json");
32214
33113
  }
32215
33114
  function readSavedTheme(cwd) {
32216
33115
  try {
32217
- const parsed = JSON.parse(fs9.readFileSync(tuiThemeFilePath(cwd), "utf8"));
33116
+ const parsed = JSON.parse(fs12.readFileSync(tuiThemeFilePath(cwd), "utf8"));
32218
33117
  return typeof parsed.theme === "string" ? parsed.theme : null;
32219
33118
  } catch {
32220
33119
  return null;
@@ -32222,16 +33121,16 @@ function readSavedTheme(cwd) {
32222
33121
  }
32223
33122
  function writeSavedTheme(cwd, themeName) {
32224
33123
  const file = tuiThemeFilePath(cwd);
32225
- fs9.mkdirSync(path16.dirname(file), { recursive: true });
32226
- fs9.writeFileSync(file, `${JSON.stringify({ theme: themeName }, null, 2)}
33124
+ fs12.mkdirSync(path19.dirname(file), { recursive: true });
33125
+ fs12.writeFileSync(file, `${JSON.stringify({ theme: themeName }, null, 2)}
32227
33126
  `);
32228
33127
  }
32229
33128
  function tuiProviderFilePath(cwd) {
32230
- return path16.join(cwd, ".deepcode", "tui-provider.json");
33129
+ return path19.join(cwd, ".deepcode", "tui-provider.json");
32231
33130
  }
32232
33131
  function readSavedProvider(cwd) {
32233
33132
  try {
32234
- const parsed = JSON.parse(fs9.readFileSync(tuiProviderFilePath(cwd), "utf8"));
33133
+ const parsed = JSON.parse(fs12.readFileSync(tuiProviderFilePath(cwd), "utf8"));
32235
33134
  const result = ProviderIdSchema.safeParse(parsed.provider);
32236
33135
  if (!result.success) return null;
32237
33136
  return {
@@ -32244,8 +33143,8 @@ function readSavedProvider(cwd) {
32244
33143
  }
32245
33144
  function writeSavedProvider(cwd, provider, model) {
32246
33145
  const file = tuiProviderFilePath(cwd);
32247
- fs9.mkdirSync(path16.dirname(file), { recursive: true });
32248
- fs9.writeFileSync(file, `${JSON.stringify({ provider, model }, null, 2)}
33146
+ fs12.mkdirSync(path19.dirname(file), { recursive: true });
33147
+ fs12.writeFileSync(file, `${JSON.stringify({ provider, model }, null, 2)}
32249
33148
  `);
32250
33149
  }
32251
33150
  function errorMessage(error) {
@@ -32254,12 +33153,13 @@ function errorMessage(error) {
32254
33153
  function buildDialogModel(dialog, options) {
32255
33154
  if (!dialog) return null;
32256
33155
  if (dialog === "help") {
33156
+ const maxNameLen = Math.max(...options.commands.map((c) => c.name.length + 1));
32257
33157
  return {
32258
- title: "Help",
32259
- lines: [
32260
- "Available commands:",
32261
- ...options.commandNames
32262
- ]
33158
+ title: "Comandos dispon\xEDveis",
33159
+ lines: options.commands.map((c) => {
33160
+ const label = `/${c.name}`.padEnd(maxNameLen + 1);
33161
+ return `${label} ${c.description}`;
33162
+ })
32263
33163
  };
32264
33164
  }
32265
33165
  if (dialog === "settings") {
@@ -32291,22 +33191,22 @@ function formatAuthSummary(config) {
32291
33191
  var ApprovalPrompt = ({ request }) => {
32292
33192
  if (!request) return null;
32293
33193
  const operationLabel = formatApprovalOperationLabel(request);
32294
- return /* @__PURE__ */ jsxs51(Box47, { flexDirection: "column", marginTop: 1, children: [
32295
- /* @__PURE__ */ jsxs51(Text55, { color: theme.status.warning, children: [
33194
+ return /* @__PURE__ */ jsxs56(Box52, { flexDirection: "column", marginTop: 1, children: [
33195
+ /* @__PURE__ */ jsxs56(Text60, { color: theme.status.warning, children: [
32296
33196
  "\u26A0 Allow ",
32297
33197
  operationLabel,
32298
33198
  "?"
32299
33199
  ] }),
32300
- request.path && /* @__PURE__ */ jsxs51(Text55, { color: theme.text.secondary, children: [
33200
+ request.path && /* @__PURE__ */ jsxs56(Text60, { color: theme.text.secondary, children: [
32301
33201
  " ",
32302
33202
  request.path
32303
33203
  ] }),
32304
- request.preview?.command && /* @__PURE__ */ jsxs51(Text55, { color: theme.text.secondary, children: [
33204
+ request.preview?.command && /* @__PURE__ */ jsxs56(Text60, { color: theme.text.secondary, children: [
32305
33205
  " $ ",
32306
33206
  request.preview.command,
32307
33207
  request.preview.args?.length ? ` ${request.preview.args.join(" ")}` : ""
32308
33208
  ] }),
32309
- /* @__PURE__ */ jsx57(Text55, { color: theme.text.secondary, children: " [\u21B5/y] once [s] session [a] always [n] deny" })
33209
+ /* @__PURE__ */ jsx62(Text60, { color: theme.text.secondary, children: " [\u21B5/y] once [s] session [a] always [n] deny" })
32310
33210
  ] });
32311
33211
  };
32312
33212
  function formatApprovalOperationLabel(request) {
@@ -32367,7 +33267,7 @@ var DeepCodeConfigAdapter = class {
32367
33267
  }
32368
33268
  };
32369
33269
  function App(props) {
32370
- return /* @__PURE__ */ jsx58(
33270
+ return /* @__PURE__ */ jsx63(
32371
33271
  AppContainer,
32372
33272
  {
32373
33273
  cwd: props.cwd,
@@ -32563,7 +33463,7 @@ function createProgram() {
32563
33463
  });
32564
33464
  program.command("chat", { isDefault: true }).description("open the terminal UI").option("--provider <provider>", "provider override for this chat session").option("--model <model>", "model override for this chat session (or <provider>/<model>)").option("--resume <id>", "resume a previous session by ID").action((options) => {
32565
33465
  render3(
32566
- React40.createElement(App, {
33466
+ React42.createElement(App, {
32567
33467
  cwd: program.opts().cwd,
32568
33468
  config: program.opts().config,
32569
33469
  provider: options.provider,