sealbridge 0.0.1 → 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.
Files changed (187) hide show
  1. package/NOTICE +43 -0
  2. package/README.ja.md +375 -0
  3. package/README.md +466 -1
  4. package/dist/cli/dist/acp.d.ts +2 -0
  5. package/dist/cli/dist/acp.js +6 -0
  6. package/dist/cli/dist/acp.js.map +1 -0
  7. package/dist/cli/dist/board.d.ts +47 -0
  8. package/dist/cli/dist/board.js +255 -0
  9. package/dist/cli/dist/board.js.map +1 -0
  10. package/dist/cli/dist/contacts.d.ts +18 -0
  11. package/dist/cli/dist/contacts.js +154 -0
  12. package/dist/cli/dist/contacts.js.map +1 -0
  13. package/dist/cli/dist/doctor.d.ts +13 -0
  14. package/dist/cli/dist/doctor.js +30 -0
  15. package/dist/cli/dist/doctor.js.map +1 -0
  16. package/dist/cli/dist/index.d.ts +2 -0
  17. package/dist/cli/dist/index.js +193 -0
  18. package/dist/cli/dist/index.js.map +1 -0
  19. package/dist/cli/dist/invite-share.d.ts +16 -0
  20. package/dist/cli/dist/invite-share.js +169 -0
  21. package/dist/cli/dist/invite-share.js.map +1 -0
  22. package/dist/cli/dist/mcp.d.ts +17 -0
  23. package/dist/cli/dist/mcp.js +105 -0
  24. package/dist/cli/dist/mcp.js.map +1 -0
  25. package/dist/cli/dist/network.d.ts +1 -0
  26. package/dist/cli/dist/network.js +320 -0
  27. package/dist/cli/dist/network.js.map +1 -0
  28. package/dist/cli/dist/public-settings.d.ts +27 -0
  29. package/dist/cli/dist/public-settings.js +33 -0
  30. package/dist/cli/dist/public-settings.js.map +1 -0
  31. package/dist/cli/dist/receipt.d.ts +39 -0
  32. package/dist/cli/dist/receipt.js +90 -0
  33. package/dist/cli/dist/receipt.js.map +1 -0
  34. package/dist/cli/dist/receive-hook.d.ts +2 -0
  35. package/dist/cli/dist/receive-hook.js +35 -0
  36. package/dist/cli/dist/receive-hook.js.map +1 -0
  37. package/dist/examples/two-owner-demo/alice-policy.json +4 -0
  38. package/dist/examples/two-owner-demo/bob-policy.json +4 -0
  39. package/dist/examples/two-owner-demo/dist/run-demo.d.ts +71 -0
  40. package/dist/examples/two-owner-demo/dist/run-demo.js +383 -0
  41. package/dist/examples/two-owner-demo/dist/run-demo.js.map +1 -0
  42. package/dist/package.json +1 -0
  43. package/dist/packages/adapters/dist/command.d.ts +120 -0
  44. package/dist/packages/adapters/dist/command.js +365 -0
  45. package/dist/packages/adapters/dist/command.js.map +1 -0
  46. package/dist/packages/adapters/dist/credential-proxy.d.ts +37 -0
  47. package/dist/packages/adapters/dist/credential-proxy.js +363 -0
  48. package/dist/packages/adapters/dist/credential-proxy.js.map +1 -0
  49. package/dist/packages/adapters/dist/index.d.ts +6 -0
  50. package/dist/packages/adapters/dist/index.js +6 -0
  51. package/dist/packages/adapters/dist/index.js.map +1 -0
  52. package/dist/packages/adapters/dist/mcp.d.ts +32 -0
  53. package/dist/packages/adapters/dist/mcp.js +87 -0
  54. package/dist/packages/adapters/dist/mcp.js.map +1 -0
  55. package/dist/packages/adapters/dist/openai.d.ts +23 -0
  56. package/dist/packages/adapters/dist/openai.js +81 -0
  57. package/dist/packages/adapters/dist/openai.js.map +1 -0
  58. package/dist/packages/adapters/dist/sandbox.d.ts +45 -0
  59. package/dist/packages/adapters/dist/sandbox.js +60 -0
  60. package/dist/packages/adapters/dist/sandbox.js.map +1 -0
  61. package/dist/packages/core/dist/capability.d.ts +36 -0
  62. package/dist/packages/core/dist/capability.js +198 -0
  63. package/dist/packages/core/dist/capability.js.map +1 -0
  64. package/dist/packages/core/dist/contract.d.ts +33 -0
  65. package/dist/packages/core/dist/contract.js +97 -0
  66. package/dist/packages/core/dist/contract.js.map +1 -0
  67. package/dist/packages/core/dist/crypto.d.ts +34 -0
  68. package/dist/packages/core/dist/crypto.js +323 -0
  69. package/dist/packages/core/dist/crypto.js.map +1 -0
  70. package/dist/packages/core/dist/discovery.d.ts +124 -0
  71. package/dist/packages/core/dist/discovery.js +511 -0
  72. package/dist/packages/core/dist/discovery.js.map +1 -0
  73. package/dist/packages/core/dist/edge.d.ts +4 -0
  74. package/dist/packages/core/dist/edge.js +6 -0
  75. package/dist/packages/core/dist/edge.js.map +1 -0
  76. package/dist/packages/core/dist/index.d.ts +9 -0
  77. package/dist/packages/core/dist/index.js +10 -0
  78. package/dist/packages/core/dist/index.js.map +1 -0
  79. package/dist/packages/core/dist/receipts.d.ts +9 -0
  80. package/dist/packages/core/dist/receipts.js +67 -0
  81. package/dist/packages/core/dist/receipts.js.map +1 -0
  82. package/dist/packages/core/dist/relay-auth.d.ts +40 -0
  83. package/dist/packages/core/dist/relay-auth.js +106 -0
  84. package/dist/packages/core/dist/relay-auth.js.map +1 -0
  85. package/dist/packages/core/dist/revocation.d.ts +55 -0
  86. package/dist/packages/core/dist/revocation.js +88 -0
  87. package/dist/packages/core/dist/revocation.js.map +1 -0
  88. package/dist/packages/core/dist/schema.d.ts +11 -0
  89. package/dist/packages/core/dist/schema.js +48 -0
  90. package/dist/packages/core/dist/schema.js.map +1 -0
  91. package/dist/packages/core/dist/types.d.ts +172 -0
  92. package/dist/packages/core/dist/types.js +2 -0
  93. package/dist/packages/core/dist/types.js.map +1 -0
  94. package/dist/packages/ledger/dist/index.d.ts +84 -0
  95. package/dist/packages/ledger/dist/index.js +269 -0
  96. package/dist/packages/ledger/dist/index.js.map +1 -0
  97. package/dist/packages/relay/dist/fetch.d.ts +223 -0
  98. package/dist/packages/relay/dist/fetch.js +1210 -0
  99. package/dist/packages/relay/dist/fetch.js.map +1 -0
  100. package/dist/packages/relay/dist/index.d.ts +92 -0
  101. package/dist/packages/relay/dist/index.js +707 -0
  102. package/dist/packages/relay/dist/index.js.map +1 -0
  103. package/dist/packages/relay/dist/journal.d.ts +70 -0
  104. package/dist/packages/relay/dist/journal.js +310 -0
  105. package/dist/packages/relay/dist/journal.js.map +1 -0
  106. package/dist/packages/relay/dist/retry.d.ts +9 -0
  107. package/dist/packages/relay/dist/retry.js +39 -0
  108. package/dist/packages/relay/dist/retry.js.map +1 -0
  109. package/dist/packages/relay/dist/ssrf.d.ts +32 -0
  110. package/dist/packages/relay/dist/ssrf.js +213 -0
  111. package/dist/packages/relay/dist/ssrf.js.map +1 -0
  112. package/dist/packages/relay/dist/worker.d.ts +85 -0
  113. package/dist/packages/relay/dist/worker.js +411 -0
  114. package/dist/packages/relay/dist/worker.js.map +1 -0
  115. package/dist/packages/runtime/dist/a2a.d.ts +8 -0
  116. package/dist/packages/runtime/dist/a2a.js +69 -0
  117. package/dist/packages/runtime/dist/a2a.js.map +1 -0
  118. package/dist/packages/runtime/dist/adapter.d.ts +51 -0
  119. package/dist/packages/runtime/dist/adapter.js +2 -0
  120. package/dist/packages/runtime/dist/adapter.js.map +1 -0
  121. package/dist/packages/runtime/dist/approval-providers.d.ts +97 -0
  122. package/dist/packages/runtime/dist/approval-providers.js +269 -0
  123. package/dist/packages/runtime/dist/approval-providers.js.map +1 -0
  124. package/dist/packages/runtime/dist/daily-limit.d.ts +2 -0
  125. package/dist/packages/runtime/dist/daily-limit.js +54 -0
  126. package/dist/packages/runtime/dist/daily-limit.js.map +1 -0
  127. package/dist/packages/runtime/dist/gateway.d.ts +35 -0
  128. package/dist/packages/runtime/dist/gateway.js +92 -0
  129. package/dist/packages/runtime/dist/gateway.js.map +1 -0
  130. package/dist/packages/runtime/dist/inbox.d.ts +10 -0
  131. package/dist/packages/runtime/dist/inbox.js +24 -0
  132. package/dist/packages/runtime/dist/inbox.js.map +1 -0
  133. package/dist/packages/runtime/dist/index.d.ts +13 -0
  134. package/dist/packages/runtime/dist/index.js +14 -0
  135. package/dist/packages/runtime/dist/index.js.map +1 -0
  136. package/dist/packages/runtime/dist/mcp-server.d.ts +90 -0
  137. package/dist/packages/runtime/dist/mcp-server.js +631 -0
  138. package/dist/packages/runtime/dist/mcp-server.js.map +1 -0
  139. package/dist/packages/runtime/dist/mcp-tool-catalog.d.ts +3 -0
  140. package/dist/packages/runtime/dist/mcp-tool-catalog.js +491 -0
  141. package/dist/packages/runtime/dist/mcp-tool-catalog.js.map +1 -0
  142. package/dist/packages/runtime/dist/mcp.d.ts +73 -0
  143. package/dist/packages/runtime/dist/mcp.js +67 -0
  144. package/dist/packages/runtime/dist/mcp.js.map +1 -0
  145. package/dist/packages/runtime/dist/policy.d.ts +19 -0
  146. package/dist/packages/runtime/dist/policy.js +41 -0
  147. package/dist/packages/runtime/dist/policy.js.map +1 -0
  148. package/dist/packages/runtime/dist/quota.d.ts +39 -0
  149. package/dist/packages/runtime/dist/quota.js +147 -0
  150. package/dist/packages/runtime/dist/quota.js.map +1 -0
  151. package/dist/packages/runtime/dist/session-audit.d.ts +88 -0
  152. package/dist/packages/runtime/dist/session-audit.js +415 -0
  153. package/dist/packages/runtime/dist/session-audit.js.map +1 -0
  154. package/dist/packages/runtime/dist/session.d.ts +288 -0
  155. package/dist/packages/runtime/dist/session.js +1880 -0
  156. package/dist/packages/runtime/dist/session.js.map +1 -0
  157. package/dist/packages/runtime/dist/verifier.d.ts +64 -0
  158. package/dist/packages/runtime/dist/verifier.js +109 -0
  159. package/dist/packages/runtime/dist/verifier.js.map +1 -0
  160. package/dist/packages/sandbox/dist/container.d.ts +33 -0
  161. package/dist/packages/sandbox/dist/container.js +189 -0
  162. package/dist/packages/sandbox/dist/container.js.map +1 -0
  163. package/dist/packages/sandbox/dist/index.d.ts +34 -0
  164. package/dist/packages/sandbox/dist/index.js +179 -0
  165. package/dist/packages/sandbox/dist/index.js.map +1 -0
  166. package/dist/packages/sandbox/dist/permission.d.ts +58 -0
  167. package/dist/packages/sandbox/dist/permission.js +90 -0
  168. package/dist/packages/sandbox/dist/permission.js.map +1 -0
  169. package/dist/spec/README.ja.md +76 -0
  170. package/dist/spec/README.md +135 -0
  171. package/dist/spec/ack-receipt.schema.json +77 -0
  172. package/dist/spec/agent-card.schema.json +83 -0
  173. package/dist/spec/approval-receipt.schema.json +94 -0
  174. package/dist/spec/audit-entry.schema.json +101 -0
  175. package/dist/spec/capability-token.schema.json +133 -0
  176. package/dist/spec/envelope.schema.json +197 -0
  177. package/dist/spec/examples/sample-ack-receipt.json +16 -0
  178. package/dist/spec/examples/sample-agent-card.json +35 -0
  179. package/dist/spec/examples/sample-approval-receipt.json +18 -0
  180. package/dist/spec/examples/sample-audit-entry.json +37 -0
  181. package/dist/spec/examples/sample-capability-token.json +39 -0
  182. package/dist/spec/examples/sample-envelope.json +21 -0
  183. package/dist/spec/examples/sample-task-manifest.json +141 -0
  184. package/dist/spec/examples/sample-usage-receipt.json +19 -0
  185. package/dist/spec/task-manifest.schema.json +422 -0
  186. package/dist/spec/usage-receipt.schema.json +91 -0
  187. package/package.json +61 -5
