git-impact 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/LICENSE +21 -0
- package/README.md +305 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +267 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/init/installer.d.ts +31 -0
- package/dist/init/installer.d.ts.map +1 -0
- package/dist/init/installer.js +225 -0
- package/dist/init/installer.js.map +1 -0
- package/dist/init/templates.d.ts +12 -0
- package/dist/init/templates.d.ts.map +1 -0
- package/dist/init/templates.js +258 -0
- package/dist/init/templates.js.map +1 -0
- package/dist/mcp/prompts.d.ts +4 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +242 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/repo.d.ts +14 -0
- package/dist/mcp/repo.d.ts.map +1 -0
- package/dist/mcp/repo.js +106 -0
- package/dist/mcp/repo.js.map +1 -0
- package/dist/mcp/resources.d.ts +4 -0
- package/dist/mcp/resources.d.ts.map +1 -0
- package/dist/mcp/resources.js +98 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/server.d.ts +14 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +61 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +12 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +285 -0
- package/dist/mcp/tools.js.map +1 -0
- package/dist/readers/git.d.ts +23 -0
- package/dist/readers/git.d.ts.map +1 -0
- package/dist/readers/git.js +120 -0
- package/dist/readers/git.js.map +1 -0
- package/dist/readers/github.d.ts +22 -0
- package/dist/readers/github.d.ts.map +1 -0
- package/dist/readers/github.js +94 -0
- package/dist/readers/github.js.map +1 -0
- package/dist/storage/db.d.ts +31 -0
- package/dist/storage/db.d.ts.map +1 -0
- package/dist/storage/db.js +170 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/translator/prompt.d.ts +21 -0
- package/dist/translator/prompt.d.ts.map +1 -0
- package/dist/translator/prompt.js +117 -0
- package/dist/translator/prompt.js.map +1 -0
- package/dist/translator/translate.d.ts +36 -0
- package/dist/translator/translate.d.ts.map +1 -0
- package/dist/translator/translate.js +73 -0
- package/dist/translator/translate.js.map +1 -0
- package/package.json +55 -0
- package/skill/SKILL.md +238 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PROMPT_DEFINITIONS = void 0;
|
|
4
|
+
exports.handleGetPrompt = handleGetPrompt;
|
|
5
|
+
const git_1 = require("../readers/git");
|
|
6
|
+
const db_1 = require("../storage/db");
|
|
7
|
+
const repo_1 = require("./repo");
|
|
8
|
+
// ─── Prompt definitions ───────────────────────────────────────────────────────
|
|
9
|
+
// Computed slash commands: fetch live data, embed it + translation instructions,
|
|
10
|
+
// return as a pre-filled message so Claude Code does the AI work in its own
|
|
11
|
+
// session — no separate API key needed.
|
|
12
|
+
exports.PROMPT_DEFINITIONS = [
|
|
13
|
+
{
|
|
14
|
+
name: "standup",
|
|
15
|
+
description: "Translate today's commits into a plain-English standup. " +
|
|
16
|
+
"Auto-detects the open project — no path needed. " +
|
|
17
|
+
"Reads .git-impact/context.json for your glossary and company context.",
|
|
18
|
+
arguments: [
|
|
19
|
+
{
|
|
20
|
+
name: "since",
|
|
21
|
+
description: '"today" (default), "yesterday", "3d", or ISO date "2026-05-01"',
|
|
22
|
+
required: false,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
name: "review",
|
|
28
|
+
description: "Synthesize saved standup history into a performance review. " +
|
|
29
|
+
"Auto-detects the open project. Reads from .git-impact/history.db.",
|
|
30
|
+
arguments: [
|
|
31
|
+
{
|
|
32
|
+
name: "period",
|
|
33
|
+
description: '"30d" (default), "90d", "Q1-2026", etc.',
|
|
34
|
+
required: false,
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
];
|
|
39
|
+
// ─── Handlers ─────────────────────────────────────────────────────────────────
|
|
40
|
+
async function handleGetPrompt(name, args) {
|
|
41
|
+
switch (name) {
|
|
42
|
+
case "standup": return buildStandupPrompt(args ?? {});
|
|
43
|
+
case "review": return buildReviewPrompt(args ?? {});
|
|
44
|
+
default: throw new Error(`Unknown prompt: ${name}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
// ─── standup ──────────────────────────────────────────────────────────────────
|
|
48
|
+
async function buildStandupPrompt(args) {
|
|
49
|
+
// Resolve repo — auto-detects open project via cwd
|
|
50
|
+
let repoRoot;
|
|
51
|
+
try {
|
|
52
|
+
repoRoot = (0, repo_1.resolveRepoPath)().path;
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
return promptError(err.message);
|
|
56
|
+
}
|
|
57
|
+
const since = parseSince(args.since || "today");
|
|
58
|
+
const until = new Date();
|
|
59
|
+
const context = (0, db_1.loadContext)(repoRoot);
|
|
60
|
+
let git;
|
|
61
|
+
try {
|
|
62
|
+
git = await (0, git_1.readGitActivity)(repoRoot, since, until);
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return promptError(`Could not read git history at ${repoRoot}.`);
|
|
66
|
+
}
|
|
67
|
+
if (git.commits.length === 0) {
|
|
68
|
+
return singleMessage("No commits found", `No commits found since ${since.toDateString()} in ${git.repoName}. Nothing to translate.`);
|
|
69
|
+
}
|
|
70
|
+
const dateLabel = since.toDateString() === (0, git_1.startOfDay)().toDateString()
|
|
71
|
+
? `Today, ${until.toLocaleDateString("en-US", { weekday: "long", month: "long", day: "numeric", year: "numeric" })}`
|
|
72
|
+
: `${since.toDateString()} → ${until.toDateString()}`;
|
|
73
|
+
const contextSection = context
|
|
74
|
+
? [
|
|
75
|
+
"## Personalization Context",
|
|
76
|
+
`Company: ${context.companyDescription || "(not set)"}`,
|
|
77
|
+
`Manager priorities: ${context.managerPriorities || "(not set)"}`,
|
|
78
|
+
Object.keys(context.glossary ?? {}).length > 0
|
|
79
|
+
? `Glossary:\n${Object.entries(context.glossary).map(([k, v]) => ` ${k} → ${v}`).join("\n")}`
|
|
80
|
+
: "",
|
|
81
|
+
]
|
|
82
|
+
.filter(Boolean)
|
|
83
|
+
.join("\n")
|
|
84
|
+
: "No .git-impact/context.json found. Use general technical language.\n" +
|
|
85
|
+
'Tip: say "set up context for this repo" to configure your glossary.';
|
|
86
|
+
const commitsSection = git.commits
|
|
87
|
+
.map((c) => `- [${c.hash}] ${c.message}` +
|
|
88
|
+
(c.body ? `\n ${c.body.split("\n")[0]}` : "") +
|
|
89
|
+
(c.filesChanged.length
|
|
90
|
+
? `\n Files: ${c.filesChanged.slice(0, 6).join(", ")}${c.filesChanged.length > 6 ? ` (+${c.filesChanged.length - 6} more)` : ""}`
|
|
91
|
+
: ""))
|
|
92
|
+
.join("\n");
|
|
93
|
+
const userMessage = `
|
|
94
|
+
# Standup Translation — ${dateLabel}
|
|
95
|
+
|
|
96
|
+
## Git Activity
|
|
97
|
+
Repo: ${git.repoName} (branch: ${git.branch})
|
|
98
|
+
Files changed: ${git.totalFilesChanged} | Commits: ${git.commits.length}
|
|
99
|
+
|
|
100
|
+
### Commits
|
|
101
|
+
${commitsSection}
|
|
102
|
+
|
|
103
|
+
${contextSection}
|
|
104
|
+
|
|
105
|
+
## Your Task
|
|
106
|
+
|
|
107
|
+
Translate the commits above into 2–5 plain-English bullets for a standup or manager update.
|
|
108
|
+
|
|
109
|
+
**Rules:**
|
|
110
|
+
1. Each bullet = what was done + why it matters to the business. Never restate the commit message verbatim.
|
|
111
|
+
2. Apply the glossary — replace every technical term listed above with its plain-English equivalent.
|
|
112
|
+
3. If you can't infer business impact confidently, say what was done and call it "technical foundation work for X".
|
|
113
|
+
4. WIP / draft work → prefix "⏳ In progress:" and state the expected outcome.
|
|
114
|
+
5. Group related commits into one bullet if they tell the same story.
|
|
115
|
+
6. Be specific — "improved performance" is too vague without a number or context.
|
|
116
|
+
7. End with: "📁 N files changed across [brief area]"
|
|
117
|
+
|
|
118
|
+
**Format:**
|
|
119
|
+
✅ [Plain English summary]
|
|
120
|
+
→ [Business impact / who it unblocks / risk reduced]
|
|
121
|
+
|
|
122
|
+
⏳ [In-progress work]
|
|
123
|
+
→ [Expected outcome]
|
|
124
|
+
`.trim();
|
|
125
|
+
return {
|
|
126
|
+
description: `Standup for ${dateLabel} — ${git.repoName}`,
|
|
127
|
+
messages: [{ role: "user", content: { type: "text", text: userMessage } }],
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// ─── review ───────────────────────────────────────────────────────────────────
|
|
131
|
+
async function buildReviewPrompt(args) {
|
|
132
|
+
let repoRoot;
|
|
133
|
+
try {
|
|
134
|
+
repoRoot = (0, repo_1.resolveRepoPath)().path;
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
return promptError(err.message);
|
|
138
|
+
}
|
|
139
|
+
const period = args.period || "30d";
|
|
140
|
+
const context = (0, db_1.loadContext)(repoRoot);
|
|
141
|
+
let entries;
|
|
142
|
+
let periodLabel;
|
|
143
|
+
if (/^Q[1-4]-\d{4}$/i.test(period)) {
|
|
144
|
+
const { from, to } = parseQuarter(period);
|
|
145
|
+
entries = (0, db_1.getEntriesForRange)(from, to, repoRoot);
|
|
146
|
+
periodLabel = period.toUpperCase();
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
const days = parseDays(period);
|
|
150
|
+
entries = (0, db_1.getEntriesForDaysAgo)(days, repoRoot);
|
|
151
|
+
periodLabel = `Last ${days} days`;
|
|
152
|
+
}
|
|
153
|
+
if (entries.length === 0) {
|
|
154
|
+
return singleMessage("No history found", `No saved history for "${period}" in ${repoRoot}.\n\n` +
|
|
155
|
+
"Use the standup prompt daily to build history, then come back for a review.");
|
|
156
|
+
}
|
|
157
|
+
const historySection = entries
|
|
158
|
+
.map((e) => `### ${e.date} — ${e.repoName} (${e.totalCommits} commits)\n` +
|
|
159
|
+
e.items.map((i) => `- [${i.status}] ${i.summary}. ${i.impact}`).join("\n"))
|
|
160
|
+
.join("\n\n");
|
|
161
|
+
const contextSection = context?.companyDescription
|
|
162
|
+
? `Company: ${context.companyDescription}\nManager priorities: ${context.managerPriorities || "(not set)"}`
|
|
163
|
+
: "";
|
|
164
|
+
const totalCommits = entries.reduce((s, e) => s + e.totalCommits, 0);
|
|
165
|
+
const userMessage = `
|
|
166
|
+
# Performance Review — ${periodLabel}
|
|
167
|
+
|
|
168
|
+
${contextSection}
|
|
169
|
+
|
|
170
|
+
## Work Log (${entries.length} days | ${totalCommits} total commits)
|
|
171
|
+
|
|
172
|
+
${historySection}
|
|
173
|
+
|
|
174
|
+
## Your Task
|
|
175
|
+
|
|
176
|
+
Synthesize the work log into a structured performance review summary.
|
|
177
|
+
|
|
178
|
+
**Instructions:**
|
|
179
|
+
1. Group by theme: "Features shipped", "Reliability & bugs", "Security", "Code review", "Infrastructure", "Developer experience" — use only themes that apply.
|
|
180
|
+
2. Within each theme: specific bullets with numbers when available. No generic summaries.
|
|
181
|
+
3. Assign each theme: high / medium / low impact.
|
|
182
|
+
4. One headline sentence capturing the biggest contribution this period.
|
|
183
|
+
5. Stats block at the end.
|
|
184
|
+
|
|
185
|
+
**Format:**
|
|
186
|
+
|
|
187
|
+
## [Headline sentence]
|
|
188
|
+
|
|
189
|
+
### 🚀 [Theme — high impact]
|
|
190
|
+
- Specific achievement...
|
|
191
|
+
|
|
192
|
+
### ✅ [Theme — medium impact]
|
|
193
|
+
- ...
|
|
194
|
+
|
|
195
|
+
### 🔧 [Theme — low impact]
|
|
196
|
+
- ...
|
|
197
|
+
|
|
198
|
+
---
|
|
199
|
+
📊 ${entries.length} days | ${totalCommits} commits | [other notable stats]
|
|
200
|
+
`.trim();
|
|
201
|
+
return {
|
|
202
|
+
description: `Performance review for ${periodLabel} — ${repoRoot.split("/").pop()}`,
|
|
203
|
+
messages: [{ role: "user", content: { type: "text", text: userMessage } }],
|
|
204
|
+
};
|
|
205
|
+
}
|
|
206
|
+
// ─── Helpers ──────────────────────────────────────────────────────────────────
|
|
207
|
+
function parseSince(when) {
|
|
208
|
+
if (when === "today")
|
|
209
|
+
return (0, git_1.startOfDay)();
|
|
210
|
+
if (when === "yesterday")
|
|
211
|
+
return (0, git_1.startOfDaysAgo)(1);
|
|
212
|
+
const daysMatch = when.match(/^(\d+)d$/);
|
|
213
|
+
if (daysMatch)
|
|
214
|
+
return (0, git_1.startOfDaysAgo)(parseInt(daysMatch[1], 10));
|
|
215
|
+
const parsed = new Date(when);
|
|
216
|
+
return isNaN(parsed.getTime()) ? (0, git_1.startOfDay)() : parsed;
|
|
217
|
+
}
|
|
218
|
+
function parseDays(period) {
|
|
219
|
+
const match = period.match(/^(\d+)d$/);
|
|
220
|
+
return match ? parseInt(match[1], 10) : 30;
|
|
221
|
+
}
|
|
222
|
+
function parseQuarter(q) {
|
|
223
|
+
const match = q.match(/^Q([1-4])-(\d{4})$/i);
|
|
224
|
+
const quarter = parseInt(match[1], 10);
|
|
225
|
+
const year = parseInt(match[2], 10);
|
|
226
|
+
const startMonth = (quarter - 1) * 3 + 1;
|
|
227
|
+
const endMonth = startMonth + 2;
|
|
228
|
+
const from = `${year}-${String(startMonth).padStart(2, "0")}-01`;
|
|
229
|
+
const lastDay = new Date(year, endMonth, 0).getDate();
|
|
230
|
+
const to = `${year}-${String(endMonth).padStart(2, "0")}-${lastDay}`;
|
|
231
|
+
return { from, to };
|
|
232
|
+
}
|
|
233
|
+
function promptError(message) {
|
|
234
|
+
return singleMessage("Error", `Error: ${message}`);
|
|
235
|
+
}
|
|
236
|
+
function singleMessage(description, text) {
|
|
237
|
+
return {
|
|
238
|
+
description,
|
|
239
|
+
messages: [{ role: "user", content: { type: "text", text } }],
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/mcp/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repo path resolution — priority order:
|
|
3
|
+
*
|
|
4
|
+
* 1. Explicit arg passed by Claude (user said "~/code/my-app")
|
|
5
|
+
* 2. Default repo saved in user context (set once, reused forever)
|
|
6
|
+
* 3. Walk up from process.cwd() until a .git folder is found
|
|
7
|
+
* → works in Claude Code CLI where cwd = open project
|
|
8
|
+
* 4. Fail with a clear message asking the user to set a default
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveRepoPath(explicitPath?: string): {
|
|
11
|
+
path: string;
|
|
12
|
+
source: string;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=repo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/mcp/repo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAOH,wBAAgB,eAAe,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAsBvF"}
|
package/dist/mcp/repo.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Repo path resolution — priority order:
|
|
4
|
+
*
|
|
5
|
+
* 1. Explicit arg passed by Claude (user said "~/code/my-app")
|
|
6
|
+
* 2. Default repo saved in user context (set once, reused forever)
|
|
7
|
+
* 3. Walk up from process.cwd() until a .git folder is found
|
|
8
|
+
* → works in Claude Code CLI where cwd = open project
|
|
9
|
+
* 4. Fail with a clear message asking the user to set a default
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.resolveRepoPath = resolveRepoPath;
|
|
46
|
+
const path = __importStar(require("path"));
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const process = __importStar(require("process"));
|
|
49
|
+
const os = __importStar(require("os"));
|
|
50
|
+
function resolveRepoPath(explicitPath) {
|
|
51
|
+
// 1. Explicit arg — highest priority
|
|
52
|
+
if (explicitPath) {
|
|
53
|
+
const resolved = expandHome(explicitPath);
|
|
54
|
+
assertIsGitRepo(resolved);
|
|
55
|
+
return { path: resolved, source: "explicit" };
|
|
56
|
+
}
|
|
57
|
+
// 2. Walk up from cwd — works when Claude Code Desktop opens a project folder
|
|
58
|
+
const fromCwd = findGitRoot(process.cwd());
|
|
59
|
+
if (fromCwd) {
|
|
60
|
+
return { path: fromCwd, source: "cwd" };
|
|
61
|
+
}
|
|
62
|
+
// 3. Nothing found
|
|
63
|
+
throw new Error("No git repository found.\n\n" +
|
|
64
|
+
"Set a default repo once with:\n" +
|
|
65
|
+
' "set my default repo to /Users/you/code/my-project"\n\n' +
|
|
66
|
+
"Or tell me the path directly:\n" +
|
|
67
|
+
' "do my standup for ~/code/my-project"');
|
|
68
|
+
}
|
|
69
|
+
/** Walk up directory tree until a .git folder is found, or return null */
|
|
70
|
+
function findGitRoot(dir) {
|
|
71
|
+
let current = path.resolve(dir);
|
|
72
|
+
const root = path.parse(current).root;
|
|
73
|
+
while (current !== root) {
|
|
74
|
+
if (isGitRepo(current))
|
|
75
|
+
return current;
|
|
76
|
+
const parent = path.dirname(current);
|
|
77
|
+
if (parent === current)
|
|
78
|
+
break; // filesystem root
|
|
79
|
+
current = parent;
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
function isGitRepo(dir) {
|
|
84
|
+
try {
|
|
85
|
+
return fs.statSync(path.join(dir, ".git")).isDirectory();
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function assertIsGitRepo(dir) {
|
|
92
|
+
if (!fs.existsSync(dir)) {
|
|
93
|
+
throw new Error(`Path does not exist: ${dir}`);
|
|
94
|
+
}
|
|
95
|
+
if (!isGitRepo(dir)) {
|
|
96
|
+
throw new Error(`Not a git repository: ${dir}`);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function expandHome(p) {
|
|
100
|
+
if (p.startsWith("~/"))
|
|
101
|
+
return path.join(os.homedir(), p.slice(2));
|
|
102
|
+
if (p === "~")
|
|
103
|
+
return os.homedir();
|
|
104
|
+
return p;
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=repo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repo.js","sourceRoot":"","sources":["../../src/mcp/repo.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAOH,0CAsBC;AA3BD,2CAA6B;AAC7B,uCAAyB;AACzB,iDAAmC;AACnC,uCAAyB;AAEzB,SAAgB,eAAe,CAAC,YAAqB;IACnD,qCAAqC;IACrC,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;QAC1C,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC1B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;IAChD,CAAC;IAED,8EAA8E;IAC9E,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC;IAC3C,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC1C,CAAC;IAED,mBAAmB;IACnB,MAAM,IAAI,KAAK,CACb,8BAA8B;QAC9B,iCAAiC;QACjC,2DAA2D;QAC3D,iCAAiC;QACjC,yCAAyC,CAC1C,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,SAAS,WAAW,CAAC,GAAW;IAC9B,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC;IAEtC,OAAO,OAAO,KAAK,IAAI,EAAE,CAAC;QACxB,IAAI,SAAS,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QACvC,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,OAAO;YAAE,MAAM,CAAC,kBAAkB;QACjD,OAAO,GAAG,MAAM,CAAC;IACnB,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,GAAW;IAC5B,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,eAAe,CAAC,GAAW;IAClC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;IACjD,CAAC;IACD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,EAAE,CAAC,CAAC;IAClD,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACnE,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC;IACnC,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAOlF,eAAO,MAAM,oBAAoB,EAAE,QAAQ,EAkB1C,CAAC;AAEF,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,kBAAkB,CAiBlE"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RESOURCE_DEFINITIONS = void 0;
|
|
4
|
+
exports.handleReadResource = handleReadResource;
|
|
5
|
+
const db_1 = require("../storage/db");
|
|
6
|
+
const repo_1 = require("./repo");
|
|
7
|
+
const CONTEXT_URI = "git-impact://context";
|
|
8
|
+
const HISTORY_URI = "git-impact://history/overview";
|
|
9
|
+
exports.RESOURCE_DEFINITIONS = [
|
|
10
|
+
{
|
|
11
|
+
uri: CONTEXT_URI,
|
|
12
|
+
name: "Project Context",
|
|
13
|
+
description: "This repo's personalization: company description, manager priorities, and glossary. " +
|
|
14
|
+
"Stored in .git-impact/context.json — committable and team-shareable. " +
|
|
15
|
+
"Claude reads this automatically when translating commits.",
|
|
16
|
+
mimeType: "application/json",
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
uri: HISTORY_URI,
|
|
20
|
+
name: "History Overview",
|
|
21
|
+
description: "Summary of saved standup entries for the current repo: date range, total commits, days tracked. " +
|
|
22
|
+
"Check before generating a performance review to confirm enough history exists.",
|
|
23
|
+
mimeType: "application/json",
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
function handleReadResource(uri) {
|
|
27
|
+
// Resolve repo for both resources — safe to fail gracefully
|
|
28
|
+
let repoRoot = null;
|
|
29
|
+
try {
|
|
30
|
+
repoRoot = (0, repo_1.resolveRepoPath)().path;
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// repo not found — return a helpful message rather than throwing
|
|
34
|
+
}
|
|
35
|
+
switch (uri) {
|
|
36
|
+
case CONTEXT_URI:
|
|
37
|
+
return readContextResource(repoRoot);
|
|
38
|
+
case HISTORY_URI:
|
|
39
|
+
return readHistoryResource(repoRoot);
|
|
40
|
+
default:
|
|
41
|
+
throw new Error(`Unknown resource URI: ${uri}`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function readContextResource(repoRoot) {
|
|
45
|
+
const payload = repoRoot
|
|
46
|
+
? (() => {
|
|
47
|
+
const ctx = (0, db_1.loadContext)(repoRoot);
|
|
48
|
+
return ctx
|
|
49
|
+
? {
|
|
50
|
+
configured: true,
|
|
51
|
+
repo: repoRoot,
|
|
52
|
+
location: `${repoRoot}/.git-impact/context.json`,
|
|
53
|
+
company_description: ctx.companyDescription,
|
|
54
|
+
manager_priorities: ctx.managerPriorities,
|
|
55
|
+
glossary: ctx.glossary,
|
|
56
|
+
has_github_token: Boolean(ctx.githubToken),
|
|
57
|
+
has_anthropic_key: Boolean(ctx.anthropicApiKey),
|
|
58
|
+
}
|
|
59
|
+
: {
|
|
60
|
+
configured: false,
|
|
61
|
+
repo: repoRoot,
|
|
62
|
+
location: `${repoRoot}/.git-impact/context.json`,
|
|
63
|
+
message: "No context yet. Ask the user to describe their company and priorities, " +
|
|
64
|
+
"then call update_context to save them.",
|
|
65
|
+
};
|
|
66
|
+
})()
|
|
67
|
+
: {
|
|
68
|
+
configured: false,
|
|
69
|
+
message: "No git repository detected. Open a project first.",
|
|
70
|
+
};
|
|
71
|
+
return {
|
|
72
|
+
contents: [{ uri: CONTEXT_URI, mimeType: "application/json", text: JSON.stringify(payload, null, 2) }],
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function readHistoryResource(repoRoot) {
|
|
76
|
+
const payload = repoRoot
|
|
77
|
+
? (() => {
|
|
78
|
+
const entries = (0, db_1.getEntriesForDaysAgo)(365, repoRoot);
|
|
79
|
+
return entries.length === 0
|
|
80
|
+
? {
|
|
81
|
+
total_entries: 0,
|
|
82
|
+
repo: repoRoot,
|
|
83
|
+
message: "No history saved yet. Run the standup prompt daily to build history.",
|
|
84
|
+
}
|
|
85
|
+
: {
|
|
86
|
+
total_entries: entries.length,
|
|
87
|
+
repo: repoRoot,
|
|
88
|
+
earliest_date: entries[0].date,
|
|
89
|
+
latest_date: entries[entries.length - 1].date,
|
|
90
|
+
total_commits: entries.reduce((s, e) => s + e.totalCommits, 0),
|
|
91
|
+
};
|
|
92
|
+
})()
|
|
93
|
+
: { total_entries: 0, message: "No git repository detected." };
|
|
94
|
+
return {
|
|
95
|
+
contents: [{ uri: HISTORY_URI, mimeType: "application/json", text: JSON.stringify(payload, null, 2) }],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/mcp/resources.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* git-impact MCP server
|
|
4
|
+
*
|
|
5
|
+
* Architecture: data-only. This server never calls Claude.
|
|
6
|
+
* It exposes three MCP primitives:
|
|
7
|
+
*
|
|
8
|
+
* Tools — actions Claude calls to read/write data
|
|
9
|
+
* Resources — semi-static data Claude reads (user context, history overview)
|
|
10
|
+
* Prompts — computed templates: fetch live data + embed translation instructions
|
|
11
|
+
* so Claude Code does the AI work inside its own session, no API key needed
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;GAUG"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* git-impact MCP server
|
|
5
|
+
*
|
|
6
|
+
* Architecture: data-only. This server never calls Claude.
|
|
7
|
+
* It exposes three MCP primitives:
|
|
8
|
+
*
|
|
9
|
+
* Tools — actions Claude calls to read/write data
|
|
10
|
+
* Resources — semi-static data Claude reads (user context, history overview)
|
|
11
|
+
* Prompts — computed templates: fetch live data + embed translation instructions
|
|
12
|
+
* so Claude Code does the AI work inside its own session, no API key needed
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
16
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
17
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
18
|
+
const tools_js_1 = require("./tools.js");
|
|
19
|
+
const resources_js_1 = require("./resources.js");
|
|
20
|
+
const prompts_js_1 = require("./prompts.js");
|
|
21
|
+
// ─── Server setup ────────────────────────────────────────────────────────────
|
|
22
|
+
const server = new index_js_1.Server({ name: "git-impact", version: "0.1.0" }, {
|
|
23
|
+
capabilities: {
|
|
24
|
+
tools: {},
|
|
25
|
+
resources: {},
|
|
26
|
+
prompts: {},
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
// ─── Tools ───────────────────────────────────────────────────────────────────
|
|
30
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
31
|
+
tools: tools_js_1.TOOL_DEFINITIONS,
|
|
32
|
+
}));
|
|
33
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
34
|
+
const { name, arguments: args } = request.params;
|
|
35
|
+
return (0, tools_js_1.handleTool)(name, (args ?? {}));
|
|
36
|
+
});
|
|
37
|
+
// ─── Resources ───────────────────────────────────────────────────────────────
|
|
38
|
+
server.setRequestHandler(types_js_1.ListResourcesRequestSchema, async () => ({
|
|
39
|
+
resources: resources_js_1.RESOURCE_DEFINITIONS,
|
|
40
|
+
}));
|
|
41
|
+
server.setRequestHandler(types_js_1.ReadResourceRequestSchema, async (request) => {
|
|
42
|
+
return (0, resources_js_1.handleReadResource)(request.params.uri);
|
|
43
|
+
});
|
|
44
|
+
// ─── Prompts ─────────────────────────────────────────────────────────────────
|
|
45
|
+
server.setRequestHandler(types_js_1.ListPromptsRequestSchema, async () => ({
|
|
46
|
+
prompts: prompts_js_1.PROMPT_DEFINITIONS,
|
|
47
|
+
}));
|
|
48
|
+
server.setRequestHandler(types_js_1.GetPromptRequestSchema, async (request) => {
|
|
49
|
+
const { name, arguments: args } = request.params;
|
|
50
|
+
return (0, prompts_js_1.handleGetPrompt)(name, args);
|
|
51
|
+
});
|
|
52
|
+
// ─── Start ───────────────────────────────────────────────────────────────────
|
|
53
|
+
async function main() {
|
|
54
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
55
|
+
await server.connect(transport);
|
|
56
|
+
}
|
|
57
|
+
main().catch((err) => {
|
|
58
|
+
console.error("git-impact MCP server failed to start:", err);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
});
|
|
61
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":";;AAEA;;;;;;;;;;GAUG;;AAEH,wEAAmE;AACnE,wEAAiF;AACjF,iEAO4C;AAE5C,yCAA0D;AAC1D,iDAA0E;AAC1E,6CAAmE;AAEnE,gFAAgF;AAEhF,MAAM,MAAM,GAAG,IAAI,iBAAM,CACvB,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,EACxC;IACE,YAAY,EAAE;QACZ,KAAK,EAAE,EAAE;QACT,SAAS,EAAE,EAAE;QACb,OAAO,EAAE,EAAE;KACZ;CACF,CACF,CAAC;AAEF,gFAAgF;AAEhF,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAC5D,KAAK,EAAE,2BAAgB;CACxB,CAAC,CAAC,CAAC;AAEJ,MAAM,CAAC,iBAAiB,CAAC,gCAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IACjD,OAAO,IAAA,qBAAU,EAAC,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAA4B,CAAC,CAAC;AACnE,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,MAAM,CAAC,iBAAiB,CAAC,qCAA0B,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAChE,SAAS,EAAE,mCAAoB;CAChC,CAAC,CAAC,CAAC;AAEJ,MAAM,CAAC,iBAAiB,CAAC,oCAAyB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACpE,OAAO,IAAA,iCAAkB,EAAC,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAChD,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,MAAM,CAAC,iBAAiB,CAAC,mCAAwB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;IAC9D,OAAO,EAAE,+BAAkB;CAC5B,CAAC,CAAC,CAAC;AAEJ,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;IACjE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IACjD,OAAO,IAAA,4BAAe,EAAC,IAAI,EAAE,IAA0C,CAAC,CAAC;AAC3E,CAAC,CAAC,CAAC;AAEH,gFAAgF;AAEhF,KAAK,UAAU,IAAI;IACjB,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Tool } from "@modelcontextprotocol/sdk/types.js";
|
|
2
|
+
export declare const TOOL_DEFINITIONS: Tool[];
|
|
3
|
+
type ToolResult = {
|
|
4
|
+
content: Array<{
|
|
5
|
+
type: "text";
|
|
6
|
+
text: string;
|
|
7
|
+
}>;
|
|
8
|
+
isError?: boolean;
|
|
9
|
+
};
|
|
10
|
+
export declare function handleTool(name: string, args: Record<string, unknown>): Promise<ToolResult>;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAgB1D,eAAO,MAAM,gBAAgB,EAAE,IAAI,EA+GlC,CAAC;AAIF,KAAK,UAAU,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAExF,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,UAAU,CAAC,CASrB"}
|