@malindar/whyline 0.1.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/settings.local.json +33 -0
- package/.github/workflows/ci.yml +35 -0
- package/.github/workflows/publish.yml +37 -0
- package/.prettierrc.json +7 -0
- package/CLAUDE.md +74 -0
- package/LICENSE +21 -0
- package/README.md +359 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +125 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/delete.d.ts +3 -0
- package/dist/commands/delete.js +42 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/doctor.d.ts +1 -0
- package/dist/commands/doctor.js +111 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/edit.d.ts +1 -0
- package/dist/commands/edit.js +78 -0
- package/dist/commands/edit.js.map +1 -0
- package/dist/commands/export.d.ts +8 -0
- package/dist/commands/export.js +90 -0
- package/dist/commands/export.js.map +1 -0
- package/dist/commands/import.d.ts +1 -0
- package/dist/commands/import.js +110 -0
- package/dist/commands/import.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.js +23 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/install-claude.d.ts +3 -0
- package/dist/commands/install-claude.js +180 -0
- package/dist/commands/install-claude.js.map +1 -0
- package/dist/commands/list.d.ts +4 -0
- package/dist/commands/list.js +35 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/mcp.d.ts +1 -0
- package/dist/commands/mcp.js +10 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/save.d.ts +4 -0
- package/dist/commands/save.js +74 -0
- package/dist/commands/save.js.map +1 -0
- package/dist/commands/search.d.ts +7 -0
- package/dist/commands/search.js +46 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/show.d.ts +3 -0
- package/dist/commands/show.js +30 -0
- package/dist/commands/show.js.map +1 -0
- package/dist/commands/stats.d.ts +1 -0
- package/dist/commands/stats.js +27 -0
- package/dist/commands/stats.js.map +1 -0
- package/dist/commands/summarize.d.ts +3 -0
- package/dist/commands/summarize.js +140 -0
- package/dist/commands/summarize.js.map +1 -0
- package/dist/config.d.ts +11 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/db/connection.d.ts +2 -0
- package/dist/db/connection.js +8 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/migrations.d.ts +2 -0
- package/dist/db/migrations.js +19 -0
- package/dist/db/migrations.js.map +1 -0
- package/dist/db/schema.d.ts +5 -0
- package/dist/db/schema.js +64 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/git/diff.d.ts +2 -0
- package/dist/git/diff.js +45 -0
- package/dist/git/diff.js.map +1 -0
- package/dist/git/git.d.ts +3 -0
- package/dist/git/git.js +25 -0
- package/dist/git/git.js.map +1 -0
- package/dist/git/repoId.d.ts +3 -0
- package/dist/git/repoId.js +49 -0
- package/dist/git/repoId.js.map +1 -0
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.js +296 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +119 -0
- package/dist/mcp/tools.js +43 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/memory/parseSummary.d.ts +14 -0
- package/dist/memory/parseSummary.js +53 -0
- package/dist/memory/parseSummary.js.map +1 -0
- package/dist/memory/qualityCheck.d.ts +13 -0
- package/dist/memory/qualityCheck.js +78 -0
- package/dist/memory/qualityCheck.js.map +1 -0
- package/dist/memory/redactSecrets.d.ts +7 -0
- package/dist/memory/redactSecrets.js +29 -0
- package/dist/memory/redactSecrets.js.map +1 -0
- package/dist/memory/repoContext.d.ts +2 -0
- package/dist/memory/repoContext.js +23 -0
- package/dist/memory/repoContext.js.map +1 -0
- package/dist/memory/saveMemory.d.ts +40 -0
- package/dist/memory/saveMemory.js +223 -0
- package/dist/memory/saveMemory.js.map +1 -0
- package/dist/memory/searchMemory.d.ts +17 -0
- package/dist/memory/searchMemory.js +122 -0
- package/dist/memory/searchMemory.js.map +1 -0
- package/dist/memory/types.d.ts +48 -0
- package/dist/memory/types.js +2 -0
- package/dist/memory/types.js.map +1 -0
- package/dist/output/format.d.ts +3 -0
- package/dist/output/format.js +43 -0
- package/dist/output/format.js.map +1 -0
- package/docs/architecture.md +387 -0
- package/docs/ec6ab3bf-60cf-4629-ad9e-3048e8e3c43a.png +0 -0
- package/docs/logo.png +0 -0
- package/eslint.config.js +16 -0
- package/how-to-run/01-install.md +69 -0
- package/how-to-run/02-wire-up-your-repo.md +80 -0
- package/how-to-run/03-test-it-manually.md +91 -0
- package/how-to-run/04-test-with-claude-code.md +70 -0
- package/how-to-run/CLAUDE.md.template +72 -0
- package/how-to-run/README.md +49 -0
- package/package.json +60 -0
- package/src/cli.ts +142 -0
- package/src/commands/delete.ts +47 -0
- package/src/commands/doctor.ts +128 -0
- package/src/commands/edit.ts +80 -0
- package/src/commands/export.ts +95 -0
- package/src/commands/import.ts +119 -0
- package/src/commands/init.ts +31 -0
- package/src/commands/install-claude.ts +203 -0
- package/src/commands/list.ts +41 -0
- package/src/commands/mcp.ts +12 -0
- package/src/commands/save.ts +85 -0
- package/src/commands/search.ts +56 -0
- package/src/commands/show.ts +37 -0
- package/src/commands/stats.ts +31 -0
- package/src/commands/summarize.ts +183 -0
- package/src/config.ts +26 -0
- package/src/db/connection.ts +8 -0
- package/src/db/migrations.ts +26 -0
- package/src/db/schema.ts +68 -0
- package/src/git/diff.ts +43 -0
- package/src/git/git.ts +25 -0
- package/src/git/repoId.ts +49 -0
- package/src/hooks/post-commit.sample.sh +9 -0
- package/src/mcp/server.ts +326 -0
- package/src/mcp/tools.ts +53 -0
- package/src/memory/parseSummary.ts +72 -0
- package/src/memory/qualityCheck.ts +102 -0
- package/src/memory/redactSecrets.ts +32 -0
- package/src/memory/repoContext.ts +25 -0
- package/src/memory/saveMemory.ts +369 -0
- package/src/memory/searchMemory.ts +153 -0
- package/src/memory/types.ts +57 -0
- package/src/output/format.ts +44 -0
- package/src/skill/SKILL.md +95 -0
- package/tests/cliV02.test.ts +213 -0
- package/tests/doctor.test.ts +253 -0
- package/tests/exportImport.test.ts +248 -0
- package/tests/fileRename.test.ts +156 -0
- package/tests/gitHelpers.test.ts +94 -0
- package/tests/init.test.ts +93 -0
- package/tests/installClaude.test.ts +157 -0
- package/tests/parseSummary.test.ts +111 -0
- package/tests/qualityCheck.test.ts +182 -0
- package/tests/redactSecrets.test.ts +75 -0
- package/tests/saveMemory.test.ts +196 -0
- package/tests/searchFilters.test.ts +139 -0
- package/tests/searchMemory.test.ts +273 -0
- package/tests/stale.test.ts +47 -0
- package/tsconfig.json +18 -0
- package/vitest.config.ts +8 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { getRepoRoot } from "../git/git.js";
|
|
4
|
+
import { getRepoName } from "../git/repoId.js";
|
|
5
|
+
const MCP_TOOL_PERMISSIONS = [
|
|
6
|
+
"mcp__whyline__save_coding_memory",
|
|
7
|
+
"mcp__whyline__search_coding_memory",
|
|
8
|
+
"mcp__whyline__get_recent_memories",
|
|
9
|
+
"mcp__whyline__get_file_memories",
|
|
10
|
+
"mcp__whyline__get_commit_memory",
|
|
11
|
+
];
|
|
12
|
+
function claudeMdSection(repoPath) {
|
|
13
|
+
return `
|
|
14
|
+
## Whyline Memory
|
|
15
|
+
|
|
16
|
+
You have access to a \`whyline\` MCP server. Use it every session.
|
|
17
|
+
|
|
18
|
+
### When you start working on ANY task
|
|
19
|
+
|
|
20
|
+
**Before asking any clarifying question or touching any file**, search for past context:
|
|
21
|
+
|
|
22
|
+
- If the task is clearly described: call \`search_coding_memory\` with:
|
|
23
|
+
- \`repoPath\`: \`${repoPath}\`
|
|
24
|
+
- \`query\`: the task or feature the user just described
|
|
25
|
+
- \`files\`: any files you already know are relevant
|
|
26
|
+
|
|
27
|
+
- If the task is vague or just starting out: call \`get_recent_memories\` with:
|
|
28
|
+
- \`repoPath\`: \`${repoPath}\`
|
|
29
|
+
- \`limit\`: 5
|
|
30
|
+
|
|
31
|
+
**If memories come back**, you MUST:
|
|
32
|
+
1. Show the user what was previously decided and why: _"I found a previous memory about this: [decision + reason]. Before I proceed — what's the reason for changing it now?"_
|
|
33
|
+
2. Wait for the user to give a reason before asking implementation questions
|
|
34
|
+
3. Record the new reason when saving the updated memory
|
|
35
|
+
|
|
36
|
+
Do not skip straight to implementation questions when a past memory exists for the same area. The reason matters — it goes into the next memory.
|
|
37
|
+
|
|
38
|
+
Treat memories as historical context — they explain past decisions, not current truth.
|
|
39
|
+
|
|
40
|
+
### After you commit
|
|
41
|
+
|
|
42
|
+
After \`git commit\` succeeds:
|
|
43
|
+
|
|
44
|
+
1. Synthesize from the conversation:
|
|
45
|
+
- What was the goal? → \`intent\`
|
|
46
|
+
- What was the key decision? → \`decision\`
|
|
47
|
+
- Why that decision (not another)? → \`why\`
|
|
48
|
+
- What alternatives were rejected? → \`alternativesRejected\`
|
|
49
|
+
- What risks exist? → \`risks\`
|
|
50
|
+
- What should be done next? → \`followUps\`
|
|
51
|
+
|
|
52
|
+
2. Show the summary to the user:
|
|
53
|
+
_"Here's what I'm saving as a coding memory — let me know if you want to add or correct anything:"_
|
|
54
|
+
Then display each field clearly.
|
|
55
|
+
|
|
56
|
+
3. Wait a moment for the user to respond. If they add or correct something, apply it.
|
|
57
|
+
|
|
58
|
+
4. Call \`save_coding_memory\` with:
|
|
59
|
+
- \`repoPath\`: \`${repoPath}\`
|
|
60
|
+
- \`commitSha\`: the commit SHA (use HEAD)
|
|
61
|
+
- \`files\`: files changed in this session
|
|
62
|
+
- \`source\`: \`"claude-code"\`
|
|
63
|
+
- all synthesized fields above
|
|
64
|
+
|
|
65
|
+
5. If the response contains a non-empty \`warnings\` array, show each warning to the user and offer to update the memory with richer detail.
|
|
66
|
+
|
|
67
|
+
### Memory quality rules
|
|
68
|
+
|
|
69
|
+
Only save memories that would genuinely help a future session. Good memory:
|
|
70
|
+
- Explains a non-obvious decision
|
|
71
|
+
- Warns about a real risk
|
|
72
|
+
- Records a rejected alternative that someone will try again
|
|
73
|
+
|
|
74
|
+
Do NOT save:
|
|
75
|
+
- Routine refactors with no tradeoffs
|
|
76
|
+
- Things obvious from reading the code
|
|
77
|
+
- Secrets or credentials
|
|
78
|
+
`;
|
|
79
|
+
}
|
|
80
|
+
function writeMcpJson(repoRoot) {
|
|
81
|
+
const mcpPath = path.join(repoRoot, ".mcp.json");
|
|
82
|
+
const whylineEntry = { command: "whyline", args: ["mcp"] };
|
|
83
|
+
let existing = {};
|
|
84
|
+
if (fs.existsSync(mcpPath)) {
|
|
85
|
+
try {
|
|
86
|
+
existing = JSON.parse(fs.readFileSync(mcpPath, "utf-8"));
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// invalid JSON — overwrite
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const servers = (existing.mcpServers ?? {});
|
|
93
|
+
const alreadyThere = JSON.stringify((servers.whyline ?? null)) === JSON.stringify(whylineEntry);
|
|
94
|
+
if (alreadyThere)
|
|
95
|
+
return "unchanged";
|
|
96
|
+
servers.whyline = whylineEntry;
|
|
97
|
+
existing.mcpServers = servers;
|
|
98
|
+
fs.writeFileSync(mcpPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
99
|
+
return fs.existsSync(mcpPath) && Object.keys(servers).length > 1 ? "updated" : "created";
|
|
100
|
+
}
|
|
101
|
+
function writeClaudeMd(repoRoot, repoPath) {
|
|
102
|
+
const claudePath = path.join(repoRoot, "CLAUDE.md");
|
|
103
|
+
const section = claudeMdSection(repoPath);
|
|
104
|
+
if (!fs.existsSync(claudePath)) {
|
|
105
|
+
const repoName = getRepoName(repoRoot);
|
|
106
|
+
const header = `# Claude Instructions for ${repoName}\n`;
|
|
107
|
+
fs.writeFileSync(claudePath, header + section, "utf-8");
|
|
108
|
+
return "created";
|
|
109
|
+
}
|
|
110
|
+
const existing = fs.readFileSync(claudePath, "utf-8");
|
|
111
|
+
// Already has the section — update repoPath lines in place
|
|
112
|
+
if (/whyline/i.test(existing)) {
|
|
113
|
+
const updated = existing.replace(/(`repoPath`:\s*`)([^`]+)(`)/g, `$1${repoPath}$3`);
|
|
114
|
+
if (updated === existing)
|
|
115
|
+
return "unchanged";
|
|
116
|
+
fs.writeFileSync(claudePath, updated, "utf-8");
|
|
117
|
+
return "updated";
|
|
118
|
+
}
|
|
119
|
+
// Exists but no Whyline section — append
|
|
120
|
+
fs.writeFileSync(claudePath, existing.trimEnd() + "\n" + section, "utf-8");
|
|
121
|
+
return "updated";
|
|
122
|
+
}
|
|
123
|
+
function writeSettingsJson(repoRoot) {
|
|
124
|
+
const settingsDir = path.join(repoRoot, ".claude");
|
|
125
|
+
const settingsPath = path.join(settingsDir, "settings.local.json");
|
|
126
|
+
let existing = {};
|
|
127
|
+
if (fs.existsSync(settingsPath)) {
|
|
128
|
+
try {
|
|
129
|
+
existing = JSON.parse(fs.readFileSync(settingsPath, "utf-8"));
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// invalid JSON — overwrite
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
const perms = (existing.permissions ?? {});
|
|
136
|
+
const allowed = Array.isArray(perms.allow) ? perms.allow : [];
|
|
137
|
+
const enabledServers = Array.isArray(existing.enabledMcpjsonServers)
|
|
138
|
+
? existing.enabledMcpjsonServers
|
|
139
|
+
: [];
|
|
140
|
+
const newAllowed = [...new Set([...allowed, ...MCP_TOOL_PERMISSIONS])];
|
|
141
|
+
const newEnabled = [...new Set([...enabledServers, "whyline"])];
|
|
142
|
+
const unchanged = newAllowed.length === allowed.length && newEnabled.length === enabledServers.length;
|
|
143
|
+
if (unchanged)
|
|
144
|
+
return "unchanged";
|
|
145
|
+
perms.allow = newAllowed;
|
|
146
|
+
existing.permissions = perms;
|
|
147
|
+
existing.enabledMcpjsonServers = newEnabled;
|
|
148
|
+
if (!fs.existsSync(settingsDir))
|
|
149
|
+
fs.mkdirSync(settingsDir, { recursive: true });
|
|
150
|
+
const wasNew = !fs.existsSync(settingsPath);
|
|
151
|
+
fs.writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
152
|
+
return wasNew ? "created" : "updated";
|
|
153
|
+
}
|
|
154
|
+
export async function runInstallClaude(options) {
|
|
155
|
+
const cwd = options.repoPath ?? process.cwd();
|
|
156
|
+
const repoRoot = getRepoRoot(cwd);
|
|
157
|
+
if (!repoRoot) {
|
|
158
|
+
console.error("Not inside a git repository. Run this command from your project root.");
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
const repoPath = repoRoot;
|
|
162
|
+
const mcpStatus = writeMcpJson(repoRoot);
|
|
163
|
+
const claudeStatus = writeClaudeMd(repoRoot, repoPath);
|
|
164
|
+
const settingsStatus = writeSettingsJson(repoRoot);
|
|
165
|
+
const label = (status, file) => {
|
|
166
|
+
const icon = status === "unchanged" ? "·" : "✓";
|
|
167
|
+
return ` ${icon} ${file} (${status})`;
|
|
168
|
+
};
|
|
169
|
+
console.log(label(mcpStatus, ".mcp.json"));
|
|
170
|
+
console.log(label(claudeStatus, "CLAUDE.md"));
|
|
171
|
+
console.log(label(settingsStatus, ".claude/settings.local.json"));
|
|
172
|
+
console.log("");
|
|
173
|
+
if (mcpStatus === "unchanged" && claudeStatus === "unchanged" && settingsStatus === "unchanged") {
|
|
174
|
+
console.log("Whyline is already configured in this repo.");
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
console.log("Done. Open this repo in Claude Code and run `whyline doctor` to verify.");
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=install-claude.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-claude.js","sourceRoot":"","sources":["../../src/commands/install-claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,oBAAoB,GAAG;IAC3B,kCAAkC;IAClC,oCAAoC;IACpC,mCAAmC;IACnC,iCAAiC;IACjC,iCAAiC;CAClC,CAAC;AAEF,SAAS,eAAe,CAAC,QAAgB;IACvC,OAAO;;;;;;;;;;sBAUa,QAAQ;;;;;sBAKR,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA+BP,QAAQ;;;;;;;;;;;;;;;;;;;CAmB9B,CAAC;AACF,CAAC;AAED,SAAS,YAAY,CAAC,QAAgB;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACjD,MAAM,YAAY,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;IAE3D,IAAI,QAAQ,GAA4B,EAAE,CAAC;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAA4B,CAAC;QACtF,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,CAAC,QAAQ,CAAC,UAAU,IAAI,EAAE,CAA4B,CAAC;IACvE,MAAM,YAAY,GAChB,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;IAE7E,IAAI,YAAY;QAAE,OAAO,WAAW,CAAC;IAErC,OAAO,CAAC,OAAO,GAAG,YAAY,CAAC;IAC/B,QAAQ,CAAC,UAAU,GAAG,OAAO,CAAC;IAC9B,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7E,OAAO,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3F,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB,EAAE,QAAgB;IACvD,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IACpD,MAAM,OAAO,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IAE1C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,6BAA6B,QAAQ,IAAI,CAAC;QACzD,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC;QACxD,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAEtD,2DAA2D;IAC3D,IAAI,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAC9B,8BAA8B,EAC9B,KAAK,QAAQ,IAAI,CAClB,CAAC;QACF,IAAI,OAAO,KAAK,QAAQ;YAAE,OAAO,WAAW,CAAC;QAC7C,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/C,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,yCAAyC;IACzC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,EAAE,GAAG,IAAI,GAAG,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3E,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IACnD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAEnE,IAAI,QAAQ,GAA4B,EAAE,CAAC;IAC3C,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAA4B,CAAC;QAC3F,CAAC;QAAC,MAAM,CAAC;YACP,2BAA2B;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,CAAC,QAAQ,CAAC,WAAW,IAAI,EAAE,CAA4B,CAAC;IACtE,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAE,KAAK,CAAC,KAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;QAClE,CAAC,CAAE,QAAQ,CAAC,qBAAkC;QAC9C,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,oBAAoB,CAAC,CAAC,CAAC,CAAC;IACvE,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,cAAc,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAEhE,MAAM,SAAS,GACb,UAAU,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC,MAAM,KAAK,cAAc,CAAC,MAAM,CAAC;IACtF,IAAI,SAAS;QAAE,OAAO,WAAW,CAAC;IAElC,KAAK,CAAC,KAAK,GAAG,UAAU,CAAC;IACzB,QAAQ,CAAC,WAAW,GAAG,KAAK,CAAC;IAC7B,QAAQ,CAAC,qBAAqB,GAAG,UAAU,CAAC;IAE5C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAChF,MAAM,MAAM,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAC5C,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;IAClF,OAAO,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AACxC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAA8B;IACnE,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAElC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,KAAK,CAAC,uEAAuE,CAAC,CAAC;QACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,QAAQ,GAAG,QAAQ,CAAC;IAE1B,MAAM,SAAS,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,YAAY,GAAG,aAAa,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAEnD,MAAM,KAAK,GAAG,CAAC,MAAc,EAAE,IAAY,EAAE,EAAE;QAC7C,MAAM,IAAI,GAAG,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QAChD,OAAO,KAAK,IAAI,KAAK,IAAI,MAAM,MAAM,GAAG,CAAC;IAC3C,CAAC,CAAC;IAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE,6BAA6B,CAAC,CAAC,CAAC;IAClE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAEhB,IAAI,SAAS,KAAK,WAAW,IAAI,YAAY,KAAK,WAAW,IAAI,cAAc,KAAK,WAAW,EAAE,CAAC;QAChG,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC7D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAC;IACzF,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { isInitialized, resolveConfig } from "../config.js";
|
|
2
|
+
import { openDb } from "../db/connection.js";
|
|
3
|
+
import { getRepoRoot } from "../git/git.js";
|
|
4
|
+
import { getRepoId } from "../git/repoId.js";
|
|
5
|
+
import { listMemories } from "../memory/saveMemory.js";
|
|
6
|
+
import { formatMemory } from "../output/format.js";
|
|
7
|
+
export async function runList(options) {
|
|
8
|
+
if (!isInitialized()) {
|
|
9
|
+
console.error("whyline is not initialized. Run `whyline init` first.");
|
|
10
|
+
process.exit(1);
|
|
11
|
+
}
|
|
12
|
+
const limit = parseInt(options.limit, 10) || 20;
|
|
13
|
+
let repoId;
|
|
14
|
+
if (options.repo) {
|
|
15
|
+
const repoRoot = getRepoRoot(process.cwd());
|
|
16
|
+
if (!repoRoot) {
|
|
17
|
+
console.error("Not inside a git repository.");
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
repoId = getRepoId(repoRoot);
|
|
21
|
+
}
|
|
22
|
+
const db = openDb(resolveConfig().storage.dbPath);
|
|
23
|
+
const memories = listMemories(db, { repoId, limit });
|
|
24
|
+
db.close();
|
|
25
|
+
if (memories.length === 0) {
|
|
26
|
+
console.log("No memories found.");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
for (const memory of memories) {
|
|
30
|
+
console.log(formatMemory(memory));
|
|
31
|
+
console.log("\n---");
|
|
32
|
+
}
|
|
33
|
+
console.log(`\n${memories.length} memory(s) shown.`);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=list.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAyC;IACrE,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAChD,IAAI,MAA0B,CAAC;IAE/B,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;IACrD,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,CAAC,MAAM,mBAAmB,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runMcp(): Promise<void>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { isInitialized } from "../config.js";
|
|
2
|
+
import { createMcpServer } from "../mcp/server.js";
|
|
3
|
+
export async function runMcp() {
|
|
4
|
+
if (!isInitialized()) {
|
|
5
|
+
process.stderr.write("coding-memory is not initialized. Run `coding-memory init` first.\n");
|
|
6
|
+
process.exit(1);
|
|
7
|
+
}
|
|
8
|
+
await createMcpServer();
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,MAAM;IAC1B,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,qEAAqE,CACtE,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,MAAM,eAAe,EAAE,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import { isInitialized, resolveConfig } from "../config.js";
|
|
3
|
+
import { openDb } from "../db/connection.js";
|
|
4
|
+
import { getRepoContext } from "../memory/repoContext.js";
|
|
5
|
+
import { parseSummary } from "../memory/parseSummary.js";
|
|
6
|
+
import { redactSecrets } from "../memory/redactSecrets.js";
|
|
7
|
+
import { saveMemory, generateMemoryId, buildEmbeddingText } from "../memory/saveMemory.js";
|
|
8
|
+
import { checkQuality, checkDuplicates } from "../memory/qualityCheck.js";
|
|
9
|
+
export async function runSave(options) {
|
|
10
|
+
if (!isInitialized()) {
|
|
11
|
+
console.error("whyline is not initialized. Run `whyline init` first.");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
let ctx;
|
|
16
|
+
try {
|
|
17
|
+
ctx = getRepoContext(cwd, options.commit);
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
if (!fs.existsSync(options.summaryFile)) {
|
|
24
|
+
console.error(`Error: summary file not found: ${options.summaryFile}`);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
}
|
|
27
|
+
const rawMarkdown = fs.readFileSync(options.summaryFile, "utf-8");
|
|
28
|
+
const parsed = parseSummary(rawMarkdown);
|
|
29
|
+
const now = new Date().toISOString();
|
|
30
|
+
const id = generateMemoryId();
|
|
31
|
+
const memory = {
|
|
32
|
+
id,
|
|
33
|
+
createdAt: now,
|
|
34
|
+
updatedAt: now,
|
|
35
|
+
repoId: ctx.repoId,
|
|
36
|
+
repoPath: ctx.repoPath,
|
|
37
|
+
repoName: ctx.repoName,
|
|
38
|
+
branch: ctx.branch ?? undefined,
|
|
39
|
+
commitSha: ctx.commitSha,
|
|
40
|
+
files: ctx.changedFiles,
|
|
41
|
+
tags: parsed.tags.map(redactSecrets),
|
|
42
|
+
task: parsed.task ? redactSecrets(parsed.task) : undefined,
|
|
43
|
+
intent: redactSecrets(parsed.intent),
|
|
44
|
+
summary: redactSecrets(parsed.summary),
|
|
45
|
+
decision: redactSecrets(parsed.decision),
|
|
46
|
+
why: redactSecrets(parsed.why),
|
|
47
|
+
alternativesRejected: parsed.alternativesRejected.map(redactSecrets),
|
|
48
|
+
risks: parsed.risks.map(redactSecrets),
|
|
49
|
+
followUps: parsed.followUps.map(redactSecrets),
|
|
50
|
+
source: "cli",
|
|
51
|
+
embeddingText: "",
|
|
52
|
+
};
|
|
53
|
+
memory.embeddingText = buildEmbeddingText(memory);
|
|
54
|
+
const db = openDb(resolveConfig().storage.dbPath);
|
|
55
|
+
const qualityWarnings = checkQuality(memory);
|
|
56
|
+
const duplicateWarnings = checkDuplicates(db, memory);
|
|
57
|
+
saveMemory(db, memory);
|
|
58
|
+
db.close();
|
|
59
|
+
console.log(`Saved memory ${memory.id}`);
|
|
60
|
+
console.log(`Repo: ${ctx.repoName}`);
|
|
61
|
+
console.log(`Commit: ${ctx.commitSha.slice(0, 8)}`);
|
|
62
|
+
console.log(`Files: ${ctx.changedFiles.length}`);
|
|
63
|
+
if (qualityWarnings.length > 0) {
|
|
64
|
+
console.log("\nQuality warnings:");
|
|
65
|
+
for (const w of qualityWarnings)
|
|
66
|
+
console.warn(` ⚠ ${w.message}`);
|
|
67
|
+
}
|
|
68
|
+
if (duplicateWarnings.length > 0) {
|
|
69
|
+
console.log("\nDuplicate warnings:");
|
|
70
|
+
for (const w of duplicateWarnings)
|
|
71
|
+
console.warn(` ⚠ ${w.message}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=save.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"save.js","sourceRoot":"","sources":["../../src/commands/save.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { isInitialized, resolveConfig } from "../config.js";
|
|
2
|
+
import { openDb } from "../db/connection.js";
|
|
3
|
+
import { getRepoRoot } from "../git/git.js";
|
|
4
|
+
import { getRepoId } from "../git/repoId.js";
|
|
5
|
+
import { getFileRenameHistory } from "../git/diff.js";
|
|
6
|
+
import { searchMemory } from "../memory/searchMemory.js";
|
|
7
|
+
import { formatSearchResult } from "../output/format.js";
|
|
8
|
+
export async function runSearch(query, options) {
|
|
9
|
+
if (!isInitialized()) {
|
|
10
|
+
console.error("whyline is not initialized. Run `whyline init` first.");
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
const limit = parseInt(options.limit, 10) || 10;
|
|
14
|
+
const cwd = process.cwd();
|
|
15
|
+
let repoId;
|
|
16
|
+
let repoPath;
|
|
17
|
+
const repoRoot = getRepoRoot(cwd);
|
|
18
|
+
if (repoRoot) {
|
|
19
|
+
repoId = getRepoId(repoRoot);
|
|
20
|
+
repoPath = repoRoot;
|
|
21
|
+
}
|
|
22
|
+
const files = options.file
|
|
23
|
+
? (repoPath ? getFileRenameHistory(repoPath, options.file) : [options.file])
|
|
24
|
+
: [];
|
|
25
|
+
const db = openDb(resolveConfig().storage.dbPath);
|
|
26
|
+
const results = searchMemory(db, {
|
|
27
|
+
query,
|
|
28
|
+
repoId,
|
|
29
|
+
repoPath,
|
|
30
|
+
files,
|
|
31
|
+
tags: options.tag ?? [],
|
|
32
|
+
since: options.since,
|
|
33
|
+
before: options.before,
|
|
34
|
+
limit,
|
|
35
|
+
});
|
|
36
|
+
db.close();
|
|
37
|
+
if (results.length === 0) {
|
|
38
|
+
console.log("No memories found.");
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
for (const result of results) {
|
|
42
|
+
console.log(formatSearchResult(result));
|
|
43
|
+
console.log("\n---");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,KAAa,EACb,OAA0F;IAE1F,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC;IAChD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAE1B,IAAI,MAA0B,CAAC;IAC/B,IAAI,QAA4B,CAAC;IAEjC,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC7B,QAAQ,GAAG,QAAQ,CAAC;IACtB,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI;QACxB,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC5E,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,OAAO,GAAG,YAAY,CAAC,EAAE,EAAE;QAC/B,KAAK;QACL,MAAM;QACN,QAAQ;QACR,KAAK;QACL,IAAI,EAAE,OAAO,CAAC,GAAG,IAAI,EAAE;QACvB,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,KAAK;KACN,CAAC,CAAC;IACH,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;QAClC,OAAO;IACT,CAAC;IAED,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { isInitialized, resolveConfig } from "../config.js";
|
|
2
|
+
import { openDb } from "../db/connection.js";
|
|
3
|
+
import { getMemoryById, getMemoryByCommit } from "../memory/saveMemory.js";
|
|
4
|
+
import { formatMemory } from "../output/format.js";
|
|
5
|
+
export async function runShow(id, options) {
|
|
6
|
+
if (!isInitialized()) {
|
|
7
|
+
console.error("whyline is not initialized. Run `whyline init` first.");
|
|
8
|
+
process.exit(1);
|
|
9
|
+
}
|
|
10
|
+
const db = openDb(resolveConfig().storage.dbPath);
|
|
11
|
+
let memory = null;
|
|
12
|
+
if (options.commit) {
|
|
13
|
+
memory = getMemoryByCommit(db, options.commit);
|
|
14
|
+
}
|
|
15
|
+
else if (id) {
|
|
16
|
+
memory = getMemoryById(db, id);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
db.close();
|
|
20
|
+
console.error("Error: provide a memory ID or use --commit <sha>");
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
db.close();
|
|
24
|
+
if (!memory) {
|
|
25
|
+
console.error(`Memory not found: ${options.commit ?? id}`);
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
console.log(formatMemory(memory, true));
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=show.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"show.js","sourceRoot":"","sources":["../../src/commands/show.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,EAAsB,EACtB,OAA4B;IAE5B,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAElD,IAAI,MAAM,GAAG,IAAI,CAAC;IAElB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,GAAG,iBAAiB,CAAC,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;IACjD,CAAC;SAAM,IAAI,EAAE,EAAE,CAAC;QACd,MAAM,GAAG,aAAa,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,kDAAkD,CAAC,CAAC;QAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,qBAAqB,OAAO,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function runStats(): Promise<void>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { isInitialized, resolveConfig } from "../config.js";
|
|
2
|
+
import { openDb } from "../db/connection.js";
|
|
3
|
+
import { getStats } from "../memory/saveMemory.js";
|
|
4
|
+
export async function runStats() {
|
|
5
|
+
if (!isInitialized()) {
|
|
6
|
+
console.error("whyline is not initialized. Run `whyline init` first.");
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
const db = openDb(resolveConfig().storage.dbPath);
|
|
10
|
+
const stats = getStats(db);
|
|
11
|
+
db.close();
|
|
12
|
+
if (stats.total === 0) {
|
|
13
|
+
console.log("No memories stored yet.");
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
console.log(`Total memories: ${stats.total}`);
|
|
17
|
+
console.log(`Repos tracked: ${stats.repos}`);
|
|
18
|
+
console.log(`Oldest memory: ${stats.oldest}`);
|
|
19
|
+
console.log(`Newest memory: ${stats.newest}`);
|
|
20
|
+
if (stats.topFiles.length > 0) {
|
|
21
|
+
console.log("\nMost referenced files:");
|
|
22
|
+
for (const { filePath, count } of stats.topFiles) {
|
|
23
|
+
console.log(` ${count}x ${filePath}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=stats.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stats.js","sourceRoot":"","sources":["../../src/commands/stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC5D,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,QAAQ;IAC5B,IAAI,CAAC,aAAa,EAAE,EAAE,CAAC;QACrB,OAAO,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,EAAE,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3B,EAAE,CAAC,KAAK,EAAE,CAAC;IAEX,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;IAEhD,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;QACxC,KAAK,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACjD,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,QAAQ,EAAE,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import https from "https";
|
|
2
|
+
import readline from "readline";
|
|
3
|
+
import { isInitialized, resolveConfig } from "../config.js";
|
|
4
|
+
import { openDb } from "../db/connection.js";
|
|
5
|
+
import { getMemoryById, updateMemory, buildEmbeddingText } from "../memory/saveMemory.js";
|
|
6
|
+
function buildPrompt(memory) {
|
|
7
|
+
return `You are improving a coding memory record. Rewrite each field to be clearer, more specific, and more useful for a future developer session. Do not invent details that aren't implied by the original. Keep each field concise. Return ONLY valid JSON with these exact keys: intent, summary, decision, why, alternativesRejected (array), risks (array), followUps (array), tags (array).
|
|
8
|
+
|
|
9
|
+
Original memory:
|
|
10
|
+
${JSON.stringify(memory, null, 2)}`;
|
|
11
|
+
}
|
|
12
|
+
async function callClaudeApi(prompt, apiKey) {
|
|
13
|
+
const body = JSON.stringify({
|
|
14
|
+
model: "claude-haiku-4-5-20251001",
|
|
15
|
+
max_tokens: 1024,
|
|
16
|
+
messages: [{ role: "user", content: prompt }],
|
|
17
|
+
});
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
const req = https.request({
|
|
20
|
+
hostname: "api.anthropic.com",
|
|
21
|
+
path: "/v1/messages",
|
|
22
|
+
method: "POST",
|
|
23
|
+
headers: {
|
|
24
|
+
"Content-Type": "application/json",
|
|
25
|
+
"x-api-key": apiKey,
|
|
26
|
+
"anthropic-version": "2023-06-01",
|
|
27
|
+
},
|
|
28
|
+
}, (res) => {
|
|
29
|
+
let data = "";
|
|
30
|
+
res.on("data", (chunk) => { data += chunk.toString(); });
|
|
31
|
+
res.on("end", () => {
|
|
32
|
+
try {
|
|
33
|
+
const parsed = JSON.parse(data);
|
|
34
|
+
if (parsed.error) {
|
|
35
|
+
reject(new Error(`Claude API error: ${parsed.error.message}`));
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const text = parsed.content?.find((c) => c.type === "text")?.text ?? "";
|
|
39
|
+
// Extract JSON from the response (may be wrapped in markdown code block)
|
|
40
|
+
const jsonMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/) ?? [null, text];
|
|
41
|
+
const improved = JSON.parse(jsonMatch[1].trim());
|
|
42
|
+
resolve(improved);
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
reject(new Error(`Failed to parse Claude response: ${String(e)}\nRaw: ${data}`));
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
req.on("error", reject);
|
|
50
|
+
req.write(body);
|
|
51
|
+
req.end();
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
function diffField(label, before, after) {
|
|
55
|
+
const b = Array.isArray(before) ? before.join(", ") : before;
|
|
56
|
+
const a = Array.isArray(after) ? after.join(", ") : after;
|
|
57
|
+
if (b === a)
|
|
58
|
+
return "";
|
|
59
|
+
return ` ${label}:\n before: ${b}\n after: ${a}`;
|
|
60
|
+
}
|
|
61
|
+
function showDiff(original, improved) {
|
|
62
|
+
const diffs = [
|
|
63
|
+
diffField("intent", original.intent, improved.intent),
|
|
64
|
+
diffField("summary", original.summary, improved.summary),
|
|
65
|
+
diffField("decision", original.decision, improved.decision),
|
|
66
|
+
diffField("why", original.why, improved.why),
|
|
67
|
+
diffField("alternativesRejected", original.alternativesRejected, improved.alternativesRejected),
|
|
68
|
+
diffField("risks", original.risks, improved.risks),
|
|
69
|
+
diffField("followUps", original.followUps, improved.followUps),
|
|
70
|
+
diffField("tags", original.tags, improved.tags),
|
|
71
|
+
].filter(Boolean);
|
|
72
|
+
if (diffs.length === 0) {
|
|
73
|
+
console.log("No changes suggested — memory is already well-written.");
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
console.log("\nProposed improvements:\n");
|
|
77
|
+
console.log(diffs.join("\n\n"));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function confirm(question) {
|
|
81
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
82
|
+
return new Promise((resolve) => {
|
|
83
|
+
rl.question(question, (answer) => {
|
|
84
|
+
rl.close();
|
|
85
|
+
resolve(answer.trim().toLowerCase() === "y");
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
export async function runSummarize(id, options) {
|
|
90
|
+
if (!isInitialized()) {
|
|
91
|
+
console.error("whyline is not initialized. Run `whyline init` first.");
|
|
92
|
+
process.exit(1);
|
|
93
|
+
}
|
|
94
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
95
|
+
if (!apiKey) {
|
|
96
|
+
console.error("ANTHROPIC_API_KEY environment variable is not set.");
|
|
97
|
+
console.error("Export it before running: export ANTHROPIC_API_KEY=your_key");
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
const db = openDb(resolveConfig().storage.dbPath);
|
|
101
|
+
const memory = getMemoryById(db, id);
|
|
102
|
+
db.close();
|
|
103
|
+
if (!memory) {
|
|
104
|
+
console.error(`Memory not found: ${id}`);
|
|
105
|
+
process.exit(1);
|
|
106
|
+
}
|
|
107
|
+
const original = {
|
|
108
|
+
intent: memory.intent,
|
|
109
|
+
summary: memory.summary,
|
|
110
|
+
decision: memory.decision,
|
|
111
|
+
why: memory.why,
|
|
112
|
+
alternativesRejected: memory.alternativesRejected,
|
|
113
|
+
risks: memory.risks,
|
|
114
|
+
followUps: memory.followUps,
|
|
115
|
+
tags: memory.tags,
|
|
116
|
+
};
|
|
117
|
+
console.log(`Summarizing memory ${id}...`);
|
|
118
|
+
const improved = await callClaudeApi(buildPrompt(original), apiKey);
|
|
119
|
+
showDiff(original, improved);
|
|
120
|
+
const hasChanges = JSON.stringify(original) !== JSON.stringify(improved);
|
|
121
|
+
if (!hasChanges) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const shouldSave = options.force || (await confirm("\nApply improvements? [y/N] "));
|
|
125
|
+
if (!shouldSave) {
|
|
126
|
+
console.log("Cancelled.");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const db2 = openDb(resolveConfig().storage.dbPath);
|
|
130
|
+
const embeddingText = buildEmbeddingText({
|
|
131
|
+
...memory,
|
|
132
|
+
...improved,
|
|
133
|
+
commitSha: memory.commitSha,
|
|
134
|
+
files: memory.files,
|
|
135
|
+
});
|
|
136
|
+
updateMemory(db2, id, { ...improved, embeddingText });
|
|
137
|
+
db2.close();
|
|
138
|
+
console.log(`Updated memory ${id}.`);
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=summarize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summarize.js","sourceRoot":"","sources":["../../src/commands/summarize.ts"],"names":[],"mappings":"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"}
|