@@ -0,0 +1,97 @@
1
+ import type { Readable, Writable } from 'node:stream';
2
+ import type { ApprovalReceipt, Gate, KeyPair } from '@acp/core';
3
+ import type { OwnerPolicy } from './policy.js';
4
+ /** Caps a worker applies before it accepts a contract or spends owner credentials. */
5
+ export interface WorkerAcceptancePolicy {
6
+ /** When non-empty, only these requester owner DIDs may be accepted. */
7
+ allowedRequesterDids?: readonly string[];
8
+ /** Explicit opt-in to accept every requester. Takes precedence over the allowlist. */
9
+ allowAnyRequester?: boolean;
10
+ maxInputTokens?: number;
11
+ maxOutputTokens?: number;
12
+ maxToolInvocations?: number;
13
+ maxWallClockSeconds?: number;
14
+ maxConcurrentTasks?: number;
15
+ /** How many PROPOSE envelopes one requester DID may submit per minute. */
16
+ maxTasksPerRequesterPerMinute?: number;
17
+ /** Replaces the one-minute window when set. */
18
+ requesterRateLimit?: {
19
+ maxRequests: number;
20
+ windowMs: number;
21
+ };
22
+ /** Register the worker AgentCard in the relay directory. Default is off. */
23
+ publishToRegistry?: boolean;
24
+ }
25
+ export declare class ProposalRejectedError extends Error {
26
+ readonly reason: string;
27
+ readonly approved = false;
28
+ readonly code = "PROPOSAL_REJECTED";
29
+ constructor(reason: string);
30
+ }
31
+ /** Returns approved:false with a reason when a proposal exceeds the worker policy. */
32
+ export declare function evaluateContractAcceptance(policy: WorkerAcceptancePolicy | undefined, details: unknown, from?: string): {
33
+ approved: true;
34
+ } | {
35
+ approved: false;
36
+ reason: string;
37
+ };
38
+ export interface ApprovalRequest {
39
+ taskId: string;
40
+ gate: Gate;
41
+ target: unknown;
42
+ details?: unknown;
43
+ signal?: AbortSignal;
44
+ }
45
+ export interface ApprovalProvider {
46
+ approve(request: ApprovalRequest): Promise<ApprovalReceipt>;
47
+ }
48
+ export declare class InteractiveCliApprovalProvider implements ApprovalProvider {
49
+ readonly owner: KeyPair;
50
+ readonly options: {
51
+ input?: Readable;
52
+ output?: Writable;
53
+ };
54
+ constructor(owner: KeyPair, options?: {
55
+ input?: Readable;
56
+ output?: Writable;
57
+ });
58
+ approve(request: ApprovalRequest): Promise<ApprovalReceipt>;
59
+ }
60
+ export declare class PolicyAutoApprovalProvider implements ApprovalProvider {
61
+ readonly owner: KeyPair;
62
+ readonly policy: OwnerPolicy;
63
+ readonly options: {
64
+ yes?: boolean;
65
+ confirmedGates?: Gate[];
66
+ acceptance?: WorkerAcceptancePolicy;
67
+ };
68
+ constructor(owner: KeyPair, policy?: OwnerPolicy, options?: {
69
+ yes?: boolean;
70
+ confirmedGates?: Gate[];
71
+ acceptance?: WorkerAcceptancePolicy;
72
+ });
73
+ approve(r: ApprovalRequest): Promise<ApprovalReceipt>;
74
+ }
75
+ export interface WebhookApprovalProviderOptions {
76
+ url: string;
77
+ ownerDid?: string;
78
+ fetch?: typeof fetch;
79
+ timeoutMs?: number;
80
+ /**
81
+ * `signed-receipt` (default) posts a signed approval request and requires a
82
+ * signed ApprovalReceipt. `owner-decision` posts
83
+ * `{ taskId, summaryHash, reason, approverDid }` and signs locally when the
84
+ * webhook returns `{ approved: true }`.
85
+ */
86
+ response?: 'signed-receipt' | 'owner-decision';
87
+ }
88
+ /** Reject webhook URLs that are not plain HTTP(S) endpoints. */
89
+ export declare function assertApprovalWebhookUrl(value: string): void;
90
+ export declare class WebhookApprovalProvider implements ApprovalProvider {
91
+ readonly owner: KeyPair;
92
+ readonly options: WebhookApprovalProviderOptions;
93
+ constructor(owner: KeyPair, options: WebhookApprovalProviderOptions);
94
+ approve(r: ApprovalRequest): Promise<ApprovalReceipt>;
95
+ /** Sign with the owner key only when the webhook explicitly approves. */
96
+ private approveOwnerDecision;
97
+ }
@@ -0,0 +1,269 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { createInterface } from 'node:readline';
3
+ import { signApproval, signPayload, verifyApproval, digest } from '../../core/dist/index.js';
4
+ export class ProposalRejectedError extends Error {
5
+ reason;
6
+ approved = false;
7
+ code = 'PROPOSAL_REJECTED';
8
+ constructor(reason) {
9
+ super('PROPOSAL_REJECTED: ' + reason);
10
+ this.reason = reason;
11
+ this.name = 'ProposalRejectedError';
12
+ }
13
+ }
14
+ const budgetFields = [
15
+ 'maxInputTokens',
16
+ 'maxOutputTokens',
17
+ 'maxToolInvocations',
18
+ 'maxWallClockSeconds',
19
+ ];
20
+ function proposedManifest(details) {
21
+ if (!details || typeof details !== 'object')
22
+ return undefined;
23
+ const manifest = details.manifest;
24
+ if (!manifest || typeof manifest !== 'object' || Array.isArray(manifest))
25
+ return undefined;
26
+ return manifest;
27
+ }
28
+ function envelopeFrom(details, from) {
29
+ if (typeof from === 'string' && from.length > 0)
30
+ return from;
31
+ if (!details || typeof details !== 'object')
32
+ return undefined;
33
+ const value = details.from;
34
+ return typeof value === 'string' && value.length > 0 ? value : undefined;
35
+ }
36
+ function budgetLimit(policy, field) {
37
+ return policy[field];
38
+ }
39
+ /** Returns approved:false with a reason when a proposal exceeds the worker policy. */
40
+ export function evaluateContractAcceptance(policy, details, from) {
41
+ if (!policy)
42
+ return { approved: true };
43
+ const manifest = proposedManifest(details);
44
+ const limited = budgetFields.some((field) => policy[field] !== undefined);
45
+ if (limited && !manifest)
46
+ return { approved: false, reason: 'manifest is missing' };
47
+ if (manifest && limited) {
48
+ const budget = manifest.budget;
49
+ if (!budget || typeof budget !== 'object' || Array.isArray(budget))
50
+ return { approved: false, reason: 'budget is missing' };
51
+ for (const field of budgetFields) {
52
+ const limit = budgetLimit(policy, field);
53
+ if (limit === undefined)
54
+ continue;
55
+ const proposed = budget[field];
56
+ if (typeof proposed !== 'number' || !Number.isFinite(proposed))
57
+ return { approved: false, reason: field + ' is missing or not a finite number' };
58
+ if (proposed > limit)
59
+ return {
60
+ approved: false,
61
+ reason: field + ' ' + proposed + ' exceeds worker limit ' + limit,
62
+ };
63
+ }
64
+ }
65
+ if (manifest && policy.maxWallClockSeconds !== undefined && 'timeoutSeconds' in manifest) {
66
+ const timeout = manifest.timeoutSeconds;
67
+ if (typeof timeout !== 'number' || !Number.isFinite(timeout))
68
+ return { approved: false, reason: 'timeoutSeconds is missing or not a finite number' };
69
+ if (timeout > policy.maxWallClockSeconds)
70
+ return {
71
+ approved: false,
72
+ reason: 'timeoutSeconds ' +
73
+ timeout +
74
+ ' exceeds worker limit ' +
75
+ policy.maxWallClockSeconds,
76
+ };
77
+ }
78
+ if (policy.allowAnyRequester)
79
+ return { approved: true };
80
+ const allow = (policy.allowedRequesterDids ?? []).map((did) => did.trim()).filter(Boolean);
81
+ if (allow.length === 0)
82
+ return { approved: true };
83
+ const ownerDid = manifest?.requester?.ownerDid;
84
+ const sender = envelopeFrom(details, from);
85
+ if (typeof sender === 'string' && typeof ownerDid === 'string' && sender !== ownerDid)
86
+ return {
87
+ approved: false,
88
+ reason: 'requester ' + ownerDid + ' does not match envelope from ' + sender,
89
+ };
90
+ const authenticated = typeof ownerDid === 'string' && ownerDid.length > 0 ? ownerDid : sender;
91
+ if (typeof authenticated === 'string' && allow.includes(authenticated))
92
+ return { approved: true };
93
+ return {
94
+ approved: false,
95
+ reason: 'requester ' + (authenticated ?? 'unknown') + ' is not allowed',
96
+ };
97
+ }
98
+ export class InteractiveCliApprovalProvider {
99
+ owner;
100
+ options;
101
+ constructor(owner, options = {}) {
102
+ this.owner = owner;
103
+ this.options = options;
104
+ }
105
+ async approve(request) {
106
+ const output = this.options.output ?? process.stdout;
107
+ output.write(JSON.stringify({
108
+ taskId: request.taskId,
109
+ gate: request.gate,
110
+ targetDigest: digest(request.target),
111
+ target: request.target,
112
+ details: request.details ?? null,
113
+ }, null, 2) + '\nApprove [y/N]? ');
114
+ const rl = createInterface({ input: this.options.input ?? process.stdin, crlfDelay: Infinity });
115
+ try {
116
+ const answer = await new Promise((resolve, reject) => {
117
+ const abort = () => {
118
+ cleanup();
119
+ reject(new Error('APPROVAL_ABORTED'));
120
+ };
121
+ const cleanup = () => request.signal?.removeEventListener('abort', abort);
122
+ rl.once('line', (line) => {
123
+ cleanup();
124
+ resolve(line);
125
+ });
126
+ rl.once('close', () => {
127
+ cleanup();
128
+ resolve('');
129
+ });
130
+ rl.once('error', (e) => {
131
+ cleanup();
132
+ reject(e);
133
+ });
134
+ request.signal?.addEventListener('abort', abort, { once: true });
135
+ if (request.signal?.aborted)
136
+ abort();
137
+ });
138
+ return signApproval(request.taskId, request.gate, request.target, this.owner, /^y(es)?$/i.test(answer.trim()) ? 'APPROVED' : 'REJECTED');
139
+ }
140
+ finally {
141
+ rl.close();
142
+ }
143
+ }
144
+ }
145
+ export class PolicyAutoApprovalProvider {
146
+ owner;
147
+ policy;
148
+ options;
149
+ constructor(owner, policy = {
150
+ requiredGates: [],
151
+ autoApprove: ['contract_acceptance', 'final_verification'],
152
+ }, options = {}) {
153
+ this.owner = owner;
154
+ this.policy = policy;
155
+ this.options = options;
156
+ }
157
+ async approve(r) {
158
+ if (r.gate === 'contract_acceptance') {
159
+ const decision = evaluateContractAcceptance(this.options.acceptance, r.details);
160
+ if (!decision.approved)
161
+ throw new ProposalRejectedError(decision.reason);
162
+ }
163
+ const explicit = this.options.confirmedGates?.includes(r.gate);
164
+ const sensitive = ['external_side_effect', 'budget_increase'].includes(r.gate);
165
+ if (!explicit &&
166
+ (sensitive ||
167
+ this.policy.requiredGates.includes(r.gate) ||
168
+ (!this.options.yes && !this.policy.autoApprove.includes(r.gate))))
169
+ throw new Error('HITL_REQUIRED: ' + r.gate);
170
+ return signApproval(r.taskId, r.gate, r.target, this.owner);
171
+ }
172
+ }
173
+ /** Reject webhook URLs that are not plain HTTP(S) endpoints. */
174
+ export function assertApprovalWebhookUrl(value) {
175
+ let url;
176
+ try {
177
+ url = new URL(value);
178
+ }
179
+ catch {
180
+ throw new Error('INVALID_APPROVAL_WEBHOOK_URL');
181
+ }
182
+ if ((url.protocol !== 'http:' && url.protocol !== 'https:') || url.username || url.password)
183
+ throw new Error('INVALID_APPROVAL_WEBHOOK_URL');
184
+ }
185
+ function approvalReason(request) {
186
+ const details = request.details;
187
+ if (details && typeof details === 'object' && !Array.isArray(details)) {
188
+ const reason = details.reason;
189
+ if (typeof reason === 'string' && reason.length > 0)
190
+ return reason;
191
+ }
192
+ return request.gate;
193
+ }
194
+ export class WebhookApprovalProvider {
195
+ owner;
196
+ options;
197
+ constructor(owner, options) {
198
+ this.owner = owner;
199
+ this.options = options;
200
+ if (options.response === 'owner-decision')
201
+ assertApprovalWebhookUrl(options.url);
202
+ }
203
+ async approve(r) {
204
+ if (this.options.response === 'owner-decision')
205
+ return this.approveOwnerDecision(r);
206
+ const body = signPayload({
207
+ type: 'ApprovalRequest',
208
+ taskId: r.taskId,
209
+ gate: r.gate,
210
+ target: r.target,
211
+ targetDigest: digest(r.target),
212
+ details: r.details ?? null,
213
+ }, this.owner);
214
+ const signal = AbortSignal.any([
215
+ AbortSignal.timeout(this.options.timeoutMs ?? 60000),
216
+ ...(r.signal ? [r.signal] : []),
217
+ ]);
218
+ const response = await (this.options.fetch ?? fetch)(this.options.url, {
219
+ method: 'POST',
220
+ headers: { 'content-type': 'application/json' },
221
+ body: JSON.stringify(body),
222
+ signal,
223
+ redirect: 'error',
224
+ });
225
+ if (!response.ok)
226
+ throw new Error('APPROVAL_WEBHOOK_FAILED');
227
+ const receipt = (await response.json());
228
+ if (!verifyApproval(receipt, this.options.ownerDid ?? this.owner.did, r.taskId, r.gate, r.target))
229
+ throw new Error('INVALID_APPROVAL_RESPONSE');
230
+ return receipt;
231
+ }
232
+ /** Sign with the owner key only when the webhook explicitly approves. */
233
+ async approveOwnerDecision(r) {
234
+ const body = {
235
+ taskId: r.taskId,
236
+ summaryHash: digest(r.target),
237
+ reason: approvalReason(r),
238
+ approverDid: this.owner.did,
239
+ };
240
+ const signal = AbortSignal.any([
241
+ AbortSignal.timeout(this.options.timeoutMs ?? 60000),
242
+ ...(r.signal ? [r.signal] : []),
243
+ ]);
244
+ const response = await (this.options.fetch ?? fetch)(this.options.url, {
245
+ method: 'POST',
246
+ headers: { 'content-type': 'application/json' },
247
+ body: JSON.stringify(body),
248
+ signal,
249
+ redirect: 'error',
250
+ });
251
+ if (!response.ok)
252
+ throw new Error('APPROVAL_REJECTED');
253
+ let parsed;
254
+ try {
255
+ parsed = await response.json();
256
+ }
257
+ catch {
258
+ throw new Error('APPROVAL_REJECTED');
259
+ }
260
+ const approved = !!parsed &&
261
+ typeof parsed === 'object' &&
262
+ !Array.isArray(parsed) &&
263
+ parsed.approved === true;
264
+ if (!approved)
265
+ throw new Error('APPROVAL_REJECTED');
266
+ return signApproval(r.taskId, r.gate, r.target, this.owner, 'APPROVED');
267
+ }
268
+ }
269
+ //# sourceMappingURL=approval-providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-providers.js","sourceRoot":"","sources":["../src/approval-providers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ /** Host-wide UTC admission counter. Lock contention and corrupt state fail closed. */
2
+ export declare function consumeDailyTask(path: string, limit: number, taskId: string, now?: number): void;
@@ -0,0 +1,54 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { mkdirSync, readFileSync, writeFileSync, renameSync, unlinkSync } from 'node:fs';
3
+ import { dirname } from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ /** Host-wide UTC admission counter. Lock contention and corrupt state fail closed. */
6
+ export function consumeDailyTask(path, limit, taskId, now = Date.now()) {
7
+ if (!Number.isSafeInteger(limit) || limit < 1 || !Number.isFinite(now) || !taskId)
8
+ throw new Error('INVALID_DAILY_LIMIT');
9
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
10
+ const lock = path + '.lock', temporary = path + '.' + randomUUID() + '.tmp';
11
+ try {
12
+ writeFileSync(lock, '', { flag: 'wx', mode: 0o600 });
13
+ }
14
+ catch {
15
+ throw new Error('DAILY_LIMIT_BUSY: retry later; never remove a live lock');
16
+ }
17
+ try {
18
+ const day = new Date(now).toISOString().slice(0, 10);
19
+ let state = { version: 1, day, tasks: [] };
20
+ try {
21
+ state = JSON.parse(readFileSync(path, 'utf8'));
22
+ }
23
+ catch (e) {
24
+ if (e.code !== 'ENOENT')
25
+ throw new Error('DAILY_LIMIT_INVALID');
26
+ }
27
+ if (state.version !== 1 || !/^\d{4}-\d{2}-\d{2}$/.test(state.day) ||
28
+ !Array.isArray(state.tasks) || state.tasks.some(t => typeof t !== 'string') ||
29
+ new Set(state.tasks).size !== state.tasks.length)
30
+ throw new Error('DAILY_LIMIT_INVALID');
31
+ if (day < state.day)
32
+ throw new Error('DAILY_LIMIT_CLOCK_ROLLBACK');
33
+ if (day > state.day)
34
+ state = { version: 1, day, tasks: [] };
35
+ if (state.tasks.includes(taskId))
36
+ throw new Error('DAILY_TASK_REPLAY');
37
+ if (state.tasks.length >= limit)
38
+ throw new Error('DAILY_LIMIT_REACHED');
39
+ state.tasks.push(taskId);
40
+ writeFileSync(temporary, JSON.stringify(state), { flag: 'wx', mode: 0o600, flush: true });
41
+ renameSync(temporary, path);
42
+ }
43
+ finally {
44
+ try {
45
+ unlinkSync(temporary);
46
+ }
47
+ catch (e) {
48
+ if (e.code !== 'ENOENT')
49
+ throw e;
50
+ }
51
+ unlinkSync(lock);
52
+ }
53
+ }
54
+ //# sourceMappingURL=daily-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daily-limit.js","sourceRoot":"","sources":["../src/daily-limit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import { ContractMachine, CapabilityGuard } from '@acp/core';
2
+ import type { TaskContract, KeyPair, ApprovalReceipt, CapabilityToken, Capability, Signed, Transition, ContractEvent, Json, SignedEnvelope, RevocationList } from '@acp/core';
3
+ import type { SandboxBoundaryMetadata } from '@acp/sandbox';
4
+ import { ApprovalGate } from './policy.js';
5
+ import type { OwnerPolicy } from './policy.js';
6
+ import { QuotaMeter } from './quota.js';
7
+ import type { MCPProxy } from './mcp.js';
8
+ import { EnvelopeInbox } from './inbox.js';
9
+ import { VerificationEngine } from './verifier.js';
10
+ export declare class OwnerGateway {
11
+ readonly owner: KeyPair;
12
+ readonly contract: TaskContract;
13
+ effectiveIsolationLevel: string;
14
+ /** Set by `execute` from the runner. Undefined until a sandbox task has run. */
15
+ sandboxBoundary?: SandboxBoundaryMetadata;
16
+ readonly capabilities: CapabilityGuard;
17
+ readonly inbox: EnvelopeInbox;
18
+ readonly machine: ContractMachine;
19
+ readonly approvals: ApprovalGate;
20
+ readonly quota: QuotaMeter;
21
+ constructor(owner: KeyPair, contract: TaskContract, policy: OwnerPolicy, revocation?: RevocationList);
22
+ accept(receipt: ApprovalReceipt): Signed<Transition>;
23
+ private applyOwn;
24
+ transition(event: ContractEvent): Signed<Transition>;
25
+ verifyAndSettle(envelope: SignedEnvelope, engine: VerificationEngine, approval?: ApprovalReceipt | (() => Promise<ApprovalReceipt>), options?: {
26
+ allowUnencryptedEnvelopes?: boolean;
27
+ }): Promise<{
28
+ result: import("./verifier.js").VerificationResult;
29
+ verification: Signed<Transition>;
30
+ settlement: Signed<Transition> | undefined;
31
+ }>;
32
+ redelegate(chain: CapabilityToken[], params: Omit<Capability, 'id' | 'type' | 'issuer' | 'parentHash'>, receipt: ApprovalReceipt): CapabilityToken;
33
+ execute(code: string, proxy: MCPProxy, input?: Json): Promise<Json>;
34
+ close(): void;
35
+ }
@@ -0,0 +1,92 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { ContractMachine, createCapability, verifyCapabilityChain, digest, CapabilityGuard, } from '../../core/dist/index.js';
3
+ import { runContainerOrSubprocessSandbox } from '../../sandbox/dist/index.js';
4
+ import { ApprovalGate } from './policy.js';
5
+ import { QuotaMeter } from './quota.js';
6
+ import { EnvelopeInbox } from './inbox.js';
7
+ export class OwnerGateway {
8
+ owner;
9
+ contract;
10
+ effectiveIsolationLevel = 'subprocess_restricted';
11
+ /** Set by `execute` from the runner. Undefined until a sandbox task has run. */
12
+ sandboxBoundary;
13
+ capabilities;
14
+ inbox;
15
+ machine;
16
+ approvals;
17
+ quota;
18
+ constructor(owner, contract, policy, revocation) {
19
+ this.owner = owner;
20
+ this.contract = contract;
21
+ if (![contract.manifest.requester.ownerDid, contract.manifest.worker?.ownerDid].includes(owner.did))
22
+ throw new Error('GATEWAY_OWNER_MISMATCH');
23
+ this.inbox = new EnvelopeInbox(owner.did, owner.did === contract.manifest.requester.ownerDid
24
+ ? contract.manifest.worker.ownerDid
25
+ : contract.manifest.requester.ownerDid, contract.manifest.taskId);
26
+ this.machine = new ContractMachine(contract);
27
+ this.capabilities = new CapabilityGuard(revocation);
28
+ this.approvals = new ApprovalGate(owner.did, policy);
29
+ this.quota = new QuotaMeter(contract.manifest.taskId, contract.manifest.budget, owner.did);
30
+ }
31
+ accept(receipt) {
32
+ this.approvals.require(this.contract.manifest.taskId, 'contract_acceptance', this.contract.contractDigest, receipt);
33
+ return this.applyOwn('ACCEPT');
34
+ }
35
+ applyOwn(event) {
36
+ const signed = this.machine.event(event, this.owner);
37
+ this.machine.apply(signed);
38
+ if (['SETTLED', 'CANCELLED'].includes(this.machine.state))
39
+ this.capabilities.revokeTask(this.contract.manifest.taskId);
40
+ return signed;
41
+ }
42
+ transition(event) {
43
+ if (['ACCEPT', 'VERIFY_ACCEPT', 'VERIFY_REJECT', 'SETTLE'].includes(event))
44
+ throw new Error('GATED_TRANSITION_REQUIRED');
45
+ return this.applyOwn(event);
46
+ }
47
+ async verifyAndSettle(envelope, engine, approval, options) {
48
+ if (this.owner.did !== this.contract.manifest.requester.ownerDid ||
49
+ this.machine.state !== 'DELIVERED')
50
+ throw new Error('INVALID_VERIFICATION_STATE');
51
+ const result = await engine.verify(this.contract, envelope, this.approvals, approval, this.owner, options);
52
+ const verification = this.applyOwn(result.event);
53
+ const settlement = result.accepted ? this.applyOwn('SETTLE') : undefined;
54
+ return { result, verification, settlement };
55
+ }
56
+ redelegate(chain, params, receipt) {
57
+ if (this.machine.state !== 'IN_PROGRESS')
58
+ throw new Error('CAPABILITY_VIOLATION: inactive task');
59
+ verifyCapabilityChain(chain, {
60
+ rootDid: this.contract.manifest.requester.ownerDid,
61
+ audience: this.owner.did,
62
+ taskId: this.contract.manifest.taskId,
63
+ });
64
+ this.approvals.require(this.contract.manifest.taskId, 'redelegation', { parentDigest: digest(chain.at(-1)), params }, receipt);
65
+ return createCapability(params, this.owner, chain.at(-1));
66
+ }
67
+ async execute(code, proxy, input) {
68
+ if (this.machine.state !== 'IN_PROGRESS')
69
+ throw new Error('CONTRACT_NOT_RUNNING');
70
+ const policy = this.contract.manifest.sandboxPolicy;
71
+ if (!['subprocess_restricted', 'oci_container'].includes(policy.isolationLevel) ||
72
+ policy.networkAccess !== 'none' ||
73
+ policy.filesystemScope !== 'ephemeral_workspace_only')
74
+ throw new Error('UNSUPPORTED_SANDBOX_POLICY');
75
+ const result = await runContainerOrSubprocessSandbox({
76
+ isolationLevel: policy.isolationLevel,
77
+ code,
78
+ input,
79
+ timeoutMs: this.quota.budget.maxWallClockSeconds * 1000,
80
+ signal: this.quota.controller.signal,
81
+ onTool: (name, args) => proxy.callTool(name, args),
82
+ onUsage: (i, o) => this.quota.record(i, o),
83
+ });
84
+ this.effectiveIsolationLevel = result.effectiveIsolationLevel;
85
+ this.sandboxBoundary = result.sandboxBoundary;
86
+ return result.output;
87
+ }
88
+ close() {
89
+ this.quota.close();
90
+ }
91
+ }
92
+ //# sourceMappingURL=gateway.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway.js","sourceRoot":"","sources":["../src/gateway.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { SignedEnvelope } from '@acp/core';
2
+ /** Gateway-owned replay defense, independent of any relay behavior. */
3
+ export declare class EnvelopeInbox {
4
+ #private;
5
+ readonly recipientDid: string;
6
+ readonly senderDid: string;
7
+ readonly taskId: string;
8
+ constructor(recipientDid: string, senderDid: string, taskId: string);
9
+ receive(envelope: SignedEnvelope): SignedEnvelope;
10
+ }
@@ -0,0 +1,24 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { verifyEnvelope } from '../../core/dist/index.js';
3
+ /** Gateway-owned replay defense, independent of any relay behavior. */
4
+ export class EnvelopeInbox {
5
+ recipientDid;
6
+ senderDid;
7
+ taskId;
8
+ #next = 0;
9
+ constructor(recipientDid, senderDid, taskId) {
10
+ this.recipientDid = recipientDid;
11
+ this.senderDid = senderDid;
12
+ this.taskId = taskId;
13
+ }
14
+ receive(envelope) {
15
+ if (!verifyEnvelope(envelope, this.recipientDid) ||
16
+ envelope.payload.senderDid !== this.senderDid ||
17
+ envelope.payload.taskId !== this.taskId ||
18
+ envelope.payload.seq !== this.#next)
19
+ throw new Error('INVALID_OR_REPLAYED_ENVELOPE');
20
+ this.#next++;
21
+ return structuredClone(envelope);
22
+ }
23
+ }
24
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,uEAAuE;AACvE,MAAM,OAAO,aAAa;IAGb;IACA;IACA;IAJX,KAAK,GAAG,CAAC,CAAC;IACV,YACW,YAAoB,EACpB,SAAiB,EACjB,MAAc;QAFd,iBAAY,GAAZ,YAAY,CAAQ;QACpB,cAAS,GAAT,SAAS,CAAQ;QACjB,WAAM,GAAN,MAAM,CAAQ;IACtB,CAAC;IACJ,OAAO,CAAC,QAAwB;QAC9B,IACE,CAAC,cAAc,CAAC,QAAQ,EAAE,IAAI,CAAC,YAAY,CAAC;YAC5C,QAAQ,CAAC,OAAO,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS;YAC7C,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC,MAAM;YACvC,QAAQ,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,KAAK;YAEnC,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;QAClD,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,eAAe,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ export * from './policy.js';
2
+ export * from './quota.js';
3
+ export * from './mcp.js';
4
+ export * from './mcp-server.js';
5
+ export * from './verifier.js';
6
+ export * from './gateway.js';
7
+ export * from './a2a.js';
8
+ export * from './inbox.js';
9
+ export * from './adapter.js';
10
+ export * from './approval-providers.js';
11
+ export { createSignedAgentCard, verifySignedAgentCard, toA2AAgentCard, createInviteToken, parseAndVerifyInviteToken, } from '@acp/core';
12
+ export * from './session.js';
13
+ export { PeerRejectedError } from './session-audit.js';