@tutti-os/agent-gui 0.0.94 → 0.0.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/README.md +86 -38
  2. package/dist/AgentGUI-DWdvUV4x.d.ts +1038 -0
  3. package/dist/agent-conversation/index.d.ts +6 -7
  4. package/dist/agent-conversation/index.js +15 -10
  5. package/dist/agent-conversation/index.js.map +1 -1
  6. package/dist/agent-env/index.d.ts +10 -36
  7. package/dist/agent-env/index.js +2 -57
  8. package/dist/agent-env/index.js.map +1 -1
  9. package/dist/agent-gui.d.ts +21 -0
  10. package/dist/agent-gui.js +39 -0
  11. package/dist/agent-message-center/index.d.ts +156 -124
  12. package/dist/agent-message-center/index.js +1656 -1463
  13. package/dist/agent-message-center/index.js.map +1 -1
  14. package/dist/{agentConversationVM-Cl4G0Lln.d.ts → agentConversationVM-C335TR6S.d.ts} +112 -7
  15. package/dist/agentFileMentionContracts-58IjMU-u.d.ts +108 -0
  16. package/dist/{agentGuiNodeTypes-CAioPXK9.d.ts → agentGuiNodeTypes-B9X4aWfv.d.ts} +123 -163
  17. package/dist/agentPlanPromptDispatch-C7cCMjve.d.ts +37 -0
  18. package/dist/agents.d.ts +13 -0
  19. package/dist/agents.js +13 -0
  20. package/dist/app/renderer/agentactivity.css +276 -83
  21. package/dist/app/renderer/assets/icons/agent-vinyls/tutti-vinyl.png +0 -0
  22. package/dist/app/renderer/assets/icons/open-link-lined.svg +4 -0
  23. package/dist/{chunk-7BUYFVRI.js → chunk-2HJEOO7W.js} +2931 -2946
  24. package/dist/chunk-2HJEOO7W.js.map +1 -0
  25. package/dist/{chunk-E5FOXRUM.js → chunk-3XXBDYAI.js} +293 -258
  26. package/dist/chunk-3XXBDYAI.js.map +1 -0
  27. package/dist/{chunk-ZUW4B5AT.js → chunk-3Y3F7CS5.js} +21 -32
  28. package/dist/chunk-3Y3F7CS5.js.map +1 -0
  29. package/dist/{chunk-SCLLP5DO.js → chunk-4PQPJ5OY.js} +50 -155
  30. package/dist/chunk-4PQPJ5OY.js.map +1 -0
  31. package/dist/chunk-4YG7YK7S.js +23 -0
  32. package/dist/chunk-4YG7YK7S.js.map +1 -0
  33. package/dist/chunk-5X7YDOC6.js +42 -0
  34. package/dist/chunk-5X7YDOC6.js.map +1 -0
  35. package/dist/{chunk-R2EWECUP.js → chunk-7BXWPI4F.js} +17 -2
  36. package/dist/{chunk-R2EWECUP.js.map → chunk-7BXWPI4F.js.map} +1 -1
  37. package/dist/chunk-AGT7MUTV.js +491 -0
  38. package/dist/chunk-AGT7MUTV.js.map +1 -0
  39. package/dist/chunk-C35SNDVZ.js +96 -0
  40. package/dist/chunk-C35SNDVZ.js.map +1 -0
  41. package/dist/{chunk-5FE7M42A.js → chunk-E4HQUTM3.js} +2 -2
  42. package/dist/chunk-FGLQZ6I4.js +9 -0
  43. package/dist/chunk-FGLQZ6I4.js.map +1 -0
  44. package/dist/chunk-H5F3QSCF.js +25 -0
  45. package/dist/chunk-H5F3QSCF.js.map +1 -0
  46. package/dist/chunk-H6IQ63DQ.js +14 -0
  47. package/dist/chunk-H6IQ63DQ.js.map +1 -0
  48. package/dist/{chunk-45FF4DQU.js → chunk-IYEXLOUE.js} +22 -27
  49. package/dist/chunk-IYEXLOUE.js.map +1 -0
  50. package/dist/{chunk-P72YLKC6.js → chunk-JKIZA7EJ.js} +3573 -3755
  51. package/dist/chunk-JKIZA7EJ.js.map +1 -0
  52. package/dist/chunk-KJQERFKX.js +259 -0
  53. package/dist/chunk-KJQERFKX.js.map +1 -0
  54. package/dist/{chunk-XW4CVBUH.js → chunk-L3GMMGRS.js} +25 -16
  55. package/dist/chunk-L3GMMGRS.js.map +1 -0
  56. package/dist/chunk-MASXZENX.js +231 -0
  57. package/dist/chunk-MASXZENX.js.map +1 -0
  58. package/dist/{chunk-BXVPOGYK.js → chunk-O3Q5SIJH.js} +505 -504
  59. package/dist/chunk-O3Q5SIJH.js.map +1 -0
  60. package/dist/{chunk-554VG7ZW.js → chunk-QVBF5BN5.js} +2 -2
  61. package/dist/{chunk-AWAIUYG4.js → chunk-RE4AXS27.js} +532 -565
  62. package/dist/chunk-RE4AXS27.js.map +1 -0
  63. package/dist/{chunk-7LMJXF4R.js → chunk-TVIGLNNI.js} +20 -16
  64. package/dist/chunk-TVIGLNNI.js.map +1 -0
  65. package/dist/{chunk-XDV4ZRVK.js → chunk-UGVI47X6.js} +98 -37
  66. package/dist/chunk-UGVI47X6.js.map +1 -0
  67. package/dist/{chunk-GAPTLVII.js → chunk-UHBCM6RO.js} +1 -1
  68. package/dist/chunk-UHBCM6RO.js.map +1 -0
  69. package/dist/{chunk-UBDPV34P.js → chunk-W6WAGPMD.js} +1385 -1305
  70. package/dist/chunk-W6WAGPMD.js.map +1 -0
  71. package/dist/chunk-WKSFPJHZ.js +33054 -0
  72. package/dist/chunk-WKSFPJHZ.js.map +1 -0
  73. package/dist/{chunk-IGY4ASUF.js → chunk-WMNS4MAQ.js} +1288 -1696
  74. package/dist/chunk-WMNS4MAQ.js.map +1 -0
  75. package/dist/{chunk-MATIJPGF.js → chunk-XPFHJMZP.js} +541 -401
  76. package/dist/chunk-XPFHJMZP.js.map +1 -0
  77. package/dist/chunk-YMXYBG7U.js +12 -0
  78. package/dist/chunk-YMXYBG7U.js.map +1 -0
  79. package/dist/context-mention-palette/index.d.ts +3 -2
  80. package/dist/context-mention-palette/index.js +17 -12
  81. package/dist/custom-mention.d.ts +42 -0
  82. package/dist/custom-mention.js +17 -0
  83. package/dist/custom-mention.js.map +1 -0
  84. package/dist/dock-icons.d.ts +4 -0
  85. package/dist/dock-icons.js +11 -0
  86. package/dist/dock-icons.js.map +1 -0
  87. package/dist/i18n/index.d.ts +880 -841
  88. package/dist/i18n/index.js +2 -2
  89. package/dist/index.d.ts +56 -1063
  90. package/dist/index.js +78 -35532
  91. package/dist/index.js.map +1 -1
  92. package/dist/mention-search.d.ts +226 -0
  93. package/dist/mention-search.js +29 -0
  94. package/dist/mention-search.js.map +1 -0
  95. package/dist/open-link-lined-JWEKUKME.svg +4 -0
  96. package/dist/pastedTextKinds-D-XuInaS.d.ts +4 -0
  97. package/dist/provider-icons.d.ts +6 -0
  98. package/dist/provider-icons.js +12 -0
  99. package/dist/provider-icons.js.map +1 -0
  100. package/dist/provider-identity.d.ts +9 -0
  101. package/dist/provider-identity.js +21 -0
  102. package/dist/provider-identity.js.map +1 -0
  103. package/dist/runtime-BBNdWgDU.d.ts +10 -0
  104. package/dist/startup-shell.d.ts +8 -0
  105. package/dist/startup-shell.js +184 -0
  106. package/dist/startup-shell.js.map +1 -0
  107. package/dist/{types-PLFZ8SBX.d.ts → types-CnT8rNUI.d.ts} +43 -87
  108. package/dist/workbench/contribution.d.ts +34 -41
  109. package/dist/workbench/contribution.js +10 -6
  110. package/dist/workbench/index.d.ts +5 -4
  111. package/dist/workbench/index.js +27 -25
  112. package/dist/workbench/launch.d.ts +4 -7
  113. package/dist/workbench/launch.js +4 -3
  114. package/dist/workbench/providerCatalog.d.ts +2 -2
  115. package/dist/workbench/providerCatalog.js +2 -1
  116. package/dist/workbench/sessionTitle.d.ts +11 -14
  117. package/dist/workbench/sessionTitle.js +6 -7
  118. package/dist/workbench/state.d.ts +1 -1
  119. package/dist/workbench/state.js +3 -2
  120. package/dist/workbench/types.d.ts +2 -4
  121. package/dist/workbench/types.js +1 -1
  122. package/dist/workspace-agent-generated-files.d.ts +20 -2
  123. package/dist/workspace-agent-generated-files.js +6 -5
  124. package/dist/workspaceAgentActivityListTypes-C7gPWYiA.d.ts +71 -0
  125. package/package.json +70 -26
  126. package/dist/AgentMentionSearchController-DD_WOred.d.ts +0 -241
  127. package/dist/AgentMessageMarkdown-DeYPURtF.d.ts +0 -7
  128. package/dist/chunk-45FF4DQU.js.map +0 -1
  129. package/dist/chunk-4HP6V2YA.js +0 -207
  130. package/dist/chunk-4HP6V2YA.js.map +0 -1
  131. package/dist/chunk-7BUYFVRI.js.map +0 -1
  132. package/dist/chunk-7LMJXF4R.js.map +0 -1
  133. package/dist/chunk-AWAIUYG4.js.map +0 -1
  134. package/dist/chunk-BXVPOGYK.js.map +0 -1
  135. package/dist/chunk-E5FOXRUM.js.map +0 -1
  136. package/dist/chunk-GAPTLVII.js.map +0 -1
  137. package/dist/chunk-IBIMGLCD.js +0 -66
  138. package/dist/chunk-IBIMGLCD.js.map +0 -1
  139. package/dist/chunk-IGY4ASUF.js.map +0 -1
  140. package/dist/chunk-LR4FA5X6.js +0 -368
  141. package/dist/chunk-LR4FA5X6.js.map +0 -1
  142. package/dist/chunk-MATIJPGF.js.map +0 -1
  143. package/dist/chunk-MKHDRIGN.js +0 -71
  144. package/dist/chunk-MKHDRIGN.js.map +0 -1
  145. package/dist/chunk-P72YLKC6.js.map +0 -1
  146. package/dist/chunk-SCLLP5DO.js.map +0 -1
  147. package/dist/chunk-UBDPV34P.js.map +0 -1
  148. package/dist/chunk-VAKFNNKT.js +0 -410
  149. package/dist/chunk-VAKFNNKT.js.map +0 -1
  150. package/dist/chunk-XDV4ZRVK.js.map +0 -1
  151. package/dist/chunk-XW4CVBUH.js.map +0 -1
  152. package/dist/chunk-ZUW4B5AT.js.map +0 -1
  153. package/dist/plan-decision-ops.d.ts +0 -70
  154. package/dist/plan-decision-ops.js +0 -19
  155. package/dist/queued-prompt-runtime.d.ts +0 -115
  156. package/dist/queued-prompt-runtime.js +0 -9
  157. package/dist/uiSettings-BQS9r2eo.d.ts +0 -6
  158. package/dist/workspaceAgentActivityListViewModel-BzV-cf0D.d.ts +0 -340
  159. package/dist/workspaceLinkActions-DS9LWqzI.d.ts +0 -74
  160. /package/dist/{plan-decision-ops.js.map → agent-gui.js.map} +0 -0
  161. /package/dist/{queued-prompt-runtime.js.map → agents.js.map} +0 -0
  162. /package/dist/{chunk-5FE7M42A.js.map → chunk-E4HQUTM3.js.map} +0 -0
  163. /package/dist/{chunk-554VG7ZW.js.map → chunk-QVBF5BN5.js.map} +0 -0
