aweshare 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 (69) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +246 -0
  3. package/apps/agent/dist/adapters.d.ts +15 -0
  4. package/apps/agent/dist/adapters.js +25 -0
  5. package/apps/agent/dist/adapters.js.map +1 -0
  6. package/apps/agent/dist/cli.d.ts +2 -0
  7. package/apps/agent/dist/cli.js +175 -0
  8. package/apps/agent/dist/cli.js.map +1 -0
  9. package/apps/agent/dist/config.d.ts +38 -0
  10. package/apps/agent/dist/config.js +150 -0
  11. package/apps/agent/dist/config.js.map +1 -0
  12. package/apps/agent/dist/connection.d.ts +40 -0
  13. package/apps/agent/dist/connection.js +359 -0
  14. package/apps/agent/dist/connection.js.map +1 -0
  15. package/apps/agent/dist/doctor.d.ts +14 -0
  16. package/apps/agent/dist/doctor.js +125 -0
  17. package/apps/agent/dist/doctor.js.map +1 -0
  18. package/apps/agent/dist/health.d.ts +15 -0
  19. package/apps/agent/dist/health.js +45 -0
  20. package/apps/agent/dist/health.js.map +1 -0
  21. package/apps/agent/dist/index.d.ts +5 -0
  22. package/apps/agent/dist/index.js +6 -0
  23. package/apps/agent/dist/index.js.map +1 -0
  24. package/apps/agent/package.json +20 -0
  25. package/apps/hub/dist/admin.d.ts +10 -0
  26. package/apps/hub/dist/admin.js +208 -0
  27. package/apps/hub/dist/admin.js.map +1 -0
  28. package/apps/hub/dist/auth.d.ts +17 -0
  29. package/apps/hub/dist/auth.js +28 -0
  30. package/apps/hub/dist/auth.js.map +1 -0
  31. package/apps/hub/dist/cli.d.ts +2 -0
  32. package/apps/hub/dist/cli.js +243 -0
  33. package/apps/hub/dist/cli.js.map +1 -0
  34. package/apps/hub/dist/config.d.ts +25 -0
  35. package/apps/hub/dist/config.js +53 -0
  36. package/apps/hub/dist/config.js.map +1 -0
  37. package/apps/hub/dist/consumer.d.ts +18 -0
  38. package/apps/hub/dist/consumer.js +157 -0
  39. package/apps/hub/dist/consumer.js.map +1 -0
  40. package/apps/hub/dist/db.d.ts +91 -0
  41. package/apps/hub/dist/db.js +236 -0
  42. package/apps/hub/dist/db.js.map +1 -0
  43. package/apps/hub/dist/http.d.ts +31 -0
  44. package/apps/hub/dist/http.js +118 -0
  45. package/apps/hub/dist/http.js.map +1 -0
  46. package/apps/hub/dist/limiter.d.ts +35 -0
  47. package/apps/hub/dist/limiter.js +78 -0
  48. package/apps/hub/dist/limiter.js.map +1 -0
  49. package/apps/hub/dist/limits.d.ts +30 -0
  50. package/apps/hub/dist/limits.js +52 -0
  51. package/apps/hub/dist/limits.js.map +1 -0
  52. package/apps/hub/dist/meter.d.ts +25 -0
  53. package/apps/hub/dist/meter.js +135 -0
  54. package/apps/hub/dist/meter.js.map +1 -0
  55. package/apps/hub/dist/sanitize.d.ts +3 -0
  56. package/apps/hub/dist/sanitize.js +56 -0
  57. package/apps/hub/dist/sanitize.js.map +1 -0
  58. package/apps/hub/dist/server.d.ts +25 -0
  59. package/apps/hub/dist/server.js +77 -0
  60. package/apps/hub/dist/server.js.map +1 -0
  61. package/apps/hub/dist/tokens.d.ts +9 -0
  62. package/apps/hub/dist/tokens.js +35 -0
  63. package/apps/hub/dist/tokens.js.map +1 -0
  64. package/apps/hub/dist/tunnel.d.ts +108 -0
  65. package/apps/hub/dist/tunnel.js +424 -0
  66. package/apps/hub/dist/tunnel.js.map +1 -0
  67. package/apps/hub/package.json +21 -0
  68. package/bin/aweshare.mjs +43 -0
  69. package/package.json +47 -0
