codesesh 1.0.0 → 1.0.2

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 (46) hide show
  1. package/README.md +29 -5
  2. package/dist/{chunk-TIHF4T3K.js → chunk-PROMURPM.js} +80 -16
  3. package/dist/chunk-PROMURPM.js.map +1 -0
  4. package/dist/{chunk-BEF6LLRG.js → chunk-VAUC2W7I.js} +5317 -2268
  5. package/dist/chunk-VAUC2W7I.js.map +1 -0
  6. package/dist/{dist-3F467V44.js → dist-6QTGTYZT.js} +40 -4
  7. package/dist/index.js +1818 -454
  8. package/dist/index.js.map +1 -1
  9. package/dist/scan-refresh-worker.js +274 -95
  10. package/dist/scan-refresh-worker.js.map +1 -1
  11. package/dist/search-index-worker.js +112 -50
  12. package/dist/search-index-worker.js.map +1 -1
  13. package/dist/smart-tag-worker.js +5 -3
  14. package/dist/smart-tag-worker.js.map +1 -1
  15. package/dist/web/assets/ErrorBoundary-D11tWzfn.js +1 -0
  16. package/dist/web/assets/OverviewScreen-DriPmCam.js +1 -0
  17. package/dist/web/assets/Projects-BPDIcUBK.js +1 -0
  18. package/dist/web/assets/SearchFilterBar-Bx73B5e9.js +1 -0
  19. package/dist/web/assets/SearchResultsPanel-A6_3TPhW.js +1 -0
  20. package/dist/web/assets/SessionDetail-BnpvDwtH.js +54 -0
  21. package/dist/web/assets/agents-BkRP_ww3.js +1 -0
  22. package/dist/web/assets/contract-V6QuD0UY.js +1 -0
  23. package/dist/web/assets/index-99ZxpV2y.js +1410 -0
  24. package/dist/web/assets/index-B2RqUgZ5.css +1 -0
  25. package/dist/web/assets/panel-C-gc79Gz.js +1 -0
  26. package/dist/web/assets/session-indexes-0oT5HSS5.js +4 -0
  27. package/dist/web/assets/utils-DgUgu15E.js +1 -0
  28. package/dist/web/icon/agent/dsh.svg +3 -0
  29. package/dist/web/index.html +10 -32
  30. package/dist/web/theme-bootstrap.js +19 -0
  31. package/package.json +10 -10
  32. package/dist/chunk-BEF6LLRG.js.map +0 -1
  33. package/dist/chunk-TIHF4T3K.js.map +0 -1
  34. package/dist/web/assets/ErrorBoundary-BY-N1QzJ.js +0 -1
  35. package/dist/web/assets/OverviewScreen-_ZaVjhxN.js +0 -1
  36. package/dist/web/assets/Projects-q6cEm2dc.js +0 -1
  37. package/dist/web/assets/SearchFilterBar-CrVBpo40.js +0 -1
  38. package/dist/web/assets/SearchResultsPanel-Cg5V8Ia6.js +0 -1
  39. package/dist/web/assets/SessionDetail-BSSuddsZ.js +0 -54
  40. package/dist/web/assets/chunk-62JRHF6Z-BWRsEBnL.js +0 -4
  41. package/dist/web/assets/index-C3KgxGwE.js +0 -1410
  42. package/dist/web/assets/index-DQX42cFQ.css +0 -1
  43. package/dist/web/assets/panel-B7kuE60V.js +0 -1
  44. package/dist/web/assets/session-indexes-DmnjZ_JL.js +0 -1
  45. package/dist/web/assets/utils-t2u9IbNT.js +0 -1
  46. /package/dist/{dist-3F467V44.js.map → dist-6QTGTYZT.js.map} +0 -0
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  <p align="center"><strong>One place to see every AI coding session you've ever had.</strong></p>
8
8
 
9
- CodeSesh scans your local machine, finds every AI agent session (Claude Code, Cursor, Kimi, Kimi-Code, Codex, Grok, Pi, OpenCode, ZCode), and surfaces them in a unified, beautiful Web UI.
9
+ CodeSesh scans your local machine, finds every AI agent session (Claude Code, Cursor, Kimi, Kimi-Code, Codex, Grok, Pi, OpenCode, ZCode, DSH), and surfaces them in a unified, beautiful Web UI.
10
10
 
