@nkmc/agent-fs 0.1.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/dist/chunk-7LIZT7L3.js +966 -0
- package/dist/index.cjs +1278 -0
- package/dist/index.d.cts +96 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.js +419 -0
- package/dist/rpc-D1IHpjF_.d.cts +330 -0
- package/dist/rpc-D1IHpjF_.d.ts +330 -0
- package/dist/testing.cjs +842 -0
- package/dist/testing.d.cts +29 -0
- package/dist/testing.d.ts +29 -0
- package/dist/testing.js +10 -0
- package/package.json +25 -0
- package/src/agent-fs.ts +151 -0
- package/src/backends/http.ts +835 -0
- package/src/backends/memory.ts +183 -0
- package/src/backends/rpc.ts +456 -0
- package/src/index.ts +36 -0
- package/src/mount.ts +84 -0
- package/src/parser.ts +162 -0
- package/src/server.ts +158 -0
- package/src/testing.ts +3 -0
- package/src/types.ts +52 -0
- package/test/agent-fs.test.ts +325 -0
- package/test/http-204.test.ts +102 -0
- package/test/http-auth-prefix.test.ts +79 -0
- package/test/http-cloudflare.test.ts +533 -0
- package/test/http-form-encoding.test.ts +119 -0
- package/test/http-github.test.ts +580 -0
- package/test/http-listkey.test.ts +128 -0
- package/test/http-oauth2.test.ts +174 -0
- package/test/http-pagination.test.ts +200 -0
- package/test/http-param-styles.test.ts +98 -0
- package/test/http-passthrough.test.ts +282 -0
- package/test/http-retry.test.ts +132 -0
- package/test/http.test.ts +360 -0
- package/test/memory.test.ts +120 -0
- package/test/mount.test.ts +94 -0
- package/test/parser.test.ts +100 -0
- package/test/rpc-crud.test.ts +627 -0
- package/test/rpc-evm.test.ts +390 -0
- package/tsconfig.json +8 -0
- package/tsup.config.ts +8 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/** The 5 filesystem operations */
|
|
2
|
+
type FsOp = "ls" | "cat" | "write" | "rm" | "grep";
|
|
3
|
+
/** A parsed command from the LLM */
|
|
4
|
+
interface FsCommand {
|
|
5
|
+
op: FsOp;
|
|
6
|
+
path: string;
|
|
7
|
+
data?: unknown;
|
|
8
|
+
pattern?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Result of a filesystem operation */
|
|
11
|
+
type FsResult = {
|
|
12
|
+
ok: true;
|
|
13
|
+
data: unknown;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
error: FsError;
|
|
17
|
+
};
|
|
18
|
+
/** Error types */
|
|
19
|
+
type FsError = {
|
|
20
|
+
code: "PARSE_ERROR";
|
|
21
|
+
message: string;
|
|
22
|
+
} | {
|
|
23
|
+
code: "INVALID_PATH";
|
|
24
|
+
message: string;
|
|
25
|
+
} | {
|
|
26
|
+
code: "NOT_FOUND";
|
|
27
|
+
message: string;
|
|
28
|
+
} | {
|
|
29
|
+
code: "PERMISSION_DENIED";
|
|
30
|
+
message: string;
|
|
31
|
+
} | {
|
|
32
|
+
code: "NO_MOUNT";
|
|
33
|
+
message: string;
|
|
34
|
+
} | {
|
|
35
|
+
code: "BACKEND_ERROR";
|
|
36
|
+
message: string;
|
|
37
|
+
};
|
|
38
|
+
/** Agent identity context passed through the call chain */
|
|
39
|
+
interface AgentContext {
|
|
40
|
+
id: string;
|
|
41
|
+
roles: string[];
|
|
42
|
+
}
|
|
43
|
+
/** Access role for permissions */
|
|
44
|
+
type AccessRole = "public" | "agent" | "premium" | "admin" | string;
|
|
45
|
+
/** Mount point configuration — maps a virtual path to a backend */
|
|
46
|
+
interface Mount {
|
|
47
|
+
path: string;
|
|
48
|
+
backend: FsBackend;
|
|
49
|
+
permissions?: {
|
|
50
|
+
read?: AccessRole[];
|
|
51
|
+
write?: AccessRole[];
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** The interface every backend must implement */
|
|
55
|
+
interface FsBackend {
|
|
56
|
+
list(path: string): Promise<string[]>;
|
|
57
|
+
read(path: string): Promise<unknown>;
|
|
58
|
+
write(path: string, data: unknown): Promise<{
|
|
59
|
+
id: string;
|
|
60
|
+
}>;
|
|
61
|
+
remove(path: string): Promise<void>;
|
|
62
|
+
search(path: string, pattern: string): Promise<unknown[]>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Auth configuration for HTTP requests */
|
|
66
|
+
type HttpAuth = {
|
|
67
|
+
type: "bearer";
|
|
68
|
+
token: string;
|
|
69
|
+
prefix?: string;
|
|
70
|
+
} | {
|
|
71
|
+
type: "api-key";
|
|
72
|
+
header: string;
|
|
73
|
+
key: string;
|
|
74
|
+
} | {
|
|
75
|
+
type: "basic";
|
|
76
|
+
username: string;
|
|
77
|
+
password: string;
|
|
78
|
+
} | {
|
|
79
|
+
type: "oauth2";
|
|
80
|
+
tokenUrl: string;
|
|
81
|
+
clientId: string;
|
|
82
|
+
clientSecret: string;
|
|
83
|
+
scope?: string;
|
|
84
|
+
};
|
|
85
|
+
/** A resource (collection-like, from skill.md Schema section) */
|
|
86
|
+
interface HttpResource {
|
|
87
|
+
/** Name used in filesystem path: /mount/{name}/ */
|
|
88
|
+
name: string;
|
|
89
|
+
/** API base path for this resource. Defaults to /{name} */
|
|
90
|
+
apiPath?: string;
|
|
91
|
+
/** Field name for record ID in API responses. Defaults to "id" */
|
|
92
|
+
idField?: string;
|
|
93
|
+
/** Key to extract array from list response. e.g. "result" for Cloudflare, "data" for others */
|
|
94
|
+
listKey?: string;
|
|
95
|
+
/** Schema fields (for _schema support) */
|
|
96
|
+
fields?: {
|
|
97
|
+
name: string;
|
|
98
|
+
type: string;
|
|
99
|
+
description?: string;
|
|
100
|
+
}[];
|
|
101
|
+
/** Child resources (for nested paths like /zones/{id}/dns_records) */
|
|
102
|
+
children?: HttpResource[];
|
|
103
|
+
/** "tree" mode: all remaining path segments form the ID (for file-tree APIs) */
|
|
104
|
+
pathMode?: "tree";
|
|
105
|
+
/** Override HTTP method for updates. Default "PUT" */
|
|
106
|
+
updateMethod?: "PUT" | "PATCH";
|
|
107
|
+
/** Data transformation hooks */
|
|
108
|
+
transform?: {
|
|
109
|
+
/** Transform item after GET response */
|
|
110
|
+
read?: (data: unknown) => unknown;
|
|
111
|
+
/** Transform data before POST/PUT body */
|
|
112
|
+
write?: (data: unknown) => unknown;
|
|
113
|
+
/** Build DELETE body from read result */
|
|
114
|
+
remove?: (readResult: unknown | null) => unknown;
|
|
115
|
+
/** Format each list item to display string. Default: item[idField] + ".json" */
|
|
116
|
+
list?: (item: unknown) => string;
|
|
117
|
+
};
|
|
118
|
+
/** Auto-read before write/delete to obtain fields like SHA, ETag */
|
|
119
|
+
readBeforeWrite?: {
|
|
120
|
+
inject: (readResult: unknown, writeData: unknown) => unknown;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/** An API endpoint (invocation-like, from skill.md API section) */
|
|
124
|
+
interface HttpEndpoint {
|
|
125
|
+
/** Name used in filesystem path: /mount/_api/{name} */
|
|
126
|
+
name: string;
|
|
127
|
+
/** HTTP method */
|
|
128
|
+
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
129
|
+
/** API path */
|
|
130
|
+
apiPath: string;
|
|
131
|
+
/** Description */
|
|
132
|
+
description?: string;
|
|
133
|
+
}
|
|
134
|
+
/** Configuration for HttpBackend */
|
|
135
|
+
interface HttpBackendConfig {
|
|
136
|
+
/** Base URL of the API (e.g. "https://api.cloudflare.com/client/v4") */
|
|
137
|
+
baseUrl: string;
|
|
138
|
+
/** Authentication */
|
|
139
|
+
auth?: HttpAuth;
|
|
140
|
+
/** Resource definitions (from skill.md Schema section) */
|
|
141
|
+
resources?: HttpResource[];
|
|
142
|
+
/** API endpoint definitions (from skill.md API section) */
|
|
143
|
+
endpoints?: HttpEndpoint[];
|
|
144
|
+
/** Static parameters for template resolution (e.g. { accountId: "abc123" }) */
|
|
145
|
+
params?: Record<string, string>;
|
|
146
|
+
/** Body encoding: "json" (default) or "form" (application/x-www-form-urlencoded) */
|
|
147
|
+
bodyEncoding?: "json" | "form";
|
|
148
|
+
/** Custom fetch function (for testing) */
|
|
149
|
+
fetch?: typeof globalThis.fetch;
|
|
150
|
+
/** Auto-pagination for list operations */
|
|
151
|
+
pagination?: PaginationConfig;
|
|
152
|
+
/** Retry configuration for transient errors (429, 5xx) */
|
|
153
|
+
retry?: {
|
|
154
|
+
/** Max retry attempts (default 3) */
|
|
155
|
+
maxRetries?: number;
|
|
156
|
+
/** Base delay in ms for exponential backoff (default 1000) */
|
|
157
|
+
baseDelayMs?: number;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/** Pagination configuration — supports multiple strategies */
|
|
161
|
+
type PaginationConfig = {
|
|
162
|
+
type: "link-header";
|
|
163
|
+
maxPages?: number;
|
|
164
|
+
} | {
|
|
165
|
+
type: "cursor";
|
|
166
|
+
cursorParam: string;
|
|
167
|
+
cursorPath: string;
|
|
168
|
+
maxPages?: number;
|
|
169
|
+
} | {
|
|
170
|
+
type: "offset";
|
|
171
|
+
offsetParam?: string;
|
|
172
|
+
limitParam?: string;
|
|
173
|
+
pageSize?: number;
|
|
174
|
+
maxPages?: number;
|
|
175
|
+
} | {
|
|
176
|
+
type: "page";
|
|
177
|
+
pageParam?: string;
|
|
178
|
+
maxPages?: number;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* HTTP-based FsBackend driven by skill.md descriptions.
|
|
182
|
+
*
|
|
183
|
+
* Filesystem mapping (flat):
|
|
184
|
+
* ls / → list resources + endpoints
|
|
185
|
+
* ls /{resource}/ → GET baseUrl/{apiPath} (list records)
|
|
186
|
+
* cat /{resource}/{id}.json → GET baseUrl/{apiPath}/{id} (read record)
|
|
187
|
+
* write /{resource}/ data → POST baseUrl/{apiPath} (create)
|
|
188
|
+
* write /{resource}/{id} data → PUT baseUrl/{apiPath}/{id} (update)
|
|
189
|
+
* rm /{resource}/{id}.json → DELETE baseUrl/{apiPath}/{id}
|
|
190
|
+
* grep pattern /{resource}/ → GET baseUrl/{apiPath}?q={pattern} (search)
|
|
191
|
+
*
|
|
192
|
+
* Nested resources:
|
|
193
|
+
* ls /{parent}/{pid}/ → list child resource directories
|
|
194
|
+
* ls /{parent}/{pid}/{child}/ → GET resolved nested path (list)
|
|
195
|
+
* cat /{parent}/{pid}/{child}/{id}.json → GET resolved nested path/{id}
|
|
196
|
+
*
|
|
197
|
+
* Endpoints:
|
|
198
|
+
* ls /_api/ → list available endpoints
|
|
199
|
+
* cat /_api/{name} → GET endpoint (for GET endpoints)
|
|
200
|
+
* write /_api/{name} data → POST/PUT/etc endpoint (for non-GET endpoints)
|
|
201
|
+
*/
|
|
202
|
+
declare class HttpBackend implements FsBackend {
|
|
203
|
+
private baseUrl;
|
|
204
|
+
private auth?;
|
|
205
|
+
private resourceList;
|
|
206
|
+
private endpoints;
|
|
207
|
+
private params;
|
|
208
|
+
private _fetch;
|
|
209
|
+
private bodyEncoding;
|
|
210
|
+
private pagination?;
|
|
211
|
+
private retryConfig;
|
|
212
|
+
/** Cached OAuth2 access token */
|
|
213
|
+
private _oauth2Token?;
|
|
214
|
+
constructor(config: HttpBackendConfig);
|
|
215
|
+
list(path: string): Promise<string[]>;
|
|
216
|
+
read(path: string): Promise<unknown>;
|
|
217
|
+
write(path: string, data: unknown): Promise<{
|
|
218
|
+
id: string;
|
|
219
|
+
}>;
|
|
220
|
+
remove(path: string): Promise<void>;
|
|
221
|
+
search(path: string, pattern: string): Promise<unknown[]>;
|
|
222
|
+
private request;
|
|
223
|
+
/** Obtain (or refresh) OAuth2 access token via client_credentials grant */
|
|
224
|
+
private getOAuth2Token;
|
|
225
|
+
/** Parse Link header to extract rel="next" URL */
|
|
226
|
+
private getNextPageUrl;
|
|
227
|
+
/** Fetch all items with optional pagination */
|
|
228
|
+
private fetchAllItems;
|
|
229
|
+
/** Format list items using transform.list or default idField + ".json" */
|
|
230
|
+
private formatListItems;
|
|
231
|
+
private getEndpoint;
|
|
232
|
+
/** Replace :param and {param} placeholders in API paths with values from config.params */
|
|
233
|
+
private resolveTemplate;
|
|
234
|
+
/** Recursively resolve a filesystem path against the resource tree */
|
|
235
|
+
private resolveResourcePath;
|
|
236
|
+
private parsePath;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Transport interface for RPC calls */
|
|
240
|
+
interface RpcTransport {
|
|
241
|
+
call(method: string, params: unknown[]): Promise<unknown>;
|
|
242
|
+
batch?(calls: Array<{
|
|
243
|
+
method: string;
|
|
244
|
+
params: unknown[];
|
|
245
|
+
}>): Promise<unknown[]>;
|
|
246
|
+
}
|
|
247
|
+
/** Configuration for JSON-RPC 2.0 transport */
|
|
248
|
+
interface JsonRpcTransportConfig {
|
|
249
|
+
url: string;
|
|
250
|
+
headers?: Record<string, string>;
|
|
251
|
+
fetch?: typeof globalThis.fetch;
|
|
252
|
+
/** Retry configuration for transient errors (429, 5xx, -32603, -32000~-32099) */
|
|
253
|
+
retry?: {
|
|
254
|
+
/** Max retry attempts (default 3) */
|
|
255
|
+
maxRetries?: number;
|
|
256
|
+
/** Base delay in ms for exponential backoff (default 1000) */
|
|
257
|
+
baseDelayMs?: number;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/** JSON-RPC error with code and optional data */
|
|
261
|
+
declare class RpcError extends Error {
|
|
262
|
+
code: number;
|
|
263
|
+
data?: unknown;
|
|
264
|
+
constructor(code: number, message: string, data?: unknown);
|
|
265
|
+
}
|
|
266
|
+
/** Context passed to RpcMethod.params callback */
|
|
267
|
+
interface RpcCallContext {
|
|
268
|
+
id?: string;
|
|
269
|
+
data?: unknown;
|
|
270
|
+
pattern?: string;
|
|
271
|
+
}
|
|
272
|
+
/** Maps a filesystem operation to an RPC call */
|
|
273
|
+
interface RpcMethod {
|
|
274
|
+
method: string;
|
|
275
|
+
params: (ctx: RpcCallContext) => unknown[];
|
|
276
|
+
}
|
|
277
|
+
/** A resource exposed as a directory in the filesystem */
|
|
278
|
+
interface RpcResource {
|
|
279
|
+
name: string;
|
|
280
|
+
idField?: string;
|
|
281
|
+
methods: {
|
|
282
|
+
list?: RpcMethod;
|
|
283
|
+
read?: RpcMethod;
|
|
284
|
+
write?: RpcMethod;
|
|
285
|
+
create?: RpcMethod;
|
|
286
|
+
remove?: RpcMethod;
|
|
287
|
+
search?: RpcMethod;
|
|
288
|
+
};
|
|
289
|
+
transform?: {
|
|
290
|
+
read?: (data: unknown) => unknown;
|
|
291
|
+
write?: (data: unknown) => unknown;
|
|
292
|
+
remove?: (id: string) => unknown;
|
|
293
|
+
list?: (item: unknown) => string | string[];
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/** Configuration for RpcBackend */
|
|
297
|
+
interface RpcBackendConfig {
|
|
298
|
+
transport: RpcTransport;
|
|
299
|
+
resources: RpcResource[];
|
|
300
|
+
}
|
|
301
|
+
declare class JsonRpcTransport implements RpcTransport {
|
|
302
|
+
private url;
|
|
303
|
+
private headers;
|
|
304
|
+
private _fetch;
|
|
305
|
+
private nextId;
|
|
306
|
+
private retryConfig;
|
|
307
|
+
constructor(config: JsonRpcTransportConfig);
|
|
308
|
+
call(method: string, params: unknown[]): Promise<unknown>;
|
|
309
|
+
batch(calls: Array<{
|
|
310
|
+
method: string;
|
|
311
|
+
params: unknown[];
|
|
312
|
+
}>): Promise<unknown[]>;
|
|
313
|
+
/** Exponential backoff with jitter + Retry-After header support */
|
|
314
|
+
private backoff;
|
|
315
|
+
}
|
|
316
|
+
declare class RpcBackend implements FsBackend {
|
|
317
|
+
private transport;
|
|
318
|
+
private resources;
|
|
319
|
+
constructor(config: RpcBackendConfig);
|
|
320
|
+
list(path: string): Promise<string[]>;
|
|
321
|
+
read(path: string): Promise<unknown>;
|
|
322
|
+
write(path: string, data: unknown): Promise<{
|
|
323
|
+
id: string;
|
|
324
|
+
}>;
|
|
325
|
+
remove(path: string): Promise<void>;
|
|
326
|
+
search(path: string, pattern: string): Promise<unknown[]>;
|
|
327
|
+
private parsePath;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export { type AgentContext as A, type FsResult as F, type HttpAuth as H, JsonRpcTransport as J, type Mount as M, type PaginationConfig as P, RpcBackend as R, type FsError as a, type FsBackend as b, type FsCommand as c, type AccessRole as d, type FsOp as e, HttpBackend as f, type HttpBackendConfig as g, type HttpEndpoint as h, type HttpResource as i, type JsonRpcTransportConfig as j, type RpcBackendConfig as k, type RpcCallContext as l, RpcError as m, type RpcMethod as n, type RpcResource as o, type RpcTransport as p };
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
/** The 5 filesystem operations */
|
|
2
|
+
type FsOp = "ls" | "cat" | "write" | "rm" | "grep";
|
|
3
|
+
/** A parsed command from the LLM */
|
|
4
|
+
interface FsCommand {
|
|
5
|
+
op: FsOp;
|
|
6
|
+
path: string;
|
|
7
|
+
data?: unknown;
|
|
8
|
+
pattern?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Result of a filesystem operation */
|
|
11
|
+
type FsResult = {
|
|
12
|
+
ok: true;
|
|
13
|
+
data: unknown;
|
|
14
|
+
} | {
|
|
15
|
+
ok: false;
|
|
16
|
+
error: FsError;
|
|
17
|
+
};
|
|
18
|
+
/** Error types */
|
|
19
|
+
type FsError = {
|
|
20
|
+
code: "PARSE_ERROR";
|
|
21
|
+
message: string;
|
|
22
|
+
} | {
|
|
23
|
+
code: "INVALID_PATH";
|
|
24
|
+
message: string;
|
|
25
|
+
} | {
|
|
26
|
+
code: "NOT_FOUND";
|
|
27
|
+
message: string;
|
|
28
|
+
} | {
|
|
29
|
+
code: "PERMISSION_DENIED";
|
|
30
|
+
message: string;
|
|
31
|
+
} | {
|
|
32
|
+
code: "NO_MOUNT";
|
|
33
|
+
message: string;
|
|
34
|
+
} | {
|
|
35
|
+
code: "BACKEND_ERROR";
|
|
36
|
+
message: string;
|
|
37
|
+
};
|
|
38
|
+
/** Agent identity context passed through the call chain */
|
|
39
|
+
interface AgentContext {
|
|
40
|
+
id: string;
|
|
41
|
+
roles: string[];
|
|
42
|
+
}
|
|
43
|
+
/** Access role for permissions */
|
|
44
|
+
type AccessRole = "public" | "agent" | "premium" | "admin" | string;
|
|
45
|
+
/** Mount point configuration — maps a virtual path to a backend */
|
|
46
|
+
interface Mount {
|
|
47
|
+
path: string;
|
|
48
|
+
backend: FsBackend;
|
|
49
|
+
permissions?: {
|
|
50
|
+
read?: AccessRole[];
|
|
51
|
+
write?: AccessRole[];
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/** The interface every backend must implement */
|
|
55
|
+
interface FsBackend {
|
|
56
|
+
list(path: string): Promise<string[]>;
|
|
57
|
+
read(path: string): Promise<unknown>;
|
|
58
|
+
write(path: string, data: unknown): Promise<{
|
|
59
|
+
id: string;
|
|
60
|
+
}>;
|
|
61
|
+
remove(path: string): Promise<void>;
|
|
62
|
+
search(path: string, pattern: string): Promise<unknown[]>;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** Auth configuration for HTTP requests */
|
|
66
|
+
type HttpAuth = {
|
|
67
|
+
type: "bearer";
|
|
68
|
+
token: string;
|
|
69
|
+
prefix?: string;
|
|
70
|
+
} | {
|
|
71
|
+
type: "api-key";
|
|
72
|
+
header: string;
|
|
73
|
+
key: string;
|
|
74
|
+
} | {
|
|
75
|
+
type: "basic";
|
|
76
|
+
username: string;
|
|
77
|
+
password: string;
|
|
78
|
+
} | {
|
|
79
|
+
type: "oauth2";
|
|
80
|
+
tokenUrl: string;
|
|
81
|
+
clientId: string;
|
|
82
|
+
clientSecret: string;
|
|
83
|
+
scope?: string;
|
|
84
|
+
};
|
|
85
|
+
/** A resource (collection-like, from skill.md Schema section) */
|
|
86
|
+
interface HttpResource {
|
|
87
|
+
/** Name used in filesystem path: /mount/{name}/ */
|
|
88
|
+
name: string;
|
|
89
|
+
/** API base path for this resource. Defaults to /{name} */
|
|
90
|
+
apiPath?: string;
|
|
91
|
+
/** Field name for record ID in API responses. Defaults to "id" */
|
|
92
|
+
idField?: string;
|
|
93
|
+
/** Key to extract array from list response. e.g. "result" for Cloudflare, "data" for others */
|
|
94
|
+
listKey?: string;
|
|
95
|
+
/** Schema fields (for _schema support) */
|
|
96
|
+
fields?: {
|
|
97
|
+
name: string;
|
|
98
|
+
type: string;
|
|
99
|
+
description?: string;
|
|
100
|
+
}[];
|
|
101
|
+
/** Child resources (for nested paths like /zones/{id}/dns_records) */
|
|
102
|
+
children?: HttpResource[];
|
|
103
|
+
/** "tree" mode: all remaining path segments form the ID (for file-tree APIs) */
|
|
104
|
+
pathMode?: "tree";
|
|
105
|
+
/** Override HTTP method for updates. Default "PUT" */
|
|
106
|
+
updateMethod?: "PUT" | "PATCH";
|
|
107
|
+
/** Data transformation hooks */
|
|
108
|
+
transform?: {
|
|
109
|
+
/** Transform item after GET response */
|
|
110
|
+
read?: (data: unknown) => unknown;
|
|
111
|
+
/** Transform data before POST/PUT body */
|
|
112
|
+
write?: (data: unknown) => unknown;
|
|
113
|
+
/** Build DELETE body from read result */
|
|
114
|
+
remove?: (readResult: unknown | null) => unknown;
|
|
115
|
+
/** Format each list item to display string. Default: item[idField] + ".json" */
|
|
116
|
+
list?: (item: unknown) => string;
|
|
117
|
+
};
|
|
118
|
+
/** Auto-read before write/delete to obtain fields like SHA, ETag */
|
|
119
|
+
readBeforeWrite?: {
|
|
120
|
+
inject: (readResult: unknown, writeData: unknown) => unknown;
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/** An API endpoint (invocation-like, from skill.md API section) */
|
|
124
|
+
interface HttpEndpoint {
|
|
125
|
+
/** Name used in filesystem path: /mount/_api/{name} */
|
|
126
|
+
name: string;
|
|
127
|
+
/** HTTP method */
|
|
128
|
+
method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
|
|
129
|
+
/** API path */
|
|
130
|
+
apiPath: string;
|
|
131
|
+
/** Description */
|
|
132
|
+
description?: string;
|
|
133
|
+
}
|
|
134
|
+
/** Configuration for HttpBackend */
|
|
135
|
+
interface HttpBackendConfig {
|
|
136
|
+
/** Base URL of the API (e.g. "https://api.cloudflare.com/client/v4") */
|
|
137
|
+
baseUrl: string;
|
|
138
|
+
/** Authentication */
|
|
139
|
+
auth?: HttpAuth;
|
|
140
|
+
/** Resource definitions (from skill.md Schema section) */
|
|
141
|
+
resources?: HttpResource[];
|
|
142
|
+
/** API endpoint definitions (from skill.md API section) */
|
|
143
|
+
endpoints?: HttpEndpoint[];
|
|
144
|
+
/** Static parameters for template resolution (e.g. { accountId: "abc123" }) */
|
|
145
|
+
params?: Record<string, string>;
|
|
146
|
+
/** Body encoding: "json" (default) or "form" (application/x-www-form-urlencoded) */
|
|
147
|
+
bodyEncoding?: "json" | "form";
|
|
148
|
+
/** Custom fetch function (for testing) */
|
|
149
|
+
fetch?: typeof globalThis.fetch;
|
|
150
|
+
/** Auto-pagination for list operations */
|
|
151
|
+
pagination?: PaginationConfig;
|
|
152
|
+
/** Retry configuration for transient errors (429, 5xx) */
|
|
153
|
+
retry?: {
|
|
154
|
+
/** Max retry attempts (default 3) */
|
|
155
|
+
maxRetries?: number;
|
|
156
|
+
/** Base delay in ms for exponential backoff (default 1000) */
|
|
157
|
+
baseDelayMs?: number;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/** Pagination configuration — supports multiple strategies */
|
|
161
|
+
type PaginationConfig = {
|
|
162
|
+
type: "link-header";
|
|
163
|
+
maxPages?: number;
|
|
164
|
+
} | {
|
|
165
|
+
type: "cursor";
|
|
166
|
+
cursorParam: string;
|
|
167
|
+
cursorPath: string;
|
|
168
|
+
maxPages?: number;
|
|
169
|
+
} | {
|
|
170
|
+
type: "offset";
|
|
171
|
+
offsetParam?: string;
|
|
172
|
+
limitParam?: string;
|
|
173
|
+
pageSize?: number;
|
|
174
|
+
maxPages?: number;
|
|
175
|
+
} | {
|
|
176
|
+
type: "page";
|
|
177
|
+
pageParam?: string;
|
|
178
|
+
maxPages?: number;
|
|
179
|
+
};
|
|
180
|
+
/**
|
|
181
|
+
* HTTP-based FsBackend driven by skill.md descriptions.
|
|
182
|
+
*
|
|
183
|
+
* Filesystem mapping (flat):
|
|
184
|
+
* ls / → list resources + endpoints
|
|
185
|
+
* ls /{resource}/ → GET baseUrl/{apiPath} (list records)
|
|
186
|
+
* cat /{resource}/{id}.json → GET baseUrl/{apiPath}/{id} (read record)
|
|
187
|
+
* write /{resource}/ data → POST baseUrl/{apiPath} (create)
|
|
188
|
+
* write /{resource}/{id} data → PUT baseUrl/{apiPath}/{id} (update)
|
|
189
|
+
* rm /{resource}/{id}.json → DELETE baseUrl/{apiPath}/{id}
|
|
190
|
+
* grep pattern /{resource}/ → GET baseUrl/{apiPath}?q={pattern} (search)
|
|
191
|
+
*
|
|
192
|
+
* Nested resources:
|
|
193
|
+
* ls /{parent}/{pid}/ → list child resource directories
|
|
194
|
+
* ls /{parent}/{pid}/{child}/ → GET resolved nested path (list)
|
|
195
|
+
* cat /{parent}/{pid}/{child}/{id}.json → GET resolved nested path/{id}
|
|
196
|
+
*
|
|
197
|
+
* Endpoints:
|
|
198
|
+
* ls /_api/ → list available endpoints
|
|
199
|
+
* cat /_api/{name} → GET endpoint (for GET endpoints)
|
|
200
|
+
* write /_api/{name} data → POST/PUT/etc endpoint (for non-GET endpoints)
|
|
201
|
+
*/
|
|
202
|
+
declare class HttpBackend implements FsBackend {
|
|
203
|
+
private baseUrl;
|
|
204
|
+
private auth?;
|
|
205
|
+
private resourceList;
|
|
206
|
+
private endpoints;
|
|
207
|
+
private params;
|
|
208
|
+
private _fetch;
|
|
209
|
+
private bodyEncoding;
|
|
210
|
+
private pagination?;
|
|
211
|
+
private retryConfig;
|
|
212
|
+
/** Cached OAuth2 access token */
|
|
213
|
+
private _oauth2Token?;
|
|
214
|
+
constructor(config: HttpBackendConfig);
|
|
215
|
+
list(path: string): Promise<string[]>;
|
|
216
|
+
read(path: string): Promise<unknown>;
|
|
217
|
+
write(path: string, data: unknown): Promise<{
|
|
218
|
+
id: string;
|
|
219
|
+
}>;
|
|
220
|
+
remove(path: string): Promise<void>;
|
|
221
|
+
search(path: string, pattern: string): Promise<unknown[]>;
|
|
222
|
+
private request;
|
|
223
|
+
/** Obtain (or refresh) OAuth2 access token via client_credentials grant */
|
|
224
|
+
private getOAuth2Token;
|
|
225
|
+
/** Parse Link header to extract rel="next" URL */
|
|
226
|
+
private getNextPageUrl;
|
|
227
|
+
/** Fetch all items with optional pagination */
|
|
228
|
+
private fetchAllItems;
|
|
229
|
+
/** Format list items using transform.list or default idField + ".json" */
|
|
230
|
+
private formatListItems;
|
|
231
|
+
private getEndpoint;
|
|
232
|
+
/** Replace :param and {param} placeholders in API paths with values from config.params */
|
|
233
|
+
private resolveTemplate;
|
|
234
|
+
/** Recursively resolve a filesystem path against the resource tree */
|
|
235
|
+
private resolveResourcePath;
|
|
236
|
+
private parsePath;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
/** Transport interface for RPC calls */
|
|
240
|
+
interface RpcTransport {
|
|
241
|
+
call(method: string, params: unknown[]): Promise<unknown>;
|
|
242
|
+
batch?(calls: Array<{
|
|
243
|
+
method: string;
|
|
244
|
+
params: unknown[];
|
|
245
|
+
}>): Promise<unknown[]>;
|
|
246
|
+
}
|
|
247
|
+
/** Configuration for JSON-RPC 2.0 transport */
|
|
248
|
+
interface JsonRpcTransportConfig {
|
|
249
|
+
url: string;
|
|
250
|
+
headers?: Record<string, string>;
|
|
251
|
+
fetch?: typeof globalThis.fetch;
|
|
252
|
+
/** Retry configuration for transient errors (429, 5xx, -32603, -32000~-32099) */
|
|
253
|
+
retry?: {
|
|
254
|
+
/** Max retry attempts (default 3) */
|
|
255
|
+
maxRetries?: number;
|
|
256
|
+
/** Base delay in ms for exponential backoff (default 1000) */
|
|
257
|
+
baseDelayMs?: number;
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
/** JSON-RPC error with code and optional data */
|
|
261
|
+
declare class RpcError extends Error {
|
|
262
|
+
code: number;
|
|
263
|
+
data?: unknown;
|
|
264
|
+
constructor(code: number, message: string, data?: unknown);
|
|
265
|
+
}
|
|
266
|
+
/** Context passed to RpcMethod.params callback */
|
|
267
|
+
interface RpcCallContext {
|
|
268
|
+
id?: string;
|
|
269
|
+
data?: unknown;
|
|
270
|
+
pattern?: string;
|
|
271
|
+
}
|
|
272
|
+
/** Maps a filesystem operation to an RPC call */
|
|
273
|
+
interface RpcMethod {
|
|
274
|
+
method: string;
|
|
275
|
+
params: (ctx: RpcCallContext) => unknown[];
|
|
276
|
+
}
|
|
277
|
+
/** A resource exposed as a directory in the filesystem */
|
|
278
|
+
interface RpcResource {
|
|
279
|
+
name: string;
|
|
280
|
+
idField?: string;
|
|
281
|
+
methods: {
|
|
282
|
+
list?: RpcMethod;
|
|
283
|
+
read?: RpcMethod;
|
|
284
|
+
write?: RpcMethod;
|
|
285
|
+
create?: RpcMethod;
|
|
286
|
+
remove?: RpcMethod;
|
|
287
|
+
search?: RpcMethod;
|
|
288
|
+
};
|
|
289
|
+
transform?: {
|
|
290
|
+
read?: (data: unknown) => unknown;
|
|
291
|
+
write?: (data: unknown) => unknown;
|
|
292
|
+
remove?: (id: string) => unknown;
|
|
293
|
+
list?: (item: unknown) => string | string[];
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
/** Configuration for RpcBackend */
|
|
297
|
+
interface RpcBackendConfig {
|
|
298
|
+
transport: RpcTransport;
|
|
299
|
+
resources: RpcResource[];
|
|
300
|
+
}
|
|
301
|
+
declare class JsonRpcTransport implements RpcTransport {
|
|
302
|
+
private url;
|
|
303
|
+
private headers;
|
|
304
|
+
private _fetch;
|
|
305
|
+
private nextId;
|
|
306
|
+
private retryConfig;
|
|
307
|
+
constructor(config: JsonRpcTransportConfig);
|
|
308
|
+
call(method: string, params: unknown[]): Promise<unknown>;
|
|
309
|
+
batch(calls: Array<{
|
|
310
|
+
method: string;
|
|
311
|
+
params: unknown[];
|
|
312
|
+
}>): Promise<unknown[]>;
|
|
313
|
+
/** Exponential backoff with jitter + Retry-After header support */
|
|
314
|
+
private backoff;
|
|
315
|
+
}
|
|
316
|
+
declare class RpcBackend implements FsBackend {
|
|
317
|
+
private transport;
|
|
318
|
+
private resources;
|
|
319
|
+
constructor(config: RpcBackendConfig);
|
|
320
|
+
list(path: string): Promise<string[]>;
|
|
321
|
+
read(path: string): Promise<unknown>;
|
|
322
|
+
write(path: string, data: unknown): Promise<{
|
|
323
|
+
id: string;
|
|
324
|
+
}>;
|
|
325
|
+
remove(path: string): Promise<void>;
|
|
326
|
+
search(path: string, pattern: string): Promise<unknown[]>;
|
|
327
|
+
private parsePath;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
export { type AgentContext as A, type FsResult as F, type HttpAuth as H, JsonRpcTransport as J, type Mount as M, type PaginationConfig as P, RpcBackend as R, type FsError as a, type FsBackend as b, type FsCommand as c, type AccessRole as d, type FsOp as e, HttpBackend as f, type HttpBackendConfig as g, type HttpEndpoint as h, type HttpResource as i, type JsonRpcTransportConfig as j, type RpcBackendConfig as k, type RpcCallContext as l, RpcError as m, type RpcMethod as n, type RpcResource as o, type RpcTransport as p };
|