@advicenxt/sbp-server 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 (63) hide show
  1. package/benchmarks/bench.ts +272 -0
  2. package/dist/auth.d.ts +20 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +69 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/blackboard.d.ts +84 -0
  7. package/dist/blackboard.d.ts.map +1 -0
  8. package/dist/blackboard.js +502 -0
  9. package/dist/blackboard.js.map +1 -0
  10. package/dist/cli.d.ts +7 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +102 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/conditions.d.ts +27 -0
  15. package/dist/conditions.d.ts.map +1 -0
  16. package/dist/conditions.js +240 -0
  17. package/dist/conditions.js.map +1 -0
  18. package/dist/decay.d.ts +21 -0
  19. package/dist/decay.d.ts.map +1 -0
  20. package/dist/decay.js +88 -0
  21. package/dist/decay.js.map +1 -0
  22. package/dist/index.d.ts +13 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +13 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/rate-limiter.d.ts +21 -0
  27. package/dist/rate-limiter.d.ts.map +1 -0
  28. package/dist/rate-limiter.js +75 -0
  29. package/dist/rate-limiter.js.map +1 -0
  30. package/dist/server.d.ts +63 -0
  31. package/dist/server.d.ts.map +1 -0
  32. package/dist/server.js +401 -0
  33. package/dist/server.js.map +1 -0
  34. package/dist/store.d.ts +54 -0
  35. package/dist/store.d.ts.map +1 -0
  36. package/dist/store.js +55 -0
  37. package/dist/store.js.map +1 -0
  38. package/dist/types.d.ts +247 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +26 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/validation.d.ts +296 -0
  43. package/dist/validation.d.ts.map +1 -0
  44. package/dist/validation.js +205 -0
  45. package/dist/validation.js.map +1 -0
  46. package/eslint.config.js +26 -0
  47. package/package.json +66 -0
  48. package/src/auth.ts +89 -0
  49. package/src/blackboard.test.ts +287 -0
  50. package/src/blackboard.ts +651 -0
  51. package/src/cli.ts +116 -0
  52. package/src/conditions.ts +305 -0
  53. package/src/conformance.test.ts +686 -0
  54. package/src/decay.ts +103 -0
  55. package/src/index.ts +24 -0
  56. package/src/rate-limiter.ts +104 -0
  57. package/src/server.integration.test.ts +436 -0
  58. package/src/server.ts +500 -0
  59. package/src/store.ts +108 -0
  60. package/src/types.ts +314 -0
  61. package/src/validation.ts +251 -0
  62. package/tsconfig.eslint.json +5 -0
  63. package/tsconfig.json +20 -0