11
11
  ## Quick Start
12
12
 
@@ -52,6 +52,7 @@ Your browser will open at `http://localhost:4521` with all your sessions ready t
52
52
  | Pi | ✅ Supported |
53
53
  | OpenCode | ✅ Supported |
54
54
  | ZCode | ✅ Supported |
55
+ | DSH | ✅ Supported |
55
56
 
56
57
  ## Usage
57
58
 
@@ -87,7 +88,10 @@ npx codesesh --trace
87
88
  | ----------- | ----- | ------- | ----------------------------------------------------------- |
88
89
  | `--port` | `-p` | `4521` | HTTP server starting port; falls back to the next available port if busy |
89
90
  | `--host` | — | `127.0.0.1` | HTTP server bind address; non-loopback values require `--remote-access` |
90
- | `--remote-access` | — | `false` | Enable token-protected access on a non-loopback host |
91
+ | `--remote-access` | — | `false` | Enable token-protected access for any remotely exposed transport |
92
+ | `--tls-cert` | — | — | Path to a TLS certificate; serves remote access over HTTPS |
93
+ | `--tls-key` | — | — | Path to the private key matching `--tls-cert` |
94
+ | `--trust-proxy` | — | `false` | A reverse proxy in front of CodeSesh terminates TLS |
91
95
  | `--days` | `-d` | `7` | Only include sessions active in the last N days (`0` = all time) |
92
96
  | `--cwd` | — | — | Filter to sessions from a project directory |
93
97
  | `--agent` | `-a` | all | Filter to specific agent(s), comma-separated |
@@ -101,14 +105,34 @@ npx codesesh --trace
101
105
  | `--clear-cache` | — | `false` | Clear scan cache before starting |
102
106
  | `-v` | — | — | Print version number |
103
107
 
104
- When remote access is enabled, CodeSesh prints a startup URL containing a fresh access token.
105
- Anyone with that URL can read the indexed AI session history, so treat it as a password and do not
106
- share or persist it.
108
+ Non-loopback binding and `--trust-proxy` both require `--remote-access`. This includes the common
109
+ setup where CodeSesh listens on `127.0.0.1` and a same-machine reverse proxy exposes it publicly.
110
+ CodeSesh prints a startup URL containing a fresh access token. Anyone with that URL can read the
111
+ indexed AI session history, so treat it as a password and do not share or persist it.
112
+
113
+ A token authenticates the requester but does not encrypt traffic. Without TLS, the token and full
114
+ session content travel over the network in plaintext, and URL tokens may be recorded in proxy logs.
115
+ Use one of these protected transports:
116
+
117
+ ```bash
118
+ # CodeSesh terminates TLS
119
+ npx codesesh --host 0.0.0.0 --remote-access --tls-cert ./cert.pem --tls-key ./key.pem
120
+
121
+ # A reverse proxy terminates TLS; CodeSesh stays bound to loopback
122
+ npx codesesh --host 127.0.0.1 --remote-access --trust-proxy
123
+ ```
124
+
125
+ `--trust-proxy` requires `X-Forwarded-Proto: https` on every API request. The listener must remain
126
+ unreachable except through that trusted proxy.
107
127
 
108
128
  ## Requirements
109
129
 
130
+ <!-- repo-fact:node-version:start -->
131
+
110
132
  - Node.js 22+
111
133
 
134
+ <!-- repo-fact:node-version:end -->
135
+
112
136
  ## Links
113
137
 
114
138
  - [GitHub](https://github.com/xingkaixin/codesesh)
@@ -1,10 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
+ WORKER_LOG_MESSAGE_TYPE,
3
4
  ensurePrivateDirectory,
5
+ isWorkerLogMessage,
4
6
  restrictExistingPrivateFiles,
5
7
  restrictPrivateFile,
6
8
  setCoreDiagnostics
7
- } from "./chunk-BEF6LLRG.js";
9
+ } from "./chunk-VAUC2W7I.js";
8
10
 
