sealbridge 0.0.1 → 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.
Files changed (208) hide show
  1. package/NOTICE +43 -0
  2. package/README.ja.md +397 -0
  3. package/README.md +567 -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/approval-summary.d.ts +2 -0
  8. package/dist/cli/dist/approval-summary.js +32 -0
  9. package/dist/cli/dist/approval-summary.js.map +1 -0
  10. package/dist/cli/dist/board.d.ts +47 -0
  11. package/dist/cli/dist/board.js +255 -0
  12. package/dist/cli/dist/board.js.map +1 -0
  13. package/dist/cli/dist/contacts.d.ts +18 -0
  14. package/dist/cli/dist/contacts.js +154 -0
  15. package/dist/cli/dist/contacts.js.map +1 -0
  16. package/dist/cli/dist/doctor.d.ts +13 -0
  17. package/dist/cli/dist/doctor.js +30 -0
  18. package/dist/cli/dist/doctor.js.map +1 -0
  19. package/dist/cli/dist/error-messages.d.ts +2 -0
  20. package/dist/cli/dist/error-messages.js +24 -0
  21. package/dist/cli/dist/error-messages.js.map +1 -0
  22. package/dist/cli/dist/index.d.ts +2 -0
  23. package/dist/cli/dist/index.js +194 -0
  24. package/dist/cli/dist/index.js.map +1 -0
  25. package/dist/cli/dist/invite-share.d.ts +16 -0
  26. package/dist/cli/dist/invite-share.js +163 -0
  27. package/dist/cli/dist/invite-share.js.map +1 -0
  28. package/dist/cli/dist/mcp.d.ts +17 -0
  29. package/dist/cli/dist/mcp.js +105 -0
  30. package/dist/cli/dist/mcp.js.map +1 -0
  31. package/dist/cli/dist/network.d.ts +1 -0
  32. package/dist/cli/dist/network.js +396 -0
  33. package/dist/cli/dist/network.js.map +1 -0
  34. package/dist/cli/dist/public-settings.d.ts +27 -0
  35. package/dist/cli/dist/public-settings.js +33 -0
  36. package/dist/cli/dist/public-settings.js.map +1 -0
  37. package/dist/cli/dist/receipt.d.ts +39 -0
  38. package/dist/cli/dist/receipt.js +90 -0
  39. package/dist/cli/dist/receipt.js.map +1 -0
  40. package/dist/cli/dist/receive-hook.d.ts +2 -0
  41. package/dist/cli/dist/receive-hook.js +35 -0
  42. package/dist/cli/dist/receive-hook.js.map +1 -0
  43. package/dist/cli/dist/task-input.d.ts +2 -0
  44. package/dist/cli/dist/task-input.js +19 -0
  45. package/dist/cli/dist/task-input.js.map +1 -0
  46. package/dist/cli/dist/wake-hook.d.ts +3 -0
  47. package/dist/cli/dist/wake-hook.js +32 -0
  48. package/dist/cli/dist/wake-hook.js.map +1 -0
  49. package/dist/examples/two-owner-demo/alice-policy.json +4 -0
  50. package/dist/examples/two-owner-demo/bob-policy.json +4 -0
  51. package/dist/examples/two-owner-demo/dist/run-demo.d.ts +71 -0
  52. package/dist/examples/two-owner-demo/dist/run-demo.js +383 -0
  53. package/dist/examples/two-owner-demo/dist/run-demo.js.map +1 -0
  54. package/dist/package.json +1 -0
  55. package/dist/packages/adapters/dist/command.d.ts +122 -0
  56. package/dist/packages/adapters/dist/command.js +378 -0
  57. package/dist/packages/adapters/dist/command.js.map +1 -0
  58. package/dist/packages/adapters/dist/credential-proxy.d.ts +37 -0
  59. package/dist/packages/adapters/dist/credential-proxy.js +363 -0
  60. package/dist/packages/adapters/dist/credential-proxy.js.map +1 -0
  61. package/dist/packages/adapters/dist/index.d.ts +6 -0
  62. package/dist/packages/adapters/dist/index.js +6 -0
  63. package/dist/packages/adapters/dist/index.js.map +1 -0
  64. package/dist/packages/adapters/dist/mcp.d.ts +32 -0
  65. package/dist/packages/adapters/dist/mcp.js +87 -0
  66. package/dist/packages/adapters/dist/mcp.js.map +1 -0
  67. package/dist/packages/adapters/dist/openai.d.ts +23 -0
  68. package/dist/packages/adapters/dist/openai.js +81 -0
  69. package/dist/packages/adapters/dist/openai.js.map +1 -0
  70. package/dist/packages/adapters/dist/sandbox.d.ts +45 -0
  71. package/dist/packages/adapters/dist/sandbox.js +60 -0
  72. package/dist/packages/adapters/dist/sandbox.js.map +1 -0
  73. package/dist/packages/core/dist/capability.d.ts +36 -0
  74. package/dist/packages/core/dist/capability.js +203 -0
  75. package/dist/packages/core/dist/capability.js.map +1 -0
  76. package/dist/packages/core/dist/contract.d.ts +33 -0
  77. package/dist/packages/core/dist/contract.js +97 -0
  78. package/dist/packages/core/dist/contract.js.map +1 -0
  79. package/dist/packages/core/dist/crypto.d.ts +34 -0
  80. package/dist/packages/core/dist/crypto.js +329 -0
  81. package/dist/packages/core/dist/crypto.js.map +1 -0
  82. package/dist/packages/core/dist/discovery.d.ts +129 -0
  83. package/dist/packages/core/dist/discovery.js +527 -0
  84. package/dist/packages/core/dist/discovery.js.map +1 -0
  85. package/dist/packages/core/dist/edge.d.ts +4 -0
  86. package/dist/packages/core/dist/edge.js +6 -0
  87. package/dist/packages/core/dist/edge.js.map +1 -0
  88. package/dist/packages/core/dist/index.d.ts +9 -0
  89. package/dist/packages/core/dist/index.js +10 -0
  90. package/dist/packages/core/dist/index.js.map +1 -0
  91. package/dist/packages/core/dist/receipts.d.ts +9 -0
  92. package/dist/packages/core/dist/receipts.js +67 -0
  93. package/dist/packages/core/dist/receipts.js.map +1 -0
  94. package/dist/packages/core/dist/relay-auth.d.ts +40 -0
  95. package/dist/packages/core/dist/relay-auth.js +106 -0
  96. package/dist/packages/core/dist/relay-auth.js.map +1 -0
  97. package/dist/packages/core/dist/revocation.d.ts +58 -0
  98. package/dist/packages/core/dist/revocation.js +112 -0
  99. package/dist/packages/core/dist/revocation.js.map +1 -0
  100. package/dist/packages/core/dist/schema.d.ts +11 -0
  101. package/dist/packages/core/dist/schema.js +48 -0
  102. package/dist/packages/core/dist/schema.js.map +1 -0
  103. package/dist/packages/core/dist/types.d.ts +172 -0
  104. package/dist/packages/core/dist/types.js +2 -0
  105. package/dist/packages/core/dist/types.js.map +1 -0
  106. package/dist/packages/ledger/dist/index.d.ts +84 -0
  107. package/dist/packages/ledger/dist/index.js +269 -0
  108. package/dist/packages/ledger/dist/index.js.map +1 -0
  109. package/dist/packages/relay/dist/fetch.d.ts +250 -0
  110. package/dist/packages/relay/dist/fetch.js +1401 -0
  111. package/dist/packages/relay/dist/fetch.js.map +1 -0
  112. package/dist/packages/relay/dist/index.d.ts +103 -0
  113. package/dist/packages/relay/dist/index.js +855 -0
  114. package/dist/packages/relay/dist/index.js.map +1 -0
  115. package/dist/packages/relay/dist/journal.d.ts +77 -0
  116. package/dist/packages/relay/dist/journal.js +339 -0
  117. package/dist/packages/relay/dist/journal.js.map +1 -0
  118. package/dist/packages/relay/dist/notifications.d.ts +63 -0
  119. package/dist/packages/relay/dist/notifications.js +55 -0
  120. package/dist/packages/relay/dist/notifications.js.map +1 -0
  121. package/dist/packages/relay/dist/retry.d.ts +12 -0
  122. package/dist/packages/relay/dist/retry.js +59 -0
  123. package/dist/packages/relay/dist/retry.js.map +1 -0
  124. package/dist/packages/relay/dist/ssrf.d.ts +32 -0
  125. package/dist/packages/relay/dist/ssrf.js +213 -0
  126. package/dist/packages/relay/dist/ssrf.js.map +1 -0
  127. package/dist/packages/relay/dist/worker.d.ts +92 -0
  128. package/dist/packages/relay/dist/worker.js +460 -0
  129. package/dist/packages/relay/dist/worker.js.map +1 -0
  130. package/dist/packages/runtime/dist/a2a.d.ts +8 -0
  131. package/dist/packages/runtime/dist/a2a.js +69 -0
  132. package/dist/packages/runtime/dist/a2a.js.map +1 -0
  133. package/dist/packages/runtime/dist/adapter.d.ts +51 -0
  134. package/dist/packages/runtime/dist/adapter.js +2 -0
  135. package/dist/packages/runtime/dist/adapter.js.map +1 -0
  136. package/dist/packages/runtime/dist/approval-providers.d.ts +99 -0
  137. package/dist/packages/runtime/dist/approval-providers.js +269 -0
  138. package/dist/packages/runtime/dist/approval-providers.js.map +1 -0
  139. package/dist/packages/runtime/dist/daily-limit.d.ts +2 -0
  140. package/dist/packages/runtime/dist/daily-limit.js +54 -0
  141. package/dist/packages/runtime/dist/daily-limit.js.map +1 -0
  142. package/dist/packages/runtime/dist/gateway.d.ts +35 -0
  143. package/dist/packages/runtime/dist/gateway.js +92 -0
  144. package/dist/packages/runtime/dist/gateway.js.map +1 -0
  145. package/dist/packages/runtime/dist/inbox.d.ts +10 -0
  146. package/dist/packages/runtime/dist/inbox.js +24 -0
  147. package/dist/packages/runtime/dist/inbox.js.map +1 -0
  148. package/dist/packages/runtime/dist/index.d.ts +13 -0
  149. package/dist/packages/runtime/dist/index.js +14 -0
  150. package/dist/packages/runtime/dist/index.js.map +1 -0
  151. package/dist/packages/runtime/dist/mcp-server.d.ts +90 -0
  152. package/dist/packages/runtime/dist/mcp-server.js +647 -0
  153. package/dist/packages/runtime/dist/mcp-server.js.map +1 -0
  154. package/dist/packages/runtime/dist/mcp-tool-catalog.d.ts +3 -0
  155. package/dist/packages/runtime/dist/mcp-tool-catalog.js +507 -0
  156. package/dist/packages/runtime/dist/mcp-tool-catalog.js.map +1 -0
  157. package/dist/packages/runtime/dist/mcp.d.ts +73 -0
  158. package/dist/packages/runtime/dist/mcp.js +67 -0
  159. package/dist/packages/runtime/dist/mcp.js.map +1 -0
  160. package/dist/packages/runtime/dist/policy.d.ts +19 -0
  161. package/dist/packages/runtime/dist/policy.js +41 -0
  162. package/dist/packages/runtime/dist/policy.js.map +1 -0
  163. package/dist/packages/runtime/dist/quota.d.ts +39 -0
  164. package/dist/packages/runtime/dist/quota.js +147 -0
  165. package/dist/packages/runtime/dist/quota.js.map +1 -0
  166. package/dist/packages/runtime/dist/session-audit.d.ts +107 -0
  167. package/dist/packages/runtime/dist/session-audit.js +520 -0
  168. package/dist/packages/runtime/dist/session-audit.js.map +1 -0
  169. package/dist/packages/runtime/dist/session-timeouts.d.ts +33 -0
  170. package/dist/packages/runtime/dist/session-timeouts.js +62 -0
  171. package/dist/packages/runtime/dist/session-timeouts.js.map +1 -0
  172. package/dist/packages/runtime/dist/session.d.ts +323 -0
  173. package/dist/packages/runtime/dist/session.js +2252 -0
  174. package/dist/packages/runtime/dist/session.js.map +1 -0
  175. package/dist/packages/runtime/dist/task-journal.d.ts +36 -0
  176. package/dist/packages/runtime/dist/task-journal.js +104 -0
  177. package/dist/packages/runtime/dist/task-journal.js.map +1 -0
  178. package/dist/packages/runtime/dist/verifier.d.ts +64 -0
  179. package/dist/packages/runtime/dist/verifier.js +109 -0
  180. package/dist/packages/runtime/dist/verifier.js.map +1 -0
  181. package/dist/packages/sandbox/dist/container.d.ts +33 -0
  182. package/dist/packages/sandbox/dist/container.js +189 -0
  183. package/dist/packages/sandbox/dist/container.js.map +1 -0
  184. package/dist/packages/sandbox/dist/index.d.ts +34 -0
  185. package/dist/packages/sandbox/dist/index.js +179 -0
  186. package/dist/packages/sandbox/dist/index.js.map +1 -0
  187. package/dist/packages/sandbox/dist/permission.d.ts +58 -0
  188. package/dist/packages/sandbox/dist/permission.js +90 -0
  189. package/dist/packages/sandbox/dist/permission.js.map +1 -0
  190. package/dist/spec/README.ja.md +76 -0
  191. package/dist/spec/README.md +135 -0
  192. package/dist/spec/ack-receipt.schema.json +77 -0
  193. package/dist/spec/agent-card.schema.json +83 -0
  194. package/dist/spec/approval-receipt.schema.json +94 -0
  195. package/dist/spec/audit-entry.schema.json +101 -0
  196. package/dist/spec/capability-token.schema.json +133 -0
  197. package/dist/spec/envelope.schema.json +197 -0
  198. package/dist/spec/examples/sample-ack-receipt.json +16 -0
  199. package/dist/spec/examples/sample-agent-card.json +35 -0
  200. package/dist/spec/examples/sample-approval-receipt.json +18 -0
  201. package/dist/spec/examples/sample-audit-entry.json +37 -0
  202. package/dist/spec/examples/sample-capability-token.json +39 -0
  203. package/dist/spec/examples/sample-envelope.json +21 -0
  204. package/dist/spec/examples/sample-task-manifest.json +141 -0
  205. package/dist/spec/examples/sample-usage-receipt.json +19 -0
  206. package/dist/spec/task-manifest.schema.json +422 -0
  207. package/dist/spec/usage-receipt.schema.json +91 -0
  208. package/package.json +61 -5
