@sourcegraph/amp-sdk 0.1.0-20251014155204-ge7f0f28 → 0.1.0-20251020161918-gf8ab86d
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 +32 -0
- package/dist/index.d.ts +9 -10
- package/dist/index.js +100 -18
- package/dist/types.d.ts +100 -8
- package/dist/types.js +64 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -191,6 +191,38 @@ for await (const message of execute({
|
|
|
191
191
|
}
|
|
192
192
|
```
|
|
193
193
|
|
|
194
|
+
### Tool Permissions
|
|
195
|
+
|
|
196
|
+
Control which tools Amp can use with fine-grained permissions:
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
import { execute, createPermission } from '@sourcegraph/amp-sdk'
|
|
200
|
+
|
|
201
|
+
for await (const message of execute({
|
|
202
|
+
prompt: 'List files and run tests',
|
|
203
|
+
options: {
|
|
204
|
+
permissions: [
|
|
205
|
+
// Allow listing files
|
|
206
|
+
createPermission('Bash', 'allow', { matches: { cmd: 'ls *' } }),
|
|
207
|
+
// Allow running tests
|
|
208
|
+
createPermission('Bash', 'allow', { matches: { cmd: 'npm test' } }),
|
|
209
|
+
// Ask before reading sensitive files
|
|
210
|
+
createPermission('Read', 'ask', { matches: { path: '/etc/*' } }),
|
|
211
|
+
],
|
|
212
|
+
},
|
|
213
|
+
})) {
|
|
214
|
+
// Process messages
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Permission rules support:
|
|
219
|
+
|
|
220
|
+
- **Pattern matching**: Use `*` wildcards and regex patterns
|
|
221
|
+
- **Context control**: Restrict rules to main thread or sub-agents
|
|
222
|
+
- **Delegation**: Delegate permission decisions to external programs
|
|
223
|
+
|
|
224
|
+
Learn more about permissions in the [manual](https://ampcode.com/manual#permissions) and the [appendix](https://ampcode.com/manual/appendix#permissions-reference).
|
|
225
|
+
|
|
194
226
|
## Advanced Usage
|
|
195
227
|
|
|
196
228
|
### Interactive Progress Tracking
|
package/dist/index.d.ts
CHANGED
|
@@ -5,17 +5,16 @@
|
|
|
5
5
|
* run Amp programmatically in Node.js applications. It wraps the Amp CLI
|
|
6
6
|
* with the --stream-json flag to provide structured output.
|
|
7
7
|
*/
|
|
8
|
-
import { type ExecuteOptions, type StreamMessage, type UserInputMessage } from './types.js';
|
|
9
|
-
/**
|
|
10
|
-
* Execute a command with Amp CLI and return an async iterator of messages
|
|
11
|
-
*
|
|
12
|
-
* @param options Execute configuration including prompt and options
|
|
13
|
-
* @returns Async iterator of stream messages from Amp CLI
|
|
14
|
-
*/
|
|
8
|
+
import { type ExecuteOptions, type Permission, type PermissionMatchCondition, type StreamMessage, type UserInputMessage } from './types.js';
|
|
9
|
+
/** Execute a command with Amp CLI and return an async iterator of messages */
|
|
15
10
|
export declare function execute(options: ExecuteOptions): AsyncIterable<StreamMessage>;
|
|
16
|
-
/**
|
|
17
|
-
* Helper function to create streaming input messages
|
|
18
|
-
*/
|
|
11
|
+
/** Create a user input message for streaming conversations */
|
|
19
12
|
export declare function createUserMessage(text: string): UserInputMessage;
|
|
13
|
+
/** Create a permission object for controlling tool usage */
|
|
14
|
+
export declare function createPermission(tool: string, action: 'allow' | 'reject' | 'ask' | 'delegate', options?: {
|
|
15
|
+
matches?: Record<string, PermissionMatchCondition>;
|
|
16
|
+
context?: 'thread' | 'subagent';
|
|
17
|
+
to?: string;
|
|
18
|
+
}): Permission;
|
|
20
19
|
export * from './types.js';
|
|
21
20
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import { spawn } from 'node:child_process';
|
|
9
9
|
import fs from 'node:fs';
|
|
10
|
+
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
10
11
|
import { createRequire } from 'node:module';
|
|
11
12
|
import path from 'node:path';
|
|
12
13
|
import { createInterface } from 'node:readline';
|
|
@@ -16,31 +17,33 @@ const isWindows = process.platform === 'win32';
|
|
|
16
17
|
// ============================================================================
|
|
17
18
|
// Main Execute Function
|
|
18
19
|
// ============================================================================
|
|
19
|
-
/**
|
|
20
|
-
* Execute a command with Amp CLI and return an async iterator of messages
|
|
21
|
-
*
|
|
22
|
-
* @param options Execute configuration including prompt and options
|
|
23
|
-
* @returns Async iterator of stream messages from Amp CLI
|
|
24
|
-
*/
|
|
20
|
+
/** Execute a command with Amp CLI and return an async iterator of messages */
|
|
25
21
|
export async function* execute(options) {
|
|
26
22
|
const { prompt, options: ampOptions = {}, signal } = options;
|
|
27
23
|
// Validate options
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
const
|
|
24
|
+
let validatedOptions = AmpOptionsSchema.parse(ampOptions);
|
|
25
|
+
// Build settings file (create temp file if needed)
|
|
26
|
+
const { settingsFilePath, cleanupTempFile } = await buildSettingsFile(validatedOptions, generateSessionId());
|
|
27
|
+
// Update options with temp settings file path if created
|
|
28
|
+
validatedOptions = {
|
|
29
|
+
...validatedOptions,
|
|
30
|
+
...(settingsFilePath && { settingsFile: settingsFilePath }),
|
|
31
|
+
};
|
|
31
32
|
// Build CLI arguments
|
|
32
33
|
const args = buildCliArgs(validatedOptions);
|
|
34
|
+
// Handle different prompt types
|
|
35
|
+
const isStreamingInput = typeof prompt !== 'string' && Symbol.asyncIterator in prompt;
|
|
33
36
|
// Add flag for streaming input if needed
|
|
34
37
|
if (isStreamingInput) {
|
|
35
38
|
args.push('--stream-json-input');
|
|
36
39
|
}
|
|
40
|
+
// Build environment variables
|
|
41
|
+
const env = buildEnvironmentVariables(validatedOptions);
|
|
37
42
|
// Log the full CLI command for debugging (only in debug mode)
|
|
38
43
|
if (process.env.AMP_DEBUG || validatedOptions.logLevel === 'debug') {
|
|
39
44
|
const ampCommand = findAmpCommand();
|
|
40
45
|
console.debug(`Executing Amp CLI: ${ampCommand.command} ${[...ampCommand.args, ...args].join(' ')}`);
|
|
41
46
|
}
|
|
42
|
-
// Build environment variables
|
|
43
|
-
const env = buildEnvironmentVariables(validatedOptions);
|
|
44
47
|
// Spawn Amp CLI process
|
|
45
48
|
const ampProcess = spawnAmpCli(args, {
|
|
46
49
|
env,
|
|
@@ -88,14 +91,71 @@ export async function* execute(options) {
|
|
|
88
91
|
}
|
|
89
92
|
throw error;
|
|
90
93
|
}
|
|
94
|
+
finally {
|
|
95
|
+
// Clean up temp settings file
|
|
96
|
+
await cleanupTempFile();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// Settings File Management
|
|
101
|
+
// ============================================================================
|
|
102
|
+
/** Generate a unique session ID for organizing temp files */
|
|
103
|
+
function generateSessionId() {
|
|
104
|
+
const randomHex = Math.random().toString(36).substring(2, 10);
|
|
105
|
+
return `sdk-${Date.now()}-${randomHex}`;
|
|
106
|
+
}
|
|
107
|
+
/** Build settings file for CLI execution, creating a temp file if permissions need to be passed */
|
|
108
|
+
async function buildSettingsFile(options, sessionId) {
|
|
109
|
+
// Check if we need to create a temp settings file
|
|
110
|
+
if (!options.permissions) {
|
|
111
|
+
// No temp file needed
|
|
112
|
+
return {
|
|
113
|
+
settingsFilePath: null,
|
|
114
|
+
cleanupTempFile: async () => { },
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
// Determine working directory
|
|
118
|
+
const cwd = options.cwd || process.cwd();
|
|
119
|
+
// Create temp directory path: {cwd}/.tmp/{sessionId}/
|
|
120
|
+
const tempDir = path.join(cwd, '.tmp', sessionId);
|
|
121
|
+
const tempSettingsPath = path.join(tempDir, 'settings.json');
|
|
122
|
+
// Read existing settings file if provided
|
|
123
|
+
let mergedSettings = {};
|
|
124
|
+
if (options.settingsFile) {
|
|
125
|
+
try {
|
|
126
|
+
const settingsContent = await readFile(options.settingsFile, 'utf-8');
|
|
127
|
+
mergedSettings = JSON.parse(settingsContent);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
// If file doesn't exist or can't be read, start with empty settings
|
|
131
|
+
if (error.code !== 'ENOENT') {
|
|
132
|
+
throw new Error(`Failed to read settings file ${options.settingsFile}: ${error instanceof Error ? error.message : String(error)}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Add permissions to settings with amp. prefix
|
|
137
|
+
mergedSettings['amp.permissions'] = options.permissions;
|
|
138
|
+
// Create temp directory
|
|
139
|
+
await mkdir(tempDir, { recursive: true });
|
|
140
|
+
// Write merged settings to temp file
|
|
141
|
+
await writeFile(tempSettingsPath, JSON.stringify(mergedSettings, null, 2), 'utf-8');
|
|
142
|
+
// Return temp file path and cleanup function
|
|
143
|
+
return {
|
|
144
|
+
settingsFilePath: tempSettingsPath,
|
|
145
|
+
cleanupTempFile: async () => {
|
|
146
|
+
try {
|
|
147
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
148
|
+
}
|
|
149
|
+
catch (error) {
|
|
150
|
+
// Ignore cleanup errors
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
};
|
|
91
154
|
}
|
|
92
155
|
// ============================================================================
|
|
93
156
|
// Environment Variable Management
|
|
94
157
|
// ============================================================================
|
|
95
|
-
/**
|
|
96
|
-
* Build environment variables for the Amp CLI process
|
|
97
|
-
* Combines system environment variables with user-provided options
|
|
98
|
-
*/
|
|
158
|
+
/** Build environment variables for the Amp CLI process */
|
|
99
159
|
function buildEnvironmentVariables(options) {
|
|
100
160
|
const env = {
|
|
101
161
|
...process.env,
|
|
@@ -113,6 +173,7 @@ function buildEnvironmentVariables(options) {
|
|
|
113
173
|
// ============================================================================
|
|
114
174
|
// CLI Process Management
|
|
115
175
|
// ============================================================================
|
|
176
|
+
/** Spawn the Amp CLI process with the given arguments */
|
|
116
177
|
function spawnAmpCli(args, options) {
|
|
117
178
|
const { env, cwd, signal } = options;
|
|
118
179
|
// Find amp executable
|
|
@@ -129,6 +190,7 @@ function spawnAmpCli(args, options) {
|
|
|
129
190
|
});
|
|
130
191
|
return childProcess;
|
|
131
192
|
}
|
|
193
|
+
/** Find the Amp CLI executable in the local node_modules */
|
|
132
194
|
function findAmpCommand() {
|
|
133
195
|
// Try to find the local CLI (npm already resolved the correct version)
|
|
134
196
|
try {
|
|
@@ -152,6 +214,7 @@ function findAmpCommand() {
|
|
|
152
214
|
throw new Error('Could not find local @sourcegraph/amp package. Make sure it is installed.');
|
|
153
215
|
}
|
|
154
216
|
}
|
|
217
|
+
/** Build CLI arguments from options */
|
|
155
218
|
function buildCliArgs(options) {
|
|
156
219
|
const args = [];
|
|
157
220
|
// Handle continue option first as it changes the base command structure
|
|
@@ -190,6 +253,7 @@ function buildCliArgs(options) {
|
|
|
190
253
|
// ============================================================================
|
|
191
254
|
// Stream Processing
|
|
192
255
|
// ============================================================================
|
|
256
|
+
/** Process the stdout stream from Amp CLI and yield parsed messages */
|
|
193
257
|
async function* processOutputStream(stdout) {
|
|
194
258
|
if (!stdout) {
|
|
195
259
|
throw new Error('No stdout stream available from Amp CLI process');
|
|
@@ -215,6 +279,7 @@ async function* processOutputStream(stdout) {
|
|
|
215
279
|
readline.close();
|
|
216
280
|
}
|
|
217
281
|
}
|
|
282
|
+
/** Handle streaming input by writing user messages to the process stdin */
|
|
218
283
|
async function handleStreamingInput(process, prompt, signal) {
|
|
219
284
|
if (!process.stdin) {
|
|
220
285
|
throw new Error('No stdin stream available for Amp CLI process');
|
|
@@ -248,6 +313,7 @@ async function handleStreamingInput(process, prompt, signal) {
|
|
|
248
313
|
process.stdin.end();
|
|
249
314
|
}
|
|
250
315
|
}
|
|
316
|
+
/** Handle string input by writing the prompt to process stdin */
|
|
251
317
|
function handleStringInput(process, prompt) {
|
|
252
318
|
if (!process.stdin) {
|
|
253
319
|
throw new Error('No stdin stream available for Amp CLI process');
|
|
@@ -256,6 +322,7 @@ function handleStringInput(process, prompt) {
|
|
|
256
322
|
process.stdin.write(prompt + '\n');
|
|
257
323
|
process.stdin.end();
|
|
258
324
|
}
|
|
325
|
+
/** Wait for the process to exit and capture exit code, stderr, and signal */
|
|
259
326
|
function waitForProcess(process, signal) {
|
|
260
327
|
return new Promise((resolve, reject) => {
|
|
261
328
|
let resolved = false;
|
|
@@ -306,9 +373,7 @@ function waitForProcess(process, signal) {
|
|
|
306
373
|
// ============================================================================
|
|
307
374
|
// Utility Functions
|
|
308
375
|
// ============================================================================
|
|
309
|
-
/**
|
|
310
|
-
* Helper function to create streaming input messages
|
|
311
|
-
*/
|
|
376
|
+
/** Create a user input message for streaming conversations */
|
|
312
377
|
export function createUserMessage(text) {
|
|
313
378
|
return {
|
|
314
379
|
type: 'user',
|
|
@@ -318,6 +383,23 @@ export function createUserMessage(text) {
|
|
|
318
383
|
},
|
|
319
384
|
};
|
|
320
385
|
}
|
|
386
|
+
/** Create a permission object for controlling tool usage */
|
|
387
|
+
export function createPermission(tool, action, options) {
|
|
388
|
+
const permission = {
|
|
389
|
+
tool,
|
|
390
|
+
action,
|
|
391
|
+
...(options?.matches && { matches: options.matches }),
|
|
392
|
+
...(options?.context && { context: options.context }),
|
|
393
|
+
};
|
|
394
|
+
// delegate requires "to"
|
|
395
|
+
if (action === 'delegate') {
|
|
396
|
+
if (!options?.to) {
|
|
397
|
+
throw new Error('delegate action requires "to" option');
|
|
398
|
+
}
|
|
399
|
+
permission.to = options.to;
|
|
400
|
+
}
|
|
401
|
+
return permission;
|
|
402
|
+
}
|
|
321
403
|
// ============================================================================
|
|
322
404
|
// Re-export types for convenience
|
|
323
405
|
// ============================================================================
|
package/dist/types.d.ts
CHANGED
|
@@ -91,7 +91,9 @@ export interface ErrorResultMessage extends BaseResultMessage {
|
|
|
91
91
|
is_error: true;
|
|
92
92
|
error: string;
|
|
93
93
|
}
|
|
94
|
+
/** Union of all possible stream messages */
|
|
94
95
|
export type StreamMessage = SystemMessage | AssistantMessage | UserMessage | ResultMessage | ErrorResultMessage;
|
|
96
|
+
/** User input message schema */
|
|
95
97
|
export declare const UserInputMessageSchema: z.ZodObject<{
|
|
96
98
|
type: z.ZodLiteral<"user">;
|
|
97
99
|
message: z.ZodObject<{
|
|
@@ -138,6 +140,51 @@ export declare const UserInputMessageSchema: z.ZodObject<{
|
|
|
138
140
|
};
|
|
139
141
|
type: "user";
|
|
140
142
|
}>;
|
|
143
|
+
/** User input message for streaming conversations */
|
|
144
|
+
export type UserInputMessage = z.infer<typeof UserInputMessageSchema>;
|
|
145
|
+
/** Recursive type for permission match conditions */
|
|
146
|
+
export type PermissionMatchCondition = string | PermissionMatchCondition[] | {
|
|
147
|
+
[key in string]: PermissionMatchCondition;
|
|
148
|
+
} | boolean | number | null | undefined;
|
|
149
|
+
/** Permission match condition for tool arguments schema */
|
|
150
|
+
export declare const PermissionMatchConditionSchema: z.ZodType<PermissionMatchCondition>;
|
|
151
|
+
/** Individual permission schema */
|
|
152
|
+
export declare const PermissionSchema: z.ZodEffects<z.ZodObject<{
|
|
153
|
+
tool: z.ZodString;
|
|
154
|
+
matches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<PermissionMatchCondition, z.ZodTypeDef, PermissionMatchCondition>>>;
|
|
155
|
+
action: z.ZodEnum<["allow", "reject", "ask", "delegate"]>;
|
|
156
|
+
context: z.ZodOptional<z.ZodEnum<["thread", "subagent"]>>;
|
|
157
|
+
to: z.ZodOptional<z.ZodString>;
|
|
158
|
+
}, "strip", z.ZodTypeAny, {
|
|
159
|
+
tool: string;
|
|
160
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
161
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
162
|
+
context?: "thread" | "subagent" | undefined;
|
|
163
|
+
to?: string | undefined;
|
|
164
|
+
}, {
|
|
165
|
+
tool: string;
|
|
166
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
167
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
168
|
+
context?: "thread" | "subagent" | undefined;
|
|
169
|
+
to?: string | undefined;
|
|
170
|
+
}>, {
|
|
171
|
+
tool: string;
|
|
172
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
173
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
174
|
+
context?: "thread" | "subagent" | undefined;
|
|
175
|
+
to?: string | undefined;
|
|
176
|
+
}, {
|
|
177
|
+
tool: string;
|
|
178
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
179
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
180
|
+
context?: "thread" | "subagent" | undefined;
|
|
181
|
+
to?: string | undefined;
|
|
182
|
+
}>;
|
|
183
|
+
/** Permission */
|
|
184
|
+
export type Permission = z.infer<typeof PermissionSchema>;
|
|
185
|
+
/** Permissions list */
|
|
186
|
+
export type PermissionsList = Permission[];
|
|
187
|
+
/** MCP server configuration schema */
|
|
141
188
|
export declare const MCPServerSchema: z.ZodObject<{
|
|
142
189
|
command: z.ZodString;
|
|
143
190
|
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
@@ -151,6 +198,7 @@ export declare const MCPServerSchema: z.ZodObject<{
|
|
|
151
198
|
args?: string[] | undefined;
|
|
152
199
|
env?: Record<string, string> | undefined;
|
|
153
200
|
}>;
|
|
201
|
+
/** MCP configuration schema */
|
|
154
202
|
export declare const MCPConfigSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
155
203
|
command: z.ZodString;
|
|
156
204
|
args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
@@ -164,6 +212,11 @@ export declare const MCPConfigSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
164
212
|
args?: string[] | undefined;
|
|
165
213
|
env?: Record<string, string> | undefined;
|
|
166
214
|
}>>;
|
|
215
|
+
/** MCP server configuration */
|
|
216
|
+
export type MCPServer = z.infer<typeof MCPServerSchema>;
|
|
217
|
+
/** MCP configuration object */
|
|
218
|
+
export type MCPConfig = z.infer<typeof MCPConfigSchema>;
|
|
219
|
+
/** Configuration options for Amp execution schema */
|
|
167
220
|
export declare const AmpOptionsSchema: z.ZodObject<{
|
|
168
221
|
cwd: z.ZodOptional<z.ZodString>;
|
|
169
222
|
dangerouslyAllowAll: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -187,6 +240,37 @@ export declare const AmpOptionsSchema: z.ZodObject<{
|
|
|
187
240
|
env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
188
241
|
continue: z.ZodOptional<z.ZodUnion<[z.ZodBoolean, z.ZodString]>>;
|
|
189
242
|
toolbox: z.ZodOptional<z.ZodString>;
|
|
243
|
+
permissions: z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{
|
|
244
|
+
tool: z.ZodString;
|
|
245
|
+
matches: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodType<PermissionMatchCondition, z.ZodTypeDef, PermissionMatchCondition>>>;
|
|
246
|
+
action: z.ZodEnum<["allow", "reject", "ask", "delegate"]>;
|
|
247
|
+
context: z.ZodOptional<z.ZodEnum<["thread", "subagent"]>>;
|
|
248
|
+
to: z.ZodOptional<z.ZodString>;
|
|
249
|
+
}, "strip", z.ZodTypeAny, {
|
|
250
|
+
tool: string;
|
|
251
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
252
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
253
|
+
context?: "thread" | "subagent" | undefined;
|
|
254
|
+
to?: string | undefined;
|
|
255
|
+
}, {
|
|
256
|
+
tool: string;
|
|
257
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
258
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
259
|
+
context?: "thread" | "subagent" | undefined;
|
|
260
|
+
to?: string | undefined;
|
|
261
|
+
}>, {
|
|
262
|
+
tool: string;
|
|
263
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
264
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
265
|
+
context?: "thread" | "subagent" | undefined;
|
|
266
|
+
to?: string | undefined;
|
|
267
|
+
}, {
|
|
268
|
+
tool: string;
|
|
269
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
270
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
271
|
+
context?: "thread" | "subagent" | undefined;
|
|
272
|
+
to?: string | undefined;
|
|
273
|
+
}>, "many">>;
|
|
190
274
|
}, "strict", z.ZodTypeAny, {
|
|
191
275
|
env?: Record<string, string> | undefined;
|
|
192
276
|
cwd?: string | undefined;
|
|
@@ -202,6 +286,13 @@ export declare const AmpOptionsSchema: z.ZodObject<{
|
|
|
202
286
|
}> | undefined;
|
|
203
287
|
continue?: string | boolean | undefined;
|
|
204
288
|
toolbox?: string | undefined;
|
|
289
|
+
permissions?: {
|
|
290
|
+
tool: string;
|
|
291
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
292
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
293
|
+
context?: "thread" | "subagent" | undefined;
|
|
294
|
+
to?: string | undefined;
|
|
295
|
+
}[] | undefined;
|
|
205
296
|
}, {
|
|
206
297
|
env?: Record<string, string> | undefined;
|
|
207
298
|
cwd?: string | undefined;
|
|
@@ -217,18 +308,19 @@ export declare const AmpOptionsSchema: z.ZodObject<{
|
|
|
217
308
|
}> | undefined;
|
|
218
309
|
continue?: string | boolean | undefined;
|
|
219
310
|
toolbox?: string | undefined;
|
|
311
|
+
permissions?: {
|
|
312
|
+
tool: string;
|
|
313
|
+
action: "allow" | "reject" | "ask" | "delegate";
|
|
314
|
+
matches?: Record<string, PermissionMatchCondition> | undefined;
|
|
315
|
+
context?: "thread" | "subagent" | undefined;
|
|
316
|
+
to?: string | undefined;
|
|
317
|
+
}[] | undefined;
|
|
220
318
|
}>;
|
|
221
|
-
/**
|
|
222
|
-
export type UserInputMessage = z.infer<typeof UserInputMessageSchema>;
|
|
223
|
-
/** MCP server configuration */
|
|
224
|
-
export type MCPServer = z.infer<typeof MCPServerSchema>;
|
|
225
|
-
/** MCP configuration object */
|
|
226
|
-
export type MCPConfig = z.infer<typeof MCPConfigSchema>;
|
|
227
|
-
/** Configuration options for Amp CLI execution */
|
|
319
|
+
/** Configuration options for Amp execution */
|
|
228
320
|
export type AmpOptions = z.infer<typeof AmpOptionsSchema>;
|
|
229
321
|
/** Input type for prompts - either a string or streaming user messages */
|
|
230
322
|
type PromptInput = string | AsyncIterable<UserInputMessage>;
|
|
231
|
-
/** Options for executing Amp
|
|
323
|
+
/** Options for executing Amp commands */
|
|
232
324
|
export interface ExecuteOptions {
|
|
233
325
|
prompt: PromptInput;
|
|
234
326
|
options?: AmpOptions;
|
package/dist/types.js
CHANGED
|
@@ -5,8 +5,9 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
// ============================================================================
|
|
8
|
-
//
|
|
8
|
+
// User Message Schemas & Types
|
|
9
9
|
// ============================================================================
|
|
10
|
+
/** User input message schema */
|
|
10
11
|
export const UserInputMessageSchema = z.object({
|
|
11
12
|
type: z.literal('user'),
|
|
12
13
|
message: z.object({
|
|
@@ -17,6 +18,59 @@ export const UserInputMessageSchema = z.object({
|
|
|
17
18
|
})),
|
|
18
19
|
}),
|
|
19
20
|
});
|
|
21
|
+
/** Permission match condition for tool arguments schema */
|
|
22
|
+
export const PermissionMatchConditionSchema = z.lazy(() => z.union([
|
|
23
|
+
z.string().describe('Pattern match where "*" matches any number of any characters'),
|
|
24
|
+
z.array(PermissionMatchConditionSchema).min(1).describe('OR match of each entry'),
|
|
25
|
+
z.boolean().describe('A literal boolean match'),
|
|
26
|
+
z.number().describe('A literal number match'),
|
|
27
|
+
z.null().describe('A literal null match'),
|
|
28
|
+
z.undefined().describe('A literal undefined match'),
|
|
29
|
+
z
|
|
30
|
+
.record(z.string(), PermissionMatchConditionSchema)
|
|
31
|
+
.describe('Matching individual keys of an object'),
|
|
32
|
+
]));
|
|
33
|
+
/** Individual permission schema */
|
|
34
|
+
export const PermissionSchema = z
|
|
35
|
+
.object({
|
|
36
|
+
tool: z.string().min(1).describe('The name of the tool to which this entry applies'),
|
|
37
|
+
matches: z
|
|
38
|
+
.record(z.string(), PermissionMatchConditionSchema)
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('Maps tool inputs to conditions'),
|
|
41
|
+
action: z
|
|
42
|
+
.enum(['allow', 'reject', 'ask', 'delegate'])
|
|
43
|
+
.describe('How Amp should proceed in case of a match'),
|
|
44
|
+
context: z
|
|
45
|
+
.enum(['thread', 'subagent'])
|
|
46
|
+
.optional()
|
|
47
|
+
.describe('Only apply this entry in this context'),
|
|
48
|
+
to: z
|
|
49
|
+
.string()
|
|
50
|
+
.min(1)
|
|
51
|
+
.optional()
|
|
52
|
+
.describe('Command to delegate to when action is "delegate"'),
|
|
53
|
+
})
|
|
54
|
+
.superRefine((data, ctx) => {
|
|
55
|
+
if (data.action === 'delegate' && !data.to) {
|
|
56
|
+
ctx.addIssue({
|
|
57
|
+
code: z.ZodIssueCode.custom,
|
|
58
|
+
message: 'delegate action requires "to" field',
|
|
59
|
+
path: ['to'],
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
if (data.action !== 'delegate' && data.to) {
|
|
63
|
+
ctx.addIssue({
|
|
64
|
+
code: z.ZodIssueCode.custom,
|
|
65
|
+
message: '"to" field only allowed with delegate action',
|
|
66
|
+
path: ['to'],
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// MCP Schemas & Types
|
|
72
|
+
// ============================================================================
|
|
73
|
+
/** MCP server configuration schema */
|
|
20
74
|
export const MCPServerSchema = z.object({
|
|
21
75
|
command: z.string().describe('Command to run the MCP server'),
|
|
22
76
|
args: z.array(z.string()).describe('Arguments for the MCP server command').optional(),
|
|
@@ -25,9 +79,14 @@ export const MCPServerSchema = z.object({
|
|
|
25
79
|
.describe('Environment variables for the server')
|
|
26
80
|
.optional(),
|
|
27
81
|
});
|
|
82
|
+
/** MCP configuration schema */
|
|
28
83
|
export const MCPConfigSchema = z
|
|
29
84
|
.record(z.string(), MCPServerSchema)
|
|
30
85
|
.describe('MCP server configurations keyed by server name');
|
|
86
|
+
// ============================================================================
|
|
87
|
+
// Execute Schemas & Types
|
|
88
|
+
// ============================================================================
|
|
89
|
+
/** Configuration options for Amp execution schema */
|
|
31
90
|
export const AmpOptionsSchema = z
|
|
32
91
|
.object({
|
|
33
92
|
cwd: z.string().describe('Current working directory').optional(),
|
|
@@ -59,6 +118,10 @@ export const AmpOptionsSchema = z
|
|
|
59
118
|
.describe('Continue the most recent thread (true) or a specific thread by ID (string)')
|
|
60
119
|
.optional(),
|
|
61
120
|
toolbox: z.string().describe('Folder path with toolbox scripts').optional(),
|
|
121
|
+
permissions: z
|
|
122
|
+
.array(PermissionSchema)
|
|
123
|
+
.describe('Permission rules for tool usage')
|
|
124
|
+
.optional(),
|
|
62
125
|
})
|
|
63
126
|
.strict();
|
|
64
127
|
//# sourceMappingURL=types.js.map
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"email": "amp-devs@sourcegraph.com"
|
|
5
5
|
},
|
|
6
6
|
"dependencies": {
|
|
7
|
-
"@sourcegraph/amp": "
|
|
7
|
+
"@sourcegraph/amp": "latest",
|
|
8
8
|
"zod": "^3.23.8"
|
|
9
9
|
},
|
|
10
10
|
"description": "TypeScript SDK for Amp CLI - Build custom AI agents with Amp's capabilities",
|
|
@@ -44,12 +44,12 @@
|
|
|
44
44
|
},
|
|
45
45
|
"type": "module",
|
|
46
46
|
"types": "dist/index.d.ts",
|
|
47
|
-
"version": "0.1.0-
|
|
47
|
+
"version": "0.1.0-20251020161918-gf8ab86d",
|
|
48
48
|
"scripts": {
|
|
49
49
|
"build": "pnpm exec tsc -b",
|
|
50
50
|
"dev": "pnpm exec tsc -b --watch",
|
|
51
51
|
"clean": "rm -rf dist tsconfig.tsbuildinfo",
|
|
52
|
-
"examples:basic": "pnpm run build && bun run examples/basic
|
|
52
|
+
"examples:basic": "pnpm run build && bun run examples/basic.ts",
|
|
53
53
|
"test": "vitest run",
|
|
54
54
|
"test:watch": "vitest",
|
|
55
55
|
"pin-cli-version": "bun run scripts/pin-cli-version.ts"
|