k0ntext 3.3.0 → 3.5.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/README.md +240 -26
- package/dist/agents/cleanup-agent.d.ts.map +1 -1
- package/dist/agents/cleanup-agent.js +18 -6
- package/dist/agents/cleanup-agent.js.map +1 -1
- package/dist/agents/drift-agent.d.ts +7 -0
- package/dist/agents/drift-agent.d.ts.map +1 -1
- package/dist/agents/drift-agent.js +29 -8
- package/dist/agents/drift-agent.js.map +1 -1
- package/dist/cli/commands/cleanup.d.ts.map +1 -1
- package/dist/cli/commands/cleanup.js +8 -1
- package/dist/cli/commands/cleanup.js.map +1 -1
- package/dist/cli/commands/drift-detect.d.ts.map +1 -1
- package/dist/cli/commands/drift-detect.js +21 -1
- package/dist/cli/commands/drift-detect.js.map +1 -1
- package/dist/cli/commands/restore.d.ts +12 -0
- package/dist/cli/commands/restore.d.ts.map +1 -0
- package/dist/cli/commands/restore.js +261 -0
- package/dist/cli/commands/restore.js.map +1 -0
- package/dist/cli/commands/sync-templates.d.ts +15 -0
- package/dist/cli/commands/sync-templates.d.ts.map +1 -0
- package/dist/cli/commands/sync-templates.js +181 -0
- package/dist/cli/commands/sync-templates.js.map +1 -0
- package/dist/cli/commands/version-check.d.ts +12 -0
- package/dist/cli/commands/version-check.d.ts.map +1 -0
- package/dist/cli/commands/version-check.js +133 -0
- package/dist/cli/commands/version-check.js.map +1 -0
- package/dist/cli/generate.d.ts +5 -0
- package/dist/cli/generate.d.ts.map +1 -1
- package/dist/cli/generate.js +80 -16
- package/dist/cli/generate.js.map +1 -1
- package/dist/cli/index.js +145 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/repl/index.d.ts +4 -0
- package/dist/cli/repl/index.d.ts.map +1 -1
- package/dist/cli/repl/index.js +113 -95
- package/dist/cli/repl/index.js.map +1 -1
- package/dist/cli/repl/tui/panels/config.d.ts +71 -0
- package/dist/cli/repl/tui/panels/config.d.ts.map +1 -0
- package/dist/cli/repl/tui/panels/config.js +392 -0
- package/dist/cli/repl/tui/panels/config.js.map +1 -0
- package/dist/cli/repl/tui/panels/drift.d.ts +95 -0
- package/dist/cli/repl/tui/panels/drift.d.ts.map +1 -0
- package/dist/cli/repl/tui/panels/drift.js +353 -0
- package/dist/cli/repl/tui/panels/drift.js.map +1 -0
- package/dist/cli/repl/tui/panels/indexing.d.ts +86 -0
- package/dist/cli/repl/tui/panels/indexing.d.ts.map +1 -0
- package/dist/cli/repl/tui/panels/indexing.js +254 -0
- package/dist/cli/repl/tui/panels/indexing.js.map +1 -0
- package/dist/cli/repl/tui/panels/search.d.ts +66 -0
- package/dist/cli/repl/tui/panels/search.d.ts.map +1 -0
- package/dist/cli/repl/tui/panels/search.js +215 -0
- package/dist/cli/repl/tui/panels/search.js.map +1 -0
- package/dist/cli/utils/backup-manager.d.ts +94 -0
- package/dist/cli/utils/backup-manager.d.ts.map +1 -0
- package/dist/cli/utils/backup-manager.js +230 -0
- package/dist/cli/utils/backup-manager.js.map +1 -0
- package/dist/cli/utils/file-detector.d.ts +87 -0
- package/dist/cli/utils/file-detector.d.ts.map +1 -0
- package/dist/cli/utils/file-detector.js +131 -0
- package/dist/cli/utils/file-detector.js.map +1 -0
- package/dist/cli/utils/index.d.ts +9 -0
- package/dist/cli/utils/index.d.ts.map +1 -0
- package/dist/cli/utils/index.js +9 -0
- package/dist/cli/utils/index.js.map +1 -0
- package/dist/cli/utils/modification-prompt.d.ts +41 -0
- package/dist/cli/utils/modification-prompt.d.ts.map +1 -0
- package/dist/cli/utils/modification-prompt.js +84 -0
- package/dist/cli/utils/modification-prompt.js.map +1 -0
- package/dist/cli/version/checker.d.ts +47 -0
- package/dist/cli/version/checker.d.ts.map +1 -0
- package/dist/cli/version/checker.js +143 -0
- package/dist/cli/version/checker.js.map +1 -0
- package/dist/cli/version/comparator.d.ts +46 -0
- package/dist/cli/version/comparator.d.ts.map +1 -0
- package/dist/cli/version/comparator.js +99 -0
- package/dist/cli/version/comparator.js.map +1 -0
- package/dist/cli/version/index.d.ts +11 -0
- package/dist/cli/version/index.d.ts.map +1 -0
- package/dist/cli/version/index.js +11 -0
- package/dist/cli/version/index.js.map +1 -0
- package/dist/cli/version/parser.d.ts +38 -0
- package/dist/cli/version/parser.d.ts.map +1 -0
- package/dist/cli/version/parser.js +90 -0
- package/dist/cli/version/parser.js.map +1 -0
- package/dist/cli/version/prompt.d.ts +40 -0
- package/dist/cli/version/prompt.d.ts.map +1 -0
- package/dist/cli/version/prompt.js +162 -0
- package/dist/cli/version/prompt.js.map +1 -0
- package/dist/cli/version/types.d.ts +89 -0
- package/dist/cli/version/types.d.ts.map +1 -0
- package/dist/cli/version/types.js +7 -0
- package/dist/cli/version/types.js.map +1 -0
- package/dist/db/client.d.ts +64 -2
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +148 -2
- package/dist/db/client.js.map +1 -1
- package/dist/db/schema.d.ts +41 -2
- package/dist/db/schema.d.ts.map +1 -1
- package/dist/db/schema.js +77 -2
- package/dist/db/schema.js.map +1 -1
- package/dist/mcp.js +2 -2
- package/dist/mcp.js.map +1 -1
- package/dist/template-engine/data-transformer.d.ts +17 -0
- package/dist/template-engine/data-transformer.d.ts.map +1 -0
- package/dist/template-engine/data-transformer.js +343 -0
- package/dist/template-engine/data-transformer.js.map +1 -0
- package/dist/template-engine/engine.d.ts +74 -0
- package/dist/template-engine/engine.d.ts.map +1 -0
- package/dist/template-engine/engine.js +183 -0
- package/dist/template-engine/engine.js.map +1 -0
- package/dist/template-engine/helpers.d.ts +81 -0
- package/dist/template-engine/helpers.d.ts.map +1 -0
- package/dist/template-engine/helpers.js +153 -0
- package/dist/template-engine/helpers.js.map +1 -0
- package/dist/template-engine/index.d.ts +10 -0
- package/dist/template-engine/index.d.ts.map +1 -0
- package/dist/template-engine/index.js +10 -0
- package/dist/template-engine/index.js.map +1 -0
- package/dist/template-engine/types.d.ts +147 -0
- package/dist/template-engine/types.d.ts.map +1 -0
- package/dist/template-engine/types.js +7 -0
- package/dist/template-engine/types.js.map +1 -0
- package/dist/template-sync/comparator.d.ts +138 -0
- package/dist/template-sync/comparator.d.ts.map +1 -0
- package/dist/template-sync/comparator.js +353 -0
- package/dist/template-sync/comparator.js.map +1 -0
- package/dist/template-sync/conflict-resolver.d.ts +112 -0
- package/dist/template-sync/conflict-resolver.d.ts.map +1 -0
- package/dist/template-sync/conflict-resolver.js +328 -0
- package/dist/template-sync/conflict-resolver.js.map +1 -0
- package/dist/template-sync/engine.d.ts +93 -0
- package/dist/template-sync/engine.d.ts.map +1 -0
- package/dist/template-sync/engine.js +350 -0
- package/dist/template-sync/engine.js.map +1 -0
- package/dist/template-sync/hasher.d.ts +67 -0
- package/dist/template-sync/hasher.d.ts.map +1 -0
- package/dist/template-sync/hasher.js +94 -0
- package/dist/template-sync/hasher.js.map +1 -0
- package/dist/template-sync/index.d.ts +20 -0
- package/dist/template-sync/index.d.ts.map +1 -0
- package/dist/template-sync/index.js +14 -0
- package/dist/template-sync/index.js.map +1 -0
- package/dist/template-sync/manifest.d.ts +131 -0
- package/dist/template-sync/manifest.d.ts.map +1 -0
- package/dist/template-sync/manifest.js +309 -0
- package/dist/template-sync/manifest.js.map +1 -0
- package/dist/template-sync/merger.d.ts +125 -0
- package/dist/template-sync/merger.d.ts.map +1 -0
- package/dist/template-sync/merger.js +371 -0
- package/dist/template-sync/merger.js.map +1 -0
- package/dist/template-sync/scanner.d.ts +106 -0
- package/dist/template-sync/scanner.d.ts.map +1 -0
- package/dist/template-sync/scanner.js +196 -0
- package/dist/template-sync/scanner.js.map +1 -0
- package/dist/template-sync/types.d.ts +199 -0
- package/dist/template-sync/types.d.ts.map +1 -0
- package/dist/template-sync/types.js +30 -0
- package/dist/template-sync/types.js.map +1 -0
- package/package.json +2 -1
- package/src/agents/cleanup-agent.ts +21 -6
- package/src/agents/drift-agent.ts +31 -8
- package/src/cli/commands/cleanup.ts +9 -1
- package/src/cli/commands/drift-detect.ts +24 -1
- package/src/cli/commands/restore.ts +318 -0
- package/src/cli/commands/sync-templates.ts +210 -0
- package/src/cli/commands/version-check.ts +158 -0
- package/src/cli/generate.ts +99 -17
- package/src/cli/index.ts +167 -1
- package/src/cli/repl/index.ts +118 -105
- package/src/cli/repl/tui/panels/config.ts +457 -0
- package/src/cli/repl/tui/panels/drift.ts +458 -0
- package/src/cli/repl/tui/panels/indexing.ts +324 -0
- package/src/cli/repl/tui/panels/search.ts +272 -0
- package/src/cli/utils/backup-manager.ts +275 -0
- package/src/cli/utils/file-detector.ts +181 -0
- package/src/cli/utils/index.ts +9 -0
- package/src/cli/utils/modification-prompt.ts +112 -0
- package/src/cli/version/checker.ts +172 -0
- package/src/cli/version/comparator.ts +106 -0
- package/src/cli/version/index.ts +11 -0
- package/src/cli/version/parser.ts +101 -0
- package/src/cli/version/prompt.ts +208 -0
- package/src/cli/version/types.ts +95 -0
- package/src/db/client.ts +220 -3
- package/src/db/schema.ts +109 -2
- package/src/mcp.ts +2 -2
- package/src/template-engine/data-transformer.ts +367 -0
- package/src/template-engine/engine.ts +213 -0
- package/src/template-engine/helpers.ts +163 -0
- package/src/template-engine/index.ts +10 -0
- package/src/template-engine/types.ts +158 -0
- package/src/template-sync/comparator.ts +452 -0
- package/src/template-sync/conflict-resolver.ts +401 -0
- package/src/template-sync/engine.ts +417 -0
- package/src/template-sync/hasher.ts +104 -0
- package/src/template-sync/index.ts +60 -0
- package/src/template-sync/manifest.ts +358 -0
- package/src/template-sync/merger.ts +454 -0
- package/src/template-sync/scanner.ts +254 -0
- package/src/template-sync/types.ts +247 -0
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Template Comparator
|
|
3
|
+
*
|
|
4
|
+
* Compares template files with local files to detect changes.
|
|
5
|
+
* Determines file state: identical, safe-update, conflict, new, deleted, user-only.
|
|
6
|
+
*/
|
|
7
|
+
import { promises as fs } from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { TemplateHasher } from './hasher.js';
|
|
10
|
+
import { TemplateManifestManager } from './manifest.js';
|
|
11
|
+
import { TemplateScanner } from './scanner.js';
|
|
12
|
+
/**
|
|
13
|
+
* Compares template versions to detect changes
|
|
14
|
+
*/
|
|
15
|
+
export class TemplateComparator {
|
|
16
|
+
db;
|
|
17
|
+
projectRoot;
|
|
18
|
+
templateRoot;
|
|
19
|
+
manifestManager;
|
|
20
|
+
verbose = false;
|
|
21
|
+
constructor(db, projectRoot = process.cwd(), templateRoot, verbose = false) {
|
|
22
|
+
this.db = db;
|
|
23
|
+
this.projectRoot = projectRoot;
|
|
24
|
+
this.templateRoot = templateRoot;
|
|
25
|
+
this.manifestManager = new TemplateManifestManager(db, projectRoot);
|
|
26
|
+
this.verbose = verbose;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Compare template files with local files
|
|
30
|
+
*
|
|
31
|
+
* @param options - Comparison options
|
|
32
|
+
* @returns Array of file comparisons
|
|
33
|
+
*/
|
|
34
|
+
async compare(options = {}) {
|
|
35
|
+
const startTime = Date.now();
|
|
36
|
+
// Load manifest for user modification tracking
|
|
37
|
+
const manifest = await this.manifestManager.loadReconciledManifest();
|
|
38
|
+
// Define paths
|
|
39
|
+
const templateBasePath = this.templateRoot;
|
|
40
|
+
const localBasePath = path.join(this.projectRoot, '.claude');
|
|
41
|
+
// Scan template files
|
|
42
|
+
const templateFiles = await TemplateScanner.scanAndHash(templateBasePath, options.subdirectories);
|
|
43
|
+
// Scan local files
|
|
44
|
+
const localFiles = await this.scanLocalFiles(localBasePath, options.subdirectories);
|
|
45
|
+
// Build comparison map
|
|
46
|
+
const comparisons = await this.buildComparisons(templateFiles, localFiles, manifest, templateBasePath, localBasePath);
|
|
47
|
+
// Count by state
|
|
48
|
+
const counts = this.countByState(comparisons);
|
|
49
|
+
return {
|
|
50
|
+
comparisons,
|
|
51
|
+
counts,
|
|
52
|
+
total: comparisons.length,
|
|
53
|
+
durationMs: Date.now() - startTime
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Scan local files in .claude/
|
|
58
|
+
*
|
|
59
|
+
* @param localBasePath - Base path to .claude/
|
|
60
|
+
* @param subdirectories - Subdirectories to scan
|
|
61
|
+
* @returns Map of relative path to hash
|
|
62
|
+
*/
|
|
63
|
+
async scanLocalFiles(localBasePath, subdirectories) {
|
|
64
|
+
const localFiles = new Map();
|
|
65
|
+
try {
|
|
66
|
+
const dirs = subdirectories ?? TemplateScanner.getSyncedSubdirs();
|
|
67
|
+
for (const subdir of dirs) {
|
|
68
|
+
const dirPath = path.join(localBasePath, subdir);
|
|
69
|
+
try {
|
|
70
|
+
// Read directory entries directly
|
|
71
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
72
|
+
if (this.verbose) {
|
|
73
|
+
console.log(`[DEBUG] Scanning local directory: ${dirPath}`);
|
|
74
|
+
console.log(`[DEBUG] Found ${entries.length} entries`);
|
|
75
|
+
}
|
|
76
|
+
for (const entry of entries) {
|
|
77
|
+
if (entry.isFile() && !this.shouldExcludeFile(entry.name)) {
|
|
78
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
79
|
+
const hash = await TemplateHasher.hashFileSafe(fullPath);
|
|
80
|
+
// Normalize to forward slashes for consistency
|
|
81
|
+
const relativePath = path.join(subdir, entry.name).split(path.sep).join('/');
|
|
82
|
+
if (this.verbose) {
|
|
83
|
+
console.log(`[DEBUG] Found local file: ${relativePath} (hash: ${hash})`);
|
|
84
|
+
}
|
|
85
|
+
localFiles.set(relativePath, {
|
|
86
|
+
hash,
|
|
87
|
+
exists: true
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else if (entry.isDirectory()) {
|
|
91
|
+
// Recursively scan subdirectories within this subdir
|
|
92
|
+
await this.scanLocalFilesRecursive(path.join(dirPath, entry.name), path.join(subdir, entry.name), localFiles);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
// Directory doesn't exist - skip
|
|
98
|
+
if (this.verbose) {
|
|
99
|
+
console.log(`[DEBUG] Error scanning ${dirPath}: ${error.code || error}`);
|
|
100
|
+
}
|
|
101
|
+
if (error.code !== 'ENOENT') {
|
|
102
|
+
console.warn(`Warning: Could not scan ${dirPath}: ${error}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (this.verbose) {
|
|
107
|
+
console.log(`[DEBUG] Total local files found: ${localFiles.size}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
// Base directory doesn't exist yet - return empty map
|
|
112
|
+
if (this.verbose) {
|
|
113
|
+
console.log(`[DEBUG] Base directory error: ${error}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return localFiles;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Recursively scan local files within a subdirectory
|
|
120
|
+
*/
|
|
121
|
+
async scanLocalFilesRecursive(dirPath, relativePrefix, localFiles) {
|
|
122
|
+
try {
|
|
123
|
+
const entries = await fs.readdir(dirPath, { withFileTypes: true });
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
if (entry.isFile() && !this.shouldExcludeFile(entry.name)) {
|
|
126
|
+
const fullPath = path.join(dirPath, entry.name);
|
|
127
|
+
const hash = await TemplateHasher.hashFileSafe(fullPath);
|
|
128
|
+
// Normalize to forward slashes for consistency
|
|
129
|
+
const relativePath = path.join(relativePrefix, entry.name).split(path.sep).join('/');
|
|
130
|
+
localFiles.set(relativePath, {
|
|
131
|
+
hash,
|
|
132
|
+
exists: true
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
else if (entry.isDirectory()) {
|
|
136
|
+
await this.scanLocalFilesRecursive(path.join(dirPath, entry.name), path.join(relativePrefix, entry.name), localFiles);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
// Directory doesn't exist - skip
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Check if a file should be excluded from scanning
|
|
146
|
+
*/
|
|
147
|
+
shouldExcludeFile(filename) {
|
|
148
|
+
const excludePatterns = ['.DS_Store', '*.log', '.k0ntext-manifest.json'];
|
|
149
|
+
return excludePatterns.some(pattern => {
|
|
150
|
+
if (pattern.includes('*')) {
|
|
151
|
+
const regex = new RegExp('^' + pattern.replace(/\*/g, '.*').replace(/\?/g, '.') + '$');
|
|
152
|
+
return regex.test(filename);
|
|
153
|
+
}
|
|
154
|
+
return filename === pattern;
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Build comparison results
|
|
159
|
+
*
|
|
160
|
+
* @param templateFiles - Files from templates/base/.claude/
|
|
161
|
+
* @param localFiles - Files from local .claude/
|
|
162
|
+
* @param manifest - Template manifest
|
|
163
|
+
* @param templateBasePath - Template base path
|
|
164
|
+
* @param localBasePath - Local base path
|
|
165
|
+
* @returns Array of file comparisons
|
|
166
|
+
*/
|
|
167
|
+
async buildComparisons(templateFiles, localFiles, manifest, templateBasePath, localBasePath) {
|
|
168
|
+
const comparisons = [];
|
|
169
|
+
// Process template files
|
|
170
|
+
for (const templateFile of templateFiles) {
|
|
171
|
+
const localInfo = localFiles.get(templateFile.relativePath);
|
|
172
|
+
const manifestEntry = manifest?.files[templateFile.relativePath];
|
|
173
|
+
const comparison = await this.compareFile(templateFile, localInfo?.hash, localInfo?.exists ?? false, manifestEntry);
|
|
174
|
+
comparisons.push(comparison);
|
|
175
|
+
}
|
|
176
|
+
// Find user-only files (exist locally but not in template)
|
|
177
|
+
for (const [relativePath, localInfo] of localFiles.entries()) {
|
|
178
|
+
const isInTemplate = templateFiles.some(f => f.relativePath === relativePath);
|
|
179
|
+
if (!isInTemplate && localInfo.exists) {
|
|
180
|
+
// User-only file
|
|
181
|
+
comparisons.push({
|
|
182
|
+
path: relativePath,
|
|
183
|
+
state: 'user-only',
|
|
184
|
+
templateHash: '',
|
|
185
|
+
localHash: localInfo.hash,
|
|
186
|
+
userModified: false
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
return comparisons;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Compare a single file
|
|
194
|
+
*
|
|
195
|
+
* @param templateFile - Template file metadata
|
|
196
|
+
* @param localHash - Local file hash (if exists)
|
|
197
|
+
* @param localExists - Whether local file exists
|
|
198
|
+
* @param manifestEntry - Manifest entry (if any)
|
|
199
|
+
* @returns File comparison
|
|
200
|
+
*/
|
|
201
|
+
async compareFile(templateFile, localHash, localExists, manifestEntry) {
|
|
202
|
+
const templateHash = templateFile.hash;
|
|
203
|
+
const manifestUserModified = manifestEntry?.userModified ?? false;
|
|
204
|
+
const originalHash = manifestEntry?.originalHash;
|
|
205
|
+
// Determine state
|
|
206
|
+
let state;
|
|
207
|
+
let userModified = manifestUserModified;
|
|
208
|
+
if (!localExists) {
|
|
209
|
+
// File exists in template but not locally
|
|
210
|
+
state = 'new';
|
|
211
|
+
}
|
|
212
|
+
else if (!localHash) {
|
|
213
|
+
// Shouldn't happen, but handle gracefully
|
|
214
|
+
state = 'new';
|
|
215
|
+
}
|
|
216
|
+
else if (localHash === templateHash) {
|
|
217
|
+
// Files are identical
|
|
218
|
+
state = 'identical';
|
|
219
|
+
}
|
|
220
|
+
else if (manifestEntry && localHash === manifestEntry.hash) {
|
|
221
|
+
// File matches manifest (not user-modified), but template changed
|
|
222
|
+
state = 'safe-update';
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
// File hash doesn't match template
|
|
226
|
+
// Check if this is a user modification
|
|
227
|
+
if (manifestUserModified) {
|
|
228
|
+
// Already marked as user-modified in manifest
|
|
229
|
+
state = 'conflict';
|
|
230
|
+
}
|
|
231
|
+
else if (manifestEntry && localHash !== manifestEntry.hash) {
|
|
232
|
+
// File differs from manifest - user modified it after sync
|
|
233
|
+
state = 'conflict';
|
|
234
|
+
userModified = true; // Detect and flag user modification
|
|
235
|
+
}
|
|
236
|
+
else if (!manifestEntry) {
|
|
237
|
+
// No manifest entry, file was modified before tracking started
|
|
238
|
+
state = 'conflict';
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
// File hash doesn't match template or manifest
|
|
242
|
+
state = 'conflict';
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return {
|
|
246
|
+
path: templateFile.relativePath,
|
|
247
|
+
state,
|
|
248
|
+
templateHash,
|
|
249
|
+
localHash: localHash ?? '',
|
|
250
|
+
userModified,
|
|
251
|
+
originalHash
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Count comparisons by state
|
|
256
|
+
*
|
|
257
|
+
* @param comparisons - Array of comparisons
|
|
258
|
+
* @returns Record of state to count
|
|
259
|
+
*/
|
|
260
|
+
countByState(comparisons) {
|
|
261
|
+
const counts = {
|
|
262
|
+
identical: 0,
|
|
263
|
+
'safe-update': 0,
|
|
264
|
+
conflict: 0,
|
|
265
|
+
new: 0,
|
|
266
|
+
deleted: 0,
|
|
267
|
+
'user-only': 0
|
|
268
|
+
};
|
|
269
|
+
for (const comparison of comparisons) {
|
|
270
|
+
counts[comparison.state]++;
|
|
271
|
+
}
|
|
272
|
+
return counts;
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* Filter comparisons by state
|
|
276
|
+
*
|
|
277
|
+
* @param comparisons - Array of comparisons
|
|
278
|
+
* @param states - States to include
|
|
279
|
+
* @returns Filtered comparisons
|
|
280
|
+
*/
|
|
281
|
+
static filterByState(comparisons, states) {
|
|
282
|
+
return comparisons.filter(c => states.includes(c.state));
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Get comparisons needing action
|
|
286
|
+
*
|
|
287
|
+
* @param comparisons - Array of comparisons
|
|
288
|
+
* @returns Comparisons that need user action or update
|
|
289
|
+
*/
|
|
290
|
+
static getActionableComparisons(comparisons) {
|
|
291
|
+
return TemplateComparator.filterByState(comparisons, [
|
|
292
|
+
'safe-update',
|
|
293
|
+
'conflict',
|
|
294
|
+
'new'
|
|
295
|
+
]);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Get comparisons with conflicts
|
|
299
|
+
*
|
|
300
|
+
* @param comparisons - Array of comparisons
|
|
301
|
+
* @returns Comparisons with conflicts
|
|
302
|
+
*/
|
|
303
|
+
static getConflicts(comparisons) {
|
|
304
|
+
return TemplateComparator.filterByState(comparisons, ['conflict']);
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Get safe updates
|
|
308
|
+
*
|
|
309
|
+
* @param comparisons - Array of comparisons
|
|
310
|
+
* @returns Comparisons that can be safely updated
|
|
311
|
+
*/
|
|
312
|
+
static getSafeUpdates(comparisons) {
|
|
313
|
+
return TemplateComparator.filterByState(comparisons, ['safe-update', 'new']);
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Format comparison for display
|
|
317
|
+
*
|
|
318
|
+
* @param comparison - File comparison
|
|
319
|
+
* @returns Formatted string
|
|
320
|
+
*/
|
|
321
|
+
static formatComparison(comparison) {
|
|
322
|
+
const stateIcon = {
|
|
323
|
+
identical: '✓',
|
|
324
|
+
'safe-update': '→',
|
|
325
|
+
conflict: '⚠',
|
|
326
|
+
new: '+',
|
|
327
|
+
deleted: '-',
|
|
328
|
+
'user-only': '👤'
|
|
329
|
+
};
|
|
330
|
+
const icon = stateIcon[comparison.state];
|
|
331
|
+
const userFlag = comparison.userModified ? ' [modified]' : '';
|
|
332
|
+
return `${icon} ${comparison.path}${userFlag}`;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Generate summary text for comparison results
|
|
336
|
+
*
|
|
337
|
+
* @param result - Comparison result
|
|
338
|
+
* @returns Formatted summary
|
|
339
|
+
*/
|
|
340
|
+
static generateSummary(result) {
|
|
341
|
+
const lines = [];
|
|
342
|
+
lines.push(`Template Comparison Summary:`);
|
|
343
|
+
lines.push(` Total files: ${result.total}`);
|
|
344
|
+
lines.push(` Identical: ${result.counts.identical}`);
|
|
345
|
+
lines.push(` Safe updates: ${result.counts['safe-update']}`);
|
|
346
|
+
lines.push(` New files: ${result.counts.new}`);
|
|
347
|
+
lines.push(` Conflicts: ${result.counts.conflict}`);
|
|
348
|
+
lines.push(` User-only: ${result.counts['user-only']}`);
|
|
349
|
+
lines.push(` Duration: ${result.durationMs}ms`);
|
|
350
|
+
return lines.join('\n');
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
//# sourceMappingURL=comparator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comparator.js","sourceRoot":"","sources":["../../src/template-sync/comparator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict Resolver
|
|
3
|
+
*
|
|
4
|
+
* Handles interactive conflict resolution for template sync.
|
|
5
|
+
* Uses @inquirer/prompts for user interaction.
|
|
6
|
+
*/
|
|
7
|
+
import type { FileComparison, ResolutionChoice, ResolutionResult } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Resolution options for a single conflict
|
|
10
|
+
*/
|
|
11
|
+
export interface ResolutionOptions {
|
|
12
|
+
/** Whether to show diffs by default */
|
|
13
|
+
showDiff?: boolean;
|
|
14
|
+
/** Whether to allow batch resolution */
|
|
15
|
+
allowBatch?: boolean;
|
|
16
|
+
/** Default choice */
|
|
17
|
+
defaultChoice?: ResolutionChoice;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Batch resolution strategy
|
|
21
|
+
*/
|
|
22
|
+
export type BatchStrategy = 'keep-all' | 'overwrite-all' | 'individual';
|
|
23
|
+
/**
|
|
24
|
+
* Handles interactive conflict resolution
|
|
25
|
+
*/
|
|
26
|
+
export declare class ConflictResolver {
|
|
27
|
+
private projectRoot;
|
|
28
|
+
private templateRoot;
|
|
29
|
+
constructor(projectRoot: string | undefined, templateRoot: string);
|
|
30
|
+
/**
|
|
31
|
+
* Resolve conflicts interactively
|
|
32
|
+
*
|
|
33
|
+
* @param conflicts - Array of conflicting comparisons
|
|
34
|
+
* @param options - Resolution options
|
|
35
|
+
* @returns Array of resolution results
|
|
36
|
+
*/
|
|
37
|
+
resolveConflicts(conflicts: FileComparison[], options?: ResolutionOptions): Promise<ResolutionResult[]>;
|
|
38
|
+
/**
|
|
39
|
+
* Resolve a single conflict
|
|
40
|
+
*
|
|
41
|
+
* @param conflict - File comparison in conflict
|
|
42
|
+
* @param options - Resolution options
|
|
43
|
+
* @returns Resolution result
|
|
44
|
+
*/
|
|
45
|
+
resolveConflict(conflict: FileComparison, options?: ResolutionOptions): Promise<ResolutionResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Prompt for batch resolution strategy
|
|
48
|
+
*
|
|
49
|
+
* @param count - Number of conflicts
|
|
50
|
+
* @returns Batch strategy
|
|
51
|
+
*/
|
|
52
|
+
private promptBatchStrategy;
|
|
53
|
+
/**
|
|
54
|
+
* Prompt for resolution of a single conflict
|
|
55
|
+
*
|
|
56
|
+
* @param conflict - File comparison
|
|
57
|
+
* @param options - Resolution options
|
|
58
|
+
* @returns Resolution choice
|
|
59
|
+
*/
|
|
60
|
+
private promptResolution;
|
|
61
|
+
/**
|
|
62
|
+
* Show conflict information
|
|
63
|
+
*
|
|
64
|
+
* @param conflict - File comparison
|
|
65
|
+
*/
|
|
66
|
+
private showConflictInfo;
|
|
67
|
+
/**
|
|
68
|
+
* Show conflict summary
|
|
69
|
+
*
|
|
70
|
+
* @param conflicts - Array of conflicts
|
|
71
|
+
*/
|
|
72
|
+
private showConflictSummary;
|
|
73
|
+
/**
|
|
74
|
+
* Show diff for a conflict
|
|
75
|
+
*
|
|
76
|
+
* @param conflict - File comparison
|
|
77
|
+
*/
|
|
78
|
+
private showDiff;
|
|
79
|
+
/**
|
|
80
|
+
* Format file state for display
|
|
81
|
+
*
|
|
82
|
+
* @param state - File state
|
|
83
|
+
* @returns Formatted state string
|
|
84
|
+
*/
|
|
85
|
+
private formatState;
|
|
86
|
+
/**
|
|
87
|
+
* Apply resolution results using merger
|
|
88
|
+
*
|
|
89
|
+
* @param resolutions - Array of resolution results
|
|
90
|
+
* @param conflicts - Original conflicts for reference
|
|
91
|
+
* @returns Results of applied resolutions
|
|
92
|
+
*/
|
|
93
|
+
applyResolutions(resolutions: ResolutionResult[], conflicts: FileComparison[]): Promise<{
|
|
94
|
+
applied: number;
|
|
95
|
+
skipped: number;
|
|
96
|
+
errors: number;
|
|
97
|
+
}>;
|
|
98
|
+
/**
|
|
99
|
+
* Prompt for archival of removed files
|
|
100
|
+
*
|
|
101
|
+
* @param removedFiles - Array of removed file paths
|
|
102
|
+
* @returns true if user wants to archive
|
|
103
|
+
*/
|
|
104
|
+
promptArchiveRemoved(removedFiles: string[]): Promise<boolean>;
|
|
105
|
+
/**
|
|
106
|
+
* Show dry run results
|
|
107
|
+
*
|
|
108
|
+
* @param comparisons - File comparisons
|
|
109
|
+
*/
|
|
110
|
+
showDryRunResults(comparisons: FileComparison[]): void;
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=conflict-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"conflict-resolver.d.ts","sourceRoot":"","sources":["../../src/template-sync/conflict-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAGrF;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,uCAAuC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qBAAqB;IACrB,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,eAAe,GAAG,YAAY,CAAC;AAExE;;GAEG;AACH,qBAAa,gBAAgB;IAEzB,OAAO,CAAC,WAAW;IACnB,OAAO,CAAC,YAAY;gBADZ,WAAW,EAAE,MAAM,YAAgB,EACnC,YAAY,EAAE,MAAM;IAG9B;;;;;;OAMG;IACG,gBAAgB,CACpB,SAAS,EAAE,cAAc,EAAE,EAC3B,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,EAAE,CAAC;IA6C9B;;;;;;OAMG;IACG,eAAe,CACnB,QAAQ,EAAE,cAAc,EACxB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC;IAmB5B;;;;;OAKG;YACW,mBAAmB;IAuBjC;;;;;;OAMG;YACW,gBAAgB;IAuC9B;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAgBxB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAa3B;;;;OAIG;YACW,QAAQ;IAyBtB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAanB;;;;;;OAMG;IACG,gBAAgB,CACpB,WAAW,EAAE,gBAAgB,EAAE,EAC/B,SAAS,EAAE,cAAc,EAAE,GAC1B,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA8BhE;;;;;OAKG;IACG,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBpE;;;;OAIG;IACH,iBAAiB,CAAC,WAAW,EAAE,cAAc,EAAE,GAAG,IAAI;CAwCvD"}
|