@epiccontext/mcp 0.1.55 → 0.1.57
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/dist/api/client.d.ts +27 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +102 -0
- package/dist/api/client.js.map +1 -1
- package/dist/cli/commands/add-app.d.ts +9 -0
- package/dist/cli/commands/add-app.d.ts.map +1 -0
- package/dist/cli/commands/add-app.js +111 -0
- package/dist/cli/commands/add-app.js.map +1 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +37 -16
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/pull.d.ts +2 -0
- package/dist/cli/commands/pull.d.ts.map +1 -1
- package/dist/cli/commands/pull.js +122 -67
- package/dist/cli/commands/pull.js.map +1 -1
- package/dist/cli/commands/push.d.ts +2 -0
- package/dist/cli/commands/push.d.ts.map +1 -1
- package/dist/cli/commands/push.js +130 -75
- package/dist/cli/commands/push.js.map +1 -1
- package/dist/cli/commands/serve.d.ts.map +1 -1
- package/dist/cli/commands/serve.js +2 -1
- package/dist/cli/commands/serve.js.map +1 -1
- package/dist/cli/commands/status.d.ts.map +1 -1
- package/dist/cli/commands/status.js +21 -3
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/validate.d.ts.map +1 -1
- package/dist/cli/commands/validate.js +6 -5
- package/dist/cli/commands/validate.js.map +1 -1
- package/dist/cli/config.d.ts +4 -0
- package/dist/cli/config.d.ts.map +1 -1
- package/dist/cli/config.js +20 -0
- package/dist/cli/config.js.map +1 -1
- package/dist/cli/files.d.ts +9 -1
- package/dist/cli/files.d.ts.map +1 -1
- package/dist/cli/files.js +147 -31
- package/dist/cli/files.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +12 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/mcp/server.d.ts +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +12 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools/list-documents.d.ts +10 -0
- package/dist/mcp/tools/list-documents.d.ts.map +1 -0
- package/dist/mcp/tools/list-documents.js +86 -0
- package/dist/mcp/tools/list-documents.js.map +1 -0
- package/dist/mcp/tools/read-document.d.ts +10 -0
- package/dist/mcp/tools/read-document.d.ts.map +1 -0
- package/dist/mcp/tools/read-document.js +119 -0
- package/dist/mcp/tools/read-document.js.map +1 -0
- package/dist/mcp/tools/sync-all.d.ts.map +1 -1
- package/dist/mcp/tools/sync-all.js +9 -0
- package/dist/mcp/tools/sync-all.js.map +1 -1
- package/dist/mcp/tools/sync-documents.d.ts +10 -0
- package/dist/mcp/tools/sync-documents.d.ts.map +1 -0
- package/dist/mcp/tools/sync-documents.js +89 -0
- package/dist/mcp/tools/sync-documents.js.map +1 -0
- package/dist/mcp/tools/sync-from-app.d.ts.map +1 -1
- package/dist/mcp/tools/sync-from-app.js +6 -0
- package/dist/mcp/tools/sync-from-app.js.map +1 -1
- package/dist/mcp/tools/sync-to-app.d.ts.map +1 -1
- package/dist/mcp/tools/sync-to-app.js +6 -0
- package/dist/mcp/tools/sync-to-app.js.map +1 -1
- package/dist/skills/generator.d.ts.map +1 -1
- package/dist/skills/generator.js +98 -5
- package/dist/skills/generator.js.map +1 -1
- package/dist/sync/deletions.d.ts +31 -0
- package/dist/sync/deletions.d.ts.map +1 -0
- package/dist/sync/deletions.js +110 -0
- package/dist/sync/deletions.js.map +1 -0
- package/dist/sync/document-files.d.ts +31 -0
- package/dist/sync/document-files.d.ts.map +1 -0
- package/dist/sync/document-files.js +98 -0
- package/dist/sync/document-files.js.map +1 -0
- package/dist/sync/document-manifest.d.ts +22 -0
- package/dist/sync/document-manifest.d.ts.map +1 -0
- package/dist/sync/document-manifest.js +55 -0
- package/dist/sync/document-manifest.js.map +1 -0
- package/dist/sync/document-pull.d.ts +16 -0
- package/dist/sync/document-pull.d.ts.map +1 -0
- package/dist/sync/document-pull.js +149 -0
- package/dist/sync/document-pull.js.map +1 -0
- package/dist/sync/document-push.d.ts +14 -0
- package/dist/sync/document-push.d.ts.map +1 -0
- package/dist/sync/document-push.js +107 -0
- package/dist/sync/document-push.js.map +1 -0
- package/dist/sync/pull.d.ts +4 -0
- package/dist/sync/pull.d.ts.map +1 -1
- package/dist/sync/pull.js +91 -0
- package/dist/sync/pull.js.map +1 -1
- package/dist/sync/push.d.ts +4 -0
- package/dist/sync/push.d.ts.map +1 -1
- package/dist/sync/push.js +44 -1
- package/dist/sync/push.js.map +1 -1
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +25 -5
- package/dist/sync/watcher.js.map +1 -1
- package/dist/types/index.d.ts +127 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/skills/generator.js
CHANGED
|
@@ -74,6 +74,12 @@ const SECTION_CONFIGS = {
|
|
|
74
74
|
folder: "metrics",
|
|
75
75
|
blockTypes: ["metric", "analytics_event", "north_star", "kpi"],
|
|
76
76
|
},
|
|
77
|
+
performance: {
|
|
78
|
+
name: "Performance Expert",
|
|
79
|
+
description: "Reviews performance metrics for clarity and actionability. Helps read charts, set insights, and analyze KPI trends",
|
|
80
|
+
folder: "performance",
|
|
81
|
+
blockTypes: ["metric", "analytics_event", "north_star", "kpi"],
|
|
82
|
+
},
|
|
77
83
|
decisions: {
|
|
78
84
|
name: "Decision Recorder",
|
|
79
85
|
description: "Ensures decisions are properly documented with context and rationale",
|
|
@@ -177,6 +183,13 @@ Example:
|
|
|
177
183
|
- This addresses: [link to existing content]
|
|
178
184
|
\`\`\`
|
|
179
185
|
|
|
186
|
+
## Context Staleness Check
|
|
187
|
+
|
|
188
|
+
When this section's blocks are referenced in code changes, verify they're still accurate.
|
|
189
|
+
If you implemented something that relates to blocks in CONTEXT/${config.folder}/:
|
|
190
|
+
- Update block status if work is complete
|
|
191
|
+
- Flag any content that no longer matches the implementation
|
|
192
|
+
|
|
180
193
|
## Anti-Patterns to Avoid
|
|
181
194
|
|
|
182
195
|
- Creating content without reading existing CONTEXT
|
|
@@ -184,6 +197,7 @@ Example:
|
|
|
184
197
|
- Not linking to related sections
|
|
185
198
|
- Using placeholder text (TBD, TODO, Lorem ipsum)
|
|
186
199
|
- Using wrong block types for the content
|
|
200
|
+
- Leaving block status as "draft" after implementation is complete
|
|
187
201
|
`;
|
|
188
202
|
}
|
|
189
203
|
/**
|
|
@@ -205,12 +219,23 @@ allowed-tools: Read, Grep, Glob
|
|
|
205
219
|
This project uses EpicContext for structured product documentation.
|
|
206
220
|
The CONTEXT/ folder is the single source of truth.
|
|
207
221
|
|
|
222
|
+
## Project Structure
|
|
223
|
+
|
|
224
|
+
\`\`\`
|
|
225
|
+
./
|
|
226
|
+
├── CONTEXT/ Documentation blocks (syncs with EpicContext cloud)
|
|
227
|
+
├── DOCUMENTS/ Reference files: PDFs, images, research (syncs with cloud)
|
|
228
|
+
├── apps/ Code repositories (git repos)
|
|
229
|
+
└── .epicontext Project configuration
|
|
230
|
+
\`\`\`
|
|
231
|
+
|
|
208
232
|
## Critical Rules
|
|
209
233
|
|
|
210
234
|
1. **ALWAYS read CONTEXT first** - Before any development task, check relevant sections
|
|
211
235
|
2. **Traceability required** - All code must trace to documented requirements
|
|
212
236
|
3. **One block per file** - Never combine multiple items
|
|
213
237
|
4. **Use correct block types** - See CONTEXT/AI-GUIDE.md
|
|
238
|
+
5. **Update CONTEXT after implementation** - Keep documentation in sync with code
|
|
214
239
|
|
|
215
240
|
## Quick Navigation
|
|
216
241
|
|
|
@@ -222,20 +247,42 @@ The CONTEXT/ folder is the single source of truth.
|
|
|
222
247
|
| How to build | CONTEXT/technical/ |
|
|
223
248
|
| Past decisions | CONTEXT/decisions/ |
|
|
224
249
|
| Visual design | CONTEXT/design-system/ and CONTEXT/brand/ |
|
|
250
|
+
| Reference docs | DOCUMENTS/ |
|
|
225
251
|
|
|
226
252
|
## Before Starting Work
|
|
227
253
|
|
|
228
254
|
1. Read \`CONTEXT/AI-GUIDE.md\` for block schemas
|
|
229
255
|
2. Check relevant sections for your task
|
|
230
|
-
3.
|
|
231
|
-
4.
|
|
256
|
+
3. Browse \`DOCUMENTS/\` for reference materials
|
|
257
|
+
4. Cite sources in your output
|
|
258
|
+
|
|
259
|
+
## AFTER Implementation — Context Update Triggers
|
|
260
|
+
|
|
261
|
+
**You MUST update CONTEXT when your work changes the product.**
|
|
262
|
+
|
|
263
|
+
| What You Did | Required Context Update |
|
|
264
|
+
|-------------|------------------------|
|
|
265
|
+
| Implemented a feature | Set feature block \`status: complete\` |
|
|
266
|
+
| Made a technical decision | Create a \`decision\` block in \`decisions/\` |
|
|
267
|
+
| Added an API endpoint | Create an \`api_endpoint\` block in \`technical/api/\` |
|
|
268
|
+
| Completed a task | Set task block \`status: complete\` |
|
|
269
|
+
| Changed data models | Update \`data_model\` blocks in \`technical/models/\` |
|
|
270
|
+
| Added a new integration | Create an \`integration\` block in \`technical/integrations/\` |
|
|
271
|
+
| Discovered a constraint | Create a \`constraint\` block |
|
|
272
|
+
|
|
273
|
+
After updating CONTEXT, push changes:
|
|
274
|
+
\`\`\`bash
|
|
275
|
+
npx @epiccontext/mcp push
|
|
276
|
+
\`\`\`
|
|
232
277
|
|
|
233
278
|
## Sync Commands
|
|
234
279
|
|
|
235
280
|
\`\`\`bash
|
|
236
|
-
npx @epiccontext/mcp push
|
|
237
|
-
npx @epiccontext/mcp pull
|
|
238
|
-
npx @epiccontext/mcp
|
|
281
|
+
npx @epiccontext/mcp push # Push CONTEXT to cloud
|
|
282
|
+
npx @epiccontext/mcp pull # Pull CONTEXT from cloud
|
|
283
|
+
npx @epiccontext/mcp push --with-documents # Push CONTEXT + DOCUMENTS
|
|
284
|
+
npx @epiccontext/mcp pull --with-documents # Pull CONTEXT + DOCUMENTS
|
|
285
|
+
npx @epiccontext/mcp status # Check sync status
|
|
239
286
|
\`\`\`
|
|
240
287
|
`;
|
|
241
288
|
}
|
|
@@ -485,6 +532,52 @@ export function generateSkills(projectRoot) {
|
|
|
485
532
|
path: ".claude/skills/epicontext-core/SKILL.md",
|
|
486
533
|
content: generateCoreSkillMd(),
|
|
487
534
|
});
|
|
535
|
+
// Core skill workflow: post-implementation context update
|
|
536
|
+
result.workflows.push({
|
|
537
|
+
path: ".claude/skills/epicontext-core/workflows/post-implementation.md",
|
|
538
|
+
content: generateWorkflowMd("epicontext-core", {
|
|
539
|
+
id: "post-implementation",
|
|
540
|
+
name: "Post-Implementation",
|
|
541
|
+
description: "Check which CONTEXT blocks need updating after implementing code changes",
|
|
542
|
+
allowedTools: ["Read", "Grep", "Glob"],
|
|
543
|
+
prompt: `# Post-Implementation Context Check
|
|
544
|
+
|
|
545
|
+
After implementing code changes, check which CONTEXT blocks need updating.
|
|
546
|
+
|
|
547
|
+
## Process
|
|
548
|
+
|
|
549
|
+
1. **Identify what changed** — Look at the code changes just made
|
|
550
|
+
2. **Check related CONTEXT blocks** — Search for blocks that reference this area:
|
|
551
|
+
- Grep for feature names in CONTEXT/product/features/
|
|
552
|
+
- Grep for task/story names in CONTEXT/development/
|
|
553
|
+
- Check CONTEXT/technical/ for relevant API or data model blocks
|
|
554
|
+
3. **Suggest updates** — For each related block:
|
|
555
|
+
- If a feature was implemented → suggest setting status to "complete"
|
|
556
|
+
- If a task was completed → suggest setting status to "complete"
|
|
557
|
+
- If a decision was made → suggest creating a decision block
|
|
558
|
+
- If data models changed → suggest updating data_model blocks
|
|
559
|
+
- If a new API was added → suggest creating api_endpoint block
|
|
560
|
+
|
|
561
|
+
## Output Format
|
|
562
|
+
|
|
563
|
+
\`\`\`
|
|
564
|
+
## Context Blocks to Update
|
|
565
|
+
|
|
566
|
+
### Status Changes
|
|
567
|
+
- [ ] CONTEXT/development/tasks/[task].md → status: complete
|
|
568
|
+
- [ ] CONTEXT/product/features/[feature].md → status: complete
|
|
569
|
+
|
|
570
|
+
### New Blocks Needed
|
|
571
|
+
- [ ] Create decision block: [what was decided]
|
|
572
|
+
- [ ] Create api_endpoint block: [new endpoint]
|
|
573
|
+
|
|
574
|
+
### No Action Needed
|
|
575
|
+
- [blocks that are still accurate]
|
|
576
|
+
\`\`\`
|
|
577
|
+
|
|
578
|
+
Remind the user to run \`npx @epiccontext/mcp push\` after updates.`,
|
|
579
|
+
}),
|
|
580
|
+
});
|
|
488
581
|
// Alignment skill with workflows
|
|
489
582
|
result.skills.push({
|
|
490
583
|
path: ".claude/skills/epicontext-alignment/SKILL.md",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/skills/generator.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"generator.js","sourceRoot":"","sources":["../../src/skills/generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { DeletionEntry, DeletionManifest } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Read the deletion manifest from the CONTEXT folder.
|
|
4
|
+
* Returns an empty manifest if the file doesn't exist or is invalid.
|
|
5
|
+
*/
|
|
6
|
+
export declare function readDeletionManifest(contextPath: string): DeletionManifest;
|
|
7
|
+
/**
|
|
8
|
+
* Write the deletion manifest to the CONTEXT folder.
|
|
9
|
+
*/
|
|
10
|
+
export declare function writeDeletionManifest(contextPath: string, manifest: DeletionManifest): void;
|
|
11
|
+
/**
|
|
12
|
+
* Add a deletion entry to the manifest.
|
|
13
|
+
* Deduplicates by key+section — if an entry already exists for the same
|
|
14
|
+
* key+section, it is replaced with the new one.
|
|
15
|
+
*/
|
|
16
|
+
export declare function addDeletion(contextPath: string, entry: Omit<DeletionEntry, "deletedAt">): void;
|
|
17
|
+
/**
|
|
18
|
+
* Remove a deletion entry from the manifest (used when a block is restored).
|
|
19
|
+
*/
|
|
20
|
+
export declare function removeDeletion(contextPath: string, key: string, section: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* Remove deletion entries older than maxAgeDays.
|
|
23
|
+
* Returns the pruned manifest (does NOT write to disk — caller decides).
|
|
24
|
+
*/
|
|
25
|
+
export declare function pruneOldDeletions(manifest: DeletionManifest, maxAgeDays?: number): DeletionManifest;
|
|
26
|
+
/**
|
|
27
|
+
* Merge two deletion manifests (e.g., local + cloud).
|
|
28
|
+
* Union by key+section, keeping the entry with the most recent deletedAt.
|
|
29
|
+
*/
|
|
30
|
+
export declare function mergeDeletionManifests(local: DeletionManifest, cloud: DeletionManifest): DeletionManifest;
|
|
31
|
+
//# sourceMappingURL=deletions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deletions.d.ts","sourceRoot":"","sources":["../../src/sync/deletions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAYzE;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,GAAG,gBAAgB,CAsB1E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,gBAAgB,GACzB,IAAI,CAGN;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CACzB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,GACtC,IAAI,CAcN;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,WAAW,EAAE,MAAM,EACnB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,GACd,IAAI,CAYN;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,gBAAgB,EAC1B,UAAU,GAAE,MAA6B,GACxC,gBAAgB,CAYlB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,gBAAgB,EACvB,KAAK,EAAE,gBAAgB,GACtB,gBAAgB,CAyBlB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
const MANIFEST_FILENAME = ".deletions.json";
|
|
4
|
+
const DEFAULT_MAX_AGE_DAYS = 30;
|
|
5
|
+
/**
|
|
6
|
+
* Get the full path to the .deletions.json file
|
|
7
|
+
*/
|
|
8
|
+
function getManifestPath(contextPath) {
|
|
9
|
+
return path.join(contextPath, MANIFEST_FILENAME);
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Read the deletion manifest from the CONTEXT folder.
|
|
13
|
+
* Returns an empty manifest if the file doesn't exist or is invalid.
|
|
14
|
+
*/
|
|
15
|
+
export function readDeletionManifest(contextPath) {
|
|
16
|
+
const manifestPath = getManifestPath(contextPath);
|
|
17
|
+
try {
|
|
18
|
+
if (!fs.existsSync(manifestPath)) {
|
|
19
|
+
return { version: 1, deletions: [] };
|
|
20
|
+
}
|
|
21
|
+
const raw = fs.readFileSync(manifestPath, "utf-8");
|
|
22
|
+
const parsed = JSON.parse(raw);
|
|
23
|
+
// Validate basic structure
|
|
24
|
+
if (parsed && parsed.version === 1 && Array.isArray(parsed.deletions)) {
|
|
25
|
+
return parsed;
|
|
26
|
+
}
|
|
27
|
+
// Invalid structure, return empty
|
|
28
|
+
return { version: 1, deletions: [] };
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
// File doesn't exist or is invalid JSON
|
|
32
|
+
return { version: 1, deletions: [] };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Write the deletion manifest to the CONTEXT folder.
|
|
37
|
+
*/
|
|
38
|
+
export function writeDeletionManifest(contextPath, manifest) {
|
|
39
|
+
const manifestPath = getManifestPath(contextPath);
|
|
40
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Add a deletion entry to the manifest.
|
|
44
|
+
* Deduplicates by key+section — if an entry already exists for the same
|
|
45
|
+
* key+section, it is replaced with the new one.
|
|
46
|
+
*/
|
|
47
|
+
export function addDeletion(contextPath, entry) {
|
|
48
|
+
const manifest = readDeletionManifest(contextPath);
|
|
49
|
+
// Remove existing entry for same key+section (dedup)
|
|
50
|
+
manifest.deletions = manifest.deletions.filter((d) => !(d.key === entry.key && d.section === entry.section));
|
|
51
|
+
manifest.deletions.push({
|
|
52
|
+
...entry,
|
|
53
|
+
deletedAt: new Date().toISOString(),
|
|
54
|
+
});
|
|
55
|
+
writeDeletionManifest(contextPath, manifest);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Remove a deletion entry from the manifest (used when a block is restored).
|
|
59
|
+
*/
|
|
60
|
+
export function removeDeletion(contextPath, key, section) {
|
|
61
|
+
const manifest = readDeletionManifest(contextPath);
|
|
62
|
+
const before = manifest.deletions.length;
|
|
63
|
+
manifest.deletions = manifest.deletions.filter((d) => !(d.key === key && d.section === section));
|
|
64
|
+
// Only write if something changed
|
|
65
|
+
if (manifest.deletions.length !== before) {
|
|
66
|
+
writeDeletionManifest(contextPath, manifest);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Remove deletion entries older than maxAgeDays.
|
|
71
|
+
* Returns the pruned manifest (does NOT write to disk — caller decides).
|
|
72
|
+
*/
|
|
73
|
+
export function pruneOldDeletions(manifest, maxAgeDays = DEFAULT_MAX_AGE_DAYS) {
|
|
74
|
+
const cutoff = new Date();
|
|
75
|
+
cutoff.setDate(cutoff.getDate() - maxAgeDays);
|
|
76
|
+
const cutoffTime = cutoff.getTime();
|
|
77
|
+
return {
|
|
78
|
+
version: 1,
|
|
79
|
+
deletions: manifest.deletions.filter((d) => {
|
|
80
|
+
const deletedTime = new Date(d.deletedAt).getTime();
|
|
81
|
+
return deletedTime >= cutoffTime;
|
|
82
|
+
}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Merge two deletion manifests (e.g., local + cloud).
|
|
87
|
+
* Union by key+section, keeping the entry with the most recent deletedAt.
|
|
88
|
+
*/
|
|
89
|
+
export function mergeDeletionManifests(local, cloud) {
|
|
90
|
+
const map = new Map();
|
|
91
|
+
// Helper to create a unique key for dedup
|
|
92
|
+
const entryKey = (d) => `${d.section}:${d.key}`;
|
|
93
|
+
// Add all local entries
|
|
94
|
+
for (const entry of local.deletions) {
|
|
95
|
+
map.set(entryKey(entry), entry);
|
|
96
|
+
}
|
|
97
|
+
// Merge cloud entries — keep the one with the newer deletedAt
|
|
98
|
+
for (const entry of cloud.deletions) {
|
|
99
|
+
const key = entryKey(entry);
|
|
100
|
+
const existing = map.get(key);
|
|
101
|
+
if (!existing || new Date(entry.deletedAt) > new Date(existing.deletedAt)) {
|
|
102
|
+
map.set(key, entry);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
version: 1,
|
|
107
|
+
deletions: Array.from(map.values()),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=deletions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deletions.js","sourceRoot":"","sources":["../../src/sync/deletions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scanned file info from the local DOCUMENTS folder
|
|
3
|
+
*/
|
|
4
|
+
export interface ScannedFile {
|
|
5
|
+
/** Relative path within DOCUMENTS/, e.g., "research/user-interviews.pdf" */
|
|
6
|
+
relativePath: string;
|
|
7
|
+
/** Absolute path on disk */
|
|
8
|
+
absolutePath: string;
|
|
9
|
+
/** File size in bytes */
|
|
10
|
+
size: number;
|
|
11
|
+
/** Last modified time */
|
|
12
|
+
mtime: Date;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Recursively scan the DOCUMENTS folder for all non-hidden files
|
|
16
|
+
*/
|
|
17
|
+
export declare function scanDocumentsFolder(documentsPath: string): ScannedFile[];
|
|
18
|
+
/**
|
|
19
|
+
* Ensure the DOCUMENTS folder and manifest exist
|
|
20
|
+
*/
|
|
21
|
+
export declare function ensureDocumentsFolderExists(documentsPath: string): void;
|
|
22
|
+
/**
|
|
23
|
+
* Get a MIME type from file extension
|
|
24
|
+
*/
|
|
25
|
+
export declare function getMimeType(fileName: string): string;
|
|
26
|
+
/**
|
|
27
|
+
* Compute the local file path for a document based on its folder path and file name.
|
|
28
|
+
* e.g., folderPath="research/interviews", fileName="report.pdf" → "research/interviews/report.pdf"
|
|
29
|
+
*/
|
|
30
|
+
export declare function computeLocalPath(folderPath: string | null, fileName: string): string;
|
|
31
|
+
//# sourceMappingURL=document-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-files.d.ts","sourceRoot":"","sources":["../../src/sync/document-files.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,4EAA4E;IAC5E,YAAY,EAAE,MAAM,CAAC;IACrB,4BAA4B;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,yBAAyB;IACzB,KAAK,EAAE,IAAI,CAAC;CACb;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,aAAa,EAAE,MAAM,GAAG,WAAW,EAAE,CAqCxE;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAavE;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuBpD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,QAAQ,EAAE,MAAM,GACf,MAAM,CAKR"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Files to skip when scanning the DOCUMENTS folder
|
|
5
|
+
*/
|
|
6
|
+
const SKIP_FILES = new Set([
|
|
7
|
+
".manifest.json",
|
|
8
|
+
".ds_store",
|
|
9
|
+
"thumbs.db",
|
|
10
|
+
".gitkeep",
|
|
11
|
+
]);
|
|
12
|
+
/**
|
|
13
|
+
* Recursively scan the DOCUMENTS folder for all non-hidden files
|
|
14
|
+
*/
|
|
15
|
+
export function scanDocumentsFolder(documentsPath) {
|
|
16
|
+
const results = [];
|
|
17
|
+
function walk(dir) {
|
|
18
|
+
if (!fs.existsSync(dir))
|
|
19
|
+
return;
|
|
20
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
21
|
+
for (const entry of entries) {
|
|
22
|
+
// Skip hidden files/directories
|
|
23
|
+
if (entry.name.startsWith("."))
|
|
24
|
+
continue;
|
|
25
|
+
// Skip known system files
|
|
26
|
+
if (SKIP_FILES.has(entry.name.toLowerCase()))
|
|
27
|
+
continue;
|
|
28
|
+
const fullPath = path.join(dir, entry.name);
|
|
29
|
+
if (entry.isDirectory()) {
|
|
30
|
+
walk(fullPath);
|
|
31
|
+
}
|
|
32
|
+
else if (entry.isFile()) {
|
|
33
|
+
const stats = fs.statSync(fullPath);
|
|
34
|
+
const relativePath = path.relative(documentsPath, fullPath);
|
|
35
|
+
// Skip README.md at root level
|
|
36
|
+
if (relativePath === "README.md")
|
|
37
|
+
continue;
|
|
38
|
+
results.push({
|
|
39
|
+
relativePath,
|
|
40
|
+
absolutePath: fullPath,
|
|
41
|
+
size: stats.size,
|
|
42
|
+
mtime: stats.mtime,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
walk(documentsPath);
|
|
48
|
+
return results;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Ensure the DOCUMENTS folder and manifest exist
|
|
52
|
+
*/
|
|
53
|
+
export function ensureDocumentsFolderExists(documentsPath) {
|
|
54
|
+
if (!fs.existsSync(documentsPath)) {
|
|
55
|
+
fs.mkdirSync(documentsPath, { recursive: true });
|
|
56
|
+
}
|
|
57
|
+
const manifestPath = path.join(documentsPath, ".manifest.json");
|
|
58
|
+
if (!fs.existsSync(manifestPath)) {
|
|
59
|
+
fs.writeFileSync(manifestPath, JSON.stringify({ version: 1, lastSyncAt: null, entries: [] }, null, 2), "utf-8");
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Get a MIME type from file extension
|
|
64
|
+
*/
|
|
65
|
+
export function getMimeType(fileName) {
|
|
66
|
+
const ext = path.extname(fileName).toLowerCase();
|
|
67
|
+
const mimeMap = {
|
|
68
|
+
".pdf": "application/pdf",
|
|
69
|
+
".jpg": "image/jpeg",
|
|
70
|
+
".jpeg": "image/jpeg",
|
|
71
|
+
".png": "image/png",
|
|
72
|
+
".gif": "image/gif",
|
|
73
|
+
".webp": "image/webp",
|
|
74
|
+
".svg": "image/svg+xml",
|
|
75
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
76
|
+
".xls": "application/vnd.ms-excel",
|
|
77
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
78
|
+
".doc": "application/msword",
|
|
79
|
+
".pptx": "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
80
|
+
".ppt": "application/vnd.ms-powerpoint",
|
|
81
|
+
".txt": "text/plain",
|
|
82
|
+
".csv": "text/csv",
|
|
83
|
+
".md": "text/markdown",
|
|
84
|
+
".zip": "application/zip",
|
|
85
|
+
};
|
|
86
|
+
return mimeMap[ext] || "application/octet-stream";
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Compute the local file path for a document based on its folder path and file name.
|
|
90
|
+
* e.g., folderPath="research/interviews", fileName="report.pdf" → "research/interviews/report.pdf"
|
|
91
|
+
*/
|
|
92
|
+
export function computeLocalPath(folderPath, fileName) {
|
|
93
|
+
if (folderPath) {
|
|
94
|
+
return path.join(folderPath, fileName);
|
|
95
|
+
}
|
|
96
|
+
return fileName;
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=document-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-files.js","sourceRoot":"","sources":["../../src/sync/document-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { DocumentManifest, DocumentManifestEntry } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* Read the document manifest from the DOCUMENTS folder
|
|
4
|
+
*/
|
|
5
|
+
export declare function readDocumentManifest(documentsPath: string): DocumentManifest;
|
|
6
|
+
/**
|
|
7
|
+
* Write the document manifest to the DOCUMENTS folder
|
|
8
|
+
*/
|
|
9
|
+
export declare function writeDocumentManifest(documentsPath: string, manifest: DocumentManifest): void;
|
|
10
|
+
/**
|
|
11
|
+
* Update a single entry in the manifest (upsert by document ID)
|
|
12
|
+
*/
|
|
13
|
+
export declare function updateManifestEntry(documentsPath: string, entry: DocumentManifestEntry): void;
|
|
14
|
+
/**
|
|
15
|
+
* Remove an entry from the manifest by document ID
|
|
16
|
+
*/
|
|
17
|
+
export declare function removeManifestEntry(documentsPath: string, documentId: string): void;
|
|
18
|
+
/**
|
|
19
|
+
* Find a manifest entry by local path
|
|
20
|
+
*/
|
|
21
|
+
export declare function findEntryByLocalPath(manifest: DocumentManifest, localPath: string): DocumentManifestEntry | undefined;
|
|
22
|
+
//# sourceMappingURL=document-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-manifest.d.ts","sourceRoot":"","sources":["../../src/sync/document-manifest.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAIjF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,MAAM,GAAG,gBAAgB,CAa5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,gBAAgB,GACzB,IAAI,CAGN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,qBAAqB,GAC3B,IAAI,CAWN;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,MAAM,GACjB,IAAI,CAIN;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,gBAAgB,EAC1B,SAAS,EAAE,MAAM,GAChB,qBAAqB,GAAG,SAAS,CAEnC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
const MANIFEST_FILENAME = ".manifest.json";
|
|
4
|
+
/**
|
|
5
|
+
* Read the document manifest from the DOCUMENTS folder
|
|
6
|
+
*/
|
|
7
|
+
export function readDocumentManifest(documentsPath) {
|
|
8
|
+
const manifestPath = path.join(documentsPath, MANIFEST_FILENAME);
|
|
9
|
+
if (!fs.existsSync(manifestPath)) {
|
|
10
|
+
return { version: 1, lastSyncAt: null, entries: [] };
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const content = fs.readFileSync(manifestPath, "utf-8");
|
|
14
|
+
return JSON.parse(content);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return { version: 1, lastSyncAt: null, entries: [] };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Write the document manifest to the DOCUMENTS folder
|
|
22
|
+
*/
|
|
23
|
+
export function writeDocumentManifest(documentsPath, manifest) {
|
|
24
|
+
const manifestPath = path.join(documentsPath, MANIFEST_FILENAME);
|
|
25
|
+
fs.writeFileSync(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Update a single entry in the manifest (upsert by document ID)
|
|
29
|
+
*/
|
|
30
|
+
export function updateManifestEntry(documentsPath, entry) {
|
|
31
|
+
const manifest = readDocumentManifest(documentsPath);
|
|
32
|
+
const idx = manifest.entries.findIndex((e) => e.id === entry.id);
|
|
33
|
+
if (idx >= 0) {
|
|
34
|
+
manifest.entries[idx] = entry;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
manifest.entries.push(entry);
|
|
38
|
+
}
|
|
39
|
+
writeDocumentManifest(documentsPath, manifest);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Remove an entry from the manifest by document ID
|
|
43
|
+
*/
|
|
44
|
+
export function removeManifestEntry(documentsPath, documentId) {
|
|
45
|
+
const manifest = readDocumentManifest(documentsPath);
|
|
46
|
+
manifest.entries = manifest.entries.filter((e) => e.id !== documentId);
|
|
47
|
+
writeDocumentManifest(documentsPath, manifest);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Find a manifest entry by local path
|
|
51
|
+
*/
|
|
52
|
+
export function findEntryByLocalPath(manifest, localPath) {
|
|
53
|
+
return manifest.entries.find((e) => e.localPath === localPath);
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=document-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-manifest.js","sourceRoot":"","sources":["../../src/sync/document-manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAG7B,MAAM,iBAAiB,GAAG,gBAAgB,CAAC;AAE3C;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,aAAqB;IACxD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;IAEjE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAqB,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;IACvD,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CACnC,aAAqB,EACrB,QAA0B;IAE1B,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;IACjE,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AAC7E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,aAAqB,EACrB,KAA4B;IAE5B,MAAM,QAAQ,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;IACrD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;IAEjE,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC;QACb,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED,qBAAqB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CACjC,aAAqB,EACrB,UAAkB;IAElB,MAAM,QAAQ,GAAG,oBAAoB,CAAC,aAAa,CAAC,CAAC;IACrD,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU,CAAC,CAAC;IACvE,qBAAqB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA0B,EAC1B,SAAiB;IAEjB,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC;AACjE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { EpicContextClient } from "../api/client.js";
|
|
2
|
+
import type { DocumentSyncResult } from "../types/index.js";
|
|
3
|
+
export interface DocumentPullOptions {
|
|
4
|
+
/** Overwrite local files even if they are newer */
|
|
5
|
+
force?: boolean;
|
|
6
|
+
/** Skip files larger than this (bytes) */
|
|
7
|
+
maxFileSize?: number;
|
|
8
|
+
/** Preview changes without downloading */
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Pull documents from the cloud to the local DOCUMENTS folder.
|
|
13
|
+
* Only downloads new or updated files (delta sync based on timestamps).
|
|
14
|
+
*/
|
|
15
|
+
export declare function pullDocuments(client: EpicContextClient, documentsPath: string, options?: DocumentPullOptions): Promise<DocumentSyncResult>;
|
|
16
|
+
//# sourceMappingURL=document-pull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document-pull.d.ts","sourceRoot":"","sources":["../../src/sync/document-pull.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAEV,kBAAkB,EAEnB,MAAM,mBAAmB,CAAC;AAI3B,MAAM,WAAW,mBAAmB;IAClC,mDAAmD;IACnD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,0CAA0C;IAC1C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0CAA0C;IAC1C,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA+I7B"}
|