faf-mcp 4.1.0 → 4.1.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.
- package/CHANGELOG.md +18 -1
- package/CLAUDE.md +2 -2
- package/README.md +13 -3
- package/dist/src/handlers/fileHandler.d.ts +6 -0
- package/dist/src/handlers/fileHandler.js +119 -11
- package/dist/src/handlers/fileHandler.js.map +1 -1
- package/dist/src/handlers/tools.js +59 -4
- package/dist/src/handlers/tools.js.map +1 -1
- package/dist/src/instructions.js +1 -1
- package/dist/src/instructions.js.map +1 -1
- package/dist/src/utils/git-history.d.ts +38 -0
- package/dist/src/utils/git-history.js +628 -0
- package/dist/src/utils/git-history.js.map +1 -0
- package/dist/src/utils/safe-path.d.ts +21 -0
- package/dist/src/utils/safe-path.js +99 -0
- package/dist/src/utils/safe-path.js.map +1 -1
- package/package.json +1 -1
- package/project.faf +2 -2
|
@@ -64,3 +64,24 @@ export interface ConfineOptions {
|
|
|
64
64
|
* callers do that with the returned value.
|
|
65
65
|
*/
|
|
66
66
|
export declare function confinePath(input: unknown, opts?: ConfineOptions): string;
|
|
67
|
+
/**
|
|
68
|
+
* Roots for `faf_write`. Stricter than fileOpRoots(): the project (cwd) only,
|
|
69
|
+
* no OS temp dir. An operator can still set an explicit boundary with
|
|
70
|
+
* `FAF_ALLOWED_ROOTS`.
|
|
71
|
+
*/
|
|
72
|
+
export declare function writeOpRoots(): string[];
|
|
73
|
+
/** The birth certificate. Written once by faf_dna, never by faf_write. */
|
|
74
|
+
export declare function isFafDnaFile(p: string): boolean;
|
|
75
|
+
/**
|
|
76
|
+
* Confine a `faf_write` target. Resolves the real path (through symlinks) and
|
|
77
|
+
* refuses:
|
|
78
|
+
* - anything outside writeOpRoots() (cwd by default),
|
|
79
|
+
* - anything inside a `.git/` directory,
|
|
80
|
+
* - a path through a folder that is a broken symlink (refused here, before
|
|
81
|
+
* faf_write reaches mkdir),
|
|
82
|
+
* - `.faf-dna` as the file or as any path segment (any case), by its
|
|
83
|
+
* lexical path or its real target, so `.faf-dna/x` and a symlink to the
|
|
84
|
+
* birth certificate are refused too.
|
|
85
|
+
* Returns the canonical path to write.
|
|
86
|
+
*/
|
|
87
|
+
export declare function confineWriteOp(input: unknown): string;
|
|
@@ -69,6 +69,9 @@ exports.allowedRoots = allowedRoots;
|
|
|
69
69
|
exports.fileOpRoots = fileOpRoots;
|
|
70
70
|
exports.confineFileOp = confineFileOp;
|
|
71
71
|
exports.confinePath = confinePath;
|
|
72
|
+
exports.writeOpRoots = writeOpRoots;
|
|
73
|
+
exports.isFafDnaFile = isFafDnaFile;
|
|
74
|
+
exports.confineWriteOp = confineWriteOp;
|
|
72
75
|
const path = __importStar(require("path"));
|
|
73
76
|
const os = __importStar(require("os"));
|
|
74
77
|
const fs = __importStar(require("fs"));
|
|
@@ -200,4 +203,100 @@ function confinePath(input, opts = {}) {
|
|
|
200
203
|
}
|
|
201
204
|
return resolved;
|
|
202
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Roots for `faf_write`. Stricter than fileOpRoots(): the project (cwd) only,
|
|
208
|
+
* no OS temp dir. An operator can still set an explicit boundary with
|
|
209
|
+
* `FAF_ALLOWED_ROOTS`.
|
|
210
|
+
*/
|
|
211
|
+
function writeOpRoots() {
|
|
212
|
+
const opt = allowedRoots();
|
|
213
|
+
if (opt.length)
|
|
214
|
+
return opt;
|
|
215
|
+
return [path.resolve(process.cwd())];
|
|
216
|
+
}
|
|
217
|
+
/** The birth certificate. Written once by faf_dna, never by faf_write. */
|
|
218
|
+
function isFafDnaFile(p) {
|
|
219
|
+
return path.basename(p).toLowerCase() === '.faf-dna';
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* True when any segment of `p` below its root is `name` (any case). Used for
|
|
223
|
+
* `.git` and `.faf-dna`: neither may be written, nor written under, so
|
|
224
|
+
* `.faf-dna/x` cannot turn the certificate's path into a directory.
|
|
225
|
+
*/
|
|
226
|
+
function hasSegment(p, roots, name) {
|
|
227
|
+
const root = roots.find((r) => p === r || p.startsWith(r + path.sep));
|
|
228
|
+
const rel = root ? path.relative(root, p) : p;
|
|
229
|
+
return rel.split(/[\\/]+/).some((seg) => seg.toLowerCase() === name);
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* The first folder on the way to `p` that is a symlink whose target cannot be
|
|
233
|
+
* resolved (dangling or a loop), or null. canonicalize() walks past such a
|
|
234
|
+
* link as if it were a missing folder, so it must be refused explicitly.
|
|
235
|
+
*/
|
|
236
|
+
function brokenSymlinkFolder(p) {
|
|
237
|
+
const folders = [];
|
|
238
|
+
for (let cur = path.dirname(p);; cur = path.dirname(cur)) {
|
|
239
|
+
folders.push(cur);
|
|
240
|
+
if (path.dirname(cur) === cur)
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
for (const folder of folders.reverse()) {
|
|
244
|
+
let isLink = false;
|
|
245
|
+
try {
|
|
246
|
+
isLink = fs.lstatSync(folder).isSymbolicLink();
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
continue; // absent: mkdir creates it
|
|
250
|
+
}
|
|
251
|
+
if (!isLink)
|
|
252
|
+
continue;
|
|
253
|
+
try {
|
|
254
|
+
fs.realpathSync(folder);
|
|
255
|
+
}
|
|
256
|
+
catch {
|
|
257
|
+
return folder;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return null;
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Confine a `faf_write` target. Resolves the real path (through symlinks) and
|
|
264
|
+
* refuses:
|
|
265
|
+
* - anything outside writeOpRoots() (cwd by default),
|
|
266
|
+
* - anything inside a `.git/` directory,
|
|
267
|
+
* - a path through a folder that is a broken symlink (refused here, before
|
|
268
|
+
* faf_write reaches mkdir),
|
|
269
|
+
* - `.faf-dna` as the file or as any path segment (any case), by its
|
|
270
|
+
* lexical path or its real target, so `.faf-dna/x` and a symlink to the
|
|
271
|
+
* birth certificate are refused too.
|
|
272
|
+
* Returns the canonical path to write.
|
|
273
|
+
*/
|
|
274
|
+
function confineWriteOp(input) {
|
|
275
|
+
if (typeof input !== 'string' || input.length === 0) {
|
|
276
|
+
throw new PathConfinementError('path must be a non-empty string');
|
|
277
|
+
}
|
|
278
|
+
if (input.includes('\0')) {
|
|
279
|
+
throw new PathConfinementError('path contains a null byte');
|
|
280
|
+
}
|
|
281
|
+
const lexical = path.resolve(expandTilde(input));
|
|
282
|
+
const resolved = canonicalize(lexical);
|
|
283
|
+
const roots = writeOpRoots().map(canonicalize);
|
|
284
|
+
const lexicalRoots = writeOpRoots().map((r) => path.resolve(r));
|
|
285
|
+
// `.faf-dna` as the file or as any directory segment, lexical or real.
|
|
286
|
+
if (isFafDnaFile(lexical) || isFafDnaFile(resolved) ||
|
|
287
|
+
hasSegment(lexical, lexicalRoots, '.faf-dna') || hasSegment(resolved, roots, '.faf-dna')) {
|
|
288
|
+
throw new PathConfinementError(`refusing to write .faf-dna or anything under a .faf-dna path: "${input}". The birth certificate is written once by faf_dna and never changed.`);
|
|
289
|
+
}
|
|
290
|
+
if (hasSegment(lexical, lexicalRoots, '.git') || hasSegment(resolved, roots, '.git')) {
|
|
291
|
+
throw new PathConfinementError(`refusing to write inside a .git directory: "${input}".`);
|
|
292
|
+
}
|
|
293
|
+
const broken = brokenSymlinkFolder(lexical);
|
|
294
|
+
if (broken) {
|
|
295
|
+
throw new PathConfinementError(`refusing to write through a broken symlinked folder: "${input}" (${broken} points to a target that does not exist).`);
|
|
296
|
+
}
|
|
297
|
+
if (!withinRoots(resolved, roots)) {
|
|
298
|
+
throw new PathConfinementError(`path escapes the project root (cwd${allowedRoots().length ? ' / FAF_ALLOWED_ROOTS' : ''}): "${input}".`);
|
|
299
|
+
}
|
|
300
|
+
return resolved;
|
|
301
|
+
}
|
|
203
302
|
//# sourceMappingURL=safe-path.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"safe-path.js","sourceRoot":"","sources":["../../../src/utils/safe-path.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcH,4CAGC;AAcD,oCAUC;AAkCD,kCAWC;AAQD,sCAEC;AAgBD,kCAsCC;
|
|
1
|
+
{"version":3,"file":"safe-path.js","sourceRoot":"","sources":["../../../src/utils/safe-path.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "faf-mcp",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.2",
|
|
4
4
|
"mcpName": "one.faf/faf-mcp",
|
|
5
5
|
"description": ".FAF Context — persistent project context for Cursor, VS Code and every MCP-compatible IDE. IANA-registered .faf format. Curated core tools by default, full set via FAF_TOOLS=all.",
|
|
6
6
|
"icon": "./assets/icons/faf-icon-256.png",
|
package/project.faf
CHANGED
|
@@ -2,7 +2,7 @@ faf_version: "3.0"
|
|
|
2
2
|
project:
|
|
3
3
|
name: faf-mcp
|
|
4
4
|
title: .FAF Context
|
|
5
|
-
version: 4.1.
|
|
5
|
+
version: 4.1.2
|
|
6
6
|
goal: The Interop MCP for Context — the Cursor / IDE Edition. Persistent context for Cursor, VS Code, and every MCP-compatible IDE. IANA-registered application/vnd.faf+yaml. Start with "Use FAF".
|
|
7
7
|
main_language: TypeScript
|
|
8
8
|
type: mcp
|
|
@@ -33,7 +33,7 @@ human_context:
|
|
|
33
33
|
what: The Cursor / IDE Edition — persistent context for Cursor, VS Code, and every MCP-compatible IDE — 29 MCP tools (15 essential shown by default), interop with AGENTS.md, .cursorrules, GEMINI.md
|
|
34
34
|
why: Eliminate the 20-minute AI context tax — give AI instant project understanding in 30 seconds
|
|
35
35
|
where: npm · MCP Registry · any MCP-compatible IDE — people get it how they wish
|
|
36
|
-
when: Production/Stable — v4.1.
|
|
36
|
+
when: Production/Stable — v4.1.2 The Instructions Edition, WJTTC certified
|
|
37
37
|
how: npx faf-mcp or npm install -g faf-mcp, then add to your MCP config
|
|
38
38
|
monorepo:
|
|
39
39
|
packages_count: slotignored
|