@@ -0,0 +1,502 @@
1
+ /**
2
+ * SBP Blackboard - Core State Management
3
+ */
4
+ import { v7 as uuidv7 } from "uuid";
5
+ import { MemoryStore } from "./store.js";
6
+ import { computeIntensity, isEvaporated, defaultDecay } from "./decay.js";
7
+ import { evaluateCondition, createSnapshot } from "./conditions.js";
8
+ import { createHash } from "crypto";
9
+ export class Blackboard {
10
+ store;
11
+ scents = new Map();
12
+ triggerHandlers = new Map();
13
+ emissionHistory = [];
14
+ evaluationTimer = null;
15
+ startTime = Date.now();
16
+ options;
17
+ constructor(options = {}) {
18
+ this.store = options.store ?? new MemoryStore();
19
+ this.options = {
20
+ evaluationInterval: options.evaluationInterval ?? 100,
21
+ defaultDecay: options.defaultDecay ?? defaultDecay(),
22
+ defaultTtlFloor: options.defaultTtlFloor ?? 0.01,
23
+ maxPheromones: options.maxPheromones ?? 100000,
24
+ trackEmissionHistory: options.trackEmissionHistory ?? true,
25
+ emissionHistoryWindow: options.emissionHistoryWindow ?? 60000,
26
+ };
27
+ }
28
+ // ==========================================================================
29
+ // EMIT
30
+ // ==========================================================================
31
+ emit(params) {
32
+ const now = Date.now();
33
+ const { trail, type, intensity, decay = this.options.defaultDecay, payload = {}, tags = [], merge_strategy = "reinforce", source_agent, } = params;
34
+ // Validate intensity
35
+ const clampedIntensity = Math.max(0, Math.min(1, intensity));
36
+ // Track emission for rate conditions
37
+ if (this.options.trackEmissionHistory) {
38
+ this.emissionHistory.push({ trail, type, timestamp: now });
39
+ this.pruneEmissionHistory(now);
40
+ }
41
+ // Generate payload hash for matching
42
+ const payloadHash = this.hashPayload(payload);
43
+ // Find existing pheromone for merge
44
+ let existing;
45
+ if (merge_strategy !== "new") {
46
+ for (const p of this.store.values()) {
47
+ if (p.trail === trail &&
48
+ p.type === type &&
49
+ this.hashPayload(p.payload) === payloadHash &&
50
+ !isEvaporated(p, now)) {
51
+ existing = p;
52
+ break;
53
+ }
54
+ }
55
+ }
56
+ if (existing) {
57
+ const previousIntensity = computeIntensity(existing, now);
58
+ let action = "reinforced";
59
+ switch (merge_strategy) {
60
+ case "reinforce":
61
+ existing.initial_intensity = clampedIntensity;
62
+ existing.last_reinforced_at = now;
63
+ action = "reinforced";
64
+ break;
65
+ case "replace":
66
+ existing.initial_intensity = clampedIntensity;
67
+ existing.last_reinforced_at = now;
68
+ existing.payload = payload;
69
+ existing.tags = tags;
70
+ if (source_agent)
71
+ existing.source_agent = source_agent;
72
+ action = "replaced";
73
+ break;
74
+ case "max":
75
+ existing.initial_intensity = Math.max(previousIntensity, clampedIntensity);
76
+ existing.last_reinforced_at = now;
77
+ action = "merged";
78
+ break;
79
+ case "add":
80
+ existing.initial_intensity = Math.min(1, previousIntensity + clampedIntensity);
81
+ existing.last_reinforced_at = now;
82
+ action = "merged";
83
+ break;
84
+ }
85
+ return {
86
+ pheromone_id: existing.id,
87
+ action,
88
+ previous_intensity: previousIntensity,
89
+ new_intensity: computeIntensity(existing, now),
90
+ };
91
+ }
92
+ // Create new pheromone
93
+ const id = uuidv7();
94
+ const pheromone = {
95
+ id,
96
+ trail,
97
+ type,
98
+ emitted_at: now,
99
+ last_reinforced_at: now,
100
+ initial_intensity: clampedIntensity,
101
+ decay_model: decay,
102
+ payload,
103
+ source_agent,
104
+ tags,
105
+ ttl_floor: this.options.defaultTtlFloor,
106
+ };
107
+ this.store.set(id, pheromone);
108
+ // Trigger GC if needed
109
+ if (this.store.size > this.options.maxPheromones) {
110
+ this.gc();
111
+ }
112
+ return {
113
+ pheromone_id: id,
114
+ action: "created",
115
+ new_intensity: clampedIntensity,
116
+ };
117
+ }
118
+ // ==========================================================================
119
+ // SNIFF
120
+ // ==========================================================================
121
+ sniff(params = {}) {
122
+ const now = Date.now();
123
+ const { trails, types, min_intensity = 0, max_age_ms, tags, limit = 100, include_evaporated = false, } = params;
124
+ const results = [];
125
+ const aggregates = new Map();
126
+ for (const p of this.store.values()) {
127
+ // Filter by trail
128
+ if (trails && trails.length > 0 && !trails.includes(p.trail))
129
+ continue;
130
+ // Filter by type
131
+ if (types && types.length > 0 && !types.includes(p.type))
132
+ continue;
133
+ const intensity = computeIntensity(p, now);
134
+ // Filter evaporated
135
+ if (!include_evaporated && intensity < p.ttl_floor)
136
+ continue;
137
+ // Filter by min intensity
138
+ if (intensity < min_intensity)
139
+ continue;
140
+ // Filter by max age
141
+ if (max_age_ms !== undefined && now - p.emitted_at > max_age_ms)
142
+ continue;
143
+ // Filter by tags
144
+ if (tags && !this.matchTags(p.tags, tags))
145
+ continue;
146
+ results.push(createSnapshot(p, now));
147
+ // Aggregate
148
+ const key = `${p.trail}/${p.type}`;
149
+ const agg = aggregates.get(key) || { count: 0, sum: 0, max: 0 };
150
+ agg.count++;
151
+ agg.sum += intensity;
152
+ agg.max = Math.max(agg.max, intensity);
153
+ aggregates.set(key, agg);
154
+ }
155
+ // Sort by intensity descending
156
+ results.sort((a, b) => b.current_intensity - a.current_intensity);
157
+ // Build aggregates result
158
+ const aggregatesResult = {};
159
+ for (const [key, agg] of aggregates) {
160
+ aggregatesResult[key] = {
161
+ count: agg.count,
162
+ sum_intensity: agg.sum,
163
+ max_intensity: agg.max,
164
+ avg_intensity: agg.count > 0 ? agg.sum / agg.count : 0,
165
+ };
166
+ }
167
+ return {
168
+ timestamp: now,
169
+ pheromones: results.slice(0, limit),
170
+ aggregates: aggregatesResult,
171
+ };
172
+ }
173
+ // ==========================================================================
174
+ // REGISTER_SCENT
175
+ // ==========================================================================
176
+ registerScent(params) {
177
+ const { scent_id, agent_endpoint, condition, cooldown_ms = 0, activation_payload = {}, trigger_mode = "level", hysteresis = 0, max_execution_ms = 30000, context_trails, } = params;
178
+ const isUpdate = this.scents.has(scent_id);
179
+ const scent = {
180
+ scent_id,
181
+ agent_endpoint,
182
+ condition,
183
+ cooldown_ms,
184
+ activation_payload,
185
+ trigger_mode,
186
+ hysteresis,
187
+ max_execution_ms,
188
+ last_triggered_at: null,
189
+ last_condition_met: false,
190
+ context_trails,
191
+ };
192
+ this.scents.set(scent_id, scent);
193
+ // Evaluate current state
194
+ const now = Date.now();
195
+ const evalResult = evaluateCondition(condition, {
196
+ pheromones: [...this.store.values()],
197
+ now,
198
+ emissionHistory: this.emissionHistory,
199
+ });
200
+ return {
201
+ scent_id,
202
+ status: isUpdate ? "updated" : "registered",
203
+ current_condition_state: {
204
+ met: evalResult.met,
205
+ },
206
+ };
207
+ }
208
+ // ==========================================================================
209
+ // DEREGISTER_SCENT
210
+ // ==========================================================================
211
+ deregisterScent(params) {
212
+ const { scent_id } = params;
213
+ if (this.scents.has(scent_id)) {
214
+ this.scents.delete(scent_id);
215
+ this.triggerHandlers.delete(scent_id);
216
+ return { scent_id, status: "deregistered" };
217
+ }
218
+ return { scent_id, status: "not_found" };
219
+ }
220
+ // ==========================================================================
221
+ // EVAPORATE
222
+ // ==========================================================================
223
+ evaporate(params = {}) {
224
+ const now = Date.now();
225
+ const { trail, types, older_than_ms, below_intensity, tags } = params;
226
+ const toRemove = [];
227
+ const trailsAffected = new Set();
228
+ for (const [id, p] of this.store.entries()) {
229
+ if (trail && p.trail !== trail)
230
+ continue;
231
+ if (types && types.length > 0 && !types.includes(p.type))
232
+ continue;
233
+ if (older_than_ms !== undefined && now - p.emitted_at < older_than_ms)
234
+ continue;
235
+ if (below_intensity !== undefined && computeIntensity(p, now) >= below_intensity)
236
+ continue;
237
+ if (tags && !this.matchTags(p.tags, tags))
238
+ continue;
239
+ toRemove.push(id);
240
+ trailsAffected.add(p.trail);
241
+ }
242
+ for (const id of toRemove) {
243
+ this.store.delete(id);
244
+ }
245
+ return {
246
+ evaporated_count: toRemove.length,
247
+ trails_affected: [...trailsAffected],
248
+ };
249
+ }
250
+ // ==========================================================================
251
+ // INSPECT
252
+ // ==========================================================================
253
+ inspect(params = {}) {
254
+ const now = Date.now();
255
+ const include = params.include ?? ["trails", "scents", "stats"];
256
+ const result = { timestamp: now };
257
+ if (include.includes("trails")) {
258
+ const trailMap = new Map();
259
+ for (const p of this.store.values()) {
260
+ if (isEvaporated(p, now))
261
+ continue;
262
+ const current = trailMap.get(p.trail) || { count: 0, intensity: 0 };
263
+ current.count++;
264
+ current.intensity += computeIntensity(p, now);
265
+ trailMap.set(p.trail, current);
266
+ }
267
+ result.trails = [...trailMap.entries()].map(([name, data]) => ({
268
+ name,
269
+ pheromone_count: data.count,
270
+ total_intensity: data.intensity,
271
+ avg_intensity: data.count > 0 ? data.intensity / data.count : 0,
272
+ }));
273
+ }
274
+ if (include.includes("scents")) {
275
+ result.scents = [...this.scents.values()].map((s) => ({
276
+ scent_id: s.scent_id,
277
+ agent_endpoint: s.agent_endpoint,
278
+ condition_met: s.last_condition_met,
279
+ in_cooldown: s.last_triggered_at
280
+ ? now - s.last_triggered_at < s.cooldown_ms
281
+ : false,
282
+ last_triggered_at: s.last_triggered_at,
283
+ }));
284
+ }
285
+ if (include.includes("stats")) {
286
+ let activeCount = 0;
287
+ for (const p of this.store.values()) {
288
+ if (!isEvaporated(p, now))
289
+ activeCount++;
290
+ }
291
+ result.stats = {
292
+ total_pheromones: this.store.size,
293
+ active_pheromones: activeCount,
294
+ total_scents: this.scents.size,
295
+ uptime_ms: now - this.startTime,
296
+ };
297
+ }
298
+ return result;
299
+ }
300
+ // ==========================================================================
301
+ // TRIGGER HANDLING
302
+ // ==========================================================================
303
+ /**
304
+ * Register a local handler for a scent
305
+ */
306
+ onTrigger(scentId, handler) {
307
+ this.triggerHandlers.set(scentId, handler);
308
+ }
309
+ /**
310
+ * Remove a local trigger handler
311
+ */
312
+ offTrigger(scentId) {
313
+ this.triggerHandlers.delete(scentId);
314
+ }
315
+ // ==========================================================================
316
+ // EVALUATION LOOP
317
+ // ==========================================================================
318
+ /**
319
+ * Start the background scent evaluation loop
320
+ */
321
+ start() {
322
+ if (this.evaluationTimer)
323
+ return;
324
+ this.evaluationTimer = setInterval(() => {
325
+ this.evaluateScents().catch((err) => {
326
+ console.error("[SBP] Evaluation error:", err);
327
+ });
328
+ }, this.options.evaluationInterval);
329
+ }
330
+ /**
331
+ * Stop the background evaluation loop
332
+ */
333
+ stop() {
334
+ if (this.evaluationTimer) {
335
+ clearInterval(this.evaluationTimer);
336
+ this.evaluationTimer = null;
337
+ }
338
+ }
339
+ /**
340
+ * Evaluate all scents and trigger as needed
341
+ */
342
+ async evaluateScents() {
343
+ const now = Date.now();
344
+ const pheromones = [...this.store.values()];
345
+ for (const scent of this.scents.values()) {
346
+ // Check cooldown
347
+ if (scent.last_triggered_at && now - scent.last_triggered_at < scent.cooldown_ms) {
348
+ continue;
349
+ }
350
+ const evalResult = evaluateCondition(scent.condition, {
351
+ pheromones,
352
+ now,
353
+ emissionHistory: this.emissionHistory,
354
+ });
355
+ const shouldTrigger = this.shouldTrigger(scent, evalResult.met, now);
356
+ scent.last_condition_met = evalResult.met;
357
+ if (shouldTrigger) {
358
+ scent.last_triggered_at = now;
359
+ await this.dispatchTrigger(scent, evalResult, now);
360
+ }
361
+ }
362
+ }
363
+ /**
364
+ * Determine if a scent should trigger based on mode
365
+ */
366
+ shouldTrigger(scent, conditionMet, _now) {
367
+ switch (scent.trigger_mode) {
368
+ case "level":
369
+ return conditionMet;
370
+ case "edge_rising":
371
+ return conditionMet && !scent.last_condition_met;
372
+ case "edge_falling":
373
+ return !conditionMet && scent.last_condition_met;
374
+ default:
375
+ return conditionMet;
376
+ }
377
+ }
378
+ /**
379
+ * Dispatch a trigger to the agent
380
+ */
381
+ async dispatchTrigger(scent, evalResult, now) {
382
+ // Build context pheromones
383
+ const contextTrails = scent.context_trails || [];
384
+ const contextPheromones = [];
385
+ if (contextTrails.length > 0) {
386
+ for (const p of this.store.values()) {
387
+ if (contextTrails.includes(p.trail) && !isEvaporated(p, now)) {
388
+ contextPheromones.push(createSnapshot(p, now));
389
+ }
390
+ }
391
+ }
392
+ else {
393
+ // Include matching pheromones
394
+ for (const id of evalResult.matchingPheromoneIds) {
395
+ const p = this.store.get(id);
396
+ if (p) {
397
+ contextPheromones.push(createSnapshot(p, now));
398
+ }
399
+ }
400
+ }
401
+ const payload = {
402
+ scent_id: scent.scent_id,
403
+ triggered_at: now,
404
+ condition_snapshot: {
405
+ [scent.scent_id]: {
406
+ value: evalResult.value,
407
+ pheromone_ids: evalResult.matchingPheromoneIds,
408
+ },
409
+ },
410
+ context_pheromones: contextPheromones,
411
+ activation_payload: scent.activation_payload,
412
+ };
413
+ // Try local handler first
414
+ const localHandler = this.triggerHandlers.get(scent.scent_id);
415
+ if (localHandler) {
416
+ try {
417
+ await localHandler(payload);
418
+ }
419
+ catch (err) {
420
+ console.error(`[SBP] Trigger handler error for ${scent.scent_id}:`, err);
421
+ }
422
+ return;
423
+ }
424
+ // Otherwise, HTTP POST to endpoint
425
+ try {
426
+ const response = await fetch(scent.agent_endpoint, {
427
+ method: "POST",
428
+ headers: {
429
+ "Content-Type": "application/json",
430
+ "X-SBP-Version": "0.1",
431
+ },
432
+ body: JSON.stringify({
433
+ jsonrpc: "2.0",
434
+ method: "sbp/trigger",
435
+ params: payload,
436
+ }),
437
+ signal: AbortSignal.timeout(scent.max_execution_ms),
438
+ });
439
+ if (!response.ok) {
440
+ console.error(`[SBP] Trigger failed for ${scent.scent_id}: ${response.status}`);
441
+ }
442
+ }
443
+ catch (err) {
444
+ console.error(`[SBP] Trigger dispatch error for ${scent.scent_id}:`, err);
445
+ }
446
+ }
447
+ // ==========================================================================
448
+ // UTILITIES
449
+ // ==========================================================================
450
+ /**
451
+ * Garbage collect evaporated pheromones
452
+ */
453
+ gc() {
454
+ const now = Date.now();
455
+ const toRemove = [];
456
+ for (const [id, p] of this.store.entries()) {
457
+ if (isEvaporated(p, now)) {
458
+ toRemove.push(id);
459
+ }
460
+ }
461
+ for (const id of toRemove) {
462
+ this.store.delete(id);
463
+ }
464
+ return toRemove.length;
465
+ }
466
+ /**
467
+ * Get raw pheromone count (for testing)
468
+ */
469
+ get size() {
470
+ return this.store.size;
471
+ }
472
+ /**
473
+ * Get scent count
474
+ */
475
+ get scentCount() {
476
+ return this.scents.size;
477
+ }
478
+ hashPayload(payload) {
479
+ const content = JSON.stringify(payload, Object.keys(payload).sort());
480
+ return createHash("sha256").update(content).digest("hex").slice(0, 16);
481
+ }
482
+ matchTags(tags, filter) {
483
+ if (filter.any && filter.any.length > 0) {
484
+ if (!filter.any.some((t) => tags.includes(t)))
485
+ return false;
486
+ }
487
+ if (filter.all && filter.all.length > 0) {
488
+ if (!filter.all.every((t) => tags.includes(t)))
489
+ return false;
490
+ }
491
+ if (filter.none && filter.none.length > 0) {
492
+ if (filter.none.some((t) => tags.includes(t)))
493
+ return false;
494
+ }
495
+ return true;
496
+ }
497
+ pruneEmissionHistory(now) {
498
+ const cutoff = now - this.options.emissionHistoryWindow;
499
+ this.emissionHistory = this.emissionHistory.filter((e) => e.timestamp >= cutoff);
500
+ }
501
+ }
502
+ //# sourceMappingURL=blackboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"blackboard.js","sourceRoot":"","sources":["../src/blackboard.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * SBP Server CLI
4
+ * Streamable HTTP with SSE transport
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;GAGG"}
package/dist/cli.js ADDED
@@ -0,0 +1,102 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * SBP Server CLI
4
+ * Streamable HTTP with SSE transport
5
+ */
6
+ import { SbpServer } from "./server.js";
7
+ const args = process.argv.slice(2);
8
+ function parseArgs(args) {
9
+ const result = {};
10
+ for (let i = 0; i < args.length; i++) {
11
+ const arg = args[i];
12
+ if (arg.startsWith("--")) {
13
+ const key = arg.slice(2);
14
+ const next = args[i + 1];
15
+ if (next && !next.startsWith("--")) {
16
+ result[key] = next;
17
+ i++;
18
+ }
19
+ else {
20
+ result[key] = true;
21
+ }
22
+ }
23
+ }
24
+ return result;
25
+ }
26
+ function printHelp() {
27
+ console.log(`
28
+ SBP Server - Stigmergic Blackboard Protocol
29
+
30
+ Usage:
31
+ sbp-server [options]
32
+
33
+ Options:
34
+ --port <number> Port to listen on (default: 3000)
35
+ --host <string> Host to bind to (default: localhost)
36
+ --log Enable request logging
37
+ --api-key <keys> Comma-separated API keys for authentication
38
+ --rate-limit <n> Max requests per minute per agent (default: off)
39
+ --help Show this help message
40
+
41
+ Transport:
42
+ Streamable HTTP with SSE (Server-Sent Events)
43
+ - POST /sbp Client -> Server messages
44
+ - GET /sbp Server -> Client triggers (SSE stream)
45
+
46
+ Authentication:
47
+ When --api-key is set, all requests must include:
48
+ Authorization: Bearer <api-key>
49
+ API keys can also be set via SBP_API_KEYS env variable.
50
+
51
+ Examples:
52
+ sbp-server
53
+ sbp-server --port 8080
54
+ sbp-server --host 0.0.0.0 --port 3000 --log
55
+ sbp-server --api-key key1,key2 --rate-limit 500
56
+ `);
57
+ }
58
+ async function main() {
59
+ const options = parseArgs(args);
60
+ if (options.help) {
61
+ printHelp();
62
+ process.exit(0);
63
+ }
64
+ // Parse API keys from CLI arg or env variable
65
+ const apiKeyArg = options["api-key"] || process.env.SBP_API_KEYS || "";
66
+ const apiKeys = apiKeyArg
67
+ .split(",")
68
+ .map((k) => k.trim())
69
+ .filter(Boolean);
70
+ // Parse rate limit
71
+ const rateLimitMax = options["rate-limit"]
72
+ ? parseInt(options["rate-limit"], 10)
73
+ : undefined;
74
+ const server = new SbpServer({
75
+ port: options.port ? parseInt(options.port, 10) : 3000,
76
+ host: options.host || "localhost",
77
+ logging: !!options.log,
78
+ auth: apiKeys.length > 0
79
+ ? { apiKeys, requireAuth: true }
80
+ : undefined,
81
+ rateLimit: rateLimitMax
82
+ ? { maxRequests: rateLimitMax, windowMs: 60000 }
83
+ : undefined,
84
+ });
85
+ // Graceful shutdown
86
+ const shutdown = async () => {
87
+ console.log("\n[SBP] Shutting down...");
88
+ await server.stop();
89
+ process.exit(0);
90
+ };
91
+ process.on("SIGINT", shutdown);
92
+ process.on("SIGTERM", shutdown);
93
+ try {
94
+ await server.start();
95
+ }
96
+ catch (err) {
97
+ console.error("[SBP] Failed to start server:", err);
98
+ process.exit(1);
99
+ }
100
+ }
101
+ main();
102
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Scent condition evaluation
3
+ */
4
+ import type { Pheromone, PheromoneSnapshot, ScentCondition } from "./types.js";
5
+ export interface EvaluationContext {
6
+ pheromones: Pheromone[];
7
+ now: number;
8
+ emissionHistory?: Array<{
9
+ trail: string;
10
+ type: string;
11
+ timestamp: number;
12
+ }>;
13
+ }
14
+ export interface EvaluationResult {
15
+ met: boolean;
16
+ value: number;
17
+ matchingPheromoneIds: string[];
18
+ }
19
+ /**
20
+ * Evaluate a scent condition against the current environment
21
+ */
22
+ export declare function evaluateCondition(condition: ScentCondition, ctx: EvaluationContext): EvaluationResult;
23
+ /**
24
+ * Create a snapshot of a pheromone for trigger payloads
25
+ */
26
+ export declare function createSnapshot(pheromone: Pheromone, now: number): PheromoneSnapshot;
27
+ //# sourceMappingURL=conditions.d.ts.map