@diegoaltoworks/chatter 0.50.0 โ†’ 0.51.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/README.md CHANGED
@@ -26,6 +26,12 @@
26
26
  - โšก **High Performance**: Built on Hono with streaming support
27
27
  - ๐Ÿ›ก๏ธ **Security First**: Rate limiting, CORS, referrer checking, and input guardrails
28
28
  - ๐Ÿ’ธ **Usage Metering**: Per-caller and global daily caps for paid features, multi-instance safe, via `@diegoaltoworks/chatter/usage` ([guide](./docs/usage.md))
29
+ - ๐Ÿ’ฌ **Channels**: Built-in WhatsApp transport plus a Channel SPI for plugging in any other one โ€” allowlist/mute gates, reply rate-limiting, and a shared inbound pipeline every channel reuses ([WhatsApp guide](./docs/channels.md), [build your own](./docs/build-a-channel.md))
30
+ - ๐Ÿงฉ **Flows**: Multi-turn, schema-driven slot-filling for structured conversations, with hybrid keyword + LLM intent matching ([guide](./docs/flows.md))
31
+ - ๐Ÿ–ผ๏ธ **Images**: On-demand generation and editing with cache-before-spend ordering and optional Cloudinary upload ([guide](./docs/images.md))
32
+ - ๐ŸŽญ **Personas**: Windowed, per-contact prompt layers and named greetings from a JSON registry ([guide](./docs/personas.md))
33
+ - ๐Ÿ—‚๏ธ **Conversation History**: Structural, multi-turn context store, multi-instance safe and host-replaceable ([guide](./docs/history.md))
34
+ - โฐ **Scheduler**: Exactly-once outbound scheduling with a fire-time grace window, multi-instance safe ([guide](./docs/scheduler.md))
29
35
  - ๐Ÿ“ฆ **Framework Agnostic**: Works with any JavaScript framework or vanilla JS
30
36
  - ๐ŸŽฏ **TypeScript**: Fully typed for excellent developer experience
31
37
 
@@ -84,13 +90,23 @@ is runtime-neutral. Development and the quality gates run on Bun.
84
90
 
85
91
  ## Documentation
86
92
 
87
- Complete guides for setup, deployment, and integration:
93
+ Complete guides for setup, deployment, and integration โ€” see
94
+ [docs/index.md](./docs/index.md) for the full, ordered walkthrough:
88
95
 
89
96
  - **[Requirements](./docs/requirements.md)** - OpenAI, Turso, Clerk setup and pricing
90
97
  - **[Server Setup](./docs/server.md)** - Configuration, knowledge base, prompts, API keys
91
98
  - **[Client Integration](./docs/client.md)** - Widgets, React components, theming
99
+ - **[UI Integrations](./docs/integrations.md)** - OpenAI-compatible API, headless mode, bring-your-own-brain
92
100
  - **[Usage Metering](./docs/usage.md)** - Daily spend caps for paid features
101
+ - **[Personas](./docs/personas.md)** - Dynamic prompt layers and named greetings
102
+ - **[WhatsApp Channel](./docs/channels.md)** - Link a WhatsApp number as a transport
103
+ - **[Building a Channel](./docs/build-a-channel.md)** - Plug in a new transport
104
+ - **[Flows](./docs/flows.md)** - Multi-turn, schema-driven slot-filling flows
105
+ - **[Images](./docs/images.md)** - Generate and cache images on demand
106
+ - **[Conversation History](./docs/history.md)** - Structural, host-replaceable multi-turn context
107
+ - **[Scheduler](./docs/scheduler.md)** - Exactly-once outbound scheduling
93
108
  - **[Deployment](./docs/deployment.md)** - Google Cloud Run, Fly.io, Railway, VPS
109
+ - **[Packaging](./docs/packaging.md)** - The subpath contract and the release chain
94
110
  - **[Testing](./docs/testing.md)** - Comprehensive testing guide
95
111
  - **[Sprint Review](./docs/sprint-review.md)** - Cross-module & security-invariant audit
96
112
  - **[FAQs](./docs/faqs.md)** - Troubleshooting and common questions
