contextmate 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,161 @@
1
+ import { readFile, writeFile, readdir, stat, mkdir, copyFile } from 'node:fs/promises';
2
+ import { join, relative, dirname, resolve } from 'node:path';
3
+ import { homedir } from 'node:os';
4
+ import picomatch from 'picomatch';
5
+ export class ExtraPathsManager {
6
+ patterns;
7
+ vaultPath;
8
+ resolvedPatterns;
9
+ // vaultRelative -> absolute source path
10
+ mappings = new Map();
11
+ constructor(patterns, vaultPath) {
12
+ this.patterns = patterns;
13
+ this.vaultPath = vaultPath;
14
+ this.resolvedPatterns = this.parsePatterns();
15
+ }
16
+ resolveTilde(p) {
17
+ return p.startsWith('~') ? p.replace('~', homedir()) : p;
18
+ }
19
+ parsePatterns() {
20
+ return this.patterns.map((raw) => {
21
+ const resolved = this.resolveTilde(raw);
22
+ const scan = picomatch.scan(resolved);
23
+ // scan.base is the static prefix (directory portion before any glob chars)
24
+ const baseDir = scan.isGlob ? scan.base : dirname(resolved);
25
+ return { baseDir, pattern: resolved };
26
+ });
27
+ }
28
+ getWatchPaths() {
29
+ const dirs = new Set();
30
+ for (const { baseDir } of this.resolvedPatterns) {
31
+ dirs.add(baseDir);
32
+ }
33
+ return [...dirs];
34
+ }
35
+ sourceToVaultPath(absoluteSourcePath) {
36
+ // Check if this path matches any pattern
37
+ for (const { baseDir, pattern } of this.resolvedPatterns) {
38
+ const isMatch = picomatch(pattern);
39
+ if (isMatch(absoluteSourcePath)) {
40
+ const parentOfBase = dirname(baseDir);
41
+ const rel = relative(parentOfBase, absoluteSourcePath);
42
+ const vaultRelative = join('custom', rel);
43
+ this.mappings.set(vaultRelative, absoluteSourcePath);
44
+ return vaultRelative;
45
+ }
46
+ }
47
+ return null;
48
+ }
49
+ getSourcePath(vaultRelative) {
50
+ return this.mappings.get(vaultRelative) ?? null;
51
+ }
52
+ async writeBackToSource(vaultRelative, content) {
53
+ const sourcePath = this.mappings.get(vaultRelative);
54
+ if (!sourcePath)
55
+ return;
56
+ await mkdir(dirname(sourcePath), { recursive: true });
57
+ await writeFile(sourcePath, content);
58
+ }
59
+ async importToVault() {
60
+ const imported = [];
61
+ const skipped = [];
62
+ const discovered = await this.discoverFiles();
63
+ for (const { sourcePath, vaultRelative } of discovered) {
64
+ const vaultDest = join(this.vaultPath, vaultRelative);
65
+ try {
66
+ const sourceContent = await readFile(sourcePath);
67
+ // Check if vault already has identical content
68
+ try {
69
+ const existingContent = await readFile(vaultDest);
70
+ if (Buffer.compare(sourceContent, existingContent) === 0) {
71
+ skipped.push(vaultRelative);
72
+ continue;
73
+ }
74
+ }
75
+ catch {
76
+ // Doesn't exist in vault yet
77
+ }
78
+ await mkdir(dirname(vaultDest), { recursive: true });
79
+ await copyFile(sourcePath, vaultDest);
80
+ imported.push(vaultRelative);
81
+ }
82
+ catch {
83
+ // Source unreadable, skip
84
+ }
85
+ }
86
+ return { imported, skipped };
87
+ }
88
+ async discoverFiles() {
89
+ const results = [];
90
+ const seen = new Set();
91
+ for (const { baseDir, pattern } of this.resolvedPatterns) {
92
+ const isMatch = picomatch(pattern);
93
+ const scan = picomatch.scan(pattern);
94
+ if (!scan.isGlob) {
95
+ // Literal file path
96
+ const resolved = resolve(pattern);
97
+ if (seen.has(resolved))
98
+ continue;
99
+ try {
100
+ const s = await stat(resolved);
101
+ if (s.isFile()) {
102
+ const parentOfBase = dirname(baseDir);
103
+ const rel = relative(parentOfBase, resolved);
104
+ const vaultRelative = join('custom', rel);
105
+ this.mappings.set(vaultRelative, resolved);
106
+ results.push({ sourcePath: resolved, vaultRelative });
107
+ seen.add(resolved);
108
+ }
109
+ }
110
+ catch {
111
+ // File doesn't exist
112
+ }
113
+ continue;
114
+ }
115
+ // Walk the base directory and match
116
+ const matches = await this.walkAndMatch(baseDir, isMatch);
117
+ const parentOfBase = dirname(baseDir);
118
+ for (const absolutePath of matches) {
119
+ if (seen.has(absolutePath))
120
+ continue;
121
+ const rel = relative(parentOfBase, absolutePath);
122
+ const vaultRelative = join('custom', rel);
123
+ this.mappings.set(vaultRelative, absolutePath);
124
+ results.push({ sourcePath: absolutePath, vaultRelative });
125
+ seen.add(absolutePath);
126
+ }
127
+ }
128
+ return results;
129
+ }
130
+ async walkAndMatch(dir, isMatch) {
131
+ const matches = [];
132
+ let entries;
133
+ try {
134
+ entries = await readdir(dir);
135
+ }
136
+ catch {
137
+ return matches;
138
+ }
139
+ for (const name of entries) {
140
+ if (name.startsWith('.') || name === 'node_modules')
141
+ continue;
142
+ const full = join(dir, name);
143
+ try {
144
+ const s = await stat(full);
145
+ if (s.isDirectory()) {
146
+ matches.push(...await this.walkAndMatch(full, isMatch));
147
+ }
148
+ else if (s.isFile()) {
149
+ if (isMatch(full)) {
150
+ matches.push(full);
151
+ }
152
+ }
153
+ }
154
+ catch {
155
+ // Skip inaccessible
156
+ }
157
+ }
158
+ return matches;
159
+ }
160
+ }
161
+ //# sourceMappingURL=extra-paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extra-paths.js","sourceRoot":"","sources":["../../../src/sync/extra-paths.ts"],"names":[],"mappings":"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"}
@@ -3,4 +3,5 @@ export { SyncStateDB } from './state.js';
3
3
  export { FileWatcher } from './watcher.js';
4
4
  export { SyncClient, ConflictError } from './client.js';
5
5
  export { SyncWebSocket } from './websocket.js';
6
+ export { ExtraPathsManager } from './extra-paths.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -3,4 +3,5 @@ export { SyncStateDB } from './state.js';
3
3
  export { FileWatcher } from './watcher.js';
4
4
  export { SyncClient, ConflictError } from './client.js';
5
5
  export { SyncWebSocket } from './websocket.js';
6
+ export { ExtraPathsManager } from './extra-paths.js';
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/sync/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contextmate",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
4
4
  "description": "Zero-knowledge encrypted sync for AI agent context",
5
5
  "type": "module",
6
6
  "bin": {