@@ -0,0 +1,42 @@
1
+ // shared/agentCustomMentionKinds.ts
2
+ var registry = /* @__PURE__ */ new Map();
3
+ var RESERVED_AGENT_MENTION_PROVIDER_IDS = /* @__PURE__ */ new Set([
4
+ "agent-session",
5
+ "agent-target",
6
+ "custom",
7
+ "file",
8
+ "issue",
9
+ "session",
10
+ "task",
11
+ "workspace-app",
12
+ "workspace-app-factory",
13
+ "workspace-issue",
14
+ "workspace-reference"
15
+ ]);
16
+ function registerAgentCustomMentionKind(definition) {
17
+ const kind = definition.kind.trim().toLowerCase();
18
+ if (!kind) {
19
+ throw new Error(
20
+ "[agent-gui] custom mention kind must be a non-empty provider id"
21
+ );
22
+ }
23
+ if (RESERVED_AGENT_MENTION_PROVIDER_IDS.has(kind)) {
24
+ throw new Error(
25
+ `[agent-gui] custom mention kind "${kind}" collides with a built-in provider id`
26
+ );
27
+ }
28
+ registry.set(kind, definition);
29
+ }
30
+ function getAgentCustomMentionKind(kind) {
31
+ return registry.get(kind.trim().toLowerCase());
32
+ }
33
+ function resetAgentCustomMentionKindsForTests() {
34
+ registry.clear();
35
+ }
36
+
37
+ export {
38
+ registerAgentCustomMentionKind,
39
+ getAgentCustomMentionKind,
40
+ resetAgentCustomMentionKindsForTests
41
+ };
42
+ //# sourceMappingURL=chunk-5X7YDOC6.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../shared/agentCustomMentionKinds.ts"],"sourcesContent":["import type { ReactNode } from \"react\";\n\n// 自定义 mention kind 注册表:让宿主(如 tsh)从外部注册 mention://<kind>/... 链接的\n// 解析与 composer 内 chip 渲染,包内不内置任何具体业务 kind。\n//\n// 管线接点:\n// - 解析:agentFileMentionExtension.parseMentionItemFromHref 命中注册 kind 时产出\n// AgentMentionCustomItem(展示字段由 present() 提取;href 是完整信息源,round-trip 无损)\n// - 渲染:AgentMentionNodeView 对 kind===\"custom\" 调 renderChip(),缺省用包内通用双行卡\n// - 点击:clickable 的 kind 经 resolveWorkspaceMentionLinkAction 上抛\n// open-custom-mention 链接动作(携带原始 href,宿主自行二次解析)\n//\n// 注册时机:宿主渲染进程 bootstrap(早于首个 composer 挂载);模块级单例,重复注册以\n// 后者为准(HMR 友好)。\n\nexport interface AgentCustomMentionIdentity {\n entityId: string;\n label: string;\n scope?: Readonly<Record<string, string>>;\n}\n\nexport interface AgentCustomMentionPresentation {\n /** chip 第一行(缺省用链接 label)。 */\n name: string;\n /** chip 第二行(可选,通用双行卡的次要文案)。 */\n summary?: string;\n /** 所属 workspace(可选;custom kind 的 scope 键由注册方约定)。 */\n workspaceId?: string;\n}\n\nexport interface AgentCustomMentionChipContext {\n href: string;\n name: string;\n summary?: string;\n isEditable: boolean;\n /** 可编辑态的移除按钮,由 NodeView 注入;自定义渲染需自行摆放。 */\n removeAction?: ReactNode;\n}\n\nexport interface AgentCustomMentionKindDefinition {\n /** mention://<kind>/... 的 providerId(URL hostname,小写)。 */\n kind: string;\n /**\n * 从 canonical mention 链接提取展示字段;返回 null 表示链接无效,\n * 退化为普通链接/字面文本。\n */\n present(\n mention: AgentCustomMentionIdentity,\n href: string\n ): AgentCustomMentionPresentation | null;\n /** 自定义 chip 渲染;缺省用包内通用双行卡(name + summary)。 */\n renderChip?(context: AgentCustomMentionChipContext): ReactNode;\n /** 点击是否上抛 open-custom-mention 链接动作;缺省 false(chip 只展示)。 */\n clickable?: boolean;\n}\n\nconst registry = new Map<string, AgentCustomMentionKindDefinition>();\n\n// 包内管线已内置处理的 providerId(agentFileMentionExtension /\n// resolveWorkspaceMentionLinkAction),以及宿主侧沿用的 legacy 短名与内部 kind。\n// 注册表查找在部分链路先于内置分支执行,若放行同名注册会静默劫持内置 mention\n// 的解析——注册发生在宿主 bootstrap,直接抛错 fail-fast。\nconst RESERVED_AGENT_MENTION_PROVIDER_IDS = new Set([\n \"agent-session\",\n \"agent-target\",\n \"custom\",\n \"file\",\n \"issue\",\n \"session\",\n \"task\",\n \"workspace-app\",\n \"workspace-app-factory\",\n \"workspace-issue\",\n \"workspace-reference\"\n]);\n\nexport function registerAgentCustomMentionKind(\n definition: AgentCustomMentionKindDefinition\n): void {\n const kind = definition.kind.trim().toLowerCase();\n if (!kind) {\n throw new Error(\n \"[agent-gui] custom mention kind must be a non-empty provider id\"\n );\n }\n if (RESERVED_AGENT_MENTION_PROVIDER_IDS.has(kind)) {\n throw new Error(\n `[agent-gui] custom mention kind \"${kind}\" collides with a built-in provider id`\n );\n }\n registry.set(kind, definition);\n}\n\nexport function getAgentCustomMentionKind(\n kind: string\n): AgentCustomMentionKindDefinition | undefined {\n return registry.get(kind.trim().toLowerCase());\n}\n\nexport function resetAgentCustomMentionKindsForTests(): void {\n registry.clear();\n}\n"],"mappings":";AAwDA,IAAM,WAAW,oBAAI,IAA8C;AAMnE,IAAM,sCAAsC,oBAAI,IAAI;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAEM,SAAS,+BACd,YACM;AACN,QAAM,OAAO,WAAW,KAAK,KAAK,EAAE,YAAY;AAChD,MAAI,CAAC,MAAM;AACT,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACA,MAAI,oCAAoC,IAAI,IAAI,GAAG;AACjD,UAAM,IAAI;AAAA,MACR,oCAAoC,IAAI;AAAA,IAC1C;AAAA,EACF;AACA,WAAS,IAAI,MAAM,UAAU;AAC/B;AAEO,SAAS,0BACd,MAC8C;AAC9C,SAAO,SAAS,IAAI,KAAK,KAAK,EAAE,YAAY,CAAC;AAC/C;AAEO,SAAS,uCAA6C;AAC3D,WAAS,MAAM;AACjB;","names":[]}
@@ -125,6 +125,10 @@ var FAILED_MESSAGE_CODE_MARKERS = [
125
125
  [
126
126
  "network_error",
127
127
  ["enotfound", "econnrefused", "econnreset", "getaddrinfo", "socket hang up"]
128
+ ],
129
+ [
130
+ "quota_or_rate_limit",
131
+ ["upgrade your plan to continue", "add a payment method to continue"]
128
132
  ]
129
133
  ];
