@towry/mcp 0.1.7 → 0.3.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.
@@ -0,0 +1,277 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import * as fs from "node:fs";
3
+ import * as path from "node:path";
4
+ import * as os from "node:os";
5
+ // Import internal functions for testing
6
+ // We need to export them or test via the public API
7
+ // For now, test the core logic via file operations
8
+ const TEST_DIR = path.join(os.tmpdir(), "mcp-checkpoints-test");
9
+ // Helper to create test checkpoint file
10
+ function createTestCheckpointFile(branch, checkpoints) {
11
+ const dir = path.join(TEST_DIR, ".agents", "checkpoints");
12
+ fs.mkdirSync(dir, { recursive: true });
13
+ const safeBranch = branch.replace(/\//g, "_");
14
+ const filePath = path.join(dir, `${safeBranch}.jsonl`);
15
+ const lines = checkpoints.map((cp) => JSON.stringify(cp)).join("\n");
16
+ fs.writeFileSync(filePath, lines + "\n", "utf-8");
17
+ return filePath;
18
+ }
19
+ function readTestCheckpoints(branch) {
20
+ const dir = path.join(TEST_DIR, ".agents", "checkpoints");
21
+ const safeBranch = branch.replace(/\//g, "_");
22
+ const filePath = path.join(dir, `${safeBranch}.jsonl`);
23
+ if (!fs.existsSync(filePath))
24
+ return [];
25
+ const content = fs.readFileSync(filePath, "utf-8");
26
+ return content
27
+ .trim()
28
+ .split("\n")
29
+ .filter(Boolean)
30
+ .map((line) => JSON.parse(line));
31
+ }
32
+ // Recreate time filtering logic for testing
33
+ function filterByTime(checkpoints, since, until) {
34
+ return checkpoints.filter((cp) => {
35
+ const ts = new Date(cp.timestamp);
36
+ if (since && ts < since)
37
+ return false;
38
+ if (until && ts > until)
39
+ return false;
40
+ return true;
41
+ });
42
+ }
43
+ function parseRelativeTime(alias) {
44
+ const aliases = {
45
+ today: () => {
46
+ const d = new Date();
47
+ d.setHours(0, 0, 0, 0);
48
+ return d;
49
+ },
50
+ yesterday: () => {
51
+ const d = new Date();
52
+ d.setDate(d.getDate() - 1);
53
+ d.setHours(0, 0, 0, 0);
54
+ return d;
55
+ },
56
+ last_1h: () => new Date(Date.now() - 60 * 60 * 1000),
57
+ last_24h: () => new Date(Date.now() - 24 * 60 * 60 * 1000),
58
+ last_7d: () => new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
59
+ last_30d: () => new Date(Date.now() - 30 * 24 * 60 * 60 * 1000),
60
+ };
61
+ const fn = aliases[alias.toLowerCase()];
62
+ return fn ? fn() : null;
63
+ }
64
+ function filterByQuery(checkpoints, query) {
65
+ const q = query.toLowerCase();
66
+ return checkpoints.filter((cp) => {
67
+ if (cp.task.toLowerCase().includes(q))
68
+ return true;
69
+ if (cp.summary.toLowerCase().includes(q))
70
+ return true;
71
+ if (cp.tags?.some((t) => t.toLowerCase().includes(q)))
72
+ return true;
73
+ if (cp.references?.some((r) => r.title.toLowerCase().includes(q) || r.ref.toLowerCase().includes(q))) {
74
+ return true;
75
+ }
76
+ return false;
77
+ });
78
+ }
79
+ describe("checkpoints", () => {
80
+ beforeEach(() => {
81
+ fs.rmSync(TEST_DIR, { recursive: true, force: true });
82
+ fs.mkdirSync(TEST_DIR, { recursive: true });
83
+ });
84
+ afterEach(() => {
85
+ fs.rmSync(TEST_DIR, { recursive: true, force: true });
86
+ });
87
+ describe("record checkpoint", () => {
88
+ it("writes checkpoint to branch-scoped JSONL file", () => {
89
+ const checkpoint = {
90
+ timestamp: new Date().toISOString(),
91
+ branch: "feature/test",
92
+ task: "implement feature",
93
+ summary: "Added new checkpoint tools",
94
+ };
95
+ createTestCheckpointFile("feature/test", [checkpoint]);
96
+ const records = readTestCheckpoints("feature/test");
97
+ expect(records).toHaveLength(1);
98
+ expect(records[0]).toMatchObject({
99
+ branch: "feature/test",
100
+ task: "implement feature",
101
+ });
102
+ });
103
+ it("appends multiple checkpoints to same file", () => {
104
+ const cp1 = { timestamp: "2026-03-12T10:00:00Z", branch: "main", task: "task 1", summary: "s1" };
105
+ const cp2 = { timestamp: "2026-03-12T11:00:00Z", branch: "main", task: "task 2", summary: "s2" };
106
+ createTestCheckpointFile("main", [cp1, cp2]);
107
+ const records = readTestCheckpoints("main");
108
+ expect(records).toHaveLength(2);
109
+ });
110
+ });
111
+ describe("branch file isolation", () => {
112
+ it("stores checkpoints in separate files per branch", () => {
113
+ const mainCp = { timestamp: "2026-03-12T10:00:00Z", branch: "main", task: "main task", summary: "s" };
114
+ const featureCp = {
115
+ timestamp: "2026-03-12T11:00:00Z",
116
+ branch: "feature/x",
117
+ task: "feature task",
118
+ summary: "s",
119
+ };
120
+ createTestCheckpointFile("main", [mainCp]);
121
+ createTestCheckpointFile("feature/x", [featureCp]);
122
+ expect(readTestCheckpoints("main")).toHaveLength(1);
123
+ expect(readTestCheckpoints("feature/x")).toHaveLength(1);
124
+ });
125
+ it("sanitizes branch names with slashes", () => {
126
+ const dir = path.join(TEST_DIR, ".agents", "checkpoints");
127
+ fs.mkdirSync(dir, { recursive: true });
128
+ const branch = "feature/awesome-thing";
129
+ const safeName = branch.replace(/\//g, "_");
130
+ const filePath = path.join(dir, `${safeName}.jsonl`);
131
+ fs.writeFileSync(filePath, '{"test": true}\n', "utf-8");
132
+ expect(fs.existsSync(filePath)).toBe(true);
133
+ expect(safeName).toBe("feature_awesome-thing");
134
+ });
135
+ });
136
+ describe("ISO time filtering", () => {
137
+ it("filters by since date", () => {
138
+ const checkpoints = [
139
+ { timestamp: "2026-03-10T10:00:00Z" },
140
+ { timestamp: "2026-03-12T10:00:00Z" },
141
+ { timestamp: "2026-03-14T10:00:00Z" },
142
+ ];
143
+ const since = new Date("2026-03-11T00:00:00Z");
144
+ const filtered = filterByTime(checkpoints, since, undefined);
145
+ expect(filtered).toHaveLength(2);
146
+ });
147
+ it("filters by until date", () => {
148
+ const checkpoints = [
149
+ { timestamp: "2026-03-10T10:00:00Z" },
150
+ { timestamp: "2026-03-12T10:00:00Z" },
151
+ { timestamp: "2026-03-14T10:00:00Z" },
152
+ ];
153
+ const until = new Date("2026-03-13T00:00:00Z");
154
+ const filtered = filterByTime(checkpoints, undefined, until);
155
+ expect(filtered).toHaveLength(2);
156
+ });
157
+ it("filters by date range", () => {
158
+ const checkpoints = [
159
+ { timestamp: "2026-03-10T10:00:00Z" },
160
+ { timestamp: "2026-03-12T10:00:00Z" },
161
+ { timestamp: "2026-03-14T10:00:00Z" },
162
+ ];
163
+ const since = new Date("2026-03-11T00:00:00Z");
164
+ const until = new Date("2026-03-13T00:00:00Z");
165
+ const filtered = filterByTime(checkpoints, since, until);
166
+ expect(filtered).toHaveLength(1);
167
+ });
168
+ });
169
+ describe("relativeTime alias filtering", () => {
170
+ it("parses 'today' as start of current day", () => {
171
+ const today = parseRelativeTime("today");
172
+ expect(today).not.toBeNull();
173
+ expect(today.getHours()).toBe(0);
174
+ expect(today.getMinutes()).toBe(0);
175
+ expect(today.getSeconds()).toBe(0);
176
+ });
177
+ it("parses 'yesterday' as start of previous day", () => {
178
+ const yesterday = parseRelativeTime("yesterday");
179
+ const today = parseRelativeTime("today");
180
+ expect(yesterday).not.toBeNull();
181
+ const diffMs = today.getTime() - yesterday.getTime();
182
+ expect(diffMs).toBe(24 * 60 * 60 * 1000);
183
+ });
184
+ it("parses 'last_1h' as 1 hour ago", () => {
185
+ const last1h = parseRelativeTime("last_1h");
186
+ expect(last1h).not.toBeNull();
187
+ const diffMs = Date.now() - last1h.getTime();
188
+ expect(diffMs).toBeGreaterThanOrEqual(60 * 60 * 1000 - 1000);
189
+ expect(diffMs).toBeLessThanOrEqual(60 * 60 * 1000 + 1000);
190
+ });
191
+ it("parses 'last_7d' as 7 days ago", () => {
192
+ const last7d = parseRelativeTime("last_7d");
193
+ expect(last7d).not.toBeNull();
194
+ const diffMs = Date.now() - last7d.getTime();
195
+ expect(diffMs).toBeGreaterThanOrEqual(7 * 24 * 60 * 60 * 1000 - 1000);
196
+ });
197
+ it("filters checkpoints using relative time", () => {
198
+ const now = new Date();
199
+ const oneHourAgo = new Date(now.getTime() - 30 * 60 * 1000); // 30 min ago
200
+ const twoHoursAgo = new Date(now.getTime() - 2 * 60 * 60 * 1000);
201
+ const checkpoints = [
202
+ { timestamp: twoHoursAgo.toISOString() },
203
+ { timestamp: oneHourAgo.toISOString() },
204
+ ];
205
+ const since = parseRelativeTime("last_1h");
206
+ const filtered = filterByTime(checkpoints, since, undefined);
207
+ expect(filtered).toHaveLength(1);
208
+ });
209
+ });
210
+ describe("keyword matching", () => {
211
+ it("matches query in task", () => {
212
+ const checkpoints = [
213
+ { task: "implement login", summary: "s1", tags: [] },
214
+ { task: "fix logout", summary: "s2", tags: [] },
215
+ ];
216
+ const filtered = filterByQuery(checkpoints, "login");
217
+ expect(filtered).toHaveLength(1);
218
+ });
219
+ it("matches query in summary", () => {
220
+ const checkpoints = [
221
+ { task: "t1", summary: "added authentication flow", tags: [] },
222
+ { task: "t2", summary: "fixed styling", tags: [] },
223
+ ];
224
+ const filtered = filterByQuery(checkpoints, "authentication");
225
+ expect(filtered).toHaveLength(1);
226
+ });
227
+ it("matches query in tags", () => {
228
+ const checkpoints = [
229
+ { task: "t1", summary: "s1", tags: ["mcp", "checkpoint"] },
230
+ { task: "t2", summary: "s2", tags: ["test"] },
231
+ ];
232
+ const filtered = filterByQuery(checkpoints, "mcp");
233
+ expect(filtered).toHaveLength(1);
234
+ });
235
+ it("matches query in references title", () => {
236
+ const checkpoints = [
237
+ {
238
+ task: "t1",
239
+ summary: "s1",
240
+ references: [{ kind: "file", title: "MCP Server Docs", ref: "docs/mcp.md" }],
241
+ },
242
+ { task: "t2", summary: "s2" },
243
+ ];
244
+ const filtered = filterByQuery(checkpoints, "server");
245
+ expect(filtered).toHaveLength(1);
246
+ });
247
+ it("matches query in references ref", () => {
248
+ const checkpoints = [
249
+ {
250
+ task: "t1",
251
+ summary: "s1",
252
+ references: [{ kind: "url", title: "API", ref: "https://example.com/api/auth" }],
253
+ },
254
+ { task: "t2", summary: "s2" },
255
+ ];
256
+ const filtered = filterByQuery(checkpoints, "auth");
257
+ expect(filtered).toHaveLength(1);
258
+ });
259
+ it("is case-insensitive", () => {
260
+ const checkpoints = [{ task: "Implement LOGIN", summary: "S", tags: [] }];
261
+ const filtered = filterByQuery(checkpoints, "login");
262
+ expect(filtered).toHaveLength(1);
263
+ });
264
+ });
265
+ describe("non-git directory fallback", () => {
266
+ it("uses 'default' branch name when not in git repo", () => {
267
+ // Non-git directory would return 'default' from getCurrentBranch
268
+ // We test that the file path is correctly generated
269
+ const branch = "default";
270
+ const filePath = path.join(TEST_DIR, ".agents", "checkpoints", `${branch}.jsonl`);
271
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
272
+ fs.writeFileSync(filePath, '{"test": true}\n', "utf-8");
273
+ expect(fs.existsSync(filePath)).toBe(true);
274
+ });
275
+ });
276
+ });
277
+ //# sourceMappingURL=checkpoints.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoints.test.js","sourceRoot":"","sources":["../src/checkpoints.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=checkpoints.validation.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoints.validation.test.d.ts","sourceRoot":"","sources":["../src/checkpoints.validation.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,28 @@
1
+ import { describe, it, expect } from "vitest";
2
+ import { countSentences, SummarySchema } from "./checkpoints.js";
3
+ describe("checkpoints summary validation", () => {
4
+ describe("countSentences", () => {
5
+ it("counts punctuation-delimited sentences", () => {
6
+ expect(countSentences("First sentence. Second sentence!")).toBe(2);
7
+ expect(countSentences("One. Two? Three! Four.")).toBe(4);
8
+ });
9
+ it("treats text without terminal punctuation as one sentence", () => {
10
+ expect(countSentences("Single sentence without punctuation")).toBe(1);
11
+ });
12
+ });
13
+ describe("SummarySchema", () => {
14
+ it("accepts 2-4 sentences", () => {
15
+ expect(SummarySchema.safeParse("Did setup. Added tests.").success).toBe(true);
16
+ expect(SummarySchema.safeParse("A. B. C. D.").success).toBe(true);
17
+ });
18
+ it("rejects fewer than 2 sentences", () => {
19
+ const result = SummarySchema.safeParse("Only one sentence.");
20
+ expect(result.success).toBe(false);
21
+ });
22
+ it("rejects more than 4 sentences", () => {
23
+ const result = SummarySchema.safeParse("A. B. C. D. E.");
24
+ expect(result.success).toBe(false);
25
+ });
26
+ });
27
+ });
28
+ //# sourceMappingURL=checkpoints.validation.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"checkpoints.validation.test.js","sourceRoot":"","sources":["../src/checkpoints.validation.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjE,QAAQ,CAAC,gCAAgC,EAAE,GAAG,EAAE;IAC9C,QAAQ,CAAC,gBAAgB,EAAE,GAAG,EAAE;QAC9B,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;YAChD,MAAM,CAAC,cAAc,CAAC,kCAAkC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACnE,MAAM,CAAC,cAAc,CAAC,wBAAwB,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC3D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0DAA0D,EAAE,GAAG,EAAE;YAClE,MAAM,CAAC,cAAc,CAAC,qCAAqC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;QAC7B,EAAE,CAAC,uBAAuB,EAAE,GAAG,EAAE;YAC/B,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9E,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gCAAgC,EAAE,GAAG,EAAE;YACxC,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YAC7D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;YACvC,MAAM,MAAM,GAAG,aAAa,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YACzD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,16 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @towry/mcp - Knowledge Graph & Tmux MCP Server
3
+ * @towry/mcp - Grep MCP Server
4
4
  *
5
5
  * Provides tools for:
6
- * - Document management in a knowledge graph
7
- * - Tmux pane management and control
6
+ * - Fast grep-based code search
8
7
  *
9
- * Environment Variables:
10
- * - KG_API_URL: API base URL (default: http://localhost:8361)
11
- * - KG_API_KEY or KG_API_TOKEN: API authentication key
12
- *
13
- * Keywords: mcp, knowledge-graph, document-management, tmux, ai-tools, llm-server
8
+ * Keywords: mcp, grep, ai-tools, llm-server
14
9
  */
15
10
  export {};
16
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;GAYG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG"}