@@ -0,0 +1,424 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { EventEmitter } from 'node:events';
3
+ import { BACKPRESSURE_LIMIT_BYTES, chunkBody, decodeChunkFrame, isValidAlias, PROTOCOLS, parseControlMessage, WIRE_VERSION, } from 'aweshare-protocol';
4
+ import { WebSocket, WebSocketServer } from 'ws';
5
+ import { findProducerByHash, upsertOfferings } from './db.js';
6
+ import { hashToken } from './tokens.js';
7
+ export const HEARTBEAT_TIMEOUT_MS = 45_000;
8
+ const SWEEP_INTERVAL_MS = 10_000;
9
+ const MAX_OFFERINGS = 256;
10
+ export function statusForCode(code) {
11
+ switch (code) {
12
+ case 'TICKET_EXPIRED':
13
+ case 'STREAM_IDLE_TIMEOUT':
14
+ case 'BACKEND_TIMEOUT':
15
+ return 504;
16
+ case 'REQUEST_CANCELED':
17
+ return 499;
18
+ default:
19
+ return 502;
20
+ }
21
+ }
22
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
23
+ /**
24
+ * One dispatched consumer request: ticket + dispatch + response pump.
25
+ * Emits: 'head' {status, headers}, 'chunk' (Uint8Array), 'end', 'error' (RelayFailure).
26
+ * waitFinished() always resolves — never rejects — with the final RelayResult.
27
+ */
28
+ export class TunnelRequest extends EventEmitter {
29
+ session;
30
+ init;
31
+ config;
32
+ requestId = randomUUID().replaceAll('-', '');
33
+ startedAt = Date.now();
34
+ bytesOut = 0;
35
+ headPromise;
36
+ resolveHead;
37
+ rejectHead;
38
+ finishedPromise;
39
+ settleFinished;
40
+ result = {
41
+ status: null,
42
+ errorCode: null,
43
+ canceled: false,
44
+ durationMs: 0,
45
+ bytesOut: 0,
46
+ };
47
+ finished = false;
48
+ headArrived = false;
49
+ streamingStarted = false;
50
+ bufferedChunks = [];
51
+ pendingEnd = false;
52
+ headTimer = null;
53
+ idleTimer = null;
54
+ constructor(session, init, config) {
55
+ super();
56
+ this.session = session;
57
+ this.init = init;
58
+ this.config = config;
59
+ this.headPromise = new Promise((resolve, reject) => {
60
+ this.resolveHead = resolve;
61
+ this.rejectHead = reject;
62
+ });
63
+ this.finishedPromise = new Promise((resolve) => {
64
+ this.settleFinished = resolve;
65
+ });
66
+ this.session.requests.set(this.requestId, this);
67
+ }
68
+ async dispatch() {
69
+ const start = {
70
+ type: 'request.start',
71
+ requestId: this.requestId,
72
+ protocol: this.init.protocol,
73
+ backendId: this.init.backendId,
74
+ method: this.init.method,
75
+ path: this.init.path,
76
+ query: this.init.query,
77
+ headers: this.init.headers,
78
+ };
79
+ await this.send(JSON.stringify(start));
80
+ for (const frame of chunkBody(this.requestId, this.init.body)) {
81
+ await this.send(frame);
82
+ }
83
+ await this.send(JSON.stringify({ type: 'request.end', requestId: this.requestId }));
84
+ this.headTimer = setTimeout(() => this.fail('TICKET_EXPIRED', 'no response head from producer', statusForCode('TICKET_EXPIRED')), this.config.headTimeoutMs);
85
+ }
86
+ waitHead() {
87
+ return this.headPromise;
88
+ }
89
+ /** Flush chunks buffered between head and consumer attach; after this, chunks emit live. */
90
+ startStreaming() {
91
+ this.streamingStarted = true;
92
+ for (const chunk of this.bufferedChunks)
93
+ this.emit('chunk', chunk);
94
+ this.bufferedChunks = [];
95
+ if (this.pendingEnd) {
96
+ this.pendingEnd = false;
97
+ this.emit('end');
98
+ }
99
+ }
100
+ waitFinished() {
101
+ return this.finishedPromise;
102
+ }
103
+ /** Consumer went away; tell the agent to abort upstream. */
104
+ cancel() {
105
+ if (this.finished)
106
+ return;
107
+ this.sendBestEffort(JSON.stringify({ type: 'request.cancel', requestId: this.requestId }));
108
+ this.finalize({ errorCode: 'REQUEST_CANCELED', canceled: true });
109
+ }
110
+ handleHead(status, headers) {
111
+ if (this.finished || this.headArrived)
112
+ return;
113
+ this.headArrived = true;
114
+ this.clearTimers();
115
+ this.result.status = status;
116
+ this.armIdleTimer();
117
+ this.resolveHead({ status, headers });
118
+ this.emit('head', status, headers);
119
+ }
120
+ handleChunk(payload) {
121
+ if (this.finished || !this.headArrived)
122
+ return;
123
+ this.bytesOut += payload.byteLength;
124
+ this.result.bytesOut = this.bytesOut;
125
+ this.armIdleTimer();
126
+ if (this.streamingStarted)
127
+ this.emit('chunk', payload);
128
+ else
129
+ this.bufferedChunks.push(payload);
130
+ }
131
+ handleEnd() {
132
+ if (this.finished)
133
+ return;
134
+ this.clearTimers();
135
+ if (!this.headArrived) {
136
+ // protocol violation: end without head
137
+ this.fail('TUNNEL_CLOSED', 'producer ended request without a response head', 502);
138
+ return;
139
+ }
140
+ this.finalize({});
141
+ // ws may deliver head+end in one tick, before the consumer attached; hold until streaming
142
+ if (this.streamingStarted)
143
+ this.emit('end');
144
+ else
145
+ this.pendingEnd = true;
146
+ }
147
+ handleError(code, message) {
148
+ if (this.finished)
149
+ return;
150
+ this.fail(code, message, statusForCode(code));
151
+ }
152
+ handleSessionClosed() {
153
+ if (this.finished)
154
+ return;
155
+ this.fail('TUNNEL_CLOSED', 'producer tunnel closed mid-request', 502);
156
+ }
157
+ fail(code, message, status) {
158
+ this.clearTimers();
159
+ this.sendBestEffort(JSON.stringify({ type: 'request.cancel', requestId: this.requestId }));
160
+ if (!this.headArrived) {
161
+ this.rejectHead({ code, message, status });
162
+ }
163
+ else {
164
+ this.emit('error', { code, message, status });
165
+ }
166
+ this.finalize({ errorCode: code });
167
+ }
168
+ finalize(overrides) {
169
+ if (this.finished)
170
+ return;
171
+ this.finished = true;
172
+ this.clearTimers();
173
+ this.result.durationMs = Date.now() - this.startedAt;
174
+ if (overrides.errorCode !== undefined)
175
+ this.result.errorCode = overrides.errorCode;
176
+ if (overrides.canceled)
177
+ this.result.canceled = true;
178
+ // settle the head promise too: the consumer handler may still be awaiting it
179
+ if (!this.headArrived) {
180
+ const code = this.result.errorCode ?? 'REQUEST_CANCELED';
181
+ this.rejectHead({
182
+ code,
183
+ message: `request ended before response head (${code})`,
184
+ status: statusForCode(code),
185
+ });
186
+ }
187
+ this.session.requests.delete(this.requestId);
188
+ this.settleFinished(this.result);
189
+ }
190
+ armIdleTimer() {
191
+ if (this.idleTimer)
192
+ clearTimeout(this.idleTimer);
193
+ this.idleTimer = setTimeout(() => {
194
+ this.fail('STREAM_IDLE_TIMEOUT', 'response stream idle', statusForCode('STREAM_IDLE_TIMEOUT'));
195
+ }, this.config.idleTimeoutMs);
196
+ }
197
+ clearTimers() {
198
+ if (this.headTimer)
199
+ clearTimeout(this.headTimer);
200
+ if (this.idleTimer)
201
+ clearTimeout(this.idleTimer);
202
+ this.headTimer = null;
203
+ this.idleTimer = null;
204
+ }
205
+ async send(data) {
206
+ while (this.session.ws.bufferedAmount > BACKPRESSURE_LIMIT_BYTES) {
207
+ await sleep(20);
208
+ }
209
+ this.session.ws.send(data);
210
+ }
211
+ sendBestEffort(data) {
212
+ if (this.session.ws.readyState === WebSocket.OPEN)
213
+ this.session.ws.send(data);
214
+ }
215
+ }
216
+ /** WS endpoint /ws/v1/producer: upgrade auth, register, heartbeat, request routing. */
217
+ export class Tunnel {
218
+ db;
219
+ auth;
220
+ config;
221
+ log;
222
+ sessions = new Map();
223
+ wss = new WebSocketServer({ noServer: true, maxPayload: 256 * 1024 });
224
+ sweeper;
225
+ constructor(db, auth, config, log) {
226
+ this.db = db;
227
+ this.auth = auth;
228
+ this.config = config;
229
+ this.log = log;
230
+ this.sweeper = setInterval(() => this.sweep(), SWEEP_INTERVAL_MS);
231
+ this.sweeper.unref();
232
+ }
233
+ attach(server) {
234
+ server.on('upgrade', (req, socket, head) => {
235
+ const url = new URL(req.url ?? '/', 'http://local');
236
+ if (url.pathname !== '/ws/v1/producer') {
237
+ socket.destroy();
238
+ return;
239
+ }
240
+ const bearer = req.headers.authorization?.startsWith('Bearer ')
241
+ ? req.headers.authorization.slice(7).trim()
242
+ : null;
243
+ const producer = bearer
244
+ ? findProducerByHash(this.db, hashToken(bearer, this.auth.pepper))
245
+ : undefined;
246
+ if (!producer || producer.revoked_at) {
247
+ socket.write('HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n');
248
+ socket.destroy();
249
+ return;
250
+ }
251
+ this.wss.handleUpgrade(req, socket, head, (ws) => {
252
+ this.onConnection(ws, producer.id, producer.name);
253
+ });
254
+ });
255
+ }
256
+ getSession(producerId) {
257
+ return this.sessions.get(producerId);
258
+ }
259
+ offeringStatus(offering) {
260
+ const session = this.sessions.get(offering.producer_id);
261
+ if (!session)
262
+ return 'offline';
263
+ if (session.backendStatus.get(offering.backend_id)?.state === 'degraded')
264
+ return 'degraded';
265
+ return 'online';
266
+ }
267
+ openRequest(session, init) {
268
+ return new TunnelRequest(session, init, this.config);
269
+ }
270
+ close() {
271
+ clearInterval(this.sweeper);
272
+ for (const session of this.sessions.values()) {
273
+ session.ws.terminate();
274
+ }
275
+ this.sessions.clear();
276
+ this.wss.close();
277
+ }
278
+ onConnection(ws, producerId, name) {
279
+ // latest-wins: a fresh connection replaces the old one for this producer
280
+ const existing = this.sessions.get(producerId);
281
+ if (existing) {
282
+ existing.ws.close(4000, 'replaced');
283
+ }
284
+ const session = {
285
+ producerId,
286
+ name,
287
+ ws,
288
+ backendStatus: new Map(),
289
+ lastHeartbeat: Date.now(),
290
+ requests: new Map(),
291
+ };
292
+ this.sessions.set(producerId, session);
293
+ const wire = (msg) => ws.send(JSON.stringify(msg));
294
+ wire({ type: 'hello', wireVersion: WIRE_VERSION });
295
+ this.log.info({ producer: name }, 'producer tunnel connected');
296
+ ws.on('message', (data, isBinary) => {
297
+ try {
298
+ if (isBinary) {
299
+ const frame = decodeChunkFrame(data);
300
+ session.requests.get(frame.requestId)?.handleChunk(frame.payload);
301
+ return;
302
+ }
303
+ const msg = parseControlMessage(data.toString('utf8'));
304
+ this.handleControl(session, msg, wire);
305
+ }
306
+ catch (err) {
307
+ this.log.warn({ producer: name, err: err instanceof Error ? err.message : err }, 'bad tunnel frame');
308
+ ws.close(1008, 'bad frame');
309
+ }
310
+ });
311
+ ws.on('close', () => {
312
+ if (this.sessions.get(producerId) === session) {
313
+ this.sessions.delete(producerId);
314
+ }
315
+ for (const request of [...session.requests.values()]) {
316
+ request.handleSessionClosed();
317
+ }
318
+ this.log.info({ producer: name }, 'producer tunnel closed');
319
+ });
320
+ ws.on('error', (err) => {
321
+ this.log.debug({ producer: name, err: err.message }, 'tunnel socket error');
322
+ });
323
+ }
324
+ handleControl(session, msg, wire) {
325
+ switch (msg.type) {
326
+ case 'register': {
327
+ const raw = msg.offerings;
328
+ const accepted = [];
329
+ const rejected = [];
330
+ if (raw.length > MAX_OFFERINGS) {
331
+ rejected.push({ alias: '*', reason: `too many offerings (max ${MAX_OFFERINGS})` });
332
+ }
333
+ else {
334
+ for (const item of raw) {
335
+ const check = this.validateOffering(session.name, item);
336
+ if ('reason' in check) {
337
+ rejected.push({ alias: check.alias, reason: check.reason });
338
+ }
339
+ else {
340
+ accepted.push(check.offering);
341
+ }
342
+ }
343
+ if (accepted.length > 0 || raw.length === 0) {
344
+ upsertOfferings(this.db, session.producerId, accepted);
345
+ }
346
+ }
347
+ wire({ type: 'registered', accepted: accepted.map((o) => o.alias), rejected });
348
+ break;
349
+ }
350
+ case 'heartbeat': {
351
+ session.lastHeartbeat = Date.now();
352
+ session.backendStatus.clear();
353
+ for (const [id, s] of Object.entries(msg.backendStatus ?? {})) {
354
+ session.backendStatus.set(id, s);
355
+ }
356
+ break;
357
+ }
358
+ case 'response.head': {
359
+ session.requests.get(msg.requestId)?.handleHead(msg.status, msg.headers ?? {});
360
+ break;
361
+ }
362
+ case 'response.end': {
363
+ session.requests.get(msg.requestId)?.handleEnd();
364
+ break;
365
+ }
366
+ case 'response.error': {
367
+ session.requests
368
+ .get(msg.requestId)
369
+ ?.handleError(String(msg.code), String(msg.message ?? ''));
370
+ break;
371
+ }
372
+ default:
373
+ this.log.debug({ producer: session.name }, 'ignored control message');
374
+ }
375
+ }
376
+ validateOffering(producerName, item) {
377
+ const o = item;
378
+ const alias = typeof o.alias === 'string' ? o.alias : '(missing)';
379
+ if (typeof o.alias !== 'string' ||
380
+ typeof o.upstreamModel !== 'string' ||
381
+ typeof o.backendId !== 'string') {
382
+ return { alias, reason: 'alias, upstreamModel and backendId are required strings' };
383
+ }
384
+ if (!o.alias.startsWith(`${producerName}/`)) {
385
+ return { alias: o.alias, reason: `alias must start with your namespace '${producerName}/'` };
386
+ }
387
+ if (!isValidAlias(o.alias)) {
388
+ return {
389
+ alias: o.alias,
390
+ reason: 'alias must be lowercase namespace/name ([a-z0-9][a-z0-9._-])',
391
+ };
392
+ }
393
+ if (!o.protocol || !PROTOCOLS.includes(o.protocol)) {
394
+ return { alias: o.alias, reason: 'protocol must be openai, anthropic or responses' };
395
+ }
396
+ if (o.upstreamModel.length === 0) {
397
+ return { alias: o.alias, reason: 'upstreamModel must be a real backend model id' };
398
+ }
399
+ const maxConcurrency = Number(o.maxConcurrency ?? 1);
400
+ if (!Number.isInteger(maxConcurrency) || maxConcurrency < 1 || maxConcurrency > 64) {
401
+ return { alias: o.alias, reason: 'maxConcurrency must be an integer 1..64' };
402
+ }
403
+ return {
404
+ offering: {
405
+ alias: o.alias,
406
+ protocol: o.protocol,
407
+ upstreamModel: o.upstreamModel,
408
+ backendId: o.backendId,
409
+ maxConcurrency,
410
+ },
411
+ alias: o.alias,
412
+ };
413
+ }
414
+ sweep() {
415
+ const now = Date.now();
416
+ for (const session of this.sessions.values()) {
417
+ if (now - session.lastHeartbeat > HEARTBEAT_TIMEOUT_MS) {
418
+ this.log.info({ producer: session.name }, 'heartbeat timeout, terminating tunnel');
419
+ session.ws.terminate();
420
+ }
421
+ }
422
+ }
423
+ }
424
+ //# sourceMappingURL=tunnel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tunnel.js","sourceRoot":"","sources":["../src/tunnel.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@aweshare/hub",
3
+ "version": "0.2.0",
4
+ "private": true,
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "scripts": {
8
+ "build": "tsc -b"
9
+ },
10
+ "dependencies": {
11
+ "aweshare-protocol": "workspace:*",
12
+ "better-sqlite3": "^12.2.0",
13
+ "pino": "^9.7.0",
14
+ "ws": "^8.18.3"
15
+ },
16
+ "devDependencies": {
17
+ "@types/better-sqlite3": "^7.6.13",
18
+ "@types/ws": "^8.18.1",
19
+ "typescript": "^5.8.3"
20
+ }
21
+ }
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env node
2
+ // Umbrella CLI: `aweshare hub ...` / `aweshare agent ...`.
3
+ // Dev convenience — the real entry points live in apps/hub and apps/agent.
4
+ import { readFileSync } from 'node:fs'
5
+
6
+ const [, , cmd, ...rest] = process.argv
7
+
8
+ const routes = {
9
+ hub: new URL('../apps/hub/dist/cli.js', import.meta.url).href,
10
+ agent: new URL('../apps/agent/dist/cli.js', import.meta.url).href,
11
+ }
12
+
13
+ async function main() {
14
+ if (cmd === '-v' || cmd === '--version') {
15
+ const pkg = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'))
16
+ console.log(`aweshare ${pkg.version}`)
17
+ return
18
+ }
19
+ if (!cmd || cmd === 'help' || cmd === '--help' || cmd === '-h') {
20
+ console.log(`aweshare — local-first AI capability relay
21
+
22
+ Usage:
23
+ aweshare hub <command> hub side: init, serve, token, grant, consumer, usage
24
+ aweshare agent <command> producer side: init, start, doctor, grant, revoke, list
25
+
26
+ Install (published): npm install -g aweshare
27
+ From source: pnpm install && pnpm build, then pnpm link --global`)
28
+ return
29
+ }
30
+ const target = Object.hasOwn(routes, cmd) ? routes[cmd] : undefined
31
+ if (!target) {
32
+ console.error(`unknown target '${cmd}' — expected 'hub' or 'agent'`)
33
+ process.exitCode = 1
34
+ return
35
+ }
36
+ process.argv = [process.argv[0], `aweshare-${cmd}`, ...rest]
37
+ await import(target)
38
+ }
39
+
40
+ main().catch((err) => {
41
+ console.error(err instanceof Error ? err.stack ?? err.message : err)
42
+ process.exit(1)
43
+ })
package/package.json ADDED
@@ -0,0 +1,47 @@
1
+ {
2
+ "name": "aweshare",
3
+ "version": "0.2.0",
4
+ "type": "module",
5
+ "description": "Open-source, local-first AI capability relay",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/mugpeng/aweshare.git"
10
+ },
11
+ "bin": {
12
+ "aweshare": "./bin/aweshare.mjs"
13
+ },
14
+ "engines": {
15
+ "node": ">=22"
16
+ },
17
+ "files": [
18
+ "bin",
19
+ "apps/hub/dist",
20
+ "apps/hub/package.json",
21
+ "apps/agent/dist",
22
+ "apps/agent/package.json"
23
+ ],
24
+ "publishConfig": {
25
+ "access": "public"
26
+ },
27
+ "dependencies": {
28
+ "better-sqlite3": "^12.2.0",
29
+ "pino": "^9.7.0",
30
+ "smol-toml": "^1.4.2",
31
+ "ws": "^8.18.3",
32
+ "aweshare-protocol": "0.2.0"
33
+ },
34
+ "devDependencies": {
35
+ "@anthropic-ai/sdk": "^0.117.1",
36
+ "@biomejs/biome": "^2.1.4",
37
+ "@types/node": "^22.15.0",
38
+ "openai": "^7.4.0",
39
+ "typescript": "^5.8.3",
40
+ "vitest": "^3.2.4"
41
+ },
42
+ "scripts": {
43
+ "build": "tsc -b",
44
+ "test": "vitest run",
45
+ "check": "biome check ."
46
+ }
47
+ }