@chozzz/vargos 2.0.4 → 2.0.6

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 (105) hide show
  1. package/dist/lib/async-handlers.d.ts +13 -0
  2. package/dist/lib/async-handlers.d.ts.map +1 -0
  3. package/dist/lib/async-handlers.js +6 -0
  4. package/dist/lib/async-handlers.js.map +1 -0
  5. package/dist/lib/error-store.d.ts +19 -0
  6. package/dist/lib/error-store.d.ts.map +1 -0
  7. package/dist/lib/error-store.js +19 -0
  8. package/dist/lib/error-store.js.map +1 -0
  9. package/dist/lib/error.d.ts +11 -0
  10. package/dist/lib/error.d.ts.map +1 -0
  11. package/dist/lib/error.js +41 -0
  12. package/dist/lib/error.js.map +1 -0
  13. package/dist/lib/frontmatter.d.ts +23 -0
  14. package/dist/lib/frontmatter.d.ts.map +1 -0
  15. package/dist/lib/frontmatter.js +136 -0
  16. package/dist/lib/frontmatter.js.map +1 -0
  17. package/dist/lib/glob.d.ts +14 -0
  18. package/dist/lib/glob.d.ts.map +1 -0
  19. package/dist/lib/glob.js +22 -0
  20. package/dist/lib/glob.js.map +1 -0
  21. package/dist/lib/heartbeat.d.ts +23 -0
  22. package/dist/lib/heartbeat.d.ts.map +1 -0
  23. package/dist/lib/heartbeat.js +62 -0
  24. package/dist/lib/heartbeat.js.map +1 -0
  25. package/dist/lib/html.d.ts +8 -0
  26. package/dist/lib/html.d.ts.map +1 -0
  27. package/dist/lib/html.js +28 -0
  28. package/dist/lib/html.js.map +1 -0
  29. package/dist/lib/http-validate.d.ts +12 -0
  30. package/dist/lib/http-validate.d.ts.map +1 -0
  31. package/dist/lib/http-validate.js +11 -0
  32. package/dist/lib/http-validate.js.map +1 -0
  33. package/dist/lib/id.d.ts +3 -0
  34. package/dist/lib/id.d.ts.map +1 -0
  35. package/dist/lib/id.js +5 -0
  36. package/dist/lib/id.js.map +1 -0
  37. package/dist/lib/logger.d.ts +12 -0
  38. package/dist/lib/logger.d.ts.map +1 -0
  39. package/dist/lib/logger.js +28 -0
  40. package/dist/lib/logger.js.map +1 -0
  41. package/dist/lib/media-transcribe.d.ts +57 -0
  42. package/dist/lib/media-transcribe.d.ts.map +1 -0
  43. package/dist/lib/media-transcribe.js +98 -0
  44. package/dist/lib/media-transcribe.js.map +1 -0
  45. package/dist/lib/media.d.ts +7 -0
  46. package/dist/lib/media.d.ts.map +1 -0
  47. package/dist/lib/media.js +18 -0
  48. package/dist/lib/media.js.map +1 -0
  49. package/dist/lib/mime.d.ts +6 -0
  50. package/dist/lib/mime.d.ts.map +1 -0
  51. package/dist/lib/mime.js +71 -0
  52. package/dist/lib/mime.js.map +1 -0
  53. package/dist/lib/paginate.d.ts +3 -0
  54. package/dist/lib/paginate.d.ts.map +1 -0
  55. package/dist/lib/paginate.js +5 -0
  56. package/dist/lib/paginate.js.map +1 -0
  57. package/dist/lib/paths.d.ts +14 -0
  58. package/dist/lib/paths.d.ts.map +1 -0
  59. package/dist/lib/paths.js +29 -0
  60. package/dist/lib/paths.js.map +1 -0
  61. package/dist/lib/provider-loader.d.ts +10 -0
  62. package/dist/lib/provider-loader.d.ts.map +1 -0
  63. package/dist/lib/provider-loader.js +24 -0
  64. package/dist/lib/provider-loader.js.map +1 -0
  65. package/dist/lib/retry.d.ts +20 -0
  66. package/dist/lib/retry.d.ts.map +1 -0
  67. package/dist/lib/retry.js +40 -0
  68. package/dist/lib/retry.js.map +1 -0
  69. package/dist/lib/safe-async.d.ts +27 -0
  70. package/dist/lib/safe-async.d.ts.map +1 -0
  71. package/dist/lib/safe-async.js +38 -0
  72. package/dist/lib/safe-async.js.map +1 -0
  73. package/dist/lib/skills.d.ts +9 -0
  74. package/dist/lib/skills.d.ts.map +1 -0
  75. package/dist/lib/skills.js +15 -0
  76. package/dist/lib/skills.js.map +1 -0
  77. package/dist/lib/sleep.d.ts +6 -0
  78. package/dist/lib/sleep.d.ts.map +1 -0
  79. package/dist/lib/sleep.js +22 -0
  80. package/dist/lib/sleep.js.map +1 -0
  81. package/dist/lib/strip-markdown.d.ts +7 -0
  82. package/dist/lib/strip-markdown.d.ts.map +1 -0
  83. package/dist/lib/strip-markdown.js +32 -0
  84. package/dist/lib/strip-markdown.js.map +1 -0
  85. package/dist/lib/subagent.d.ts +14 -0
  86. package/dist/lib/subagent.d.ts.map +1 -0
  87. package/dist/lib/subagent.js +25 -0
  88. package/dist/lib/subagent.js.map +1 -0
  89. package/dist/lib/templates.d.ts +8 -0
  90. package/dist/lib/templates.d.ts.map +1 -0
  91. package/dist/lib/templates.js +39 -0
  92. package/dist/lib/templates.js.map +1 -0
  93. package/dist/lib/timeout.d.ts +6 -0
  94. package/dist/lib/timeout.d.ts.map +1 -0
  95. package/dist/lib/timeout.js +11 -0
  96. package/dist/lib/timeout.js.map +1 -0
  97. package/dist/lib/truncate.d.ts +11 -0
  98. package/dist/lib/truncate.d.ts.map +1 -0
  99. package/dist/lib/truncate.js +17 -0
  100. package/dist/lib/truncate.js.map +1 -0
  101. package/dist/lib/url-expand.d.ts +22 -0
  102. package/dist/lib/url-expand.d.ts.map +1 -0
  103. package/dist/lib/url-expand.js +74 -0
  104. package/dist/lib/url-expand.js.map +1 -0
  105. package/package.json +2 -1
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Generic async handler and callback type definitions.
3
+ * Reusable across services for consistent typing of async operations.
4
+ */
5
+ /** Basic async handler: input → Promise<output> */
6
+ export type AsyncHandler<I, O = void> = (input: I) => Promise<O>;
7
+ /** Batch async handler: multiple inputs → Promise<output> */
8
+ export type AsyncBatchHandler<I, O = void> = (batch: I[]) => Promise<O>;
9
+ /** Optional async handler (may not be implemented) */
10
+ export type OptionalAsyncHandler<I, O = void> = AsyncHandler<I, O> | undefined;
11
+ /** Variadic async handler: any arguments → Promise<output> */
12
+ export type AsyncFunction<O = void> = (...args: unknown[]) => Promise<O>;
13
+ //# sourceMappingURL=async-handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-handlers.d.ts","sourceRoot":"","sources":["../../lib/async-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,mDAAmD;AACnD,MAAM,MAAM,YAAY,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAEjE,6DAA6D;AAC7D,MAAM,MAAM,iBAAiB,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;AAExE,sDAAsD;AACtD,MAAM,MAAM,oBAAoB,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC;AAE/E,8DAA8D;AAC9D,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Generic async handler and callback type definitions.
3
+ * Reusable across services for consistent typing of async operations.
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=async-handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async-handlers.js","sourceRoot":"","sources":["../../lib/async-handlers.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Centralized error store — append-only JSONL at ~/.vargos/errors.jsonl
3
+ * Persists classified errors for pattern analysis and self-healing.
4
+ */
5
+ import { type ErrorClass } from './error.js';
6
+ export interface ErrorRecord {
7
+ ts: string;
8
+ runId?: string;
9
+ sessionKey?: string;
10
+ tool?: string;
11
+ errorClass: ErrorClass | 'validation' | 'fatal';
12
+ message: string;
13
+ model?: string;
14
+ resolved?: boolean;
15
+ }
16
+ export declare function appendError(entry: Omit<ErrorRecord, 'ts' | 'errorClass'> & {
17
+ errorClass?: ErrorClass | 'validation' | 'fatal';
18
+ }): Promise<void>;
19
+ //# sourceMappingURL=error-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-store.d.ts","sourceRoot":"","sources":["../../lib/error-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,EAAgC,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAE3E,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,UAAU,GAAG,YAAY,GAAG,OAAO,CAAC;IAChD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,wBAAsB,WAAW,CAC/B,KAAK,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,GAAG,YAAY,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,OAAO,CAAA;CAAE,GACnG,OAAO,CAAC,IAAI,CAAC,CASf"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Centralized error store — append-only JSONL at ~/.vargos/errors.jsonl
3
+ * Persists classified errors for pattern analysis and self-healing.
4
+ */
5
+ import { promises as fs } from 'node:fs';
6
+ import path from 'node:path';
7
+ import { getDataPaths } from './paths.js';
8
+ import { sanitizeError, classifyError } from './error.js';
9
+ export async function appendError(entry) {
10
+ const full = {
11
+ ts: new Date().toISOString(),
12
+ errorClass: entry.errorClass ?? classifyError(entry.message),
13
+ ...entry,
14
+ message: sanitizeError(entry.message),
15
+ };
16
+ const filePath = path.join(getDataPaths().dataDir, 'errors.jsonl');
17
+ await fs.appendFile(filePath, JSON.stringify(full) + '\n', 'utf-8');
18
+ }
19
+ //# sourceMappingURL=error-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-store.js","sourceRoot":"","sources":["../../lib/error-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AAa3E,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAoG;IAEpG,MAAM,IAAI,GAAgB;QACxB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC;QAC5D,GAAG,KAAK;QACR,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,OAAO,CAAC;KACtC,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IACnE,MAAM,EAAE,CAAC,UAAU,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Error utilities — message extraction, sanitization, classification.
3
+ */
4
+ /** Extract a human-readable message from an unknown error value. */
5
+ export declare function toMessage(err: unknown): string;
6
+ /** Scrub API keys, bearer tokens, and credentials from error strings. */
7
+ export declare function sanitizeError(msg: string): string;
8
+ export type ErrorClass = 'transient' | 'auth' | 'timeout' | 'rate_limit' | 'capability' | 'unknown';
9
+ /** Classify an error message for user-facing display. */
10
+ export declare function classifyError(msg: string): ErrorClass;
11
+ //# sourceMappingURL=error.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.d.ts","sourceRoot":"","sources":["../../lib/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,oEAAoE;AACpE,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAE9C;AAED,yEAAyE;AACzE,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUjD;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,YAAY,GAAG,SAAS,CAAC;AAEpG,yDAAyD;AACzD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAoBrD"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Error utilities — message extraction, sanitization, classification.
3
+ */
4
+ /** Extract a human-readable message from an unknown error value. */
5
+ export function toMessage(err) {
6
+ return err instanceof Error ? err.message : String(err);
7
+ }
8
+ /** Scrub API keys, bearer tokens, and credentials from error strings. */
9
+ export function sanitizeError(msg) {
10
+ return msg
11
+ // URL-embedded credentials (postgresql://user:pass@host)
12
+ .replace(/:\/\/([^:]+):([^@]+)@/g, '://$1:***@')
13
+ // Bearer tokens (including JWT with +/=)
14
+ .replace(/Bearer\s+[A-Za-z0-9_\-.+/=]+/gi, 'Bearer ***')
15
+ // Common API key formats (sk-..., xoxb-..., etc.)
16
+ .replace(/\b(sk|xoxb|xoxp|ghp|gho|ghu|ghs|ghr|glpat)-[A-Za-z0-9_-]{8,}/g, '$1-***')
17
+ // Generic key=value patterns for common secret field names
18
+ .replace(/(api[_-]?key|token|secret|password|authorization)[=:]\s*["']?[^\s"',}{]+/gi, '$1=***');
19
+ }
20
+ /** Classify an error message for user-facing display. */
21
+ export function classifyError(msg) {
22
+ const lower = msg.toLowerCase();
23
+ if (/\b(401|403|unauthorized|forbidden|invalid.*auth|invalid.*key)\b/.test(lower)) {
24
+ return 'auth';
25
+ }
26
+ if (/\b(429|rate.?limit|too many requests|quota|billing)\b/.test(lower)) {
27
+ return 'rate_limit';
28
+ }
29
+ if (/\b(timeout|timed?\s*out|etimedout|deadline exceeded)\b/.test(lower)) {
30
+ return 'timeout';
31
+ }
32
+ if (/\b(502|503|529|econnreset|econnrefused|network|socket hang up|fetch failed|retry)\b/.test(lower)) {
33
+ return 'transient';
34
+ }
35
+ // Model capability mismatches — not retryable
36
+ if (/no endpoints found|not support|unsupported.*model|model.*not.*available/i.test(lower)) {
37
+ return 'capability';
38
+ }
39
+ return 'unknown';
40
+ }
41
+ //# sourceMappingURL=error.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error.js","sourceRoot":"","sources":["../../lib/error.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,oEAAoE;AACpE,MAAM,UAAU,SAAS,CAAC,GAAY;IACpC,OAAO,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,OAAO,GAAG;QACR,yDAAyD;SACxD,OAAO,CAAC,wBAAwB,EAAE,YAAY,CAAC;QAChD,yCAAyC;SACxC,OAAO,CAAC,gCAAgC,EAAE,YAAY,CAAC;QACxD,kDAAkD;SACjD,OAAO,CAAC,+DAA+D,EAAE,QAAQ,CAAC;QACnF,2DAA2D;SAC1D,OAAO,CAAC,4EAA4E,EAAE,QAAQ,CAAC,CAAC;AACrG,CAAC;AAID,yDAAyD;AACzD,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAEhC,IAAI,iEAAiE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAClF,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,uDAAuD,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACxE,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,IAAI,wDAAwD,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACzE,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,qFAAqF,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtG,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,8CAA8C;IAC9C,IAAI,0EAA0E,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3F,OAAO,YAAY,CAAC;IACtB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Shared YAML frontmatter parser for markdown files.
3
+ * Supports the format:
4
+ * ---
5
+ * key: value
6
+ * multiline:
7
+ * - item1
8
+ * - item2
9
+ * ---
10
+ * body content
11
+ */
12
+ export interface FrontmatterResult<T = Record<string, unknown>> {
13
+ meta: T;
14
+ body: string;
15
+ }
16
+ /**
17
+ * Parse YAML-ish frontmatter. The optional generic `T` lets callers declare the expected
18
+ * meta shape — at runtime the parsed value is just cast (no validation), so callers should
19
+ * still treat fields as optional unless they validate downstream (Zod, manual checks).
20
+ */
21
+ export declare function parseFrontmatter<T = Record<string, unknown>>(content: string): FrontmatterResult<T> | null;
22
+ export declare function serializeFrontmatter(meta: Record<string, unknown>, body: string): string;
23
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../../lib/frontmatter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,iBAAiB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC5D,IAAI,EAAE,CAAC,CAAC;IACR,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC,GAAG,IAAI,CA+D1G;AAsBD,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAOxF"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Shared YAML frontmatter parser for markdown files.
3
+ * Supports the format:
4
+ * ---
5
+ * key: value
6
+ * multiline:
7
+ * - item1
8
+ * - item2
9
+ * ---
10
+ * body content
11
+ */
12
+ /**
13
+ * Parse YAML-ish frontmatter. The optional generic `T` lets callers declare the expected
14
+ * meta shape — at runtime the parsed value is just cast (no validation), so callers should
15
+ * still treat fields as optional unless they validate downstream (Zod, manual checks).
16
+ */
17
+ export function parseFrontmatter(content) {
18
+ if (!content || typeof content !== 'string') {
19
+ return null;
20
+ }
21
+ const match = content.match(/^---\n([\s\S]*?)\n?---\n?([\s\S]*)/);
22
+ if (!match) {
23
+ return null;
24
+ }
25
+ const meta = {};
26
+ const metaStr = match[1].trim();
27
+ const body = match[2]?.trim() ?? '';
28
+ // Empty frontmatter (e.g. `---\n---\n\n`) is valid — return empty meta + body so callers
29
+ // can distinguish "no frontmatter wrapper" (parse returns null) from "wrapper but empty".
30
+ if (!metaStr) {
31
+ return { meta: {}, body };
32
+ }
33
+ const lines = metaStr.split('\n');
34
+ let i = 0;
35
+ while (i < lines.length) {
36
+ const line = lines[i];
37
+ if (!line.trim()) {
38
+ i++;
39
+ continue;
40
+ }
41
+ const colonIdx = line.indexOf(':');
42
+ if (colonIdx === -1) {
43
+ i++;
44
+ continue;
45
+ }
46
+ const key = line.substring(0, colonIdx).trim();
47
+ if (!key) {
48
+ i++;
49
+ continue;
50
+ }
51
+ const rawValue = line.substring(colonIdx + 1).trim();
52
+ // Check if this is a multi-line array (next line starts with -)
53
+ if (!rawValue && i + 1 < lines.length && lines[i + 1].trim().startsWith('-')) {
54
+ const arrayItems = [];
55
+ i++;
56
+ while (i < lines.length && lines[i].trim().startsWith('-')) {
57
+ const item = lines[i].trim().substring(1).trim();
58
+ // Strip quotes from array items (e.g., "0 9 * * *" -> 0 9 * * *)
59
+ const unquoted = item.replace(/^["']|["']$/g, '');
60
+ arrayItems.push(unquoted);
61
+ i++;
62
+ }
63
+ meta[key] = arrayItems;
64
+ }
65
+ else {
66
+ meta[key] = parseFrontmatterValue(rawValue);
67
+ i++;
68
+ }
69
+ }
70
+ return { meta: meta, body };
71
+ }
72
+ function parseFrontmatterValue(value) {
73
+ if (value === 'true')
74
+ return true;
75
+ if (value === 'false')
76
+ return false;
77
+ if (value.startsWith('[') && value.endsWith(']')) {
78
+ try {
79
+ return JSON.parse(value);
80
+ }
81
+ catch {
82
+ return value;
83
+ }
84
+ }
85
+ // Try to parse as number (integer or float)
86
+ if (/^-?\d+(\.\d+)?$/.test(value)) {
87
+ return Number(value);
88
+ }
89
+ return value.replace(/^["']|["']$/g, '');
90
+ }
91
+ export function serializeFrontmatter(meta, body) {
92
+ const frontmatter = Object.entries(meta)
93
+ .filter(([, value]) => value !== undefined && value !== null)
94
+ .map(([key, value]) => formatEntry(key, value))
95
+ .join('\n');
96
+ return `---\n${frontmatter}\n---\n\n${body}\n`;
97
+ }
98
+ function formatEntry(key, value) {
99
+ if (Array.isArray(value)) {
100
+ if (value.length === 0)
101
+ return `${key}: []`;
102
+ if (value.every(v => typeof v === 'number')) {
103
+ return `${key}: [${value.join(', ')}]`;
104
+ }
105
+ return `${key}:\n${value.map(v => ` - ${formatScalar(v)}`).join('\n')}`;
106
+ }
107
+ return `${key}: ${formatScalar(value)}`;
108
+ }
109
+ function formatScalar(value) {
110
+ if (typeof value === 'boolean' || typeof value === 'number')
111
+ return String(value);
112
+ const s = String(value);
113
+ return needsQuotes(s) ? `"${s.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"` : s;
114
+ }
115
+ function needsQuotes(s) {
116
+ if (s === '')
117
+ return true;
118
+ if (/^(true|false|null|yes|no|on|off|~)$/i.test(s))
119
+ return true;
120
+ if (/^-?\d+(\.\d+)?$/.test(s))
121
+ return true;
122
+ // Starts with a YAML-special character or whitespace
123
+ if (/^[\s!&*?|>%@`[\]{},#"'-]/.test(s))
124
+ return true;
125
+ // Contains ": ", " #", tab, or newline
126
+ if (/:\s|\s#|\t|\n/.test(s))
127
+ return true;
128
+ // Trailing whitespace
129
+ if (/\s$/.test(s))
130
+ return true;
131
+ // Contains chars conventionally quoted for safety (cron expressions, etc.)
132
+ if (/[*?&!|>%`]/.test(s))
133
+ return true;
134
+ return false;
135
+ }
136
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../../lib/frontmatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Match a string against a glob pattern. Only `*` wildcard is supported (matches any
3
+ * characters, zero or more). Patterns without `*` must match exactly. Other regex
4
+ * specials in the pattern are escaped.
5
+ *
6
+ * Examples:
7
+ * matchesGlob('memory.*', 'memory.search') // true
8
+ * matchesGlob('memory.*', 'channel.send') // false
9
+ * matchesGlob('mcp.atlassian.*', 'mcp.atlassian.create_issue') // true
10
+ * matchesGlob('*', 'anything') // true
11
+ * matchesGlob('exact', 'exact') // true
12
+ */
13
+ export declare function matchesGlob(pattern: string, str: string): boolean;
14
+ //# sourceMappingURL=glob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.d.ts","sourceRoot":"","sources":["../../lib/glob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAMjE"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Match a string against a glob pattern. Only `*` wildcard is supported (matches any
3
+ * characters, zero or more). Patterns without `*` must match exactly. Other regex
4
+ * specials in the pattern are escaped.
5
+ *
6
+ * Examples:
7
+ * matchesGlob('memory.*', 'memory.search') // true
8
+ * matchesGlob('memory.*', 'channel.send') // false
9
+ * matchesGlob('mcp.atlassian.*', 'mcp.atlassian.create_issue') // true
10
+ * matchesGlob('*', 'anything') // true
11
+ * matchesGlob('exact', 'exact') // true
12
+ */
13
+ export function matchesGlob(pattern, str) {
14
+ if (!pattern.includes('*'))
15
+ return pattern === str;
16
+ const re = new RegExp('^' + pattern.split('*').map(escapeRegex).join('.*') + '$');
17
+ return re.test(str);
18
+ }
19
+ function escapeRegex(s) {
20
+ return s.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
21
+ }
22
+ //# sourceMappingURL=glob.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"glob.js","sourceRoot":"","sources":["../../lib/glob.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,GAAW;IACtD,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,KAAK,GAAG,CAAC;IACnD,MAAM,EAAE,GAAG,IAAI,MAAM,CACnB,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAC3D,CAAC;IACF,OAAO,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACtB,CAAC;AAED,SAAS,WAAW,CAAC,CAAS;IAC5B,OAAO,CAAC,CAAC,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Heartbeat utilities — pure functions for heartbeat poll logic
3
+ */
4
+ /**
5
+ * Returns true if HEARTBEAT.md content has no actionable tasks.
6
+ * Skips blank lines, markdown headers, empty list items, and HTML comments.
7
+ */
8
+ export declare function isHeartbeatContentEffectivelyEmpty(content: string): boolean;
9
+ /**
10
+ * Strip HEARTBEAT_OK token from response text.
11
+ * Returns null if the entire response was only the token (signal to skip delivery).
12
+ * Returns cleaned text otherwise.
13
+ */
14
+ export declare function stripHeartbeatToken(text: string): string | null;
15
+ /**
16
+ * Check if the current hour is within active hours.
17
+ * Returns true if no config (always active).
18
+ * Supports overnight ranges (e.g. 22→6).
19
+ *
20
+ * @param activeHours [startHour, endHour] (0–23). Interpreted in `timeZone` when set, else UTC.
21
+ */
22
+ export declare function isWithinActiveHours(activeHours?: [number, number], timeZone?: string): boolean;
23
+ //# sourceMappingURL=heartbeat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../lib/heartbeat.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAU3E;AAKD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI/D;AAYD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAOT"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Heartbeat utilities — pure functions for heartbeat poll logic
3
+ */
4
+ /**
5
+ * Returns true if HEARTBEAT.md content has no actionable tasks.
6
+ * Skips blank lines, markdown headers, empty list items, and HTML comments.
7
+ */
8
+ export function isHeartbeatContentEffectivelyEmpty(content) {
9
+ for (const line of content.split('\n')) {
10
+ const trimmed = line.trim();
11
+ if (!trimmed)
12
+ continue;
13
+ if (trimmed.startsWith('#'))
14
+ continue;
15
+ if (trimmed === '-' || trimmed === '- [ ]')
16
+ continue;
17
+ if (trimmed.startsWith('<!--') && trimmed.endsWith('-->'))
18
+ continue;
19
+ return false;
20
+ }
21
+ return true;
22
+ }
23
+ // Matches HEARTBEAT_OK with optional markdown wrapping (bold, backtick, strikethrough)
24
+ const HEARTBEAT_TOKEN_RE = /(?:\*{1,2}|`|~~)?HEARTBEAT_OK(?:\*{1,2}|`|~~)?/g;
25
+ /**
26
+ * Strip HEARTBEAT_OK token from response text.
27
+ * Returns null if the entire response was only the token (signal to skip delivery).
28
+ * Returns cleaned text otherwise.
29
+ */
30
+ export function stripHeartbeatToken(text) {
31
+ const stripped = text.replace(HEARTBEAT_TOKEN_RE, '').trim();
32
+ if (!stripped)
33
+ return null;
34
+ return stripped;
35
+ }
36
+ function currentHourInZone(timeZone) {
37
+ const parts = new Intl.DateTimeFormat('en-GB', {
38
+ timeZone,
39
+ hour: 'numeric',
40
+ hour12: false,
41
+ }).formatToParts(new Date());
42
+ const hourPart = parts.find(p => p.type === 'hour');
43
+ return parseInt(hourPart?.value ?? '0', 10);
44
+ }
45
+ /**
46
+ * Check if the current hour is within active hours.
47
+ * Returns true if no config (always active).
48
+ * Supports overnight ranges (e.g. 22→6).
49
+ *
50
+ * @param activeHours [startHour, endHour] (0–23). Interpreted in `timeZone` when set, else UTC.
51
+ */
52
+ export function isWithinActiveHours(activeHours, timeZone) {
53
+ if (!activeHours)
54
+ return true;
55
+ const [start, end] = activeHours;
56
+ const hour = timeZone ? currentHourInZone(timeZone) : new Date().getUTCHours();
57
+ if (start <= end)
58
+ return hour >= start && hour < end;
59
+ // Overnight: e.g. [22, 6] → active 22:00→06:00
60
+ return hour >= start || hour < end;
61
+ }
62
+ //# sourceMappingURL=heartbeat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"heartbeat.js","sourceRoot":"","sources":["../../lib/heartbeat.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;GAGG;AACH,MAAM,UAAU,kCAAkC,CAAC,OAAe;IAChE,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACtC,IAAI,OAAO,KAAK,GAAG,IAAI,OAAO,KAAK,OAAO;YAAE,SAAS;QACrD,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QACpE,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,uFAAuF;AACvF,MAAM,kBAAkB,GAAG,iDAAiD,CAAC;AAE7E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC7D,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAC;IAC3B,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;QAC7C,QAAQ;QACR,IAAI,EAAE,SAAS;QACf,MAAM,EAAE,KAAK;KACd,CAAC,CAAC,aAAa,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IACpD,OAAO,QAAQ,CAAC,QAAQ,EAAE,KAAK,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,WAA8B,EAC9B,QAAiB;IAEjB,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,GAAG,WAAW,CAAC;IACjC,MAAM,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/E,IAAI,KAAK,IAAI,GAAG;QAAE,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,CAAC;IACrD,+CAA+C;IAC/C,OAAO,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG,GAAG,CAAC;AACrC,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Shared HTML utilities backed by turndown.
3
+ * - stripHtml: simple tag stripping (for link expansion)
4
+ * - htmlToMarkdown: proper conversion preserving links, headings, lists (for web.fetch)
5
+ */
6
+ export declare function htmlToMarkdown(html: string): string;
7
+ export declare function stripHtml(html: string): string;
8
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../lib/html.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAOH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAKnD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY9C"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Shared HTML utilities backed by turndown.
3
+ * - stripHtml: simple tag stripping (for link expansion)
4
+ * - htmlToMarkdown: proper conversion preserving links, headings, lists (for web.fetch)
5
+ */
6
+ import TurndownService from 'turndown';
7
+ const turndown = new TurndownService({ headingStyle: 'atx', bulletListMarker: '-' });
8
+ turndown.remove(['script', 'style', 'noscript']);
9
+ export function htmlToMarkdown(html) {
10
+ const titleMatch = html.match(/<title[^>]*>([\s\S]*?)<\/title>/i);
11
+ const title = titleMatch?.[1]?.trim();
12
+ const text = turndown.turndown(html).replace(/\n{3,}/g, '\n\n').trim();
13
+ return title ? `# ${title}\n\n${text}` : text;
14
+ }
15
+ export function stripHtml(html) {
16
+ return html
17
+ .replace(/<(script|style)[^>]*>[\s\S]*?<\/\1>/gi, ' ')
18
+ .replace(/<[^>]+>/g, ' ')
19
+ .replace(/&amp;/g, '&')
20
+ .replace(/&lt;/g, '<')
21
+ .replace(/&gt;/g, '>')
22
+ .replace(/&quot;/g, '"')
23
+ .replace(/&#39;/g, "'")
24
+ .replace(/&nbsp;/g, ' ')
25
+ .replace(/\s+/g, ' ')
26
+ .trim();
27
+ }
28
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../lib/html.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,eAAe,MAAM,UAAU,CAAC;AAEvC,MAAM,QAAQ,GAAG,IAAI,eAAe,CAAC,EAAE,YAAY,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,EAAE,CAAC,CAAC;AACrF,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;AAEjD,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,kCAAkC,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC;IACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;IACvE,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,IAAI;SACR,OAAO,CAAC,uCAAuC,EAAE,GAAG,CAAC;SACrD,OAAO,CAAC,UAAU,EAAE,GAAG,CAAC;SACxB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC;SACrB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;SACtB,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC;SACvB,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;AACZ,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** HTTP response validation utilities */
2
+ export interface HttpResponse {
3
+ ok: boolean;
4
+ status: number;
5
+ statusText?: string;
6
+ }
7
+ /**
8
+ * Validate HTTP response and throw with formatted error message.
9
+ * Extracts method/URL context from error message if available.
10
+ */
11
+ export declare function validateHttpResponse(res: HttpResponse, context: string): void;
12
+ //# sourceMappingURL=http-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-validate.d.ts","sourceRoot":"","sources":["../../lib/http-validate.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,GAAG,EAAE,YAAY,EACjB,OAAO,EAAE,MAAM,GACd,IAAI,CAIN"}
@@ -0,0 +1,11 @@
1
+ /** HTTP response validation utilities */
2
+ /**
3
+ * Validate HTTP response and throw with formatted error message.
4
+ * Extracts method/URL context from error message if available.
5
+ */
6
+ export function validateHttpResponse(res, context) {
7
+ if (!res.ok) {
8
+ throw new Error(`${context} failed: ${res.status} ${res.statusText || 'error'}`);
9
+ }
10
+ }
11
+ //# sourceMappingURL=http-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http-validate.js","sourceRoot":"","sources":["../../lib/http-validate.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAQzC;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,GAAiB,EACjB,OAAe;IAEf,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,GAAG,OAAO,YAAY,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,IAAI,OAAO,EAAE,CAAC,CAAC;IACnF,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ /** Generate a short unique ID with a prefix: `prefix-timestamp-random` */
2
+ export declare function generateId(prefix: string): string;
3
+ //# sourceMappingURL=id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.d.ts","sourceRoot":"","sources":["../../lib/id.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD"}
package/dist/lib/id.js ADDED
@@ -0,0 +1,5 @@
1
+ /** Generate a short unique ID with a prefix: `prefix-timestamp-random` */
2
+ export function generateId(prefix) {
3
+ return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
4
+ }
5
+ //# sourceMappingURL=id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"id.js","sourceRoot":"","sources":["../../lib/id.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,GAAG,MAAM,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { Bus } from '../gateway/bus.js';
2
+ import type { Json } from '../gateway/events.js';
3
+ /** Called once by LogService.boot() to wire the global logger to the bus. */
4
+ export declare function setLoggerBus(bus: Bus): void;
5
+ export declare function ts(): string;
6
+ export declare function createLogger(service: string): {
7
+ debug: (msg: string, data?: Json) => void;
8
+ info: (msg: string, data?: Json) => void;
9
+ warn: (msg: string, data?: Json) => void;
10
+ error: (msg: string, data?: Json) => void;
11
+ };
12
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAIjD,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,CAE3C;AAED,wBAAgB,EAAE,IAAI,MAAM,CAK3B;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM;iBAU3B,MAAM,SAAS,IAAI;gBACnB,MAAM,SAAS,IAAI;gBACnB,MAAM,SAAS,IAAI;iBACnB,MAAM,SAAS,IAAI;EAEnC"}
@@ -0,0 +1,28 @@
1
+ let _bus = null;
2
+ /** Called once by LogService.boot() to wire the global logger to the bus. */
3
+ export function setLoggerBus(bus) {
4
+ _bus = bus;
5
+ }
6
+ export function ts() {
7
+ const d = new Date();
8
+ const pad = (n) => String(n).padStart(2, '0');
9
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ` +
10
+ `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}.${Math.floor(d.getMilliseconds() / 100)}`;
11
+ }
12
+ export function createLogger(service) {
13
+ function write(level, message, data) {
14
+ if (_bus) {
15
+ _bus.emit('log.onLog', { level, service, message, ...(data !== undefined ? { data } : {}) });
16
+ }
17
+ else {
18
+ console.error(`${ts()} [${service}] ${level.toUpperCase()} ${message}`, data ?? '');
19
+ }
20
+ }
21
+ return {
22
+ debug: (msg, data) => write('debug', msg, data),
23
+ info: (msg, data) => write('info', msg, data),
24
+ warn: (msg, data) => write('warn', msg, data),
25
+ error: (msg, data) => write('error', msg, data),
26
+ };
27
+ }
28
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../lib/logger.ts"],"names":[],"mappings":"AAGA,IAAI,IAAI,GAAe,IAAI,CAAC;AAE5B,6EAA6E;AAC7E,MAAM,UAAU,YAAY,CAAC,GAAQ;IACnC,IAAI,GAAG,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,EAAE;IAChB,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACrB,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG;QAClE,GAAG,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,EAAE,GAAG,GAAG,CAAC,EAAE,CAAC;AACvH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,SAAS,KAAK,CAAC,KAA0C,EAAE,OAAe,EAAE,IAAW;QACrF,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/F,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,KAAK,OAAO,KAAK,KAAK,CAAC,WAAW,EAAE,IAAI,OAAO,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAED,OAAO;QACL,KAAK,EAAE,CAAC,GAAW,EAAE,IAAW,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;QAC9D,IAAI,EAAG,CAAC,GAAW,EAAE,IAAW,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAG,GAAG,EAAE,IAAI,CAAC;QAC9D,IAAI,EAAG,CAAC,GAAW,EAAE,IAAW,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAG,GAAG,EAAE,IAAI,CAAC;QAC9D,KAAK,EAAE,CAAC,GAAW,EAAE,IAAW,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC;KAC/D,CAAC;AACJ,CAAC"}