@dupecom/botcha-cloudflare 0.16.0 → 0.19.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.
Files changed (42) hide show
  1. package/README.md +1 -1
  2. package/dist/auth.d.ts +48 -3
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +89 -21
  5. package/dist/dashboard/docs.d.ts +15 -0
  6. package/dist/dashboard/docs.d.ts.map +1 -0
  7. package/dist/dashboard/docs.js +556 -0
  8. package/dist/dashboard/layout.d.ts +12 -0
  9. package/dist/dashboard/layout.d.ts.map +1 -1
  10. package/dist/dashboard/layout.js +12 -5
  11. package/dist/dashboard/showcase.d.ts.map +1 -1
  12. package/dist/dashboard/showcase.js +2 -1
  13. package/dist/dashboard/whitepaper.d.ts.map +1 -1
  14. package/dist/dashboard/whitepaper.js +3 -3
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +125 -13
  18. package/dist/static.d.ts +592 -2
  19. package/dist/static.d.ts.map +1 -1
  20. package/dist/static.js +422 -9
  21. package/dist/tap-attestation-routes.d.ts +204 -0
  22. package/dist/tap-attestation-routes.d.ts.map +1 -0
  23. package/dist/tap-attestation-routes.js +396 -0
  24. package/dist/tap-attestation.d.ts +178 -0
  25. package/dist/tap-attestation.d.ts.map +1 -0
  26. package/dist/tap-attestation.js +416 -0
  27. package/dist/tap-delegation-routes.d.ts +236 -0
  28. package/dist/tap-delegation-routes.d.ts.map +1 -0
  29. package/dist/tap-delegation-routes.js +378 -0
  30. package/dist/tap-delegation.d.ts +127 -0
  31. package/dist/tap-delegation.d.ts.map +1 -0
  32. package/dist/tap-delegation.js +490 -0
  33. package/dist/tap-jwks.d.ts +2 -1
  34. package/dist/tap-jwks.d.ts.map +1 -1
  35. package/dist/tap-jwks.js +31 -7
  36. package/dist/tap-reputation-routes.d.ts +154 -0
  37. package/dist/tap-reputation-routes.d.ts.map +1 -0
  38. package/dist/tap-reputation-routes.js +341 -0
  39. package/dist/tap-reputation.d.ts +136 -0
  40. package/dist/tap-reputation.d.ts.map +1 -0
  41. package/dist/tap-reputation.js +346 -0
  42. package/package.json +1 -1
