@bridgekitux/agent 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +17 -0
  2. package/dist/src/audit.d.ts +18 -0
  3. package/dist/src/audit.d.ts.map +1 -0
  4. package/dist/src/audit.js +30 -0
  5. package/dist/src/audit.js.map +1 -0
  6. package/dist/src/cli.d.ts +3 -0
  7. package/dist/src/cli.d.ts.map +1 -0
  8. package/dist/src/cli.js +173 -0
  9. package/dist/src/cli.js.map +1 -0
  10. package/dist/src/config.d.ts +24 -0
  11. package/dist/src/config.d.ts.map +1 -0
  12. package/dist/src/config.js +66 -0
  13. package/dist/src/config.js.map +1 -0
  14. package/dist/src/handlers.d.ts +87 -0
  15. package/dist/src/handlers.d.ts.map +1 -0
  16. package/dist/src/handlers.js +1143 -0
  17. package/dist/src/handlers.js.map +1 -0
  18. package/dist/src/index.d.ts +7 -0
  19. package/dist/src/index.d.ts.map +1 -0
  20. package/dist/src/index.js +7 -0
  21. package/dist/src/index.js.map +1 -0
  22. package/dist/src/path-scope.d.ts +2 -0
  23. package/dist/src/path-scope.d.ts.map +1 -0
  24. package/dist/src/path-scope.js +12 -0
  25. package/dist/src/path-scope.js.map +1 -0
  26. package/dist/src/resources.d.ts +74 -0
  27. package/dist/src/resources.d.ts.map +1 -0
  28. package/dist/src/resources.js +92 -0
  29. package/dist/src/resources.js.map +1 -0
  30. package/dist/src/server.d.ts +54 -0
  31. package/dist/src/server.d.ts.map +1 -0
  32. package/dist/src/server.js +291 -0
  33. package/dist/src/server.js.map +1 -0
  34. package/dist/src/state.d.ts +59 -0
  35. package/dist/src/state.d.ts.map +1 -0
  36. package/dist/src/state.js +98 -0
  37. package/dist/src/state.js.map +1 -0
  38. package/dist/src/vault.d.ts +31 -0
  39. package/dist/src/vault.d.ts.map +1 -0
  40. package/dist/src/vault.js +69 -0
  41. package/dist/src/vault.js.map +1 -0
  42. package/package.json +50 -0