130
134
  function classifyFailedAgentMessage(body) {
@@ -139,6 +143,16 @@ function classifyFailedAgentMessage(body) {
139
143
  }
140
144
  return null;
141
145
  }
146
+ function isProviderPlanLimitMessage(detail) {
147
+ const normalized = detail?.trim().toLowerCase() ?? "";
148
+ if (!normalized) {
149
+ return false;
150
+ }
151
+ const markers = FAILED_MESSAGE_CODE_MARKERS.find(
152
+ ([code]) => code === "quota_or_rate_limit"
153
+ )?.[1] ?? [];
154
+ return markers.some((marker) => normalized.includes(marker));
155
+ }
142
156
 
143
157
  export {
144
158
  openAgentEnvPanel,
@@ -146,6 +160,7 @@ export {
146
160
  getAgentEnvPanelStore,
147
161
  useAgentEnvPanelRequest,
148
162
  resolveAgentErrorPresentation,
149
- classifyFailedAgentMessage
163
+ classifyFailedAgentMessage,
164
+ isProviderPlanLimitMessage
150
165
  };
151
- //# sourceMappingURL=chunk-R2EWECUP.js.map
166
+ //# sourceMappingURL=chunk-7BXWPI4F.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../shared/agentEnv/agentEnvPanelStore.ts","../shared/agentEnv/agentErrorPresentation.ts"],"sourcesContent":["import { useSnapshot } from \"valtio\";\nimport { proxy } from \"valtio/vanilla\";\n\n/**\n * Section the Agent Env panel (the片6 Setup Wizard / config panel) should scroll\n * to / emphasise when opened via a deep-link. The error card (片5) maps a domain\n * error code to one of these so the user lands on the relevant remediation.\n */\nexport type AgentEnvPanelFocus =\n | \"detect\"\n | \"install\"\n | \"repair\"\n | \"upgrade\"\n | \"auth\"\n | \"network\"\n | \"registry\";\n\nexport interface AgentEnvPanelRequest {\n open: boolean;\n provider: string | null;\n focus: AgentEnvPanelFocus | null;\n /**\n * Bumped on every openAgentEnvPanel() call. The host panel watches this to\n * re-run detection even when it is already open (e.g. a second deep-link).\n */\n requestSequence: number;\n}\n\nexport interface OpenAgentEnvPanelInput {\n provider?: string | null;\n focus?: AgentEnvPanelFocus | null;\n}\n\nconst agentEnvPanelStore = proxy<AgentEnvPanelRequest>({\n open: false,\n provider: null,\n focus: null,\n requestSequence: 0\n});\n\n/**\n * Open the agent environment panel. Safe to call from anywhere in the agent-gui\n * tree (rail footer entry, error-card deep-link). The host renders the actual\n * panel and reacts to this singleton store.\n */\nexport function openAgentEnvPanel(input?: OpenAgentEnvPanelInput): void {\n agentEnvPanelStore.open = true;\n agentEnvPanelStore.provider = input?.provider ?? null;\n agentEnvPanelStore.focus = input?.focus ?? null;\n agentEnvPanelStore.requestSequence += 1;\n}\n\nexport function closeAgentEnvPanel(): void {\n agentEnvPanelStore.open = false;\n}\n\n/** Imperative read, mainly for tests. Components should use the hook. */\nexport function getAgentEnvPanelStore(): AgentEnvPanelRequest {\n return agentEnvPanelStore;\n}\n\n/** Reactive snapshot of the panel request for the host renderer. */\nexport function useAgentEnvPanelRequest(): AgentEnvPanelRequest {\n return useSnapshot(agentEnvPanelStore);\n}\n","import type { AgentEnvPanelFocus } from \"./agentEnvPanelStore\";\n\n/**\n * Run-failure codes actually emitted by the daemon runtime classifier\n * (packages/agent/daemon/runtime/visible_error.go `visibleFailureCode`). These\n * are the codes the conversation error card really receives — unlike the\n * aspirational `CODEX_*` codes, which the run pipeline never produces.\n *\n * Keep this union aligned with the Go switch in `visibleFailureCode`.\n */\nexport type AgentRunErrorCode =\n | \"auth_required\"\n | \"cli_not_found\"\n | \"cli_version_unsupported\"\n | \"network_error\"\n | \"runtime_unavailable\"\n | \"request_timed_out\"\n | \"provider_config_timeout\"\n | \"provider_stream_disconnected\"\n | \"provider_concurrency_limit\"\n | \"insufficient_credits\"\n | \"quota_or_rate_limit\"\n | \"process_exited\"\n | \"provider_error\"\n | \"unknown\";\n\nexport interface AgentErrorPresentation {\n /**\n * i18n key for the one human sentence shown in the card, or null to let the\n * caller fall back to its phase-aware generic title.\n */\n messageKey: string | null;\n /**\n * Env-panel section the remediation button deep-links to, or null when the\n * failure is transient/server-side and the wizard cannot fix it — in which\n * case no call-to-action is shown (showing one would misrepresent reality).\n */\n focus: AgentEnvPanelFocus | null;\n /** i18n key for the remediation button. */\n actionKey: string | null;\n /** External remediation destination, when the action is account-level. */\n externalUrl?: string | null;\n}\n\nconst NO_CTA = { focus: null, actionKey: null } as const;\n\n// The escape hatch for hard failures whose cause is ambiguous from the message\n// alone (a non-zero exit, an unclassified provider error): send the user into\n// the wizard to self-detect, but keep the generic message.\nconst SELF_DETECT = {\n messageKey: null,\n focus: \"detect\" as const,\n actionKey: \"agentHost.agentGui.visibleErrorActionDetect\"\n};\n\nconst PRESENTATIONS: Record<AgentRunErrorCode, AgentErrorPresentation> = {\n // Environment problems the wizard can detect or repair → route to its step.\n auth_required: {\n messageKey: \"agentHost.agentGui.visibleErrorAuthRequired\",\n focus: \"auth\",\n actionKey: \"agentHost.agentGui.visibleErrorActionRelogin\"\n },\n cli_not_found: {\n messageKey: \"agentHost.agentGui.visibleErrorCliNotFound\",\n focus: \"install\",\n actionKey: \"agentHost.agentGui.visibleErrorActionInstall\"\n },\n cli_version_unsupported: {\n messageKey: \"agentHost.agentGui.visibleErrorVersionUnsupported\",\n focus: \"upgrade\",\n actionKey: \"agentHost.agentGui.visibleErrorActionUpgrade\"\n },\n network_error: {\n messageKey: \"agentHost.agentGui.visibleErrorNetwork\",\n focus: \"network\",\n actionKey: \"agentHost.agentGui.visibleErrorActionCheckNetwork\"\n },\n runtime_unavailable: {\n messageKey: \"agentHost.agentGui.visibleErrorRuntimeUnavailable\",\n focus: \"detect\",\n actionKey: \"agentHost.agentGui.visibleErrorActionDetect\"\n },\n // Transient / server-side failures: accurate copy, but no wizard CTA — it\n // cannot fix a rate limit or a dropped stream.\n request_timed_out: {\n messageKey: \"agentHost.agentGui.visibleErrorRequestTimedOut\",\n ...NO_CTA\n },\n provider_config_timeout: {\n messageKey: \"agentHost.agentGui.visibleErrorConfigTimeout\",\n ...NO_CTA\n },\n provider_stream_disconnected: {\n messageKey: \"agentHost.agentGui.visibleErrorStreamDisconnected\",\n ...NO_CTA\n },\n provider_concurrency_limit: {\n messageKey: \"agentHost.agentGui.visibleErrorConcurrencyLimit\",\n ...NO_CTA\n },\n insufficient_credits: {\n messageKey: \"agentHost.agentGui.visibleErrorInsufficientCredits\",\n focus: null,\n actionKey: \"agentHost.agentGui.visibleErrorActionViewPlans\",\n externalUrl: \"https://tutti.sh/profile/plan\"\n },\n quota_or_rate_limit: {\n messageKey: \"agentHost.agentGui.visibleErrorQuotaOrRateLimit\",\n ...NO_CTA\n },\n // Ambiguous hard failures → generic message + self-detect escape hatch.\n process_exited: SELF_DETECT,\n provider_error: SELF_DETECT,\n unknown: SELF_DETECT\n};\n\n/**\n * Resolves the card presentation for a run-failure code. Returns null for codes\n * outside the known vocabulary so the caller renders its plain generic card with\n * no call-to-action.\n */\nexport function resolveAgentErrorPresentation(\n code: string | null | undefined\n): AgentErrorPresentation | null {\n if (!code) {\n return null;\n }\n return PRESENTATIONS[code as AgentRunErrorCode] ?? null;\n}\n\nconst FAILED_MESSAGE_CODE_MARKERS: ReadonlyArray<\n readonly [AgentRunErrorCode, readonly string[]]\n> = [\n [\n \"auth_required\",\n [\n \"authentication_failed\",\n \"invalid authentication credentials\",\n \"401 invalid authentication\",\n \"unauthorized\",\n \"not logged in\",\n \"please run /login\",\n \"invalid api key\"\n ]\n ],\n [\n \"cli_version_unsupported\",\n [\"requires a newer version\", \"version is too old\", \"unsupported version\"]\n ],\n [\n \"cli_not_found\",\n [\n \"no such file or directory\",\n \"command not found\",\n \"enoent\",\n \"executable file not found\"\n ]\n ],\n [\n \"network_error\",\n [\"enotfound\", \"econnrefused\", \"econnreset\", \"getaddrinfo\", \"socket hang up\"]\n ]\n];\n\n/**\n * Some providers (notably Claude Code) report an environment failure — e.g. a\n * dropped login (401) — as a plain failed assistant message rather than a\n * structured visibleError, so it never gets the remediation card. This recovers\n * the env-fixable code from that message's text so the caller can still route the\n * user to the wizard. Returns null when the text isn't a recognized env failure\n * (so transient/unknown failures stay plain).\n */\nexport function classifyFailedAgentMessage(\n body: string | null | undefined\n): AgentRunErrorCode | null {\n if (!body) {\n return null;\n }\n const lower = body.toLowerCase();\n for (const [code, markers] of FAILED_MESSAGE_CODE_MARKERS) {\n if (markers.some((marker) => lower.includes(marker))) {\n return code;\n }\n }\n return null;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../shared/agentEnv/agentEnvPanelStore.ts","../shared/agentEnv/agentErrorPresentation.ts"],"sourcesContent":["import { useSnapshot } from \"valtio\";\nimport { proxy } from \"valtio/vanilla\";\n\n/**\n * Section the Agent Env panel (the片6 Setup Wizard / config panel) should scroll\n * to / emphasise when opened via a deep-link. The error card (片5) maps a domain\n * error code to one of these so the user lands on the relevant remediation.\n */\nexport type AgentEnvPanelFocus =\n | \"detect\"\n | \"install\"\n | \"repair\"\n | \"upgrade\"\n | \"auth\"\n | \"network\"\n | \"registry\";\n\nexport interface AgentEnvPanelRequest {\n open: boolean;\n provider: string | null;\n focus: AgentEnvPanelFocus | null;\n /**\n * Bumped on every openAgentEnvPanel() call. The host panel watches this to\n * re-run detection even when it is already open (e.g. a second deep-link).\n */\n requestSequence: number;\n}\n\nexport interface OpenAgentEnvPanelInput {\n provider?: string | null;\n focus?: AgentEnvPanelFocus | null;\n}\n\nconst agentEnvPanelStore = proxy<AgentEnvPanelRequest>({\n open: false,\n provider: null,\n focus: null,\n requestSequence: 0\n});\n\n/**\n * Open the agent environment panel. Safe to call from anywhere in the agent-gui\n * tree (rail footer entry, error-card deep-link). The host renders the actual\n * panel and reacts to this singleton store.\n */\nexport function openAgentEnvPanel(input?: OpenAgentEnvPanelInput): void {\n agentEnvPanelStore.open = true;\n agentEnvPanelStore.provider = input?.provider ?? null;\n agentEnvPanelStore.focus = input?.focus ?? null;\n agentEnvPanelStore.requestSequence += 1;\n}\n\nexport function closeAgentEnvPanel(): void {\n agentEnvPanelStore.open = false;\n}\n\n/** Imperative read, mainly for tests. Components should use the hook. */\nexport function getAgentEnvPanelStore(): AgentEnvPanelRequest {\n return agentEnvPanelStore;\n}\n\n/** Reactive snapshot of the panel request for the host renderer. */\nexport function useAgentEnvPanelRequest(): AgentEnvPanelRequest {\n return useSnapshot(agentEnvPanelStore);\n}\n","import type { AgentEnvPanelFocus } from \"./agentEnvPanelStore\";\n\n/**\n * Run-failure codes actually emitted by the daemon runtime classifier\n * (packages/agent/daemon/runtime/visible_error.go `visibleFailureCode`). These\n * are the codes the conversation error card really receives — unlike the\n * aspirational `CODEX_*` codes, which the run pipeline never produces.\n *\n * Keep this union aligned with the Go switch in `visibleFailureCode`.\n */\nexport type AgentRunErrorCode =\n | \"auth_required\"\n | \"cli_not_found\"\n | \"cli_version_unsupported\"\n | \"network_error\"\n | \"runtime_unavailable\"\n | \"request_timed_out\"\n | \"provider_config_timeout\"\n | \"provider_stream_disconnected\"\n | \"provider_concurrency_limit\"\n | \"insufficient_credits\"\n | \"quota_or_rate_limit\"\n | \"process_exited\"\n | \"provider_error\"\n | \"unknown\";\n\nexport interface AgentErrorPresentation {\n /**\n * i18n key for the one human sentence shown in the card, or null to let the\n * caller fall back to its phase-aware generic title.\n */\n messageKey: string | null;\n /**\n * Env-panel section the remediation button deep-links to, or null when the\n * failure is transient/server-side and the wizard cannot fix it — in which\n * case no call-to-action is shown (showing one would misrepresent reality).\n */\n focus: AgentEnvPanelFocus | null;\n /** i18n key for the remediation button. */\n actionKey: string | null;\n /** External remediation destination, when the action is account-level. */\n externalUrl?: string | null;\n}\n\nconst NO_CTA = { focus: null, actionKey: null } as const;\n\n// The escape hatch for hard failures whose cause is ambiguous from the message\n// alone (a non-zero exit, an unclassified provider error): send the user into\n// the wizard to self-detect, but keep the generic message.\nconst SELF_DETECT = {\n messageKey: null,\n focus: \"detect\" as const,\n actionKey: \"agentHost.agentGui.visibleErrorActionDetect\"\n};\n\nconst PRESENTATIONS: Record<AgentRunErrorCode, AgentErrorPresentation> = {\n // Environment problems the wizard can detect or repair → route to its step.\n auth_required: {\n messageKey: \"agentHost.agentGui.visibleErrorAuthRequired\",\n focus: \"auth\",\n actionKey: \"agentHost.agentGui.visibleErrorActionRelogin\"\n },\n cli_not_found: {\n messageKey: \"agentHost.agentGui.visibleErrorCliNotFound\",\n focus: \"install\",\n actionKey: \"agentHost.agentGui.visibleErrorActionInstall\"\n },\n cli_version_unsupported: {\n messageKey: \"agentHost.agentGui.visibleErrorVersionUnsupported\",\n focus: \"upgrade\",\n actionKey: \"agentHost.agentGui.visibleErrorActionUpgrade\"\n },\n network_error: {\n messageKey: \"agentHost.agentGui.visibleErrorNetwork\",\n focus: \"network\",\n actionKey: \"agentHost.agentGui.visibleErrorActionCheckNetwork\"\n },\n runtime_unavailable: {\n messageKey: \"agentHost.agentGui.visibleErrorRuntimeUnavailable\",\n focus: \"detect\",\n actionKey: \"agentHost.agentGui.visibleErrorActionDetect\"\n },\n // Transient / server-side failures: accurate copy, but no wizard CTA — it\n // cannot fix a rate limit or a dropped stream.\n request_timed_out: {\n messageKey: \"agentHost.agentGui.visibleErrorRequestTimedOut\",\n ...NO_CTA\n },\n provider_config_timeout: {\n messageKey: \"agentHost.agentGui.visibleErrorConfigTimeout\",\n ...NO_CTA\n },\n provider_stream_disconnected: {\n messageKey: \"agentHost.agentGui.visibleErrorStreamDisconnected\",\n ...NO_CTA\n },\n provider_concurrency_limit: {\n messageKey: \"agentHost.agentGui.visibleErrorConcurrencyLimit\",\n ...NO_CTA\n },\n insufficient_credits: {\n messageKey: \"agentHost.agentGui.visibleErrorInsufficientCredits\",\n focus: null,\n actionKey: \"agentHost.agentGui.visibleErrorActionViewPlans\",\n externalUrl: \"https://tutti.sh/profile/plan\"\n },\n quota_or_rate_limit: {\n messageKey: \"agentHost.agentGui.visibleErrorQuotaOrRateLimit\",\n ...NO_CTA\n },\n // Ambiguous hard failures → generic message + self-detect escape hatch.\n process_exited: SELF_DETECT,\n provider_error: SELF_DETECT,\n unknown: SELF_DETECT\n};\n\n/**\n * Resolves the card presentation for a run-failure code. Returns null for codes\n * outside the known vocabulary so the caller renders its plain generic card with\n * no call-to-action.\n */\nexport function resolveAgentErrorPresentation(\n code: string | null | undefined\n): AgentErrorPresentation | null {\n if (!code) {\n return null;\n }\n return PRESENTATIONS[code as AgentRunErrorCode] ?? null;\n}\n\nconst FAILED_MESSAGE_CODE_MARKERS: ReadonlyArray<\n readonly [AgentRunErrorCode, readonly string[]]\n> = [\n [\n \"auth_required\",\n [\n \"authentication_failed\",\n \"invalid authentication credentials\",\n \"401 invalid authentication\",\n \"unauthorized\",\n \"not logged in\",\n \"please run /login\",\n \"invalid api key\"\n ]\n ],\n [\n \"cli_version_unsupported\",\n [\"requires a newer version\", \"version is too old\", \"unsupported version\"]\n ],\n [\n \"cli_not_found\",\n [\n \"no such file or directory\",\n \"command not found\",\n \"enoent\",\n \"executable file not found\"\n ]\n ],\n [\n \"network_error\",\n [\"enotfound\", \"econnrefused\", \"econnreset\", \"getaddrinfo\", \"socket hang up\"]\n ],\n [\n \"quota_or_rate_limit\",\n [\"upgrade your plan to continue\", \"add a payment method to continue\"]\n ]\n];\n\n/**\n * Some providers (notably Claude Code) report an environment failure — e.g. a\n * dropped login (401) — as a plain failed assistant message rather than a\n * structured visibleError, so it never gets the remediation card. This recovers\n * the env-fixable code from that message's text so the caller can still route the\n * user to the wizard. Returns null when the text isn't a recognized env failure\n * (so transient/unknown failures stay plain).\n */\nexport function classifyFailedAgentMessage(\n body: string | null | undefined\n): AgentRunErrorCode | null {\n if (!body) {\n return null;\n }\n const lower = body.toLowerCase();\n for (const [code, markers] of FAILED_MESSAGE_CODE_MARKERS) {\n if (markers.some((marker) => lower.includes(marker))) {\n return code;\n }\n }\n return null;\n}\n\n/** True when detail text is a provider plan/payment gate (not a generic quota). */\nexport function isProviderPlanLimitMessage(\n detail: string | null | undefined\n): boolean {\n const normalized = detail?.trim().toLowerCase() ?? \"\";\n if (!normalized) {\n return false;\n }\n const markers =\n FAILED_MESSAGE_CODE_MARKERS.find(\n ([code]) => code === \"quota_or_rate_limit\"\n )?.[1] ?? [];\n return markers.some((marker) => normalized.includes(marker));\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,491 @@
1
+ import {
2
+ AGENT_MENTION_FILTER_TAB_ORDER,
3
+ agentGeneratedMentionItemKey,
4
+ agentMentionEmptyGroupLabel,
5
+ agentMentionFilterLabel,
6
+ agentMentionGroupLabel,
7
+ mentionGroupExpandCount
8
+ } from "./chunk-WMNS4MAQ.js";
9
+ import {
10
+ resolveAgentMentionFileThumbnailUrl,
11
+ resolveAgentMentionFileVisualKind
12
+ } from "./chunk-LUGELG5V.js";
13
+ import {
14
+ userAvatarPlaceholderUrl,
15
+ workspaceAgentActivityStatusLabel
16
+ } from "./chunk-QVBF5BN5.js";
17
+ import {
18
+ managedAgentRoundedIconUrl
19
+ } from "./chunk-MASXZENX.js";
20
+ import {
21
+ translate
22
+ } from "./chunk-E4HQUTM3.js";
23
+
24
+ // agent-gui/agentGuiNode/AgentFileMentionPalette.tsx
25
+ import {
26
+ normalizeAgentActivityDisplayStatus
27
+ } from "@tutti-os/agent-activity-core";
28
+ import {
29
+ MentionPaletteFromState,
30
+ flattenMentionPaletteEntries,
31
+ renderMentionRow
32
+ } from "@tutti-os/ui-rich-text/at-panel";
33
+ import { resolveIssueManagerStatusPresentation } from "@tutti-os/workspace-issue-manager/ui";
34
+
35
+ // shared/roomIssueStatusLabel.ts
36
+ function roomIssueStatusLabel(status, t) {
37
+ const translateFn = t ?? translate;
38
+ switch (status) {
39
+ case "not_started":
40
+ return translateFn("agentHost.roomIssueNode.issueStatusNotStarted");
41
+ case "running":
42
+ return translateFn("agentHost.roomIssueNode.issueStatusRunning");
43
+ case "in_progress":
44
+ return translateFn("agentHost.roomIssueNode.issueStatusInProgress");
45
+ case "pending_acceptance":
46
+ return translateFn(
47
+ "agentHost.roomIssueNode.issueStatusPendingAcceptance"
48
+ );
49
+ case "completed":
50
+ return translateFn("agentHost.roomIssueNode.issueStatusCompleted");
51
+ case "failed":
52
+ return translateFn("agentHost.roomIssueNode.issueStatusFailed");
53
+ case "canceled":
54
+ return translateFn("agentHost.roomIssueNode.issueStatusCanceled");
55
+ default:
56
+ return status || translateFn("agentHost.roomIssueNode.issueStatusUnknown");
57
+ }
58
+ }
59
+
60
+ // agent-gui/agentGuiNode/AgentFileMentionPalette.tsx
61
+ import { jsx } from "react/jsx-runtime";
62
+ var AGENT_MENTION_PALETTE_THEME = {
63
+ classNames: {
64
+ palette: "agent-gui-node__mention-palette",
65
+ header: "agent-gui-node__mention-palette-header",
66
+ footer: "agent-gui-node__mention-palette-footer",
67
+ tabs: "agent-gui-node__mention-palette-tabs",
68
+ scrollRegion: "agent-gui-node__mention-palette-scroll-region",
69
+ scrollbar: "workspace-agents-status-panel__scrollbar agent-gui-node__mention-palette-scrollbar",
70
+ scrollbarThumb: "workspace-agents-status-panel__scrollbar-thumb",
71
+ hint: "agent-gui-node__mention-palette-hint",
72
+ hintItem: "agent-gui-node__mention-palette-hint-item",
73
+ hintButton: "agent-gui-node__mention-palette-hint-button",
74
+ hintSeparator: "agent-gui-node__mention-palette-hint-separator",
75
+ shortcut: "agent-gui-node__mention-palette-shortcut",
76
+ shortcutArrow: "agent-gui-node__mention-palette-shortcut--arrow",
77
+ shortcutButton: "agent-gui-node__mention-palette-shortcut-button",
78
+ shortcutGroup: "agent-gui-node__mention-palette-shortcut-group"
79
+ },
80
+ testIds: {
81
+ emptyState: "agent-gui-mention-palette-empty-state",
82
+ hint: "agent-gui-mention-palette-hint",
83
+ scrollbar: "agent-gui-mention-palette-scrollbar",
84
+ loadingSpinner: "agent-mention-loading-spinner"
85
+ },
86
+ groupDividerAttribute: "data-agent-mention-group-divider"
87
+ };
88
+ var AGENT_MENTION_ROW_CLASS_NAMES = {
89
+ fileIcon: "agent-gui-node__mention-file-icon",
90
+ fileThumb: "agent-gui-node__mention-file-thumb",
91
+ kindIcon: "tsh-agent-object-token__kind-icon",
92
+ avatarImgUserPlaceholder: "workspace-agents-status-panel__avatar-img--user-placeholder"
93
+ };
94
+ function agentMentionItemKey(item) {
95
+ return `${item.kind}:${item.kind === "file" ? agentGeneratedMentionItemKey(item) : item.targetId}`;
96
+ }
97
+ function flattenAgentMentionPaletteEntries(state) {
98
+ return flattenMentionPaletteEntries(
99
+ state,
100
+ (item) => agentMentionItemKey(item)
101
+ ).map((entry) => {
102
+ if (entry.type === "item") {
103
+ const item = entry.groupId !== void 0 && entry.itemIndex !== void 0 ? state.groups.find((group) => group.id === entry.groupId)?.items[entry.itemIndex] : void 0;
104
+ return {
105
+ key: entry.key,
106
+ type: "item",
107
+ groupId: entry.groupId,
108
+ item
109
+ };
110
+ }
111
+ return {
112
+ key: entry.key,
113
+ type: entry.type,
114
+ categoryId: entry.categoryId,
115
+ groupId: entry.groupId
116
+ };
117
+ });
118
+ }
119
+ function groupStartKeys(state) {
120
+ if (state.mode === "browse") {
121
+ return state.categories.map((category) => `category:${category.id}`);
122
+ }
123
+ return state.groups.map((group) => {
124
+ const firstItem = group.items[0];
125
+ if (firstItem) {
126
+ return `${group.id}:${agentMentionItemKey(firstItem)}`;
127
+ }
128
+ if (group.hasMore) {
129
+ return `expand:${group.id}`;
130
+ }
131
+ return null;
132
+ }).filter((key) => key !== null);
133
+ }
134
+ function AgentFileMentionPalette({
135
+ state,
136
+ highlightedKey,
137
+ label,
138
+ loadingLabel,
139
+ emptyLabel,
140
+ errorLabel,
141
+ tabHintLabel,
142
+ maxHeightPx,
143
+ shouldCenterHighlightedItem = false,
144
+ onHighlightChange,
145
+ onSelectItem,
146
+ onSelectCategory,
147
+ onSelectFilter,
148
+ onExpandGroup,
149
+ onNavigateHierarchy,
150
+ onNavigateIntoItem,
151
+ onOpenReferences
152
+ }) {
153
+ "use memo";
154
+ const openReferencesLabel = translate(
155
+ "agentHost.agentGui.mentionOpenReferences"
156
+ );
157
+ const navigateIntoLabel = translate(
158
+ "agentHost.agentGui.fileMentionEnterFolder"
159
+ );
160
+ const filter = state.filter;
161
+ const highlightedBrowseCategory = highlightedKey?.startsWith("category:") ? highlightedKey.slice("category:".length) : null;
162
+ const showBrowseHint = shouldShowBrowseSearchHint({
163
+ browseFilter: filter,
164
+ groups: state.groups,
165
+ highlightedBrowseCategory,
166
+ mode: state.mode
167
+ });
168
+ const categories = state.mode === "browse" ? state.categories : AGENT_MENTION_FILTER_TAB_ORDER.map((id) => ({
169
+ id,
170
+ label: agentMentionFilterLabel(id)
171
+ }));
172
+ const shellState = showBrowseHint ? { ...state, categories, groups: [] } : {
173
+ ...state,
174
+ categories,
175
+ groups: state.groups.map(
176
+ (group, index) => decorateMentionGroup(
177
+ group,
178
+ index,
179
+ state.groups,
180
+ filter,
181
+ state.query
182
+ )
183
+ )
184
+ };
185
+ const emptyLabelForShell = showBrowseHint ? browseHintForFilter(filter) : resolveMentionPaletteEmptyLabel({
186
+ emptyLabel,
187
+ filter,
188
+ mode: state.mode,
189
+ query: state.query
190
+ });
191
+ return /* @__PURE__ */ jsx(
192
+ MentionPaletteFromState,
193
+ {
194
+ state: shellState,
195
+ highlightedKey,
196
+ getItemKey: agentMentionItemKey,
197
+ renderItem: (item, { group }) => renderMentionRow(agentMentionItemToRowItem(item), {
198
+ classNames: AGENT_MENTION_ROW_CLASS_NAMES,
199
+ dataAttributeMode: "agent",
200
+ ...onNavigateIntoItem && canNavigateIntoMentionItem(item, group) ? {
201
+ onNavigateInto: () => onNavigateIntoItem(item),
202
+ navigateIntoLabel
203
+ } : {},
204
+ ...onOpenReferences && isReferenceableMentionItem(item) ? {
205
+ onOpenReferences: () => onOpenReferences(item),
206
+ openReferencesLabel
207
+ } : {}
208
+ }),
209
+ labels: {
210
+ loading: loadingLabel,
211
+ empty: emptyLabelForShell,
212
+ error: errorLabel,
213
+ tabHint: tabHintLabel,
214
+ listbox: label
215
+ },
216
+ hintLabels: {
217
+ cycleFilter: translate("agentHost.agentGui.fileMentionSwitchCategory"),
218
+ moveSelection: translate(
219
+ "agentHost.agentGui.fileMentionSwitchSelection"
220
+ ),
221
+ navigateHierarchy: translate(
222
+ "agentHost.agentGui.fileMentionNavigateHierarchy"
223
+ )
224
+ },
225
+ maxHeightPx,
226
+ scrollHighlightedIntoViewCentered: shouldCenterHighlightedItem,
227
+ theme: AGENT_MENTION_PALETTE_THEME,
228
+ callbacks: {
229
+ onHighlightChange,
230
+ onActiveCategoryIdChange: (categoryId) => {
231
+ onSelectCategory(categoryId);
232
+ onSelectFilter(categoryId);
233
+ },
234
+ onExpandGroup: (groupId) => onExpandGroup(groupId),
235
+ onSelectItem
236
+ },
237
+ onNavigateHierarchy
238
+ }
239
+ );
240
+ }
241
+ var AgentContextMentionPalette = AgentFileMentionPalette;
242
+ function decorateMentionGroup(group, index, groups, filter, query) {
243
+ const groupId = group.id;
244
+ const suppressChrome = shouldSuppressFileSearchGroupChrome(filter, query);
245
+ const followsMySessions = groupId === "collab_sessions" && groups[index - 1]?.id === "my_sessions";
246
+ const showLabel = shouldRenderMentionGroupLabel({
247
+ filter,
248
+ groupCount: groups.length,
249
+ groupId,
250
+ query
251
+ });
252
+ return {
253
+ ...group,
254
+ label: showLabel ? agentMentionGroupLabel(groupId) : void 0,
255
+ emptyLabel: suppressChrome ? void 0 : agentMentionEmptyGroupLabel(groupId, query),
256
+ expandLabel: group.hasMore ? translate("agentHost.agentGui.contextPickerExpandMore", {
257
+ count: mentionGroupExpandCount(group, filter)
258
+ }) : void 0,
259
+ sectionClassName: followsMySessions ? "mt-2" : void 0,
260
+ hideTopDivider: suppressChrome
261
+ };
262
+ }
263
+ function shouldSuppressFileSearchGroupChrome(filter, query) {
264
+ return filter === "file" && query.trim().length > 0;
265
+ }
266
+ function resolveMentionPaletteEmptyLabel(input) {
267
+ if (input.mode === "results" && input.filter === "file" && input.query.trim().length > 0) {
268
+ return translate("agentHost.agentGui.mentionNoMatchingFiles");
269
+ }
270
+ if (input.filter === "session") {
271
+ return agentMentionEmptyGroupLabel("my_sessions", input.query);
272
+ }
273
+ if (input.filter === "app") {
274
+ return agentMentionEmptyGroupLabel("apps", input.query);
275
+ }
276
+ if (input.filter === "agent") {
277
+ return agentMentionEmptyGroupLabel("agents", input.query);
278
+ }
279
+ if (input.filter === "issue") {
280
+ return agentMentionEmptyGroupLabel("issues", input.query);
281
+ }
282
+ return input.emptyLabel;
283
+ }
284
+ function shouldRenderMentionGroupLabel(input) {
285
+ if (shouldSuppressFileSearchGroupChrome(input.filter, input.query)) {
286
+ return false;
287
+ }
288
+ if (input.groupCount !== 1) {
289
+ return true;
290
+ }
291
+ return agentMentionGroupLabel(input.groupId) !== agentMentionFilterLabel(input.filter);
292
+ }
293
+ function agentMentionItemToRowItem(item) {
294
+ if (item.kind === "file") {
295
+ const visualKind = resolveAgentMentionFileVisualKind({
296
+ entryKind: item.entryKind,
297
+ href: item.href,
298
+ mentionNavigation: item.mentionNavigation,
299
+ name: item.name,
300
+ path: item.path
301
+ });
302
+ const childCountLabel = item.mentionNavigation === "agent-generated-folder" && typeof item.childCount === "number" && item.childCount > 0 ? translate("agentHost.agentGui.mentionAgentGeneratedFolderFileCount", {
303
+ count: item.childCount
304
+ }) : null;
305
+ return {
306
+ kind: "file",
307
+ name: item.name,
308
+ visualKind,
309
+ thumbnailUrl: resolveAgentMentionFileThumbnailUrl(item) ?? null,
310
+ childCountLabel,
311
+ entryKind: item.entryKind,
312
+ mentionNavigation: item.mentionNavigation
313
+ };
314
+ }
315
+ if (item.kind === "session") {
316
+ const isMySession = item.scope === "my_sessions";
317
+ return {
318
+ kind: "session",
319
+ participant: isMySession ? item.agentName : `${item.initiatorName} & ${item.agentName}`,
320
+ summary: item.title,
321
+ userAvatarUrl: isMySession ? null : item.initiatorAvatarUrl ?? null,
322
+ userAvatarPlaceholderUrl,
323
+ agentIconUrl: item.agentIconUrl?.trim() || managedAgentRoundedIconUrl(
324
+ mentionSessionAgentProvider(item) ?? item.agentName
325
+ ),
326
+ showUserAvatar: !isMySession,
327
+ statusTag: agentSessionStatusTag(item.status)
328
+ };
329
+ }
330
+ if (item.kind === "workspace-app") {
331
+ return {
332
+ kind: "app",
333
+ name: item.name,
334
+ description: item.description ?? null,
335
+ iconUrl: item.iconUrl ?? null
336
+ };
337
+ }
338
+ if (item.kind === "agent-target") {
339
+ return {
340
+ kind: "app",
341
+ name: item.name,
342
+ description: item.description ?? null,
343
+ iconUrl: item.iconUrl ?? managedAgentRoundedIconUrl(item.agentProviderId),
344
+ statusTag: agentTargetAvailableStatusTag()
345
+ };
346
+ }
347
+ if (item.kind === "workspace-reference") {
348
+ return {
349
+ kind: "app",
350
+ name: item.name,
351
+ description: null,
352
+ iconUrl: item.iconUrl ?? null
353
+ };
354
+ }
355
+ if (item.kind === "workspace-app-factory") {
356
+ return {
357
+ kind: "app-factory",
358
+ name: item.name
359
+ };
360
+ }
361
+ if (item.kind === "custom") {
362
+ return {
363
+ kind: "issue",
364
+ title: item.name,
365
+ creatorName: null,
366
+ statusTag: null
367
+ };
368
+ }
369
+ return {
370
+ kind: "issue",
371
+ title: item.title,
372
+ creatorName: item.creatorName ?? null,
373
+ statusTag: agentIssueStatusTag(item.status)
374
+ };
375
+ }
376
+ function isReferenceableMentionItem(item) {
377
+ if (item.kind === "workspace-issue") {
378
+ return true;
379
+ }
380
+ if (item.kind === "workspace-app") {
381
+ return item.referencesListSupported === true;
382
+ }
383
+ return false;
384
+ }
385
+ function canNavigateIntoMentionItem(item, group) {
386
+ return group.id === "agent_generated_files" && item.kind === "file" && item.mentionNavigation === "agent-generated-folder";
387
+ }
388
+ function mentionSessionAgentProvider(item) {
389
+ const queryStart = item.href.indexOf("?");
390
+ if (queryStart < 0) {
391
+ return null;
392
+ }
393
+ return new URLSearchParams(item.href.slice(queryStart + 1)).get("provider");
394
+ }
395
+ function agentSessionStatusTag(status) {
396
+ if (!status) {
397
+ return null;
398
+ }
399
+ const activityStatus = normalizeAgentActivityDisplayStatus(status);
400
+ return {
401
+ label: workspaceAgentActivityStatusLabel(activityStatus),
402
+ tone: mentionStatusTone(activityStatus),
403
+ pulse: activityStatus === "working" || activityStatus === "waiting",
404
+ variant: "activity",
405
+ dataStatus: activityStatus
406
+ };
407
+ }
408
+ function agentTargetAvailableStatusTag() {
409
+ return {
410
+ label: translate("agentHost.agentGui.mentionAgentTargetAvailable"),
411
+ tone: "green",
412
+ variant: "activity",
413
+ dataStatus: "available"
414
+ };
415
+ }
416
+ function agentIssueStatusTag(status) {
417
+ if (!status) {
418
+ return null;
419
+ }
420
+ const presentation = resolveIssueManagerStatusPresentation(status);
421
+ return {
422
+ label: roomIssueStatusLabel(status),
423
+ tone: presentation.mentionTone,
424
+ variant: "issue",
425
+ dataStatus: presentation.dataStatus
426
+ };
427
+ }
428
+ function mentionStatusTone(status) {
429
+ if (status === "working") {
430
+ return "blue";
431
+ }
432
+ if (status === "waiting" || status === "canceled") {
433
+ return "amber";
434
+ }
435
+ if (status === "completed" || status === "idle") {
436
+ return "green";
437
+ }
438
+ if (status === "failed") {
439
+ return "red";
440
+ }
441
+ return "neutral";
442
+ }
443
+ function browseHintForFilter(filter) {
444
+ switch (filter) {
445
+ case "agent":
446
+ return translate("agentHost.agentGui.contextPickerBrowseAgentHint");
447
+ case "app":
448
+ return translate("agentHost.agentGui.contextPickerBrowseAppHint");
449
+ case "file":
450
+ return translate("agentHost.agentGui.contextPickerBrowseFileHint");
451
+ case "session":
452
+ return translate("agentHost.agentGui.contextPickerBrowseSessionHint");
453
+ case "issue":
454
+ return translate("agentHost.agentGui.contextPickerBrowseIssueHint");
455
+ }
456
+ }
457
+ function hasInteractiveGroupEntries(groups) {
458
+ return groups.some((group) => group.items.length > 0 || group.hasMore);
459
+ }
460
+ function isFileBrowseGroupsOnlyEmpty(groups) {
461
+ const fileGroups = groups.filter(
462
+ (group) => group.id === "opened_files" || group.id === "agent_generated_files"
463
+ );
464
+ if (fileGroups.length === 0) {
465
+ return false;
466
+ }
467
+ return fileGroups.every(
468
+ (group) => group.items.length === 0 && !group.hasMore
469
+ );
470
+ }
471
+ function shouldShowBrowseSearchHint(input) {
472
+ if (input.mode !== "browse" || hasInteractiveGroupEntries(input.groups)) {
473
+ return false;
474
+ }
475
+ if (input.groups.length === 0) {
476
+ return true;
477
+ }
478
+ if (input.highlightedBrowseCategory !== null && input.highlightedBrowseCategory !== input.browseFilter) {
479
+ return true;
480
+ }
481
+ return input.browseFilter === "file" && isFileBrowseGroupsOnlyEmpty(input.groups);
482
+ }
483
+
484
+ export {
485
+ agentMentionItemKey,
486
+ flattenAgentMentionPaletteEntries,
487
+ groupStartKeys,
488
+ AgentFileMentionPalette,
489
+ AgentContextMentionPalette
490
+ };
491
+ //# sourceMappingURL=chunk-AGT7MUTV.js.map