@chatcops/server 0.5.0 → 0.6.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 (71) hide show
  1. package/README.md +4 -4
  2. package/dist/adapters/ai-sdk.d.ts +12 -0
  3. package/dist/adapters/ai-sdk.d.ts.map +1 -0
  4. package/dist/adapters/ai-sdk.js +27 -0
  5. package/dist/adapters/ai-sdk.js.map +1 -0
  6. package/dist/adapters/cloudflare.d.ts.map +1 -1
  7. package/dist/adapters/cloudflare.js +9 -83
  8. package/dist/adapters/cloudflare.js.map +1 -1
  9. package/dist/adapters/express.d.ts +6 -2
  10. package/dist/adapters/express.d.ts.map +1 -1
  11. package/dist/adapters/express.js +101 -30
  12. package/dist/adapters/express.js.map +1 -1
  13. package/dist/adapters/index.d.ts +1 -0
  14. package/dist/adapters/index.d.ts.map +1 -1
  15. package/dist/adapters/index.js +1 -0
  16. package/dist/adapters/index.js.map +1 -1
  17. package/dist/adapters/vercel.d.ts.map +1 -1
  18. package/dist/adapters/vercel.js +7 -74
  19. package/dist/adapters/vercel.js.map +1 -1
  20. package/dist/client-ip.d.ts +36 -0
  21. package/dist/client-ip.d.ts.map +1 -0
  22. package/dist/client-ip.js +62 -0
  23. package/dist/client-ip.js.map +1 -0
  24. package/dist/config.d.ts +110 -8
  25. package/dist/config.d.ts.map +1 -1
  26. package/dist/config.js +5 -1
  27. package/dist/config.js.map +1 -1
  28. package/dist/handler.d.ts +50 -1
  29. package/dist/handler.d.ts.map +1 -1
  30. package/dist/handler.js +384 -130
  31. package/dist/handler.js.map +1 -1
  32. package/dist/http.d.ts +66 -0
  33. package/dist/http.d.ts.map +1 -0
  34. package/dist/http.js +262 -0
  35. package/dist/http.js.map +1 -0
  36. package/dist/index.d.ts +3 -0
  37. package/dist/index.d.ts.map +1 -1
  38. package/dist/index.js +1 -0
  39. package/dist/index.js.map +1 -1
  40. package/dist/rate-limit.d.ts +5 -0
  41. package/dist/rate-limit.d.ts.map +1 -1
  42. package/dist/rate-limit.js +5 -0
  43. package/dist/rate-limit.js.map +1 -1
  44. package/dist/security/origin-policy.d.ts +19 -0
  45. package/dist/security/origin-policy.d.ts.map +1 -0
  46. package/dist/security/origin-policy.js +58 -0
  47. package/dist/security/origin-policy.js.map +1 -0
  48. package/dist/security/origin.d.ts +5 -0
  49. package/dist/security/origin.d.ts.map +1 -0
  50. package/dist/security/origin.js +47 -0
  51. package/dist/security/origin.js.map +1 -0
  52. package/dist/security/session-token.d.ts +65 -0
  53. package/dist/security/session-token.d.ts.map +1 -0
  54. package/dist/security/session-token.js +338 -0
  55. package/dist/security/session-token.js.map +1 -0
  56. package/dist/security/sessions.d.ts +49 -0
  57. package/dist/security/sessions.d.ts.map +1 -0
  58. package/dist/security/sessions.js +159 -0
  59. package/dist/security/sessions.js.map +1 -0
  60. package/dist/security/startup-checks.d.ts +44 -0
  61. package/dist/security/startup-checks.d.ts.map +1 -0
  62. package/dist/security/startup-checks.js +134 -0
  63. package/dist/security/startup-checks.js.map +1 -0
  64. package/dist/security/turnstile.d.ts +24 -0
  65. package/dist/security/turnstile.d.ts.map +1 -0
  66. package/dist/security/turnstile.js +93 -0
  67. package/dist/security/turnstile.js.map +1 -0
  68. package/dist/visitor-context.d.ts.map +1 -1
  69. package/dist/visitor-context.js +1 -0
  70. package/dist/visitor-context.js.map +1 -1
  71. package/package.json +22 -5
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Startup checks for the security settings the server is about to add: the
3
+ * allowed origins and the secrets that sign session tokens.
4
+ *
5
+ * These are the mistakes that fail silently. A secret that is ten characters
6
+ * long works, and so does a secret that is also a `NEXT_PUBLIC_` variable, so
7
+ * nothing breaks until the day it does. A function that finds them before the
8
+ * server starts is worth more than one that finds them during a request.
9
+ *
10
+ * Nothing here logs or throws. The caller decides what to do with a problem.
11
+ */
12
+ /** The security settings a server is configured with. */
13
+ export interface SecuritySettings {
14
+ /** The origins the server accepts requests from. `*` allows every origin. */
15
+ allowedOrigins?: string[];
16
+ /** The secrets that sign session tokens. */
17
+ sessionSecrets?: string[];
18
+ }
19
+ /** One thing that is wrong with the security settings. */
20
+ export interface SecurityProblem {
21
+ /** An error stops the server from starting. A warning is worth a look. */
22
+ level: 'error' | 'warning';
23
+ /** What is wrong, and what to do about it. Never contains a secret. */
24
+ message: string;
25
+ }
26
+ /**
27
+ * Finds the mistakes in the security settings, most serious first.
28
+ *
29
+ * `env` is the environment to look in, and defaults to `process.env`.
30
+ */
31
+ export declare function checkSecuritySettings(settings: SecuritySettings, env?: Record<string, string | undefined>): SecurityProblem[];
32
+ /** What a server's security settings come to, for the startup log. */
33
+ export interface SecuritySummary {
34
+ allowedOrigins: string[];
35
+ /** Seconds, when session tokens are on. */
36
+ sessionTtlSec?: number;
37
+ requireSession?: boolean;
38
+ turnstile: boolean;
39
+ }
40
+ /** The one line the server logs at startup about its security settings. */
41
+ export declare function describeSecurity(summary: SecuritySummary): string;
42
+ /** Logs the problems `checkSecuritySettings` finds, errors first, then the summary line. */
43
+ export declare function logSecurityAtStartup(settings: SecuritySettings & Omit<SecuritySummary, 'allowedOrigins'>): void;
44
+ //# sourceMappingURL=startup-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-checks.d.ts","sourceRoot":"","sources":["../../src/security/startup-checks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,yDAAyD;AACzD,MAAM,WAAW,gBAAgB;IAC/B,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,4CAA4C;IAC5C,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED,0DAA0D;AAC1D,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,uEAAuE;IACvE,OAAO,EAAE,MAAM,CAAC;CACjB;AAwBD;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACvC,eAAe,EAAE,CAkFnB;AAED,sEAAsE;AACtE,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,CASjE;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC,eAAe,EAAE,gBAAgB,CAAC,GAAG,IAAI,CAM/G"}
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Startup checks for the security settings the server is about to add: the
3
+ * allowed origins and the secrets that sign session tokens.
4
+ *
5
+ * These are the mistakes that fail silently. A secret that is ten characters
6
+ * long works, and so does a secret that is also a `NEXT_PUBLIC_` variable, so
7
+ * nothing breaks until the day it does. A function that finds them before the
8
+ * server starts is worth more than one that finds them during a request.
9
+ *
10
+ * Nothing here logs or throws. The caller decides what to do with a problem.
11
+ */
12
+ /** How many bytes a session secret needs to be worth signing with. */
13
+ const MIN_SECRET_BYTES = 32;
14
+ /**
15
+ * The env var prefixes whose value is shipped to the browser, so a secret
16
+ * that shares a value with one of them is in the client bundle.
17
+ */
18
+ const PUBLIC_ENV_PREFIXES = ['NEXT_PUBLIC_', 'VITE_', 'PUBLIC_', 'NUXT_PUBLIC_', 'EXPO_PUBLIC_', 'REACT_APP_'];
19
+ /**
20
+ * The environment to read, which is `process.env` where there is one. Workers
21
+ * have no `process`, so the checks still work there with an empty environment.
22
+ */
23
+ function defaultEnv() {
24
+ return globalThis.process?.env ?? {};
25
+ }
26
+ /** How many bytes a string takes in UTF-8, so a 32 byte secret is 32 bytes. */
27
+ function utf8Length(value) {
28
+ return new TextEncoder().encode(value).length;
29
+ }
30
+ /**
31
+ * Finds the mistakes in the security settings, most serious first.
32
+ *
33
+ * `env` is the environment to look in, and defaults to `process.env`.
34
+ */
35
+ export function checkSecuritySettings(settings, env) {
36
+ const problems = [];
37
+ const secrets = settings.sessionSecrets ?? [];
38
+ const origins = settings.allowedOrigins ?? [];
39
+ const environment = env ?? defaultEnv();
40
+ for (const [index, secret] of secrets.entries()) {
41
+ if (utf8Length(secret) < MIN_SECRET_BYTES) {
42
+ problems.push({
43
+ level: 'error',
44
+ message: `Session secret ${index + 1} is shorter than ${MIN_SECRET_BYTES} bytes.`,
45
+ });
46
+ }
47
+ }
48
+ for (const [index, secret] of secrets.entries()) {
49
+ for (const name of Object.keys(environment)) {
50
+ if (!PUBLIC_ENV_PREFIXES.some((prefix) => name.startsWith(prefix)))
51
+ continue;
52
+ if (environment[name] !== secret)
53
+ continue;
54
+ problems.push({
55
+ level: 'error',
56
+ message: `Session secret ${index + 1} is also the value of the ${name} environment variable, ` +
57
+ 'which is sent to the browser. Use a different secret.',
58
+ });
59
+ }
60
+ }
61
+ for (const [index, secret] of secrets.entries()) {
62
+ const first = secrets.indexOf(secret);
63
+ if (first !== index) {
64
+ problems.push({
65
+ level: 'warning',
66
+ message: `Session secrets ${first + 1} and ${index + 1} are the same.`,
67
+ });
68
+ }
69
+ }
70
+ for (const origin of origins) {
71
+ if (origin === '*')
72
+ continue;
73
+ if (!origin.startsWith('http://') && !origin.startsWith('https://')) {
74
+ problems.push({
75
+ level: 'error',
76
+ message: `Allowed origin "${origin}" must start with http:// or https://.`,
77
+ });
78
+ continue;
79
+ }
80
+ let parsed;
81
+ try {
82
+ parsed = new URL(origin);
83
+ }
84
+ catch {
85
+ problems.push({
86
+ level: 'error',
87
+ message: `Allowed origin "${origin}" is not a valid URL.`,
88
+ });
89
+ continue;
90
+ }
91
+ if (parsed.pathname !== '/' || parsed.search !== '' || parsed.hash !== '' || /[/?#]$/.test(origin)) {
92
+ problems.push({
93
+ level: 'error',
94
+ message: `Allowed origin "${origin}" must not have a path, a query, a fragment or a trailing slash, ` +
95
+ `because browsers send the origin without one. Use "${parsed.origin}".`,
96
+ });
97
+ continue;
98
+ }
99
+ if (origin.startsWith('http://') && parsed.hostname !== 'localhost' && parsed.hostname !== '127.0.0.1') {
100
+ problems.push({
101
+ level: 'warning',
102
+ message: `Allowed origin "${origin}" uses http://. Use https://, unless it is a local development server.`,
103
+ });
104
+ }
105
+ }
106
+ if (origins.includes('*') && origins.length > 1) {
107
+ problems.push({
108
+ level: 'warning',
109
+ message: 'Allowed origins include "*", which allows every site, so the other entries do nothing.',
110
+ });
111
+ }
112
+ return problems;
113
+ }
114
+ /** The one line the server logs at startup about its security settings. */
115
+ export function describeSecurity(summary) {
116
+ const origins = summary.allowedOrigins.includes('*')
117
+ ? 'any site (allowedOrigins is "*"; list your sites in production)'
118
+ : summary.allowedOrigins.join(', ');
119
+ const sessions = summary.sessionTtlSec === undefined
120
+ ? 'session tokens off'
121
+ : `session tokens on (${summary.sessionTtlSec}s${summary.requireSession === false ? ', not required' : ''})`;
122
+ return `[chatcops] Security: chat allowed from ${origins}; ${sessions}; Turnstile ${summary.turnstile ? 'on' : 'off'}.`;
123
+ }
124
+ /** Logs the problems `checkSecuritySettings` finds, errors first, then the summary line. */
125
+ export function logSecurityAtStartup(settings) {
126
+ const allowedOrigins = settings.allowedOrigins ?? ['*'];
127
+ const problems = checkSecuritySettings({ ...settings, allowedOrigins });
128
+ for (const problem of problems.filter((p) => p.level === 'error'))
129
+ console.error(`[chatcops] ERROR: ${problem.message}`);
130
+ for (const problem of problems.filter((p) => p.level === 'warning'))
131
+ console.warn(`[chatcops] ${problem.message}`);
132
+ console.info(describeSecurity({ ...settings, allowedOrigins }));
133
+ }
134
+ //# sourceMappingURL=startup-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"startup-checks.js","sourceRoot":"","sources":["../../src/security/startup-checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface TurnstileConfig {
2
+ secretKey: string;
3
+ /** Expected action to validate against the Turnstile response. */
4
+ action?: string;
5
+ /** Expected hostnames where the challenge may be solved. */
6
+ expectedHostnames?: string[];
7
+ /** Timeout in milliseconds for the verification request. Defaults to 5000 ms. */
8
+ timeoutMs?: number;
9
+ }
10
+ export type TurnstileResult = {
11
+ ok: true;
12
+ hostname?: string;
13
+ action?: string;
14
+ } | {
15
+ ok: false;
16
+ code: 'missing_token' | 'invalid_token' | 'hostname_mismatch' | 'action_mismatch' | 'unavailable';
17
+ errorCodes?: string[];
18
+ };
19
+ export declare function verifyTurnstile(token: string | undefined, config: TurnstileConfig, opts?: {
20
+ remoteIp?: string;
21
+ idempotencyKey?: string;
22
+ fetch?: typeof fetch;
23
+ }): Promise<TurnstileResult>;
24
+ //# sourceMappingURL=turnstile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnstile.d.ts","sourceRoot":"","sources":["../../src/security/turnstile.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,kEAAkE;IAClE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4DAA4D;IAC5D,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,eAAe,GACvB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IACE,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EACA,eAAe,GACf,eAAe,GACf,mBAAmB,GACnB,iBAAiB,GACjB,aAAa,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB,CAAC;AAKN,wBAAsB,eAAe,CACnC,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,MAAM,EAAE,eAAe,EACvB,IAAI,CAAC,EAAE;IACL,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB,GACA,OAAO,CAAC,eAAe,CAAC,CA+G1B"}
@@ -0,0 +1,93 @@
1
+ const SITEVERIFY_URL = 'https://challenges.cloudflare.com/turnstile/v0/siteverify';
2
+ const DEFAULT_TIMEOUT_MS = 5000;
3
+ export async function verifyTurnstile(token, config, opts) {
4
+ if (token === undefined || token === null || typeof token !== 'string' || token.trim() === '') {
5
+ return { ok: false, code: 'missing_token' };
6
+ }
7
+ try {
8
+ const body = {
9
+ secret: config.secretKey,
10
+ response: token,
11
+ };
12
+ if (opts?.remoteIp !== undefined && opts.remoteIp !== '') {
13
+ body.remoteip = opts.remoteIp;
14
+ }
15
+ if (opts?.idempotencyKey !== undefined && opts.idempotencyKey !== '') {
16
+ body.idempotency_key = opts.idempotencyKey;
17
+ }
18
+ const fetchFn = opts?.fetch ?? globalThis.fetch;
19
+ const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
20
+ let response;
21
+ try {
22
+ response = await fetchFn(SITEVERIFY_URL, {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Content-Type': 'application/json',
26
+ },
27
+ body: JSON.stringify(body),
28
+ signal: AbortSignal.timeout(timeoutMs),
29
+ });
30
+ }
31
+ catch {
32
+ return { ok: false, code: 'unavailable' };
33
+ }
34
+ let data;
35
+ try {
36
+ data = await response.json();
37
+ }
38
+ catch {
39
+ return { ok: false, code: 'unavailable' };
40
+ }
41
+ if (typeof data !== 'object' ||
42
+ data === null ||
43
+ Array.isArray(data) ||
44
+ typeof data.success !== 'boolean') {
45
+ return { ok: false, code: 'unavailable' };
46
+ }
47
+ const payload = data;
48
+ if (!response.ok) {
49
+ if (response.status >= 500 || payload.success !== false) {
50
+ return { ok: false, code: 'unavailable' };
51
+ }
52
+ }
53
+ if (!payload.success) {
54
+ const errorCodes = Array.isArray(payload['error-codes'])
55
+ ? payload['error-codes'].map(String)
56
+ : undefined;
57
+ const isUnavailable = errorCodes?.includes('internal-error');
58
+ const result = {
59
+ ok: false,
60
+ code: isUnavailable ? 'unavailable' : 'invalid_token',
61
+ };
62
+ if (errorCodes !== undefined) {
63
+ result.errorCodes = errorCodes;
64
+ }
65
+ return result;
66
+ }
67
+ const returnedHostname = typeof payload.hostname === 'string' ? payload.hostname : undefined;
68
+ const returnedAction = typeof payload.action === 'string' ? payload.action : undefined;
69
+ if (config.expectedHostnames !== undefined) {
70
+ if (!returnedHostname ||
71
+ !config.expectedHostnames.some((expected) => expected.toLowerCase() === returnedHostname.toLowerCase())) {
72
+ return { ok: false, code: 'hostname_mismatch' };
73
+ }
74
+ }
75
+ if (config.action !== undefined) {
76
+ if (returnedAction !== config.action) {
77
+ return { ok: false, code: 'action_mismatch' };
78
+ }
79
+ }
80
+ const result = { ok: true };
81
+ if (returnedHostname !== undefined) {
82
+ result.hostname = returnedHostname;
83
+ }
84
+ if (returnedAction !== undefined) {
85
+ result.action = returnedAction;
86
+ }
87
+ return result;
88
+ }
89
+ catch {
90
+ return { ok: false, code: 'unavailable' };
91
+ }
92
+ }
93
+ //# sourceMappingURL=turnstile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"turnstile.js","sourceRoot":"","sources":["../../src/security/turnstile.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"visitor-context.d.ts","sourceRoot":"","sources":["../src/visitor-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,kSACyP,CAAC;AAElS,yFAAyF;AACzF,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAa9C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,oBAAoB,EAAE,aAAa,GAAG,UAAU,CAAC,GAAG,MAAM,GAAG,IAAI,CAqB9G;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,EAAE,CAOjG;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD"}
1
+ {"version":3,"file":"visitor-context.d.ts","sourceRoot":"","sources":["../src/visitor-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAGxD;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,kSACyP,CAAC;AAElS,yFAAyF;AACzF,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAc9C,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,IAAI,CAAC,oBAAoB,EAAE,aAAa,GAAG,UAAU,CAAC,GAAG,MAAM,GAAG,IAAI,CAqB9G;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,GAAG,WAAW,EAAE,CAOjG;AAED,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEnD"}
@@ -12,6 +12,7 @@ const TAG = 'visitor_context';
12
12
  /** One line of plain text: no control characters, no line breaks, no tags that could close the block. */
13
13
  function clean(value) {
14
14
  return value
15
+ // biome-ignore lint/suspicious/noControlCharactersInRegex: sanitize control characters
15
16
  .replace(/[\u0000-\u001f\u007f]+/g, ' ')
16
17
  .replace(new RegExp(`<\\s*/?\\s*${TAG}[^>]*>`, 'gi'), '')
17
18
  .replace(/\s+/g, ' ')
@@ -1 +1 @@
1
- {"version":3,"file":"visitor-context.js","sourceRoot":"","sources":["../src/visitor-context.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"visitor-context.js","sourceRoot":"","sources":["../src/visitor-context.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,19 @@
1
1
  {
2
2
  "name": "@chatcops/server",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Server-side handler and adapters for ChatCops",
5
+ "keywords": [
6
+ "chatcops",
7
+ "ai",
8
+ "chatbot",
9
+ "llm",
10
+ "sse",
11
+ "express",
12
+ "vercel",
13
+ "cloudflare-workers"
14
+ ],
15
+ "homepage": "https://chat.codercops.com",
16
+ "bugs": "https://github.com/codercops/chatcops/issues",
5
17
  "type": "module",
6
18
  "main": "dist/index.js",
7
19
  "types": "dist/index.d.ts",
@@ -28,7 +40,7 @@
28
40
  ],
29
41
  "dependencies": {
30
42
  "zod": "^3.24.0",
31
- "@chatcops/core": "0.4.0"
43
+ "@chatcops/core": "0.5.0"
32
44
  },
33
45
  "peerDependencies": {
34
46
  "express": "^4.0.0 || ^5.0.0"
@@ -39,19 +51,24 @@
39
51
  }
40
52
  },
41
53
  "devDependencies": {
54
+ "@types/express": "^5.0.0",
55
+ "ai": "7.0.122",
42
56
  "typescript": "^5.7.0",
43
- "vitest": "^4.1.11",
44
- "@types/express": "^5.0.0"
57
+ "vitest": "^4.1.11"
45
58
  },
46
59
  "repository": {
47
60
  "type": "git",
48
- "url": "https://github.com/codercops/chatcops",
61
+ "url": "git+https://github.com/codercops/chatcops.git",
49
62
  "directory": "packages/server"
50
63
  },
51
64
  "publishConfig": {
52
65
  "access": "public"
53
66
  },
54
67
  "license": "MIT",
68
+ "engines": {
69
+ "node": ">=22"
70
+ },
71
+ "sideEffects": false,
55
72
  "scripts": {
56
73
  "build": "tsc",
57
74
  "typecheck": "tsc --noEmit",