@ampcode/plugin 0.0.0-20260225013638-g011c7ef

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/README.md ADDED
@@ -0,0 +1,60 @@
1
+ <!-- This file is rendered directly on https://ampcode.com/manual/plugin-api -->
2
+
3
+ # Amp Plugin API
4
+
5
+ Amp plugins are TypeScript files that extend and customize [Amp](https://ampcode.com). Plugins live in `~/.amp/plugins/` (global) or `.amp/plugins/` (project).
6
+
7
+ > The Amp plugin API is experimental. Expect many breaking changes if you choose to use it right now. Do not use it for anything critical.
8
+
9
+ <br/>
10
+
11
+ The plugin API supports:
12
+
13
+ - **Event handlers** — `amp.on(...)` for hooking into tool calls, messages, and other events
14
+ - **Tools** — `amp.registerTool(...)` for custom tools
15
+ - **Commands** — `amp.registerCommand(...)` to add to Amp's command palette
16
+ - **User input and UI** — `ctx.ui.notify(...)`, `ctx.ui.confirm(...)`
17
+ - **AI & system utilities** — `amp.ai.ask(...)` for yes-no LLM answers
18
+
19
+ <br/>
20
+
21
+ You can use plugins to:
22
+
23
+ - Format files and report file diagnostics after each edit
24
+ - Ensure Amp runs tests before finishing its work
25
+ - Block or require confirmation for commands you deem risky
26
+ - Correct common agent mistakes that AGENTS.md alone can't fix
27
+
28
+ See [Amp Plugin API documentation](https://ampcode.com/manual/plugin-api).
29
+
30
+ ## Example
31
+
32
+ `.amp/plugins/permissions.ts`:
33
+
34
+ ```ts
35
+ // @i-know-the-amp-plugin-api-is-wip-and-very-experimental-right-now
36
+ import type { PluginAPI } from '@ampcode/plugin'
37
+
38
+ export default function (amp: PluginAPI) {
39
+ // Ask the user before executing any tool.
40
+ amp.on('tool.call', async (event, ctx) => {
41
+ const confirmed = await ctx.ui.confirm({
42
+ title: `Allow ${event.tool}?`,
43
+ message: `The agent wants to execute the "${event.tool}" tool.`,
44
+ confirmButtonText: 'Allow',
45
+ })
46
+ if (!confirmed) {
47
+ ctx.logger.log(`User rejected tool execution: ${event.tool}`)
48
+ return {
49
+ action: 'reject-and-continue',
50
+ message: `User rejected execution of tool ${event.tool}.`,
51
+ }
52
+ }
53
+ return { action: 'allow' }
54
+ })
55
+ }
56
+ ```
57
+
58
+ ## Acknowledgment
59
+
60
+ Amp's plugin API is inspired by [pi's extension API](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/docs/extensions.md).
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@ampcode/plugin",
3
+ "version": "0.0.0-20260225013638-g011c7ef",
4
+ "description": "Amp Plugin API",
5
+ "homepage": "https://ampcode.com/manual/plugin-api",
6
+ "author": {
7
+ "name": "The Amp Team",
8
+ "email": "amp-devs@ampcode.com"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/sourcegraph/amp",
13
+ "directory": "lib/plugin-api"
14
+ },
15
+ "type": "module",
16
+ "types": "src/index.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./src/index.ts"
20
+ }
21
+ },
22
+ "files": [
23
+ "src",
24
+ "README.md"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "sideEffects": false,
30
+ "scripts": {
31
+ "test": "biome check --config-path=../.. src"
32
+ },
33
+ "devDependencies": {
34
+ "@types/node": "catalog:"
35
+ }
36
+ }
package/src/ai.ts ADDED
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Result from an AI ask operation.
3
+ */
4
+ export interface PluginAIAskResult {
5
+ /** The classification result: 'yes', 'no', or 'uncertain' */
6
+ result: 'yes' | 'no' | 'uncertain'
7
+
8
+ /** Probability (0-1) that the answer is yes */
9
+ probability: number
10
+
11
+ /** Explanation of why the AI gave this answer */
12
+ reason: string
13
+ }
14
+
15
+ /**
16
+ * AI capabilities provided to plugins.
17
+ */
18
+ export interface PluginAI {
19
+ /**
20
+ * Ask an AI model a yes/no question and get a confidence-based response with reasoning.
21
+ * @param question - The yes/no question to ask
22
+ * @returns Object with result, probability, and reason
23
+ */
24
+ ask(question: string): Promise<PluginAIAskResult>
25
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Observer interface for subscribing to configuration changes.
3
+ */
4
+ export interface PluginConfigurationObserver<T> {
5
+ next?(value: T): void
6
+
7
+ error?(error: unknown): void
8
+
9
+ complete?(): void
10
+ }
11
+
12
+ /**
13
+ * Subscription that can be unsubscribed to release resources.
14
+ */
15
+ export interface Subscription {
16
+ unsubscribe(): void
17
+ }
18
+
19
+ /**
20
+ * Target for configuration updates.
21
+ */
22
+ export type PluginConfigurationTarget = 'workspace' | 'global'
23
+
24
+ /**
25
+ * Observable-like interface for Amp configuration.
26
+ * Provides a limited subset of Observable functionality for plugins.
27
+ */
28
+ export interface PluginConfiguration<T> {
29
+ /**
30
+ * Subscribe to configuration changes.
31
+ */
32
+ subscribe(observer: PluginConfigurationObserver<T>): Subscription
33
+ subscribe(onNext: (value: T) => void): Subscription
34
+
35
+ /**
36
+ * Pipe operators for transforming the configuration observable.
37
+ */
38
+ pipe<Out>(op: (input: PluginConfiguration<T>) => Out): Out
39
+
40
+ /**
41
+ * Get the current configuration value.
42
+ */
43
+ get(): Promise<T>
44
+
45
+ /**
46
+ * Update configuration with partial values.
47
+ * @param partial - The partial configuration to merge
48
+ * @param target - Where to store the setting: 'global' (user settings) or 'workspace' (default)
49
+ */
50
+ update(partial: Partial<T>, target?: PluginConfigurationTarget): Promise<void>
51
+
52
+ /**
53
+ * Delete a configuration key.
54
+ * @param key - The key to delete
55
+ * @param target - Where to delete from: 'global' (user settings) or 'workspace' (default)
56
+ */
57
+ delete(key: keyof T, target?: PluginConfigurationTarget): Promise<void>
58
+ }
package/src/events.ts ADDED
@@ -0,0 +1,240 @@
1
+ import type { PluginAI } from './ai'
2
+ import type { PluginLogger, PluginSystem, ShellFunction, SpanID } from './system'
3
+ import type { PluginThread, ThreadMessage } from './thread'
4
+ import type { PluginUI } from './ui'
5
+
6
+ /**
7
+ * URI value returned by helper APIs.
8
+ *
9
+ * This stays intentionally minimal so external plugin authors don't need
10
+ * Amp's internal URI package in their dependency graph.
11
+ */
12
+ export interface URI {
13
+ toString(): string
14
+ }
15
+
16
+ /**
17
+ * Event payload for session.start event.
18
+ */
19
+ export type SessionStartEvent = Record<string, never>
20
+
21
+ /**
22
+ * Event payload for tool.call event.
23
+ * This is a request that expects a response from the handler.
24
+ */
25
+ export interface ToolCallEvent<T = string, I = Record<string, unknown>> {
26
+ /** Unique identifier for this tool use (e.g., "toolu_xxx") */
27
+ toolUseID: string
28
+
29
+ /** Name of the tool that will be executed */
30
+ tool: T
31
+
32
+ /** Input arguments that will be passed to the tool */
33
+ input: I
34
+ }
35
+
36
+ /**
37
+ * Result returned from a tool.call handler.
38
+ * Determines how the tool execution should proceed.
39
+ */
40
+ export type ToolCallResult =
41
+ /** Allow the tool to execute with its original input */
42
+ | { action: 'allow' }
43
+
44
+ /** Reject the tool call but allow the agent to continue with other tools */
45
+ | { action: 'reject-and-continue'; message: string }
46
+
47
+ /** Modify the tool's input arguments before execution */
48
+ | { action: 'modify'; input: Record<string, unknown> }
49
+
50
+ /** Provide a synthesized result without actually running the tool */
51
+ | { action: 'synthesize'; result: { output: string; exitCode?: number } }
52
+
53
+ /** Error occurred in the plugin - stops the thread worker and shows an ephemeral error */
54
+ | { action: 'error'; message: string }
55
+
56
+ /**
57
+ * Event payload for tool.result event.
58
+ */
59
+ export interface ToolResultEvent {
60
+ /** Unique identifier for this tool use (e.g., "toolu_xxx") */
61
+ toolUseID: string
62
+
63
+ /** Name of the tool that was executed */
64
+ tool: string
65
+
66
+ /** Input arguments passed to the tool */
67
+ input: Record<string, unknown>
68
+
69
+ /** Result status of the tool execution */
70
+ status: 'done' | 'error' | 'cancelled'
71
+
72
+ /** Error message if status is 'error' */
73
+ error?: string
74
+
75
+ /** Tool output/result if available */
76
+ output?: unknown
77
+ }
78
+
79
+ /**
80
+ * Result returned from a tool.result handler.
81
+ * Allows modifying the tool result before it is sent back to the model.
82
+ */
83
+ export type ToolResultResult =
84
+ | {
85
+ status: 'done'
86
+ output?: unknown
87
+ }
88
+ | {
89
+ status: 'error'
90
+ error?: string
91
+ output?: unknown
92
+ }
93
+ | {
94
+ status: 'cancelled'
95
+ error?: string
96
+ output?: unknown
97
+ }
98
+ | undefined
99
+ | void
100
+
101
+ /**
102
+ * Event payload for agent.start event.
103
+ * Fired when a user submits a prompt (initial or reply).
104
+ */
105
+ export interface AgentStartEvent {
106
+ /** The user's prompt message */
107
+ message: string
108
+
109
+ /** The message ID */
110
+ id: number
111
+ }
112
+
113
+ /**
114
+ * Result returned from an agent.start handler.
115
+ * Allows adding context messages or modifying the system prompt.
116
+ */
117
+ export interface AgentStartResult {
118
+ /**
119
+ * A message to append after the user's content in the user message.
120
+ * If display is true, the message is shown in the UI.
121
+ */
122
+ message?: { content: string; display: true }
123
+ }
124
+
125
+ /**
126
+ * Event payload for agent.end event.
127
+ * Fired when the agent finishes handling a user prompt.
128
+ */
129
+ export interface AgentEndEvent {
130
+ /** The user's prompt message that started this turn */
131
+ message: string
132
+
133
+ /** The message ID that started this turn */
134
+ id: number
135
+
136
+ /** The outcome of the agent's turn */
137
+ status: 'done' | 'error' | 'interrupted'
138
+
139
+ /** All messages since the agent.start event (including the user message that started this turn) */
140
+ messages: ThreadMessage[]
141
+ }
142
+
143
+ /**
144
+ * Result returned from an agent.end handler.
145
+ * Allows starting a new agent turn by returning a user message.
146
+ */
147
+ export type AgentEndResult =
148
+ /** Automatically send a follow-up user message to start a new agent turn */
149
+ { action: 'continue'; userMessage: string } | void
150
+
151
+ /**
152
+ * Map of event names to their payload types.
153
+ */
154
+ export interface PluginEventMap {
155
+ 'session.start': SessionStartEvent
156
+ 'tool.call': ToolCallEvent
157
+ 'tool.result': ToolResultEvent
158
+ 'agent.start': AgentStartEvent
159
+ 'agent.end': AgentEndEvent
160
+ }
161
+
162
+ /**
163
+ * Map of request event names to their result types.
164
+ * These events expect a response from the handler.
165
+ */
166
+ export interface PluginRequestResultMap {
167
+ 'tool.call': ToolCallResult
168
+ 'tool.result': ToolResultResult
169
+ 'agent.start': AgentStartResult
170
+ 'agent.end': AgentEndResult
171
+ }
172
+
173
+ /**
174
+ * Context passed as the second argument to event handlers.
175
+ */
176
+ export interface PluginEventContext {
177
+ /** Scoped logger for plugin output. Log messages are appended to the handler's trace span events. */
178
+ logger: PluginLogger
179
+
180
+ /** Bun's shell API for executing commands */
181
+ $: ShellFunction
182
+
183
+ /** Platform UI capabilities */
184
+ ui: PluginUI
185
+
186
+ /** AI capabilities */
187
+ ai: PluginAI
188
+
189
+ /** System capabilities */
190
+ system: PluginSystem
191
+
192
+ /** Thread manipulation API */
193
+ thread: PluginThread
194
+
195
+ /** The trace span ID for this handler invocation, if tracing is enabled */
196
+ span?: SpanID
197
+ }
198
+
199
+ /**
200
+ * Handler return type based on whether the event expects a response.
201
+ * Request events (in PluginRequestResultMap) must return a result.
202
+ * Fire-and-forget events return void.
203
+ */
204
+ export type PluginHandlerResult<E extends keyof PluginEventMap> =
205
+ E extends keyof PluginRequestResultMap
206
+ ? PluginRequestResultMap[E] | Promise<PluginRequestResultMap[E]>
207
+ : void | Promise<void>
208
+
209
+ /**
210
+ * Standardized shell command representation.
211
+ */
212
+ export interface ShellCommand {
213
+ command: string
214
+ dir?: string
215
+ }
216
+
217
+ /**
218
+ * A tool call and its corresponding terminal tool result extracted from thread messages.
219
+ */
220
+ export interface ToolCallWithResult {
221
+ call: ToolCallEvent
222
+ result: ToolResultEvent
223
+ }
224
+
225
+ /**
226
+ * Extracts the shell command from a Bash or shell_command tool call.
227
+ * Returns null if the event is not a shell command tool call.
228
+ */
229
+ export type ShellCommandFromToolCall = (event: ToolCallEvent) => ShellCommand | null
230
+
231
+ /**
232
+ * Extracts paired tool calls and terminal tool results from a list of thread messages.
233
+ */
234
+ export type ToolCallsInMessages = (messages: ThreadMessage[]) => ToolCallWithResult[]
235
+
236
+ /**
237
+ * Returns an array of file URIs modified by a tool call, or null if the tool doesn't modify files.
238
+ * Supports edit/create/apply_patch tools and sed in-place shell commands.
239
+ */
240
+ export type FilesModifiedByToolCall = (event: ToolCallEvent | ToolResultEvent) => URI[] | null
package/src/index.ts ADDED
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Amp Plugin API
3
+ *
4
+ * Plugins are JavaScript/TypeScript programs that extend Amp's functionality.
5
+ * They are long-lived processes that may run for multiple threads.
6
+ *
7
+ * Plugins live in `.amp/plugins/*.{js,ts}` and are executed using Bun.
8
+ *
9
+ * A plugin exports a default function that receives a {@link PluginAPI} instance:
10
+ *
11
+ * ```ts
12
+ * import type { PluginAPI } from '@ampcode/plugin'
13
+ *
14
+ * export default function (amp: PluginAPI) {
15
+ * amp.on('session.start', (event, ctx) => {
16
+ * ctx.ui.notify('Welcome')
17
+ * })
18
+ * }
19
+ * ```
20
+ */
21
+
22
+ export * from './ai'
23
+ export * from './configuration'
24
+ export * from './events'
25
+ export * from './system'
26
+ export * from './thread'
27
+ export * from './ui'
28
+
29
+ import type { PluginAI } from './ai'
30
+ import type { PluginConfiguration, Subscription } from './configuration'
31
+ import type {
32
+ FilesModifiedByToolCall,
33
+ PluginEventContext,
34
+ PluginEventMap,
35
+ PluginHandlerResult,
36
+ ShellCommandFromToolCall,
37
+ ToolCallsInMessages,
38
+ } from './events'
39
+ import type { PluginLogger, PluginSystem, ShellFunction } from './system'
40
+ import type { ThreadID } from './thread'
41
+ import type { PluginUI } from './ui'
42
+
43
+ /**
44
+ * The client environment kind.
45
+ */
46
+ export type PluginClientKind = 'terminal' | 'editor' | 'web'
47
+
48
+ /**
49
+ * Information about the client running the plugin.
50
+ */
51
+ export interface PluginClient {
52
+ /** The kind of client environment */
53
+ kind: PluginClientKind
54
+
55
+ /** The version of the client */
56
+ version: string
57
+ }
58
+
59
+ /**
60
+ * Options for registering a command.
61
+ */
62
+ export interface PluginCommandOptions {
63
+ /** The title shown after the colon in the command palette (e.g., "Greet" in "Hello: Greet") */
64
+ title: string
65
+
66
+ /** The category shown before the colon (e.g., "Hello" in "Hello: Greet"). Defaults to the plugin name. */
67
+ category?: string
68
+
69
+ /** Human-readable description of what this command does */
70
+ description?: string
71
+ }
72
+
73
+ /**
74
+ * Context passed to command handlers.
75
+ * Provides access to UI capabilities for executing command actions.
76
+ */
77
+ export interface PluginCommandContext {
78
+ /** Platform UI capabilities */
79
+ ui: PluginUI
80
+
81
+ /** AI capabilities */
82
+ ai: PluginAI
83
+
84
+ /** System capabilities */
85
+ system: PluginSystem
86
+
87
+ /** Bun's shell API for executing commands */
88
+ $: ShellFunction
89
+
90
+ /** Current thread context if a thread is active, undefined otherwise */
91
+ thread?: {
92
+ id: ThreadID
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Context passed to tool execute handlers.
98
+ */
99
+ export interface PluginToolContext {
100
+ /** Scoped logger for plugin output */
101
+ logger: PluginLogger
102
+ }
103
+
104
+ /**
105
+ * Options for registering a tool that the agent can call.
106
+ */
107
+ export interface PluginToolDefinition {
108
+ /** Tool name (must match ^[a-zA-Z0-9_-]+$) */
109
+ name: string
110
+
111
+ /** Description shown to the LLM explaining what the tool does */
112
+ description: string
113
+
114
+ /** JSON Schema for the tool's input parameters */
115
+ inputSchema: {
116
+ type: 'object'
117
+ properties?: Record<string, object>
118
+ required?: string[]
119
+ [key: string]: unknown
120
+ }
121
+
122
+ /** Execute the tool with the given input and return a result */
123
+ execute: (input: Record<string, unknown>, ctx: PluginToolContext) => Promise<unknown>
124
+ }
125
+
126
+ /**
127
+ * The plugin API object passed to the plugin's default export function.
128
+ */
129
+ export interface PluginAPI {
130
+ /** Logger scoped to this plugin */
131
+ logger: PluginLogger
132
+
133
+ /** Information about the client environment */
134
+ client: PluginClient
135
+
136
+ /** Observable configuration that streams changes */
137
+ configuration: PluginConfiguration<Record<string, unknown>>
138
+
139
+ /**
140
+ * Execute shell commands using Bun's shell.
141
+ * Unlike `ctx.$` in event handlers, this is not tied to a specific hook invocation.
142
+ */
143
+ $: ShellFunction
144
+
145
+ /**
146
+ * Helper utilities for interpreting tool events.
147
+ */
148
+ helpers: {
149
+ shellCommandFromToolCall: ShellCommandFromToolCall
150
+ toolCallsInMessages: ToolCallsInMessages
151
+ filesModifiedByToolCall: FilesModifiedByToolCall
152
+ }
153
+
154
+ /**
155
+ * Register a handler for plugin events.
156
+ * For request events (e.g., tool.call), the handler must return a result.
157
+ * For fire-and-forget events, the handler returns void.
158
+ */
159
+ on<E extends keyof PluginEventMap>(
160
+ event: E,
161
+ handler: (event: PluginEventMap[E], ctx: PluginEventContext) => PluginHandlerResult<E>,
162
+ ): Subscription
163
+
164
+ /**
165
+ * Register a command that appears in Amp's command palette.
166
+ * When the user invokes the command, the handler is called.
167
+ *
168
+ * @param id - Stable identifier for the command (e.g., "hello-world").
169
+ * @param options - Configuration for the command including title, category, and description.
170
+ * @param handler - The function to execute when the command is invoked.
171
+ *
172
+ * @example
173
+ * ```ts
174
+ * amp.registerCommand('hello-world', { title: 'greet', category: 'hello', description: 'Say hello' }, async (ctx) => {
175
+ * await ctx.ui.notify('Hello, world!')
176
+ * })
177
+ * ```
178
+ */
179
+ registerCommand(
180
+ id: string,
181
+ options: PluginCommandOptions,
182
+ handler: (ctx: PluginCommandContext) => void | Promise<void>,
183
+ ): Subscription
184
+
185
+ /**
186
+ * Register a tool that the agent can call.
187
+ * Plugin tools appear alongside built-in tools and can be invoked by the LLM during conversations.
188
+ *
189
+ * @param definition - The tool definition including name, description, schema, and execute handler.
190
+ *
191
+ * @example
192
+ * ```ts
193
+ * amp.registerTool({
194
+ * name: 'hello',
195
+ * description: 'Greet someone by name',
196
+ * inputSchema: {
197
+ * type: 'object',
198
+ * properties: { name: { type: 'string', description: 'Name to greet' } },
199
+ * required: ['name'],
200
+ * },
201
+ * async execute(input) {
202
+ * return `Hello, ${input.name}!`
203
+ * },
204
+ * })
205
+ * ```
206
+ */
207
+ registerTool(definition: PluginToolDefinition): Subscription
208
+
209
+ /** AI helpers */
210
+ ai: PluginAI
211
+ }
package/src/system.ts ADDED
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Logger provided to plugins for scoped logging.
3
+ */
4
+ export interface PluginLogger {
5
+ log: (...args: unknown[]) => void
6
+ }
7
+
8
+ /**
9
+ * Bun shell function type (simplified version of Bun.$)
10
+ */
11
+ export type ShellFunction = (
12
+ strings: TemplateStringsArray,
13
+ ...values: unknown[]
14
+ ) => Promise<ShellResult>
15
+
16
+ /**
17
+ * Result from a shell command execution.
18
+ */
19
+ export interface ShellResult {
20
+ exitCode: number
21
+ stdout: string
22
+ stderr: string
23
+ }
24
+
25
+ /**
26
+ * System capabilities provided to plugins.
27
+ */
28
+ export interface PluginSystem {
29
+ /**
30
+ * Open a URL using the system's default protocol handler.
31
+ * On the CLI, it also shows a dialog with the URL text (for SSH users who can't open URLs remotely).
32
+ */
33
+ open(url: string | URL): Promise<void>
34
+
35
+ /**
36
+ * Get the effective Amp base URL currently used by this Amp client.
37
+ * This reflects the active runtime configuration (for example, custom domains via `AMP_URL`).
38
+ */
39
+ readonly ampURL: URL
40
+ }
41
+
42
+ /** @internal */
43
+ export type SpanID = string & { readonly __brand: 'SpanID' }
package/src/thread.ts ADDED
@@ -0,0 +1,97 @@
1
+ export type ThreadID = `T-${string}`
2
+
3
+ /**
4
+ * A text content block in a message.
5
+ */
6
+ export interface ThreadTextBlock {
7
+ type: 'text'
8
+ text: string
9
+ }
10
+
11
+ /**
12
+ * A thinking content block in a message.
13
+ */
14
+ export interface ThreadThinkingBlock {
15
+ type: 'thinking'
16
+ thinking: string
17
+ }
18
+
19
+ /**
20
+ * A tool use content block in a message.
21
+ */
22
+ export interface ThreadToolUseBlock {
23
+ type: 'tool_use'
24
+ id: string
25
+ name: string
26
+ input: Record<string, unknown>
27
+ }
28
+
29
+ /**
30
+ * A tool result content block in a message.
31
+ */
32
+ export interface ThreadToolResultBlock {
33
+ type: 'tool_result'
34
+ toolUseID: string
35
+ output?: string
36
+ status: 'done' | 'error' | 'cancelled' | 'running' | 'pending'
37
+ }
38
+
39
+ /**
40
+ * A user message in the thread.
41
+ */
42
+ export interface ThreadUserMessage {
43
+ role: 'user'
44
+
45
+ /** The message ID, which is unique in the thread. */
46
+ id: number
47
+
48
+ content: (ThreadTextBlock | ThreadToolResultBlock)[]
49
+ }
50
+
51
+ /**
52
+ * An assistant message in the thread.
53
+ */
54
+ export interface ThreadAssistantMessage {
55
+ role: 'assistant'
56
+
57
+ /** The message ID, which is unique in the thread. */
58
+ id: number
59
+
60
+ content: (ThreadTextBlock | ThreadThinkingBlock | ThreadToolUseBlock)[]
61
+ }
62
+
63
+ /**
64
+ * An info message in the thread.
65
+ */
66
+ export interface ThreadInfoMessage {
67
+ role: 'info'
68
+
69
+ /** The message ID, which is unique in the thread. */
70
+ id: number
71
+
72
+ content: ThreadTextBlock[]
73
+ }
74
+
75
+ /**
76
+ * A message in the thread (simplified view for plugins).
77
+ */
78
+ export type ThreadMessage = ThreadUserMessage | ThreadAssistantMessage | ThreadInfoMessage
79
+
80
+ /**
81
+ * Thread API for manipulating the current thread.
82
+ */
83
+ export interface PluginThread {
84
+ /**
85
+ * Append a user message to the thread.
86
+ */
87
+ append(messages: UserMessage[]): Promise<void>
88
+ }
89
+
90
+ /**
91
+ * A user message that can be appended to the thread.
92
+ */
93
+ export interface UserMessage {
94
+ type: 'user-message'
95
+
96
+ content: string
97
+ }
package/src/ui.ts ADDED
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Options for the input dialog.
3
+ */
4
+ export interface PluginInputOptions {
5
+ /** Dialog title */
6
+ title?: string
7
+
8
+ /** Help text/description shown below the title */
9
+ helpText?: string
10
+
11
+ /** Initial text value in the input field */
12
+ initialValue?: string
13
+
14
+ /** Text for the submit button (default: "Submit") */
15
+ submitButtonText?: string
16
+ }
17
+
18
+ /**
19
+ * Options for the confirm dialog.
20
+ */
21
+ export interface PluginConfirmOptions {
22
+ /** Dialog title */
23
+ title: string
24
+
25
+ /** Message body shown below the title */
26
+ message?: string
27
+
28
+ /** Text for the confirm button (default: "Yes") */
29
+ confirmButtonText?: string
30
+ }
31
+
32
+ /**
33
+ * UI capabilities provided to plugins.
34
+ */
35
+ export interface PluginUI {
36
+ notify(message: string): Promise<void>
37
+ /**
38
+ * Show an input dialog prompting the user for text input.
39
+ * @returns The entered text, or undefined if the user cancelled.
40
+ */
41
+ input(options: PluginInputOptions): Promise<string | undefined>
42
+
43
+ /**
44
+ * Show a confirmation dialog with Yes/No options.
45
+ * @returns true if the user confirmed, false if they cancelled.
46
+ */
47
+ confirm(options: PluginConfirmOptions): Promise<boolean>
48
+ }