@geminilight/mindos 0.6.29 → 0.6.31

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 (110) hide show
  1. package/README.md +10 -4
  2. package/README_zh.md +10 -4
  3. package/app/app/api/acp/config/route.ts +82 -0
  4. package/app/app/api/acp/detect/route.ts +71 -48
  5. package/app/app/api/acp/install/route.ts +51 -0
  6. package/app/app/api/acp/session/route.ts +141 -11
  7. package/app/app/api/ask/route.ts +126 -18
  8. package/app/app/api/export/route.ts +105 -0
  9. package/app/app/api/workflows/route.ts +156 -0
  10. package/app/app/globals.css +2 -2
  11. package/app/app/page.tsx +7 -2
  12. package/app/app/trash/page.tsx +7 -0
  13. package/app/app/view/[...path]/ViewPageClient.tsx +234 -2
  14. package/app/components/ActivityBar.tsx +12 -4
  15. package/app/components/AskModal.tsx +4 -1
  16. package/app/components/ExportModal.tsx +220 -0
  17. package/app/components/FileTree.tsx +42 -11
  18. package/app/components/HomeContent.tsx +92 -20
  19. package/app/components/MarkdownView.tsx +45 -10
  20. package/app/components/Panel.tsx +1 -0
  21. package/app/components/RightAskPanel.tsx +5 -1
  22. package/app/components/Sidebar.tsx +10 -1
  23. package/app/components/SidebarLayout.tsx +6 -0
  24. package/app/components/TrashPageClient.tsx +263 -0
  25. package/app/components/agents/AgentDetailContent.tsx +263 -47
  26. package/app/components/agents/AgentsContentPage.tsx +11 -0
  27. package/app/components/agents/AgentsPanelA2aTab.tsx +285 -46
  28. package/app/components/agents/AgentsPanelSessionsTab.tsx +166 -0
  29. package/app/components/agents/agents-content-model.ts +2 -2
  30. package/app/components/ask/AgentSelectorCapsule.tsx +218 -0
  31. package/app/components/ask/AskContent.tsx +197 -239
  32. package/app/components/ask/FileChip.tsx +82 -17
  33. package/app/components/ask/MentionPopover.tsx +21 -3
  34. package/app/components/ask/MessageList.tsx +30 -9
  35. package/app/components/ask/SlashCommandPopover.tsx +21 -3
  36. package/app/components/ask/ToolCallBlock.tsx +102 -18
  37. package/app/components/changes/ChangesContentPage.tsx +58 -14
  38. package/app/components/explore/ExploreContent.tsx +4 -7
  39. package/app/components/explore/UseCaseCard.tsx +18 -1
  40. package/app/components/explore/use-cases.generated.ts +76 -0
  41. package/app/components/explore/use-cases.yaml +185 -0
  42. package/app/components/panels/AgentsPanel.tsx +1 -0
  43. package/app/components/panels/AgentsPanelHubNav.tsx +9 -2
  44. package/app/components/panels/DiscoverPanel.tsx +1 -1
  45. package/app/components/panels/WorkflowsPanel.tsx +206 -0
  46. package/app/components/renderers/workflow-yaml/StepEditor.tsx +164 -0
  47. package/app/components/renderers/workflow-yaml/WorkflowEditor.tsx +211 -0
  48. package/app/components/renderers/workflow-yaml/WorkflowRunner.tsx +269 -0
  49. package/app/components/renderers/workflow-yaml/WorkflowYamlRenderer.tsx +126 -0
  50. package/app/components/renderers/workflow-yaml/execution.ts +229 -0
  51. package/app/components/renderers/workflow-yaml/index.ts +6 -0
  52. package/app/components/renderers/workflow-yaml/manifest.ts +21 -0
  53. package/app/components/renderers/workflow-yaml/parser.ts +172 -0
  54. package/app/components/renderers/workflow-yaml/selectors.tsx +574 -0
  55. package/app/components/renderers/workflow-yaml/serializer.ts +56 -0
  56. package/app/components/renderers/workflow-yaml/types.ts +46 -0
  57. package/app/components/settings/AiTab.tsx +191 -174
  58. package/app/components/settings/AppearanceTab.tsx +168 -77
  59. package/app/components/settings/KnowledgeTab.tsx +131 -136
  60. package/app/components/settings/McpTab.tsx +11 -11
  61. package/app/components/settings/Primitives.tsx +60 -0
  62. package/app/components/settings/SettingsContent.tsx +15 -8
  63. package/app/components/settings/SyncTab.tsx +12 -12
  64. package/app/components/settings/UninstallTab.tsx +8 -18
  65. package/app/components/settings/UpdateTab.tsx +82 -82
  66. package/app/components/settings/types.ts +17 -8
  67. package/app/hooks/useAcpConfig.ts +96 -0
  68. package/app/hooks/useAcpDetection.ts +69 -14
  69. package/app/hooks/useAcpRegistry.ts +46 -11
  70. package/app/hooks/useAskModal.ts +12 -5
  71. package/app/hooks/useAskPanel.ts +8 -5
  72. package/app/hooks/useAskSession.ts +19 -2
  73. package/app/hooks/useImageUpload.ts +152 -0
  74. package/app/lib/acp/acp-tools.ts +3 -1
  75. package/app/lib/acp/agent-descriptors.ts +274 -0
  76. package/app/lib/acp/bridge.ts +6 -0
  77. package/app/lib/acp/index.ts +20 -4
  78. package/app/lib/acp/registry.ts +74 -7
  79. package/app/lib/acp/session.ts +490 -28
  80. package/app/lib/acp/subprocess.ts +307 -21
  81. package/app/lib/acp/types.ts +158 -20
  82. package/app/lib/actions.ts +57 -3
  83. package/app/lib/agent/model.ts +18 -3
  84. package/app/lib/agent/stream-consumer.ts +18 -0
  85. package/app/lib/agent/to-agent-messages.ts +25 -2
  86. package/app/lib/agent/tools.ts +56 -9
  87. package/app/lib/core/export.ts +116 -0
  88. package/app/lib/core/trash.ts +241 -0
  89. package/app/lib/fs.ts +47 -0
  90. package/app/lib/hooks/usePinnedFiles.ts +90 -0
  91. package/app/lib/i18n/generated/explore-i18n.generated.ts +138 -0
  92. package/app/lib/i18n/index.ts +3 -0
  93. package/app/lib/i18n/modules/knowledge.ts +124 -6
  94. package/app/lib/i18n/modules/navigation.ts +2 -0
  95. package/app/lib/i18n/modules/onboarding.ts +2 -134
  96. package/app/lib/i18n/modules/panels.ts +146 -2
  97. package/app/lib/i18n/modules/settings.ts +12 -0
  98. package/app/lib/pi-integration/skills.ts +21 -6
  99. package/app/lib/renderers/index.ts +2 -2
  100. package/app/lib/settings.ts +10 -0
  101. package/app/lib/types.ts +12 -1
  102. package/app/next-env.d.ts +1 -1
  103. package/app/package.json +11 -3
  104. package/app/scripts/generate-explore.ts +145 -0
  105. package/package.json +1 -1
  106. package/templates/en/.mindos/workflows/Sprint Release.flow.yaml +130 -0
  107. package/templates/zh/.mindos/workflows//345/221/250/350/277/255/344/273/243/346/243/200/346/237/245.flow.yaml +84 -0
  108. package/app/components/explore/use-cases.ts +0 -58
  109. package/app/components/renderers/workflow/WorkflowRenderer.tsx +0 -409
  110. package/app/components/renderers/workflow/manifest.ts +0 -14
