@ory/amp 0.10.0
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 +120 -0
- package/dist/cli/assets.d.ts +18 -0
- package/dist/cli/assets.js +91 -0
- package/dist/cli/main.d.ts +12 -0
- package/dist/cli/main.js +192 -0
- package/dist/cli/setup.d.ts +32 -0
- package/dist/cli/setup.js +197 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +15 -0
- package/dist/permission.d.ts +46 -0
- package/dist/permission.js +201 -0
- package/dist/plugin.d.ts +42 -0
- package/dist/plugin.js +217 -0
- package/dist/types.d.ts +176 -0
- package/dist/types.js +45 -0
- package/package.json +87 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Amp (Sourcegraph's coding agent) plugin types.
|
|
3
|
+
*
|
|
4
|
+
* Verified against the installed `amp` binary (Bun-compiled, embedded JS
|
|
5
|
+
* bundle exposing the `@ampcode/plugin` API). Amp's integration is a HYBRID
|
|
6
|
+
* of two mechanisms:
|
|
7
|
+
*
|
|
8
|
+
* 1. Permission delegate helper (PRIMARY, blocking) — a standalone
|
|
9
|
+
* program named in `amp.permissions` as `{ tool, action: "delegate",
|
|
10
|
+
* to: "<program>" }`. Amp invokes it as a subprocess, passing the tool
|
|
11
|
+
* parameters as JSON on stdin. The program decides by exit code:
|
|
12
|
+
* 0 = allow, 1 = ask the user, ≥2 = reject (stderr → model reason).
|
|
13
|
+
* A 10-second delegate timeout applies (a timed-out delegate is
|
|
14
|
+
* treated as a reject). See `AmpDelegateInput` below.
|
|
15
|
+
*
|
|
16
|
+
* 2. In-process plugin (SECONDARY, tracing/auth) — a default-exported
|
|
17
|
+
* factory placed under `.amp/plugins/*.ts` that receives a `PluginAPI`
|
|
18
|
+
* (the `@ampcode/plugin` contract). Runs under Bun's TypeScript
|
|
19
|
+
* runtime. Used here ONLY for advisory session-start auth and
|
|
20
|
+
* post-tool tracing; the blocking decision lives in the delegate
|
|
21
|
+
* helper for cleaner subprocess parity.
|
|
22
|
+
*
|
|
23
|
+
* We model the `@ampcode/plugin` API surface locally (the plugin package
|
|
24
|
+
* takes no harness SDK dependency — see AGENTS.md). The shapes mirror the
|
|
25
|
+
* binary's `PluginEventMap` / `PluginEventContext` exactly.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* JSON payload Amp writes to the delegate program's stdin.
|
|
29
|
+
*
|
|
30
|
+
* The delegate receives the tool name and its arguments. We read several
|
|
31
|
+
* plausible spellings for the tool name (`tool` / `toolName` / `name`) and
|
|
32
|
+
* arguments (`input` / `params` / `arguments` / `args`) so the helper
|
|
33
|
+
* degrades gracefully across Amp revisions; anything we cannot find falls
|
|
34
|
+
* back to "unknown", which fails open (allow) per the design rules.
|
|
35
|
+
*/
|
|
36
|
+
export interface AmpDelegateInput {
|
|
37
|
+
/** Tool being invoked (canonical: `tool`). */
|
|
38
|
+
tool?: string;
|
|
39
|
+
/** Alternate spellings tolerated for forward/backward compatibility. */
|
|
40
|
+
toolName?: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
/** Tool parameters (canonical: `input`). */
|
|
43
|
+
input?: Record<string, unknown>;
|
|
44
|
+
params?: Record<string, unknown>;
|
|
45
|
+
arguments?: Record<string, unknown>;
|
|
46
|
+
args?: Record<string, unknown>;
|
|
47
|
+
/** Optional session/thread correlation id, if Amp supplies one. */
|
|
48
|
+
threadID?: string;
|
|
49
|
+
sessionID?: string;
|
|
50
|
+
session_id?: string;
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Exit codes the delegate program returns to Amp.
|
|
55
|
+
* NOTE the inversion vs. other harnesses: deny is exit ≥2, not exit 0/1.
|
|
56
|
+
*/
|
|
57
|
+
export declare const AMP_DELEGATE_EXIT: {
|
|
58
|
+
/** Allow the tool call. */
|
|
59
|
+
readonly ALLOW: 0;
|
|
60
|
+
/**
|
|
61
|
+
* Ask the user. Reserved — not produced by this version. Ory observe
|
|
62
|
+
* mode passes through (exit 0) and enforce mode rejects (exit 2); there
|
|
63
|
+
* is no "ask Ory then ask the user" middle state yet.
|
|
64
|
+
*/
|
|
65
|
+
readonly ASK: 1;
|
|
66
|
+
/** Reject the tool call; stderr is forwarded to the model as the reason. */
|
|
67
|
+
readonly REJECT: 2;
|
|
68
|
+
};
|
|
69
|
+
/** Thread reference carried on every plugin event. */
|
|
70
|
+
export interface AmpThreadRef {
|
|
71
|
+
id: string;
|
|
72
|
+
[key: string]: unknown;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The result an in-process `tool.call` handler can return to influence a
|
|
76
|
+
* tool invocation. We never return a blocking action from the in-process
|
|
77
|
+
* plugin — the delegate helper owns blocking — but the type is modeled in
|
|
78
|
+
* full to match `@ampcode/plugin`.
|
|
79
|
+
*/
|
|
80
|
+
export type AmpToolCallResult = {
|
|
81
|
+
action: "allow";
|
|
82
|
+
} | {
|
|
83
|
+
action: "reject-and-continue";
|
|
84
|
+
message: string;
|
|
85
|
+
} | {
|
|
86
|
+
action: "modify";
|
|
87
|
+
input: Record<string, unknown>;
|
|
88
|
+
} | {
|
|
89
|
+
action: "synthesize";
|
|
90
|
+
result: {
|
|
91
|
+
output: string;
|
|
92
|
+
exitCode?: number;
|
|
93
|
+
};
|
|
94
|
+
} | {
|
|
95
|
+
action: "error";
|
|
96
|
+
message: string;
|
|
97
|
+
};
|
|
98
|
+
/** `session.start` — a new thread/session begins. */
|
|
99
|
+
export interface AmpSessionStartEvent {
|
|
100
|
+
thread: AmpThreadRef;
|
|
101
|
+
[key: string]: unknown;
|
|
102
|
+
}
|
|
103
|
+
/** `agent.start` — the user submitted a prompt; a turn begins. */
|
|
104
|
+
export interface AmpAgentStartEvent {
|
|
105
|
+
thread: AmpThreadRef;
|
|
106
|
+
[key: string]: unknown;
|
|
107
|
+
}
|
|
108
|
+
/** `tool.call` — a tool is about to execute (pre-execution). */
|
|
109
|
+
export interface AmpToolCallEvent {
|
|
110
|
+
toolUseID: string;
|
|
111
|
+
tool: string;
|
|
112
|
+
input: Record<string, unknown>;
|
|
113
|
+
thread: AmpThreadRef;
|
|
114
|
+
[key: string]: unknown;
|
|
115
|
+
}
|
|
116
|
+
/** `tool.result` — a tool finished executing (post-execution). */
|
|
117
|
+
export interface AmpToolResultEvent {
|
|
118
|
+
toolUseID: string;
|
|
119
|
+
tool: string;
|
|
120
|
+
input: Record<string, unknown>;
|
|
121
|
+
status: "done" | "error" | "cancelled";
|
|
122
|
+
error?: string;
|
|
123
|
+
output?: unknown;
|
|
124
|
+
thread: AmpThreadRef;
|
|
125
|
+
[key: string]: unknown;
|
|
126
|
+
}
|
|
127
|
+
/** `agent.end` — a turn ended, carrying the produced messages. */
|
|
128
|
+
export interface AmpAgentEndEvent {
|
|
129
|
+
thread: AmpThreadRef;
|
|
130
|
+
messages?: unknown[];
|
|
131
|
+
[key: string]: unknown;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Context (`PluginEventContext`) passed as the SECOND argument to every
|
|
135
|
+
* handler. Carries Amp's UI helpers, a shell runner (`$`), etc. Modeled as
|
|
136
|
+
* an open object — this plugin only authenticates and traces, so it does
|
|
137
|
+
* not depend on any specific context member.
|
|
138
|
+
*/
|
|
139
|
+
export interface AmpPluginEventContext {
|
|
140
|
+
[key: string]: unknown;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Map of Amp plugin event name → payload type. Handlers receive the payload
|
|
144
|
+
* as the first arg and a `PluginEventContext` as the second.
|
|
145
|
+
*/
|
|
146
|
+
export interface AmpEventMap {
|
|
147
|
+
"session.start": AmpSessionStartEvent;
|
|
148
|
+
"agent.start": AmpAgentStartEvent;
|
|
149
|
+
"tool.call": AmpToolCallEvent;
|
|
150
|
+
"tool.result": AmpToolResultEvent;
|
|
151
|
+
"agent.end": AmpAgentEndEvent;
|
|
152
|
+
}
|
|
153
|
+
export type AmpEvent = keyof AmpEventMap;
|
|
154
|
+
/** Return type for each event handler. */
|
|
155
|
+
export interface AmpEventReturn {
|
|
156
|
+
"session.start": void;
|
|
157
|
+
"agent.start": void;
|
|
158
|
+
"tool.call": void | AmpToolCallResult;
|
|
159
|
+
"tool.result": void;
|
|
160
|
+
"agent.end": void;
|
|
161
|
+
}
|
|
162
|
+
/** Handler signature for a given event: `(event, ctx) => result`. */
|
|
163
|
+
export type AmpEventHandler<E extends AmpEvent> = (event: AmpEventMap[E], ctx: AmpPluginEventContext) => AmpEventReturn[E] | Promise<AmpEventReturn[E]>;
|
|
164
|
+
/**
|
|
165
|
+
* The PluginAPI object Amp passes to the default-exported plugin factory
|
|
166
|
+
* (`@ampcode/plugin`'s `PluginAPI`).
|
|
167
|
+
*/
|
|
168
|
+
export interface AmpPluginApi {
|
|
169
|
+
/** Subscribe to a lifecycle event. */
|
|
170
|
+
on<E extends AmpEvent>(event: E, handler: AmpEventHandler<E>): void;
|
|
171
|
+
/** Register a custom tool. Unused by this plugin; modeled for completeness. */
|
|
172
|
+
registerTool?: (name: string, def: unknown) => void;
|
|
173
|
+
[key: string]: unknown;
|
|
174
|
+
}
|
|
175
|
+
/** The default-exported plugin factory Amp invokes at load time. */
|
|
176
|
+
export type AmpPlugin = (api: AmpPluginApi) => void | Promise<void>;
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Amp (Sourcegraph's coding agent) plugin types.
|
|
4
|
+
*
|
|
5
|
+
* Verified against the installed `amp` binary (Bun-compiled, embedded JS
|
|
6
|
+
* bundle exposing the `@ampcode/plugin` API). Amp's integration is a HYBRID
|
|
7
|
+
* of two mechanisms:
|
|
8
|
+
*
|
|
9
|
+
* 1. Permission delegate helper (PRIMARY, blocking) — a standalone
|
|
10
|
+
* program named in `amp.permissions` as `{ tool, action: "delegate",
|
|
11
|
+
* to: "<program>" }`. Amp invokes it as a subprocess, passing the tool
|
|
12
|
+
* parameters as JSON on stdin. The program decides by exit code:
|
|
13
|
+
* 0 = allow, 1 = ask the user, ≥2 = reject (stderr → model reason).
|
|
14
|
+
* A 10-second delegate timeout applies (a timed-out delegate is
|
|
15
|
+
* treated as a reject). See `AmpDelegateInput` below.
|
|
16
|
+
*
|
|
17
|
+
* 2. In-process plugin (SECONDARY, tracing/auth) — a default-exported
|
|
18
|
+
* factory placed under `.amp/plugins/*.ts` that receives a `PluginAPI`
|
|
19
|
+
* (the `@ampcode/plugin` contract). Runs under Bun's TypeScript
|
|
20
|
+
* runtime. Used here ONLY for advisory session-start auth and
|
|
21
|
+
* post-tool tracing; the blocking decision lives in the delegate
|
|
22
|
+
* helper for cleaner subprocess parity.
|
|
23
|
+
*
|
|
24
|
+
* We model the `@ampcode/plugin` API surface locally (the plugin package
|
|
25
|
+
* takes no harness SDK dependency — see AGENTS.md). The shapes mirror the
|
|
26
|
+
* binary's `PluginEventMap` / `PluginEventContext` exactly.
|
|
27
|
+
*/
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.AMP_DELEGATE_EXIT = void 0;
|
|
30
|
+
/**
|
|
31
|
+
* Exit codes the delegate program returns to Amp.
|
|
32
|
+
* NOTE the inversion vs. other harnesses: deny is exit ≥2, not exit 0/1.
|
|
33
|
+
*/
|
|
34
|
+
exports.AMP_DELEGATE_EXIT = {
|
|
35
|
+
/** Allow the tool call. */
|
|
36
|
+
ALLOW: 0,
|
|
37
|
+
/**
|
|
38
|
+
* Ask the user. Reserved — not produced by this version. Ory observe
|
|
39
|
+
* mode passes through (exit 0) and enforce mode rejects (exit 2); there
|
|
40
|
+
* is no "ask Ory then ask the user" middle state yet.
|
|
41
|
+
*/
|
|
42
|
+
ASK: 1,
|
|
43
|
+
/** Reject the tool call; stderr is forwarded to the model as the reason. */
|
|
44
|
+
REJECT: 2,
|
|
45
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ory/amp",
|
|
3
|
+
"version": "0.10.0",
|
|
4
|
+
"description": "Ory plugin for Amp (Sourcegraph's coding agent): a permission delegate that authorizes every tool call plus an in-process plugin for session auth and audit tracing",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://ory.com",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"ory",
|
|
9
|
+
"amp",
|
|
10
|
+
"ampcode",
|
|
11
|
+
"sourcegraph",
|
|
12
|
+
"coding-agent",
|
|
13
|
+
"permissions",
|
|
14
|
+
"plugin",
|
|
15
|
+
"delegate",
|
|
16
|
+
"identity",
|
|
17
|
+
"identity-management",
|
|
18
|
+
"iam",
|
|
19
|
+
"authentication",
|
|
20
|
+
"authorization",
|
|
21
|
+
"access-control",
|
|
22
|
+
"rbac",
|
|
23
|
+
"zanzibar",
|
|
24
|
+
"oauth",
|
|
25
|
+
"oauth2",
|
|
26
|
+
"openid-connect",
|
|
27
|
+
"oidc",
|
|
28
|
+
"session",
|
|
29
|
+
"mfa",
|
|
30
|
+
"sso",
|
|
31
|
+
"audit",
|
|
32
|
+
"audit-log",
|
|
33
|
+
"compliance",
|
|
34
|
+
"agent",
|
|
35
|
+
"ai-agent",
|
|
36
|
+
"agent-security",
|
|
37
|
+
"guardrails",
|
|
38
|
+
"llm",
|
|
39
|
+
"tracing",
|
|
40
|
+
"distributed-tracing",
|
|
41
|
+
"observability",
|
|
42
|
+
"kratos",
|
|
43
|
+
"keto",
|
|
44
|
+
"hydra"
|
|
45
|
+
],
|
|
46
|
+
"publishConfig": {
|
|
47
|
+
"access": "public",
|
|
48
|
+
"registry": "https://registry.npmjs.org/",
|
|
49
|
+
"provenance": true
|
|
50
|
+
},
|
|
51
|
+
"main": "dist/index.js",
|
|
52
|
+
"types": "dist/index.d.ts",
|
|
53
|
+
"exports": {
|
|
54
|
+
".": {
|
|
55
|
+
"types": "./dist/index.d.ts",
|
|
56
|
+
"default": "./dist/index.js"
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"bin": {
|
|
60
|
+
"ory-amp": "dist/cli/main.js",
|
|
61
|
+
"ory-amp-permission": "dist/permission.js",
|
|
62
|
+
"ory-amp-setup": "dist/cli/setup.js"
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"dist",
|
|
66
|
+
"!dist/dev",
|
|
67
|
+
"!dist/**/*.tsbuildinfo"
|
|
68
|
+
],
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@ory/argus": "0.10.0"
|
|
71
|
+
},
|
|
72
|
+
"devDependencies": {
|
|
73
|
+
"typescript": "^6.0.2",
|
|
74
|
+
"vitest": "4.1.4"
|
|
75
|
+
},
|
|
76
|
+
"engines": {
|
|
77
|
+
"node": ">=22"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"build": "tsc",
|
|
81
|
+
"clean": "rm -rf dist *.tsbuildinfo",
|
|
82
|
+
"test": "vitest run",
|
|
83
|
+
"test:watch": "vitest",
|
|
84
|
+
"typecheck": "tsc --noEmit",
|
|
85
|
+
"dev": "node dist/dev/launcher.js"
|
|
86
|
+
}
|
|
87
|
+
}
|