faf-mcp 2.3.0 → 3.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/CHANGELOG.md +42 -3
- package/CLAUDE.md +7 -7
- package/README.md +73 -74
- package/dist/src/faf-core/commands/bi-sync.d.ts +1 -3
- package/dist/src/faf-core/commands/bi-sync.js +21 -64
- package/dist/src/faf-core/commands/bi-sync.js.map +1 -1
- package/dist/src/faf-core/commands/sync.js.map +1 -1
- package/dist/src/faf-core/engines/dependency-tsa.js.map +1 -1
- package/dist/src/faf-core/fix-once/colors.js +1 -1
- package/dist/src/faf-core/fix-once/colors.js.map +1 -1
- package/dist/src/faf-core/parsers/agents-parser.d.ts +15 -0
- package/dist/src/faf-core/parsers/agents-parser.js +29 -123
- package/dist/src/faf-core/parsers/agents-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/conductor-parser.js +1 -1
- package/dist/src/faf-core/parsers/conductor-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/cursorrules-parser.d.ts +15 -0
- package/dist/src/faf-core/parsers/cursorrules-parser.js +54 -111
- package/dist/src/faf-core/parsers/cursorrules-parser.js.map +1 -1
- package/dist/src/faf-core/parsers/faf-git-generator.js +0 -1
- package/dist/src/faf-core/parsers/faf-git-generator.js.map +1 -1
- package/dist/src/faf-core/parsers/gemini-parser.d.ts +10 -0
- package/dist/src/faf-core/parsers/gemini-parser.js +19 -77
- package/dist/src/faf-core/parsers/gemini-parser.js.map +1 -1
- package/dist/src/handlers/engine-adapter.d.ts +13 -12
- package/dist/src/handlers/engine-adapter.js +124 -688
- package/dist/src/handlers/engine-adapter.js.map +1 -1
- package/dist/src/handlers/resources.d.ts +19 -1
- package/dist/src/handlers/resources.js +108 -23
- package/dist/src/handlers/resources.js.map +1 -1
- package/dist/src/handlers/skills.d.ts +70 -0
- package/dist/src/handlers/skills.js +174 -0
- package/dist/src/handlers/skills.js.map +1 -0
- package/dist/src/handlers/tools.d.ts +41 -5
- package/dist/src/handlers/tools.js +213 -258
- package/dist/src/handlers/tools.js.map +1 -1
- package/dist/src/server.d.ts +4 -0
- package/dist/src/server.js +51 -6
- package/dist/src/server.js.map +1 -1
- package/dist/src/utils/faf-cli-bridge.d.ts +2 -0
- package/dist/src/utils/faf-cli-bridge.js +16 -0
- package/dist/src/utils/faf-cli-bridge.js.map +1 -1
- package/package.json +17 -14
- package/project.faf +23 -5
- package/scripts/check-engines.mjs +53 -0
- package/scripts/run-tests.sh +54 -0
- package/scripts/sync-version.js +33 -19
- package/skills/faf-ide/SKILL.md +40 -0
- package/dist/src/config/visibility.d.ts +0 -41
- package/dist/src/config/visibility.js +0 -158
- package/dist/src/config/visibility.js.map +0 -1
- package/dist/src/faf-core/commands/audit.d.ts +0 -21
- package/dist/src/faf-core/commands/audit.js +0 -83
- package/dist/src/faf-core/commands/audit.js.map +0 -1
- package/dist/src/faf-core/commands/auto.d.ts +0 -25
- package/dist/src/faf-core/commands/auto.js +0 -74
- package/dist/src/faf-core/commands/auto.js.map +0 -1
- package/dist/src/faf-core/commands/doctor.d.ts +0 -17
- package/dist/src/faf-core/commands/doctor.js +0 -198
- package/dist/src/faf-core/commands/doctor.js.map +0 -1
- package/dist/src/faf-core/commands/enhance.d.ts +0 -46
- package/dist/src/faf-core/commands/enhance.js +0 -360
- package/dist/src/faf-core/commands/enhance.js.map +0 -1
- package/dist/src/faf-core/commands/formats.d.ts +0 -22
- package/dist/src/faf-core/commands/formats.js +0 -117
- package/dist/src/faf-core/commands/formats.js.map +0 -1
- package/dist/src/faf-core/commands/human.d.ts +0 -27
- package/dist/src/faf-core/commands/human.js +0 -183
- package/dist/src/faf-core/commands/human.js.map +0 -1
- package/dist/src/faf-core/commands/init.d.ts +0 -26
- package/dist/src/faf-core/commands/init.js +0 -114
- package/dist/src/faf-core/commands/init.js.map +0 -1
- package/dist/src/faf-core/commands/innit.d.ts +0 -7
- package/dist/src/faf-core/commands/innit.js +0 -13
- package/dist/src/faf-core/commands/innit.js.map +0 -1
- package/dist/src/faf-core/commands/migrate.d.ts +0 -15
- package/dist/src/faf-core/commands/migrate.js +0 -86
- package/dist/src/faf-core/commands/migrate.js.map +0 -1
- package/dist/src/faf-core/commands/quick.d.ts +0 -16
- package/dist/src/faf-core/commands/quick.js +0 -184
- package/dist/src/faf-core/commands/quick.js.map +0 -1
- package/dist/src/faf-core/commands/readme.d.ts +0 -47
- package/dist/src/faf-core/commands/readme.js +0 -361
- package/dist/src/faf-core/commands/readme.js.map +0 -1
- package/dist/src/faf-core/commands/score.d.ts +0 -47
- package/dist/src/faf-core/commands/score.js +0 -49
- package/dist/src/faf-core/commands/score.js.map +0 -1
- package/dist/src/faf-core/commands/update.d.ts +0 -12
- package/dist/src/faf-core/commands/update.js +0 -46
- package/dist/src/faf-core/commands/update.js.map +0 -1
- package/dist/src/faf-core/commands/validate.d.ts +0 -21
- package/dist/src/faf-core/commands/validate.js +0 -81
- package/dist/src/faf-core/commands/validate.js.map +0 -1
- package/dist/src/faf-core/compiler/faf-compiler.d.ts +0 -138
- package/dist/src/faf-core/compiler/faf-compiler.js +0 -1362
- package/dist/src/faf-core/compiler/faf-compiler.js.map +0 -1
- package/dist/src/faf-core/engines/fab-formats-processor.d.ts +0 -166
- package/dist/src/faf-core/engines/fab-formats-processor.js +0 -1274
- package/dist/src/faf-core/engines/fab-formats-processor.js.map +0 -1
- package/dist/src/faf-core/engines/faf-dna.d.ts +0 -159
- package/dist/src/faf-core/engines/faf-dna.js +0 -555
- package/dist/src/faf-core/engines/faf-dna.js.map +0 -1
- package/dist/src/faf-core/engines/relentless-context-extractor.d.ts +0 -100
- package/dist/src/faf-core/engines/relentless-context-extractor.js +0 -625
- package/dist/src/faf-core/engines/relentless-context-extractor.js.map +0 -1
- package/dist/src/faf-core/fix-once/types.d.ts +0 -257
- package/dist/src/faf-core/fix-once/types.js +0 -26
- package/dist/src/faf-core/fix-once/types.js.map +0 -1
- package/dist/src/faf-core/generators/faf-generator-championship.d.ts +0 -16
- package/dist/src/faf-core/generators/faf-generator-championship.js +0 -463
- package/dist/src/faf-core/generators/faf-generator-championship.js.map +0 -1
- package/dist/src/faf-core/inject.d.ts +0 -19
- package/dist/src/faf-core/inject.js +0 -57
- package/dist/src/faf-core/inject.js.map +0 -1
- package/dist/src/faf-core/parsers/index.d.ts +0 -12
- package/dist/src/faf-core/parsers/index.js +0 -29
- package/dist/src/faf-core/parsers/index.js.map +0 -1
- package/dist/src/faf-core/utils/balance-visualizer.d.ts +0 -37
- package/dist/src/faf-core/utils/balance-visualizer.js +0 -197
- package/dist/src/faf-core/utils/balance-visualizer.js.map +0 -1
- package/dist/src/faf-core/utils/championship-style.d.ts +0 -109
- package/dist/src/faf-core/utils/championship-style.js +0 -219
- package/dist/src/faf-core/utils/championship-style.js.map +0 -1
- package/dist/src/faf-core/utils/chrome-extension-detector.d.ts +0 -73
- package/dist/src/faf-core/utils/chrome-extension-detector.js +0 -268
- package/dist/src/faf-core/utils/chrome-extension-detector.js.map +0 -1
- package/dist/src/faf-core/utils/platform-detector.d.ts +0 -30
- package/dist/src/faf-core/utils/platform-detector.js +0 -218
- package/dist/src/faf-core/utils/platform-detector.js.map +0 -1
- package/dist/src/faf-core/utils/technical-credit.d.ts +0 -35
- package/dist/src/faf-core/utils/technical-credit.js +0 -286
- package/dist/src/faf-core/utils/technical-credit.js.map +0 -1
- package/dist/src/faf-core/utils/yaml-generator.d.ts +0 -41
- package/dist/src/faf-core/utils/yaml-generator.js +0 -360
- package/dist/src/faf-core/utils/yaml-generator.js.map +0 -1
- package/dist/src/handlers/behavioral-instruction.d.ts +0 -16
- package/dist/src/handlers/behavioral-instruction.js +0 -43
- package/dist/src/handlers/behavioral-instruction.js.map +0 -1
- package/dist/src/handlers/championship-tools.d.ts +0 -116
- package/dist/src/handlers/championship-tools.js +0 -2320
- package/dist/src/handlers/championship-tools.js.map +0 -1
- package/dist/src/handlers/cloud-handler.d.ts +0 -59
- package/dist/src/handlers/cloud-handler.js +0 -348
- package/dist/src/handlers/cloud-handler.js.map +0 -1
- package/dist/src/handlers/tool-registry.d.ts +0 -23
- package/dist/src/handlers/tool-registry.js +0 -68
- package/dist/src/handlers/tool-registry.js.map +0 -1
- package/dist/src/handlers/tool-types.d.ts +0 -167
- package/dist/src/handlers/tool-types.js +0 -7
- package/dist/src/handlers/tool-types.js.map +0 -1
- package/dist/src/test-all-functions.d.ts +0 -15
- package/dist/src/test-all-functions.js +0 -163
- package/dist/src/test-all-functions.js.map +0 -1
- package/dist/src/types/mcp-tools.d.ts +0 -53
- package/dist/src/types/mcp-tools.js +0 -77
- package/dist/src/types/mcp-tools.js.map +0 -1
- package/dist/src/types/tool-visibility.d.ts +0 -36
- package/dist/src/types/tool-visibility.js +0 -551
- package/dist/src/types/tool-visibility.js.map +0 -1
- package/dist/src/utils/auto-path-detection.d.ts +0 -26
- package/dist/src/utils/auto-path-detection.js +0 -198
- package/dist/src/utils/auto-path-detection.js.map +0 -1
- package/dist/src/utils/championship-format.d.ts +0 -30
- package/dist/src/utils/championship-format.js +0 -81
- package/dist/src/utils/championship-format.js.map +0 -1
- package/dist/src/utils/cli-detector.d.ts +0 -17
- package/dist/src/utils/cli-detector.js +0 -247
- package/dist/src/utils/cli-detector.js.map +0 -1
- package/dist/src/utils/display-protocol.d.ts +0 -57
- package/dist/src/utils/display-protocol.js +0 -131
- package/dist/src/utils/display-protocol.js.map +0 -1
- package/dist/src/utils/username-detector.d.ts +0 -27
- package/dist/src/utils/username-detector.js +0 -90
- package/dist/src/utils/username-detector.js.map +0 -1
- package/dist/src/utils/visual-style.d.ts +0 -62
- package/dist/src/utils/visual-style.js +0 -166
- package/dist/src/utils/visual-style.js.map +0 -1
- package/scripts/postinstall.js +0 -50
- package/skill/SKILL.md +0 -385
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "faf-mcp",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"mcpName": "one.faf/faf-mcp",
|
|
5
|
-
"description": "Persistent Project Context for Cursor, IDEs and VS Code. IANA-registered .faf format
|
|
5
|
+
"description": "Persistent Project Context for Cursor, IDEs and VS Code. IANA-registered .faf format. Curated core tools by default, full set via FAF_TOOLS=all.",
|
|
6
6
|
"icon": "./assets/icons/faf-icon-256.png",
|
|
7
7
|
"logo": "./assets/icons/faf-icon-256.png",
|
|
8
8
|
"displayName": ".faf 🐘",
|
|
@@ -11,11 +11,10 @@
|
|
|
11
11
|
"faf-mcp": "dist/src/index.js"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
+
"prebuild": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
14
15
|
"build": "tsc",
|
|
15
|
-
"start": "node start-http.js",
|
|
16
16
|
"dev": "ts-node src/server.ts",
|
|
17
17
|
"dev:stdio": "ts-node src/cli.ts --transport stdio",
|
|
18
|
-
"dev:http": "ts-node src/cli.ts --transport http-sse --port 3001",
|
|
19
18
|
"test": "bun test --isolate --timeout=120000 --path-ignore-patterns=\"**/performance.test.ts\"",
|
|
20
19
|
"test:performance": "bun test tests/performance.test.ts",
|
|
21
20
|
"test:mcp": "mcp-inspector stdio ts-node src/cli.ts",
|
|
@@ -23,13 +22,11 @@
|
|
|
23
22
|
"lint:fix": "eslint src/**/*.ts --fix",
|
|
24
23
|
"type-check": "tsc --noEmit",
|
|
25
24
|
"check:stylesheet": "node scripts/check-stylesheet-drift.mjs",
|
|
26
|
-
"
|
|
27
|
-
"format": "prettier --write \"src/**/*.ts\"",
|
|
25
|
+
"check:engines": "node scripts/check-engines.mjs",
|
|
28
26
|
"prepare": "npm run build",
|
|
29
27
|
"sync-version": "node scripts/sync-version.js",
|
|
30
|
-
"version": "npm run sync-version && git add project.faf",
|
|
31
|
-
"prepublishOnly": "npm run build",
|
|
32
|
-
"postinstall": "node scripts/postinstall.js",
|
|
28
|
+
"version": "npm run sync-version && git add project.faf server.json CHANGELOG.md docs/index.html AGENTS.md",
|
|
29
|
+
"prepublishOnly": "npm run build && npm run check:engines",
|
|
33
30
|
"debug": "node --inspect-brk=0.0.0.0:9229 -r ts-node/register src/cli.ts"
|
|
34
31
|
},
|
|
35
32
|
"keywords": [
|
|
@@ -82,16 +79,15 @@
|
|
|
82
79
|
},
|
|
83
80
|
"homepage": "https://faf.one",
|
|
84
81
|
"engines": {
|
|
85
|
-
"node": ">=
|
|
82
|
+
"node": ">=22.0.0"
|
|
86
83
|
},
|
|
87
84
|
"files": [
|
|
88
85
|
"dist/**/*",
|
|
89
86
|
"assets/**/*",
|
|
90
87
|
"scripts/**/*",
|
|
91
|
-
"
|
|
88
|
+
"skills/**",
|
|
92
89
|
"README.md",
|
|
93
90
|
"CLAUDE.md",
|
|
94
|
-
".faf",
|
|
95
91
|
"project.faf",
|
|
96
92
|
"LICENSE",
|
|
97
93
|
"CHANGELOG.md",
|
|
@@ -101,8 +97,8 @@
|
|
|
101
97
|
"access": "public"
|
|
102
98
|
},
|
|
103
99
|
"dependencies": {
|
|
104
|
-
"@modelcontextprotocol/sdk": "^1.
|
|
105
|
-
"faf-cli": "^
|
|
100
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
101
|
+
"faf-cli": "^7.12.0",
|
|
106
102
|
"faf-scoring-kernel": "^2.0.3",
|
|
107
103
|
"yaml": "^2.4.1"
|
|
108
104
|
},
|
|
@@ -114,5 +110,12 @@
|
|
|
114
110
|
"eslint": "^8.56.0",
|
|
115
111
|
"ts-node": "^10.9.2",
|
|
116
112
|
"typescript": "^5.9.3"
|
|
113
|
+
},
|
|
114
|
+
"overrides": {
|
|
115
|
+
"hono": ">=4.13.5",
|
|
116
|
+
"fast-uri": ">=4.1.2",
|
|
117
|
+
"ip-address": ">=10.3.1",
|
|
118
|
+
"brace-expansion@1": "1.1.18",
|
|
119
|
+
"brace-expansion@2": "2.1.4"
|
|
117
120
|
}
|
|
118
121
|
}
|
package/project.faf
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
faf_version: "3.0"
|
|
2
2
|
project:
|
|
3
3
|
name: faf-mcp
|
|
4
|
+
title: .FAF Context
|
|
5
|
+
version: 3.0.0
|
|
4
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".
|
|
5
7
|
main_language: TypeScript
|
|
6
8
|
type: mcp
|
|
@@ -12,11 +14,11 @@ stack:
|
|
|
12
14
|
ui_library: slotignored
|
|
13
15
|
state_management: slotignored
|
|
14
16
|
backend: MCP SDK (TS)
|
|
15
|
-
api_type: MCP (stdio
|
|
16
|
-
runtime: Node.js >=
|
|
17
|
+
api_type: MCP (stdio)
|
|
18
|
+
runtime: Node.js >=22
|
|
17
19
|
database: slotignored
|
|
18
20
|
connection: slotignored
|
|
19
|
-
hosting: npm
|
|
21
|
+
hosting: npm
|
|
20
22
|
build: TypeScript (tsc)
|
|
21
23
|
cicd: GitHub Actions
|
|
22
24
|
monorepo_tool: slotignored
|
|
@@ -30,8 +32,8 @@ human_context:
|
|
|
30
32
|
who: Developers using Claude, Cursor, Windsurf, VS Code, Cline, and any MCP-compatible IDE
|
|
31
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
|
|
32
34
|
why: Eliminate the 20-minute AI context tax — give AI instant project understanding in 30 seconds
|
|
33
|
-
where: npm · MCP Registry ·
|
|
34
|
-
when: Production/Stable —
|
|
35
|
+
where: npm · MCP Registry · any MCP-compatible IDE — people get it how they wish
|
|
36
|
+
when: Production/Stable — v3.0.0 The Compose Edition, WJTTC certified
|
|
35
37
|
how: npx faf-mcp or npm install -g faf-mcp, then add to your MCP config
|
|
36
38
|
monorepo:
|
|
37
39
|
packages_count: slotignored
|
|
@@ -39,3 +41,19 @@ monorepo:
|
|
|
39
41
|
versioning_strategy: slotignored
|
|
40
42
|
shared_configs: slotignored
|
|
41
43
|
remote_cache: slotignored
|
|
44
|
+
surfaces:
|
|
45
|
+
# Distribution map — the machine-checkable form of human_context.where. Score-neutral.
|
|
46
|
+
auto: # derived from manifests; regenerate with `faf surface --sync`
|
|
47
|
+
- { type: npm, id: faf-mcp, source: "package.json#name" }
|
|
48
|
+
- { type: github, id: Wolfe-Jam/faf-mcp, source: "package.json#repository" }
|
|
49
|
+
- { type: mcp-registry, id: one.faf/faf-mcp, state: active, source: "server.json#name" }
|
|
50
|
+
declared: # hand-authored: surfaces the manifests don't carry + targets
|
|
51
|
+
# v3.0: removed a false hosted-endpoint `mcpaas` entry here. The URL it
|
|
52
|
+
# pointed at serves MCPaaS (mcpaas-cf) — a different product with a
|
|
53
|
+
# different tool surface — not this package's tools. faf-mcp runs
|
|
54
|
+
# locally over stdio; no hosted deployment of it exists today.
|
|
55
|
+
- { type: homebrew, id: faf-mcp, status: live }
|
|
56
|
+
- { type: mcp-registry, id: io.github.Wolfe-Jam/faf-mcp, state: deprecated, superseded_by: one.faf/faf-mcp }
|
|
57
|
+
- { type: pulsemcp, id: faf-mcp, status: pending }
|
|
58
|
+
- { type: glama, id: faf-mcp, status: pending }
|
|
59
|
+
- { type: awesome-mcp-servers, id: faf-mcp, status: pending }
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// check-engines.mjs — the Node engine floor must match what CI actually runs.
|
|
3
|
+
//
|
|
4
|
+
// House rule (memory: feedback-node-engine-floor-and-terminal-release-test):
|
|
5
|
+
// `engines.node` == the LOWEST Node in the CI matrix, never aspirational. You
|
|
6
|
+
// can't raise the floor without dropping that Node from CI (a visible,
|
|
7
|
+
// deliberate act), and you can't claim support for a Node the gate never runs.
|
|
8
|
+
// faf-mcp receipt: the floor said >=18 while six production transitives
|
|
9
|
+
// required >=20 — every Node-18 install printed EBADENGINE six times.
|
|
10
|
+
//
|
|
11
|
+
// Runs in CI (Code Quality) and in prepublishOnly.
|
|
12
|
+
|
|
13
|
+
import { readFileSync } from 'node:fs';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
15
|
+
import { dirname, join } from 'node:path';
|
|
16
|
+
|
|
17
|
+
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
|
|
18
|
+
const read = (p) => readFileSync(join(root, p), 'utf8');
|
|
19
|
+
|
|
20
|
+
const enginesRaw = JSON.parse(read('package.json')).engines?.node ?? '';
|
|
21
|
+
const floorMatch = enginesRaw.match(/(\d+)/);
|
|
22
|
+
if (!floorMatch) {
|
|
23
|
+
console.error(`✗ package.json engines.node missing or unparseable: ${JSON.stringify(enginesRaw)}`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const floor = Number(floorMatch[1]);
|
|
27
|
+
|
|
28
|
+
// CI node matrix — this repo writes it as `node: [22.x, 24.x]`.
|
|
29
|
+
const ci = read('.github/workflows/ci.yml');
|
|
30
|
+
const matrixMatch = ci.match(/node:\s*\[([^\]]+)\]/);
|
|
31
|
+
if (!matrixMatch) {
|
|
32
|
+
console.error('✗ .github/workflows/ci.yml — could not find `node: [ ... ]` matrix');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
const matrix = matrixMatch[1]
|
|
36
|
+
.split(',')
|
|
37
|
+
.map((s) => Number(s.replace(/['"\s]/g, '').replace(/\.x$/, '')))
|
|
38
|
+
.filter((n) => Number.isFinite(n))
|
|
39
|
+
.sort((a, b) => a - b);
|
|
40
|
+
if (matrix.length === 0) {
|
|
41
|
+
console.error('✗ CI node matrix parsed empty');
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
const ciMin = matrix[0];
|
|
45
|
+
|
|
46
|
+
if (floor !== ciMin) {
|
|
47
|
+
console.error(
|
|
48
|
+
`✗ engine floor drift — package.json engines.node = ">=${floor}", CI node matrix low = ${ciMin} (matrix: ${matrix.join(', ')}).\n` +
|
|
49
|
+
` Make them equal: lower the floor to ${ciMin}, or drop Node ${ciMin} from ci.yml on purpose.`,
|
|
50
|
+
);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
console.log(`✓ engine floor ${floor} == CI matrix low ${ciMin} (matrix: ${matrix.join(', ')})`);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Test runner with a bounded, discriminating retry for the Linux bun --isolate
|
|
3
|
+
# epoll flake. (Ported from the grok-faf-mcp fix, 2026-06-26.)
|
|
4
|
+
#
|
|
5
|
+
# Background: `bun test --isolate` on Ubuntu intermittently errors with
|
|
6
|
+
# "EEXIST: file already exists, epoll_ctl"
|
|
7
|
+
# — a runner-shutdown race, not a code bug (green on macOS + Windows in the same
|
|
8
|
+
# matrix, re-runs pass). It manifests TWO ways: a fast error (epoll_ctl in
|
|
9
|
+
# output) OR a HARNESS HANG (no output, never exits).
|
|
10
|
+
#
|
|
11
|
+
# This wrapper:
|
|
12
|
+
# 1. On Linux, bounds the run with `timeout` so a HANG is killed (exit 124)
|
|
13
|
+
# instead of running unbounded → cancelled CI run → RED npm badge.
|
|
14
|
+
# 2. Retries ONCE on the flake — whether it failed fast (epoll_ctl) or hung (124).
|
|
15
|
+
# 3. Propagates any real failure immediately — does NOT mask.
|
|
16
|
+
# macOS/Windows run bare (no flake, no portable `timeout`).
|
|
17
|
+
#
|
|
18
|
+
# Doctrine: targeted retry, not blind retry. Real test failures still fail.
|
|
19
|
+
|
|
20
|
+
set -u
|
|
21
|
+
|
|
22
|
+
TMP=$(mktemp -t faf-tests.XXXXXX)
|
|
23
|
+
trap 'rm -f "$TMP"' EXIT
|
|
24
|
+
|
|
25
|
+
if [ "$(uname)" = "Linux" ] && command -v timeout >/dev/null 2>&1; then
|
|
26
|
+
TIMEOUT="timeout 600"
|
|
27
|
+
else
|
|
28
|
+
TIMEOUT=""
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Capture exit via file + $? (not `| tee` + PIPESTATUS, a bashism that masks the
|
|
32
|
+
# real exit under sh/dash → a timeout-killed hang would read as a false green).
|
|
33
|
+
$TIMEOUT bun test --isolate --timeout=120000 --path-ignore-patterns="**/performance.test.ts" "$@" > "$TMP" 2>&1
|
|
34
|
+
RC=$?
|
|
35
|
+
cat "$TMP"
|
|
36
|
+
|
|
37
|
+
if [ "$RC" -eq 0 ]; then
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Discriminating retry — the epoll flake, whether it fails fast (epoll_ctl in
|
|
42
|
+
# output) or HANGS (timeout kills it, exit 124). Real failures still propagate.
|
|
43
|
+
if grep -q "epoll_ctl" "$TMP" || [ "$RC" -eq 124 ]; then
|
|
44
|
+
echo ""
|
|
45
|
+
echo "============================================================"
|
|
46
|
+
echo "Detected Linux bun --isolate epoll flake (fail or hang) — retrying ONCE."
|
|
47
|
+
echo "============================================================"
|
|
48
|
+
echo ""
|
|
49
|
+
$TIMEOUT bun test --isolate --timeout=120000 --path-ignore-patterns="**/performance.test.ts" "$@"
|
|
50
|
+
exit $?
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Real failure — propagate original exit code, do NOT mask
|
|
54
|
+
exit "$RC"
|
package/scripts/sync-version.js
CHANGED
|
@@ -1,34 +1,48 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* Sync
|
|
4
|
-
* Run: npm run sync-version
|
|
5
|
-
*
|
|
3
|
+
* Sync the package.json version to every other stamp that carries it.
|
|
4
|
+
* Run: npm run sync-version (auto on `npm version` via the "version" hook)
|
|
5
|
+
*
|
|
6
|
+
* project.faf project.version
|
|
7
|
+
* server.json top-level version + packages[].version
|
|
8
|
+
* CHANGELOG.md <!-- faf: doc=changelog | latest=vX.Y.Z ... --> meta-stamp
|
|
9
|
+
* docs/index.html the version badge (guarded by wjttc-p0-no-false-hosted-claim)
|
|
10
|
+
* AGENTS.md the "· vX.Y.Z" stamp on the facts line
|
|
11
|
+
*
|
|
12
|
+
* Doc Gate 101 (/pubpro) refuses on any drift between these; this is what
|
|
13
|
+
* keeps them from drifting in the first place.
|
|
6
14
|
*/
|
|
7
15
|
|
|
8
16
|
const fs = require('fs');
|
|
9
17
|
const path = require('path');
|
|
10
18
|
|
|
11
|
-
const
|
|
12
|
-
const
|
|
19
|
+
const root = path.join(__dirname, '..');
|
|
20
|
+
const read = (f) => fs.readFileSync(path.join(root, f), 'utf-8');
|
|
21
|
+
const write = (f, s) => fs.writeFileSync(path.join(root, f), s);
|
|
22
|
+
const version = JSON.parse(read('package.json')).version;
|
|
23
|
+
const changed = [];
|
|
13
24
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
25
|
+
function sub(file, pattern, replacement, label) {
|
|
26
|
+
const before = read(file);
|
|
27
|
+
const after = before.replace(pattern, replacement);
|
|
28
|
+
if (after !== before) { write(file, after); changed.push(`${file} (${label})`); }
|
|
29
|
+
else if (!pattern.test(before)) console.warn(`⚠️ ${file}: no ${label} stamp found — nothing synced`);
|
|
30
|
+
}
|
|
18
31
|
|
|
19
|
-
|
|
20
|
-
|
|
32
|
+
try {
|
|
33
|
+
sub('project.faf', /^(\s*version:\s*).+$/m, `$1${version}`, 'project.version');
|
|
21
34
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
35
|
+
const serverJson = JSON.parse(read('server.json'));
|
|
36
|
+
let touched = false;
|
|
37
|
+
if (serverJson.version !== version) { serverJson.version = version; touched = true; }
|
|
38
|
+
for (const p of serverJson.packages ?? []) if (p.version !== version) { p.version = version; touched = true; }
|
|
39
|
+
if (touched) { write('server.json', JSON.stringify(serverJson, null, 2) + '\n'); changed.push('server.json (version, packages[].version)'); }
|
|
27
40
|
|
|
28
|
-
|
|
29
|
-
|
|
41
|
+
sub('CHANGELOG.md', /(<!-- faf: doc=changelog \| latest=v)\d+\.\d+\.\d+/, `$1${version}`, 'latest= meta-stamp');
|
|
42
|
+
sub('docs/index.html', /(id="versionBadge"[^>]*>[^<]*v)\d+\.\d+\.\d+/, `$1${version}`, 'version badge');
|
|
43
|
+
sub('AGENTS.md', /(·\s*v)\d+\.\d+\.\d+(?=\s*$)/m, `$1${version}`, 'facts-line stamp');
|
|
30
44
|
|
|
31
|
-
console.log(`Synced
|
|
45
|
+
console.log(changed.length ? `Synced v${version} → ${changed.join(', ')}` : `All stamps already at v${version}`);
|
|
32
46
|
} catch (error) {
|
|
33
47
|
console.error('Failed to sync version:', error.message);
|
|
34
48
|
process.exit(1);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: faf-ide
|
|
3
|
+
description: Use FAF context and IDE interop tools on this server — score, sync, platform formats; claim equals wire.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# faf-ide
|
|
7
|
+
|
|
8
|
+
Product playbook for **faf-mcp** (`one.faf/faf-mcp`) — IANA `.faf` project context over MCP for Cursor, VS Code, Windsurf, Cline-class hosts.
|
|
9
|
+
|
|
10
|
+
**Transport:** local stdio (`npx` / `bunx faf-mcp`). Skills guide; tools act.
|
|
11
|
+
|
|
12
|
+
## Tools (call these)
|
|
13
|
+
|
|
14
|
+
| Tool | When |
|
|
15
|
+
|------|------|
|
|
16
|
+
| `faf_auto` | Zero → context in one shot (init, detect, sync, score) |
|
|
17
|
+
| `faf_init` | Create or enhance `project.faf` |
|
|
18
|
+
| `faf_score` | AI-readiness 0–100% + gaps |
|
|
19
|
+
| `faf_context` | Current project context snapshot |
|
|
20
|
+
| `faf_sync` | Reconcile `project.faf` with package.json / git (dry-run; `apply:true` writes) |
|
|
21
|
+
| `faf_bi_sync` | Write CLAUDE.md + IDE format files from `project.faf` |
|
|
22
|
+
| `faf_cursor` | Cursor / `.cursorrules` interop |
|
|
23
|
+
| `faf_agents` | `AGENTS.md` interop |
|
|
24
|
+
| `faf_gemini` | Gemini context interop |
|
|
25
|
+
| `faf_about` | What `.faf` is (format overview) |
|
|
26
|
+
|
|
27
|
+
Default `tools/list` is a curated Core set; more tools may exist when `FAF_TOOLS=all`. Only call tools this server lists.
|
|
28
|
+
|
|
29
|
+
## Rules
|
|
30
|
+
|
|
31
|
+
1. Prefer **structured `.faf`** over free-form chat memory for project facts.
|
|
32
|
+
2. **Claim equals wire** — only tools advertised by this server.
|
|
33
|
+
3. **No secrets** in skill text or tool args you do not own.
|
|
34
|
+
4. **Origin** — served by faf-mcp (`skills/*` + `resources/read`); not a remote install authority.
|
|
35
|
+
|
|
36
|
+
## Flow
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
initialize → skills/list → resources/read(skill://faf-ide/SKILL.md) → tools/call
|
|
40
|
+
```
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🏎️ FAF Tool Visibility Configuration - v2.8.0
|
|
3
|
-
* Controls which tools are visible (core vs all)
|
|
4
|
-
* Championship-grade configuration management
|
|
5
|
-
*/
|
|
6
|
-
export interface VisibilityConfig {
|
|
7
|
-
showAdvanced: boolean;
|
|
8
|
-
source: 'env' | 'flag' | 'config' | 'default';
|
|
9
|
-
}
|
|
10
|
-
export interface FafConfig {
|
|
11
|
-
showAdvanced?: boolean;
|
|
12
|
-
[key: string]: unknown;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Get visibility configuration from multiple sources
|
|
16
|
-
* Priority: ENV var > config file > default
|
|
17
|
-
*/
|
|
18
|
-
export declare function getVisibilityConfig(): VisibilityConfig;
|
|
19
|
-
/**
|
|
20
|
-
* Read configuration from .fafrc file
|
|
21
|
-
* Checks multiple locations:
|
|
22
|
-
* 1. ~/.fafrc (home directory)
|
|
23
|
-
* 2. ./.fafrc (current working directory)
|
|
24
|
-
*/
|
|
25
|
-
export declare function readConfigFile(): FafConfig | null;
|
|
26
|
-
/**
|
|
27
|
-
* Write configuration to ~/.fafrc file
|
|
28
|
-
*/
|
|
29
|
-
export declare function writeConfigFile(config: FafConfig): boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Enable advanced tools
|
|
32
|
-
*/
|
|
33
|
-
export declare function enableAdvancedTools(): boolean;
|
|
34
|
-
/**
|
|
35
|
-
* Disable advanced tools (show core only)
|
|
36
|
-
*/
|
|
37
|
-
export declare function disableAdvancedTools(): boolean;
|
|
38
|
-
/**
|
|
39
|
-
* Get current tool visibility status (for logging)
|
|
40
|
-
*/
|
|
41
|
-
export declare function getVisibilityStatus(): string;
|
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* 🏎️ FAF Tool Visibility Configuration - v2.8.0
|
|
4
|
-
* Controls which tools are visible (core vs all)
|
|
5
|
-
* Championship-grade configuration management
|
|
6
|
-
*/
|
|
7
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
-
if (k2 === undefined) k2 = k;
|
|
9
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
-
}
|
|
13
|
-
Object.defineProperty(o, k2, desc);
|
|
14
|
-
}) : (function(o, m, k, k2) {
|
|
15
|
-
if (k2 === undefined) k2 = k;
|
|
16
|
-
o[k2] = m[k];
|
|
17
|
-
}));
|
|
18
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
-
}) : function(o, v) {
|
|
21
|
-
o["default"] = v;
|
|
22
|
-
});
|
|
23
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
-
var ownKeys = function(o) {
|
|
25
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
-
var ar = [];
|
|
27
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
-
return ar;
|
|
29
|
-
};
|
|
30
|
-
return ownKeys(o);
|
|
31
|
-
};
|
|
32
|
-
return function (mod) {
|
|
33
|
-
if (mod && mod.__esModule) return mod;
|
|
34
|
-
var result = {};
|
|
35
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
-
__setModuleDefault(result, mod);
|
|
37
|
-
return result;
|
|
38
|
-
};
|
|
39
|
-
})();
|
|
40
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
41
|
-
exports.getVisibilityConfig = getVisibilityConfig;
|
|
42
|
-
exports.readConfigFile = readConfigFile;
|
|
43
|
-
exports.writeConfigFile = writeConfigFile;
|
|
44
|
-
exports.enableAdvancedTools = enableAdvancedTools;
|
|
45
|
-
exports.disableAdvancedTools = disableAdvancedTools;
|
|
46
|
-
exports.getVisibilityStatus = getVisibilityStatus;
|
|
47
|
-
const fs = __importStar(require("fs"));
|
|
48
|
-
const path = __importStar(require("path"));
|
|
49
|
-
const os = __importStar(require("os"));
|
|
50
|
-
/**
|
|
51
|
-
* Get visibility configuration from multiple sources
|
|
52
|
-
* Priority: ENV var > config file > default
|
|
53
|
-
*/
|
|
54
|
-
function getVisibilityConfig() {
|
|
55
|
-
// 1. Check ENV: FAF_MCP_SHOW_ADVANCED=true
|
|
56
|
-
if (process.env.FAF_MCP_SHOW_ADVANCED === 'true') {
|
|
57
|
-
return { showAdvanced: true, source: 'env' };
|
|
58
|
-
}
|
|
59
|
-
// 2. Check config file: ~/.fafrc or .fafrc
|
|
60
|
-
const configFile = readConfigFile();
|
|
61
|
-
if (configFile?.showAdvanced === true) {
|
|
62
|
-
return { showAdvanced: true, source: 'config' };
|
|
63
|
-
}
|
|
64
|
-
// 3. Default: core only (changed from "show all" to align with spec)
|
|
65
|
-
// NOTE: For backward compatibility during transition, you may want to
|
|
66
|
-
// temporarily set default to `true` and notify users to update config
|
|
67
|
-
return { showAdvanced: false, source: 'default' };
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Read configuration from .fafrc file
|
|
71
|
-
* Checks multiple locations:
|
|
72
|
-
* 1. ~/.fafrc (home directory)
|
|
73
|
-
* 2. ./.fafrc (current working directory)
|
|
74
|
-
*/
|
|
75
|
-
function readConfigFile() {
|
|
76
|
-
const configPaths = [
|
|
77
|
-
path.join(os.homedir(), '.fafrc'),
|
|
78
|
-
path.join(process.cwd(), '.fafrc'),
|
|
79
|
-
];
|
|
80
|
-
for (const configPath of configPaths) {
|
|
81
|
-
try {
|
|
82
|
-
if (fs.existsSync(configPath)) {
|
|
83
|
-
const content = fs.readFileSync(configPath, 'utf-8');
|
|
84
|
-
// Support both JSON and simple key=value format
|
|
85
|
-
if (content.trim().startsWith('{')) {
|
|
86
|
-
// JSON format
|
|
87
|
-
return JSON.parse(content);
|
|
88
|
-
}
|
|
89
|
-
else {
|
|
90
|
-
// Simple key=value format
|
|
91
|
-
const config = {};
|
|
92
|
-
const lines = content.split('\n');
|
|
93
|
-
for (const line of lines) {
|
|
94
|
-
const trimmed = line.trim();
|
|
95
|
-
if (!trimmed || trimmed.startsWith('#'))
|
|
96
|
-
continue;
|
|
97
|
-
const [key, value] = trimmed.split('=').map((s) => s.trim());
|
|
98
|
-
if (key === 'showAdvanced' || key === 'FAF_SHOW_ADVANCED') {
|
|
99
|
-
config.showAdvanced = value === 'true';
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return config;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
catch (error) {
|
|
107
|
-
// Silently ignore config file errors - graceful degradation
|
|
108
|
-
// Config file is optional, errors are non-critical
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* Write configuration to ~/.fafrc file
|
|
115
|
-
*/
|
|
116
|
-
function writeConfigFile(config) {
|
|
117
|
-
const configPath = path.join(os.homedir(), '.fafrc');
|
|
118
|
-
try {
|
|
119
|
-
const content = JSON.stringify(config, null, 2);
|
|
120
|
-
fs.writeFileSync(configPath, content, 'utf-8');
|
|
121
|
-
return true;
|
|
122
|
-
}
|
|
123
|
-
catch (error) {
|
|
124
|
-
// Silent failure - config file write is optional
|
|
125
|
-
return false;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
/**
|
|
129
|
-
* Enable advanced tools
|
|
130
|
-
*/
|
|
131
|
-
function enableAdvancedTools() {
|
|
132
|
-
const config = readConfigFile() || {};
|
|
133
|
-
config.showAdvanced = true;
|
|
134
|
-
return writeConfigFile(config);
|
|
135
|
-
}
|
|
136
|
-
/**
|
|
137
|
-
* Disable advanced tools (show core only)
|
|
138
|
-
*/
|
|
139
|
-
function disableAdvancedTools() {
|
|
140
|
-
const config = readConfigFile() || {};
|
|
141
|
-
config.showAdvanced = false;
|
|
142
|
-
return writeConfigFile(config);
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Get current tool visibility status (for logging)
|
|
146
|
-
*/
|
|
147
|
-
function getVisibilityStatus() {
|
|
148
|
-
const config = getVisibilityConfig();
|
|
149
|
-
const toolCount = config.showAdvanced ? '51 (ALL)' : '20 (CORE)';
|
|
150
|
-
const sourceEmoji = {
|
|
151
|
-
env: '🌍',
|
|
152
|
-
flag: '🚩',
|
|
153
|
-
config: '⚙️',
|
|
154
|
-
default: '🏁',
|
|
155
|
-
};
|
|
156
|
-
return `${sourceEmoji[config.source]} ${toolCount} tools via ${config.source.toUpperCase()}`;
|
|
157
|
-
}
|
|
158
|
-
//# sourceMappingURL=visibility.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"visibility.js","sourceRoot":"","sources":["../../../src/config/visibility.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 🔍 faf audit - Comprehensive Quality Audit (Mk3 Bundled)
|
|
3
|
-
* Audit project.faf quality and completeness
|
|
4
|
-
*/
|
|
5
|
-
export interface AuditOptions {
|
|
6
|
-
json?: boolean;
|
|
7
|
-
verbose?: boolean;
|
|
8
|
-
}
|
|
9
|
-
export interface AuditResult {
|
|
10
|
-
success: boolean;
|
|
11
|
-
score: number;
|
|
12
|
-
grade: string;
|
|
13
|
-
issues: Array<{
|
|
14
|
-
severity: 'high' | 'medium' | 'low';
|
|
15
|
-
message: string;
|
|
16
|
-
fix?: string;
|
|
17
|
-
}>;
|
|
18
|
-
strengths: string[];
|
|
19
|
-
message: string;
|
|
20
|
-
}
|
|
21
|
-
export declare function auditFafFile(projectPath?: string, options?: AuditOptions): Promise<AuditResult>;
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* 🔍 faf audit - Comprehensive Quality Audit (Mk3 Bundled)
|
|
4
|
-
* Audit project.faf quality and completeness
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.auditFafFile = auditFafFile;
|
|
8
|
-
const fs_1 = require("fs");
|
|
9
|
-
const yaml_1 = require("../fix-once/yaml");
|
|
10
|
-
const file_utils_1 = require("../utils/file-utils");
|
|
11
|
-
const faf_compiler_1 = require("../compiler/faf-compiler");
|
|
12
|
-
async function auditFafFile(projectPath, options = {}) {
|
|
13
|
-
try {
|
|
14
|
-
const fafPath = projectPath ? `${projectPath}/project.faf` : await (0, file_utils_1.findFafFile)();
|
|
15
|
-
if (!fafPath || !await (0, file_utils_1.fileExists)(fafPath)) {
|
|
16
|
-
return {
|
|
17
|
-
success: false,
|
|
18
|
-
score: 0,
|
|
19
|
-
grade: 'F',
|
|
20
|
-
issues: [{ severity: 'high', message: 'No project.faf file found', fix: 'Run faf init' }],
|
|
21
|
-
strengths: [],
|
|
22
|
-
message: 'No project.faf file found'
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
// Read and parse
|
|
26
|
-
const content = await fs_1.promises.readFile(fafPath, 'utf-8');
|
|
27
|
-
const fafData = (0, yaml_1.parse)(content);
|
|
28
|
-
// Run compiler scoring
|
|
29
|
-
const compiler = new faf_compiler_1.FafCompiler();
|
|
30
|
-
const scoreResult = await compiler.compile(fafPath);
|
|
31
|
-
const issues = [];
|
|
32
|
-
const strengths = [];
|
|
33
|
-
// Audit checks
|
|
34
|
-
if (!fafData.project?.name) {
|
|
35
|
-
issues.push({ severity: 'high', message: 'Missing project name', fix: 'Add project.name field' });
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
strengths.push('Project name defined');
|
|
39
|
-
}
|
|
40
|
-
if (!fafData.project?.goal) {
|
|
41
|
-
issues.push({ severity: 'medium', message: 'Missing project goal', fix: 'Add project.goal field' });
|
|
42
|
-
}
|
|
43
|
-
else {
|
|
44
|
-
strengths.push('Project goal defined');
|
|
45
|
-
}
|
|
46
|
-
if (!fafData.stack?.frontend && !fafData.stack?.backend) {
|
|
47
|
-
issues.push({ severity: 'medium', message: 'Stack information incomplete', fix: 'Add stack details' });
|
|
48
|
-
}
|
|
49
|
-
else {
|
|
50
|
-
strengths.push('Stack information present');
|
|
51
|
-
}
|
|
52
|
-
if (!fafData.instant_context?.what_building) {
|
|
53
|
-
issues.push({ severity: 'low', message: 'Missing instant context', fix: 'Add what_building description' });
|
|
54
|
-
}
|
|
55
|
-
else {
|
|
56
|
-
strengths.push('Instant context defined');
|
|
57
|
-
}
|
|
58
|
-
// Determine grade
|
|
59
|
-
const grade = scoreResult.score >= 90 ? 'A' :
|
|
60
|
-
scoreResult.score >= 80 ? 'B' :
|
|
61
|
-
scoreResult.score >= 70 ? 'C' :
|
|
62
|
-
scoreResult.score >= 60 ? 'D' : 'F';
|
|
63
|
-
return {
|
|
64
|
-
success: true,
|
|
65
|
-
score: scoreResult.score,
|
|
66
|
-
grade,
|
|
67
|
-
issues,
|
|
68
|
-
strengths,
|
|
69
|
-
message: `Audit complete - Score: ${scoreResult.score}% (Grade: ${grade})`
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
return {
|
|
74
|
-
success: false,
|
|
75
|
-
score: 0,
|
|
76
|
-
grade: 'F',
|
|
77
|
-
issues: [{ severity: 'high', message: error instanceof Error ? error.message : 'Audit failed' }],
|
|
78
|
-
strengths: [],
|
|
79
|
-
message: 'Audit failed'
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
//# sourceMappingURL=audit.js.map
|