@@ -0,0 +1,274 @@
1
+ /**
2
+ * ACP Agent Descriptors — Single source of truth for agent detection, launch, and install.
3
+ * Replaces the previously separate AGENT_BINARY_MAP, AGENT_OVERRIDES, and INSTALL_COMMANDS maps.
4
+ */
5
+
6
+ import type { AcpRegistryEntry, AcpTransportType } from './types';
7
+
8
+ /* ── Types ─────────────────────────────────────────────────────────────── */
9
+
10
+ /** Complete agent launch/detection metadata. */
11
+ export interface AcpAgentDescriptor {
12
+ /** Binary name for `which` detection (e.g., "gemini", "codebuddy") */
13
+ binary: string;
14
+ /** Command to execute when spawning */
15
+ cmd: string;
16
+ /** CLI args for ACP mode */
17
+ args: string[];
18
+ /** Install command shown in UI / used by auto-install */
19
+ installCmd?: string;
20
+ /** Curated display name (overrides registry name) */
21
+ displayName?: string;
22
+ /** Curated description (overrides registry description) */
23
+ description?: string;
24
+ }
25
+
26
+ /** User override for a specific agent, persisted in settings. */
27
+ export interface AcpAgentOverride {
28
+ /** Override command path (e.g., "/usr/local/bin/gemini") */
29
+ command?: string;
30
+ /** Override CLI args (e.g., ["--acp", "--verbose"]) */
31
+ args?: string[];
32
+ /** Extra environment variables */
33
+ env?: Record<string, string>;
34
+ /** false = skip this agent entirely (default: true) */
35
+ enabled?: boolean;
36
+ }
37
+
38
+ /** Fully resolved command ready for spawn, with provenance. */
39
+ export interface ResolvedAgentCommand {
40
+ cmd: string;
41
+ args: string[];
42
+ env?: Record<string, string>;
43
+ /** Where the command came from */
44
+ source: 'user-override' | 'descriptor' | 'registry';
45
+ /** Binary name for detection */
46
+ binary: string;
47
+ /** Install command for UI */
48
+ installCmd?: string;
49
+ /** Whether agent is enabled */
50
+ enabled: boolean;
51
+ }
52
+
53
+ /* ── Canonical Descriptors ─────────────────────────────────────────────── */
54
+
55
+ /**
56
+ * All known ACP agents with their detection binary, launch command, and install hint.
57
+ * Both detection (`which binary?`) and launch (`spawn cmd args`) read from here.
58
+ */
59
+ export const AGENT_DESCRIPTORS: Record<string, AcpAgentDescriptor> = {
60
+ // Gemini CLI — Google's AI coding agent
61
+ 'gemini': { binary: 'gemini', cmd: 'gemini', args: ['--experimental-acp'], installCmd: 'npm install -g @google/gemini-cli',
62
+ displayName: 'Gemini CLI',
63
+ description: 'Google Gemini 驱动的编程智能体。支持多文件编辑、代码审查、调试和项目级重构,原生集成 Google 搜索实时查询技术文档。' },
64
+ 'gemini-cli': { binary: 'gemini', cmd: 'gemini', args: ['--experimental-acp'], installCmd: 'npm install -g @google/gemini-cli',
65
+ displayName: 'Gemini CLI',
66
+ description: 'Google Gemini 驱动的编程智能体。支持多文件编辑、代码审查、调试和项目级重构,原生集成 Google 搜索实时查询技术文档。' },
67
+ // Claude Code — Anthropic's AI coding agent
68
+ 'claude': { binary: 'claude', cmd: 'npx', args: ['--yes', '@agentclientprotocol/claude-agent-acp'], installCmd: 'npm install -g @anthropic-ai/claude-code',
69
+ displayName: 'Claude Code',
70
+ description: 'Anthropic Claude 驱动的编程智能体。擅长复杂推理、长上下文理解和安全代码生成,支持多文件编辑与 agentic 工作流。' },
71
+ 'claude-code': { binary: 'claude', cmd: 'npx', args: ['--yes', '@agentclientprotocol/claude-agent-acp'], installCmd: 'npm install -g @anthropic-ai/claude-code',
72
+ displayName: 'Claude Code',
73
+ description: 'Anthropic Claude 驱动的编程智能体。擅长复杂推理、长上下文理解和安全代码生成,支持多文件编辑与 agentic 工作流。' },
74
+ 'claude-acp': { binary: 'claude', cmd: 'npx', args: ['--yes', '@agentclientprotocol/claude-agent-acp'], installCmd: 'npm install -g @anthropic-ai/claude-code',
75
+ displayName: 'Claude Code',
76
+ description: 'Anthropic Claude 驱动的编程智能体。擅长复杂推理、长上下文理解和安全代码生成,支持多文件编辑与 agentic 工作流。' },
77
+ // CodeBuddy Code — Tencent Cloud's AI coding agent
78
+ 'codebuddy-code': { binary: 'codebuddy', cmd: 'codebuddy', args: ['--acp'], installCmd: 'npm install -g @tencent-ai/codebuddy-code',
79
+ displayName: 'CodeBuddy Code',
80
+ description: '腾讯云智能编程助手。基于混元大模型,支持代码补全、生成、审查和多文件重构,深度理解中文语境,适配国内开发生态。' },
81
+ 'codebuddy': { binary: 'codebuddy', cmd: 'codebuddy', args: ['--acp'], installCmd: 'npm install -g @tencent-ai/codebuddy-code',
82
+ displayName: 'CodeBuddy Code',
83
+ description: '腾讯云智能编程助手。基于混元大模型,支持代码补全、生成、审查和多文件重构,深度理解中文语境,适配国内开发生态。' },
84
+ // Codex — OpenAI's coding agent
85
+ 'codex-acp': { binary: 'codex', cmd: 'codex', args: [], installCmd: 'npm install -g @openai/codex',
86
+ displayName: 'Codex',
87
+ description: 'OpenAI Codex 编程智能体。基于 GPT 系列模型,擅长代码生成、自动化任务和多语言编程支持。' },
88
+ 'codex': { binary: 'codex', cmd: 'codex', args: [], installCmd: 'npm install -g @openai/codex',
89
+ displayName: 'Codex',
90
+ description: 'OpenAI Codex 编程智能体。基于 GPT 系列模型,擅长代码生成、自动化任务和多语言编程支持。' },
91
+ // Cursor — AI-first code editor agent
92
+ 'cursor': { binary: 'cursor', cmd: 'cursor', args: [],
93
+ displayName: 'Cursor',
94
+ description: 'Cursor AI 编程智能体。AI-first 代码编辑器的 CLI 模式,支持上下文感知的代码编辑、Tab 补全和多文件协同修改。' },
95
+ 'cline': { binary: 'cline', cmd: 'cline', args: [], installCmd: 'npm install -g cline',
96
+ displayName: 'Cline',
97
+ description: '开源自主编程智能体。支持多模型后端,内置文件编辑、终端执行和浏览器自动化能力。' },
98
+ 'github-copilot-cli': { binary: 'github-copilot', cmd: 'github-copilot', args: [], installCmd: 'npm install -g @github/copilot',
99
+ displayName: 'GitHub Copilot',
100
+ description: 'GitHub Copilot 编程智能体。基于海量开源代码训练,擅长代码补全、测试生成和跨语言编程支持。' },
101
+ 'goose': { binary: 'goose', cmd: 'goose', args: [], installCmd: 'pip install goose-ai',
102
+ displayName: 'Goose',
103
+ description: 'Block 开源自主编程智能体。支持多模型后端,可扩展插件架构,擅长复杂任务自动化。' },
104
+ 'opencode': { binary: 'opencode', cmd: 'opencode', args: [], installCmd: 'go install github.com/opencode-ai/opencode@latest',
105
+ displayName: 'OpenCode',
106
+ description: '开源终端编程智能体。Go 实现,轻量快速,支持多模型后端和丰富的代码编辑工具。' },
107
+ 'kilo': { binary: 'kilo', cmd: 'kilo', args: [], installCmd: 'npm install -g @kilocode/cli',
108
+ displayName: 'Kilo Code',
109
+ description: 'Kilo Code 编程智能体。开源 VS Code 扩展的 CLI 模式,支持多模型、自动审批和代码差异预览。' },
110
+ 'openclaw': { binary: 'openclaw', cmd: 'openclaw', args: [],
111
+ displayName: 'OpenClaw',
112
+ description: 'OpenClaw 编程智能体。开源 Claude Code 替代方案,支持多模型后端和完整的 agentic 工作流。' },
113
+ 'pi': { binary: 'pi', cmd: 'pi', args: [],
114
+ displayName: 'Pi Agent',
115
+ description: 'Pi Agent 编程智能体。轻量级终端编程助手。' },
116
+ 'pi-acp': { binary: 'pi', cmd: 'pi', args: [],
117
+ displayName: 'Pi Agent',
118
+ description: 'Pi Agent 编程智能体。轻量级终端编程助手。' },
119
+ 'auggie': { binary: 'auggie', cmd: 'auggie', args: [],
120
+ displayName: 'Auggie',
121
+ description: 'Augment Code 编程智能体。支持代码理解、生成和全仓库上下文感知。' },
122
+ 'iflow': { binary: 'iflow', cmd: 'iflow', args: [],
123
+ displayName: 'iFlow',
124
+ description: 'iFlow 编程智能体。AI 驱动的工作流自动化工具。' },
125
+ 'kimi': { binary: 'kimi', cmd: 'kimi', args: [],
126
+ displayName: 'Kimi',
127
+ description: 'Moonshot AI Kimi 编程智能体。擅长超长上下文理解,支持中文语境下的代码生成与分析。' },
128
+ 'qwen-code': { binary: 'qwen-code', cmd: 'qwen-code', args: [], installCmd: 'npm install -g @qwen-code/qwen-code',
129
+ displayName: 'Qwen Code',
130
+ description: '阿里通义千问 Qwen 编程智能体。基于 Qwen 大模型,支持代码生成、审查和多语言编程,深度适配中文开发场景。' },
131
+ };
132
+
133
+ /* ── Resolution ────────────────────────────────────────────────────────── */
134
+
135
+ /**
136
+ * Resolve the final command for an agent by layering:
137
+ * 1. User override (highest priority)
138
+ * 2. Built-in descriptor
139
+ * 3. Registry entry (fallback for unknown agents)
140
+ * 4. Transport-based default (last resort)
141
+ */
142
+ export function resolveAgentCommand(
143
+ agentId: string,
144
+ registryEntry?: AcpRegistryEntry,
145
+ userOverride?: AcpAgentOverride,
146
+ ): ResolvedAgentCommand {
147
+ const descriptor = AGENT_DESCRIPTORS[agentId];
148
+ const enabled = userOverride?.enabled !== false;
149
+
150
+ // Layer 1: User override
151
+ if (userOverride && (userOverride.command || userOverride.args)) {
152
+ return {
153
+ cmd: userOverride.command ?? descriptor?.cmd ?? registryEntry?.command ?? agentId,
154
+ args: userOverride.args ?? descriptor?.args ?? [],
155
+ env: userOverride.env,
156
+ source: 'user-override',
157
+ binary: descriptor?.binary ?? agentId,
158
+ installCmd: descriptor?.installCmd,
159
+ enabled,
160
+ };
161
+ }
162
+
163
+ // Layer 2: Built-in descriptor
164
+ if (descriptor) {
165
+ return {
166
+ cmd: descriptor.cmd,
167
+ args: descriptor.args,
168
+ env: userOverride?.env,
169
+ source: 'descriptor',
170
+ binary: descriptor.binary,
171
+ installCmd: descriptor.installCmd,
172
+ enabled,
173
+ };
174
+ }
175
+
176
+ // Layer 3: Registry entry
177
+ if (registryEntry) {
178
+ const { cmd, args } = registryToCommand(registryEntry);
179
+ return {
180
+ cmd,
181
+ args,
182
+ env: userOverride?.env,
183
+ source: 'registry',
184
+ binary: agentId,
185
+ installCmd: registryEntry.packageName ? `npm install -g ${registryEntry.packageName}` : undefined,
186
+ enabled,
187
+ };
188
+ }
189
+
190
+ // Layer 4: Last resort — try using agentId as command
191
+ return {
192
+ cmd: agentId,
193
+ args: [],
194
+ env: userOverride?.env,
195
+ source: 'registry',
196
+ binary: agentId,
197
+ enabled,
198
+ };
199
+ }
200
+
201
+ /** Convert a registry entry's transport info to a spawn command. */
202
+ function registryToCommand(entry: AcpRegistryEntry): { cmd: string; args: string[] } {
203
+ const transport: AcpTransportType = entry.transport;
204
+ switch (transport) {
205
+ case 'npx':
206
+ return { cmd: 'npx', args: ['--yes', entry.command, ...(entry.args ?? [])] };
207
+ case 'uvx':
208
+ return { cmd: 'uvx', args: [entry.command, ...(entry.args ?? [])] };
209
+ case 'binary':
210
+ case 'stdio':
211
+ default:
212
+ return { cmd: entry.command, args: entry.args ?? [] };
213
+ }
214
+ }
215
+
216
+ /* ── Helpers ───────────────────────────────────────────────────────────── */
217
+
218
+ /** Get the binary name for detection (used by detect endpoint). */
219
+ export function getDescriptorBinary(agentId: string): string | undefined {
220
+ return AGENT_DESCRIPTORS[agentId]?.binary;
221
+ }
222
+
223
+ /** Get the install command for UI display. */
224
+ export function getDescriptorInstallCmd(agentId: string): string | undefined {
225
+ return AGENT_DESCRIPTORS[agentId]?.installCmd;
226
+ }
227
+
228
+ /** Get curated display name (overrides registry name if available). */
229
+ export function getDescriptorDisplayName(agentId: string): string | undefined {
230
+ return AGENT_DESCRIPTORS[agentId]?.displayName;
231
+ }
232
+
233
+ /** Get curated description (overrides registry description if available). */
234
+ export function getDescriptorDescription(agentId: string): string | undefined {
235
+ return AGENT_DESCRIPTORS[agentId]?.description;
236
+ }
237
+
238
+ /** Parse and validate acpAgents config from raw settings JSON. */
239
+ export function parseAcpAgentOverrides(raw: unknown): Record<string, AcpAgentOverride> | undefined {
240
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return undefined;
241
+ const obj = raw as Record<string, unknown>;
242
+ const result: Record<string, AcpAgentOverride> = {};
243
+ let hasEntries = false;
244
+
245
+ for (const [key, val] of Object.entries(obj)) {
246
+ if (!val || typeof val !== 'object' || Array.isArray(val)) continue;
247
+ const entry = val as Record<string, unknown>;
248
+ const override: AcpAgentOverride = {};
249
+
250
+ if (typeof entry.command === 'string' && entry.command.trim()) {
251
+ override.command = entry.command.trim();
252
+ }
253
+ if (Array.isArray(entry.args)) {
254
+ override.args = entry.args.filter((a): a is string => typeof a === 'string');
255
+ }
256
+ if (entry.env && typeof entry.env === 'object' && !Array.isArray(entry.env)) {
257
+ const env: Record<string, string> = {};
258
+ for (const [ek, ev] of Object.entries(entry.env as Record<string, unknown>)) {
259
+ if (typeof ev === 'string') env[ek] = ev;
260
+ }
261
+ if (Object.keys(env).length > 0) override.env = env;
262
+ }
263
+ if (typeof entry.enabled === 'boolean') {
264
+ override.enabled = entry.enabled;
265
+ }
266
+
267
+ if (Object.keys(override).length > 0) {
268
+ result[key] = override;
269
+ hasEntries = true;
270
+ }
271
+ }
272
+
273
+ return hasEntries ? result : undefined;
274
+ }
@@ -88,8 +88,13 @@ export function bridgeAcpUpdatesToA2a(
88
88
  for (const update of updates) {
89
89
  switch (update.type) {
90
90
  case 'text':
91
+ case 'agent_message_chunk':
91
92
  aggregatedText += update.text ?? '';
92
93
  break;
94
+ case 'agent_thought_chunk':
95
+ // Include thought in output with label
96
+ if (update.text) aggregatedText += update.text;
97
+ break;
93
98
  case 'done':
94
99
  finalState = 'TASK_STATE_COMPLETED';
95
100
  break;
@@ -97,6 +102,7 @@ export function bridgeAcpUpdatesToA2a(
97
102
  finalState = 'TASK_STATE_FAILED';
98
103
  errorMessage = update.error ?? 'Unknown error';
99
104
  break;
105
+ // tool_call, tool_call_update, plan, etc. — pass through for now
100
106
  }
101
107
  }
102
108
 
@@ -1,13 +1,21 @@
1
1
  export { fetchAcpRegistry, getAcpAgents, findAcpAgent, clearRegistryCache } from './registry';
2
- export { spawnAcpAgent, sendMessage, sendAndWait, onMessage, killAgent, killAllAgents, getProcess, getActiveProcesses } from './subprocess';
3
- export { createSession, createSessionFromEntry, prompt, promptStream, cancelPrompt, closeSession, getSession, getActiveSessions, closeAllSessions } from './session';
2
+ export { spawnAcpAgent, sendMessage, sendAndWait, onMessage, onRequest, sendResponse, installAutoApproval, killAgent, killAllAgents, getProcess, getActiveProcesses } from './subprocess';
3
+ export { createSession, createSessionFromEntry, loadSession, listSessions, prompt, promptStream, cancelPrompt, setMode, setConfigOption, closeSession, getSession, getActiveSessions, closeAllSessions } from './session';
4
4
  export { bridgeA2aToAcp, bridgeAcpResponseToA2a, bridgeAcpUpdatesToA2a } from './bridge';
5
5
  export { acpTools } from './acp-tools';
6
6
  export { ACP_ERRORS } from './types';
7
7
  export type {
8
- AcpCapabilities,
8
+ AcpAgentCapabilities,
9
+ AcpClientCapabilities,
10
+ AcpContentBlock,
11
+ AcpStopReason,
12
+ AcpMode,
13
+ AcpConfigOption,
14
+ AcpConfigOptionEntry,
15
+ AcpAuthMethod,
9
16
  AcpSessionState,
10
17
  AcpSession,
18
+ AcpSessionInfo,
11
19
  AcpJsonRpcRequest,
12
20
  AcpJsonRpcResponse,
13
21
  AcpJsonRpcError,
@@ -16,9 +24,17 @@ export type {
16
24
  AcpUpdateType,
17
25
  AcpSessionUpdate,
18
26
  AcpToolCall,
27
+ AcpToolCallFull,
28
+ AcpToolCallKind,
29
+ AcpToolCallStatus,
19
30
  AcpToolResult,
31
+ AcpPlan,
32
+ AcpPlanEntry,
33
+ AcpPlanEntryStatus,
34
+ AcpPlanEntryPriority,
35
+ AcpPermissionOutcome,
20
36
  AcpRegistryEntry,
21
37
  AcpRegistry,
22
38
  AcpTransportType,
23
39
  } from './types';
24
- export type { AcpProcess } from './subprocess';
40
+ export type { AcpProcess, AcpIncomingRequest } from './subprocess';
@@ -5,6 +5,7 @@
5
5
  */
6
6
 
7
7
  import type { AcpRegistry, AcpRegistryEntry } from './types';
8
+ import { getDescriptorDisplayName, getDescriptorDescription } from './agent-descriptors';
8
9
 
9
10
  /* ── Constants ─────────────────────────────────────────────────────────── */
10
11
 
@@ -114,20 +115,86 @@ function normalizeEntry(raw: unknown): AcpRegistryEntry | null {
114
115
  const name = String(entry.name ?? entry.id ?? '');
115
116
  if (!id && !name) return null;
116
117
 
118
+ // Extract transport/command/args from the `distribution` field (ACP registry v1 format)
119
+ const { transport, command, packageName, args: distArgs } = extractDistribution(entry);
120
+
121
+ const agentId = id || name;
122
+
123
+ // Apply curated display name and description from local descriptors (if available)
124
+ const curatedName = getDescriptorDisplayName(agentId);
125
+ const curatedDesc = getDescriptorDescription(agentId);
126
+
117
127
  return {
118
- id: id || name,
119
- name: name || id,
120
- description: String(entry.description ?? ''),
128
+ id: agentId,
129
+ name: curatedName ?? name ?? id,
130
+ description: curatedDesc ?? String(entry.description ?? ''),
121
131
  version: entry.version ? String(entry.version) : undefined,
122
- transport: normalizeTransport(entry.transport),
123
- command: String(entry.command ?? entry.cmd ?? ''),
124
- args: Array.isArray(entry.args) ? entry.args.map(String) : undefined,
132
+ transport,
133
+ command,
134
+ packageName,
135
+ args: distArgs ?? (Array.isArray(entry.args) ? entry.args.map(String) : undefined),
125
136
  env: entry.env && typeof entry.env === 'object' ? entry.env as Record<string, string> : undefined,
126
137
  tags: Array.isArray(entry.tags) ? entry.tags.map(String) : undefined,
127
- homepage: entry.homepage ? String(entry.homepage) : undefined,
138
+ homepage: entry.homepage ?? entry.website ? String(entry.homepage ?? entry.website) : undefined,
128
139
  };
129
140
  }
130
141
 
142
+ /**
143
+ * Extract transport type, command, packageName, and args from
144
+ * the registry's `distribution` field. Falls back to legacy
145
+ * `transport`/`command` fields if `distribution` is absent.
146
+ */
147
+ function extractDistribution(entry: Record<string, unknown>): {
148
+ transport: AcpRegistryEntry['transport'];
149
+ command: string;
150
+ packageName?: string;
151
+ args?: string[];
152
+ } {
153
+ const dist = entry.distribution as Record<string, unknown> | undefined;
154
+
155
+ if (dist && typeof dist === 'object') {
156
+ // npx transport: { npx: { package: "@scope/name@version", args?: [...] } }
157
+ if (dist.npx && typeof dist.npx === 'object') {
158
+ const npx = dist.npx as Record<string, unknown>;
159
+ const fullPkg = String(npx.package ?? '');
160
+ // Strip version suffix: "@scope/name@1.2.3" -> "@scope/name"
161
+ const packageName = stripVersion(fullPkg);
162
+ const args = Array.isArray(npx.args) ? npx.args.map(String) : undefined;
163
+ // Also extract env if present at npx level
164
+ return { transport: 'npx', command: packageName, packageName, args };
165
+ }
166
+
167
+ // uvx transport: { uvx: { package: "name@version", args?: [...] } }
168
+ if (dist.uvx && typeof dist.uvx === 'object') {
169
+ const uvx = dist.uvx as Record<string, unknown>;
170
+ const fullPkg = String(uvx.package ?? '');
171
+ const packageName = stripVersion(fullPkg);
172
+ const args = Array.isArray(uvx.args) ? uvx.args.map(String) : undefined;
173
+ return { transport: 'uvx', command: packageName, packageName, args };
174
+ }
175
+
176
+ // binary transport: { binary: { "linux-x86_64": { cmd, args } } }
177
+ if (dist.binary && typeof dist.binary === 'object') {
178
+ return { transport: 'binary', command: '' };
179
+ }
180
+ }
181
+
182
+ // Legacy fallback: read flat `transport`/`command` fields
183
+ return {
184
+ transport: normalizeTransport(entry.transport),
185
+ command: String(entry.command ?? entry.cmd ?? ''),
186
+ };
187
+ }
188
+
189
+ /** Strip trailing @version from a package name. "@scope/pkg@1.0" -> "@scope/pkg" */
190
+ function stripVersion(pkg: string): string {
191
+ if (!pkg) return '';
192
+ // Scoped: @scope/name@version — find the last @ that isn't position 0
193
+ const lastAt = pkg.lastIndexOf('@');
194
+ if (lastAt > 0) return pkg.slice(0, lastAt);
195
+ return pkg;
196
+ }
197
+
131
198
  function normalizeTransport(raw: unknown): AcpRegistryEntry['transport'] {
132
199
  const t = String(raw ?? 'stdio').toLowerCase();
133
200
  if (t === 'npx' || t === 'uvx' || t === 'binary') return t;