@@ -0,0 +1,32 @@
1
+ function record(value) {
2
+ return value && typeof value === 'object' && !Array.isArray(value)
3
+ ? value : {};
4
+ }
5
+ // Remote text should not be able to control the terminal displaying an approval.
6
+ function display(value) {
7
+ return (typeof value === 'string' ? value : JSON.stringify(value, null, 2) ?? 'unknown')
8
+ .replace(/[\x00-\x08\x0b-\x1f\x7f-\x9f]/g, '');
9
+ }
10
+ export function approvalSummary(request) {
11
+ const details = record(request.details), manifest = record(details.manifest);
12
+ const lines = [`Approval: ${request.gate}`, `Task: ${request.taskId}`];
13
+ if (request.gate === 'contract_acceptance') {
14
+ const budget = record(manifest.budget), input = details.input;
15
+ const diff = record(input).diff;
16
+ const size = typeof diff === 'string'
17
+ ? `${diff === '' ? 0 : diff.split('\n').length - (diff.endsWith('\n') ? 1 : 0)} diff lines, ${Buffer.byteLength(diff)} bytes`
18
+ : `${Buffer.byteLength(JSON.stringify(input) ?? '')} bytes (JSON)`;
19
+ lines.push(`From: ${display(record(manifest.requester).ownerDid ?? details.from)}`, `Title: ${display(record(manifest.task).title)}`, `Input: ${size}`, `Time limit: ${display(budget.maxWallClockSeconds)} seconds`, `Budget: input ${display(budget.maxInputTokens)} tokens; output ${display(budget.maxOutputTokens)} tokens; tools ${display(budget.maxToolInvocations)}`);
20
+ }
21
+ else if (request.gate === 'final_verification') {
22
+ const data = record(record(record(request.target).artifact).payload).data;
23
+ lines.push('Review result:', display(data));
24
+ }
25
+ else {
26
+ // Side effects and budget changes still display the full action being approved.
27
+ lines.push('Action:', display(request.target), 'Details:', display(request.details));
28
+ }
29
+ lines.push('Use --verbose when starting this command to display full approval details.');
30
+ return lines.join('\n');
31
+ }
32
+ //# sourceMappingURL=approval-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval-summary.js","sourceRoot":"","sources":["../src/approval-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import type { Json, KeyPair, OpenPolicy, Signed, SignedAgentCard } from '@acp/core';
2
+ import type { AgentAdapter, ApprovalProvider } from '@acp/runtime';
3
+ export interface BoardPost {
4
+ type: 'BoardPost';
5
+ id: string;
6
+ ownerDid: string;
7
+ relay: string;
8
+ what: string;
9
+ skillId: string;
10
+ taskType: string;
11
+ budget: Required<OpenPolicy>;
12
+ inputDigest: string;
13
+ createdAt: string;
14
+ deadline: string;
15
+ }
16
+ export interface BoardLease {
17
+ type: 'BoardLease';
18
+ postId: string;
19
+ postDigest: string;
20
+ ownerDid: string;
21
+ workerDid: string;
22
+ agentDid: string;
23
+ claimTaskId: string;
24
+ nonce: string;
25
+ expiresAt: string;
26
+ accepted: boolean;
27
+ consumed: boolean;
28
+ }
29
+ export declare function verifyPost(value: Signed<BoardPost>, now?: number): BoardPost;
30
+ export declare function createPost(key: KeyPair, fields: Omit<BoardPost, 'type' | 'id' | 'ownerDid' | 'createdAt' | 'inputDigest'>, input: Json): Signed<BoardPost>;
31
+ export declare function candidateFit(post: Signed<BoardPost>, card: SignedAgentCard): string[];
32
+ export declare function boardCandidates(post: Signed<BoardPost>, raw: unknown): {
33
+ name: string;
34
+ did: string;
35
+ taskTypes: string[];
36
+ limits: Partial<Pick<import("@acp/core").BudgetSpec, "maxInputTokens" | "maxOutputTokens" | "maxToolInvocations" | "maxWallClockSeconds">>;
37
+ reasons: string[];
38
+ card: SignedAgentCard;
39
+ }[];
40
+ export declare function claimPost(path: string, key: KeyPair, post: Signed<BoardPost>, card: SignedAgentCard, senderDid: string, claimTaskId: string, now?: number): BoardLease;
41
+ export declare function consumeLease(path: string, key: KeyPair, post: Signed<BoardPost>, input: Json, now?: number): BoardLease;
42
+ /** Metadata claim is a normal encrypted ACP job; the real input is a later job. */
43
+ export declare function boardHost(post: Signed<BoardPost>, key: KeyPair, path: string, interactive: ApprovalProvider): {
44
+ adapter: AgentAdapter;
45
+ approvalProvider: ApprovalProvider;
46
+ };
47
+ export declare function boardCommand(args: string[]): Promise<void>;
@@ -0,0 +1,255 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { mkdirSync, readFileSync, writeFileSync, renameSync, unlinkSync, readdirSync } from 'node:fs';
3
+ import { dirname, join } from 'node:path';
4
+ import { randomUUID } from 'node:crypto';
5
+ import { digest, signPayload, verifySigned, verifySignedAgentCard, validateRelayEndpointUrl, discoverAgentCards, OPEN_POLICY_FIELDS } from '../../packages/core/dist/index.js';
6
+ import { WorkerNode, RequesterClient, InteractiveCliApprovalProvider, buildTaskManifest } from '../../packages/runtime/dist/index.js';
7
+ import { HttpRelayClient } from '../../packages/relay/dist/index.js';
8
+ function exactKeys(value, keys) {
9
+ return Object.keys(value).sort().join(',') === keys.sort().join(',');
10
+ }
11
+ export function verifyPost(value, now = Date.now()) {
12
+ try {
13
+ const p = value.payload;
14
+ if (!verifySigned(value, p.ownerDid) || p.type !== 'BoardPost' ||
15
+ !exactKeys(p, ['type', 'id', 'ownerDid', 'relay', 'what', 'skillId', 'taskType', 'budget', 'inputDigest', 'createdAt', 'deadline']) ||
16
+ !/^[a-f0-9-]{36}$/.test(p.id) || !/^sha256:[a-f0-9]{64}$/.test(p.inputDigest) ||
17
+ [p.what, p.skillId, p.taskType].some(s => typeof s !== 'string' || !s || s.length > 240 || /[\x00-\x1f\x7f]/.test(s)) ||
18
+ !Number.isFinite(Date.parse(p.createdAt)) || Date.parse(p.createdAt) > now + 60000 ||
19
+ !Number.isFinite(Date.parse(p.deadline)) || Date.parse(p.deadline) <= now || Date.parse(p.deadline) <= Date.parse(p.createdAt) ||
20
+ !exactKeys(p.budget, [...OPEN_POLICY_FIELDS]) ||
21
+ OPEN_POLICY_FIELDS.some(f => !Number.isSafeInteger(p.budget[f]) || p.budget[f] < 1))
22
+ throw new Error();
23
+ validateRelayEndpointUrl(p.relay);
24
+ return p;
25
+ }
26
+ catch {
27
+ throw new Error('INVALID_BOARD_POST');
28
+ }
29
+ }
30
+ export function createPost(key, fields, input) {
31
+ const post = signPayload({ ...fields, type: 'BoardPost', id: randomUUID(), ownerDid: key.did,
32
+ createdAt: new Date().toISOString(), inputDigest: digest(input) }, key);
33
+ verifyPost(post);
34
+ return post;
35
+ }
36
+ export function candidateFit(post, card) {
37
+ const p = verifyPost(post);
38
+ if (!verifySignedAgentCard(card))
39
+ return ['Invalid or expired public profile'];
40
+ const c = card.payload, reasons = [];
41
+ if (c.accessMode !== 'open')
42
+ reasons.push('Invite only');
43
+ if (c.relayEndpoint !== p.relay)
44
+ reasons.push('Different relay');
45
+ if (!c.skills.some(s => s.id === p.skillId && s.taskTypes?.includes(p.taskType)))
46
+ reasons.push('Job type is not accepted');
47
+ for (const f of OPEN_POLICY_FIELDS)
48
+ if (c.openPolicy?.[f] !== undefined && p.budget[f] > c.openPolicy[f])
49
+ reasons.push(f + ': job asks for ' + p.budget[f] + ', worker allows ' + c.openPolicy[f]);
50
+ return reasons;
51
+ }
52
+ export function boardCandidates(post, raw) {
53
+ return discoverAgentCards(raw).map(card => ({ name: card.payload.name, did: card.payload.agentDid,
54
+ taskTypes: card.payload.skills.flatMap(s => s.taskTypes ?? []), limits: card.payload.openPolicy ?? {},
55
+ reasons: candidateFit(post, card), card })).sort((a, b) => a.reasons.length - b.reasons.length ||
56
+ Date.parse(b.card.signature.signedAt) - Date.parse(a.card.signature.signedAt));
57
+ }
58
+ function mutateLease(path, key, change) {
59
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
60
+ const lock = path + '.lock', temp = path + '.' + randomUUID() + '.tmp';
61
+ try {
62
+ writeFileSync(lock, '', { flag: 'wx', mode: 0o600 });
63
+ }
64
+ catch {
65
+ throw new Error('CLAIM_LOST');
66
+ }
67
+ try {
68
+ let old;
69
+ try {
70
+ const signed = JSON.parse(readFileSync(path, 'utf8'));
71
+ if (!verifySigned(signed, key.did) || signed.payload.ownerDid !== key.did || signed.payload.type !== 'BoardLease')
72
+ throw new Error('INVALID_LEASE');
73
+ old = signed.payload;
74
+ }
75
+ catch (e) {
76
+ if (e.code !== 'ENOENT')
77
+ throw e;
78
+ }
79
+ const { lease, result } = change(old);
80
+ writeFileSync(temp, JSON.stringify(signPayload(lease, key)), { flag: 'wx', mode: 0o600, flush: true });
81
+ renameSync(temp, path);
82
+ return result;
83
+ }
84
+ finally {
85
+ try {
86
+ unlinkSync(temp);
87
+ }
88
+ catch (e) {
89
+ if (e.code !== 'ENOENT')
90
+ throw e;
91
+ }
92
+ unlinkSync(lock);
93
+ }
94
+ }
95
+ export function claimPost(path, key, post, card, senderDid, claimTaskId, now = Date.now()) {
96
+ const p = verifyPost(post, now);
97
+ if (p.ownerDid !== key.did || card.payload.ownerDid !== senderDid || candidateFit(post, card).length)
98
+ throw new Error('INVALID_BOARD_CLAIM');
99
+ return mutateLease(path, key, old => {
100
+ if (old && (old.postId !== p.id || old.consumed || Date.parse(old.expiresAt) > now))
101
+ throw new Error('CLAIM_LOST');
102
+ const lease = { type: 'BoardLease', postId: p.id, postDigest: digest(post), ownerDid: key.did,
103
+ workerDid: senderDid, agentDid: card.payload.agentDid, claimTaskId, nonce: randomUUID(),
104
+ expiresAt: new Date(Math.min(now + 300000, Date.parse(p.deadline))).toISOString(), accepted: false, consumed: false };
105
+ return { lease, result: lease };
106
+ });
107
+ }
108
+ export function consumeLease(path, key, post, input, now = Date.now()) {
109
+ const p = verifyPost(post, now);
110
+ if (p.ownerDid !== key.did || digest(input) !== p.inputDigest)
111
+ throw new Error('INVALID_BOARD_INPUT');
112
+ return mutateLease(path, key, old => {
113
+ if (!old || !old.accepted || old.postId !== p.id || old.postDigest !== digest(post) || old.consumed || Date.parse(old.expiresAt) <= now)
114
+ throw new Error('CLAIM_LOST');
115
+ const lease = { ...old, consumed: true };
116
+ return { lease, result: lease };
117
+ });
118
+ }
119
+ /** Metadata claim is a normal encrypted ACP job; the real input is a later job. */
120
+ export function boardHost(post, key, path, interactive) {
121
+ const p = verifyPost(post);
122
+ if (p.ownerDid !== key.did)
123
+ throw new Error('INVALID_BOARD_OWNER');
124
+ const approved = new Map();
125
+ const approvalProvider = { async approve(request) {
126
+ if (request.gate !== 'contract_acceptance')
127
+ return interactive.approve(request);
128
+ const details = request.details;
129
+ let claim;
130
+ try {
131
+ claim = JSON.parse(details.manifest.task.description);
132
+ }
133
+ catch {
134
+ throw new Error('INVALID_BOARD_CLAIM');
135
+ }
136
+ if (claim.postId !== p.id)
137
+ throw new Error('INVALID_BOARD_CLAIM');
138
+ const lease = claimPost(path, key, post, claim.card, details.from, request.taskId);
139
+ const receipt = await interactive.approve(request);
140
+ if (Date.parse(lease.expiresAt) <= Date.now())
141
+ throw new Error('CLAIM_LOST');
142
+ approved.set(request.taskId, lease);
143
+ return receipt;
144
+ } };
145
+ const adapter = { id: 'board-claims', name: 'Job board claims',
146
+ skills: [{ id: 'board-claim', name: 'Claim a posted job', taskTypes: ['board-claim'] }],
147
+ async executeTask(context) {
148
+ const lease = approved.get(context.taskId);
149
+ approved.delete(context.taskId);
150
+ if (!lease)
151
+ throw new Error('INVALID_BOARD_CLAIM');
152
+ const accepted = mutateLease(path, key, old => {
153
+ if (!old || old.nonce !== lease.nonce || old.consumed || Date.parse(old.expiresAt) <= Date.now())
154
+ throw new Error('CLAIM_LOST');
155
+ const updated = { ...old, accepted: true };
156
+ return { lease: updated, result: updated };
157
+ });
158
+ return JSON.parse(JSON.stringify(signPayload(accepted, key)));
159
+ },
160
+ };
161
+ return { adapter, approvalProvider };
162
+ }
163
+ export async function boardCommand(args) {
164
+ const [action, ...rest] = args;
165
+ const f = new Map();
166
+ const allowed = ['--key', '--post', '--dir', '--input-file', '--what', '--skill', '--task-type', '--deadline', '--relay',
167
+ '--max-input-tokens', '--max-output-tokens', '--max-tool-calls', '--max-wall-seconds', '--card', '--state', '--out', '--audit'];
168
+ for (let i = 0; i < rest.length; i += 2) {
169
+ if (!allowed.includes(rest[i]) || f.has(rest[i]) || !rest[i + 1] || rest[i + 1].startsWith('--'))
170
+ throw new Error('INVALID_BOARD_OPTION: owner approval cannot be bypassed');
171
+ f.set(rest[i], rest[i + 1]);
172
+ }
173
+ const need = (n) => { const v = f.get('--' + n); if (!v)
174
+ throw new Error('Missing --' + n); return v; };
175
+ const read = (n) => JSON.parse(readFileSync(need(n), 'utf8'));
176
+ const save = (n, v) => writeFileSync(need(n), JSON.stringify(v, null, 2), { flag: 'wx', mode: 0o600 });
177
+ if (action === 'list') {
178
+ const dir = need('dir');
179
+ let skipped = 0;
180
+ const posts = readdirSync(dir).filter(n => n.endsWith('.json')).flatMap(n => {
181
+ try {
182
+ const signed = JSON.parse(readFileSync(join(dir, n), 'utf8'));
183
+ return [verifyPost(signed)];
184
+ }
185
+ catch {
186
+ skipped++;
187
+ return [];
188
+ }
189
+ });
190
+ if (skipped)
191
+ console.warn(`${skipped} invalid job${skipped === 1 ? '' : 's'} skipped`);
192
+ console.log(JSON.stringify(posts));
193
+ return;
194
+ }
195
+ if (action === 'post') {
196
+ const key = read('key');
197
+ const post = createPost(key, { relay: need('relay'), what: need('what'), skillId: need('skill'), taskType: need('task-type'),
198
+ deadline: need('deadline'), budget: { maxInputTokens: Number(need('max-input-tokens')),
199
+ maxOutputTokens: Number(need('max-output-tokens')), maxToolInvocations: Number(need('max-tool-calls')),
200
+ maxWallClockSeconds: Number(need('max-wall-seconds')) } }, read('input-file'));
201
+ save('out', post);
202
+ console.log(JSON.stringify({ postId: post.payload.id, saved: true }));
203
+ return;
204
+ }
205
+ const post = read('post'), p = verifyPost(post);
206
+ if (action === 'candidates') {
207
+ console.log(JSON.stringify(boardCandidates(post, await new HttpRelayClient(p.relay).discover())));
208
+ return;
209
+ }
210
+ const key = read('key');
211
+ const approval = new InteractiveCliApprovalProvider(key);
212
+ if (action === 'serve') {
213
+ const host = boardHost(post, key, need('state'), approval);
214
+ const worker = new WorkerNode({ owner: key, relay: p.relay, relayUrl: p.relay, accessMode: 'open',
215
+ ...host, auditPath: need('audit'), maxConcurrentTasks: 8, maxTasksPerRequesterPerMinute: 5 });
216
+ await worker.register();
217
+ console.log('Waiting for claims. Owner approval is required; no task input is published.');
218
+ const stop = () => worker.stop();
219
+ process.once('SIGINT', stop);
220
+ process.once('SIGTERM', stop);
221
+ try {
222
+ await worker.start();
223
+ }
224
+ finally {
225
+ process.removeListener('SIGINT', stop);
226
+ process.removeListener('SIGTERM', stop);
227
+ }
228
+ }
229
+ else if (action === 'claim') {
230
+ const card = read('card');
231
+ if (card.payload.ownerDid !== key.did || candidateFit(post, card).length)
232
+ throw new Error('INVALID_BOARD_CLAIM');
233
+ const claim = { postId: p.id, card };
234
+ const client = new RequesterClient({ owner: key, relay: p.relay, approvalProvider: approval, auditPath: need('audit') });
235
+ const result = await client.delegate({ to: p.ownerDid, discover: { skillId: 'board-claim', taskType: 'board-claim' },
236
+ title: 'Claim job ' + p.id, description: JSON.stringify(claim), input: { postId: p.id } });
237
+ save('out', result.deliverable);
238
+ console.log(JSON.stringify({ state: result.state, taskId: result.taskId }));
239
+ }
240
+ else if (action === 'dispatch') {
241
+ const input = read('input-file');
242
+ // Consume before transmission. Ambiguous network failures must never trigger a second dispatch.
243
+ const lease = consumeLease(need('state'), key, post, input);
244
+ const manifest = buildTaskManifest({ ownerDid: key.did, workerDid: lease.workerDid, agentDid: lease.agentDid,
245
+ title: p.what, description: 'Job board entry ' + p.id, budget: p.budget, skillId: p.skillId, taskType: p.taskType });
246
+ manifest.deadline = p.deadline;
247
+ const client = new RequesterClient({ owner: key, relay: p.relay, approvalProvider: approval, auditPath: need('audit') });
248
+ const result = await client.delegate({ to: lease.agentDid, title: p.what, description: manifest.task.description, input, manifest });
249
+ save('out', result.deliverable);
250
+ console.log(JSON.stringify({ state: result.state, taskId: result.taskId }));
251
+ }
252
+ else
253
+ throw new Error('INVALID_BOARD_ACTION');
254
+ }
255
+ //# sourceMappingURL=board.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"board.js","sourceRoot":"","sources":["../src/board.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { KeyPair } from '@acp/core';
2
+ import type { ApprovalProvider, WorkerAcceptancePolicy } from '@acp/runtime';
3
+ export interface Contact {
4
+ displayName: string;
5
+ ownerDid: string;
6
+ agentDid: string;
7
+ relay: string;
8
+ verifiedAt: string;
9
+ allow: boolean;
10
+ revoked: boolean;
11
+ saved: boolean;
12
+ }
13
+ export declare function contactsPath(): string;
14
+ export declare function loadContacts(path: string, ownerDid: string): Contact[];
15
+ export declare function updateContacts(path: string, key: KeyPair, change: (contacts: Contact[]) => void): Contact[];
16
+ export declare function addContact(path: string, key: KeyPair, token: string, name?: string, allowPrivateRelay?: boolean): Contact[];
17
+ export declare function contactsApproval(path: string, key: KeyPair, automatic: boolean, base: WorkerAcceptancePolicy, interactive: ApprovalProvider): ApprovalProvider;
18
+ export declare function contactsCommand(args: string[]): void;
@@ -0,0 +1,154 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ import { readFileSync, writeFileSync, mkdirSync, renameSync, unlinkSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join } from 'node:path';
5
+ import { randomUUID } from 'node:crypto';
6
+ import { parseAndVerifyInviteToken, signPayload, verifySigned } from '../../packages/core/dist/index.js';
7
+ import { PolicyAutoApprovalProvider } from '../../packages/runtime/dist/index.js';
8
+ export function contactsPath() {
9
+ const base = process.env.ACP_DATA_DIR ?? (process.platform === 'win32'
10
+ ? join(process.env.LOCALAPPDATA ?? homedir(), 'AgentCollaborationPlatform')
11
+ : process.platform === 'darwin' ? join(homedir(), 'Library', 'Application Support', 'AgentCollaborationPlatform')
12
+ : join(process.env.XDG_DATA_HOME ?? join(homedir(), '.local', 'share'), 'agent-collab-platform'));
13
+ return join(base, 'contacts.json');
14
+ }
15
+ export function loadContacts(path, ownerDid) {
16
+ let raw;
17
+ try {
18
+ raw = readFileSync(path, 'utf8');
19
+ }
20
+ catch (error) {
21
+ if (error.code === 'ENOENT')
22
+ return [];
23
+ throw error;
24
+ }
25
+ try {
26
+ const signed = JSON.parse(raw);
27
+ const p = signed.payload;
28
+ if (!verifySigned(signed, ownerDid) || p.version !== 1 || p.ownerDid !== ownerDid || !Array.isArray(p.contacts))
29
+ throw new Error();
30
+ const seen = new Set();
31
+ for (const c of p.contacts) {
32
+ if (!c || typeof c.displayName !== 'string' || c.displayName.length > 200 ||
33
+ !c.ownerDid.startsWith('did:key:') || !c.agentDid.startsWith('did:key:') ||
34
+ typeof c.relay !== 'string' || !Number.isFinite(Date.parse(c.verifiedAt)) ||
35
+ typeof c.allow !== 'boolean' || typeof c.revoked !== 'boolean' || typeof c.saved !== 'boolean' ||
36
+ (c.allow && (c.revoked || !c.saved)) || seen.has(c.ownerDid))
37
+ throw new Error();
38
+ seen.add(c.ownerDid);
39
+ }
40
+ return p.contacts;
41
+ }
42
+ catch {
43
+ throw new Error('CONTACTS_INVALID: signature, owner or schema mismatch');
44
+ }
45
+ }
46
+ export function updateContacts(path, key, change) {
47
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
48
+ // Exclusive lock prevents concurrent read-modify-write updates from losing revocations.
49
+ const lock = path + '.lock';
50
+ writeFileSync(lock, '', { flag: 'wx', mode: 0o600 });
51
+ const temporary = path + '.' + randomUUID() + '.tmp';
52
+ try {
53
+ const contacts = loadContacts(path, key.did);
54
+ change(contacts);
55
+ const signed = signPayload({ version: 1, ownerDid: key.did, contacts }, key);
56
+ writeFileSync(temporary, JSON.stringify(signed, null, 2) + '\n', { flag: 'wx', mode: 0o600 });
57
+ renameSync(temporary, path);
58
+ return contacts;
59
+ }
60
+ finally {
61
+ try {
62
+ unlinkSync(temporary);
63
+ }
64
+ catch (e) {
65
+ if (e.code !== 'ENOENT')
66
+ throw e;
67
+ }
68
+ unlinkSync(lock);
69
+ }
70
+ }
71
+ export function addContact(path, key, token, name, allowPrivateRelay = false) {
72
+ const invite = parseAndVerifyInviteToken(token, Date.now(), { allowPrivateRelay });
73
+ const displayName = name ?? invite.agentCard.payload.name;
74
+ if (!displayName || displayName.length > 200 || /[\x00-\x1f\x7f]/.test(displayName))
75
+ throw new Error('INVALID_CONTACT_NAME');
76
+ return updateContacts(path, key, (contacts) => {
77
+ const old = contacts.find(c => c.ownerDid === invite.ownerDid);
78
+ const contact = { displayName, ownerDid: invite.ownerDid, agentDid: invite.agentDid,
79
+ relay: invite.relayUrl, verifiedAt: new Date().toISOString(), allow: old?.allow ?? false, revoked: old?.revoked ?? false, saved: true };
80
+ if (old)
81
+ Object.assign(old, contact);
82
+ else
83
+ contacts.push(contact);
84
+ });
85
+ }
86
+ export function contactsApproval(path, key, automatic, base, interactive) {
87
+ return { async approve(request) {
88
+ const contacts = loadContacts(path, key.did);
89
+ {
90
+ const details = request.details;
91
+ const did = details?.manifest?.requester?.ownerDid;
92
+ const contact = contacts.find(c => c.ownerDid === did);
93
+ if (contact?.revoked)
94
+ throw new Error('CONTACT_REVOKED');
95
+ if (automatic && request.gate === 'contract_acceptance' && contact && !contact.allow)
96
+ throw new Error('CONTACT_NOT_ALLOWED');
97
+ }
98
+ const acceptance = { ...base, allowedRequesterDids: [...new Set([
99
+ ...(base.allowedRequesterDids ?? []), ...contacts.filter(c => c.allow && !c.revoked).map(c => c.ownerDid),
100
+ ])] };
101
+ return (automatic ? new PolicyAutoApprovalProvider(key, undefined, { acceptance }) : interactive).approve(request);
102
+ } };
103
+ }
104
+ export function contactsCommand(args) {
105
+ const [action, ...rest] = args;
106
+ const options = new Map();
107
+ const positional = [];
108
+ for (let i = 0; i < rest.length; i++) {
109
+ if (!rest[i].startsWith('--')) {
110
+ positional.push(rest[i]);
111
+ continue;
112
+ }
113
+ const flag = rest[i];
114
+ if (!['--key', '--file', '--name', '--allow-private-relay'].includes(flag) || options.has(flag))
115
+ throw new Error('INVALID_CONTACT_OPTION');
116
+ if (flag === '--allow-private-relay') {
117
+ options.set(flag, 'true');
118
+ continue;
119
+ }
120
+ const value = rest[++i];
121
+ if (!value || value.startsWith('--'))
122
+ throw new Error('MISSING_CONTACT_OPTION');
123
+ options.set(flag, value);
124
+ }
125
+ if (!['list', 'add', 'allow', 'revoke', 'remove'].includes(action) || positional.length !== (action === 'list' ? 0 : 1) || !options.has('--key'))
126
+ throw new Error('Usage: sealbridge contacts list|add <invite>|allow <ownerDid>|revoke <ownerDid>|remove <ownerDid> --key <key> [--file <contacts.json>] [--name <name>]');
127
+ const key = JSON.parse(readFileSync(options.get('--key'), 'utf8'));
128
+ const path = options.get('--file') ?? contactsPath();
129
+ let contacts;
130
+ if (action === 'list')
131
+ contacts = loadContacts(path, key.did);
132
+ else if (action === 'add')
133
+ contacts = addContact(path, key, positional[0], options.get('--name'), options.has('--allow-private-relay'));
134
+ else
135
+ contacts = updateContacts(path, key, (items) => {
136
+ const index = items.findIndex(c => c.ownerDid === positional[0]);
137
+ if (index < 0)
138
+ throw new Error('CONTACT_NOT_FOUND');
139
+ if (action === 'remove') {
140
+ items[index].saved = false;
141
+ items[index].displayName = '';
142
+ items[index].allow = false;
143
+ items[index].revoked = true;
144
+ }
145
+ else {
146
+ if (action === 'allow' && !items[index].saved)
147
+ throw new Error('CONTACT_NOT_SAVED');
148
+ items[index].allow = action === 'allow';
149
+ items[index].revoked = action === 'revoke';
150
+ }
151
+ });
152
+ console.log(JSON.stringify({ version: 1, contacts: contacts.filter(c => c.saved) }));
153
+ }
154
+ //# sourceMappingURL=contacts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contacts.js","sourceRoot":"","sources":["../src/contacts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface DoctorOptions {
2
+ version?: string;
3
+ path?: string;
4
+ home?: string;
5
+ exists?: (path: string) => boolean;
6
+ fetch?: typeof fetch;
7
+ }
8
+ export declare function diagnose(options?: DoctorOptions): Promise<{
9
+ name: string;
10
+ ok: boolean;
11
+ message: string;
12
+ }[]>;
13
+ export declare function doctorCommand(): Promise<void>;
@@ -0,0 +1,30 @@
1
+ import { existsSync } from 'node:fs';
2
+ import { delimiter, join } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ export async function diagnose(options = {}) {
5
+ const exists = options.exists ?? existsSync;
6
+ const version = options.version ?? process.versions.node;
7
+ const paths = (options.path ?? process.env.PATH ?? '').split(delimiter);
8
+ const key = join(options.home ?? homedir(), '.acp', 'worker.private.json');
9
+ const checks = [
10
+ { name: 'Node.js', ok: Number(version.split('.')[0]) >= 22, message: `Node ${version}. Node 22 or newer is required; rerun the installer to update.` },
11
+ { name: 'PATH', ok: paths.some(p => exists(join(p, process.platform === 'win32' ? 'sealbridge.cmd' : 'sealbridge'))), message: 'If sealbridge is not found, reopen your terminal or add the installer bin directory to PATH.' },
12
+ { name: 'Keys', ok: true, message: exists(key) ? `Key file exists at ${key}; contents were not read.` : `No worker key at ${key}. Before receiving tasks, run: sealbridge keygen "${key}" (create the .acp directory first). Existing keys elsewhere can be used with --key.` },
13
+ ];
14
+ try {
15
+ const response = await (options.fetch ?? fetch)('https://relay.sealbridge.dev/health', { signal: AbortSignal.timeout(8000), redirect: 'error' });
16
+ checks.push({ name: 'Relay', ok: response.ok, message: response.ok ? 'https://relay.sealbridge.dev is reachable.' : `Relay returned HTTP ${response.status}. Check your connection and try again.` });
17
+ }
18
+ catch {
19
+ checks.push({ name: 'Relay', ok: false, message: 'Cannot reach https://relay.sealbridge.dev. Check internet, proxy or firewall settings, then run sealbridge doctor again.' });
20
+ }
21
+ return checks;
22
+ }
23
+ export async function doctorCommand() {
24
+ const checks = await diagnose();
25
+ for (const check of checks)
26
+ console.log(`${check.ok ? 'OK' : 'WARN'} ${check.name}: ${check.message}`);
27
+ if (checks.some(check => !check.ok))
28
+ process.exitCode = 1;
29
+ }
30
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAQlC,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,UAAyB,EAAE;IACxD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC;IAC5C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC;IACzD,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IACxE,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,OAAO,EAAE,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAC3E,MAAM,MAAM,GAAG;QACb,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,QAAQ,OAAO,gEAAgE,EAAE;QACtJ,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,8FAA8F,EAAE;QAC/N,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,sBAAsB,GAAG,2BAA2B,CAAC,CAAC,CAAC,oBAAoB,GAAG,qDAAqD,GAAG,sFAAsF,EAAE;KAChR,CAAC;IACF,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,CAAC,qCAAqC,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;QACjJ,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,4CAA4C,CAAC,CAAC,CAAC,uBAAuB,QAAQ,CAAC,MAAM,wCAAwC,EAAE,CAAC,CAAC;IACxM,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,0HAA0H,EAAE,CAAC,CAAC;IACjL,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,MAAM,MAAM,GAAG,MAAM,QAAQ,EAAE,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACvG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAAE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare function japaneseErrorReason(message: string): string | undefined;
2
+ export declare function formatCliError(error: unknown): string;