@mseep/obsidian-agent-client 0.10.6
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/.claude/hooks/gh-setup.sh +49 -0
- package/.claude/settings.json +15 -0
- package/.claude/skills/release-notes/SKILL.md +331 -0
- package/.editorconfig +10 -0
- package/.github/FUNDING.yml +2 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +90 -0
- package/.github/ISSUE_TEMPLATE/config.yml +11 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +59 -0
- package/.github/copilot-instructions.md +45 -0
- package/.github/pull_request_template.md +32 -0
- package/.github/workflows/ci.yaml +25 -0
- package/.github/workflows/docs.yml +58 -0
- package/.github/workflows/relay_to_openclaw.yml +59 -0
- package/.github/workflows/release.yaml +45 -0
- package/.prettierignore +10 -0
- package/.prettierrc +13 -0
- package/.vscode/extensions.json +7 -0
- package/.vscode/settings.json +37 -0
- package/.zed/settings.json +42 -0
- package/AGENTS.md +330 -0
- package/ARCHITECTURE.md +390 -0
- package/CONTRIBUTING.md +216 -0
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.ja.md +121 -0
- package/README.md +125 -0
- package/docs/.vitepress/config.mts +124 -0
- package/docs/.vitepress/theme/custom.css +111 -0
- package/docs/.vitepress/theme/index.ts +4 -0
- package/docs/agent-setup/claude-code.md +84 -0
- package/docs/agent-setup/codex.md +76 -0
- package/docs/agent-setup/custom-agents.md +67 -0
- package/docs/agent-setup/gemini-cli.md +99 -0
- package/docs/agent-setup/index.md +34 -0
- package/docs/announcements/gemini-cli-deprecation.md +73 -0
- package/docs/getting-started/index.md +78 -0
- package/docs/getting-started/quick-start.md +38 -0
- package/docs/help/faq.md +181 -0
- package/docs/help/troubleshooting.md +221 -0
- package/docs/index.md +63 -0
- package/docs/public/apple-touch-icon.png +0 -0
- package/docs/public/demo.mp4 +0 -0
- package/docs/public/favicon-16x16.png +0 -0
- package/docs/public/favicon-32x32.png +0 -0
- package/docs/public/favicon.ico +0 -0
- package/docs/public/images/editing.webp +0 -0
- package/docs/public/images/export.webp +0 -0
- package/docs/public/images/floating-chat-button.webp +0 -0
- package/docs/public/images/floating-chat-instance-menu.webp +0 -0
- package/docs/public/images/floating-chat-view.webp +0 -0
- package/docs/public/images/mode-selection.webp +0 -0
- package/docs/public/images/model-selection.webp +0 -0
- package/docs/public/images/multi-session.webp +0 -0
- package/docs/public/images/remove-image.webp +0 -0
- package/docs/public/images/ribbon-icon.webp +0 -0
- package/docs/public/images/selection-context.gif +0 -0
- package/docs/public/images/sending-images.webp +0 -0
- package/docs/public/images/sending-messages.webp +0 -0
- package/docs/public/images/session-history-button.webp +0 -0
- package/docs/public/images/slash-commands-1.webp +0 -0
- package/docs/public/images/slash-commands-2.webp +0 -0
- package/docs/public/images/switch-agent.webp +0 -0
- package/docs/public/images/switch-default-agent.webp +0 -0
- package/docs/public/images/temporary-disable.gif +0 -0
- package/docs/reference/acp-support.md +110 -0
- package/docs/usage/chat-export.md +80 -0
- package/docs/usage/commands.md +51 -0
- package/docs/usage/context-files.md +57 -0
- package/docs/usage/editing.md +69 -0
- package/docs/usage/floating-chat.md +84 -0
- package/docs/usage/index.md +97 -0
- package/docs/usage/mcp-tools.md +33 -0
- package/docs/usage/mentions.md +70 -0
- package/docs/usage/mode-selection.md +28 -0
- package/docs/usage/model-selection.md +32 -0
- package/docs/usage/multi-session.md +68 -0
- package/docs/usage/sending-images.md +64 -0
- package/docs/usage/session-history.md +91 -0
- package/docs/usage/slash-commands.md +44 -0
- package/esbuild.config.mjs +49 -0
- package/eslint.config.mjs +25 -0
- package/main.js +228 -0
- package/manifest.json +11 -0
- package/package.json +52 -0
- package/src/acp/acp-client.ts +921 -0
- package/src/acp/acp-handler.ts +252 -0
- package/src/acp/permission-handler.ts +282 -0
- package/src/acp/terminal-handler.ts +264 -0
- package/src/acp/type-converter.ts +272 -0
- package/src/hooks/useAgent.ts +250 -0
- package/src/hooks/useAgentMessages.ts +470 -0
- package/src/hooks/useAgentSession.ts +544 -0
- package/src/hooks/useChatActions.ts +400 -0
- package/src/hooks/useHistoryModal.ts +219 -0
- package/src/hooks/useSessionHistory.ts +863 -0
- package/src/hooks/useSettings.ts +19 -0
- package/src/hooks/useSuggestions.ts +342 -0
- package/src/main.ts +9 -0
- package/src/plugin.ts +1126 -0
- package/src/services/chat-exporter.ts +552 -0
- package/src/services/message-sender.ts +755 -0
- package/src/services/message-state.ts +375 -0
- package/src/services/session-helpers.ts +211 -0
- package/src/services/session-state.ts +130 -0
- package/src/services/session-storage.ts +267 -0
- package/src/services/settings-normalizer.ts +255 -0
- package/src/services/settings-service.ts +285 -0
- package/src/services/update-checker.ts +128 -0
- package/src/services/vault-service.ts +558 -0
- package/src/services/view-registry.ts +345 -0
- package/src/types/agent.ts +92 -0
- package/src/types/chat.ts +351 -0
- package/src/types/errors.ts +136 -0
- package/src/types/obsidian-internals.d.ts +14 -0
- package/src/types/session.ts +731 -0
- package/src/ui/ChangeDirectoryModal.ts +137 -0
- package/src/ui/ChatContext.ts +25 -0
- package/src/ui/ChatHeader.tsx +295 -0
- package/src/ui/ChatPanel.tsx +1162 -0
- package/src/ui/ChatView.tsx +348 -0
- package/src/ui/ErrorBanner.tsx +104 -0
- package/src/ui/FloatingButton.tsx +351 -0
- package/src/ui/FloatingChatView.tsx +531 -0
- package/src/ui/InputArea.tsx +1107 -0
- package/src/ui/InputToolbar.tsx +371 -0
- package/src/ui/MessageBubble.tsx +442 -0
- package/src/ui/MessageList.tsx +265 -0
- package/src/ui/PermissionBanner.tsx +61 -0
- package/src/ui/SessionHistoryModal.tsx +821 -0
- package/src/ui/SettingsTab.ts +1337 -0
- package/src/ui/SuggestionPopup.tsx +138 -0
- package/src/ui/TerminalBlock.tsx +107 -0
- package/src/ui/ToolCallBlock.tsx +456 -0
- package/src/ui/shared/AttachmentStrip.tsx +57 -0
- package/src/ui/shared/IconButton.tsx +55 -0
- package/src/ui/shared/MarkdownRenderer.tsx +103 -0
- package/src/ui/view-host.ts +56 -0
- package/src/utils/error-utils.ts +274 -0
- package/src/utils/logger.ts +44 -0
- package/src/utils/mention-parser.ts +129 -0
- package/src/utils/paths.ts +246 -0
- package/src/utils/platform.ts +425 -0
- package/styles.css +2322 -0
- package/tsconfig.json +18 -0
- package/version-bump.mjs +18 -0
- package/versions.json +3 -0
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registry for managing all chat view containers.
|
|
3
|
+
*
|
|
4
|
+
* Provides unified access to views for:
|
|
5
|
+
* - Focus tracking (replacing _lastActiveChatViewId + floating tracking)
|
|
6
|
+
* - Broadcast commands (extending to all view types)
|
|
7
|
+
* - Multi-view operations (focusNext, toAll, etc.)
|
|
8
|
+
*
|
|
9
|
+
* Design notes:
|
|
10
|
+
* - Views register themselves on mount, unregister on close
|
|
11
|
+
* - Focus is tracked via focusedViewId
|
|
12
|
+
* - Registry does not own view lifecycle, only tracks references
|
|
13
|
+
* - clear() is called during plugin unload for cleanup
|
|
14
|
+
* - focusNext/Previous order is based on registration order, not workspace leaf order
|
|
15
|
+
* (this is acceptable as users don't have strong expectations about the order)
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { ChatInputState } from "../types/chat";
|
|
19
|
+
import { getLogger } from "../utils/logger";
|
|
20
|
+
|
|
21
|
+
// ============================================================================
|
|
22
|
+
// Port Types (from chat-view-container.port.ts)
|
|
23
|
+
// ============================================================================
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Type of chat view container.
|
|
27
|
+
* Used for filtering and type-specific behavior.
|
|
28
|
+
*/
|
|
29
|
+
export type ChatViewType = "sidebar" | "floating";
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Interface that all chat view containers must implement.
|
|
33
|
+
* Enables the plugin to manage views uniformly regardless of their implementation.
|
|
34
|
+
*/
|
|
35
|
+
export interface IChatViewContainer {
|
|
36
|
+
// ============================================================
|
|
37
|
+
// Identification
|
|
38
|
+
// ============================================================
|
|
39
|
+
|
|
40
|
+
/** Unique identifier for this view instance */
|
|
41
|
+
readonly viewId: string;
|
|
42
|
+
|
|
43
|
+
/** Type of this view (sidebar, floating, etc.) */
|
|
44
|
+
readonly viewType: ChatViewType;
|
|
45
|
+
|
|
46
|
+
/** Human-readable display name for this view (e.g. active agent label). */
|
|
47
|
+
getDisplayName(): string;
|
|
48
|
+
|
|
49
|
+
// ============================================================
|
|
50
|
+
// Lifecycle
|
|
51
|
+
// ============================================================
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Called when this view becomes the active/focused view.
|
|
55
|
+
* Triggered by ChatViewRegistry.setFocused().
|
|
56
|
+
*/
|
|
57
|
+
onActivate(): void;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Called when this view loses active/focused status.
|
|
61
|
+
* Triggered by ChatViewRegistry.setFocused() or unregister().
|
|
62
|
+
*/
|
|
63
|
+
onDeactivate(): void;
|
|
64
|
+
|
|
65
|
+
// ============================================================
|
|
66
|
+
// Focus Management
|
|
67
|
+
// ============================================================
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Programmatically focus this view's input.
|
|
71
|
+
* Should focus the chat input textarea.
|
|
72
|
+
* For floating views, this also expands the window if collapsed.
|
|
73
|
+
*/
|
|
74
|
+
focus(): void;
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Check if this view currently has focus.
|
|
78
|
+
* Returns true if any element within this view's container is focused.
|
|
79
|
+
*/
|
|
80
|
+
hasFocus(): boolean;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Expand the view if it's in a collapsed state.
|
|
84
|
+
* For sidebar views, this is a no-op.
|
|
85
|
+
* For floating views, this expands the window.
|
|
86
|
+
*
|
|
87
|
+
* Note: This method is provided for explicit expand operations (e.g., from UI).
|
|
88
|
+
* When focus() is called, it internally handles expansion before focusing.
|
|
89
|
+
* ChatViewRegistry uses focus() which implicitly expands, so expand() is not
|
|
90
|
+
* directly called by the registry.
|
|
91
|
+
*/
|
|
92
|
+
expand(): void;
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Collapse the view if it's in an expanded state.
|
|
96
|
+
* For sidebar views, this is a no-op.
|
|
97
|
+
* For floating views, this hides the window without destroying the instance.
|
|
98
|
+
*/
|
|
99
|
+
collapse(): void;
|
|
100
|
+
|
|
101
|
+
// ============================================================
|
|
102
|
+
// Broadcast Commands
|
|
103
|
+
// ============================================================
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Get current input state (text + images) for broadcast.
|
|
107
|
+
* Returns null if input state is not available.
|
|
108
|
+
*/
|
|
109
|
+
getInputState(): ChatInputState | null;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Set input state (text + images) from broadcast.
|
|
113
|
+
* Used to copy prompt from one view to another.
|
|
114
|
+
*/
|
|
115
|
+
setInputState(state: ChatInputState): void;
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Check if this view is ready to send a message.
|
|
119
|
+
* Returns true if:
|
|
120
|
+
* - Session is ready
|
|
121
|
+
* - Not currently sending
|
|
122
|
+
* - Not loading session history
|
|
123
|
+
* - Has content (text or images)
|
|
124
|
+
*/
|
|
125
|
+
canSend(): boolean;
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Trigger send message with full support for images.
|
|
129
|
+
* @returns Promise<boolean> - true if message was sent, false otherwise
|
|
130
|
+
*/
|
|
131
|
+
sendMessage(): Promise<boolean>;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Cancel current operation.
|
|
135
|
+
* Stops ongoing message generation.
|
|
136
|
+
*/
|
|
137
|
+
cancelOperation(): Promise<void>;
|
|
138
|
+
|
|
139
|
+
// ============================================================
|
|
140
|
+
// Container Access
|
|
141
|
+
// ============================================================
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Get the DOM container element for this view.
|
|
145
|
+
* Used for focus detection and DOM queries.
|
|
146
|
+
*/
|
|
147
|
+
getContainerEl(): HTMLElement;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export class ChatViewRegistry {
|
|
151
|
+
private views = new Map<string, IChatViewContainer>();
|
|
152
|
+
private focusedViewId: string | null = null;
|
|
153
|
+
private logger = getLogger();
|
|
154
|
+
|
|
155
|
+
// ============================================================
|
|
156
|
+
// Registration
|
|
157
|
+
// ============================================================
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Register a view container.
|
|
161
|
+
* The first registered view automatically becomes focused.
|
|
162
|
+
*/
|
|
163
|
+
register(view: IChatViewContainer): void {
|
|
164
|
+
this.logger.log(
|
|
165
|
+
`[ChatViewRegistry] Registering view: ${view.viewId} (${view.viewType})`,
|
|
166
|
+
);
|
|
167
|
+
this.views.set(view.viewId, view);
|
|
168
|
+
|
|
169
|
+
// First view becomes focused by default
|
|
170
|
+
if (this.views.size === 1) {
|
|
171
|
+
this.setFocused(view.viewId);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Unregister a view container.
|
|
177
|
+
* If the focused view is unregistered, focus moves to another view.
|
|
178
|
+
*/
|
|
179
|
+
unregister(viewId: string): void {
|
|
180
|
+
this.logger.log(`[ChatViewRegistry] Unregistering view: ${viewId}`);
|
|
181
|
+
const view = this.views.get(viewId);
|
|
182
|
+
if (view) {
|
|
183
|
+
view.onDeactivate();
|
|
184
|
+
}
|
|
185
|
+
this.views.delete(viewId);
|
|
186
|
+
|
|
187
|
+
// Move focus if this was the focused view
|
|
188
|
+
if (this.focusedViewId === viewId) {
|
|
189
|
+
const remaining = Array.from(this.views.keys());
|
|
190
|
+
this.focusedViewId = remaining.length > 0 ? remaining[0] : null;
|
|
191
|
+
if (this.focusedViewId) {
|
|
192
|
+
this.views.get(this.focusedViewId)?.onActivate();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Clear all views from the registry.
|
|
199
|
+
* Called during plugin unload to clean up resources.
|
|
200
|
+
* Note: This does NOT call unmount() on views - that should be done separately.
|
|
201
|
+
*/
|
|
202
|
+
clear(): void {
|
|
203
|
+
this.logger.log("[ChatViewRegistry] Clearing all views");
|
|
204
|
+
for (const view of this.views.values()) {
|
|
205
|
+
view.onDeactivate();
|
|
206
|
+
}
|
|
207
|
+
this.views.clear();
|
|
208
|
+
this.focusedViewId = null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// ============================================================
|
|
212
|
+
// Focus Management
|
|
213
|
+
// ============================================================
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Get the currently focused view.
|
|
217
|
+
*/
|
|
218
|
+
getFocused(): IChatViewContainer | null {
|
|
219
|
+
return this.focusedViewId
|
|
220
|
+
? (this.views.get(this.focusedViewId) ?? null)
|
|
221
|
+
: null;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get the focused view ID.
|
|
226
|
+
*/
|
|
227
|
+
getFocusedId(): string | null {
|
|
228
|
+
return this.focusedViewId;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Set a view as focused.
|
|
233
|
+
*/
|
|
234
|
+
setFocused(viewId: string): void {
|
|
235
|
+
if (this.focusedViewId === viewId) return;
|
|
236
|
+
if (!this.views.has(viewId)) return;
|
|
237
|
+
|
|
238
|
+
// Deactivate previous
|
|
239
|
+
if (this.focusedViewId) {
|
|
240
|
+
this.views.get(this.focusedViewId)?.onDeactivate();
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Activate new
|
|
244
|
+
this.focusedViewId = viewId;
|
|
245
|
+
this.views.get(viewId)?.onActivate();
|
|
246
|
+
this.logger.log(`[ChatViewRegistry] Focus changed to: ${viewId}`);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Focus the next view in the list (cyclic).
|
|
251
|
+
* Order is based on registration order (Map insertion order).
|
|
252
|
+
*/
|
|
253
|
+
focusNext(): void {
|
|
254
|
+
const ids = Array.from(this.views.keys());
|
|
255
|
+
if (ids.length === 0) return;
|
|
256
|
+
|
|
257
|
+
const currentIndex = this.focusedViewId
|
|
258
|
+
? ids.indexOf(this.focusedViewId)
|
|
259
|
+
: -1;
|
|
260
|
+
const nextIndex = (currentIndex + 1) % ids.length;
|
|
261
|
+
this.setFocused(ids[nextIndex]);
|
|
262
|
+
this.views.get(ids[nextIndex])?.focus();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Focus the previous view in the list (cyclic).
|
|
267
|
+
* Order is based on registration order (Map insertion order).
|
|
268
|
+
*/
|
|
269
|
+
focusPrevious(): void {
|
|
270
|
+
const ids = Array.from(this.views.keys());
|
|
271
|
+
if (ids.length === 0) return;
|
|
272
|
+
|
|
273
|
+
const currentIndex = this.focusedViewId
|
|
274
|
+
? ids.indexOf(this.focusedViewId)
|
|
275
|
+
: 0;
|
|
276
|
+
const prevIndex = (currentIndex - 1 + ids.length) % ids.length;
|
|
277
|
+
this.setFocused(ids[prevIndex]);
|
|
278
|
+
this.views.get(ids[prevIndex])?.focus();
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// ============================================================
|
|
282
|
+
// Broadcast Operations
|
|
283
|
+
// ============================================================
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Execute action on the focused view only.
|
|
287
|
+
*/
|
|
288
|
+
toFocused<T>(action: (view: IChatViewContainer) => T): T | null {
|
|
289
|
+
const focused = this.getFocused();
|
|
290
|
+
return focused ? action(focused) : null;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Execute action on all views.
|
|
295
|
+
*/
|
|
296
|
+
toAll(action: (view: IChatViewContainer) => void): void {
|
|
297
|
+
this.views.forEach(action);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Execute action on views of a specific type.
|
|
302
|
+
*/
|
|
303
|
+
toType(
|
|
304
|
+
type: ChatViewType,
|
|
305
|
+
action: (view: IChatViewContainer) => void,
|
|
306
|
+
): void {
|
|
307
|
+
this.views.forEach((view) => {
|
|
308
|
+
if (view.viewType === type) action(view);
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// ============================================================
|
|
313
|
+
// Query
|
|
314
|
+
// ============================================================
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Get all registered views.
|
|
318
|
+
*/
|
|
319
|
+
getAll(): IChatViewContainer[] {
|
|
320
|
+
return Array.from(this.views.values());
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Get views of a specific type.
|
|
325
|
+
*/
|
|
326
|
+
getByType(type: ChatViewType): IChatViewContainer[] {
|
|
327
|
+
return Array.from(this.views.values()).filter(
|
|
328
|
+
(v) => v.viewType === type,
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Get a view by ID.
|
|
334
|
+
*/
|
|
335
|
+
get(viewId: string): IChatViewContainer | null {
|
|
336
|
+
return this.views.get(viewId) ?? null;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Get count of registered views.
|
|
341
|
+
*/
|
|
342
|
+
get size(): number {
|
|
343
|
+
return this.views.size;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain Models for Agent Configuration
|
|
3
|
+
*
|
|
4
|
+
* These types represent agent settings and configuration,
|
|
5
|
+
* independent of the plugin infrastructure. They define
|
|
6
|
+
* the core concepts of agent identity, capabilities, and
|
|
7
|
+
* connection parameters.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
// ============================================================================
|
|
11
|
+
// Environment Configuration
|
|
12
|
+
// ============================================================================
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Environment variable for agent process.
|
|
16
|
+
*
|
|
17
|
+
* Used to pass configuration and credentials to agent processes
|
|
18
|
+
* via environment variables (e.g., API keys, paths, feature flags).
|
|
19
|
+
*/
|
|
20
|
+
export interface AgentEnvVar {
|
|
21
|
+
/** Environment variable name (e.g., "ANTHROPIC_API_KEY") */
|
|
22
|
+
key: string;
|
|
23
|
+
|
|
24
|
+
/** Environment variable value */
|
|
25
|
+
value: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Agent Configuration
|
|
30
|
+
// ============================================================================
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Base configuration shared by all agent types.
|
|
34
|
+
*
|
|
35
|
+
* Defines the common properties needed to launch and communicate
|
|
36
|
+
* with any ACP-compatible agent, regardless of the specific
|
|
37
|
+
* implementation (Claude Code, Gemini CLI, custom agents, etc.).
|
|
38
|
+
*/
|
|
39
|
+
export interface BaseAgentSettings {
|
|
40
|
+
/** Unique identifier for this agent (e.g., "claude", "gemini", "custom-1") */
|
|
41
|
+
id: string;
|
|
42
|
+
|
|
43
|
+
/** Human-readable display name shown in UI */
|
|
44
|
+
displayName: string;
|
|
45
|
+
|
|
46
|
+
/** Command to execute (full path to executable or command name) */
|
|
47
|
+
command: string;
|
|
48
|
+
|
|
49
|
+
/** Command-line arguments passed to the agent */
|
|
50
|
+
args: string[];
|
|
51
|
+
|
|
52
|
+
/** Environment variables for the agent process */
|
|
53
|
+
env: AgentEnvVar[];
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Configuration for Gemini CLI agent.
|
|
58
|
+
*
|
|
59
|
+
* Extends base settings with Gemini-specific requirements.
|
|
60
|
+
*/
|
|
61
|
+
export interface GeminiAgentSettings extends BaseAgentSettings {
|
|
62
|
+
/** Gemini API key (GEMINI_API_KEY) */
|
|
63
|
+
apiKey: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Configuration for Claude Code agent.
|
|
68
|
+
*
|
|
69
|
+
* Extends base settings with Claude-specific requirements.
|
|
70
|
+
*/
|
|
71
|
+
export interface ClaudeAgentSettings extends BaseAgentSettings {
|
|
72
|
+
/** Anthropic API key for Claude (ANTHROPIC_API_KEY) */
|
|
73
|
+
apiKey: string;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Configuration for Codex CLI agent.
|
|
78
|
+
*
|
|
79
|
+
* Extends base settings with Codex-specific requirements.
|
|
80
|
+
*/
|
|
81
|
+
export interface CodexAgentSettings extends BaseAgentSettings {
|
|
82
|
+
/** OpenAI API key for Codex (OPENAI_API_KEY) */
|
|
83
|
+
apiKey: string;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Configuration for custom ACP-compatible agents.
|
|
88
|
+
*
|
|
89
|
+
* Uses only the base settings, allowing users to configure
|
|
90
|
+
* any agent that implements the Agent Client Protocol.
|
|
91
|
+
*/
|
|
92
|
+
export type CustomAgentSettings = BaseAgentSettings;
|