faf-cli 6.3.3 → 6.4.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/dist/index.js CHANGED
@@ -2,3 +2,6 @@ import{createRequire as O}from"node:module";var E=Object.defineProperty;var I=(x
2
2
 
3
3
  Run: npm install faf-scoring-kernel
4
4
  `)}return z}function V(x){return JSON.parse(_().score_faf(x))}function W(x){return JSON.parse(_().score_faf_enterprise(x))}function j(x){return _().validate_faf(x)}function C(x){return _().compile_fafb(x)}function G(x){return JSON.parse(_().decompile_fafb(x))}function f(x){return JSON.parse(_().fafb_info(x))}function m(x){return JSON.parse(_().score_fafb(x))}function K(){return _().sdk_version()}export{R as validateFaf,U as slotsByCategory,D as kernel,$ as isPlaceholder,Y as getTier,h as getNextTier,M as enrichScore,F as TIERS,T as SLOT_BY_PATH,p as SLOTS,A as PLACEHOLDERS,Z as ENTERPRISE_SLOTS,X as BASE_SLOTS};
5
+
6
+ //# debugId=DC6FDBAB48D1F38D64756E2164756E21
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/slots.ts", "../src/ui/colors.ts", "../src/core/tiers.ts", "../src/core/scorer.ts", "../src/core/schema.ts", "../src/wasm/kernel.ts"],
4
+ "sourcesContent": [
5
+ "import type { SlotDef, SlotCategory } from './types.js';\n\n/** All 33 Mk4 canonical slots */\nexport const SLOTS: SlotDef[] = [\n // Project Meta (3)\n { index: 1, path: 'project.name', description: 'Project name', category: 'project' },\n { index: 2, path: 'project.goal', description: 'What the project does', category: 'project' },\n { index: 3, path: 'project.main_language', description: 'Primary language', category: 'project' },\n\n // Human Context (6)\n { index: 4, path: 'human_context.who', description: 'Who is building this', category: 'human' },\n { index: 5, path: 'human_context.what', description: 'What are they building', category: 'human' },\n { index: 6, path: 'human_context.why', description: 'Why does it exist', category: 'human' },\n { index: 7, path: 'human_context.where', description: 'Where does it run', category: 'human' },\n { index: 8, path: 'human_context.when', description: 'When was it started / timeline', category: 'human' },\n { index: 9, path: 'human_context.how', description: 'How is it built', category: 'human' },\n\n // Frontend Stack (4)\n { index: 10, path: 'stack.frontend', description: 'Framework (React, Svelte, etc.)', category: 'frontend' },\n { index: 11, path: 'stack.css_framework', description: 'CSS framework', category: 'frontend' },\n { index: 12, path: 'stack.ui_library', description: 'UI component library', category: 'frontend' },\n { index: 13, path: 'stack.state_management', description: 'State management', category: 'frontend' },\n\n // Backend Stack (5)\n { index: 14, path: 'stack.backend', description: 'Backend framework', category: 'backend' },\n { index: 15, path: 'stack.api_type', description: 'API style (REST, GraphQL, etc.)', category: 'backend' },\n { index: 16, path: 'stack.runtime', description: 'Runtime (Node, Bun, Python, etc.)', category: 'backend' },\n { index: 17, path: 'stack.database', description: 'Database', category: 'backend' },\n { index: 18, path: 'stack.connection', description: 'Connection method (Prisma, etc.)', category: 'backend' },\n\n // Universal Stack (3)\n { index: 19, path: 'stack.hosting', description: 'Hosting platform', category: 'universal' },\n { index: 20, path: 'stack.build', description: 'Build tool', category: 'universal' },\n { index: 21, path: 'stack.cicd', description: 'CI/CD', category: 'universal' },\n\n // Enterprise Infra (5)\n { index: 22, path: 'stack.monorepo_tool', description: 'Monorepo tool', category: 'enterprise_infra' },\n { index: 23, path: 'stack.package_manager', description: 'Package manager', category: 'enterprise_infra' },\n { index: 24, path: 'stack.workspaces', description: 'Workspace configuration', category: 'enterprise_infra' },\n { index: 25, path: 'monorepo.packages_count', description: 'Number of packages', category: 'enterprise_infra' },\n { index: 26, path: 'monorepo.build_orchestrator', description: 'Build orchestration tool', category: 'enterprise_infra' },\n\n // Enterprise App (4)\n { index: 27, path: 'stack.admin', description: 'Admin panel', category: 'enterprise_app' },\n { index: 28, path: 'stack.cache', description: 'Caching layer', category: 'enterprise_app' },\n { index: 29, path: 'stack.search', description: 'Search engine', category: 'enterprise_app' },\n { index: 30, path: 'stack.storage', description: 'Object storage', category: 'enterprise_app' },\n\n // Enterprise Ops (3)\n { index: 31, path: 'monorepo.versioning_strategy', description: 'Version strategy', category: 'enterprise_ops' },\n { index: 32, path: 'monorepo.shared_configs', description: 'Shared configs', category: 'enterprise_ops' },\n { index: 33, path: 'monorepo.remote_cache', description: 'Remote build cache', category: 'enterprise_ops' },\n];\n\n/** Slot lookup by path */\nexport const SLOT_BY_PATH = new Map(SLOTS.map(s => [s.path, s]));\n\n/** Slots grouped by category */\nexport function slotsByCategory(category: SlotCategory): SlotDef[] {\n return SLOTS.filter(s => s.category === category);\n}\n\n/** Base-tier slots (1-21) — used by score_faf */\nexport const BASE_SLOTS = SLOTS.filter(s => s.index <= 21);\n\n/** Enterprise-tier slots (1-33) — used by score_faf_enterprise */\nexport const ENTERPRISE_SLOTS = SLOTS;\n\n/** Placeholder values treated as Empty */\nexport const PLACEHOLDERS = new Set([\n 'describe your project goal',\n 'development teams',\n 'cloud platform',\n 'null',\n 'none',\n 'unknown',\n 'n/a',\n 'not applicable',\n]);\n\n/** Check if a value is a placeholder (empty) */\nexport function isPlaceholder(value: unknown): boolean {\n if (value === null || value === undefined || value === '') return true;\n if (typeof value === 'string') {\n return PLACEHOLDERS.has(value.toLowerCase().trim());\n }\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && Object.keys(value as object).length === 0) return true;\n return false;\n}\n\n/** App-type to active category mapping for faf init */\nexport const APP_TYPE_CATEGORIES: Record<string, SlotCategory[]> = {\n cli: ['project', 'human'],\n library: ['project', 'human'],\n mcp: ['project', 'backend', 'human'],\n backend: ['project', 'backend', 'universal', 'human'],\n 'data-science': ['project', 'backend', 'human'],\n frontend: ['project', 'frontend', 'human'],\n fullstack: ['project', 'frontend', 'backend', 'universal', 'human'],\n svelte: ['project', 'frontend', 'backend', 'universal', 'human'],\n framework: ['project', 'frontend', 'backend', 'universal', 'human'],\n enterprise: ['project', 'frontend', 'backend', 'universal', 'human', 'enterprise_infra', 'enterprise_app', 'enterprise_ops'],\n};\n",
6
+ "// ANSI color helpers — zero deps\n// Design: black/white text by default. Cyan + orange are the only brand colors.\nconst esc = (code: string) => (s: string) => `\\x1b[${code}m${s}\\x1b[0m`;\n\nexport const bold = esc('1');\nexport const dim = esc('2');\nexport const italic = esc('3');\n\n// Brand colors only — no red/green/yellow rainbow\nexport const fafCyan = (s: string) => `\\x1b[38;2;0;212;212m${s}\\x1b[0m`; // #00D4D4\nexport const orange = (s: string) => `\\x1b[38;5;208m${s}\\x1b[0m`;\n",
7
+ "import type { TierInfo } from './types.js';\nimport { bold, dim, fafCyan, orange } from '../ui/colors.js';\n\n/** Tier boundaries — ordered from highest to lowest\n *\n * Indicators:\n * 🏆 trophy (earned at 100%)\n * ★ filled star (gold — orange)\n * ◆ filled diamond (silver — cyan)\n * ◇ open diamond (bronze — cyan)\n * ● filled circle (mid tiers)\n * ○ open circle (low — dim)\n * ♡ heart (empty — good luck)\n */\nexport const TIERS: TierInfo[] = [\n { name: 'TROPHY', indicator: `${orange('🏆')} ${orange('TROPHY')}`, threshold: 100 },\n { name: 'GOLD', indicator: `${orange(bold('★'))} ${orange('GOLD')}`, threshold: 99 },\n { name: 'SILVER', indicator: `${fafCyan('◆')} ${fafCyan('SILVER')}`, threshold: 95 },\n { name: 'BRONZE', indicator: `${fafCyan('◇')} ${fafCyan('BRONZE')}`, threshold: 85 },\n { name: 'GREEN', indicator: `${bold('●')} GREEN`, threshold: 70 },\n { name: 'YELLOW', indicator: `${dim('●')} YELLOW`, threshold: 55 },\n { name: 'RED', indicator: `${dim('○')} RED`, threshold: 1 },\n { name: 'WHITE', indicator: `${dim('♡')}`, threshold: 0 },\n];\n\n/** Get the display badge for a tier */\nexport function tierBadge(tier: TierInfo): string {\n return tier.indicator;\n}\n\n/** Get tier info for a given score */\nexport function getTier(score: number): TierInfo {\n for (const tier of TIERS) {\n if (score >= tier.threshold) return tier;\n }\n return TIERS[TIERS.length - 1]; // White\n}\n\n/** Get the next tier above the current score (for progress display) */\nexport function getNextTier(score: number): TierInfo | null {\n const current = getTier(score);\n const idx = TIERS.indexOf(current);\n return idx > 0 ? TIERS[idx - 1] : null;\n}\n",
8
+ "import type { KernelScoreResult, ScoreResult } from './types.js';\nimport { getTier } from './tiers.js';\n\n/** Convert kernel result into enriched ScoreResult */\nexport function enrichScore(kernel: KernelScoreResult): ScoreResult {\n return {\n score: kernel.score,\n tier: getTier(kernel.score),\n populated: kernel.populated,\n empty: kernel.empty,\n ignored: kernel.ignored,\n active: kernel.active,\n total: kernel.total,\n slots: kernel.slots,\n };\n}\n",
9
+ "import type { FafData } from './types.js';\n\n/** Validate a parsed .faf object */\nexport function validateFaf(data: unknown): { valid: boolean; errors: string[] } {\n const errors: string[] = [];\n\n if (!data || typeof data !== 'object') {\n errors.push('File is not a valid YAML mapping');\n return { valid: false, errors };\n }\n\n const faf = data as FafData;\n\n if (!faf.faf_version) {\n errors.push('Missing required field: faf_version');\n }\n\n if (!faf.project?.name) {\n errors.push('Missing required field: project.name');\n }\n\n return { valid: errors.length === 0, errors };\n}\n",
10
+ "import type { KernelScoreResult, FafbInfo } from '../core/types.js';\n\n// faf-scoring-kernel is CommonJS with synchronous WASM loading\n// eslint-disable-next-line @typescript-eslint/no-require-imports\nlet kernel: typeof import('faf-scoring-kernel') | null = null;\n\nfunction getKernel(): typeof import('faf-scoring-kernel') {\n if (!kernel) {\n try {\n kernel = require('faf-scoring-kernel');\n } catch {\n throw new Error(\n 'faf-scoring-kernel not installed.\\n\\n Run: npm install faf-scoring-kernel\\n'\n );\n }\n }\n return kernel;\n}\n\n/** Score a .faf YAML string (21 base slots) */\nexport function score(yaml: string): KernelScoreResult {\n return JSON.parse(getKernel().score_faf(yaml));\n}\n\n/** Score a .faf YAML string (33 enterprise slots) */\nexport function scoreEnterprise(yaml: string): KernelScoreResult {\n return JSON.parse(getKernel().score_faf_enterprise(yaml));\n}\n\n/** Validate .faf YAML */\nexport function validate(yaml: string): boolean {\n return getKernel().validate_faf(yaml);\n}\n\n/** Compile .faf YAML to FAFb binary */\nexport function compile(yaml: string): Uint8Array {\n return getKernel().compile_fafb(yaml);\n}\n\n/** Decompile FAFb binary to JSON info */\nexport function decompile(bytes: Uint8Array): FafbInfo {\n return JSON.parse(getKernel().decompile_fafb(bytes));\n}\n\n/** Get FAFb file metadata */\nexport function fafbInfo(bytes: Uint8Array): FafbInfo {\n return JSON.parse(getKernel().fafb_info(bytes));\n}\n\n/** Get FAFb binary metadata (name, version, source) */\nexport interface FafbMeta {\n source: string;\n name: string;\n faf_version: string;\n}\n\nexport function scoreFafb(bytes: Uint8Array): FafbMeta {\n return JSON.parse(getKernel().score_fafb(bytes));\n}\n\n/** Get WASM SDK version */\nexport function sdkVersion(): string {\n return getKernel().sdk_version();\n}\n"
11
+ ],
12
+ "mappings": "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",
13
+ "debugId": "DC6FDBAB48D1F38D64756E2164756E21",
14
+ "names": []
15
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "faf-cli",
3
- "version": "6.3.3",
3
+ "version": "6.4.1",
4
4
  "description": "Persistent AI Context Standard — project DNA for AI. IANA-registered. Anthropic-approved.",
5
5
  "type": "module",
6
6
  "icon": "https://faf.one/orange-smiley.svg",
@@ -24,11 +24,11 @@
24
24
  ],
25
25
  "scripts": {
26
26
  "dev": "bun src/cli.ts",
27
- "build": "bun build src/cli.ts --outfile dist/cli.js --target=node --minify --external faf-scoring-kernel --external open && bun build src/index.ts --outfile dist/index.js --target=node --minify --external faf-scoring-kernel --external open",
27
+ "build": "bun build src/cli.ts --outdir dist --target=node --minify --sourcemap=linked --external faf-scoring-kernel --external open && bun build src/index.ts --outdir dist --target=node --minify --sourcemap=linked --external faf-scoring-kernel --external open",
28
28
  "compile": "bun build src/cli.ts --compile --bytecode --minify --outfile faf",
29
29
  "compile:all": "bun build src/cli.ts --compile --bytecode --minify --target=bun-darwin-arm64 --outfile faf-darwin-arm64 && bun build src/cli.ts --compile --bytecode --minify --target=bun-darwin-x64 --outfile faf-darwin-x64 && bun build src/cli.ts --compile --bytecode --minify --target=bun-linux-x64 --outfile faf-linux-x64 && bun build src/cli.ts --compile --bytecode --minify --target=bun-windows-x64 --outfile faf-windows-x64.exe",
30
- "test": "bun test",
31
- "test:watch": "bun test --watch",
30
+ "test": "bun test --timeout=30000",
31
+ "test:watch": "bun test --watch --timeout=30000",
32
32
  "lint": "eslint src/**/*.ts",
33
33
  "format": "prettier --write 'src/**/*.ts'",
34
34
  "check:no-hardcode": "! grep -rEln '/(Users|home/runner|private/var)/' dist/ || (echo '❌ Hardcoded build-machine path leaked into dist — see grep output above. Externalize the offending dep in the build script.'; exit 1)",