@openape/openclaw-plugin-grants 0.2.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.
@@ -0,0 +1,342 @@
1
+ import { ScopeRiskLevel, GrantType, OpenApeCliAuthorizationDetail, OpenApeExecutionContext } from '@openape/core';
2
+ import * as jose from 'jose';
3
+
4
+ interface PluginConfig {
5
+ mode: 'local' | 'idp';
6
+ audience: string;
7
+ defaultApproval: GrantType;
8
+ adapterPaths?: string[];
9
+ agentEmail?: string;
10
+ agentKeyPath?: string;
11
+ idpUrl?: string;
12
+ apes?: {
13
+ enabled: boolean;
14
+ binaryPath?: string;
15
+ };
16
+ pollIntervalMs?: number;
17
+ pollTimeoutMs?: number;
18
+ }
19
+ interface ToolDefinition {
20
+ name: string;
21
+ description: string;
22
+ inputSchema: Record<string, unknown>;
23
+ handler: (input: ToolInput) => Promise<ToolResult>;
24
+ }
25
+ interface ToolInput {
26
+ command: string;
27
+ reason?: string;
28
+ privileged?: boolean;
29
+ }
30
+ interface ToolResult {
31
+ success: boolean;
32
+ output?: string;
33
+ error?: string;
34
+ }
35
+ interface HookHandler {
36
+ (context: HookContext): Promise<HookResult>;
37
+ }
38
+ interface HookContext {
39
+ toolName: string;
40
+ toolInput: Record<string, unknown>;
41
+ }
42
+ interface HookResult {
43
+ allow: boolean;
44
+ message?: string;
45
+ }
46
+ interface HttpRouteDefinition {
47
+ path: string;
48
+ method: 'GET' | 'POST';
49
+ handler: (req: HttpRequest) => Promise<HttpResponse>;
50
+ }
51
+ interface HttpRequest {
52
+ method: string;
53
+ path: string;
54
+ headers: Record<string, string>;
55
+ body?: unknown;
56
+ }
57
+ interface HttpResponse {
58
+ status: number;
59
+ headers?: Record<string, string>;
60
+ body: unknown;
61
+ }
62
+ interface CliCommandDefinition {
63
+ name: string;
64
+ description: string;
65
+ subcommands?: CliSubcommand[];
66
+ handler: (args: string[]) => Promise<void>;
67
+ }
68
+ interface CliSubcommand {
69
+ name: string;
70
+ description: string;
71
+ handler: (args: string[]) => Promise<void>;
72
+ }
73
+ interface ChannelMessage {
74
+ text: string;
75
+ actions?: ChannelAction[];
76
+ }
77
+ interface ChannelAction {
78
+ label: string;
79
+ value: string;
80
+ }
81
+ interface PluginApi {
82
+ registerTool(tool: ToolDefinition): void;
83
+ on(event: 'before_tool_call', handler: HookHandler, options?: {
84
+ priority?: number;
85
+ }): void;
86
+ registerHttpRoute(route: HttpRouteDefinition): void;
87
+ registerCli(command: CliCommandDefinition): void;
88
+ sendChannelMessage(message: ChannelMessage): Promise<string | undefined>;
89
+ onChannelCommand(command: string, handler: (args: string[], responderId?: string) => Promise<void>): void;
90
+ runtime: {
91
+ system: {
92
+ runCommandWithTimeout(command: string, args: string[], options?: {
93
+ timeout?: number;
94
+ cwd?: string;
95
+ env?: Record<string, string>;
96
+ }): Promise<{
97
+ stdout: string;
98
+ stderr: string;
99
+ exitCode: number;
100
+ }>;
101
+ };
102
+ config: {
103
+ getStateDir(): string;
104
+ getWorkspaceDir(): string;
105
+ };
106
+ };
107
+ log: {
108
+ info(message: string, ...args: unknown[]): void;
109
+ warn(message: string, ...args: unknown[]): void;
110
+ error(message: string, ...args: unknown[]): void;
111
+ debug(message: string, ...args: unknown[]): void;
112
+ };
113
+ }
114
+ type GrantApproval = 'once' | 'timed' | 'always';
115
+ interface GrantRecord {
116
+ id: string;
117
+ permission: string;
118
+ approval: GrantApproval;
119
+ status: 'pending' | 'approved' | 'denied' | 'used' | 'expired' | 'revoked';
120
+ command: string;
121
+ reason?: string;
122
+ risk: ScopeRiskLevel;
123
+ display: string;
124
+ jwt?: string;
125
+ createdAt: string;
126
+ decidedAt?: string;
127
+ expiresAt?: string;
128
+ usedAt?: string;
129
+ }
130
+ interface AuditEntry {
131
+ ts: string;
132
+ event: 'grant_requested' | 'grant_approved' | 'grant_denied' | 'grant_used' | 'grant_revoked' | 'grant_expired' | 'exec_success' | 'exec_failed' | 'exec_blocked';
133
+ grantId?: string;
134
+ permission?: string;
135
+ command?: string;
136
+ detail?: string;
137
+ }
138
+
139
+ interface AdapterDefinition {
140
+ schema: string;
141
+ cli: {
142
+ id: string;
143
+ executable: string;
144
+ audience?: string;
145
+ version?: string;
146
+ };
147
+ operations: AdapterOperation[];
148
+ }
149
+ interface AdapterOperation {
150
+ id: string;
151
+ command: string[];
152
+ positionals?: string[];
153
+ required_options?: string[];
154
+ display: string;
155
+ action: string;
156
+ risk: ScopeRiskLevel;
157
+ resource_chain: string[];
158
+ exact_command?: boolean;
159
+ }
160
+ interface LoadedAdapter {
161
+ adapter: AdapterDefinition;
162
+ source: string;
163
+ digest: string;
164
+ }
165
+ interface ResolvedCommand {
166
+ adapter: AdapterDefinition;
167
+ source: string;
168
+ digest: string;
169
+ executable: string;
170
+ commandArgv: string[];
171
+ bindings: Record<string, string>;
172
+ detail: OpenApeCliAuthorizationDetail;
173
+ executionContext: OpenApeExecutionContext;
174
+ permission: string;
175
+ }
176
+ interface CommandResolutionResult {
177
+ resolved: ResolvedCommand | null;
178
+ fallback: FallbackCommand | null;
179
+ }
180
+ interface FallbackCommand {
181
+ command: string;
182
+ argv: string[];
183
+ hash: string;
184
+ permission: string;
185
+ display: string;
186
+ risk: ScopeRiskLevel;
187
+ }
188
+
189
+ declare function parseAdapterToml(content: string): AdapterDefinition;
190
+
191
+ declare function resolveCommand(loaded: LoadedAdapter, fullArgv: string[]): Promise<ResolvedCommand>;
192
+ declare function createFallbackCommand(commandString: string): Promise<FallbackCommand>;
193
+ declare function parseCommandString(command: string): string[];
194
+ declare function resolveCommandFromAdapters(adapters: LoadedAdapter[], commandString: string): Promise<CommandResolutionResult>;
195
+
196
+ interface AdapterSearchPaths {
197
+ explicit?: string[];
198
+ workspaceDir?: string;
199
+ }
200
+ declare function loadAdapterFromFile(filePath: string): LoadedAdapter;
201
+ declare function loadAdapter(cliId: string, options?: AdapterSearchPaths): LoadedAdapter;
202
+ declare function discoverAdapters(options?: AdapterSearchPaths): LoadedAdapter[];
203
+
204
+ interface CreateGrantInput {
205
+ permission: string;
206
+ command: string;
207
+ reason?: string;
208
+ risk: ScopeRiskLevel;
209
+ display: string;
210
+ }
211
+ declare class GrantStore {
212
+ private grants;
213
+ private filePath;
214
+ constructor(stateDir?: string);
215
+ createGrant(input: CreateGrantInput): GrantRecord;
216
+ approveGrant(id: string, approval: GrantApproval, expiresAt?: string): GrantRecord | null;
217
+ denyGrant(id: string): GrantRecord | null;
218
+ consumeGrant(id: string): boolean;
219
+ revokeGrant(id: string): boolean;
220
+ getGrant(id: string): GrantRecord | undefined;
221
+ listGrants(filter?: {
222
+ status?: GrantRecord['status'];
223
+ }): GrantRecord[];
224
+ getActiveGrantCount(): number;
225
+ private load;
226
+ private save;
227
+ }
228
+
229
+ declare class GrantCache {
230
+ private entries;
231
+ put(grant: GrantRecord, detail: OpenApeCliAuthorizationDetail): void;
232
+ lookup(permission: string, detail: OpenApeCliAuthorizationDetail): GrantRecord | null;
233
+ remove(permission: string): boolean;
234
+ clear(): void;
235
+ size(): number;
236
+ private isExpired;
237
+ }
238
+
239
+ declare class AuditLog {
240
+ private filePath;
241
+ constructor(stateDir?: string);
242
+ write(entry: Omit<AuditEntry, 'ts'>): void;
243
+ }
244
+
245
+ declare class LocalJwtSigner {
246
+ private privateKey;
247
+ private publicKey;
248
+ private kid;
249
+ private stateDir;
250
+ constructor(stateDir: string);
251
+ init(): Promise<void>;
252
+ signGrant(options: {
253
+ grant: GrantRecord;
254
+ audience: string;
255
+ detail: OpenApeCliAuthorizationDetail;
256
+ executionContext: OpenApeExecutionContext;
257
+ }): Promise<string>;
258
+ getJwks(): Promise<jose.JSONWebKeySet>;
259
+ getIssuer(): string;
260
+ private getExpiration;
261
+ }
262
+
263
+ declare class ChannelApproval {
264
+ private api;
265
+ private store;
266
+ private timeoutMs;
267
+ private pending;
268
+ constructor(api: PluginApi, store: GrantStore, timeoutMs?: number);
269
+ requestApproval(grant: GrantRecord): Promise<{
270
+ approved: boolean;
271
+ approval?: 'once' | 'timed' | 'always';
272
+ }>;
273
+ private registerCommands;
274
+ }
275
+
276
+ interface ExecuteOptions {
277
+ command: string;
278
+ args: string[];
279
+ jwt?: string;
280
+ privileged?: boolean;
281
+ apesBinaryPath?: string;
282
+ timeout?: number;
283
+ }
284
+ declare function executeCommand(api: PluginApi, options: ExecuteOptions): Promise<ToolResult>;
285
+
286
+ declare function detectApes(binaryPath?: string): {
287
+ available: boolean;
288
+ path: string;
289
+ version?: string;
290
+ };
291
+ declare function buildApesArgs(jwt: string, command: string, args: string[]): string[];
292
+
293
+ interface AgentAuthState {
294
+ idpUrl: string;
295
+ token: string;
296
+ email: string;
297
+ expiresAt: number;
298
+ }
299
+ declare function authenticateAgent(options: {
300
+ idpUrl: string;
301
+ email: string;
302
+ keyPath: string;
303
+ }): Promise<AgentAuthState>;
304
+ declare function isTokenExpired(state: AgentAuthState): boolean;
305
+
306
+ interface GrantExecContext {
307
+ config: PluginConfig;
308
+ api: PluginApi;
309
+ adapters: LoadedAdapter[];
310
+ store: GrantStore;
311
+ cache: GrantCache;
312
+ audit: AuditLog;
313
+ localJwt: LocalJwtSigner | null;
314
+ channelApproval: ChannelApproval | null;
315
+ idpAuthState: AgentAuthState | null;
316
+ }
317
+ declare function handleGrantExec(ctx: GrantExecContext, input: ToolInput): Promise<ToolResult>;
318
+
319
+ declare function discoverIdpUrl(email: string, pinnedUrl?: string): Promise<string>;
320
+ declare function discoverEndpoints(idpUrl: string): Promise<Record<string, unknown>>;
321
+ declare function getGrantsEndpoint(idpUrl: string): Promise<string>;
322
+ declare function clearDiscoveryCache(): void;
323
+
324
+ interface IdpGrantContext {
325
+ config: PluginConfig;
326
+ api: PluginApi;
327
+ authState: AgentAuthState;
328
+ store: GrantStore;
329
+ cache: GrantCache;
330
+ audit: AuditLog;
331
+ }
332
+ declare function handleIdpGrantExec(ctx: IdpGrantContext, options: {
333
+ resolved: ResolvedCommand | null;
334
+ fallback: FallbackCommand | null;
335
+ command: string;
336
+ reason?: string;
337
+ privileged?: boolean;
338
+ }): Promise<ToolResult>;
339
+
340
+ declare function register(api: PluginApi, userConfig?: Partial<PluginConfig>): void;
341
+
342
+ export { type AdapterDefinition, type AdapterOperation, type AdapterSearchPaths, type AgentAuthState, AuditLog, ChannelApproval, type CommandResolutionResult, type FallbackCommand, GrantCache, GrantStore, type LoadedAdapter, LocalJwtSigner, type PluginApi, type PluginConfig, type ResolvedCommand, authenticateAgent, buildApesArgs, clearDiscoveryCache, createFallbackCommand, detectApes, discoverAdapters, discoverEndpoints, discoverIdpUrl, executeCommand, getGrantsEndpoint, handleGrantExec, handleIdpGrantExec, isTokenExpired, loadAdapter, loadAdapterFromFile, parseAdapterToml, parseCommandString, register, resolveCommand, resolveCommandFromAdapters };