@@ -59,8 +59,24 @@ export declare function decideChannelAction(msg: ChannelMessage, config: Channel
59
59
  * Sliding-window rate limiter (pure, injectable clock): true = allowed and
60
60
  * counted. One instance guards one budget โ€” callers wanting separate DM and
61
61
  * group budgets create two (see {@link underReplyRateLimit}).
62
+ *
63
+ * Keyed by chatId, which โ€” unlike an IP โ€” a caller can't rotate at will, but
64
+ * a long-lived deployment still accumulates one entry per chat it has ever
65
+ * seen, including chats that never come back. A global sweep (same shape as
66
+ * `windowBucket.ts`'s) runs at most once per window, on a call for any key,
67
+ * and drops every key whose entries have all fallen out of the window โ€”
68
+ * bounding the map to chats active within roughly the last two windows
69
+ * instead of growing for the life of the process. `allow.size()` reports
70
+ * the current key count, for tests asserting eviction actually happened.
71
+ *
72
+ * @internal `size` is an observability hook for this module's own tests, not
73
+ * part of the public contract โ€” callers should treat the return value as a
74
+ * plain `(key: string) => boolean`.
62
75
  */
63
- export declare function createSlidingWindowRateLimiter(maxPerWindow: number, windowMs: number, now?: () => number): (key: string) => boolean;
76
+ export declare function createSlidingWindowRateLimiter(maxPerWindow: number, windowMs: number, now?: () => number): {
77
+ (key: string): boolean;
78
+ size: () => number;
79
+ };
64
80
  /**
65
81
  * Routes a chat to its DM or group rate limiter so a flood in one can't
66
82
  * spend the other's budget โ€” a DM flood used to be entirely unthrottled
@@ -1 +1 @@
1
- {"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/channels/gates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,YAAY,EAAE,OAAO,CAAC;IACtB,sHAAsH;IACtH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kIAAkI;IAClI,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,GAC9C,OAAO,CAQT;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAUjG;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAC5C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,MAAiB,SAGD,MAAM,KAAG,OAAO,CAY5C;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,iBAAiB,CAAC,EACvD,QAAQ,EAAE;IAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAChF,OAAO,CAET;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,uBAAuB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAE5D,qHAAqH;AACrH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAMT;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,UAAU,CAAC,EACjD,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAET"}
1
+ {"version":3,"file":"gates.d.ts","sourceRoot":"","sources":["../../src/channels/gates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,iFAAiF;AACjF,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,iFAAiF;IACjF,eAAe,EAAE,OAAO,CAAC;IACzB,mEAAmE;IACnE,WAAW,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,YAAY,EAAE,OAAO,CAAC;IACtB,sHAAsH;IACtH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEnE,MAAM,WAAW,iBAAiB;IAChC,gGAAgG;IAChG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,kIAAkI;IAClI,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC,GAC9C,OAAO,CAQT;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,iBAAiB,GAAG,aAAa,CAUjG;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,8BAA8B,CAC5C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAM,MAAiB;UAcR,MAAM,GAAG,OAAO;;EAiBrC;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,iBAAiB,CAAC,EACvD,QAAQ,EAAE;IAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC;IAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAA;CAAE,GAChF,OAAO,CAET;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,MAAM,uBAAuB,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;AAE5D,qHAAqH;AACrH,wBAAgB,gBAAgB,CAC9B,EAAE,EAAE,MAAM,GAAG,SAAS,EACtB,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAMT;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,SAAS,GAAG,UAAU,CAAC,EACjD,QAAQ,EAAE,uBAAuB,GAChC,OAAO,CAET"}
@@ -42,7 +42,7 @@ export interface Channel {
42
42
  stop?(): void | Promise<void>;
43
43
  }
44
44
  export * from "./gates";
45
- export { createInboundPipeline, type InboundPipelineConfig, type InboundPipelineDeps, type InboundPipelineOutcome, type InboundReplySender, type InboundTurn, } from "./pipeline";
45
+ export { createInboundPipeline, type InboundPipeline, type InboundPipelineConfig, type InboundPipelineDeps, type InboundPipelineOutcome, type InboundReplySender, type InboundTurn, } from "./pipeline";
46
46
  export type { ChannelSender, ChannelSenderRegistry } from "./senders";
47
47
  export { createSenderRegistry } from "./senders";
48
48
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,WAAW,OAAO;IACtB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,qBAAqB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/channels/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAEnD,MAAM,WAAW,OAAO;IACtB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACtD;;;;;;OAMG;IACH,IAAI,CAAC,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,qBAAqB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,kBAAkB,EACvB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC"}
@@ -51,18 +51,31 @@ function decideChannelAction(msg, config) {
51
51
  }
52
52
  function createSlidingWindowRateLimiter(maxPerWindow, windowMs, now = Date.now) {
53
53
  const log = /* @__PURE__ */ new Map();
54
- return function allow(key) {
55
- const cutoff = now() - windowMs;
54
+ let lastSweep = now();
55
+ function sweep(current) {
56
+ if (current - lastSweep < windowMs) return;
57
+ lastSweep = current;
58
+ const cutoff = current - windowMs;
59
+ for (const [key, entries] of log) {
60
+ if (!entries.some((t) => t > cutoff)) log.delete(key);
61
+ }
62
+ }
63
+ function allow(key) {
64
+ const current = now();
65
+ sweep(current);
66
+ const cutoff = current - windowMs;
56
67
  const entries = (log.get(key) ?? []).filter((t) => t > cutoff);
57
68
  if (entries.length >= maxPerWindow) {
58
69
  if (entries.length > 0) log.set(key, entries);
59
70
  else log.delete(key);
60
71
  return false;
61
72
  }
62
- entries.push(now());
73
+ entries.push(current);
63
74
  log.set(key, entries);
64
75
  return true;
65
- };
76
+ }
77
+ allow.size = () => log.size;
78
+ return allow;
66
79
  }
67
80
  function underReplyRateLimit(msg, limiters) {
68
81
  return msg.isDirectMessage ? limiters.dm(msg.chatId) : limiters.group(msg.chatId);
@@ -18,18 +18,31 @@ function decideChannelAction(msg, config) {
18
18
  }
19
19
  function createSlidingWindowRateLimiter(maxPerWindow, windowMs, now = Date.now) {
20
20
  const log = /* @__PURE__ */ new Map();
21
- return function allow(key) {
22
- const cutoff = now() - windowMs;
21
+ let lastSweep = now();
22
+ function sweep(current) {
23
+ if (current - lastSweep < windowMs) return;
24
+ lastSweep = current;
25
+ const cutoff = current - windowMs;
26
+ for (const [key, entries] of log) {
27
+ if (!entries.some((t) => t > cutoff)) log.delete(key);
28
+ }
29
+ }
30
+ function allow(key) {
31
+ const current = now();
32
+ sweep(current);
33
+ const cutoff = current - windowMs;
23
34
  const entries = (log.get(key) ?? []).filter((t) => t > cutoff);
24
35
  if (entries.length >= maxPerWindow) {
25
36
  if (entries.length > 0) log.set(key, entries);
26
37
  else log.delete(key);
27
38
  return false;
28
39
  }
29
- entries.push(now());
40
+ entries.push(current);
30
41
  log.set(key, entries);
31
42
  return true;
32
- };
43
+ }
44
+ allow.size = () => log.size;
45
+ return allow;
33
46
  }
34
47
  function underReplyRateLimit(msg, limiters) {
35
48
  return msg.isDirectMessage ? limiters.dm(msg.chatId) : limiters.group(msg.chatId);
@@ -624,18 +624,31 @@ function decideChannelAction(msg, config) {
624
624
  }
625
625
  function createSlidingWindowRateLimiter(maxPerWindow, windowMs, now = Date.now) {
626
626
  const log = /* @__PURE__ */ new Map();
627
- return function allow(key) {
628
- const cutoff = now() - windowMs;
627
+ let lastSweep = now();
628
+ function sweep(current) {
629
+ if (current - lastSweep < windowMs) return;
630
+ lastSweep = current;
631
+ const cutoff = current - windowMs;
632
+ for (const [key, entries] of log) {
633
+ if (!entries.some((t) => t > cutoff)) log.delete(key);
634
+ }
635
+ }
636
+ function allow(key) {
637
+ const current = now();
638
+ sweep(current);
639
+ const cutoff = current - windowMs;
629
640
  const entries = (log.get(key) ?? []).filter((t) => t > cutoff);
630
641
  if (entries.length >= maxPerWindow) {
631
642
  if (entries.length > 0) log.set(key, entries);
632
643
  else log.delete(key);
633
644
  return false;
634
645
  }
635
- entries.push(now());
646
+ entries.push(current);
636
647
  log.set(key, entries);
637
648
  return true;
638
- };
649
+ }
650
+ allow.size = () => log.size;
651
+ return allow;
639
652
  }
640
653
  function underReplyRateLimit(msg, limiters) {
641
654
  return msg.isDirectMessage ? limiters.dm(msg.chatId) : limiters.group(msg.chatId);
@@ -562,18 +562,31 @@ function decideChannelAction(msg, config) {
562
562
  }
563
563
  function createSlidingWindowRateLimiter(maxPerWindow, windowMs, now = Date.now) {
564
564
  const log = /* @__PURE__ */ new Map();
565
- return function allow(key) {
566
- const cutoff = now() - windowMs;
565
+ let lastSweep = now();
566
+ function sweep(current) {
567
+ if (current - lastSweep < windowMs) return;
568
+ lastSweep = current;
569
+ const cutoff = current - windowMs;
570
+ for (const [key, entries] of log) {
571
+ if (!entries.some((t) => t > cutoff)) log.delete(key);
572
+ }
573
+ }
574
+ function allow(key) {
575
+ const current = now();
576
+ sweep(current);
577
+ const cutoff = current - windowMs;
567
578
  const entries = (log.get(key) ?? []).filter((t) => t > cutoff);
568
579
  if (entries.length >= maxPerWindow) {
569
580
  if (entries.length > 0) log.set(key, entries);
570
581
  else log.delete(key);
571
582
  return false;
572
583
  }
573
- entries.push(now());
584
+ entries.push(current);
574
585
  log.set(key, entries);
575
586
  return true;
576
- };
587
+ }
588
+ allow.size = () => log.size;
589
+ return allow;
577
590
  }
578
591
  function underReplyRateLimit(msg, limiters) {
579
592
  return msg.isDirectMessage ? limiters.dm(msg.chatId) : limiters.group(msg.chatId);
package/dist/index.js CHANGED
@@ -1294,7 +1294,7 @@ function createRateLimiter2(config) {
1294
1294
  const limiter = createWindowBucketLimiter(6e4);
1295
1295
  const publicLimit = config.rateLimit?.public || 60;
1296
1296
  const privateLimit = config.rateLimit?.private || 120;
1297
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1297
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1298
1298
  const demoApiKeys = config.rateLimit?.demoApiKeys ?? [];
1299
1299
  return {
1300
1300
  // Public: key is IP only
@@ -1396,7 +1396,7 @@ function isHttps(c, trustProxy) {
1396
1396
  function securityHeaders(config) {
1397
1397
  const csp = config.server?.contentSecurityPolicy || DEFAULT_CSP;
1398
1398
  const hsts = config.server?.strictTransportSecurity ?? DEFAULT_HSTS;
1399
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1399
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1400
1400
  return async (c, next) => {
1401
1401
  await next();
1402
1402
  c.header("content-security-policy", csp);
@@ -1498,7 +1498,7 @@ function demoRoutes(deps) {
1498
1498
  const app = new import_hono.Hono();
1499
1499
  const demoOrigins = config.server?.allowedOrigins ?? [];
1500
1500
  const allowLocalhostDemo = config.server?.allowLocalhostDemo ?? false;
1501
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1501
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1502
1502
  app.get(
1503
1503
  "/api/demo/session",
1504
1504
  checkDemoOrigin(demoOrigins, allowLocalhostDemo),
package/dist/index.mjs CHANGED
@@ -1221,7 +1221,7 @@ function createRateLimiter2(config) {
1221
1221
  const limiter = createWindowBucketLimiter(6e4);
1222
1222
  const publicLimit = config.rateLimit?.public || 60;
1223
1223
  const privateLimit = config.rateLimit?.private || 120;
1224
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1224
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1225
1225
  const demoApiKeys = config.rateLimit?.demoApiKeys ?? [];
1226
1226
  return {
1227
1227
  // Public: key is IP only
@@ -1323,7 +1323,7 @@ function isHttps(c, trustProxy) {
1323
1323
  function securityHeaders(config) {
1324
1324
  const csp = config.server?.contentSecurityPolicy || DEFAULT_CSP;
1325
1325
  const hsts = config.server?.strictTransportSecurity ?? DEFAULT_HSTS;
1326
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1326
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1327
1327
  return async (c, next) => {
1328
1328
  await next();
1329
1329
  c.header("content-security-policy", csp);
@@ -1425,7 +1425,7 @@ function demoRoutes(deps) {
1425
1425
  const app = new Hono();
1426
1426
  const demoOrigins = config.server?.allowedOrigins ?? [];
1427
1427
  const allowLocalhostDemo = config.server?.allowLocalhostDemo ?? false;
1428
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1428
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1429
1429
  app.get(
1430
1430
  "/api/demo/session",
1431
1431
  checkDemoOrigin(demoOrigins, allowLocalhostDemo),
@@ -5,11 +5,11 @@ import type { Context } from "hono";
5
5
  * `X-Forwarded-For` is set by the client unless something in front of
6
6
  * Chatter (nginx, Cloudflare, a cloud load balancer) overwrites it with the
7
7
  * real socket address. Trusting it unconditionally lets an attacker rotate a
8
- * fake value on every request and bypass per-IP limits entirely. Pass
9
- * `trustProxy: true` only when such a proxy is guaranteed to be in front โ€”
10
- * otherwise every caller collapses onto one shared bucket, which is coarse
11
- * but not bypassable, and pair it with a fronting proxy that does the real
12
- * per-client limiting.
8
+ * fake value on every request and bypass per-IP limits entirely, so
9
+ * `trustProxy` defaults to `false`: pass `trustProxy: true` only when such a
10
+ * proxy is guaranteed to be in front. Left `false`, every caller collapses
11
+ * onto one shared bucket, which is coarse but not bypassable โ€” pair it with
12
+ * a fronting proxy that does the real per-client limiting.
13
13
  */
14
14
  export declare function clientRateLimitKey(c: Context, trustProxy: boolean): string;
15
15
  //# sourceMappingURL=clientKey.d.ts.map
@@ -9,7 +9,9 @@ import type { ChatterConfig } from "../types";
9
9
  * `X-Forwarded-Proto` โ€” see `rateLimit.trustProxy`) or `NODE_ENV=production`.
10
10
  * A browser ignores HSTS delivered over plain HTTP (RFC 6797 ยง8.1), so this
11
11
  * gate is about not asserting a guarantee the deployment doesn't back, not
12
- * about avoiding a localhost lockout.
12
+ * about avoiding a localhost lockout. `trustProxy` defaults to `false`: a
13
+ * deployment reachable directly must opt in before a client-suppliable
14
+ * header is trusted for anything.
13
15
  *
14
16
  * Headers are set after `next()` so they still land on a handler that
15
17
  * returns a raw `Response` (e.g. from `config.customRoutes`) rather than
@@ -1 +1 @@
1
- {"version":3,"file":"securityHeaders.d.ts","sourceRoot":"","sources":["../../src/middleware/securityHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAiB9C;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,OAKlC,OAAO,QAAQ,IAAI,mBAQrC"}
1
+ {"version":3,"file":"securityHeaders.d.ts","sourceRoot":"","sources":["../../src/middleware/securityHeaders.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAiB9C;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,aAAa,OAKlC,OAAO,QAAQ,IAAI,mBAQrC"}
package/dist/server.js CHANGED
@@ -796,7 +796,7 @@ function isHttps(c, trustProxy) {
796
796
  function securityHeaders(config) {
797
797
  const csp = config.server?.contentSecurityPolicy || DEFAULT_CSP;
798
798
  const hsts = config.server?.strictTransportSecurity ?? DEFAULT_HSTS;
799
- const trustProxy = config.rateLimit?.trustProxy ?? true;
799
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
800
800
  return async (c, next) => {
801
801
  await next();
802
802
  c.header("content-security-policy", csp);
@@ -996,7 +996,7 @@ function demoRoutes(deps) {
996
996
  const app = new import_hono.Hono();
997
997
  const demoOrigins = config.server?.allowedOrigins ?? [];
998
998
  const allowLocalhostDemo = config.server?.allowLocalhostDemo ?? false;
999
- const trustProxy = config.rateLimit?.trustProxy ?? true;
999
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1000
1000
  app.get(
1001
1001
  "/api/demo/session",
1002
1002
  checkDemoOrigin(demoOrigins, allowLocalhostDemo),
@@ -1129,7 +1129,7 @@ function createRateLimiter(config) {
1129
1129
  const limiter = createWindowBucketLimiter(6e4);
1130
1130
  const publicLimit = config.rateLimit?.public || 60;
1131
1131
  const privateLimit = config.rateLimit?.private || 120;
1132
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1132
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1133
1133
  const demoApiKeys = config.rateLimit?.demoApiKeys ?? [];
1134
1134
  return {
1135
1135
  // Public: key is IP only
package/dist/server.mjs CHANGED
@@ -761,7 +761,7 @@ function isHttps(c, trustProxy) {
761
761
  function securityHeaders(config) {
762
762
  const csp = config.server?.contentSecurityPolicy || DEFAULT_CSP;
763
763
  const hsts = config.server?.strictTransportSecurity ?? DEFAULT_HSTS;
764
- const trustProxy = config.rateLimit?.trustProxy ?? true;
764
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
765
765
  return async (c, next) => {
766
766
  await next();
767
767
  c.header("content-security-policy", csp);
@@ -961,7 +961,7 @@ function demoRoutes(deps) {
961
961
  const app = new Hono();
962
962
  const demoOrigins = config.server?.allowedOrigins ?? [];
963
963
  const allowLocalhostDemo = config.server?.allowLocalhostDemo ?? false;
964
- const trustProxy = config.rateLimit?.trustProxy ?? true;
964
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
965
965
  app.get(
966
966
  "/api/demo/session",
967
967
  checkDemoOrigin(demoOrigins, allowLocalhostDemo),
@@ -1094,7 +1094,7 @@ function createRateLimiter(config) {
1094
1094
  const limiter = createWindowBucketLimiter(6e4);
1095
1095
  const publicLimit = config.rateLimit?.public || 60;
1096
1096
  const privateLimit = config.rateLimit?.private || 120;
1097
- const trustProxy = config.rateLimit?.trustProxy ?? true;
1097
+ const trustProxy = config.rateLimit?.trustProxy ?? false;
1098
1098
  const demoApiKeys = config.rateLimit?.demoApiKeys ?? [];
1099
1099
  return {
1100
1100
  // Public: key is IP only
package/dist/types.d.ts CHANGED
@@ -153,8 +153,10 @@ export interface ChatterConfig {
153
153
  * Only set this when Chatter sits behind a reverse proxy (nginx,
154
154
  * Cloudflare, a cloud load balancer) that overwrites client-supplied
155
155
  * XFF with the real socket address โ€” otherwise a caller can rotate a
156
- * fake value per request and bypass limits entirely. When `false`,
157
- * every caller shares one bucket per limiter. Default: true.
156
+ * fake value per request and bypass limits entirely. When `false`
157
+ * (the default), every caller shares one bucket per limiter โ€” coarse
158
+ * but not spoofable, and the safe choice for a directly-exposed
159
+ * server. Default: false.
158
160
  */
159
161
  trustProxy?: boolean;
160
162
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@diegoaltoworks/chatter",
3
- "version": "0.50.0",
3
+ "version": "0.51.0",
4
4
  "description": "Embeddable AI chatbot framework with RAG, authentication, and customizable widgets",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",