@@ -0,0 +1,291 @@
1
+ import { createServer as createTcpServer } from 'node:net';
2
+ import { randomUUID } from 'node:crypto';
3
+ import { WebSocketServer } from 'ws';
4
+ import { createErrorMessage, createMessage, getManifestRuntime, hasCapability, parseMessage, toBridgeKitError, validateManifest } from '@bridgekitux/protocol';
5
+ import { AuditLog } from './audit.js';
6
+ import { createBridgeKitPaths, ensureBridgeKitHome, JsonFileStore } from './config.js';
7
+ import { ResourceRegistry } from './resources.js';
8
+ import { PairingStore, SessionStore } from './state.js';
9
+ import { createAgentHttpServer, invokeCapability, operationForInvoke, ProcessManager, subscribeCapability } from './handlers.js';
10
+ import { SecretVault } from './vault.js';
11
+ export class BridgeKitAgent {
12
+ options;
13
+ host;
14
+ requestedPort;
15
+ paths;
16
+ registry;
17
+ pairings;
18
+ sessions;
19
+ audit;
20
+ vault;
21
+ processManager = new ProcessManager();
22
+ httpServer;
23
+ wsServer;
24
+ currentPort;
25
+ subscriptions = new Map();
26
+ constructor(options = {}) {
27
+ this.options = options;
28
+ this.host = options.host ?? '127.0.0.1';
29
+ this.requestedPort = options.port ?? 7777;
30
+ this.paths = createBridgeKitPaths(options.home);
31
+ this.registry = new ResourceRegistry(new JsonFileStore(this.paths.resources, { resources: [] }));
32
+ this.pairings = new PairingStore(new JsonFileStore(this.paths.pairings, { pairings: [] }));
33
+ this.sessions = new SessionStore(new JsonFileStore(this.paths.sessions, { sessions: [] }));
34
+ this.audit = new AuditLog(this.paths.auditLog);
35
+ this.vault = new SecretVault(new JsonFileStore(this.paths.vault, { secrets: [] }), this.paths.vaultKey);
36
+ }
37
+ get port() {
38
+ return this.currentPort ?? this.requestedPort;
39
+ }
40
+ get url() {
41
+ return `ws://${this.host}:${this.port}/bridgekit`;
42
+ }
43
+ async start() {
44
+ await ensureBridgeKitHome(this.paths);
45
+ this.httpServer = await createAgentHttpServer(() => ({
46
+ registry: this.registry,
47
+ audit: this.audit,
48
+ vault: this.vault,
49
+ agentHost: this.host,
50
+ agentPort: this.port,
51
+ processManager: this.processManager
52
+ }));
53
+ this.wsServer = new WebSocketServer({ server: this.httpServer, path: '/bridgekit' });
54
+ this.wsServer.on('connection', (socket, request) => {
55
+ const origin = request.headers.origin;
56
+ socket.on('message', (data) => {
57
+ void this.handleRawMessage(socket, data.toString(), typeof origin === 'string' ? origin : undefined);
58
+ });
59
+ socket.on('close', () => this.closeSocketSubscriptions(socket));
60
+ });
61
+ await new Promise((resolve, reject) => {
62
+ this.httpServer.once('error', reject);
63
+ this.httpServer.listen(this.requestedPort, this.host, () => {
64
+ this.currentPort = this.httpServer.address().port;
65
+ this.httpServer.off('error', reject);
66
+ resolve();
67
+ });
68
+ });
69
+ await this.audit.write({ action: 'agent.start', outcome: 'info', details: { host: this.host, port: this.port } });
70
+ }
71
+ async stop() {
72
+ for (const [subscriptionId, subscription] of this.subscriptions.entries()) {
73
+ subscription.control.close();
74
+ this.subscriptions.delete(subscriptionId);
75
+ }
76
+ await new Promise((resolve) => {
77
+ for (const client of this.wsServer?.clients ?? [])
78
+ client.terminate();
79
+ this.wsServer?.close(() => resolve());
80
+ if (!this.wsServer)
81
+ resolve();
82
+ });
83
+ await new Promise((resolve) => {
84
+ this.httpServer?.close(() => resolve());
85
+ if (!this.httpServer)
86
+ resolve();
87
+ });
88
+ }
89
+ async handleRawMessage(socket, raw, origin) {
90
+ let message;
91
+ try {
92
+ message = parseMessage(JSON.parse(raw));
93
+ const response = await this.handleMessage(socket, message, origin);
94
+ if (response)
95
+ socket.send(JSON.stringify(response));
96
+ }
97
+ catch (error) {
98
+ socket.send(JSON.stringify(createErrorMessage('error', toBridgeKitError(error))));
99
+ }
100
+ }
101
+ async handleMessage(socket, message, origin) {
102
+ switch (message.type) {
103
+ case 'hello':
104
+ return this.handleHello(message.payload, message.id, origin);
105
+ case 'pair.request':
106
+ return this.handlePairRequest(message.payload, message.id, origin);
107
+ case 'pair.status':
108
+ return this.handlePairStatus(message.payload, message.id);
109
+ case 'invoke':
110
+ return this.handleInvoke(message.payload, message.id, origin);
111
+ case 'subscribe':
112
+ return this.handleSubscribe(socket, message.payload, message.id, origin);
113
+ case 'stream.send':
114
+ return this.handleStreamSend(message.payload, message.id, origin);
115
+ case 'unsubscribe':
116
+ return this.handleUnsubscribe(message.payload, message.id, origin);
117
+ case 'resources.list':
118
+ return createMessage('resources.list.result', { resources: await this.registry.describe() }, message.id);
119
+ default:
120
+ return createErrorMessage(`${message.type}.error`, { code: 'unknown_message', message: `Unsupported message type: ${message.type}` }, message.id);
121
+ }
122
+ }
123
+ async handleHello(payload, id, origin) {
124
+ await this.audit.write({ action: 'client.hello', outcome: 'info', origin, details: payload });
125
+ return createMessage('hello.ok', {
126
+ agentVersion: '0.1.0',
127
+ protocolVersion: '0.1.0',
128
+ bridge: 'direct-websocket'
129
+ }, id);
130
+ }
131
+ async handlePairRequest(payload, id, origin) {
132
+ const manifest = validateManifest(payload.manifest);
133
+ const pairing = await this.pairings.create({
134
+ appName: payload.appName || manifest.name,
135
+ runtime: payload.runtime ?? payload.environment ?? getManifestRuntime(manifest),
136
+ origin: payload.origin ?? origin,
137
+ manifest
138
+ });
139
+ await this.audit.write({ action: 'pair.request', outcome: 'info', pairingId: pairing.id, origin, details: { appName: pairing.appName, runtime: pairing.runtime, requestedCapabilities: pairing.requestedCapabilities } });
140
+ if (this.options.autoApprove) {
141
+ await this.pairings.update(pairing.id, (record) => ({ ...record, status: 'approved', decidedAt: new Date().toISOString() }));
142
+ const approved = await this.issueSession(pairing.id, 'auto-approve');
143
+ return createMessage('pair.approved', approved, id);
144
+ }
145
+ return createMessage('pair.pending', {
146
+ pairingId: pairing.id,
147
+ code: pairing.code,
148
+ approveUrl: `bridgekit://approve/${pairing.code}`,
149
+ requestedCapabilities: pairing.requestedCapabilities,
150
+ status: 'pending'
151
+ }, id);
152
+ }
153
+ async handlePairStatus(payload, id) {
154
+ const key = payload.pairingId ?? payload.code;
155
+ if (!key)
156
+ return createErrorMessage('pair.status.error', { code: 'invalid_request', message: 'pairingId or code is required' }, id);
157
+ const pairing = await this.pairings.find(key);
158
+ if (!pairing)
159
+ return createErrorMessage('pair.status.error', { code: 'pairing_not_found', message: `No pairing found for ${key}` }, id);
160
+ if (pairing.status === 'denied')
161
+ return createErrorMessage('pair.denied', { code: 'permission_denied', message: 'Pairing was denied' }, id);
162
+ if (pairing.status === 'approved')
163
+ return createMessage('pair.approved', await this.issueSession(pairing.id, 'local-user'), id);
164
+ return createMessage('pair.pending', {
165
+ pairingId: pairing.id,
166
+ code: pairing.code,
167
+ approveUrl: `bridgekit://approve/${pairing.code}`,
168
+ requestedCapabilities: pairing.requestedCapabilities,
169
+ status: 'pending'
170
+ }, id);
171
+ }
172
+ async issueSession(pairingId, approvedBy) {
173
+ const pairing = await this.pairings.find(pairingId);
174
+ if (!pairing)
175
+ throw new Error(`Pairing not found: ${pairingId}`);
176
+ const created = await this.sessions.createFromPairing(pairing, approvedBy);
177
+ await this.pairings.update(pairing.id, (record) => ({ ...record, status: 'approved', decidedAt: record.decidedAt ?? new Date().toISOString(), sessionId: created.session.id }));
178
+ await this.audit.write({ action: 'session.create', outcome: 'allowed', pairingId: pairing.id, sessionId: created.session.id, origin: pairing.origin, details: { grants: created.session.grants.length } });
179
+ return { sessionId: created.session.id, sessionToken: created.token, grants: created.session.grants, expiresAt: created.session.expiresAt };
180
+ }
181
+ async handleSubscribe(socket, payload, id, origin) {
182
+ const session = await this.sessions.findByToken(payload.sessionToken);
183
+ if (!session) {
184
+ await this.audit.write({ action: 'subscription.start', outcome: 'denied', capability: payload.capability, resourceId: payload.resourceId, origin, details: { reason: 'invalid_session' } });
185
+ return createErrorMessage('subscribe.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
186
+ }
187
+ const operation = operationForInvoke(payload);
188
+ const allowed = hasCapability(session.grants, payload.capability, payload.resourceId, operation);
189
+ if (!allowed) {
190
+ await this.audit.write({ action: 'subscription.start', outcome: 'denied', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation } });
191
+ return createErrorMessage('subscribe.error', { code: 'permission_denied', message: `${payload.capability} is not approved for ${payload.resourceId}` }, id);
192
+ }
193
+ const subscriptionId = randomUUID();
194
+ try {
195
+ const control = await subscribeCapability({ registry: this.registry, audit: this.audit, vault: this.vault, agentHost: this.host, agentPort: this.port, processManager: this.processManager }, { ...payload, operation }, (event) => {
196
+ const subscription = this.subscriptions.get(subscriptionId);
197
+ if (!subscription || socket.readyState !== 1)
198
+ return;
199
+ subscription.sequence += 1;
200
+ socket.send(JSON.stringify(createMessage('event', {
201
+ ...event,
202
+ subscriptionId,
203
+ sequence: subscription.sequence
204
+ })));
205
+ });
206
+ this.subscriptions.set(subscriptionId, { sessionId: session.id, socket, control, sequence: 0 });
207
+ await this.audit.write({ action: 'subscription.start', outcome: 'allowed', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation, subscriptionId } });
208
+ return createMessage('subscribe.result', { subscriptionId }, id);
209
+ }
210
+ catch (error) {
211
+ await this.audit.write({ action: 'subscription.start', outcome: 'error', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: toBridgeKitError(error) });
212
+ return createErrorMessage('subscribe.error', toBridgeKitError(error), id);
213
+ }
214
+ }
215
+ async handleUnsubscribe(payload, id, origin) {
216
+ const session = await this.sessions.findByToken(payload.sessionToken);
217
+ if (!session)
218
+ return createErrorMessage('unsubscribe.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
219
+ const subscription = this.subscriptions.get(payload.subscriptionId);
220
+ if (!subscription || subscription.sessionId !== session.id) {
221
+ return createMessage('unsubscribe.result', { subscriptionId: payload.subscriptionId, closed: false }, id);
222
+ }
223
+ subscription.control.close();
224
+ this.subscriptions.delete(payload.subscriptionId);
225
+ await this.audit.write({ action: 'subscription.stop', outcome: 'allowed', sessionId: session.id, origin, details: { subscriptionId: payload.subscriptionId } });
226
+ return createMessage('unsubscribe.result', { subscriptionId: payload.subscriptionId, closed: true }, id);
227
+ }
228
+ async handleStreamSend(payload, id, origin) {
229
+ const session = await this.sessions.findByToken(payload.sessionToken);
230
+ if (!session) {
231
+ await this.audit.write({ action: 'stream.send', outcome: 'denied', origin, details: { reason: 'invalid_session', subscriptionId: payload.subscriptionId } });
232
+ return createErrorMessage('stream.send.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
233
+ }
234
+ const subscription = this.subscriptions.get(payload.subscriptionId);
235
+ if (!subscription || subscription.sessionId !== session.id) {
236
+ await this.audit.write({ action: 'stream.send', outcome: 'denied', sessionId: session.id, origin, details: { reason: 'subscription_not_found', subscriptionId: payload.subscriptionId } });
237
+ return createErrorMessage('stream.send.error', { code: 'subscription_not_found', message: `No active stream subscription named ${payload.subscriptionId}` }, id);
238
+ }
239
+ if (!subscription.control.send) {
240
+ await this.audit.write({ action: 'stream.send', outcome: 'denied', sessionId: session.id, origin, details: { reason: 'stream_not_writable', subscriptionId: payload.subscriptionId } });
241
+ return createErrorMessage('stream.send.error', { code: 'stream_not_writable', message: `Subscription ${payload.subscriptionId} does not accept outbound data` }, id);
242
+ }
243
+ try {
244
+ const result = await subscription.control.send(payload);
245
+ await this.audit.write({ action: 'stream.send', outcome: 'allowed', sessionId: session.id, origin, details: { subscriptionId: payload.subscriptionId, bytes: result.bytes, ended: result.ended } });
246
+ return createMessage('stream.send.result', { subscriptionId: payload.subscriptionId, ...result }, id);
247
+ }
248
+ catch (error) {
249
+ await this.audit.write({ action: 'stream.send', outcome: 'error', sessionId: session.id, origin, details: toBridgeKitError(error) });
250
+ return createErrorMessage('stream.send.error', toBridgeKitError(error), id);
251
+ }
252
+ }
253
+ closeSocketSubscriptions(socket) {
254
+ for (const [subscriptionId, subscription] of this.subscriptions.entries()) {
255
+ if (subscription.socket !== socket)
256
+ continue;
257
+ subscription.control.close();
258
+ this.subscriptions.delete(subscriptionId);
259
+ }
260
+ }
261
+ async handleInvoke(payload, id, origin) {
262
+ const session = await this.sessions.findByToken(payload.sessionToken);
263
+ if (!session) {
264
+ await this.audit.write({ action: 'capability.invoke', outcome: 'denied', capability: payload.capability, resourceId: payload.resourceId, origin, details: { reason: 'invalid_session' } });
265
+ return createErrorMessage('invoke.error', { code: 'invalid_session', message: 'Session token is invalid or revoked' }, id);
266
+ }
267
+ const operation = operationForInvoke(payload);
268
+ const allowed = hasCapability(session.grants, payload.capability, payload.resourceId ?? '', operation);
269
+ if (!allowed) {
270
+ await this.audit.write({ action: 'capability.invoke', outcome: 'denied', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation } });
271
+ return createErrorMessage('invoke.error', { code: 'permission_denied', message: `${payload.capability} is not approved for ${payload.resourceId ?? 'this session'}` }, id);
272
+ }
273
+ try {
274
+ const result = await invokeCapability({ registry: this.registry, audit: this.audit, vault: this.vault, agentHost: this.host, agentPort: this.port, processManager: this.processManager }, { ...payload, operation });
275
+ await this.audit.write({ action: 'capability.invoke', outcome: 'allowed', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: { operation } });
276
+ return createMessage('invoke.result', { ok: true, result }, id);
277
+ }
278
+ catch (error) {
279
+ await this.audit.write({ action: 'capability.invoke', outcome: 'error', sessionId: session.id, capability: payload.capability, resourceId: payload.resourceId, origin, details: toBridgeKitError(error) });
280
+ return createErrorMessage('invoke.error', toBridgeKitError(error), id);
281
+ }
282
+ }
283
+ }
284
+ export async function isPortAvailable(port, host = '127.0.0.1') {
285
+ const server = createTcpServer();
286
+ return new Promise((resolve) => {
287
+ server.once('error', () => resolve(false));
288
+ server.listen(port, host, () => server.close(() => resolve(true)));
289
+ });
290
+ }
291
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ import type { BridgeKitManifest, CapabilityGrant, CapabilityRequest, RestrictedEnvironment } from '@bridgekitux/protocol';
2
+ import type { JsonFileStore } from './config.js';
3
+ export interface PairingRecord {
4
+ id: string;
5
+ code: string;
6
+ appName: string;
7
+ runtime: RestrictedEnvironment;
8
+ origin?: string;
9
+ manifest: BridgeKitManifest;
10
+ requestedCapabilities: CapabilityRequest[];
11
+ status: 'pending' | 'approved' | 'denied' | 'expired';
12
+ createdAt: string;
13
+ decidedAt?: string;
14
+ sessionId?: string;
15
+ }
16
+ export interface PairingFile {
17
+ pairings: PairingRecord[];
18
+ }
19
+ export interface SessionRecord {
20
+ id: string;
21
+ tokenHash: string;
22
+ appName: string;
23
+ runtime: RestrictedEnvironment;
24
+ origin?: string;
25
+ grants: CapabilityGrant[];
26
+ createdAt: string;
27
+ revokedAt?: string;
28
+ expiresAt?: string;
29
+ }
30
+ export interface SessionFile {
31
+ sessions: SessionRecord[];
32
+ }
33
+ export interface CreatedSession {
34
+ session: SessionRecord;
35
+ token: string;
36
+ }
37
+ export declare function createPairingCode(): string;
38
+ export declare class PairingStore {
39
+ private readonly store;
40
+ constructor(store: JsonFileStore<PairingFile>);
41
+ create(input: {
42
+ appName: string;
43
+ runtime: RestrictedEnvironment;
44
+ origin?: string;
45
+ manifest: BridgeKitManifest;
46
+ }): Promise<PairingRecord>;
47
+ list(): Promise<PairingRecord[]>;
48
+ find(idOrCode: string): Promise<PairingRecord | undefined>;
49
+ update(idOrCode: string, mutator: (pairing: PairingRecord) => PairingRecord): Promise<PairingRecord>;
50
+ }
51
+ export declare class SessionStore {
52
+ private readonly store;
53
+ constructor(store: JsonFileStore<SessionFile>);
54
+ createFromPairing(pairing: PairingRecord, approvedBy: CapabilityGrant['approvedBy']): Promise<CreatedSession>;
55
+ findByToken(token: string): Promise<SessionRecord | undefined>;
56
+ list(): Promise<SessionRecord[]>;
57
+ revoke(id: string): Promise<void>;
58
+ }
59
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE1H,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,qBAAqB,EAAE,iBAAiB,EAAE,CAAC;IAC3C,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,eAAe,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,aAAa,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAG1C;AAOD,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC;IAExD,MAAM,CAAC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,qBAAqB,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,iBAAiB,CAAA;KAAE,GAAG,OAAO,CAAC,aAAa,CAAC;IAkBxI,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAIhC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAI1D,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,KAAK,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;CAY3G;AAED,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC;IAExD,iBAAiB,CAAC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,cAAc,CAAC;IA2B7G,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAK9D,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAIhC,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAKxC"}
@@ -0,0 +1,98 @@
1
+ import { randomBytes, randomUUID } from 'node:crypto';
2
+ import { manifestToCapabilityRequests } from '@bridgekitux/protocol';
3
+ export function createPairingCode() {
4
+ const number = randomBytes(4).readUInt32BE(0) % 1_000_000;
5
+ return number.toString().padStart(6, '0');
6
+ }
7
+ async function sha256(value) {
8
+ const { createHash } = await import('node:crypto');
9
+ return createHash('sha256').update(value).digest('hex');
10
+ }
11
+ export class PairingStore {
12
+ store;
13
+ constructor(store) {
14
+ this.store = store;
15
+ }
16
+ async create(input) {
17
+ const record = {
18
+ id: randomUUID(),
19
+ code: createPairingCode(),
20
+ appName: input.appName,
21
+ runtime: input.runtime,
22
+ origin: input.origin,
23
+ manifest: input.manifest,
24
+ requestedCapabilities: manifestToCapabilityRequests(input.manifest),
25
+ status: 'pending',
26
+ createdAt: new Date().toISOString()
27
+ };
28
+ await this.store.update((file) => {
29
+ file.pairings = [record, ...file.pairings.filter((pairing) => pairing.status === 'pending').slice(0, 99)];
30
+ });
31
+ return record;
32
+ }
33
+ async list() {
34
+ return (await this.store.read()).pairings;
35
+ }
36
+ async find(idOrCode) {
37
+ return (await this.list()).find((pairing) => pairing.id === idOrCode || pairing.code === idOrCode);
38
+ }
39
+ async update(idOrCode, mutator) {
40
+ let updated;
41
+ await this.store.update((file) => {
42
+ file.pairings = file.pairings.map((pairing) => {
43
+ if (pairing.id !== idOrCode && pairing.code !== idOrCode)
44
+ return pairing;
45
+ updated = mutator(pairing);
46
+ return updated;
47
+ });
48
+ });
49
+ if (!updated)
50
+ throw new Error(`Pairing not found: ${idOrCode}`);
51
+ return updated;
52
+ }
53
+ }
54
+ export class SessionStore {
55
+ store;
56
+ constructor(store) {
57
+ this.store = store;
58
+ }
59
+ async createFromPairing(pairing, approvedBy) {
60
+ const token = `bk_${randomBytes(32).toString('base64url')}`;
61
+ const sessionId = randomUUID();
62
+ const now = new Date().toISOString();
63
+ const grants = pairing.requestedCapabilities.map((request) => ({
64
+ ...request,
65
+ id: randomUUID(),
66
+ approvedAt: now,
67
+ approvedBy,
68
+ sourceManifest: pairing.manifest.name
69
+ }));
70
+ const session = {
71
+ id: sessionId,
72
+ tokenHash: await sha256(token),
73
+ appName: pairing.appName,
74
+ runtime: pairing.runtime,
75
+ origin: pairing.origin,
76
+ grants,
77
+ createdAt: now
78
+ };
79
+ await this.store.update((file) => {
80
+ file.sessions.unshift(session);
81
+ file.sessions = file.sessions.slice(0, 500);
82
+ });
83
+ return { session, token };
84
+ }
85
+ async findByToken(token) {
86
+ const hash = await sha256(token);
87
+ return (await this.store.read()).sessions.find((session) => session.tokenHash === hash && !session.revokedAt);
88
+ }
89
+ async list() {
90
+ return (await this.store.read()).sessions;
91
+ }
92
+ async revoke(id) {
93
+ await this.store.update((file) => {
94
+ file.sessions = file.sessions.map((session) => session.id === id ? { ...session, revokedAt: new Date().toISOString() } : session);
95
+ });
96
+ }
97
+ }
98
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import type { JsonFileStore } from './config.js';
2
+ export interface VaultRecord {
3
+ id: string;
4
+ iv: string;
5
+ tag: string;
6
+ ciphertext: string;
7
+ updatedAt: string;
8
+ }
9
+ export interface VaultFile {
10
+ secrets: VaultRecord[];
11
+ }
12
+ export declare class SecretVault {
13
+ private readonly store;
14
+ private readonly keyPath;
15
+ constructor(store: JsonFileStore<VaultFile>, keyPath: string);
16
+ private key;
17
+ create(id: string, value: string): Promise<{
18
+ id: string;
19
+ updatedAt: string;
20
+ }>;
21
+ resolve(id: string): Promise<string>;
22
+ list(): Promise<Array<{
23
+ id: string;
24
+ updatedAt: string;
25
+ }>>;
26
+ revoke(id: string): Promise<{
27
+ id: string;
28
+ revoked: boolean;
29
+ }>;
30
+ }
31
+ //# sourceMappingURL=vault.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/vault.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAWD,qBAAa,WAAW;IACV,OAAO,CAAC,QAAQ,CAAC,KAAK;IAA4B,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAzD,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,EAAmB,OAAO,EAAE,MAAM;YAEhF,GAAG;IAWX,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAiB7E,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQpC,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAIzD,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAC;CASpE"}
@@ -0,0 +1,69 @@
1
+ import { constants, readFile, writeFile } from 'node:fs/promises';
2
+ import { createCipheriv, createDecipheriv, randomBytes } from 'node:crypto';
3
+ import { access } from 'node:fs/promises';
4
+ import { bridgeKitError } from '@bridgekitux/protocol';
5
+ async function fileExists(path) {
6
+ try {
7
+ await access(path, constants.F_OK);
8
+ return true;
9
+ }
10
+ catch {
11
+ return false;
12
+ }
13
+ }
14
+ export class SecretVault {
15
+ store;
16
+ keyPath;
17
+ constructor(store, keyPath) {
18
+ this.store = store;
19
+ this.keyPath = keyPath;
20
+ }
21
+ async key() {
22
+ if (!(await fileExists(this.keyPath))) {
23
+ const key = randomBytes(32).toString('base64url');
24
+ await writeFile(this.keyPath, `${key}\n`, { mode: 0o600 });
25
+ }
26
+ const encoded = (await readFile(this.keyPath, 'utf8')).trim();
27
+ const key = Buffer.from(encoded, 'base64url');
28
+ if (key.byteLength !== 32)
29
+ throw bridgeKitError('vault_error', 'BridgeKit vault key is invalid');
30
+ return key;
31
+ }
32
+ async create(id, value) {
33
+ const iv = randomBytes(12);
34
+ const cipher = createCipheriv('aes-256-gcm', await this.key(), iv);
35
+ const ciphertext = Buffer.concat([cipher.update(value, 'utf8'), cipher.final()]);
36
+ const record = {
37
+ id,
38
+ iv: iv.toString('base64url'),
39
+ tag: cipher.getAuthTag().toString('base64url'),
40
+ ciphertext: ciphertext.toString('base64url'),
41
+ updatedAt: new Date().toISOString()
42
+ };
43
+ await this.store.update((file) => {
44
+ file.secrets = [record, ...file.secrets.filter((secret) => secret.id !== id)];
45
+ });
46
+ return { id, updatedAt: record.updatedAt };
47
+ }
48
+ async resolve(id) {
49
+ const record = (await this.store.read()).secrets.find((secret) => secret.id === id);
50
+ if (!record)
51
+ throw bridgeKitError('secret_not_found', `Secret ${id} has not been stored`);
52
+ const decipher = createDecipheriv('aes-256-gcm', await this.key(), Buffer.from(record.iv, 'base64url'));
53
+ decipher.setAuthTag(Buffer.from(record.tag, 'base64url'));
54
+ return Buffer.concat([decipher.update(Buffer.from(record.ciphertext, 'base64url')), decipher.final()]).toString('utf8');
55
+ }
56
+ async list() {
57
+ return (await this.store.read()).secrets.map(({ id, updatedAt }) => ({ id, updatedAt }));
58
+ }
59
+ async revoke(id) {
60
+ let revoked = false;
61
+ await this.store.update((file) => {
62
+ const next = file.secrets.filter((secret) => secret.id !== id);
63
+ revoked = next.length !== file.secrets.length;
64
+ file.secrets = next;
65
+ });
66
+ return { id, revoked };
67
+ }
68
+ }
69
+ //# sourceMappingURL=vault.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/vault.ts"],"names":[],"mappings":"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"}