mcp-context-sync 1.0.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 +85 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.js +255 -0
- package/dist/cli.js.map +1 -0
- package/dist/db/connection.d.ts +3 -0
- package/dist/db/connection.js +44 -0
- package/dist/db/connection.js.map +1 -0
- package/dist/db/queries.d.ts +23 -0
- package/dist/db/queries.js +121 -0
- package/dist/db/queries.js.map +1 -0
- package/dist/db/schema.d.ts +2 -0
- package/dist/db/schema.js +103 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/project-id.d.ts +13 -0
- package/dist/lib/project-id.js +27 -0
- package/dist/lib/project-id.js.map +1 -0
- package/dist/lib/snapshot-renderer.d.ts +9 -0
- package/dist/lib/snapshot-renderer.js +77 -0
- package/dist/lib/snapshot-renderer.js.map +1 -0
- package/dist/lib/types.d.ts +290 -0
- package/dist/lib/types.js +122 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/uuid.d.ts +1 -0
- package/dist/lib/uuid.js +5 -0
- package/dist/lib/uuid.js.map +1 -0
- package/dist/lib/validation.d.ts +18 -0
- package/dist/lib/validation.js +63 -0
- package/dist/lib/validation.js.map +1 -0
- package/dist/prompts/auto-resume.d.ts +3 -0
- package/dist/prompts/auto-resume.js +70 -0
- package/dist/prompts/auto-resume.js.map +1 -0
- package/dist/prompts/resume-work.d.ts +2 -0
- package/dist/prompts/resume-work.js +29 -0
- package/dist/prompts/resume-work.js.map +1 -0
- package/dist/prompts/sync-session.d.ts +2 -0
- package/dist/prompts/sync-session.js +33 -0
- package/dist/prompts/sync-session.js.map +1 -0
- package/dist/resources/project-decisions.d.ts +3 -0
- package/dist/resources/project-decisions.js +69 -0
- package/dist/resources/project-decisions.js.map +1 -0
- package/dist/resources/project-snapshot.d.ts +3 -0
- package/dist/resources/project-snapshot.js +49 -0
- package/dist/resources/project-snapshot.js.map +1 -0
- package/dist/resources/status.d.ts +3 -0
- package/dist/resources/status.js +25 -0
- package/dist/resources/status.js.map +1 -0
- package/dist/tools/amend-snapshot.d.ts +3 -0
- package/dist/tools/amend-snapshot.js +126 -0
- package/dist/tools/amend-snapshot.js.map +1 -0
- package/dist/tools/get-history.d.ts +3 -0
- package/dist/tools/get-history.js +58 -0
- package/dist/tools/get-history.js.map +1 -0
- package/dist/tools/list-projects.d.ts +3 -0
- package/dist/tools/list-projects.js +40 -0
- package/dist/tools/list-projects.js.map +1 -0
- package/dist/tools/log-decision.d.ts +3 -0
- package/dist/tools/log-decision.js +46 -0
- package/dist/tools/log-decision.js.map +1 -0
- package/dist/tools/resume.d.ts +3 -0
- package/dist/tools/resume.js +113 -0
- package/dist/tools/resume.js.map +1 -0
- package/dist/tools/search-snapshots.d.ts +3 -0
- package/dist/tools/search-snapshots.js +71 -0
- package/dist/tools/search-snapshots.js.map +1 -0
- package/dist/tools/sync.d.ts +3 -0
- package/dist/tools/sync.js +102 -0
- package/dist/tools/sync.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
// Agent identifiers
|
|
3
|
+
export const AgentEnum = z.enum([
|
|
4
|
+
'claude-code',
|
|
5
|
+
'codex',
|
|
6
|
+
'gemini-cli',
|
|
7
|
+
'cursor',
|
|
8
|
+
'cline',
|
|
9
|
+
'amp',
|
|
10
|
+
'other',
|
|
11
|
+
]);
|
|
12
|
+
// Decision schema
|
|
13
|
+
export const DecisionSchema = z.object({
|
|
14
|
+
decision: z.string().describe('What was decided'),
|
|
15
|
+
reasoning: z.string().describe('Why this decision was made'),
|
|
16
|
+
alternatives: z
|
|
17
|
+
.array(z.string())
|
|
18
|
+
.optional()
|
|
19
|
+
.describe('Alternatives considered and rejected'),
|
|
20
|
+
});
|
|
21
|
+
// File modification schema
|
|
22
|
+
export const FileModSchema = z.object({
|
|
23
|
+
path: z.string().describe('Relative path from project root'),
|
|
24
|
+
action: z.enum(['created', 'modified', 'deleted', 'renamed']),
|
|
25
|
+
description: z.string().describe('What changed and why'),
|
|
26
|
+
});
|
|
27
|
+
// Decision category
|
|
28
|
+
export const DecisionCategoryEnum = z.enum([
|
|
29
|
+
'architecture',
|
|
30
|
+
'dependency',
|
|
31
|
+
'api-design',
|
|
32
|
+
'data-model',
|
|
33
|
+
'tooling',
|
|
34
|
+
'testing',
|
|
35
|
+
'deployment',
|
|
36
|
+
'other',
|
|
37
|
+
]);
|
|
38
|
+
// --- Tool input schemas ---
|
|
39
|
+
export const SyncInputSchema = z.object({
|
|
40
|
+
projectDir: z.string().describe('Absolute path to the project root directory'),
|
|
41
|
+
agent: AgentEnum.describe('Which agent is creating this snapshot'),
|
|
42
|
+
summary: z
|
|
43
|
+
.string()
|
|
44
|
+
.describe('1-3 sentence summary of what was accomplished'),
|
|
45
|
+
tasksCompleted: z
|
|
46
|
+
.array(z.string())
|
|
47
|
+
.describe('Tasks completed in this session'),
|
|
48
|
+
tasksRemaining: z
|
|
49
|
+
.array(z.string())
|
|
50
|
+
.describe('Tasks still pending or blocked'),
|
|
51
|
+
decisions: z
|
|
52
|
+
.array(DecisionSchema)
|
|
53
|
+
.optional()
|
|
54
|
+
.describe('Key decisions made'),
|
|
55
|
+
filesModified: z
|
|
56
|
+
.array(FileModSchema)
|
|
57
|
+
.optional()
|
|
58
|
+
.describe('Files changed in this session'),
|
|
59
|
+
blockers: z
|
|
60
|
+
.array(z.string())
|
|
61
|
+
.optional()
|
|
62
|
+
.describe('Issues blocking progress'),
|
|
63
|
+
nextSteps: z
|
|
64
|
+
.string()
|
|
65
|
+
.describe('What the next agent should do first -- be specific'),
|
|
66
|
+
tags: z
|
|
67
|
+
.array(z.string())
|
|
68
|
+
.optional()
|
|
69
|
+
.describe('Freeform tags, e.g. ["refactor", "feature:auth"]'),
|
|
70
|
+
});
|
|
71
|
+
export const ResumeInputSchema = z.object({
|
|
72
|
+
projectDir: z.string().describe('Absolute path to the project root directory'),
|
|
73
|
+
agent: AgentEnum.describe('Which agent is resuming work'),
|
|
74
|
+
snapshotId: z
|
|
75
|
+
.string()
|
|
76
|
+
.optional()
|
|
77
|
+
.describe('Specific snapshot ID. Omit for latest.'),
|
|
78
|
+
});
|
|
79
|
+
export const LogDecisionInputSchema = z.object({
|
|
80
|
+
projectDir: z.string().describe('Absolute path to the project root directory'),
|
|
81
|
+
agent: AgentEnum,
|
|
82
|
+
decision: z.string().describe('What was decided'),
|
|
83
|
+
reasoning: z.string().describe('Why this was chosen'),
|
|
84
|
+
alternatives: z.array(z.string()).optional(),
|
|
85
|
+
category: DecisionCategoryEnum.optional(),
|
|
86
|
+
relatedFiles: z.array(z.string()).optional(),
|
|
87
|
+
});
|
|
88
|
+
export const GetHistoryInputSchema = z.object({
|
|
89
|
+
projectDir: z.string().describe('Absolute path to the project root directory'),
|
|
90
|
+
limit: z.number().optional().default(10),
|
|
91
|
+
agentFilter: AgentEnum.or(z.literal('all')).optional().default('all'),
|
|
92
|
+
includeDecisions: z.boolean().optional().default(true),
|
|
93
|
+
});
|
|
94
|
+
export const ListProjectsInputSchema = z.object({});
|
|
95
|
+
export const SearchSnapshotsInputSchema = z.object({
|
|
96
|
+
projectDir: z
|
|
97
|
+
.string()
|
|
98
|
+
.optional()
|
|
99
|
+
.describe('Limit to one project. Omit for all.'),
|
|
100
|
+
query: z
|
|
101
|
+
.string()
|
|
102
|
+
.optional()
|
|
103
|
+
.describe('Full-text search across summaries, decisions, next steps'),
|
|
104
|
+
tags: z.array(z.string()).optional(),
|
|
105
|
+
agent: AgentEnum.optional(),
|
|
106
|
+
since: z.string().optional().describe('ISO 8601 datetime'),
|
|
107
|
+
until: z.string().optional().describe('ISO 8601 datetime'),
|
|
108
|
+
limit: z.number().optional().default(20),
|
|
109
|
+
});
|
|
110
|
+
export const AmendSnapshotInputSchema = z.object({
|
|
111
|
+
projectDir: z.string(),
|
|
112
|
+
agent: AgentEnum,
|
|
113
|
+
addTasksCompleted: z.array(z.string()).optional(),
|
|
114
|
+
addTasksRemaining: z.array(z.string()).optional(),
|
|
115
|
+
removeTasksRemaining: z.array(z.string()).optional(),
|
|
116
|
+
addDecisions: z.array(DecisionSchema).optional(),
|
|
117
|
+
updateNextSteps: z.string().optional(),
|
|
118
|
+
addBlockers: z.array(z.string()).optional(),
|
|
119
|
+
removeBlockers: z.array(z.string()).optional(),
|
|
120
|
+
addTags: z.array(z.string()).optional(),
|
|
121
|
+
});
|
|
122
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function generateId(): string;
|
package/dist/lib/uuid.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"uuid.js","sourceRoot":"","sources":["../../src/lib/uuid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,UAAU;IACxB,OAAO,UAAU,EAAE,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export interface PathValidationResult {
|
|
2
|
+
isValid: boolean;
|
|
3
|
+
normalized: string;
|
|
4
|
+
warnings: string[];
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Validates a project directory path. Only warns about things that
|
|
8
|
+
* actually cause problems — not cosmetic issues that normalization handles.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateProjectDir(rawPath: string): PathValidationResult;
|
|
11
|
+
/**
|
|
12
|
+
* Suggests the parent path if the given path ends with a known subdirectory.
|
|
13
|
+
*/
|
|
14
|
+
export declare function suggestProjectRoot(rawPath: string): string | null;
|
|
15
|
+
/**
|
|
16
|
+
* Formats warnings as a markdown block. Returns empty string if none.
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatWarnings(result: PathValidationResult): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { isAbsolute } from 'node:path';
|
|
2
|
+
import { normalizePath } from './project-id.js';
|
|
3
|
+
/**
|
|
4
|
+
* Validates a project directory path. Only warns about things that
|
|
5
|
+
* actually cause problems — not cosmetic issues that normalization handles.
|
|
6
|
+
*/
|
|
7
|
+
export function validateProjectDir(rawPath) {
|
|
8
|
+
const warnings = [];
|
|
9
|
+
const normalized = normalizePath(rawPath);
|
|
10
|
+
if (!isAbsolute(rawPath)) {
|
|
11
|
+
warnings.push('Path is relative. Use an absolute path (e.g., C:/Users/... or /home/...).');
|
|
12
|
+
}
|
|
13
|
+
if (rawPath.includes('..')) {
|
|
14
|
+
warnings.push('Path contains ".." references. Use a resolved absolute path.');
|
|
15
|
+
}
|
|
16
|
+
const segments = normalized.split('/').filter(Boolean);
|
|
17
|
+
if (segments.length < 2) {
|
|
18
|
+
warnings.push('Path is very short — might be a drive letter or root, not a project directory.');
|
|
19
|
+
}
|
|
20
|
+
const subdirHint = detectSubdirectory(normalized);
|
|
21
|
+
if (subdirHint) {
|
|
22
|
+
warnings.push(`Path ends with \`/${subdirHint}\`, which looks like a subdirectory. ` +
|
|
23
|
+
`Use the project root instead.`);
|
|
24
|
+
}
|
|
25
|
+
return { isValid: warnings.length === 0, normalized, warnings };
|
|
26
|
+
}
|
|
27
|
+
// Subdirectory suffixes that usually indicate "not the project root"
|
|
28
|
+
const SUBDIR_NAMES = new Set([
|
|
29
|
+
'src', 'dist', 'build', 'out', 'node_modules',
|
|
30
|
+
'.git', 'test', 'tests', 'lib', 'bin', 'packages',
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Returns the trailing segment name if it looks like a common subdirectory,
|
|
34
|
+
* or null if the path appears to be a project root.
|
|
35
|
+
*/
|
|
36
|
+
function detectSubdirectory(normalizedPath) {
|
|
37
|
+
const lastSlash = normalizedPath.lastIndexOf('/');
|
|
38
|
+
if (lastSlash < 0)
|
|
39
|
+
return null;
|
|
40
|
+
const tail = normalizedPath.slice(lastSlash + 1);
|
|
41
|
+
return SUBDIR_NAMES.has(tail) ? tail : null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Suggests the parent path if the given path ends with a known subdirectory.
|
|
45
|
+
*/
|
|
46
|
+
export function suggestProjectRoot(rawPath) {
|
|
47
|
+
const normalized = normalizePath(rawPath);
|
|
48
|
+
const tail = detectSubdirectory(normalized);
|
|
49
|
+
if (!tail)
|
|
50
|
+
return null;
|
|
51
|
+
const parent = normalized.slice(0, -(tail.length + 1)); // +1 for the slash
|
|
52
|
+
return parent.length > 0 ? parent : null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Formats warnings as a markdown block. Returns empty string if none.
|
|
56
|
+
*/
|
|
57
|
+
export function formatWarnings(result) {
|
|
58
|
+
if (result.warnings.length === 0)
|
|
59
|
+
return '';
|
|
60
|
+
return ('**Path warnings:**\n' +
|
|
61
|
+
result.warnings.map((w) => `- ${w}`).join('\n'));
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sourceRoot":"","sources":["../../src/lib/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAQhD;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAE1C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CAAC,2EAA2E,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,QAAQ,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;IAChF,CAAC;IAED,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,IAAI,CAAC,gFAAgF,CAAC,CAAC;IAClG,CAAC;IAED,MAAM,UAAU,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,UAAU,EAAE,CAAC;QACf,QAAQ,CAAC,IAAI,CACX,qBAAqB,UAAU,uCAAuC;YACtE,+BAA+B,CAChC,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;AAClE,CAAC;AAED,qEAAqE;AACrE,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc;IAC7C,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU;CAClD,CAAC,CAAC;AAEH;;;GAGG;AACH,SAAS,kBAAkB,CAAC,cAAsB;IAChD,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClD,IAAI,SAAS,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC;IACjD,OAAO,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,kBAAkB,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IACvB,MAAM,MAAM,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,mBAAmB;IAC3E,OAAO,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;AAC3C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAA4B;IACzD,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,OAAO,CACL,sBAAsB;QACtB,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAChD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { projectIdFromPath, displayNameFromPath } from '../lib/project-id.js';
|
|
3
|
+
import { getProject, getLatestSnapshot, listProjects } from '../db/queries.js';
|
|
4
|
+
export function registerAutoResumePrompt(server, db) {
|
|
5
|
+
server.registerPrompt('auto-resume', {
|
|
6
|
+
title: 'Auto-Resume Context',
|
|
7
|
+
description: 'Check for existing context when opening a project. ' +
|
|
8
|
+
'Returns a concise summary or confirms fresh start.',
|
|
9
|
+
argsSchema: {
|
|
10
|
+
projectDir: z.string().describe('Absolute path to the project root directory'),
|
|
11
|
+
agent: z.string().describe('Current agent name (e.g., "claude-code", "codex", "gemini-cli")'),
|
|
12
|
+
},
|
|
13
|
+
}, ({ projectDir, agent }) => {
|
|
14
|
+
const projectId = projectIdFromPath(projectDir);
|
|
15
|
+
const displayName = displayNameFromPath(projectDir);
|
|
16
|
+
const project = getProject(db, projectId);
|
|
17
|
+
// No previous context
|
|
18
|
+
if (!project) {
|
|
19
|
+
const otherCount = listProjects(db).length;
|
|
20
|
+
const note = otherCount > 0
|
|
21
|
+
? `\n\n${otherCount} other project(s) have synced context. Use \`list-projects\` to see them.`
|
|
22
|
+
: '';
|
|
23
|
+
return {
|
|
24
|
+
messages: [
|
|
25
|
+
{ role: 'user', content: { type: 'text', text: `Starting work on \`${projectDir}\`.` } },
|
|
26
|
+
{ role: 'assistant', content: { type: 'text', text: `**Fresh start** — no previous context for "${displayName}".${note}\n\n` +
|
|
27
|
+
`When done, use the \`sync\` tool to save progress for future sessions.`, } },
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
const snapshot = getLatestSnapshot(db, projectId);
|
|
32
|
+
if (!snapshot) {
|
|
33
|
+
return {
|
|
34
|
+
messages: [
|
|
35
|
+
{ role: 'user', content: { type: 'text', text: `Starting work on "${displayName}".` } },
|
|
36
|
+
{ role: 'assistant', content: { type: 'text', text: `Project "${displayName}" exists but has no snapshots. Use \`sync\` to create one.`, } },
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// Build concise summary
|
|
41
|
+
const remaining = JSON.parse(snapshot.tasks_remaining);
|
|
42
|
+
const decisions = JSON.parse(snapshot.decisions);
|
|
43
|
+
const lines = [
|
|
44
|
+
`**Resuming: ${displayName}**`,
|
|
45
|
+
'',
|
|
46
|
+
`Last session by **${snapshot.agent}** on ${snapshot.created_at.slice(0, 10)}` +
|
|
47
|
+
` (snapshot #${snapshot.sequence_number}, ${project.handoff_count} handoffs)`,
|
|
48
|
+
'',
|
|
49
|
+
`> ${snapshot.summary}`,
|
|
50
|
+
];
|
|
51
|
+
if (remaining.length > 0) {
|
|
52
|
+
lines.push('', `**Pending (${remaining.length}):**`);
|
|
53
|
+
for (const t of remaining.slice(0, 4))
|
|
54
|
+
lines.push(`- ${t}`);
|
|
55
|
+
if (remaining.length > 4)
|
|
56
|
+
lines.push(`- ...and ${remaining.length - 4} more`);
|
|
57
|
+
}
|
|
58
|
+
if (decisions.length > 0) {
|
|
59
|
+
lines.push('', `**Last decision:** ${decisions[decisions.length - 1].decision}`);
|
|
60
|
+
}
|
|
61
|
+
lines.push('', `Use \`resume\` with \`projectDir: "${projectDir}"\` and \`agent: "${agent}"\` to load the full snapshot and register the handoff.`);
|
|
62
|
+
return {
|
|
63
|
+
messages: [
|
|
64
|
+
{ role: 'user', content: { type: 'text', text: `Continuing work on \`${projectDir}\`. Load previous context.` } },
|
|
65
|
+
{ role: 'assistant', content: { type: 'text', text: lines.join('\n') } },
|
|
66
|
+
],
|
|
67
|
+
};
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=auto-resume.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-resume.js","sourceRoot":"","sources":["../../src/prompts/auto-resume.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerResumeWorkPrompt(server) {
|
|
3
|
+
server.registerPrompt('resume-work', {
|
|
4
|
+
title: 'Resume Previous Work',
|
|
5
|
+
description: 'Load the latest snapshot and orient for continuing work on a project.',
|
|
6
|
+
argsSchema: {
|
|
7
|
+
projectDir: z.string().describe('Project root directory'),
|
|
8
|
+
agent: z.string().describe('Current agent name'),
|
|
9
|
+
},
|
|
10
|
+
}, ({ projectDir, agent }) => ({
|
|
11
|
+
messages: [
|
|
12
|
+
{
|
|
13
|
+
role: 'user',
|
|
14
|
+
content: {
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: `I'm switching to you (${agent}) to continue work on "${projectDir}".
|
|
17
|
+
|
|
18
|
+
Please call the "resume" tool to load the latest context snapshot, then:
|
|
19
|
+
1. Read the snapshot carefully
|
|
20
|
+
2. Summarize what the previous agent accomplished
|
|
21
|
+
3. Note any key decisions and blockers
|
|
22
|
+
4. Confirm the next steps
|
|
23
|
+
5. Ask me if I want to proceed with the suggested next steps or do something different`,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
}));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=resume-work.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resume-work.js","sourceRoot":"","sources":["../../src/prompts/resume-work.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,wBAAwB,CAAC,MAAiB;IACxD,MAAM,CAAC,cAAc,CACnB,aAAa,EACb;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,uEAAuE;QACzE,UAAU,EAAE;YACV,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YACzD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;SACjD;KACF,EACD,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,yBAAyB,KAAK,0BAA0B,UAAU;;;;;;;uFAOG;iBAC5E;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export function registerSyncSessionPrompt(server) {
|
|
3
|
+
server.registerPrompt('sync-session', {
|
|
4
|
+
title: 'Sync Current Session',
|
|
5
|
+
description: 'Guided prompt to capture a complete context snapshot for handoff to another agent.',
|
|
6
|
+
argsSchema: {
|
|
7
|
+
projectDir: z.string().describe('Project root directory'),
|
|
8
|
+
agent: z.string().describe('Current agent name'),
|
|
9
|
+
},
|
|
10
|
+
}, ({ projectDir, agent }) => ({
|
|
11
|
+
messages: [
|
|
12
|
+
{
|
|
13
|
+
role: 'user',
|
|
14
|
+
content: {
|
|
15
|
+
type: 'text',
|
|
16
|
+
text: `You are about to sync your work session on project at "${projectDir}" as agent "${agent}".
|
|
17
|
+
|
|
18
|
+
Please call the "sync" tool with a structured snapshot of your current session. Include:
|
|
19
|
+
1. A concise summary of what you accomplished
|
|
20
|
+
2. All tasks you completed (be specific)
|
|
21
|
+
3. All tasks still remaining or blocked
|
|
22
|
+
4. Any key decisions you made and WHY
|
|
23
|
+
5. Files you created or modified
|
|
24
|
+
6. Any blockers another agent should know about
|
|
25
|
+
7. Specific, actionable next steps -- what should the next agent do FIRST?
|
|
26
|
+
|
|
27
|
+
Be concrete and specific. The next agent has NO context about your conversation -- they will only see this snapshot.`,
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
],
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=sync-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-session.js","sourceRoot":"","sources":["../../src/prompts/sync-session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,cAAc,CACnB,cAAc,EACd;QACE,KAAK,EAAE,sBAAsB;QAC7B,WAAW,EACT,oFAAoF;QACtF,UAAU,EAAE;YACV,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YACzD,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oBAAoB,CAAC;SACjD;KACF,EACD,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC1B,QAAQ,EAAE;YACR;gBACE,IAAI,EAAE,MAAe;gBACrB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,0DAA0D,UAAU,eAAe,KAAK;;;;;;;;;;;qHAWW;iBAC1G;aACF;SACF;KACF,CAAC,CACH,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { listProjects, getDecisionsByProject } from '../db/queries.js';
|
|
3
|
+
export function registerProjectDecisionsResource(server, db) {
|
|
4
|
+
server.registerResource('project-decisions', new ResourceTemplate('context-sync://project/{projectId}/decisions', {
|
|
5
|
+
list: async () => {
|
|
6
|
+
const projects = listProjects(db);
|
|
7
|
+
return {
|
|
8
|
+
resources: projects.map((p) => ({
|
|
9
|
+
uri: `context-sync://project/${p.id}/decisions`,
|
|
10
|
+
name: `${p.display_name} - Decision Log`,
|
|
11
|
+
description: `All recorded decisions for ${p.display_name}`,
|
|
12
|
+
mimeType: 'text/markdown',
|
|
13
|
+
})),
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
}), {
|
|
17
|
+
title: 'Project Decision Log',
|
|
18
|
+
description: 'All recorded architectural and implementation decisions for a project',
|
|
19
|
+
mimeType: 'text/markdown',
|
|
20
|
+
}, async (uri, { projectId }) => {
|
|
21
|
+
const pid = projectId;
|
|
22
|
+
const decisions = getDecisionsByProject(db, pid);
|
|
23
|
+
if (decisions.length === 0) {
|
|
24
|
+
return {
|
|
25
|
+
contents: [
|
|
26
|
+
{
|
|
27
|
+
uri: uri.href,
|
|
28
|
+
mimeType: 'text/plain',
|
|
29
|
+
text: 'No decisions recorded for this project.',
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const projects = listProjects(db);
|
|
35
|
+
const project = projects.find((p) => p.id === pid);
|
|
36
|
+
const displayName = project?.display_name ?? pid;
|
|
37
|
+
const lines = [
|
|
38
|
+
`# Decision Log: ${displayName}`,
|
|
39
|
+
'',
|
|
40
|
+
];
|
|
41
|
+
for (const d of decisions) {
|
|
42
|
+
lines.push(`## ${d.decision}`);
|
|
43
|
+
lines.push(`- **Agent:** ${d.agent}`);
|
|
44
|
+
lines.push(`- **Date:** ${d.created_at}`);
|
|
45
|
+
if (d.category)
|
|
46
|
+
lines.push(`- **Category:** ${d.category}`);
|
|
47
|
+
lines.push(`- **Reasoning:** ${d.reasoning}`);
|
|
48
|
+
const alts = JSON.parse(d.alternatives);
|
|
49
|
+
if (alts.length > 0) {
|
|
50
|
+
lines.push(`- **Rejected:** ${alts.join(', ')}`);
|
|
51
|
+
}
|
|
52
|
+
const files = JSON.parse(d.related_files);
|
|
53
|
+
if (files.length > 0) {
|
|
54
|
+
lines.push(`- **Files:** ${files.map((f) => `\`${f}\``).join(', ')}`);
|
|
55
|
+
}
|
|
56
|
+
lines.push('');
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
contents: [
|
|
60
|
+
{
|
|
61
|
+
uri: uri.href,
|
|
62
|
+
mimeType: 'text/markdown',
|
|
63
|
+
text: lines.join('\n'),
|
|
64
|
+
},
|
|
65
|
+
],
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=project-decisions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-decisions.js","sourceRoot":"","sources":["../../src/resources/project-decisions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import { listProjects, getLatestSnapshot, } from '../db/queries.js';
|
|
3
|
+
import { renderSnapshotMarkdown } from '../lib/snapshot-renderer.js';
|
|
4
|
+
export function registerProjectSnapshotResource(server, db) {
|
|
5
|
+
server.registerResource('project-snapshot', new ResourceTemplate('context-sync://project/{projectId}/latest', {
|
|
6
|
+
list: async () => {
|
|
7
|
+
const projects = listProjects(db);
|
|
8
|
+
return {
|
|
9
|
+
resources: projects.map((p) => ({
|
|
10
|
+
uri: `context-sync://project/${p.id}/latest`,
|
|
11
|
+
name: `${p.display_name} - Latest Snapshot`,
|
|
12
|
+
description: `Most recent context snapshot for ${p.display_name}`,
|
|
13
|
+
mimeType: 'text/markdown',
|
|
14
|
+
})),
|
|
15
|
+
};
|
|
16
|
+
},
|
|
17
|
+
}), {
|
|
18
|
+
title: 'Latest Project Snapshot',
|
|
19
|
+
description: 'The most recent context snapshot for a specific project',
|
|
20
|
+
mimeType: 'text/markdown',
|
|
21
|
+
}, async (uri, { projectId }) => {
|
|
22
|
+
const pid = projectId;
|
|
23
|
+
const snapshot = getLatestSnapshot(db, pid);
|
|
24
|
+
if (!snapshot) {
|
|
25
|
+
return {
|
|
26
|
+
contents: [
|
|
27
|
+
{
|
|
28
|
+
uri: uri.href,
|
|
29
|
+
mimeType: 'text/plain',
|
|
30
|
+
text: 'No snapshots found for this project.',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const projects = listProjects(db);
|
|
36
|
+
const project = projects.find((p) => p.id === pid);
|
|
37
|
+
const displayName = project?.display_name ?? pid;
|
|
38
|
+
return {
|
|
39
|
+
contents: [
|
|
40
|
+
{
|
|
41
|
+
uri: uri.href,
|
|
42
|
+
mimeType: 'text/markdown',
|
|
43
|
+
text: renderSnapshotMarkdown(snapshot, displayName),
|
|
44
|
+
},
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=project-snapshot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project-snapshot.js","sourceRoot":"","sources":["../../src/resources/project-snapshot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAkB,MAAM,yCAAyC,CAAC;AAE3F,OAAO,EACL,YAAY,EACZ,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAErE,MAAM,UAAU,+BAA+B,CAC7C,MAAiB,EACjB,EAAqB;IAErB,MAAM,CAAC,gBAAgB,CACrB,kBAAkB,EAClB,IAAI,gBAAgB,CAAC,2CAA2C,EAAE;QAChE,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;YAClC,OAAO;gBACL,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;oBAC9B,GAAG,EAAE,0BAA0B,CAAC,CAAC,EAAE,SAAS;oBAC5C,IAAI,EAAE,GAAG,CAAC,CAAC,YAAY,oBAAoB;oBAC3C,WAAW,EAAE,oCAAoC,CAAC,CAAC,YAAY,EAAE;oBACjE,QAAQ,EAAE,eAAwB;iBACnC,CAAC,CAAC;aACJ,CAAC;QACJ,CAAC;KACF,CAAC,EACF;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EAAE,yDAAyD;QACtE,QAAQ,EAAE,eAAe;KAC1B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC3B,MAAM,GAAG,GAAG,SAAmB,CAAC;QAChC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAE5C,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO;gBACL,QAAQ,EAAE;oBACR;wBACE,GAAG,EAAE,GAAG,CAAC,IAAI;wBACb,QAAQ,EAAE,YAAY;wBACtB,IAAI,EAAE,sCAAsC;qBAC7C;iBACF;aACF,CAAC;QACJ,CAAC;QAED,MAAM,QAAQ,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC;QACnD,MAAM,WAAW,GAAG,OAAO,EAAE,YAAY,IAAI,GAAG,CAAC;QAEjD,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,eAAe;oBACzB,IAAI,EAAE,sBAAsB,CAAC,QAAQ,EAAE,WAAW,CAAC;iBACpD;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { getTotalCounts } from '../db/queries.js';
|
|
2
|
+
export function registerStatusResource(server, db) {
|
|
3
|
+
server.registerResource('server-status', 'context-sync://status', {
|
|
4
|
+
title: 'Context Sync Server Status',
|
|
5
|
+
description: 'Server version, total projects, snapshots, and handoffs',
|
|
6
|
+
mimeType: 'application/json',
|
|
7
|
+
}, async (uri) => {
|
|
8
|
+
const counts = getTotalCounts(db);
|
|
9
|
+
return {
|
|
10
|
+
contents: [
|
|
11
|
+
{
|
|
12
|
+
uri: uri.href,
|
|
13
|
+
mimeType: 'application/json',
|
|
14
|
+
text: JSON.stringify({
|
|
15
|
+
version: '1.0.0',
|
|
16
|
+
totalProjects: counts.projects,
|
|
17
|
+
totalSnapshots: counts.snapshots,
|
|
18
|
+
totalHandoffs: counts.handoffs,
|
|
19
|
+
}, null, 2),
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/resources/status.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,UAAU,sBAAsB,CACpC,MAAiB,EACjB,EAAqB;IAErB,MAAM,CAAC,gBAAgB,CACrB,eAAe,EACf,uBAAuB,EACvB;QACE,KAAK,EAAE,4BAA4B;QACnC,WAAW,EAAE,yDAAyD;QACtE,QAAQ,EAAE,kBAAkB;KAC7B,EACD,KAAK,EAAE,GAAG,EAAE,EAAE;QACZ,MAAM,MAAM,GAAG,cAAc,CAAC,EAAE,CAAC,CAAC;QAClC,OAAO;YACL,QAAQ,EAAE;gBACR;oBACE,GAAG,EAAE,GAAG,CAAC,IAAI;oBACb,QAAQ,EAAE,kBAAkB;oBAC5B,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,OAAO,EAAE,OAAO;wBAChB,aAAa,EAAE,MAAM,CAAC,QAAQ;wBAC9B,cAAc,EAAE,MAAM,CAAC,SAAS;wBAChC,aAAa,EAAE,MAAM,CAAC,QAAQ;qBAC/B,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|