faf-mcp 2.0.1 → 2.1.1
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 +52 -0
- package/CLAUDE.md +23 -21
- package/README.md +27 -24
- package/dist/src/cli.js +1 -1
- package/dist/src/cli.js.map +1 -1
- package/dist/src/faf-core/commands/auto.d.ts +2 -2
- package/dist/src/faf-core/commands/auto.js.map +1 -1
- package/dist/src/faf-core/commands/innit.d.ts +2 -2
- package/dist/src/faf-core/commands/innit.js.map +1 -1
- package/dist/src/faf-core/commands/score.d.ts +1 -1
- package/dist/src/faf-core/commands/score.js.map +1 -1
- package/dist/src/faf-core/generators/faf-generator-championship.js.map +1 -1
- package/dist/src/faf-core/parsers/agents-parser.d.ts +1 -1
- package/dist/src/faf-core/parsers/agents-parser.js +2 -2
- package/dist/src/faf-core/parsers/agents-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/conductor-parser.d.ts +1 -1
- package/dist/src/faf-core/parsers/conductor-parser.js +1 -1
- package/dist/src/faf-core/parsers/cursorrules-parser.d.ts +1 -1
- package/dist/src/faf-core/parsers/cursorrules-parser.js +2 -2
- package/dist/src/faf-core/parsers/cursorrules-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/faf-git-generator.d.ts +1 -1
- package/dist/src/faf-core/parsers/faf-git-generator.js +2 -2
- package/dist/src/faf-core/parsers/faf-git-generator.js.map +1 -1
- package/dist/src/faf-core/parsers/gemini-parser.d.ts +1 -1
- package/dist/src/faf-core/parsers/gemini-parser.js +1 -1
- package/dist/src/faf-core/parsers/github-extractor.d.ts +1 -1
- package/dist/src/faf-core/parsers/github-extractor.js +2 -2
- package/dist/src/faf-core/parsers/github-extractor.js.map +1 -1
- package/dist/src/faf-core/parsers/slot-counter.d.ts +1 -1
- package/dist/src/faf-core/parsers/slot-counter.js +1 -1
- package/dist/src/handlers/championship-tools.d.ts +6 -13
- package/dist/src/handlers/championship-tools.js +122 -530
- package/dist/src/handlers/championship-tools.js.map +1 -1
- package/dist/src/handlers/engine-adapter.js +3 -3
- package/dist/src/handlers/engine-adapter.js.map +1 -1
- package/dist/src/handlers/fileHandler.d.ts +1 -1
- package/dist/src/handlers/fileHandler.js +1 -1
- package/dist/src/handlers/fileHandler.js.map +1 -1
- package/dist/src/handlers/resources.d.ts +1 -1
- package/dist/src/handlers/tool-registry.d.ts +2 -2
- package/dist/src/handlers/tools.d.ts +1 -1
- package/dist/src/handlers/tools.js +116 -135
- package/dist/src/handlers/tools.js.map +1 -1
- package/dist/src/index.js +2 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/server.d.ts +8 -3
- package/dist/src/server.js +16 -10
- package/dist/src/server.js.map +1 -1
- package/dist/src/test-all-functions.js +1 -1
- package/dist/src/test-all-functions.js.map +1 -1
- package/dist/src/types/mcp-tools.d.ts +2 -2
- package/dist/src/types/tool-visibility.js +1 -1
- package/dist/src/types/tool-visibility.js.map +1 -1
- package/dist/src/utils/cli-detector.d.ts +3 -6
- package/dist/src/utils/cli-detector.js +19 -2
- package/dist/src/utils/cli-detector.js.map +1 -1
- package/dist/src/utils/display-protocol.d.ts +2 -2
- package/dist/src/utils/display-protocol.js +4 -4
- package/dist/src/utils/display-protocol.js.map +1 -1
- package/dist/src/utils/faf-cli-bridge.d.ts +47 -0
- package/dist/src/utils/faf-cli-bridge.js +101 -0
- package/dist/src/utils/faf-cli-bridge.js.map +1 -0
- package/dist/src/utils/visual-style.js +1 -1
- package/dist/src/utils/visual-style.js.map +1 -1
- package/package.json +7 -10
- package/project.faf +31 -133
- package/scripts/check-stylesheet-drift.mjs +114 -0
package/project.faf
CHANGED
|
@@ -1,142 +1,40 @@
|
|
|
1
|
-
faf_version:
|
|
2
|
-
ai_scoring_system: 2025-09-20
|
|
3
|
-
ai_score: 85%
|
|
4
|
-
ai_confidence: HIGH
|
|
5
|
-
ai_value: 30_seconds_replaces_20_minutes_of_questions
|
|
6
|
-
ai_tldr:
|
|
7
|
-
project: faf-mcp - "USE>FAF™ - IANA-registered format (application/vnd.faf+yaml) • Universal AI context • MCP server for all platforms • Start with 'Use FAF'"
|
|
8
|
-
stack: CLI/TypeScript/TypeScript (tsc)/npm registry/Node.js
|
|
9
|
-
quality_bar: ZERO_ERRORS_F1_STANDARDS
|
|
10
|
-
current_focus: Production deployment preparation
|
|
11
|
-
your_role: Build features with perfect context
|
|
12
|
-
instant_context:
|
|
13
|
-
what_building: USE>FAF™ - IANA-registered format (application/vnd.faf+yaml) • Universal AI context • MCP server for all platforms • Start with 'Use FAF'
|
|
14
|
-
tech_stack: CLI/TypeScript/TypeScript (tsc)/npm registry/Node.js
|
|
15
|
-
main_language: TypeScript
|
|
16
|
-
deployment: npm registry
|
|
17
|
-
key_files:
|
|
18
|
-
- package.json
|
|
19
|
-
- tsconfig.json
|
|
20
|
-
context_quality:
|
|
21
|
-
slots_filled: 21/21 (100%)
|
|
22
|
-
ai_confidence: HIGH
|
|
23
|
-
handoff_ready: true
|
|
24
|
-
missing_context: []
|
|
1
|
+
faf_version: "3.0"
|
|
25
2
|
project:
|
|
26
3
|
name: faf-mcp
|
|
27
|
-
goal:
|
|
4
|
+
goal: The Interop MCP for Context. Universal .faf MCP server for Cursor, Windsurf, Cline, VS Code, and all MCP-compatible IDEs. IANA-registered application/vnd.faf+yaml. Start with "Use FAF".
|
|
28
5
|
main_language: TypeScript
|
|
29
|
-
type:
|
|
30
|
-
|
|
31
|
-
mission: 🚀 Make Your AI Happy! 🧡 Trust-Driven 🤖
|
|
32
|
-
revolution: 30 seconds replaces 20 minutes of questions
|
|
33
|
-
brand: F1-Inspired Software Engineering - Championship AI Context
|
|
34
|
-
ai_instructions:
|
|
35
|
-
how_to_start: Just USE FAF - Start every prompt with 'Use FAF to...' and MCP tools handle the rest
|
|
36
|
-
priority_order:
|
|
37
|
-
- 1. Read THIS .faf file first
|
|
38
|
-
- 2. Check CLAUDE.md for session context
|
|
39
|
-
- 3. Review package.json for dependencies
|
|
40
|
-
quick_commands:
|
|
41
|
-
- Use FAF to initialize your project
|
|
42
|
-
- Use FAF to sync my project.faf to all platforms
|
|
43
|
-
- Use FAF to score my AI-readiness
|
|
44
|
-
working_style:
|
|
45
|
-
code_first: true
|
|
46
|
-
explanations: minimal
|
|
47
|
-
quality_bar: zero_errors
|
|
48
|
-
testing: required
|
|
49
|
-
warnings:
|
|
50
|
-
- Never modify dial components without approval
|
|
51
|
-
- All TypeScript must pass strict mode
|
|
52
|
-
- Test coverage required for new features
|
|
6
|
+
type: mcp
|
|
7
|
+
framework: MCP SDK (TS)
|
|
53
8
|
stack:
|
|
54
|
-
frontend:
|
|
55
|
-
css_framework:
|
|
56
|
-
ui_library:
|
|
57
|
-
state_management:
|
|
58
|
-
backend:
|
|
59
|
-
|
|
60
|
-
|
|
9
|
+
frontend: slotignored
|
|
10
|
+
css_framework: slotignored
|
|
11
|
+
ui_library: slotignored
|
|
12
|
+
state_management: slotignored
|
|
13
|
+
backend: MCP SDK (TS)
|
|
14
|
+
api_type: MCP (stdio/HTTP-SSE)
|
|
15
|
+
runtime: Node.js >=18
|
|
16
|
+
database: slotignored
|
|
17
|
+
connection: slotignored
|
|
18
|
+
hosting: Vercel
|
|
61
19
|
build: TypeScript (tsc)
|
|
20
|
+
cicd: GitHub Actions
|
|
21
|
+
monorepo_tool: slotignored
|
|
62
22
|
package_manager: npm
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
missionPurpose: project documentation
|
|
69
|
-
packageManager: npm/yarn/pnpm
|
|
70
|
-
mainLanguage: JavaScript/TypeScript
|
|
71
|
-
preferences:
|
|
72
|
-
quality_bar: zero_errors
|
|
73
|
-
commit_style: conventional_emoji
|
|
74
|
-
response_style: concise_code_first
|
|
75
|
-
explanation_level: minimal
|
|
76
|
-
communication: direct
|
|
77
|
-
testing: required
|
|
78
|
-
documentation: as_needed
|
|
79
|
-
state:
|
|
80
|
-
phase: development
|
|
81
|
-
version: 2.0.0
|
|
82
|
-
focus: interop_mcp_for_context
|
|
83
|
-
status: green_flag
|
|
84
|
-
next_milestone: npm_publish_v2
|
|
85
|
-
blockers: null
|
|
86
|
-
tags:
|
|
87
|
-
auto_generated:
|
|
88
|
-
- faf-mcp
|
|
89
|
-
- cli
|
|
90
|
-
- typescript
|
|
91
|
-
- typescript-(tsc)
|
|
92
|
-
- npm-registry
|
|
93
|
-
- node.js
|
|
94
|
-
smart_defaults:
|
|
95
|
-
- .faf
|
|
96
|
-
- ai-ready
|
|
97
|
-
- "2025"
|
|
98
|
-
- software
|
|
99
|
-
- open-source
|
|
100
|
-
user_defined: null
|
|
23
|
+
workspaces: slotignored
|
|
24
|
+
admin: slotignored
|
|
25
|
+
cache: slotignored
|
|
26
|
+
search: slotignored
|
|
27
|
+
storage: slotignored
|
|
101
28
|
human_context:
|
|
102
29
|
who: Developers using Claude, Cursor, Windsurf, VS Code, Cline, and any MCP-compatible IDE
|
|
103
|
-
what: Universal MCP server providing .faf context tools
|
|
104
|
-
why: Eliminate the 20-minute AI context tax
|
|
105
|
-
where: npm
|
|
106
|
-
when: Production/Stable
|
|
30
|
+
what: Universal MCP server providing .faf context tools — 25 core + 36 advanced, interop with AGENTS.md, .cursorrules, GEMINI.md
|
|
31
|
+
why: Eliminate the 20-minute AI context tax — give AI instant project understanding in 30 seconds
|
|
32
|
+
where: Vercel web (faf-mcp.vercel.app) · npm · MCP Registry · any MCP-compatible IDE — people get it how they wish
|
|
33
|
+
when: Production/Stable — v2.0.0 WJTTC certified (309/309 tests, 9 suites)
|
|
107
34
|
how: npx faf-mcp or npm install -g faf-mcp, then add to your MCP config
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
slot_based_percentage: 76
|
|
115
|
-
ai_score: 85
|
|
116
|
-
total_slots: 21
|
|
117
|
-
filled_slots: 16
|
|
118
|
-
scoring_method: Honest percentage - no fake minimums
|
|
119
|
-
trust_embedded: COUNT ONCE architecture - trust MY embedded scores
|
|
120
|
-
faf_dna:
|
|
121
|
-
birth_dna: 22
|
|
122
|
-
birth_certificate: FAF-2025-FAFMCP-NR94
|
|
123
|
-
birth_date: 2025-11-13T20:02:03.306Z
|
|
124
|
-
current_score: 83
|
|
125
|
-
projectName: faf-mcp
|
|
126
|
-
projectGoal: faf-mcp | use>faf • IANA-registered format (application/vnd.faf+yaml) • Universal MCP server for Cursor, Windsurf, Cline, VS Code, and all platforms
|
|
127
|
-
generated: 2025-12-18T20:38:25.477Z
|
|
128
|
-
stack_signature: typescript-nodejs-javascript
|
|
129
|
-
detected_frameworks:
|
|
130
|
-
- Jest
|
|
131
|
-
- Node.js
|
|
132
|
-
- JavaScript
|
|
133
|
-
- TypeScript
|
|
134
|
-
- Vercel
|
|
135
|
-
- npm
|
|
136
|
-
turbo_cat_intelligence: 360
|
|
137
|
-
stats:
|
|
138
|
-
last_auto_time: 0.6
|
|
139
|
-
times_run: 1
|
|
140
|
-
metadata:
|
|
141
|
-
last_claude_sync: 2026-03-07T17:36:56.430Z
|
|
142
|
-
bi_sync: active
|
|
35
|
+
monorepo:
|
|
36
|
+
packages_count: slotignored
|
|
37
|
+
build_orchestrator: slotignored
|
|
38
|
+
versioning_strategy: slotignored
|
|
39
|
+
shared_configs: slotignored
|
|
40
|
+
remote_cache: slotignored
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* faf-mcp · style-sheet drift check
|
|
4
|
+
*
|
|
5
|
+
* Contract: docs/style-source.html is the canonical visual vROM.
|
|
6
|
+
* Every surface carries a sentinel-wrapped copy of the :root token block.
|
|
7
|
+
* This gate verifies the BRAND SIGNATURE (token name→value map, whitespace
|
|
8
|
+
* & case normalized) is identical across surfaces — fast, non-visual.
|
|
9
|
+
*
|
|
10
|
+
* It checks the vocabulary (right tokens, right values, none missing, none
|
|
11
|
+
* extra). It does NOT check which element uses which token — that needs
|
|
12
|
+
* rendering, which is deliberately out of scope. Vocabulary integrity at
|
|
13
|
+
* zero cost.
|
|
14
|
+
*
|
|
15
|
+
* Exit 1 on drift. Rogue off-palette hex outside the token block = warn only.
|
|
16
|
+
*/
|
|
17
|
+
import { readFileSync } from 'node:fs';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
import { dirname, join } from 'node:path';
|
|
20
|
+
|
|
21
|
+
const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
22
|
+
|
|
23
|
+
const SOURCE = 'docs/style-source.html';
|
|
24
|
+
const SURFACES = ['docs/index.html', 'api/index.ts'];
|
|
25
|
+
|
|
26
|
+
const OPEN = '/* === faf-mcp:stylesheet canonical';
|
|
27
|
+
const CLOSE = '/* === /faf-mcp:stylesheet canonical === */';
|
|
28
|
+
|
|
29
|
+
function extractBlock(file) {
|
|
30
|
+
const text = readFileSync(join(ROOT, file), 'utf8');
|
|
31
|
+
const i = text.indexOf(OPEN);
|
|
32
|
+
const j = text.indexOf(CLOSE);
|
|
33
|
+
if (i === -1 || j === -1 || j < i) {
|
|
34
|
+
return null; // surface not wired
|
|
35
|
+
}
|
|
36
|
+
return text.slice(i, j + CLOSE.length);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// name -> normalized value (whitespace stripped, lowercased)
|
|
40
|
+
function signature(block) {
|
|
41
|
+
const map = {};
|
|
42
|
+
const re = /--([\w-]+)\s*:\s*([^;]+);/g;
|
|
43
|
+
let m;
|
|
44
|
+
while ((m = re.exec(block)) !== null) {
|
|
45
|
+
map[m[1]] = m[2].replace(/\s+/g, '').toLowerCase();
|
|
46
|
+
}
|
|
47
|
+
return map;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function diff(srcSig, surfSig) {
|
|
51
|
+
const out = [];
|
|
52
|
+
const keys = new Set([...Object.keys(srcSig), ...Object.keys(surfSig)]);
|
|
53
|
+
for (const k of [...keys].sort()) {
|
|
54
|
+
if (!(k in surfSig)) out.push(` - missing --${k} (source: ${srcSig[k]})`);
|
|
55
|
+
else if (!(k in srcSig)) out.push(` - extra --${k} (surface: ${surfSig[k]})`);
|
|
56
|
+
else if (srcSig[k] !== surfSig[k])
|
|
57
|
+
out.push(` - drift --${k}: source ${srcSig[k]} ≠ surface ${surfSig[k]}`);
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const srcBlock = extractBlock(SOURCE);
|
|
63
|
+
if (!srcBlock) {
|
|
64
|
+
console.error(`✗ canonical block not found in source ${SOURCE}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
const srcSig = signature(srcBlock);
|
|
68
|
+
const palette = new Set(
|
|
69
|
+
Object.values(srcSig)
|
|
70
|
+
.join(' ')
|
|
71
|
+
.match(/#[0-9a-f]{3,8}/g) || []
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
let failed = false;
|
|
75
|
+
for (const surface of SURFACES) {
|
|
76
|
+
const block = extractBlock(surface);
|
|
77
|
+
if (!block) {
|
|
78
|
+
console.error(`✗ ${surface}: canonical block missing — surface not wired`);
|
|
79
|
+
failed = true;
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
const d = diff(srcSig, signature(block));
|
|
83
|
+
if (d.length) {
|
|
84
|
+
console.error(`✗ ${surface}: brand signature drift\n${d.join('\n')}`);
|
|
85
|
+
failed = true;
|
|
86
|
+
} else {
|
|
87
|
+
console.log(`✓ ${surface}: brand signature matches canonical`);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// warn-only: off-palette hex outside the token block.
|
|
91
|
+
// Only meaningful for single-surface .html files; a multi-page server
|
|
92
|
+
// file (.ts) legitimately hosts sibling pages with their own palettes,
|
|
93
|
+
// so the signature gate above is the real check there.
|
|
94
|
+
if (surface.endsWith('.html')) {
|
|
95
|
+
const text = readFileSync(join(ROOT, surface), 'utf8');
|
|
96
|
+
const i = text.indexOf(OPEN);
|
|
97
|
+
const j = text.indexOf(CLOSE);
|
|
98
|
+
const outside = text.slice(0, i) + text.slice(j + CLOSE.length);
|
|
99
|
+
const rogue = [
|
|
100
|
+
...new Set(
|
|
101
|
+
(outside.match(/#[0-9a-fA-F]{6}\b/g) || []).map((h) => h.toLowerCase())
|
|
102
|
+
),
|
|
103
|
+
].filter((h) => !palette.has(h));
|
|
104
|
+
if (rogue.length) {
|
|
105
|
+
console.warn(` ⚠ ${surface}: off-palette hex outside token block: ${rogue.join(', ')}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (failed) {
|
|
111
|
+
console.error('\nstyle-source drift gate FAILED — edit docs/style-source.html only, then re-sync surfaces.');
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
console.log('\nstyle-sheet drift gate PASSED — all surfaces derive from canonical.');
|