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.
- package/NOTICE +43 -0
- package/README.ja.md +397 -0
- package/README.md +567 -1
- package/dist/cli/dist/acp.d.ts +2 -0
- package/dist/cli/dist/acp.js +6 -0
- package/dist/cli/dist/acp.js.map +1 -0
- package/dist/cli/dist/approval-summary.d.ts +2 -0
- package/dist/cli/dist/approval-summary.js +32 -0
- package/dist/cli/dist/approval-summary.js.map +1 -0
- package/dist/cli/dist/board.d.ts +47 -0
- package/dist/cli/dist/board.js +255 -0
- package/dist/cli/dist/board.js.map +1 -0
- package/dist/cli/dist/contacts.d.ts +18 -0
- package/dist/cli/dist/contacts.js +154 -0
- package/dist/cli/dist/contacts.js.map +1 -0
- package/dist/cli/dist/doctor.d.ts +13 -0
- package/dist/cli/dist/doctor.js +30 -0
- package/dist/cli/dist/doctor.js.map +1 -0
- package/dist/cli/dist/error-messages.d.ts +2 -0
- package/dist/cli/dist/error-messages.js +24 -0
- package/dist/cli/dist/error-messages.js.map +1 -0
- package/dist/cli/dist/index.d.ts +2 -0
- package/dist/cli/dist/index.js +194 -0
- package/dist/cli/dist/index.js.map +1 -0
- package/dist/cli/dist/invite-share.d.ts +16 -0
- package/dist/cli/dist/invite-share.js +163 -0
- package/dist/cli/dist/invite-share.js.map +1 -0
- package/dist/cli/dist/mcp.d.ts +17 -0
- package/dist/cli/dist/mcp.js +105 -0
- package/dist/cli/dist/mcp.js.map +1 -0
- package/dist/cli/dist/network.d.ts +1 -0
- package/dist/cli/dist/network.js +396 -0
- package/dist/cli/dist/network.js.map +1 -0
- package/dist/cli/dist/public-settings.d.ts +27 -0
- package/dist/cli/dist/public-settings.js +33 -0
- package/dist/cli/dist/public-settings.js.map +1 -0
- package/dist/cli/dist/receipt.d.ts +39 -0
- package/dist/cli/dist/receipt.js +90 -0
- package/dist/cli/dist/receipt.js.map +1 -0
- package/dist/cli/dist/receive-hook.d.ts +2 -0
- package/dist/cli/dist/receive-hook.js +35 -0
- package/dist/cli/dist/receive-hook.js.map +1 -0
- package/dist/cli/dist/task-input.d.ts +2 -0
- package/dist/cli/dist/task-input.js +19 -0
- package/dist/cli/dist/task-input.js.map +1 -0
- package/dist/cli/dist/wake-hook.d.ts +3 -0
- package/dist/cli/dist/wake-hook.js +32 -0
- package/dist/cli/dist/wake-hook.js.map +1 -0
- package/dist/examples/two-owner-demo/alice-policy.json +4 -0
- package/dist/examples/two-owner-demo/bob-policy.json +4 -0
- package/dist/examples/two-owner-demo/dist/run-demo.d.ts +71 -0
- package/dist/examples/two-owner-demo/dist/run-demo.js +383 -0
- package/dist/examples/two-owner-demo/dist/run-demo.js.map +1 -0
- package/dist/package.json +1 -0
- package/dist/packages/adapters/dist/command.d.ts +122 -0
- package/dist/packages/adapters/dist/command.js +378 -0
- package/dist/packages/adapters/dist/command.js.map +1 -0
- package/dist/packages/adapters/dist/credential-proxy.d.ts +37 -0
- package/dist/packages/adapters/dist/credential-proxy.js +363 -0
- package/dist/packages/adapters/dist/credential-proxy.js.map +1 -0
- package/dist/packages/adapters/dist/index.d.ts +6 -0
- package/dist/packages/adapters/dist/index.js +6 -0
- package/dist/packages/adapters/dist/index.js.map +1 -0
- package/dist/packages/adapters/dist/mcp.d.ts +32 -0
- package/dist/packages/adapters/dist/mcp.js +87 -0
- package/dist/packages/adapters/dist/mcp.js.map +1 -0
- package/dist/packages/adapters/dist/openai.d.ts +23 -0
- package/dist/packages/adapters/dist/openai.js +81 -0
- package/dist/packages/adapters/dist/openai.js.map +1 -0
- package/dist/packages/adapters/dist/sandbox.d.ts +45 -0
- package/dist/packages/adapters/dist/sandbox.js +60 -0
- package/dist/packages/adapters/dist/sandbox.js.map +1 -0
- package/dist/packages/core/dist/capability.d.ts +36 -0
- package/dist/packages/core/dist/capability.js +203 -0
- package/dist/packages/core/dist/capability.js.map +1 -0
- package/dist/packages/core/dist/contract.d.ts +33 -0
- package/dist/packages/core/dist/contract.js +97 -0
- package/dist/packages/core/dist/contract.js.map +1 -0
- package/dist/packages/core/dist/crypto.d.ts +34 -0
- package/dist/packages/core/dist/crypto.js +329 -0
- package/dist/packages/core/dist/crypto.js.map +1 -0
- package/dist/packages/core/dist/discovery.d.ts +129 -0
- package/dist/packages/core/dist/discovery.js +527 -0
- package/dist/packages/core/dist/discovery.js.map +1 -0
- package/dist/packages/core/dist/edge.d.ts +4 -0
- package/dist/packages/core/dist/edge.js +6 -0
- package/dist/packages/core/dist/edge.js.map +1 -0
- package/dist/packages/core/dist/index.d.ts +9 -0
- package/dist/packages/core/dist/index.js +10 -0
- package/dist/packages/core/dist/index.js.map +1 -0
- package/dist/packages/core/dist/receipts.d.ts +9 -0
- package/dist/packages/core/dist/receipts.js +67 -0
- package/dist/packages/core/dist/receipts.js.map +1 -0
- package/dist/packages/core/dist/relay-auth.d.ts +40 -0
- package/dist/packages/core/dist/relay-auth.js +106 -0
- package/dist/packages/core/dist/relay-auth.js.map +1 -0
- package/dist/packages/core/dist/revocation.d.ts +58 -0
- package/dist/packages/core/dist/revocation.js +112 -0
- package/dist/packages/core/dist/revocation.js.map +1 -0
- package/dist/packages/core/dist/schema.d.ts +11 -0
- package/dist/packages/core/dist/schema.js +48 -0
- package/dist/packages/core/dist/schema.js.map +1 -0
- package/dist/packages/core/dist/types.d.ts +172 -0
- package/dist/packages/core/dist/types.js +2 -0
- package/dist/packages/core/dist/types.js.map +1 -0
- package/dist/packages/ledger/dist/index.d.ts +84 -0
- package/dist/packages/ledger/dist/index.js +269 -0
- package/dist/packages/ledger/dist/index.js.map +1 -0
- package/dist/packages/relay/dist/fetch.d.ts +250 -0
- package/dist/packages/relay/dist/fetch.js +1401 -0
- package/dist/packages/relay/dist/fetch.js.map +1 -0
- package/dist/packages/relay/dist/index.d.ts +103 -0
- package/dist/packages/relay/dist/index.js +855 -0
- package/dist/packages/relay/dist/index.js.map +1 -0
- package/dist/packages/relay/dist/journal.d.ts +77 -0
- package/dist/packages/relay/dist/journal.js +339 -0
- package/dist/packages/relay/dist/journal.js.map +1 -0
- package/dist/packages/relay/dist/notifications.d.ts +63 -0
- package/dist/packages/relay/dist/notifications.js +55 -0
- package/dist/packages/relay/dist/notifications.js.map +1 -0
- package/dist/packages/relay/dist/retry.d.ts +12 -0
- package/dist/packages/relay/dist/retry.js +59 -0
- package/dist/packages/relay/dist/retry.js.map +1 -0
- package/dist/packages/relay/dist/ssrf.d.ts +32 -0
- package/dist/packages/relay/dist/ssrf.js +213 -0
- package/dist/packages/relay/dist/ssrf.js.map +1 -0
- package/dist/packages/relay/dist/worker.d.ts +92 -0
- package/dist/packages/relay/dist/worker.js +460 -0
- package/dist/packages/relay/dist/worker.js.map +1 -0
- package/dist/packages/runtime/dist/a2a.d.ts +8 -0
- package/dist/packages/runtime/dist/a2a.js +69 -0
- package/dist/packages/runtime/dist/a2a.js.map +1 -0
- package/dist/packages/runtime/dist/adapter.d.ts +51 -0
- package/dist/packages/runtime/dist/adapter.js +2 -0
- package/dist/packages/runtime/dist/adapter.js.map +1 -0
- package/dist/packages/runtime/dist/approval-providers.d.ts +99 -0
- package/dist/packages/runtime/dist/approval-providers.js +269 -0
- package/dist/packages/runtime/dist/approval-providers.js.map +1 -0
- package/dist/packages/runtime/dist/daily-limit.d.ts +2 -0
- package/dist/packages/runtime/dist/daily-limit.js +54 -0
- package/dist/packages/runtime/dist/daily-limit.js.map +1 -0
- package/dist/packages/runtime/dist/gateway.d.ts +35 -0
- package/dist/packages/runtime/dist/gateway.js +92 -0
- package/dist/packages/runtime/dist/gateway.js.map +1 -0
- package/dist/packages/runtime/dist/inbox.d.ts +10 -0
- package/dist/packages/runtime/dist/inbox.js +24 -0
- package/dist/packages/runtime/dist/inbox.js.map +1 -0
- package/dist/packages/runtime/dist/index.d.ts +13 -0
- package/dist/packages/runtime/dist/index.js +14 -0
- package/dist/packages/runtime/dist/index.js.map +1 -0
- package/dist/packages/runtime/dist/mcp-server.d.ts +90 -0
- package/dist/packages/runtime/dist/mcp-server.js +647 -0
- package/dist/packages/runtime/dist/mcp-server.js.map +1 -0
- package/dist/packages/runtime/dist/mcp-tool-catalog.d.ts +3 -0
- package/dist/packages/runtime/dist/mcp-tool-catalog.js +507 -0
- package/dist/packages/runtime/dist/mcp-tool-catalog.js.map +1 -0
- package/dist/packages/runtime/dist/mcp.d.ts +73 -0
- package/dist/packages/runtime/dist/mcp.js +67 -0
- package/dist/packages/runtime/dist/mcp.js.map +1 -0
- package/dist/packages/runtime/dist/policy.d.ts +19 -0
- package/dist/packages/runtime/dist/policy.js +41 -0
- package/dist/packages/runtime/dist/policy.js.map +1 -0
- package/dist/packages/runtime/dist/quota.d.ts +39 -0
- package/dist/packages/runtime/dist/quota.js +147 -0
- package/dist/packages/runtime/dist/quota.js.map +1 -0
- package/dist/packages/runtime/dist/session-audit.d.ts +107 -0
- package/dist/packages/runtime/dist/session-audit.js +520 -0
- package/dist/packages/runtime/dist/session-audit.js.map +1 -0
- package/dist/packages/runtime/dist/session-timeouts.d.ts +33 -0
- package/dist/packages/runtime/dist/session-timeouts.js +62 -0
- package/dist/packages/runtime/dist/session-timeouts.js.map +1 -0
- package/dist/packages/runtime/dist/session.d.ts +323 -0
- package/dist/packages/runtime/dist/session.js +2252 -0
- package/dist/packages/runtime/dist/session.js.map +1 -0
- package/dist/packages/runtime/dist/task-journal.d.ts +36 -0
- package/dist/packages/runtime/dist/task-journal.js +104 -0
- package/dist/packages/runtime/dist/task-journal.js.map +1 -0
- package/dist/packages/runtime/dist/verifier.d.ts +64 -0
- package/dist/packages/runtime/dist/verifier.js +109 -0
- package/dist/packages/runtime/dist/verifier.js.map +1 -0
- package/dist/packages/sandbox/dist/container.d.ts +33 -0
- package/dist/packages/sandbox/dist/container.js +189 -0
- package/dist/packages/sandbox/dist/container.js.map +1 -0
- package/dist/packages/sandbox/dist/index.d.ts +34 -0
- package/dist/packages/sandbox/dist/index.js +179 -0
- package/dist/packages/sandbox/dist/index.js.map +1 -0
- package/dist/packages/sandbox/dist/permission.d.ts +58 -0
- package/dist/packages/sandbox/dist/permission.js +90 -0
- package/dist/packages/sandbox/dist/permission.js.map +1 -0
- package/dist/spec/README.ja.md +76 -0
- package/dist/spec/README.md +135 -0
- package/dist/spec/ack-receipt.schema.json +77 -0
- package/dist/spec/agent-card.schema.json +83 -0
- package/dist/spec/approval-receipt.schema.json +94 -0
- package/dist/spec/audit-entry.schema.json +101 -0
- package/dist/spec/capability-token.schema.json +133 -0
- package/dist/spec/envelope.schema.json +197 -0
- package/dist/spec/examples/sample-ack-receipt.json +16 -0
- package/dist/spec/examples/sample-agent-card.json +35 -0
- package/dist/spec/examples/sample-approval-receipt.json +18 -0
- package/dist/spec/examples/sample-audit-entry.json +37 -0
- package/dist/spec/examples/sample-capability-token.json +39 -0
- package/dist/spec/examples/sample-envelope.json +21 -0
- package/dist/spec/examples/sample-task-manifest.json +141 -0
- package/dist/spec/examples/sample-usage-receipt.json +19 -0
- package/dist/spec/task-manifest.schema.json +422 -0
- package/dist/spec/usage-receipt.schema.json +91 -0
- 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":"AAAA,sCAAsC;AACtC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACzF,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,yBAAyB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGjF,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAa1D,MAAM,UAAU,YAAY;IAC1B,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;QACpE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,OAAO,EAAE,EAAE,4BAA4B,CAAC;QAC3E,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,qBAAqB,EAAE,4BAA4B,CAAC;YACjH,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,uBAAuB,CAAC,CAAC,CAAC;IACpG,OAAO,IAAI,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;AACrC,CAAC;AACD,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,QAAgB;IACzD,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QAAC,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAAC,CAAC;IACzC,OAAO,KAAK,EAAE,CAAC;QAAC,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QAAC,MAAM,KAAK,CAAC;IAAC,CAAC;IACjG,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAC;QACnD,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC;QACzB,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC;YAAE,MAAM,IAAI,KAAK,EAAE,CAAC;QACnI,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;QAC/B,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;YAC3B,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,CAAC,CAAC,WAAW,CAAC,MAAM,GAAG,GAAG;gBACrE,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;gBACxE,OAAO,CAAC,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;gBACzE,OAAO,CAAC,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,SAAS,IAAI,OAAO,CAAC,CAAC,KAAK,KAAK,SAAS;gBAC9F,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC;gBAAE,MAAM,IAAI,KAAK,EAAE,CAAC;YACpF,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QACD,OAAO,CAAC,CAAC,QAAQ,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QAAC,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;IAAC,CAAC;AACvF,CAAC;AACD,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,GAAY,EAAE,MAAqC;IAC9F,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,wFAAwF;IACxF,MAAM,IAAI,GAAG,IAAI,GAAG,OAAO,CAAC;IAC5B,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IACrD,MAAM,SAAS,GAAG,IAAI,GAAG,GAAG,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC;IACrD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjB,MAAM,MAAM,GAAG,WAAW,CAAC,EAAE,OAAO,EAAE,CAAU,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,GAAG,CAAC,CAAC;QACtF,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAC9F,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QAC5B,OAAO,QAAQ,CAAC;IAClB,CAAC;YAAS,CAAC;QACT,IAAI,CAAC;YAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YAAC,IAAK,CAA2B,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,CAAC;QAAC,CAAC;QACzG,UAAU,CAAC,IAAI,CAAC,CAAC;IACnB,CAAC;AACH,CAAC;AACD,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,GAAY,EAAE,KAAa,EAAE,IAAa,EAAE,iBAAiB,GAAG,KAAK;IAC5G,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,EAAE,iBAAiB,EAAE,CAAC,CAAC;IACnF,MAAM,WAAW,GAAG,IAAI,IAAI,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC;IAC1D,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,GAAG,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;IAC7H,OAAO,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE;QAC5C,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/D,MAAM,OAAO,GAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ;YAC1F,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QAC1I,IAAI,GAAG;YAAE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;;YAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpE,CAAC,CAAC,CAAC;AACL,CAAC;AACD,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,GAAY,EAAE,SAAkB,EAC7E,IAA4B,EAAE,WAA6B;IAC3D,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO;YAC5B,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;YAC7C,CAAC;gBACC,MAAM,OAAO,GAAG,OAAO,CAAC,OAA2E,CAAC;gBACpG,MAAM,GAAG,GAAG,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;gBACnD,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,GAAG,CAAC,CAAC;gBACvD,IAAI,OAAO,EAAE,OAAO;oBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC;gBACzD,IAAI,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,qBAAqB,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK;oBAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAC/H,CAAC;YACD,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,EAAE,oBAAoB,EAAE,CAAC,GAAG,IAAI,GAAG,CAAC;wBAC9D,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;qBAC1G,CAAC,CAAC,EAAE,CAAC;YACN,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,0BAA0B,CAAC,GAAG,EAAE,SAAS,EAAE,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrH,CAAC,EAAE,CAAC;AACN,CAAC;AACD,MAAM,UAAU,eAAe,CAAC,IAAc;IAC5C,MAAM,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC;IAC/B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC1C,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACtE,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,uBAAuB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC3I,IAAI,IAAI,KAAK,uBAAuB,EAAE,CAAC;YAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC9E,MAAM,KAAK,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;QACxB,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IAC3B,CAAC;IACD,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;QAC9I,MAAM,IAAI,KAAK,CAAC,wJAAwJ,CAAC,CAAC;IAC5K,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAE,EAAE,MAAM,CAAC,CAAY,CAAC;IAC/E,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,YAAY,EAAE,CAAC;IACrD,IAAI,QAAmB,CAAC;IACxB,IAAI,MAAM,KAAK,MAAM;QAAE,QAAQ,GAAG,YAAY,CAAC,IAAI,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;SACzD,IAAI,MAAM,KAAK,KAAK;QAAE,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC,CAAC;;QACnI,QAAQ,GAAG,cAAc,CAAC,IAAI,EAAE,GAAG,EAAE,CAAC,KAAK,EAAE,EAAE;YAClD,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;YACjE,IAAI,KAAK,GAAG,CAAC;gBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;YACpD,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC;gBAC3B,KAAK,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC;gBAC9B,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,CAAC;gBAC3B,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC;YAC9B,CAAC;iBAAM,CAAC;gBACN,IAAI,MAAM,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK;oBAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;gBACpF,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,MAAM,KAAK,OAAO,CAAC;gBAAC,KAAK,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,MAAM,KAAK,QAAQ,CAAC;YACtF,CAAC;QACH,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;AACvF,CAAC"}
|
|
@@ -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"}
|