codesesh 0.17.0 → 0.18.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 +2 -2
- package/dist/{chunk-A4U2SMJJ.js → chunk-DHNP33L4.js} +20 -12
- package/dist/chunk-DHNP33L4.js.map +1 -0
- package/dist/{chunk-7APNDHQ6.js → chunk-HIYT2ZJL.js} +659 -353
- package/dist/chunk-HIYT2ZJL.js.map +1 -0
- package/dist/{dist-KEPJFHOC.js → dist-DMGLFBW6.js} +14 -4
- package/dist/index.js +224 -81
- package/dist/index.js.map +1 -1
- package/dist/scan-refresh-worker.js +2 -2
- package/dist/search-index-worker.js +73 -39
- package/dist/search-index-worker.js.map +1 -1
- package/dist/smart-tag-worker.js +2 -2
- package/dist/web/assets/AgentIcon-DcUJM198.js +1 -0
- package/dist/web/assets/BookmarkButton-CJjTjyae.js +1 -0
- package/dist/web/assets/Dashboard-wjTLT17d.js +39 -0
- package/dist/web/assets/DialogTitle-Bz0eXTGu.js +1 -0
- package/dist/web/assets/InteractiveReceipt-xnRqJvfd.js +1 -0
- package/dist/web/assets/PrismHighlighter-C7OfXHq2.js +6 -0
- package/dist/web/assets/Projects-DBxubQuM.js +1 -0
- package/dist/web/assets/SearchFilterBar-BG9ah_Po.js +1 -0
- package/dist/web/assets/SearchResultsPanel-Clmf2xKw.js +1 -0
- package/dist/web/assets/SessionDetail-CgR7ipmi.js +54 -0
- package/dist/web/assets/index-DR07vs5V.js +1890 -0
- package/dist/web/assets/index-DuB6tGoe.css +2 -0
- package/dist/web/assets/index.dom-CCLJ9_FR.js +1 -0
- package/dist/web/assets/jsx-runtime-n5LQ9ujS.js +1 -0
- package/dist/web/assets/preload-helper-CmKXJxR3.js +1 -0
- package/dist/web/assets/session-indexes-EHJdYE4j.js +4 -0
- package/dist/web/assets/session-title-CNhapdPJ.js +1 -0
- package/dist/web/assets/useTheme-CwDcVdGz.js +1 -0
- package/dist/web/assets/utils-B6KiDbIe.js +1 -0
- package/dist/web/index.html +11 -7
- package/package.json +3 -3
- package/dist/chunk-7APNDHQ6.js.map +0 -1
- package/dist/chunk-A4U2SMJJ.js.map +0 -1
- package/dist/web/assets/index-B076CRkD.js +0 -109
- package/dist/web/assets/index-CWNbVhet.css +0 -2
- package/dist/web/assets/markdown-dR4kAewZ.js +0 -14
- package/dist/web/assets/react-D9s532MZ.js +0 -1821
- package/dist/web/assets/rolldown-runtime-QTnfLwEv.js +0 -1
- package/dist/web/assets/syntax-mZXQuVcd.js +0 -6
- package/dist/web/assets/vendor-i9U7_fNF.js +0 -41
- /package/dist/{dist-KEPJFHOC.js.map → dist-DMGLFBW6.js.map} +0 -0
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ npx codesesh --cwd .
|
|
|
71
71
|
# Only show specific agent
|
|
72
72
|
npx codesesh --agent claudecode
|
|
73
73
|
|
|
74
|
-
#
|
|
74
|
+
# Print the session index as JSON instead of starting the server
|
|
75
75
|
npx codesesh --json
|
|
76
76
|
|
|
77
77
|
# Show performance trace logs
|
|
@@ -91,7 +91,7 @@ npx codesesh --trace
|
|
|
91
91
|
| `--from` | — | — | Sessions active after this date `YYYY-MM-DD` |
|
|
92
92
|
| `--to` | — | — | Sessions active before this date `YYYY-MM-DD` |
|
|
93
93
|
| `--session` | `-s` | — | Directly open a session (`agent://session-id`) |
|
|
94
|
-
| `--json` | `-j` | `false` |
|
|
94
|
+
| `--json` | `-j` | `false` | Print the session index as JSON and exit (metadata only) |
|
|
95
95
|
| `--no-open` | — | `false` | Don't auto-open the browser |
|
|
96
96
|
| `--trace` | — | `false` | Print performance trace logs |
|
|
97
97
|
| `--cache` | — | `true` | Use cached scan results when available |
|
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
+
ensurePrivateDirectory,
|
|
4
|
+
restrictExistingPrivateFiles,
|
|
5
|
+
restrictPrivateFile,
|
|
3
6
|
setCoreDiagnostics
|
|
4
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-HIYT2ZJL.js";
|
|
5
8
|
|
|
6
9
|
// src/logging.ts
|
|
7
|
-
import {
|
|
8
|
-
appendFileSync,
|
|
9
|
-
existsSync,
|
|
10
|
-
mkdirSync,
|
|
11
|
-
readdirSync,
|
|
12
|
-
renameSync,
|
|
13
|
-
statSync,
|
|
14
|
-
unlinkSync
|
|
15
|
-
} from "fs";
|
|
10
|
+
import { appendFileSync, existsSync, readdirSync, renameSync, statSync, unlinkSync } from "fs";
|
|
16
11
|
import { homedir } from "os";
|
|
17
12
|
import { join } from "path";
|
|
18
13
|
var LEVEL_WEIGHT = {
|
|
@@ -68,6 +63,7 @@ var AppLogger = class {
|
|
|
68
63
|
maxFiles;
|
|
69
64
|
currentPath;
|
|
70
65
|
rotationIndex = 0;
|
|
66
|
+
restrictedExistingLogs = false;
|
|
71
67
|
constructor(options = {}) {
|
|
72
68
|
this.logDir = options.logDir ?? process.env.CODESESH_LOG_DIR ?? getDefaultLogDir();
|
|
73
69
|
this.level = options.level ?? parseLevel(process.env.CODESESH_LOG_LEVEL);
|
|
@@ -93,7 +89,8 @@ var AppLogger = class {
|
|
|
93
89
|
write(level, event, data) {
|
|
94
90
|
if (LEVEL_WEIGHT[level] < LEVEL_WEIGHT[this.level]) return;
|
|
95
91
|
try {
|
|
96
|
-
|
|
92
|
+
ensurePrivateDirectory(this.logDir);
|
|
93
|
+
this.restrictExistingLogs();
|
|
97
94
|
const line = `${JSON.stringify({
|
|
98
95
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
99
96
|
level,
|
|
@@ -104,9 +101,19 @@ var AppLogger = class {
|
|
|
104
101
|
`;
|
|
105
102
|
this.rotateIfNeeded(Buffer.byteLength(line));
|
|
106
103
|
appendFileSync(this.currentPath, line, "utf8");
|
|
104
|
+
restrictPrivateFile(this.currentPath);
|
|
107
105
|
} catch {
|
|
108
106
|
}
|
|
109
107
|
}
|
|
108
|
+
/** Logs rotated by an earlier run predate the owner-only policy. */
|
|
109
|
+
restrictExistingLogs() {
|
|
110
|
+
if (this.restrictedExistingLogs) return;
|
|
111
|
+
this.restrictedExistingLogs = true;
|
|
112
|
+
restrictExistingPrivateFiles(
|
|
113
|
+
this.logDir,
|
|
114
|
+
(name) => name.startsWith("codesesh") && name.endsWith(".log")
|
|
115
|
+
);
|
|
116
|
+
}
|
|
110
117
|
rotateIfNeeded(nextBytes) {
|
|
111
118
|
if (!existsSync(this.currentPath)) {
|
|
112
119
|
this.removeExpiredLogs();
|
|
@@ -120,6 +127,7 @@ var AppLogger = class {
|
|
|
120
127
|
`codesesh-${timestampForFile()}-${process.pid}-${this.rotationIndex}.log`
|
|
121
128
|
);
|
|
122
129
|
renameSync(this.currentPath, rotatedPath);
|
|
130
|
+
restrictPrivateFile(rotatedPath);
|
|
123
131
|
this.removeExpiredLogs();
|
|
124
132
|
}
|
|
125
133
|
removeExpiredLogs() {
|
|
@@ -166,4 +174,4 @@ export {
|
|
|
166
174
|
appLogger,
|
|
167
175
|
logSearchIndexSync
|
|
168
176
|
};
|
|
169
|
-
//# sourceMappingURL=chunk-
|
|
177
|
+
//# sourceMappingURL=chunk-DHNP33L4.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 restrictExistingPrivateFiles,\n restrictPrivateFile,\n} from \"@codesesh/core\";\nimport type { SearchIndexSyncResult } from \"@codesesh/core\";\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\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\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.log\");\n }\n\n getLogPath(): string {\n return this.currentPath;\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 try {\n ensurePrivateDirectory(this.logDir);\n this.restrictExistingLogs();\n const line = `${JSON.stringify({\n ts: new Date().toISOString(),\n level,\n event,\n pid: process.pid,\n ...(toLogValue(data) as Record<string, unknown>),\n })}\\n`;\n this.rotateIfNeeded(Buffer.byteLength(line));\n appendFileSync(this.currentPath, line, \"utf8\");\n // Logs carry project paths and error detail.\n restrictPrivateFile(this.currentPath);\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): void {\n if (!existsSync(this.currentPath)) {\n this.removeExpiredLogs();\n return;\n }\n\n const currentSize = statSync(this.currentPath).size;\n if (currentSize + nextBytes <= this.maxBytes) return;\n\n this.rotationIndex += 1;\n const rotatedPath = join(\n this.logDir,\n `codesesh-${timestampForFile()}-${process.pid}-${this.rotationIndex}.log`,\n );\n renameSync(this.currentPath, rotatedPath);\n restrictPrivateFile(rotatedPath);\n this.removeExpiredLogs();\n }\n\n private removeExpiredLogs(): void {\n const rotated = readdirSync(this.logDir)\n .filter((name) => /^codesesh-.+\\.log$/.test(name))\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 || 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 { 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 */\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":[]}
|