@lossless-claude/lcm 0.5.0 → 0.7.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/.claude-plugin/commands/lcm-compact.md +10 -0
- package/.claude-plugin/commands/lcm-curate.md +16 -6
- package/.claude-plugin/commands/lcm-diagnose.md +10 -0
- package/.claude-plugin/commands/lcm-doctor.md +1 -1
- package/.claude-plugin/commands/lcm-dogfood.md +1 -1
- package/.claude-plugin/commands/lcm-import.md +10 -0
- package/.claude-plugin/commands/lcm-promote.md +10 -0
- package/.claude-plugin/commands/lcm-sensitive.md +10 -0
- package/.claude-plugin/commands/lcm-stats.md +1 -1
- package/.claude-plugin/commands/lcm-status.md +10 -0
- package/.claude-plugin/hooks/README.md +1 -1
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +14 -2
- package/.claude-plugin/skills/lcm-context/SKILL.md +10 -0
- package/.claude-plugin/skills/lcm-dogfood/SKILL.md +1 -1
- package/.claude-plugin/skills/lcm-dogfood/references/checks.md +1 -1
- package/README.md +2 -2
- package/dist/bin/lcm.js +828 -474
- package/dist/bin/lcm.js.map +1 -1
- package/dist/installer/install.d.ts +6 -5
- package/dist/installer/install.js +116 -108
- package/dist/installer/install.js.map +1 -1
- package/dist/src/batch-compact.d.ts +7 -1
- package/dist/src/batch-compact.js +80 -6
- package/dist/src/batch-compact.js.map +1 -1
- package/dist/src/bootstrap.d.ts +24 -0
- package/dist/src/bootstrap.js +76 -0
- package/dist/src/bootstrap.js.map +1 -0
- package/dist/src/cli/pipeline-runner.d.ts +47 -0
- package/dist/src/cli/pipeline-runner.js +106 -0
- package/dist/src/cli/pipeline-runner.js.map +1 -0
- package/dist/src/cli/pipeline-step.d.ts +20 -0
- package/dist/src/cli/pipeline-step.js +6 -0
- package/dist/src/cli/pipeline-step.js.map +1 -0
- package/dist/src/cli/progress-state.d.ts +61 -0
- package/dist/src/cli/progress-state.js +16 -0
- package/dist/src/cli/progress-state.js.map +1 -0
- package/dist/src/cli/render-frame.d.ts +26 -0
- package/dist/src/cli/render-frame.js +153 -0
- package/dist/src/cli/render-frame.js.map +1 -0
- package/dist/src/cli/render-summary.d.ts +8 -0
- package/dist/src/cli/render-summary.js +79 -0
- package/dist/src/cli/render-summary.js.map +1 -0
- package/dist/src/cli-help.js +15 -9
- package/dist/src/cli-help.js.map +1 -1
- package/dist/src/codex-transcript.d.ts +50 -0
- package/dist/src/codex-transcript.js +207 -0
- package/dist/src/codex-transcript.js.map +1 -0
- package/dist/src/daemon/auth.d.ts +2 -0
- package/dist/src/daemon/auth.js +40 -0
- package/dist/src/daemon/auth.js.map +1 -0
- package/dist/src/daemon/client.d.ts +5 -1
- package/dist/src/daemon/client.js +21 -2
- package/dist/src/daemon/client.js.map +1 -1
- package/dist/src/daemon/config.d.ts +15 -0
- package/dist/src/daemon/config.js +33 -8
- package/dist/src/daemon/config.js.map +1 -1
- package/dist/src/daemon/content-fence.d.ts +7 -0
- package/dist/src/daemon/content-fence.js +14 -0
- package/dist/src/daemon/content-fence.js.map +1 -0
- package/dist/src/daemon/lifecycle.js +5 -0
- package/dist/src/daemon/lifecycle.js.map +1 -1
- package/dist/src/daemon/orientation.d.ts +1 -0
- package/dist/src/daemon/orientation.js +35 -6
- package/dist/src/daemon/orientation.js.map +1 -1
- package/dist/src/daemon/project.d.ts +1 -0
- package/dist/src/daemon/project.js +95 -3
- package/dist/src/daemon/project.js.map +1 -1
- package/dist/src/daemon/routes/compact.js +41 -10
- package/dist/src/daemon/routes/compact.js.map +1 -1
- package/dist/src/daemon/routes/describe.js +12 -1
- package/dist/src/daemon/routes/describe.js.map +1 -1
- package/dist/src/daemon/routes/expand.js +12 -1
- package/dist/src/daemon/routes/expand.js.map +1 -1
- package/dist/src/daemon/routes/grep.js +11 -2
- package/dist/src/daemon/routes/grep.js.map +1 -1
- package/dist/src/daemon/routes/ingest.js +36 -8
- package/dist/src/daemon/routes/ingest.js.map +1 -1
- package/dist/src/daemon/routes/promote-events.d.ts +3 -0
- package/dist/src/daemon/routes/promote-events.js +180 -0
- package/dist/src/daemon/routes/promote-events.js.map +1 -0
- package/dist/src/daemon/routes/promote.js +18 -3
- package/dist/src/daemon/routes/promote.js.map +1 -1
- package/dist/src/daemon/routes/prompt-search.js +11 -2
- package/dist/src/daemon/routes/prompt-search.js.map +1 -1
- package/dist/src/daemon/routes/recent.js +11 -2
- package/dist/src/daemon/routes/recent.js.map +1 -1
- package/dist/src/daemon/routes/restore.js +117 -69
- package/dist/src/daemon/routes/restore.js.map +1 -1
- package/dist/src/daemon/routes/search.js +12 -1
- package/dist/src/daemon/routes/search.js.map +1 -1
- package/dist/src/daemon/routes/session-complete.d.ts +2 -0
- package/dist/src/daemon/routes/session-complete.js +36 -0
- package/dist/src/daemon/routes/session-complete.js.map +1 -0
- package/dist/src/daemon/routes/status.js +77 -64
- package/dist/src/daemon/routes/status.js.map +1 -1
- package/dist/src/daemon/routes/store.d.ts +2 -1
- package/dist/src/daemon/routes/store.js +42 -8
- package/dist/src/daemon/routes/store.js.map +1 -1
- package/dist/src/daemon/safe-error.d.ts +5 -0
- package/dist/src/daemon/safe-error.js +15 -0
- package/dist/src/daemon/safe-error.js.map +1 -0
- package/dist/src/daemon/server.d.ts +3 -1
- package/dist/src/daemon/server.js +37 -17
- package/dist/src/daemon/server.js.map +1 -1
- package/dist/src/daemon/validate-cwd.d.ts +5 -0
- package/dist/src/daemon/validate-cwd.js +38 -0
- package/dist/src/daemon/validate-cwd.js.map +1 -0
- package/dist/src/daemon/version.d.ts +10 -0
- package/dist/src/daemon/version.js +31 -0
- package/dist/src/daemon/version.js.map +1 -0
- package/dist/src/db/events-path.d.ts +2 -0
- package/dist/src/db/events-path.js +11 -0
- package/dist/src/db/events-path.js.map +1 -0
- package/dist/src/db/events-stats.d.ts +29 -0
- package/dist/src/db/events-stats.js +107 -0
- package/dist/src/db/events-stats.js.map +1 -0
- package/dist/src/db/migration.js +8 -0
- package/dist/src/db/migration.js.map +1 -1
- package/dist/src/diagnose.js +14 -1
- package/dist/src/diagnose.js.map +1 -1
- package/dist/src/doctor/doctor.d.ts +1 -1
- package/dist/src/doctor/doctor.js +184 -15
- package/dist/src/doctor/doctor.js.map +1 -1
- package/dist/src/hooks/auto-heal.js +24 -1
- package/dist/src/hooks/auto-heal.js.map +1 -1
- package/dist/src/hooks/compact.js +7 -0
- package/dist/src/hooks/compact.js.map +1 -1
- package/dist/src/hooks/dispatch.d.ts +1 -1
- package/dist/src/hooks/dispatch.js +19 -1
- package/dist/src/hooks/dispatch.js.map +1 -1
- package/dist/src/hooks/events-db.d.ts +41 -0
- package/dist/src/hooks/events-db.js +190 -0
- package/dist/src/hooks/events-db.js.map +1 -0
- package/dist/src/hooks/extractors.d.ts +17 -0
- package/dist/src/hooks/extractors.js +198 -0
- package/dist/src/hooks/extractors.js.map +1 -0
- package/dist/src/hooks/hook-errors.d.ts +14 -0
- package/dist/src/hooks/hook-errors.js +56 -0
- package/dist/src/hooks/hook-errors.js.map +1 -0
- package/dist/src/hooks/post-tool.d.ts +4 -0
- package/dist/src/hooks/post-tool.js +43 -0
- package/dist/src/hooks/post-tool.js.map +1 -0
- package/dist/src/hooks/restore.js +31 -1
- package/dist/src/hooks/restore.js.map +1 -1
- package/dist/src/hooks/session-end.d.ts +3 -0
- package/dist/src/hooks/session-end.js +68 -5
- package/dist/src/hooks/session-end.js.map +1 -1
- package/dist/src/hooks/session-snapshot.d.ts +12 -0
- package/dist/src/hooks/session-snapshot.js +100 -0
- package/dist/src/hooks/session-snapshot.js.map +1 -0
- package/dist/src/hooks/user-prompt.js +44 -5
- package/dist/src/hooks/user-prompt.js.map +1 -1
- package/dist/src/import-summary.d.ts +4 -0
- package/dist/src/import-summary.js +34 -0
- package/dist/src/import-summary.js.map +1 -0
- package/dist/src/import.d.ts +11 -1
- package/dist/src/import.js +218 -88
- package/dist/src/import.js.map +1 -1
- package/dist/src/installer/settings.d.ts +5 -0
- package/dist/src/installer/settings.js +74 -0
- package/dist/src/installer/settings.js.map +1 -0
- package/dist/src/mcp/server.d.ts +15 -0
- package/dist/src/mcp/server.js +83 -6
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/promotion/detector.js +19 -5
- package/dist/src/promotion/detector.js.map +1 -1
- package/dist/src/scrub.js +26 -0
- package/dist/src/scrub.js.map +1 -1
- package/dist/src/stats.d.ts +4 -0
- package/dist/src/stats.js +23 -0
- package/dist/src/stats.js.map +1 -1
- package/dist/src/store/conversation-store.js +2 -1
- package/dist/src/store/conversation-store.js.map +1 -1
- package/dist/src/store/regex-safety.d.ts +1 -0
- package/dist/src/store/regex-safety.js +22 -0
- package/dist/src/store/regex-safety.js.map +1 -0
- package/dist/src/store/summary-store.js +2 -1
- package/dist/src/store/summary-store.js.map +1 -1
- package/docs/passive-learning.md +138 -0
- package/lcm.mjs +20 -1
- package/package.json +5 -2
|
@@ -12,6 +12,16 @@ const DEFAULTS = {
|
|
|
12
12
|
architecturePatterns: ["src/[\\w/]+\\.ts", "[A-Z][a-zA-Z]+(Engine|Store|Service|Manager|Handler|Client)", "interface [A-Z]", "class [A-Z]"],
|
|
13
13
|
dedupBm25Threshold: 15,
|
|
14
14
|
dedupCandidateLimit: 100,
|
|
15
|
+
eventConfidence: {
|
|
16
|
+
decision: 0.5,
|
|
17
|
+
plan: 0.7,
|
|
18
|
+
errorFix: 0.4,
|
|
19
|
+
batch: 0.3,
|
|
20
|
+
pattern: 0.2,
|
|
21
|
+
},
|
|
22
|
+
reinforcementBoost: 0.3,
|
|
23
|
+
maxConfidence: 1.0,
|
|
24
|
+
insightsMaxAgeDays: 90,
|
|
15
25
|
},
|
|
16
26
|
},
|
|
17
27
|
restoration: { recentSummaries: 3, promptSearchMinScore: 2, promptSearchMaxResults: 3, promptSnippetLength: 200, recencyHalfLifeHours: 24, crossSessionAffinity: 0.85 },
|
|
@@ -20,15 +30,25 @@ const DEFAULTS = {
|
|
|
20
30
|
security: {
|
|
21
31
|
sensitivePatterns: [],
|
|
22
32
|
},
|
|
33
|
+
hooks: { snapshotIntervalSec: 60, disableAutoCompact: false },
|
|
23
34
|
};
|
|
24
|
-
|
|
35
|
+
const DENIED_KEYS = new Set(["__proto__", "constructor", "prototype"]);
|
|
36
|
+
export function deepMerge(target, source) {
|
|
25
37
|
if (!source || typeof source !== "object")
|
|
26
38
|
return target;
|
|
27
39
|
const result = { ...target };
|
|
28
40
|
for (const key of Object.keys(source)) {
|
|
41
|
+
if (DENIED_KEYS.has(key))
|
|
42
|
+
continue;
|
|
29
43
|
if (source[key] !== undefined) {
|
|
30
|
-
result[key] = (typeof source[key] === "object" &&
|
|
31
|
-
|
|
44
|
+
result[key] = (typeof source[key] === "object" &&
|
|
45
|
+
source[key] !== null &&
|
|
46
|
+
!Array.isArray(source[key]) &&
|
|
47
|
+
typeof result[key] === "object" &&
|
|
48
|
+
result[key] !== null &&
|
|
49
|
+
!Array.isArray(result[key]))
|
|
50
|
+
? deepMerge(result[key], source[key])
|
|
51
|
+
: source[key];
|
|
32
52
|
}
|
|
33
53
|
}
|
|
34
54
|
return result;
|
|
@@ -40,16 +60,21 @@ export function loadDaemonConfig(configPath, overrides, env) {
|
|
|
40
60
|
fileConfig = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
41
61
|
}
|
|
42
62
|
catch { }
|
|
43
|
-
|
|
63
|
+
// Always merge untrusted sources (fileConfig, overrides) into a trusted target so that
|
|
64
|
+
// DENIED_KEYS filtering applies before any untrusted key reaches the result object.
|
|
65
|
+
// Precedence: DEFAULTS < fileConfig < overrides.
|
|
66
|
+
const withFile = deepMerge(structuredClone(DEFAULTS), fileConfig);
|
|
67
|
+
const merged = deepMerge(withFile, overrides ?? {});
|
|
44
68
|
// Migrate legacy provider names from v0.3.0
|
|
45
69
|
if (merged.llm.provider === "claude-cli")
|
|
46
70
|
merged.llm.provider = "claude-process";
|
|
47
71
|
// Migrate legacy mergeMaxEntries (renamed to dedupCandidateLimit)
|
|
48
|
-
|
|
49
|
-
|
|
72
|
+
const thresholds = merged.compaction.promotionThresholds;
|
|
73
|
+
if (thresholds["mergeMaxEntries"] !== undefined && thresholds["dedupCandidateLimit"] === undefined) {
|
|
74
|
+
thresholds["dedupCandidateLimit"] = thresholds["mergeMaxEntries"];
|
|
50
75
|
}
|
|
51
|
-
delete
|
|
52
|
-
delete
|
|
76
|
+
delete thresholds["mergeMaxEntries"];
|
|
77
|
+
delete thresholds["confidenceDecayRate"];
|
|
53
78
|
if (merged.llm.apiKey)
|
|
54
79
|
merged.llm.apiKey = merged.llm.apiKey.replace(/\$\{(\w+)\}/g, (_, k) => e[k] ?? "");
|
|
55
80
|
// Env var override: LCM_SUMMARY_PROVIDER takes precedence over config
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/daemon/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/daemon/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps content in XML-like fence tags with basic sanitization to reduce
|
|
3
|
+
* prompt injection surface when re-injecting summaries into conversations.
|
|
4
|
+
*
|
|
5
|
+
* Not a silver bullet — defense in depth alongside auth + scrubbing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function fenceContent(content: string, tag: string): string;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wraps content in XML-like fence tags with basic sanitization to reduce
|
|
3
|
+
* prompt injection surface when re-injecting summaries into conversations.
|
|
4
|
+
*
|
|
5
|
+
* Not a silver bullet — defense in depth alongside auth + scrubbing.
|
|
6
|
+
*/
|
|
7
|
+
export function fenceContent(content, tag) {
|
|
8
|
+
// Strip ANSI escape sequences
|
|
9
|
+
let sanitized = content.replace(/\x1b\[[0-9;]*[a-zA-Z]/g, "");
|
|
10
|
+
// Escape any closing tags that match our fence tag
|
|
11
|
+
sanitized = sanitized.replace(new RegExp(`</${tag}>`, "gi"), `</${tag}>`);
|
|
12
|
+
return `<${tag}>\n${sanitized}\n</${tag}>`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=content-fence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content-fence.js","sourceRoot":"","sources":["../../../src/daemon/content-fence.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,GAAW;IACvD,8BAA8B;IAC9B,IAAI,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAC;IAC9D,mDAAmD;IACnD,SAAS,GAAG,SAAS,CAAC,OAAO,CAC3B,IAAI,MAAM,CAAC,KAAK,GAAG,GAAG,EAAE,IAAI,CAAC,EAC7B,QAAQ,GAAG,MAAM,CAClB,CAAC;IACF,OAAO,IAAI,GAAG,MAAM,SAAS,OAAO,GAAG,GAAG,CAAC;AAC7C,CAAC"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, writeFileSync, unlinkSync } from "node:fs";
|
|
2
2
|
import { spawn } from "node:child_process";
|
|
3
|
+
import { join, dirname } from "node:path";
|
|
4
|
+
import { ensureAuthToken } from "./auth.js";
|
|
3
5
|
function sleep(ms) {
|
|
4
6
|
return new Promise((r) => setTimeout(r, ms));
|
|
5
7
|
}
|
|
@@ -73,6 +75,9 @@ export async function ensureDaemon(opts) {
|
|
|
73
75
|
if (opts._skipSpawn) {
|
|
74
76
|
return { connected: false, port: opts.port, spawned: false };
|
|
75
77
|
}
|
|
78
|
+
// Ensure auth token exists before spawning
|
|
79
|
+
const tokenPath = join(dirname(opts.pidFilePath), "daemon.token");
|
|
80
|
+
ensureAuthToken(tokenPath);
|
|
76
81
|
const spawnCommand = opts.spawnCommand ?? process.execPath;
|
|
77
82
|
const spawnArgs = opts.spawnArgs ?? [process.argv[1], "daemon", "start"];
|
|
78
83
|
const spawnImpl = opts._spawnOverride ?? spawn;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/daemon/lifecycle.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC9E,OAAO,EAAE,KAAK,EAAqB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../../src/daemon/lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1,2 @@
|
|
|
1
|
+
export declare const LCM_MD_CONTENT = "# lossless-claude memory \u2014 MANDATORY routing rules\n\nMemory is captured automatically by hooks. Do NOT store manually.\n\n## When to search\n\nSearch memory BEFORE asking the user about past decisions, architectural context, or anything that may have been discussed in a prior session.\n\n## Tools\n\n| Tool | Use for |\n|------|---------|\n| `lcm_search` | Broad conceptual recall \u2014 \"how was X implemented\", \"decision about Y\" |\n| `lcm_grep` | Exact keyword, error message, function name |\n| `lcm_describe` | Check metadata of a summary node before expanding |\n| `lcm_expand` | Decompress a summary node for full content |\n\n## Retrieval chain\n\n```\nlcm_search \"topic\" \u2192 broad matches, find nodeId\nlcm_grep \"exact term\" \u2192 narrow to specific references\nlcm_describe <nodeId> \u2192 check if worth expanding\nlcm_expand <nodeId> \u2192 full decompressed content\n```\n\n## Storage\n\nMemory is captured automatically by hooks. Do NOT store manually via `lcm store` CLI \u2014 use the MCP tools (`lcm_store`) only when explicitly needed.\n";
|
|
1
2
|
export declare function buildOrientationPrompt(): string;
|
|
@@ -1,9 +1,38 @@
|
|
|
1
|
+
// Content written to ~/.claude/lcm.md during install/doctor — loaded via CLAUDE.md @include.
|
|
2
|
+
// Kept here as the single source of truth for the guidance text.
|
|
3
|
+
export const LCM_MD_CONTENT = `# lossless-claude memory — MANDATORY routing rules
|
|
4
|
+
|
|
5
|
+
Memory is captured automatically by hooks. Do NOT store manually.
|
|
6
|
+
|
|
7
|
+
## When to search
|
|
8
|
+
|
|
9
|
+
Search memory BEFORE asking the user about past decisions, architectural context, or anything that may have been discussed in a prior session.
|
|
10
|
+
|
|
11
|
+
## Tools
|
|
12
|
+
|
|
13
|
+
| Tool | Use for |
|
|
14
|
+
|------|---------|
|
|
15
|
+
| \`lcm_search\` | Broad conceptual recall — "how was X implemented", "decision about Y" |
|
|
16
|
+
| \`lcm_grep\` | Exact keyword, error message, function name |
|
|
17
|
+
| \`lcm_describe\` | Check metadata of a summary node before expanding |
|
|
18
|
+
| \`lcm_expand\` | Decompress a summary node for full content |
|
|
19
|
+
|
|
20
|
+
## Retrieval chain
|
|
21
|
+
|
|
22
|
+
\`\`\`
|
|
23
|
+
lcm_search "topic" → broad matches, find nodeId
|
|
24
|
+
lcm_grep "exact term" → narrow to specific references
|
|
25
|
+
lcm_describe <nodeId> → check if worth expanding
|
|
26
|
+
lcm_expand <nodeId> → full decompressed content
|
|
27
|
+
\`\`\`
|
|
28
|
+
|
|
29
|
+
## Storage
|
|
30
|
+
|
|
31
|
+
Memory is captured automatically by hooks. Do NOT store manually via \`lcm store\` CLI — use the MCP tools (\`lcm_store\`) only when explicitly needed.
|
|
32
|
+
`;
|
|
33
|
+
// Guidance is now delivered via ~/.claude/lcm.md (installed by `lcm install` / `lcm doctor`),
|
|
34
|
+
// which CLAUDE.md includes via @lcm.md. No per-session injection needed.
|
|
1
35
|
export function buildOrientationPrompt() {
|
|
2
|
-
return
|
|
3
|
-
Memory system active. Guidelines:
|
|
4
|
-
- lcm_grep / lcm_expand / lcm_describe / lcm_search → conversation history and project memory
|
|
5
|
-
- Do not store directly to any memory system — lossless-claude manages persistence automatically
|
|
6
|
-
- When uncertain what was discussed or decided, use lcm_search before asking the user
|
|
7
|
-
</memory-orientation>`;
|
|
36
|
+
return "";
|
|
8
37
|
}
|
|
9
38
|
//# sourceMappingURL=orientation.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"orientation.js","sourceRoot":"","sources":["../../../src/daemon/orientation.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB;IACpC,OAAO
|
|
1
|
+
{"version":3,"file":"orientation.js","sourceRoot":"","sources":["../../../src/daemon/orientation.ts"],"names":[],"mappings":"AAAA,6FAA6F;AAC7F,iEAAiE;AACjE,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B7B,CAAC;AAEF,8FAA8F;AAC9F,yEAAyE;AACzE,MAAM,UAAU,sBAAsB;IACpC,OAAO,EAAE,CAAC;AACZ,CAAC"}
|
|
@@ -3,5 +3,6 @@ export declare const projectId: (cwd: string) => string;
|
|
|
3
3
|
export declare const projectDir: (cwd: string) => string;
|
|
4
4
|
export declare const projectDbPath: (cwd: string) => string;
|
|
5
5
|
export declare const projectMetaPath: (cwd: string) => string;
|
|
6
|
+
export declare function isSafeTranscriptPath(transcriptPath: string, cwd: string): string | false;
|
|
6
7
|
/** Ensures the project dir exists and writes cwd to meta.json. */
|
|
7
8
|
export declare const ensureProjectDir: (cwd: string) => string;
|
|
@@ -1,12 +1,104 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { existsSync, lstatSync, mkdirSync, realpathSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { homedir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
4
|
+
import { join, resolve, normalize, join as pathJoin, dirname, basename } from "node:path";
|
|
5
5
|
export const BASE_DIR = join(homedir(), ".lossless-claude");
|
|
6
|
-
|
|
6
|
+
function canonicalizeCwd(cwd) {
|
|
7
|
+
try {
|
|
8
|
+
return realpathSync(cwd);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return cwd;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export const projectId = (cwd) => createHash("sha256").update(canonicalizeCwd(cwd)).digest("hex");
|
|
7
15
|
export const projectDir = (cwd) => join(BASE_DIR, "projects", projectId(cwd));
|
|
8
16
|
export const projectDbPath = (cwd) => join(projectDir(cwd), "db.sqlite");
|
|
9
17
|
export const projectMetaPath = (cwd) => join(projectDir(cwd), "meta.json");
|
|
18
|
+
function tryRealpath(p) {
|
|
19
|
+
try {
|
|
20
|
+
return realpathSync(p);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return p;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Like realpathSync but handles non-existent paths by resolving the nearest
|
|
28
|
+
* existing ancestor and appending the remaining components.
|
|
29
|
+
* This ensures symlinked parent directories are resolved even when the leaf
|
|
30
|
+
* path doesn't exist yet (e.g. a transcript file not yet created).
|
|
31
|
+
*/
|
|
32
|
+
function realpathDeep(p) {
|
|
33
|
+
try {
|
|
34
|
+
return realpathSync(p);
|
|
35
|
+
}
|
|
36
|
+
catch { /* fall through */ }
|
|
37
|
+
// Walk up to find the nearest existing ancestor, then reconstruct
|
|
38
|
+
const parts = [];
|
|
39
|
+
let cur = p;
|
|
40
|
+
while (true) {
|
|
41
|
+
const parent = dirname(cur);
|
|
42
|
+
if (parent === cur)
|
|
43
|
+
break; // reached root
|
|
44
|
+
parts.unshift(basename(cur));
|
|
45
|
+
cur = parent;
|
|
46
|
+
try {
|
|
47
|
+
const real = realpathSync(cur);
|
|
48
|
+
return join(real, ...parts);
|
|
49
|
+
}
|
|
50
|
+
catch { /* keep walking up */ }
|
|
51
|
+
}
|
|
52
|
+
return p; // fallback: return original
|
|
53
|
+
}
|
|
54
|
+
export function isSafeTranscriptPath(transcriptPath, cwd) {
|
|
55
|
+
const resolved = resolve(transcriptPath);
|
|
56
|
+
// Check for symlinks: if the resolved path is a symlink, follow it and re-validate.
|
|
57
|
+
let lstat = null;
|
|
58
|
+
try {
|
|
59
|
+
lstat = lstatSync(resolved);
|
|
60
|
+
}
|
|
61
|
+
catch { /* file doesn't exist */ }
|
|
62
|
+
if (lstat?.isSymbolicLink()) {
|
|
63
|
+
// Follow symlink to real path and re-validate against allowed bases
|
|
64
|
+
let real;
|
|
65
|
+
try {
|
|
66
|
+
real = realpathSync(resolved);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
const allowedBases = [
|
|
72
|
+
tryRealpath(pathJoin(homedir(), ".claude", "projects")),
|
|
73
|
+
tryRealpath(resolve(cwd)),
|
|
74
|
+
];
|
|
75
|
+
for (const base of allowedBases) {
|
|
76
|
+
const normalBase = normalize(base + "/");
|
|
77
|
+
if (real.startsWith(normalBase) || real === normalize(base)) {
|
|
78
|
+
return real;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
// Not a symlink (or doesn't exist yet): validate using resolve() — consistent with cwd.
|
|
84
|
+
// Canonicalize both the candidate path and the allowed bases via realpathSync so that
|
|
85
|
+
// a symlinked parent directory (e.g. /tmp -> /private/tmp on macOS) doesn't create
|
|
86
|
+
// a bypass in either direction.
|
|
87
|
+
// Use realpathDeep so non-existent leaf paths still get their parent directories
|
|
88
|
+
// resolved (e.g. /tmp/transcript.jsonl -> /private/tmp/transcript.jsonl on macOS).
|
|
89
|
+
const candidate = realpathDeep(resolved);
|
|
90
|
+
const allowedBases = [
|
|
91
|
+
tryRealpath(pathJoin(homedir(), ".claude", "projects")),
|
|
92
|
+
tryRealpath(resolve(cwd)),
|
|
93
|
+
];
|
|
94
|
+
for (const base of allowedBases) {
|
|
95
|
+
const normalBase = normalize(base + "/");
|
|
96
|
+
if (candidate.startsWith(normalBase) || candidate === normalize(base)) {
|
|
97
|
+
return candidate;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
10
102
|
/** Ensures the project dir exists and writes cwd to meta.json. */
|
|
11
103
|
export const ensureProjectDir = (cwd) => {
|
|
12
104
|
const dir = projectDir(cwd);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/daemon/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/daemon/project.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { readFileSync, writeFileSync, existsSync } from "node:fs";
|
|
2
2
|
import { DatabaseSync } from "node:sqlite";
|
|
3
|
-
import { projectId, projectDbPath, projectDir, projectMetaPath, ensureProjectDir } from "../project.js";
|
|
3
|
+
import { projectId, projectDbPath, projectDir, projectMetaPath, ensureProjectDir, isSafeTranscriptPath } from "../project.js";
|
|
4
4
|
import { enqueue } from "../project-queue.js";
|
|
5
5
|
import { sendJson } from "../server.js";
|
|
6
6
|
import { runLcmMigrations } from "../../db/migration.js";
|
|
@@ -11,6 +11,7 @@ import { CompactionEngine } from "../../compaction.js";
|
|
|
11
11
|
import { parseTranscript } from "../../transcript.js";
|
|
12
12
|
import { ScrubEngine } from "../../scrub.js";
|
|
13
13
|
import { resolveEffectiveProvider, createSummarizer } from "../summarizer.js";
|
|
14
|
+
import { validateCwd } from "../validate-cwd.js";
|
|
14
15
|
function fmtN(n) {
|
|
15
16
|
if (n >= 1_000_000)
|
|
16
17
|
return (n / 1_000_000).toFixed(1) + "M";
|
|
@@ -71,26 +72,45 @@ export function createCompactHandler(config) {
|
|
|
71
72
|
};
|
|
72
73
|
return async (_req, res, body) => {
|
|
73
74
|
const input = JSON.parse(body || "{}");
|
|
74
|
-
const { session_id,
|
|
75
|
+
const { session_id, transcript_path, skip_ingest, client, previous_summary } = input;
|
|
75
76
|
const MAX_PREVIOUS_SUMMARY_LENGTH = 50_000;
|
|
76
77
|
const validatedPreviousSummary = typeof previous_summary === "string"
|
|
77
78
|
? previous_summary.slice(0, MAX_PREVIOUS_SUMMARY_LENGTH)
|
|
78
79
|
: undefined;
|
|
79
|
-
if (!session_id || !cwd) {
|
|
80
|
+
if (!session_id || !input.cwd) {
|
|
80
81
|
sendJson(res, 400, { error: "session_id and cwd are required" });
|
|
81
82
|
return;
|
|
82
83
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
84
|
+
let cwd;
|
|
85
|
+
try {
|
|
86
|
+
cwd = validateCwd(input.cwd);
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
sendJson(res, 400, { error: err instanceof Error ? err.message : "invalid cwd" });
|
|
86
90
|
return;
|
|
87
91
|
}
|
|
92
|
+
// Guard must be checked and set synchronously (before any await) to prevent
|
|
93
|
+
// concurrent requests from racing through the has() check before add() runs.
|
|
88
94
|
if (compactingNow.has(session_id)) {
|
|
89
95
|
sendJson(res, 200, { skipped: true, summary: "Compaction already in progress for this session." });
|
|
90
96
|
return;
|
|
91
97
|
}
|
|
92
98
|
compactingNow.add(session_id);
|
|
99
|
+
const effectiveProvider = resolveEffectiveProvider(config, client);
|
|
100
|
+
const providerLabels = {
|
|
101
|
+
"claude-process": "Claude (process)",
|
|
102
|
+
"codex-process": "Codex (process)",
|
|
103
|
+
"anthropic": "Anthropic API",
|
|
104
|
+
"openai": "OpenAI API",
|
|
105
|
+
"disabled": "Disabled",
|
|
106
|
+
};
|
|
107
|
+
const providerLabel = providerLabels[effectiveProvider] ?? effectiveProvider;
|
|
93
108
|
try {
|
|
109
|
+
const summarize = await getSummarizer(effectiveProvider);
|
|
110
|
+
if (!summarize) {
|
|
111
|
+
sendJson(res, 200, { summary: "Summarization disabled — no summarizer configured.", providerId: effectiveProvider, providerLabel });
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
94
114
|
const pid = projectId(cwd);
|
|
95
115
|
const result = await enqueue(pid, async () => {
|
|
96
116
|
const dbPath = projectDbPath(cwd);
|
|
@@ -104,8 +124,9 @@ export function createCompactHandler(config) {
|
|
|
104
124
|
const summaryStore = new SummaryStore(db);
|
|
105
125
|
const conversation = await conversationStore.getOrCreateConversation(session_id);
|
|
106
126
|
// Ingest new messages from the transcript into the DB.
|
|
107
|
-
|
|
108
|
-
|
|
127
|
+
const safeTranscriptPath = transcript_path ? isSafeTranscriptPath(transcript_path, cwd) : false;
|
|
128
|
+
if (!skip_ingest && safeTranscriptPath && existsSync(safeTranscriptPath)) {
|
|
129
|
+
const parsed = parseTranscript(safeTranscriptPath);
|
|
109
130
|
const storedCount = await conversationStore.getMessageCount(conversation.conversationId);
|
|
110
131
|
const newMessages = parsed.slice(storedCount);
|
|
111
132
|
if (newMessages.length > 0) {
|
|
@@ -133,7 +154,7 @@ export function createCompactHandler(config) {
|
|
|
133
154
|
// Check if there's anything to compact
|
|
134
155
|
const tokenCount = await summaryStore.getContextTokenCount(conversation.conversationId);
|
|
135
156
|
if (tokenCount === 0) {
|
|
136
|
-
return { summary: "No messages to compact." };
|
|
157
|
+
return { summary: "No messages to compact.", providerId: effectiveProvider, providerLabel };
|
|
137
158
|
}
|
|
138
159
|
const engine = new CompactionEngine(conversationStore, summaryStore, {
|
|
139
160
|
contextThreshold: 0.75,
|
|
@@ -193,7 +214,14 @@ export function createCompactHandler(config) {
|
|
|
193
214
|
// Fall back to the most recent existing summary when no new summary was created
|
|
194
215
|
latestSummaryContent = allSummaries[allSummaries.length - 1]?.content;
|
|
195
216
|
}
|
|
196
|
-
return {
|
|
217
|
+
return {
|
|
218
|
+
summary: summaryMsg,
|
|
219
|
+
latestSummaryContent,
|
|
220
|
+
tokensBefore: compactResult.tokensBefore,
|
|
221
|
+
tokensAfter: compactResult.tokensAfter,
|
|
222
|
+
providerId: effectiveProvider,
|
|
223
|
+
providerLabel,
|
|
224
|
+
};
|
|
197
225
|
}
|
|
198
226
|
finally {
|
|
199
227
|
db.close();
|
|
@@ -201,6 +229,9 @@ export function createCompactHandler(config) {
|
|
|
201
229
|
}); // end enqueue
|
|
202
230
|
sendJson(res, 200, result);
|
|
203
231
|
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
sendJson(res, 500, { error: err instanceof Error ? err.message : "compact failed" });
|
|
234
|
+
}
|
|
204
235
|
finally {
|
|
205
236
|
compactingNow.delete(session_id);
|
|
206
237
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compact.js","sourceRoot":"","sources":["../../../../src/daemon/routes/compact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"compact.js","sourceRoot":"","sources":["../../../../src/daemon/routes/compact.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAC9H,OAAO,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,wBAAwB,EAAE,gBAAgB,EAA0B,MAAM,kBAAkB,CAAC;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,SAAS,IAAI,CAAC,CAAS;IACrB,IAAI,CAAC,IAAI,SAAS;QAAE,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAC5D,IAAI,CAAC,IAAI,KAAK;QAAE,OAAO,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IACpD,OAAO,MAAM,CAAC,CAAC,CAAC,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,CAItC;IACC,MAAM,KAAK,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC;IAC7C,MAAM,KAAK,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IACpF,MAAM,GAAG,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;QACzD,CAAC,CAAC,KAAK,CAAC;IACV,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,MAAM,MAAM,GAAG,CAAC,CAAC,YAAY,GAAG,CAAC;QAC/B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,WAAW,GAAG,CAAC,CAAC,YAAY,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,CAAC;IAC/D,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CACnB,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,EAC7B,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,MAAM,EAC7B,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EACzB,MAAM,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,MAAM,EAC9B,CAAC,CACF,CAAC;IACF,MAAM,GAAG,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG;QACX,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,kBAAkB,CAAC,CAAC,YAAY,YAAY;QACpE,KAAK,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,mBAAmB;QACvC,GAAG,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC;YACrB,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,+BAA+B,CAAC;YACtG,CAAC,CAAC,EAAE,CAAC;KACR,CAAC;IACF,OAAO;QACL,MAAM;QACN,6CAA6C;QAC7C,MAAM;QACN,EAAE;QACF,KAAK,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,4BAA4B,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE;QAC1E,KAAK,GAAG,KAAK,GAAG,SAAS;QACzB,KAAK,KAAK,sBAAsB,IAAI,CAAC,KAAK,CAAC,eAAe;QAC1D,EAAE;QACF,GAAG,IAAI;QACP,EAAE;QACF,MAAM;QACN,+CAA+C;QAC/C,MAAM;KACP,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,wDAAwD;AACxD,MAAM,CAAC,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC1D,MAAM,CAAC,MAAM,qBAAqB,GAAG,MAAM,CAAC;AAE5C,4DAA4D;AAC5D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;AAGxC,MAAM,UAAU,oBAAoB,CAAC,MAAoB;IACvD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAqD,CAAC;IAErF,MAAM,aAAa,GAAG,CAAC,QAA2B,EAAkC,EAAE;QACpF,IAAI,MAAM,GAAG,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,gBAAgB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YAC5C,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACxC,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;QACvC,MAAM,EAAE,UAAU,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAC;QACrF,MAAM,2BAA2B,GAAG,MAAM,CAAC;QAC3C,MAAM,wBAAwB,GAAG,OAAO,gBAAgB,KAAK,QAAQ;YACnE,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,2BAA2B,CAAC;YACxD,CAAC,CAAC,SAAS,CAAC;QAEd,IAAI,CAAC,UAAU,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC9B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,iCAAiC,EAAE,CAAC,CAAC;YACjE,OAAO;QACT,CAAC;QAED,IAAI,GAAW,CAAC;QAChB,IAAI,CAAC;YACH,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC;YAClF,OAAO;QACT,CAAC;QAED,4EAA4E;QAC5E,6EAA6E;QAC7E,IAAI,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YAClC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,kDAAkD,EAAE,CAAC,CAAC;YACnG,OAAO;QACT,CAAC;QACD,aAAa,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAE9B,MAAM,iBAAiB,GAAG,wBAAwB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnE,MAAM,cAAc,GAAsC;YACxD,gBAAgB,EAAE,kBAAkB;YACpC,eAAe,EAAE,iBAAiB;YAClC,WAAW,EAAE,eAAe;YAC5B,QAAQ,EAAE,YAAY;YACtB,UAAU,EAAE,UAAU;SACvB,CAAC;QACF,MAAM,aAAa,GAAG,cAAc,CAAC,iBAAiB,CAAC,IAAI,iBAAiB,CAAC;QAE7E,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,iBAAiB,CAAC,CAAC;YACzD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,oDAAoD,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAC,CAAC;gBACpI,OAAO;YACT,CAAC;YACD,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC3B,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,KAAK,IAAI,EAAE;gBAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;gBAClC,gBAAgB,CAAC,GAAG,CAAC,CAAC;gBAEtB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,UAAU,CAC3C,MAAM,CAAC,QAAQ,EAAE,iBAAiB,IAAI,EAAE,EACxC,UAAU,CAAC,GAAG,CAAC,CAChB,CAAC;gBAEF,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;gBACpC,IAAI,CAAC;oBACH,EAAE,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;oBACtC,gBAAgB,CAAC,EAAE,CAAC,CAAC;oBAErB,MAAM,iBAAiB,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;oBACpD,MAAM,YAAY,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;oBAC1C,MAAM,YAAY,GAAG,MAAM,iBAAiB,CAAC,uBAAuB,CAAC,UAAU,CAAC,CAAC;oBAEjF,uDAAuD;oBACvD,MAAM,kBAAkB,GAAG,eAAe,CAAC,CAAC,CAAC,oBAAoB,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;oBAChG,IAAI,CAAC,WAAW,IAAI,kBAAkB,IAAI,UAAU,CAAC,kBAAkB,CAAC,EAAE,CAAC;wBACzE,MAAM,MAAM,GAAG,eAAe,CAAC,kBAAkB,CAAC,CAAC;wBACnD,MAAM,WAAW,GAAG,MAAM,iBAAiB,CAAC,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;wBACzF,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;wBAC9C,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BAC3B,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;4BAC3D,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gCACtC,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gCAC7G,YAAY,CAAC,OAAO,IAAI,OAAO,CAAC;gCAChC,YAAY,CAAC,MAAM,IAAI,WAAW,CAAC;gCACnC,YAAY,CAAC,OAAO,IAAI,OAAO,CAAC;gCAChC,OAAO;oCACL,cAAc,EAAE,YAAY,CAAC,cAAc;oCAC3C,GAAG,EAAE,WAAW,GAAG,CAAC;oCACpB,IAAI,EAAE,CAAC,CAAC,IAAuC;oCAC/C,OAAO,EAAE,eAAe;oCACxB,UAAU,EAAE,CAAC,CAAC,UAAU;iCACzB,CAAC;4BACJ,CAAC,CAAC,CAAC;4BACH,MAAM,iBAAiB,CAAC,eAAe,CAAC,KAAK,IAAI,EAAE;gCACjD,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;gCACnE,qBAAqB,CAAC,EAAE,EAAE,GAAG,EAAE,YAAY,CAAC,CAAC;gCAC7C,MAAM,YAAY,CAAC,qBAAqB,CAAC,YAAY,CAAC,cAAc,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;4BACzG,CAAC,CAAC,CAAC;wBACL,CAAC;oBACH,CAAC;oBAED,uCAAuC;oBACvC,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,oBAAoB,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;oBAExF,IAAI,UAAU,KAAK,CAAC,EAAE,CAAC;wBACrB,OAAO,EAAE,OAAO,EAAE,yBAAyB,EAAE,UAAU,EAAE,iBAAiB,EAAE,aAAa,EAAE,CAAC;oBAC9F,CAAC;oBAED,MAAM,MAAM,GAAG,IAAI,gBAAgB,CAAC,iBAAiB,EAAE,YAAY,EAAE;wBACnE,gBAAgB,EAAE,IAAI;wBACtB,cAAc,EAAE,CAAC;wBACjB,aAAa,EAAE,CAAC;wBAChB,kBAAkB,EAAE,CAAC;wBACrB,sBAAsB,EAAE,CAAC;wBACzB,mBAAmB,EAAE,CAAC;wBACtB,gBAAgB,EAAE,MAAM,CAAC,UAAU,CAAC,UAAU;wBAC9C,qBAAqB,EAAE,GAAG;wBAC1B,SAAS,EAAE,EAAE;wBACb,QAAQ;qBACT,CAAC,CAAC;oBAEH,MAAM,aAAa,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;wBACzC,cAAc,EAAE,YAAY,CAAC,cAAc;wBAC3C,WAAW,EAAE,OAAO;wBACpB,SAAS;wBACT,KAAK,EAAE,IAAI;wBACX,sBAAsB,EAAE,wBAAwB;qBACjD,CAAC,CAAC;oBAEH,8EAA8E;oBAC9E,MAAM,YAAY,GAAG,MAAM,YAAY,CAAC,0BAA0B,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;oBAChG,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,eAAe,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;oBAC3F,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAE7F,4DAA4D;oBAC5D,MAAM,aAAa,GAAG,CAAC,CAAC;oBAExB,mBAAmB;oBACnB,IAAI,CAAC;wBACH,MAAM,QAAQ,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC;wBACtC,IAAI,IAAI,GAA4B,EAAE,CAAC;wBACvC,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;4BACzB,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;wBACrD,CAAC;wBACD,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;wBACf,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;wBAC5C,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;oBACzD,CAAC;oBAAC,MAAM,CAAC,CAAC,eAAe,CAAC,CAAC;oBAE3B,yBAAyB;oBACzB,gBAAgB,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;oBAE7C,MAAM,UAAU,GAAG,aAAa,CAAC,WAAW;wBAC1C,CAAC,CAAC,sBAAsB,CAAC;4BACrB,YAAY,EAAE,aAAa,CAAC,YAAY;4BACxC,WAAW,EAAE,aAAa,CAAC,WAAW;4BACtC,YAAY,EAAE,aAAa;4BAC3B,YAAY,EAAE,YAAY,CAAC,MAAM;4BACjC,QAAQ;4BACR,aAAa;yBACd,CAAC;wBACJ,CAAC,CAAC,uBAAuB,CAAC;oBAE5B,IAAI,oBAAwC,CAAC;oBAC7C,IAAI,aAAa,CAAC,gBAAgB,EAAE,CAAC;wBACnC,MAAM,aAAa,GAAG,MAAM,YAAY,CAAC,UAAU,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;wBACpF,oBAAoB,GAAG,aAAa,EAAE,OAAO,CAAC;oBAChD,CAAC;yBAAM,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;wBACnC,gFAAgF;wBAChF,oBAAoB,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC;oBACxE,CAAC;oBAED,OAAO;wBACL,OAAO,EAAE,UAAU;wBACnB,oBAAoB;wBACpB,YAAY,EAAE,aAAa,CAAC,YAAY;wBACxC,WAAW,EAAE,aAAa,CAAC,WAAW;wBACtC,UAAU,EAAE,iBAAiB;wBAC7B,aAAa;qBACd,CAAC;gBACJ,CAAC;wBAAS,CAAC;oBACT,EAAE,CAAC,KAAK,EAAE,CAAC;gBACb,CAAC;YACH,CAAC,CAAC,CAAC,CAAC,cAAc;YAElB,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACvF,CAAC;gBAAS,CAAC;YACT,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -7,14 +7,25 @@ import { runLcmMigrations } from "../../db/migration.js";
|
|
|
7
7
|
import { ConversationStore } from "../../store/conversation-store.js";
|
|
8
8
|
import { SummaryStore } from "../../store/summary-store.js";
|
|
9
9
|
import { RetrievalEngine } from "../../retrieval.js";
|
|
10
|
+
import { validateCwd } from "../validate-cwd.js";
|
|
10
11
|
export function createDescribeHandler(_config) {
|
|
11
12
|
return async (_req, res, body) => {
|
|
12
13
|
const input = JSON.parse(body || "{}");
|
|
13
|
-
const { nodeId
|
|
14
|
+
const { nodeId } = input;
|
|
14
15
|
if (!nodeId) {
|
|
15
16
|
sendJson(res, 400, { error: "nodeId is required" });
|
|
16
17
|
return;
|
|
17
18
|
}
|
|
19
|
+
let cwd;
|
|
20
|
+
if (input.cwd) {
|
|
21
|
+
try {
|
|
22
|
+
cwd = validateCwd(input.cwd);
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
sendJson(res, 200, { node: null });
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
18
29
|
if (!cwd || !existsSync(projectDbPath(cwd))) {
|
|
19
30
|
sendJson(res, 200, { node: null });
|
|
20
31
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../../../src/daemon/routes/describe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../../../../src/daemon/routes/describe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,UAAU,qBAAqB,CAAC,OAAqB;IACzD,OAAO,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;QACvC,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;QAEzB,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC,CAAC;YACpD,OAAO;QACT,CAAC;QAED,IAAI,GAAuB,CAAC;QAC5B,IAAI,KAAK,CAAC,GAAG,EAAE,CAAC;YACd,IAAI,CAAC;gBACH,GAAG,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;gBACnC,OAAO;YACT,CAAC;QACH,CAAC;QAED,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YAC5C,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YACnC,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;YAClC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAChD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;YACpC,gBAAgB,CAAC,EAAE,CAAC,CAAC;YACrB,MAAM,SAAS,GAAG,IAAI,iBAAiB,CAAC,EAAE,CAAC,CAAC;YAC5C,MAAM,SAAS,GAAG,IAAI,YAAY,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC7C,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;QACpG,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -8,14 +8,25 @@ import { ConversationStore } from "../../store/conversation-store.js";
|
|
|
8
8
|
import { SummaryStore } from "../../store/summary-store.js";
|
|
9
9
|
import { RetrievalEngine } from "../../retrieval.js";
|
|
10
10
|
import { ExpansionOrchestrator } from "../../expansion.js";
|
|
11
|
+
import { validateCwd } from "../validate-cwd.js";
|
|
11
12
|
export function createExpandHandler(_config) {
|
|
12
13
|
return async (_req, res, body) => {
|
|
13
14
|
const input = JSON.parse(body || "{}");
|
|
14
|
-
const { nodeId, depth = 1
|
|
15
|
+
const { nodeId, depth = 1 } = input;
|
|
15
16
|
if (!nodeId) {
|
|
16
17
|
sendJson(res, 400, { error: "nodeId is required" });
|
|
17
18
|
return;
|
|
18
19
|
}
|
|
20
|
+
let cwd;
|
|
21
|
+
if (input.cwd) {
|
|
22
|
+
try {
|
|
23
|
+
cwd = validateCwd(input.cwd);
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
sendJson(res, 200, { expanded: null, error: "project not found" });
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
19
30
|
if (!cwd || !existsSync(projectDbPath(cwd))) {
|
|
20
31
|
sendJson(res, 200, { expanded: null, error: "project not found" });
|
|
21
32
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expand.js","sourceRoot":"","sources":["../../../../src/daemon/routes/expand.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"expand.js","sourceRoot":"","sources":["../../../../src/daemon/routes/expand.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,15 +7,24 @@ import { runLcmMigrations } from "../../db/migration.js";
|
|
|
7
7
|
import { ConversationStore } from "../../store/conversation-store.js";
|
|
8
8
|
import { SummaryStore } from "../../store/summary-store.js";
|
|
9
9
|
import { RetrievalEngine } from "../../retrieval.js";
|
|
10
|
+
import { validateCwd } from "../validate-cwd.js";
|
|
10
11
|
export function createGrepHandler(_config) {
|
|
11
12
|
return async (_req, res, body) => {
|
|
12
13
|
const input = JSON.parse(body || "{}");
|
|
13
|
-
const { query, scope, mode, since
|
|
14
|
+
const { query, scope, mode, since } = input;
|
|
14
15
|
if (!query) {
|
|
15
16
|
sendJson(res, 400, { error: "query is required" });
|
|
16
17
|
return;
|
|
17
18
|
}
|
|
18
|
-
if (!cwd) {
|
|
19
|
+
if (!input.cwd) {
|
|
20
|
+
sendJson(res, 200, { matches: [] });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
let cwd;
|
|
24
|
+
try {
|
|
25
|
+
cwd = validateCwd(input.cwd);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
19
28
|
sendJson(res, 200, { matches: [] });
|
|
20
29
|
return;
|
|
21
30
|
}
|