9
11
  // src/logging.ts
10
12
  import { appendFileSync, existsSync, readdirSync, renameSync, statSync, unlinkSync } from "fs";
@@ -64,16 +66,34 @@ var AppLogger = class {
64
66
  currentPath;
65
67
  rotationIndex = 0;
66
68
  restrictedExistingLogs = false;
69
+ workerTarget = null;
70
+ writeFailureReported = false;
67
71
  constructor(options = {}) {
68
72
  this.logDir = options.logDir ?? process.env.CODESESH_LOG_DIR ?? getDefaultLogDir();
69
73
  this.level = options.level ?? parseLevel(process.env.CODESESH_LOG_LEVEL);
70
74
  this.maxBytes = options.maxBytes ?? parsePositiveInt(process.env.CODESESH_LOG_MAX_BYTES, 5e6);
71
75
  this.maxFiles = options.maxFiles ?? parsePositiveInt(process.env.CODESESH_LOG_MAX_FILES, 5);
72
- this.currentPath = join(this.logDir, "codesesh.log");
76
+ this.currentPath = join(this.logDir, `codesesh-${process.pid}.log`);
73
77
  }
74
78
  getLogPath() {
75
79
  return this.currentPath;
76
80
  }
81
+ forwardToParent(port, threadId2) {
82
+ this.workerTarget = { port, threadId: threadId2 };
83
+ }
84
+ consumeWorkerMessage(message) {
85
+ if (!isWorkerLogMessage(message)) return false;
86
+ if (LEVEL_WEIGHT[message.level] < LEVEL_WEIGHT[this.level]) return true;
87
+ this.appendRecord({
88
+ ...message.data,
89
+ ts: message.ts,
90
+ level: message.level,
91
+ event: message.event,
92
+ pid: message.pid,
93
+ thread_id: message.threadId
94
+ });
95
+ return true;
96
+ }
77
97
  debug(event, data = {}) {
78
98
  this.write("debug", event, data);
79
99
  }
@@ -88,20 +108,53 @@ var AppLogger = class {
88
108
  }
89
109
  write(level, event, data) {
90
110
  if (LEVEL_WEIGHT[level] < LEVEL_WEIGHT[this.level]) return;
111
+ const ts = (/* @__PURE__ */ new Date()).toISOString();
112
+ const normalizedData = toLogValue(data);
113
+ if (this.workerTarget) {
114
+ try {
115
+ this.workerTarget.port.postMessage({
116
+ type: WORKER_LOG_MESSAGE_TYPE,
117
+ ts,
118
+ level,
119
+ event,
120
+ pid: process.pid,
121
+ threadId: this.workerTarget.threadId,
122
+ data: normalizedData
123
+ });
124
+ } catch (error) {
125
+ this.reportWriteFailure(error);
126
+ }
127
+ return;
128
+ }
129
+ this.appendRecord({
130
+ ...normalizedData,
131
+ ts,
132
+ level,
133
+ event,
134
+ pid: process.pid
135
+ });
136
+ }
137
+ appendRecord(record) {
91
138
  try {
92
139
  ensurePrivateDirectory(this.logDir);
93
140
  this.restrictExistingLogs();
94
- const line = `${JSON.stringify({
95
- ts: (/* @__PURE__ */ new Date()).toISOString(),
96
- level,
97
- event,
98
- pid: process.pid,
99
- ...toLogValue(data)
100
- })}
141
+ const line = `${JSON.stringify(record)}
101
142
  `;
102
- this.rotateIfNeeded(Buffer.byteLength(line));
143
+ const restrictCurrentFile = this.rotateIfNeeded(Buffer.byteLength(line));
103
144
  appendFileSync(this.currentPath, line, "utf8");
104
- restrictPrivateFile(this.currentPath);
145
+ if (restrictCurrentFile) restrictPrivateFile(this.currentPath);
146
+ this.writeFailureReported = false;
147
+ } catch (error) {
148
+ this.reportWriteFailure(error);
149
+ }
150
+ }
151
+ reportWriteFailure(error) {
152
+ if (this.writeFailureReported) return;
153
+ this.writeFailureReported = true;
154
+ const message = error instanceof Error ? error.message : String(error);
155
+ try {
156
+ process.stderr.write(`[codesesh] Failed to write log ${this.currentPath}: ${message}
157
+ `);
105
158
  } catch {
106
159
  }
107
160
  }
@@ -117,21 +170,23 @@ var AppLogger = class {
117
170
  rotateIfNeeded(nextBytes) {
118
171
  if (!existsSync(this.currentPath)) {
119
172
  this.removeExpiredLogs();
120
- return;
173
+ return true;
121
174
  }
122
175
  const currentSize = statSync(this.currentPath).size;
123
- if (currentSize + nextBytes <= this.maxBytes) return;
176
+ if (currentSize + nextBytes <= this.maxBytes) return false;
124
177
  this.rotationIndex += 1;
125
178
  const rotatedPath = join(
126
179
  this.logDir,
127
- `codesesh-${timestampForFile()}-${process.pid}-${this.rotationIndex}.log`
180
+ `codesesh-${process.pid}-${timestampForFile()}-${this.rotationIndex}.log`
128
181
  );
129
182
  renameSync(this.currentPath, rotatedPath);
130
183
  restrictPrivateFile(rotatedPath);
131
184
  this.removeExpiredLogs();
185
+ return true;
132
186
  }
133
187
  removeExpiredLogs() {
134
- const rotated = readdirSync(this.logDir).filter((name) => /^codesesh-.+\.log$/.test(name)).map((name) => {
188
+ const ownedPrefix = `codesesh-${process.pid}-`;
189
+ const rotated = readdirSync(this.logDir).filter((name) => name.startsWith(ownedPrefix) && name.endsWith(".log")).map((name) => {
135
190
  const path = join(this.logDir, name);
136
191
  return { path, mtimeMs: statSync(path).mtimeMs };
137
192
  }).toSorted((a, b) => b.mtimeMs - a.mtimeMs);
@@ -142,6 +197,13 @@ var AppLogger = class {
142
197
  };
143
198
  var appLogger = new AppLogger();
144
199
  function logSearchIndexSync(context, result, data = {}) {
200
+ if (result?.failures?.length) {
201
+ appLogger.warn("search_index.sessions_skipped", {
202
+ context,
203
+ agent: result.agentName,
204
+ failures: result.failures
205
+ });
206
+ }
145
207
  if (!result || result.mode !== "bulk" || result.rebuildDurationMs == null) {
146
208
  return;
147
209
  }
@@ -161,6 +223,8 @@ function logSearchIndexSync(context, result, data = {}) {
161
223
  }
162
224
 
163
225
  // src/diagnostics-bridge.ts
226
+ import { parentPort, threadId } from "worker_threads";
227
+ if (parentPort) appLogger.forwardToParent(parentPort, threadId);
164
228
  setCoreDiagnostics({
165
229
  info(event, detail) {
166
230
  appLogger.info(event, detail);
@@ -174,4 +238,4 @@ export {
174
238
  appLogger,
175
239
  logSearchIndexSync
176
240
  };
177
- //# sourceMappingURL=chunk-TIHF4T3K.js.map
241
+ //# sourceMappingURL=chunk-PROMURPM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logging.ts","../src/diagnostics-bridge.ts"],"sourcesContent":["import { appendFileSync, existsSync, readdirSync, renameSync, statSync, unlinkSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n ensurePrivateDirectory,\n isWorkerLogMessage,\n restrictExistingPrivateFiles,\n restrictPrivateFile,\n WORKER_LOG_MESSAGE_TYPE,\n type WorkerLogLevel,\n type WorkerLogMessage,\n} from \"@codesesh/core\";\nimport type { SearchIndexSyncResult } from \"@codesesh/core\";\n\ntype LogLevel = WorkerLogLevel;\n\ninterface WorkerLogPort {\n postMessage(message: WorkerLogMessage): void;\n}\n\nconst LEVEL_WEIGHT: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n};\n\nexport interface LoggerOptions {\n logDir?: string;\n level?: LogLevel;\n maxBytes?: number;\n maxFiles?: number;\n}\n\nfunction parseLevel(value: string | undefined): LogLevel {\n if (value === \"debug\" || value === \"info\" || value === \"warn\" || value === \"error\") {\n return value;\n }\n return \"info\";\n}\n\nfunction parsePositiveInt(value: string | undefined, fallback: number): number {\n const parsed = Number(value);\n return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;\n}\n\nfunction getDefaultLogDir(): string {\n const base = process.env.XDG_CACHE_HOME ?? join(homedir(), \".cache\");\n return join(base, \"codesesh\", \"logs\");\n}\n\nfunction toLogValue(value: unknown, depth = 0): unknown {\n if (value == null || typeof value === \"string\" || typeof value === \"number\") return value;\n if (typeof value === \"boolean\") return value;\n if (typeof value === \"bigint\") return value.toString();\n if (value instanceof Error) {\n return {\n name: value.name,\n message: value.message,\n stack: value.stack,\n };\n }\n if (depth >= 4) return \"[truncated]\";\n if (Array.isArray(value)) return value.slice(0, 50).map((item) => toLogValue(item, depth + 1));\n if (typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(([key, item]) => [\n key,\n toLogValue(item, depth + 1),\n ]),\n );\n }\n return String(value);\n}\n\nfunction timestampForFile(date = new Date()): string {\n return date.toISOString().replace(/[:.]/g, \"-\");\n}\n\nexport class AppLogger {\n private readonly logDir: string;\n private readonly level: LogLevel;\n private readonly maxBytes: number;\n private readonly maxFiles: number;\n private readonly currentPath: string;\n private rotationIndex = 0;\n private restrictedExistingLogs = false;\n private workerTarget: { port: WorkerLogPort; threadId: number } | null = null;\n private writeFailureReported = false;\n\n constructor(options: LoggerOptions = {}) {\n this.logDir = options.logDir ?? process.env.CODESESH_LOG_DIR ?? getDefaultLogDir();\n this.level = options.level ?? parseLevel(process.env.CODESESH_LOG_LEVEL);\n this.maxBytes =\n options.maxBytes ?? parsePositiveInt(process.env.CODESESH_LOG_MAX_BYTES, 5_000_000);\n this.maxFiles = options.maxFiles ?? parsePositiveInt(process.env.CODESESH_LOG_MAX_FILES, 5);\n this.currentPath = join(this.logDir, `codesesh-${process.pid}.log`);\n }\n\n getLogPath(): string {\n return this.currentPath;\n }\n\n forwardToParent(port: WorkerLogPort, threadId: number): void {\n this.workerTarget = { port, threadId };\n }\n\n consumeWorkerMessage(message: unknown): boolean {\n if (!isWorkerLogMessage(message)) return false;\n if (LEVEL_WEIGHT[message.level] < LEVEL_WEIGHT[this.level]) return true;\n this.appendRecord({\n ...message.data,\n ts: message.ts,\n level: message.level,\n event: message.event,\n pid: message.pid,\n thread_id: message.threadId,\n });\n return true;\n }\n\n debug(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"debug\", event, data);\n }\n\n info(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"info\", event, data);\n }\n\n warn(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"warn\", event, data);\n }\n\n error(event: string, data: Record<string, unknown> = {}): void {\n this.write(\"error\", event, data);\n }\n\n private write(level: LogLevel, event: string, data: Record<string, unknown>): void {\n if (LEVEL_WEIGHT[level] < LEVEL_WEIGHT[this.level]) return;\n\n const ts = new Date().toISOString();\n const normalizedData = toLogValue(data) as Record<string, unknown>;\n if (this.workerTarget) {\n try {\n this.workerTarget.port.postMessage({\n type: WORKER_LOG_MESSAGE_TYPE,\n ts,\n level,\n event,\n pid: process.pid,\n threadId: this.workerTarget.threadId,\n data: normalizedData,\n });\n } catch (error) {\n this.reportWriteFailure(error);\n }\n return;\n }\n\n this.appendRecord({\n ...normalizedData,\n ts,\n level,\n event,\n pid: process.pid,\n });\n }\n\n private appendRecord(record: Record<string, unknown>): void {\n try {\n ensurePrivateDirectory(this.logDir);\n this.restrictExistingLogs();\n const line = `${JSON.stringify(record)}\\n`;\n const restrictCurrentFile = this.rotateIfNeeded(Buffer.byteLength(line));\n appendFileSync(this.currentPath, line, \"utf8\");\n if (restrictCurrentFile) restrictPrivateFile(this.currentPath);\n this.writeFailureReported = false;\n } catch (error) {\n this.reportWriteFailure(error);\n }\n }\n\n private reportWriteFailure(error: unknown): void {\n if (this.writeFailureReported) return;\n this.writeFailureReported = true;\n const message = error instanceof Error ? error.message : String(error);\n try {\n process.stderr.write(`[codesesh] Failed to write log ${this.currentPath}: ${message}\\n`);\n } catch {}\n }\n\n /** Logs rotated by an earlier run predate the owner-only policy. */\n private restrictExistingLogs(): void {\n if (this.restrictedExistingLogs) return;\n this.restrictedExistingLogs = true;\n restrictExistingPrivateFiles(\n this.logDir,\n (name) => name.startsWith(\"codesesh\") && name.endsWith(\".log\"),\n );\n }\n\n private rotateIfNeeded(nextBytes: number): boolean {\n if (!existsSync(this.currentPath)) {\n this.removeExpiredLogs();\n return true;\n }\n\n const currentSize = statSync(this.currentPath).size;\n if (currentSize + nextBytes <= this.maxBytes) return false;\n\n this.rotationIndex += 1;\n const rotatedPath = join(\n this.logDir,\n `codesesh-${process.pid}-${timestampForFile()}-${this.rotationIndex}.log`,\n );\n renameSync(this.currentPath, rotatedPath);\n restrictPrivateFile(rotatedPath);\n this.removeExpiredLogs();\n return true;\n }\n\n private removeExpiredLogs(): void {\n const ownedPrefix = `codesesh-${process.pid}-`;\n const rotated = readdirSync(this.logDir)\n .filter((name) => name.startsWith(ownedPrefix) && name.endsWith(\".log\"))\n .map((name) => {\n const path = join(this.logDir, name);\n return { path, mtimeMs: statSync(path).mtimeMs };\n })\n .toSorted((a, b) => b.mtimeMs - a.mtimeMs);\n\n for (const item of rotated.slice(Math.max(0, this.maxFiles - 1))) {\n unlinkSync(item.path);\n }\n }\n}\n\nexport const appLogger = new AppLogger();\n\nexport function logSearchIndexSync(\n context: string,\n result: SearchIndexSyncResult | null,\n data: Record<string, unknown> = {},\n): void {\n if (result?.failures?.length) {\n appLogger.warn(\"search_index.sessions_skipped\", {\n context,\n agent: result.agentName,\n failures: result.failures,\n });\n }\n if (!result || result.mode !== \"bulk\" || result.rebuildDurationMs == null) {\n return;\n }\n\n appLogger.info(\"search_index.sync\", {\n context,\n agent: result.agentName,\n mode: result.mode,\n sessions: result.sessions,\n changed: result.changed,\n deleted: result.deleted,\n indexed: result.indexed,\n skipped: result.skipped,\n duration_ms: Math.round(result.durationMs),\n rebuild_duration_ms: Math.round(result.rebuildDurationMs),\n ...data,\n });\n}\n","import { setCoreDiagnostics } from \"@codesesh/core\";\nimport { parentPort, threadId } from \"node:worker_threads\";\nimport { appLogger } from \"./logging.js\";\n\n/**\n * Bridges core's diagnostics sink to appLogger. Import this once, for its\n * side effect, from every entry point that gets its own module graph — the\n * main CLI thread and each worker_threads script (scan-refresh-worker,\n * search-index-worker, smart-tag-worker) — since core's module-level\n * diagnostics singleton is per-thread, not shared across workers.\n */\nif (parentPort) appLogger.forwardToParent(parentPort, threadId);\n\nsetCoreDiagnostics({\n info(event, detail) {\n appLogger.info(event, detail);\n },\n warn(event, detail) {\n appLogger.warn(event, detail);\n },\n});\n"],"mappings":"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","names":["threadId"]}