@@ -0,0 +1,236 @@
1
+ /**
2
+ * TAP Delegation Chain API Routes
3
+ *
4
+ * Endpoints for creating, querying, revoking, and verifying
5
+ * delegation chains between TAP agents.
6
+ *
7
+ * Routes:
8
+ * POST /v1/delegations — Create delegation
9
+ * GET /v1/delegations/:id — Get delegation details
10
+ * GET /v1/delegations — List delegations (by agent)
11
+ * POST /v1/delegations/:id/revoke — Revoke delegation (cascades)
12
+ * POST /v1/verify/delegation — Verify delegation chain
13
+ */
14
+ import type { Context } from 'hono';
15
+ /**
16
+ * POST /v1/delegations
17
+ * Create a delegation from one agent to another
18
+ */
19
+ export declare function createDelegationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
20
+ success: false;
21
+ error: string | undefined;
22
+ message: string;
23
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
24
+ success: false;
25
+ error: string;
26
+ message: string | undefined;
27
+ }, any, "json">) | (Response & import("hono").TypedResponse<{
28
+ success: true;
29
+ delegation_id: string;
30
+ grantor_id: string;
31
+ grantee_id: string;
32
+ app_id: string;
33
+ capabilities: {
34
+ action: import("./tap-agents.js").TAPAction;
35
+ scope?: string[] | undefined;
36
+ restrictions?: {
37
+ [x: string]: any;
38
+ max_amount?: number | undefined;
39
+ rate_limit?: number | undefined;
40
+ } | undefined;
41
+ }[];
42
+ chain: string[];
43
+ depth: number;
44
+ max_depth: number;
45
+ parent_delegation_id: string | null;
46
+ created_at: string;
47
+ expires_at: string;
48
+ metadata: {
49
+ [x: string]: string;
50
+ } | null;
51
+ }, 201, "json">)>;
52
+ /**
53
+ * GET /v1/delegations/:id
54
+ * Get delegation details
55
+ */
56
+ export declare function getDelegationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
57
+ success: false;
58
+ error: string;
59
+ message: string;
60
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
61
+ success: false;
62
+ error: string;
63
+ message: string;
64
+ }, 404, "json">) | (Response & import("hono").TypedResponse<{
65
+ success: true;
66
+ delegation_id: string;
67
+ grantor_id: string;
68
+ grantee_id: string;
69
+ app_id: string;
70
+ capabilities: {
71
+ action: import("./tap-agents.js").TAPAction;
72
+ scope?: string[] | undefined;
73
+ restrictions?: {
74
+ [x: string]: any;
75
+ max_amount?: number | undefined;
76
+ rate_limit?: number | undefined;
77
+ } | undefined;
78
+ }[];
79
+ chain: string[];
80
+ depth: number;
81
+ max_depth: number;
82
+ parent_delegation_id: string | null;
83
+ created_at: string;
84
+ expires_at: string;
85
+ revoked: boolean;
86
+ revoked_at: string | null;
87
+ revocation_reason: string | null;
88
+ metadata: {
89
+ [x: string]: string;
90
+ } | null;
91
+ time_remaining: number;
92
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
93
+ success: false;
94
+ error: string;
95
+ message: string;
96
+ }, 500, "json">)>;
97
+ /**
98
+ * GET /v1/delegations
99
+ * List delegations for an agent
100
+ *
101
+ * Query params:
102
+ * agent_id — required, the agent to list delegations for
103
+ * direction — 'in', 'out', or 'both' (default: 'both')
104
+ * include_revoked — 'true' to include revoked delegations
105
+ * include_expired — 'true' to include expired delegations
106
+ */
107
+ export declare function listDelegationsRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
108
+ success: false;
109
+ error: string | undefined;
110
+ message: string;
111
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
112
+ success: false;
113
+ error: string;
114
+ message: string;
115
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
116
+ success: false;
117
+ error: string;
118
+ message: string;
119
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
120
+ success: true;
121
+ delegations: {
122
+ delegation_id: string;
123
+ grantor_id: string;
124
+ grantee_id: string;
125
+ capabilities: {
126
+ action: import("./tap-agents.js").TAPAction;
127
+ scope?: string[] | undefined;
128
+ restrictions?: {
129
+ [x: string]: any;
130
+ max_amount?: number | undefined;
131
+ rate_limit?: number | undefined;
132
+ } | undefined;
133
+ }[];
134
+ chain: string[];
135
+ depth: number;
136
+ created_at: string;
137
+ expires_at: string;
138
+ revoked: boolean;
139
+ parent_delegation_id: string | null;
140
+ }[];
141
+ count: number;
142
+ agent_id: string;
143
+ direction: "out" | "in" | "both";
144
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
145
+ /**
146
+ * POST /v1/delegations/:id/revoke
147
+ * Revoke a delegation (cascades to sub-delegations)
148
+ */
149
+ export declare function revokeDelegationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
150
+ success: false;
151
+ error: string;
152
+ message: string;
153
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
154
+ success: false;
155
+ error: string | undefined;
156
+ message: string;
157
+ }, 401, "json">) | (Response & import("hono").TypedResponse<{
158
+ success: false;
159
+ error: string;
160
+ message: string;
161
+ }, 404, "json">) | (Response & import("hono").TypedResponse<{
162
+ success: false;
163
+ error: string;
164
+ message: string;
165
+ }, 403, "json">) | (Response & import("hono").TypedResponse<{
166
+ success: false;
167
+ error: string;
168
+ message: string | undefined;
169
+ }, 500, "json">) | (Response & import("hono").TypedResponse<{
170
+ success: true;
171
+ delegation_id: string;
172
+ revoked: true;
173
+ revoked_at: string | null;
174
+ revocation_reason: string | null;
175
+ message: string;
176
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">)>;
177
+ /**
178
+ * POST /v1/verify/delegation
179
+ * Verify an entire delegation chain is valid
180
+ *
181
+ * Body: { delegation_id: string }
182
+ *
183
+ * Returns the full chain and effective capabilities if valid.
184
+ */
185
+ export declare function verifyDelegationRoute(c: Context): Promise<(Response & import("hono").TypedResponse<{
186
+ success: false;
187
+ error: string;
188
+ message: string;
189
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
190
+ success: false;
191
+ valid: false;
192
+ error: string | undefined;
193
+ }, 400, "json">) | (Response & import("hono").TypedResponse<{
194
+ success: true;
195
+ valid: true;
196
+ chain_length: number;
197
+ chain: {
198
+ delegation_id: string;
199
+ grantor_id: string;
200
+ grantee_id: string;
201
+ capabilities: {
202
+ action: import("./tap-agents.js").TAPAction;
203
+ scope?: string[] | undefined;
204
+ restrictions?: {
205
+ [x: string]: any;
206
+ max_amount?: number | undefined;
207
+ rate_limit?: number | undefined;
208
+ } | undefined;
209
+ }[];
210
+ depth: number;
211
+ created_at: string;
212
+ expires_at: string;
213
+ }[];
214
+ effective_capabilities: {
215
+ action: import("./tap-agents.js").TAPAction;
216
+ scope?: string[] | undefined;
217
+ restrictions?: {
218
+ [x: string]: any;
219
+ max_amount?: number | undefined;
220
+ rate_limit?: number | undefined;
221
+ } | undefined;
222
+ }[] | undefined;
223
+ }, import("hono/utils/http-status").ContentfulStatusCode, "json">) | (Response & import("hono").TypedResponse<{
224
+ success: false;
225
+ error: string;
226
+ message: string;
227
+ }, 500, "json">)>;
228
+ declare const _default: {
229
+ createDelegationRoute: typeof createDelegationRoute;
230
+ getDelegationRoute: typeof getDelegationRoute;
231
+ listDelegationsRoute: typeof listDelegationsRoute;
232
+ revokeDelegationRoute: typeof revokeDelegationRoute;
233
+ verifyDelegationRoute: typeof verifyDelegationRoute;
234
+ };
235
+ export default _default;
236
+ //# sourceMappingURL=tap-delegation-routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tap-delegation-routes.d.ts","sourceRoot":"","sources":["../src/tap-delegation-routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AA4CpC;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAsGrD;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAmDlD;AAED;;;;;;;;;GASG;AACH,wBAAsB,oBAAoB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAqEpD;AAED;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;oEAsErD;AAED;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CAAC,CAAC,EAAE,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAkDrD;;;;;;;;AAED,wBAME"}
@@ -0,0 +1,378 @@
1
+ /**
2
+ * TAP Delegation Chain API Routes
3
+ *
4
+ * Endpoints for creating, querying, revoking, and verifying
5
+ * delegation chains between TAP agents.
6
+ *
7
+ * Routes:
8
+ * POST /v1/delegations — Create delegation
9
+ * GET /v1/delegations/:id — Get delegation details
10
+ * GET /v1/delegations — List delegations (by agent)
11
+ * POST /v1/delegations/:id/revoke — Revoke delegation (cascades)
12
+ * POST /v1/verify/delegation — Verify delegation chain
13
+ */
14
+ import { extractBearerToken, verifyToken } from './auth.js';
15
+ import { TAP_VALID_ACTIONS } from './tap-agents.js';
16
+ import { createDelegation, getDelegation, listDelegations, revokeDelegation, verifyDelegationChain, } from './tap-delegation.js';
17
+ // ============ VALIDATION HELPERS ============
18
+ async function validateAppAccess(c, requireAuth = true) {
19
+ const queryAppId = c.req.query('app_id');
20
+ let jwtAppId;
21
+ const authHeader = c.req.header('authorization');
22
+ const token = extractBearerToken(authHeader);
23
+ if (token) {
24
+ const result = await verifyToken(token, c.env.JWT_SECRET, c.env);
25
+ if (result.valid && result.payload) {
26
+ jwtAppId = result.payload.app_id;
27
+ }
28
+ }
29
+ const appId = queryAppId || jwtAppId;
30
+ if (requireAuth && !appId) {
31
+ return { valid: false, error: 'MISSING_APP_ID', status: 401 };
32
+ }
33
+ return { valid: true, appId };
34
+ }
35
+ // ============ ROUTE HANDLERS ============
36
+ /**
37
+ * POST /v1/delegations
38
+ * Create a delegation from one agent to another
39
+ */
40
+ export async function createDelegationRoute(c) {
41
+ try {
42
+ const appAccess = await validateAppAccess(c, true);
43
+ if (!appAccess.valid) {
44
+ return c.json({
45
+ success: false,
46
+ error: appAccess.error,
47
+ message: 'Authentication required'
48
+ }, (appAccess.status || 401));
49
+ }
50
+ const body = await c.req.json().catch(() => ({}));
51
+ // Validate required fields
52
+ if (!body.grantor_id || !body.grantee_id) {
53
+ return c.json({
54
+ success: false,
55
+ error: 'MISSING_REQUIRED_FIELDS',
56
+ message: 'grantor_id and grantee_id are required'
57
+ }, 400);
58
+ }
59
+ if (!body.capabilities || !Array.isArray(body.capabilities) || body.capabilities.length === 0) {
60
+ return c.json({
61
+ success: false,
62
+ error: 'MISSING_CAPABILITIES',
63
+ message: 'At least one capability is required'
64
+ }, 400);
65
+ }
66
+ // Validate capability actions
67
+ for (const cap of body.capabilities) {
68
+ if (!cap.action || !TAP_VALID_ACTIONS.includes(cap.action)) {
69
+ return c.json({
70
+ success: false,
71
+ error: 'INVALID_CAPABILITY',
72
+ message: `Invalid capability action. Valid: ${TAP_VALID_ACTIONS.join(', ')}`
73
+ }, 400);
74
+ }
75
+ }
76
+ const options = {
77
+ grantor_id: body.grantor_id,
78
+ grantee_id: body.grantee_id,
79
+ capabilities: body.capabilities,
80
+ duration_seconds: body.duration_seconds,
81
+ max_depth: body.max_depth,
82
+ parent_delegation_id: body.parent_delegation_id,
83
+ metadata: body.metadata,
84
+ };
85
+ const result = await createDelegation(c.env.AGENTS, c.env.SESSIONS, appAccess.appId, options);
86
+ if (!result.success) {
87
+ // Determine appropriate status code
88
+ const status = result.error?.includes('not found') ? 404
89
+ : result.error?.includes('does not belong') ? 403
90
+ : result.error?.includes('Cannot delegate') ? 403
91
+ : result.error?.includes('depth limit') ? 403
92
+ : result.error?.includes('cycle') ? 409
93
+ : result.error?.includes('revoked') ? 410
94
+ : result.error?.includes('expired') ? 410
95
+ : 400;
96
+ return c.json({
97
+ success: false,
98
+ error: 'DELEGATION_CREATION_FAILED',
99
+ message: result.error
100
+ }, status);
101
+ }
102
+ const del = result.delegation;
103
+ return c.json({
104
+ success: true,
105
+ delegation_id: del.delegation_id,
106
+ grantor_id: del.grantor_id,
107
+ grantee_id: del.grantee_id,
108
+ app_id: del.app_id,
109
+ capabilities: del.capabilities,
110
+ chain: del.chain,
111
+ depth: del.depth,
112
+ max_depth: del.max_depth,
113
+ parent_delegation_id: del.parent_delegation_id || null,
114
+ created_at: new Date(del.created_at).toISOString(),
115
+ expires_at: new Date(del.expires_at).toISOString(),
116
+ metadata: del.metadata || null,
117
+ }, 201);
118
+ }
119
+ catch (error) {
120
+ console.error('Delegation creation error:', error);
121
+ return c.json({
122
+ success: false,
123
+ error: 'INTERNAL_ERROR',
124
+ message: 'Internal server error'
125
+ }, 500);
126
+ }
127
+ }
128
+ /**
129
+ * GET /v1/delegations/:id
130
+ * Get delegation details
131
+ */
132
+ export async function getDelegationRoute(c) {
133
+ try {
134
+ const delegationId = c.req.param('id');
135
+ if (!delegationId) {
136
+ return c.json({
137
+ success: false,
138
+ error: 'MISSING_DELEGATION_ID',
139
+ message: 'Delegation ID is required'
140
+ }, 400);
141
+ }
142
+ const result = await getDelegation(c.env.SESSIONS, delegationId);
143
+ if (!result.success || !result.delegation) {
144
+ return c.json({
145
+ success: false,
146
+ error: 'DELEGATION_NOT_FOUND',
147
+ message: result.error || 'Delegation not found or expired'
148
+ }, 404);
149
+ }
150
+ const del = result.delegation;
151
+ return c.json({
152
+ success: true,
153
+ delegation_id: del.delegation_id,
154
+ grantor_id: del.grantor_id,
155
+ grantee_id: del.grantee_id,
156
+ app_id: del.app_id,
157
+ capabilities: del.capabilities,
158
+ chain: del.chain,
159
+ depth: del.depth,
160
+ max_depth: del.max_depth,
161
+ parent_delegation_id: del.parent_delegation_id || null,
162
+ created_at: new Date(del.created_at).toISOString(),
163
+ expires_at: new Date(del.expires_at).toISOString(),
164
+ revoked: del.revoked,
165
+ revoked_at: del.revoked_at ? new Date(del.revoked_at).toISOString() : null,
166
+ revocation_reason: del.revocation_reason || null,
167
+ metadata: del.metadata || null,
168
+ time_remaining: Math.max(0, del.expires_at - Date.now()),
169
+ });
170
+ }
171
+ catch (error) {
172
+ console.error('Delegation retrieval error:', error);
173
+ return c.json({
174
+ success: false,
175
+ error: 'INTERNAL_ERROR',
176
+ message: 'Internal server error'
177
+ }, 500);
178
+ }
179
+ }
180
+ /**
181
+ * GET /v1/delegations
182
+ * List delegations for an agent
183
+ *
184
+ * Query params:
185
+ * agent_id — required, the agent to list delegations for
186
+ * direction — 'in', 'out', or 'both' (default: 'both')
187
+ * include_revoked — 'true' to include revoked delegations
188
+ * include_expired — 'true' to include expired delegations
189
+ */
190
+ export async function listDelegationsRoute(c) {
191
+ try {
192
+ const appAccess = await validateAppAccess(c, true);
193
+ if (!appAccess.valid) {
194
+ return c.json({
195
+ success: false,
196
+ error: appAccess.error,
197
+ message: 'Authentication required'
198
+ }, (appAccess.status || 401));
199
+ }
200
+ const agentId = c.req.query('agent_id');
201
+ if (!agentId) {
202
+ return c.json({
203
+ success: false,
204
+ error: 'MISSING_AGENT_ID',
205
+ message: 'agent_id query parameter is required'
206
+ }, 400);
207
+ }
208
+ const direction = (c.req.query('direction') || 'both');
209
+ const includeRevoked = c.req.query('include_revoked') === 'true';
210
+ const includeExpired = c.req.query('include_expired') === 'true';
211
+ const result = await listDelegations(c.env.SESSIONS, {
212
+ agent_id: agentId,
213
+ app_id: appAccess.appId,
214
+ direction,
215
+ include_revoked: includeRevoked,
216
+ include_expired: includeExpired,
217
+ });
218
+ if (!result.success) {
219
+ return c.json({
220
+ success: false,
221
+ error: 'LIST_FAILED',
222
+ message: result.error || 'Failed to list delegations'
223
+ }, 500);
224
+ }
225
+ const delegations = result.delegations.map(del => ({
226
+ delegation_id: del.delegation_id,
227
+ grantor_id: del.grantor_id,
228
+ grantee_id: del.grantee_id,
229
+ capabilities: del.capabilities,
230
+ chain: del.chain,
231
+ depth: del.depth,
232
+ created_at: new Date(del.created_at).toISOString(),
233
+ expires_at: new Date(del.expires_at).toISOString(),
234
+ revoked: del.revoked,
235
+ parent_delegation_id: del.parent_delegation_id || null,
236
+ }));
237
+ return c.json({
238
+ success: true,
239
+ delegations,
240
+ count: delegations.length,
241
+ agent_id: agentId,
242
+ direction,
243
+ });
244
+ }
245
+ catch (error) {
246
+ console.error('Delegation listing error:', error);
247
+ return c.json({
248
+ success: false,
249
+ error: 'INTERNAL_ERROR',
250
+ message: 'Internal server error'
251
+ }, 500);
252
+ }
253
+ }
254
+ /**
255
+ * POST /v1/delegations/:id/revoke
256
+ * Revoke a delegation (cascades to sub-delegations)
257
+ */
258
+ export async function revokeDelegationRoute(c) {
259
+ try {
260
+ const delegationId = c.req.param('id');
261
+ if (!delegationId) {
262
+ return c.json({
263
+ success: false,
264
+ error: 'MISSING_DELEGATION_ID',
265
+ message: 'Delegation ID is required'
266
+ }, 400);
267
+ }
268
+ const appAccess = await validateAppAccess(c, true);
269
+ if (!appAccess.valid) {
270
+ return c.json({
271
+ success: false,
272
+ error: appAccess.error,
273
+ message: 'Authentication required'
274
+ }, (appAccess.status || 401));
275
+ }
276
+ // Verify delegation exists and belongs to this app
277
+ const existing = await getDelegation(c.env.SESSIONS, delegationId);
278
+ if (!existing.success || !existing.delegation) {
279
+ return c.json({
280
+ success: false,
281
+ error: 'DELEGATION_NOT_FOUND',
282
+ message: 'Delegation not found or expired'
283
+ }, 404);
284
+ }
285
+ if (existing.delegation.app_id !== appAccess.appId) {
286
+ return c.json({
287
+ success: false,
288
+ error: 'UNAUTHORIZED',
289
+ message: 'Delegation does not belong to this app'
290
+ }, 403);
291
+ }
292
+ const body = await c.req.json().catch(() => ({}));
293
+ const reason = body.reason || undefined;
294
+ const result = await revokeDelegation(c.env.SESSIONS, delegationId, reason);
295
+ if (!result.success) {
296
+ return c.json({
297
+ success: false,
298
+ error: 'REVOCATION_FAILED',
299
+ message: result.error
300
+ }, 500);
301
+ }
302
+ const del = result.delegation;
303
+ return c.json({
304
+ success: true,
305
+ delegation_id: del.delegation_id,
306
+ revoked: true,
307
+ revoked_at: del.revoked_at ? new Date(del.revoked_at).toISOString() : null,
308
+ revocation_reason: del.revocation_reason || null,
309
+ message: 'Delegation revoked. Sub-delegations have been cascaded.',
310
+ });
311
+ }
312
+ catch (error) {
313
+ console.error('Delegation revocation error:', error);
314
+ return c.json({
315
+ success: false,
316
+ error: 'INTERNAL_ERROR',
317
+ message: 'Internal server error'
318
+ }, 500);
319
+ }
320
+ }
321
+ /**
322
+ * POST /v1/verify/delegation
323
+ * Verify an entire delegation chain is valid
324
+ *
325
+ * Body: { delegation_id: string }
326
+ *
327
+ * Returns the full chain and effective capabilities if valid.
328
+ */
329
+ export async function verifyDelegationRoute(c) {
330
+ try {
331
+ const body = await c.req.json().catch(() => ({}));
332
+ if (!body.delegation_id) {
333
+ return c.json({
334
+ success: false,
335
+ error: 'MISSING_DELEGATION_ID',
336
+ message: 'delegation_id is required'
337
+ }, 400);
338
+ }
339
+ const result = await verifyDelegationChain(c.env.AGENTS, c.env.SESSIONS, body.delegation_id);
340
+ if (!result.valid) {
341
+ return c.json({
342
+ success: false,
343
+ valid: false,
344
+ error: result.error,
345
+ }, 400);
346
+ }
347
+ return c.json({
348
+ success: true,
349
+ valid: true,
350
+ chain_length: result.chain.length,
351
+ chain: result.chain.map(del => ({
352
+ delegation_id: del.delegation_id,
353
+ grantor_id: del.grantor_id,
354
+ grantee_id: del.grantee_id,
355
+ capabilities: del.capabilities,
356
+ depth: del.depth,
357
+ created_at: new Date(del.created_at).toISOString(),
358
+ expires_at: new Date(del.expires_at).toISOString(),
359
+ })),
360
+ effective_capabilities: result.effective_capabilities,
361
+ });
362
+ }
363
+ catch (error) {
364
+ console.error('Delegation verification error:', error);
365
+ return c.json({
366
+ success: false,
367
+ error: 'INTERNAL_ERROR',
368
+ message: 'Internal server error'
369
+ }, 500);
370
+ }
371
+ }
372
+ export default {
373
+ createDelegationRoute,
374
+ getDelegationRoute,
375
+ listDelegationsRoute,
376
+ revokeDelegationRoute,
377
+ verifyDelegationRoute,
378
+ };