faf-cli 5.2.0 → 6.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/README.md +80 -52
- package/dist/cli.js +313 -1884
- package/dist/index.js +4 -46
- package/package.json +27 -103
- package/project.faf +33 -141
- package/assets/project-faf-screenshot.png +0 -0
- package/dist/big-orange/bigo-push.d.ts +0 -18
- package/dist/big-orange/bigo-push.d.ts.map +0 -1
- package/dist/big-orange/bigo-push.js +0 -88
- package/dist/big-orange/bigo-push.js.map +0 -1
- package/dist/big-orange/compare.d.ts +0 -11
- package/dist/big-orange/compare.d.ts.map +0 -1
- package/dist/big-orange/compare.js +0 -179
- package/dist/big-orange/compare.js.map +0 -1
- package/dist/big-orange/faf-generator.d.ts +0 -22
- package/dist/big-orange/faf-generator.d.ts.map +0 -1
- package/dist/big-orange/faf-generator.js +0 -215
- package/dist/big-orange/faf-generator.js.map +0 -1
- package/dist/big-orange/index.d.ts +0 -7
- package/dist/big-orange/index.d.ts.map +0 -1
- package/dist/big-orange/index.js +0 -96
- package/dist/big-orange/index.js.map +0 -1
- package/dist/big-orange/types.d.ts +0 -62
- package/dist/big-orange/types.d.ts.map +0 -1
- package/dist/big-orange/types.js +0 -7
- package/dist/big-orange/types.js.map +0 -1
- package/dist/cli.d.ts +0 -8
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/agents.d.ts +0 -14
- package/dist/commands/agents.d.ts.map +0 -1
- package/dist/commands/agents.js +0 -353
- package/dist/commands/agents.js.map +0 -1
- package/dist/commands/ai-analyze.d.ts +0 -18
- package/dist/commands/ai-analyze.d.ts.map +0 -1
- package/dist/commands/ai-analyze.js +0 -190
- package/dist/commands/ai-analyze.js.map +0 -1
- package/dist/commands/ai-enhance.d.ts +0 -17
- package/dist/commands/ai-enhance.d.ts.map +0 -1
- package/dist/commands/ai-enhance.js +0 -275
- package/dist/commands/ai-enhance.js.map +0 -1
- package/dist/commands/antigravity.d.ts +0 -16
- package/dist/commands/antigravity.d.ts.map +0 -1
- package/dist/commands/antigravity.js +0 -398
- package/dist/commands/antigravity.js.map +0 -1
- package/dist/commands/audit.d.ts +0 -11
- package/dist/commands/audit.d.ts.map +0 -1
- package/dist/commands/audit.js +0 -148
- package/dist/commands/audit.js.map +0 -1
- package/dist/commands/auto.d.ts +0 -27
- package/dist/commands/auto.d.ts.map +0 -1
- package/dist/commands/auto.js +0 -498
- package/dist/commands/auto.js.map +0 -1
- package/dist/commands/bi-sync.d.ts +0 -50
- package/dist/commands/bi-sync.d.ts.map +0 -1
- package/dist/commands/bi-sync.js +0 -307
- package/dist/commands/bi-sync.js.map +0 -1
- package/dist/commands/chat.d.ts +0 -7
- package/dist/commands/chat.d.ts.map +0 -1
- package/dist/commands/chat.js +0 -415
- package/dist/commands/chat.js.map +0 -1
- package/dist/commands/check.d.ts +0 -31
- package/dist/commands/check.d.ts.map +0 -1
- package/dist/commands/check.js +0 -301
- package/dist/commands/check.js.map +0 -1
- package/dist/commands/clear.d.ts +0 -15
- package/dist/commands/clear.d.ts.map +0 -1
- package/dist/commands/clear.js +0 -167
- package/dist/commands/clear.js.map +0 -1
- package/dist/commands/compile.d.ts +0 -12
- package/dist/commands/compile.d.ts.map +0 -1
- package/dist/commands/compile.js +0 -51
- package/dist/commands/compile.js.map +0 -1
- package/dist/commands/conductor.d.ts +0 -15
- package/dist/commands/conductor.d.ts.map +0 -1
- package/dist/commands/conductor.js +0 -339
- package/dist/commands/conductor.js.map +0 -1
- package/dist/commands/convert.d.ts +0 -19
- package/dist/commands/convert.d.ts.map +0 -1
- package/dist/commands/convert.js +0 -99
- package/dist/commands/convert.js.map +0 -1
- package/dist/commands/credit.d.ts +0 -13
- package/dist/commands/credit.d.ts.map +0 -1
- package/dist/commands/credit.js +0 -149
- package/dist/commands/credit.js.map +0 -1
- package/dist/commands/cursor.d.ts +0 -13
- package/dist/commands/cursor.d.ts.map +0 -1
- package/dist/commands/cursor.js +0 -310
- package/dist/commands/cursor.js.map +0 -1
- package/dist/commands/decompile.d.ts +0 -9
- package/dist/commands/decompile.d.ts.map +0 -1
- package/dist/commands/decompile.js +0 -21
- package/dist/commands/decompile.js.map +0 -1
- package/dist/commands/demo.d.ts +0 -20
- package/dist/commands/demo.d.ts.map +0 -1
- package/dist/commands/demo.js +0 -205
- package/dist/commands/demo.js.map +0 -1
- package/dist/commands/doctor.d.ts +0 -6
- package/dist/commands/doctor.d.ts.map +0 -1
- package/dist/commands/doctor.js +0 -230
- package/dist/commands/doctor.js.map +0 -1
- package/dist/commands/drift.d.ts +0 -16
- package/dist/commands/drift.d.ts.map +0 -1
- package/dist/commands/drift.js +0 -524
- package/dist/commands/drift.js.map +0 -1
- package/dist/commands/edit-helper.d.ts +0 -6
- package/dist/commands/edit-helper.d.ts.map +0 -1
- package/dist/commands/edit-helper.js +0 -52
- package/dist/commands/edit-helper.js.map +0 -1
- package/dist/commands/edit.d.ts +0 -14
- package/dist/commands/edit.d.ts.map +0 -1
- package/dist/commands/edit.js +0 -196
- package/dist/commands/edit.js.map +0 -1
- package/dist/commands/enhance-real.d.ts +0 -18
- package/dist/commands/enhance-real.d.ts.map +0 -1
- package/dist/commands/enhance-real.js +0 -1164
- package/dist/commands/enhance-real.js.map +0 -1
- package/dist/commands/faf-auth.d.ts +0 -10
- package/dist/commands/faf-auth.d.ts.map +0 -1
- package/dist/commands/faf-auth.js +0 -162
- package/dist/commands/faf-auth.js.map +0 -1
- package/dist/commands/faf-dna.d.ts +0 -9
- package/dist/commands/faf-dna.d.ts.map +0 -1
- package/dist/commands/faf-dna.js +0 -141
- package/dist/commands/faf-dna.js.map +0 -1
- package/dist/commands/faf-log.d.ts +0 -9
- package/dist/commands/faf-log.d.ts.map +0 -1
- package/dist/commands/faf-log.js +0 -135
- package/dist/commands/faf-log.js.map +0 -1
- package/dist/commands/faf-recover.d.ts +0 -3
- package/dist/commands/faf-recover.d.ts.map +0 -1
- package/dist/commands/faf-recover.js +0 -296
- package/dist/commands/faf-recover.js.map +0 -1
- package/dist/commands/faf-update.d.ts +0 -9
- package/dist/commands/faf-update.d.ts.map +0 -1
- package/dist/commands/faf-update.js +0 -68
- package/dist/commands/faf-update.js.map +0 -1
- package/dist/commands/fam.d.ts +0 -15
- package/dist/commands/fam.d.ts.map +0 -1
- package/dist/commands/fam.js +0 -339
- package/dist/commands/fam.js.map +0 -1
- package/dist/commands/faq.d.ts +0 -12
- package/dist/commands/faq.d.ts.map +0 -1
- package/dist/commands/faq.js +0 -84
- package/dist/commands/faq.js.map +0 -1
- package/dist/commands/formats.d.ts +0 -12
- package/dist/commands/formats.d.ts.map +0 -1
- package/dist/commands/formats.js +0 -107
- package/dist/commands/formats.js.map +0 -1
- package/dist/commands/gemini.d.ts +0 -15
- package/dist/commands/gemini.d.ts.map +0 -1
- package/dist/commands/gemini.js +0 -357
- package/dist/commands/gemini.js.map +0 -1
- package/dist/commands/git.d.ts +0 -25
- package/dist/commands/git.d.ts.map +0 -1
- package/dist/commands/git.js +0 -365
- package/dist/commands/git.js.map +0 -1
- package/dist/commands/go.d.ts +0 -23
- package/dist/commands/go.d.ts.map +0 -1
- package/dist/commands/go.js +0 -283
- package/dist/commands/go.js.map +0 -1
- package/dist/commands/human.d.ts +0 -19
- package/dist/commands/human.d.ts.map +0 -1
- package/dist/commands/human.js +0 -204
- package/dist/commands/human.js.map +0 -1
- package/dist/commands/index.d.ts +0 -26
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -438
- package/dist/commands/index.js.map +0 -1
- package/dist/commands/init.d.ts +0 -19
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js +0 -409
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/lint.d.ts +0 -11
- package/dist/commands/lint.d.ts.map +0 -1
- package/dist/commands/lint.js +0 -233
- package/dist/commands/lint.js.map +0 -1
- package/dist/commands/memory.d.ts +0 -14
- package/dist/commands/memory.d.ts.map +0 -1
- package/dist/commands/memory.js +0 -293
- package/dist/commands/memory.js.map +0 -1
- package/dist/commands/migrate.d.ts +0 -11
- package/dist/commands/migrate.d.ts.map +0 -1
- package/dist/commands/migrate.js +0 -85
- package/dist/commands/migrate.js.map +0 -1
- package/dist/commands/notifications.d.ts +0 -12
- package/dist/commands/notifications.d.ts.map +0 -1
- package/dist/commands/notifications.js +0 -35
- package/dist/commands/notifications.js.map +0 -1
- package/dist/commands/plugin-install.d.ts +0 -20
- package/dist/commands/plugin-install.d.ts.map +0 -1
- package/dist/commands/plugin-install.js +0 -183
- package/dist/commands/plugin-install.js.map +0 -1
- package/dist/commands/pro.d.ts +0 -10
- package/dist/commands/pro.d.ts.map +0 -1
- package/dist/commands/pro.js +0 -113
- package/dist/commands/pro.js.map +0 -1
- package/dist/commands/quick.d.ts +0 -10
- package/dist/commands/quick.d.ts.map +0 -1
- package/dist/commands/quick.js +0 -207
- package/dist/commands/quick.js.map +0 -1
- package/dist/commands/ram.d.ts +0 -17
- package/dist/commands/ram.d.ts.map +0 -1
- package/dist/commands/ram.js +0 -322
- package/dist/commands/ram.js.map +0 -1
- package/dist/commands/readme.d.ts +0 -21
- package/dist/commands/readme.d.ts.map +0 -1
- package/dist/commands/readme.js +0 -519
- package/dist/commands/readme.js.map +0 -1
- package/dist/commands/rename.d.ts +0 -18
- package/dist/commands/rename.d.ts.map +0 -1
- package/dist/commands/rename.js +0 -212
- package/dist/commands/rename.js.map +0 -1
- package/dist/commands/score-v3.d.ts +0 -15
- package/dist/commands/score-v3.d.ts.map +0 -1
- package/dist/commands/score-v3.js +0 -224
- package/dist/commands/score-v3.js.map +0 -1
- package/dist/commands/score.d.ts +0 -16
- package/dist/commands/score.d.ts.map +0 -1
- package/dist/commands/score.js +0 -19
- package/dist/commands/score.js.map +0 -1
- package/dist/commands/search.d.ts +0 -16
- package/dist/commands/search.d.ts.map +0 -1
- package/dist/commands/search.js +0 -174
- package/dist/commands/search.js.map +0 -1
- package/dist/commands/share.d.ts +0 -17
- package/dist/commands/share.d.ts.map +0 -1
- package/dist/commands/share.js +0 -261
- package/dist/commands/share.js.map +0 -1
- package/dist/commands/show.d.ts +0 -10
- package/dist/commands/show.d.ts.map +0 -1
- package/dist/commands/show.js +0 -142
- package/dist/commands/show.js.map +0 -1
- package/dist/commands/sixws.d.ts +0 -6
- package/dist/commands/sixws.d.ts.map +0 -1
- package/dist/commands/sixws.js +0 -154
- package/dist/commands/sixws.js.map +0 -1
- package/dist/commands/skills.d.ts +0 -8
- package/dist/commands/skills.d.ts.map +0 -1
- package/dist/commands/skills.js +0 -43
- package/dist/commands/skills.js.map +0 -1
- package/dist/commands/stacks.d.ts +0 -51
- package/dist/commands/stacks.d.ts.map +0 -1
- package/dist/commands/stacks.js +0 -180
- package/dist/commands/stacks.js.map +0 -1
- package/dist/commands/status.d.ts +0 -14
- package/dist/commands/status.d.ts.map +0 -1
- package/dist/commands/status.js +0 -210
- package/dist/commands/status.js.map +0 -1
- package/dist/commands/sync.d.ts +0 -11
- package/dist/commands/sync.d.ts.map +0 -1
- package/dist/commands/sync.js +0 -543
- package/dist/commands/sync.js.map +0 -1
- package/dist/commands/taf-init.d.ts +0 -14
- package/dist/commands/taf-init.d.ts.map +0 -1
- package/dist/commands/taf-init.js +0 -138
- package/dist/commands/taf-init.js.map +0 -1
- package/dist/commands/taf-log.d.ts +0 -31
- package/dist/commands/taf-log.d.ts.map +0 -1
- package/dist/commands/taf-log.js +0 -351
- package/dist/commands/taf-log.js.map +0 -1
- package/dist/commands/taf-stars.d.ts +0 -8
- package/dist/commands/taf-stars.d.ts.map +0 -1
- package/dist/commands/taf-stars.js +0 -105
- package/dist/commands/taf-stars.js.map +0 -1
- package/dist/commands/taf-stats.d.ts +0 -8
- package/dist/commands/taf-stats.d.ts.map +0 -1
- package/dist/commands/taf-stats.js +0 -133
- package/dist/commands/taf-stats.js.map +0 -1
- package/dist/commands/taf-validate.d.ts +0 -8
- package/dist/commands/taf-validate.d.ts.map +0 -1
- package/dist/commands/taf-validate.js +0 -108
- package/dist/commands/taf-validate.js.map +0 -1
- package/dist/commands/taf.d.ts +0 -14
- package/dist/commands/taf.d.ts.map +0 -1
- package/dist/commands/taf.js +0 -106
- package/dist/commands/taf.js.map +0 -1
- package/dist/commands/todo.d.ts +0 -14
- package/dist/commands/todo.d.ts.map +0 -1
- package/dist/commands/todo.js +0 -282
- package/dist/commands/todo.js.map +0 -1
- package/dist/commands/trust.d.ts +0 -33
- package/dist/commands/trust.d.ts.map +0 -1
- package/dist/commands/trust.js +0 -308
- package/dist/commands/trust.js.map +0 -1
- package/dist/commands/tsa.d.ts +0 -9
- package/dist/commands/tsa.d.ts.map +0 -1
- package/dist/commands/tsa.js +0 -60
- package/dist/commands/tsa.js.map +0 -1
- package/dist/commands/validate.d.ts +0 -11
- package/dist/commands/validate.d.ts.map +0 -1
- package/dist/commands/validate.js +0 -64
- package/dist/commands/validate.js.map +0 -1
- package/dist/commands/verify.d.ts +0 -36
- package/dist/commands/verify.d.ts.map +0 -1
- package/dist/commands/verify.js +0 -194
- package/dist/commands/verify.js.map +0 -1
- package/dist/commands/version.d.ts +0 -5
- package/dist/commands/version.d.ts.map +0 -1
- package/dist/commands/version.js +0 -29
- package/dist/commands/version.js.map +0 -1
- package/dist/commands/vibe.d.ts +0 -7
- package/dist/commands/vibe.d.ts.map +0 -1
- package/dist/commands/vibe.js +0 -73
- package/dist/commands/vibe.js.map +0 -1
- package/dist/commands/welcome.d.ts +0 -10
- package/dist/commands/welcome.d.ts.map +0 -1
- package/dist/commands/welcome.js +0 -117
- package/dist/commands/welcome.js.map +0 -1
- package/dist/commands/yolo.d.ts +0 -12
- package/dist/commands/yolo.d.ts.map +0 -1
- package/dist/commands/yolo.js +0 -212
- package/dist/commands/yolo.js.map +0 -1
- package/dist/compiler/faf-compiler.d.ts +0 -176
- package/dist/compiler/faf-compiler.d.ts.map +0 -1
- package/dist/compiler/faf-compiler.js +0 -1587
- package/dist/compiler/faf-compiler.js.map +0 -1
- package/dist/converters/faf-converters.d.ts +0 -43
- package/dist/converters/faf-converters.d.ts.map +0 -1
- package/dist/converters/faf-converters.js +0 -197
- package/dist/converters/faf-converters.js.map +0 -1
- package/dist/core-extraction-fixes.d.ts +0 -92
- package/dist/core-extraction-fixes.d.ts.map +0 -1
- package/dist/core-extraction-fixes.js +0 -265
- package/dist/core-extraction-fixes.js.map +0 -1
- package/dist/engines/art-ansi-renderer.d.ts +0 -335
- package/dist/engines/art-ansi-renderer.d.ts.map +0 -1
- package/dist/engines/art-ansi-renderer.js +0 -290
- package/dist/engines/art-ansi-renderer.js.map +0 -1
- package/dist/engines/c-mirror/broadcast/terminal-display.d.ts +0 -23
- package/dist/engines/c-mirror/broadcast/terminal-display.d.ts.map +0 -1
- package/dist/engines/c-mirror/broadcast/terminal-display.js +0 -194
- package/dist/engines/c-mirror/broadcast/terminal-display.js.map +0 -1
- package/dist/engines/c-mirror/core/claude-to-faf.d.ts +0 -28
- package/dist/engines/c-mirror/core/claude-to-faf.d.ts.map +0 -1
- package/dist/engines/c-mirror/core/claude-to-faf.js +0 -195
- package/dist/engines/c-mirror/core/claude-to-faf.js.map +0 -1
- package/dist/engines/c-mirror/core/events/event-emitter.d.ts +0 -36
- package/dist/engines/c-mirror/core/events/event-emitter.d.ts.map +0 -1
- package/dist/engines/c-mirror/core/events/event-emitter.js +0 -77
- package/dist/engines/c-mirror/core/events/event-emitter.js.map +0 -1
- package/dist/engines/c-mirror/core/events/mirror-events.d.ts +0 -103
- package/dist/engines/c-mirror/core/events/mirror-events.d.ts.map +0 -1
- package/dist/engines/c-mirror/core/events/mirror-events.js +0 -65
- package/dist/engines/c-mirror/core/events/mirror-events.js.map +0 -1
- package/dist/engines/c-mirror/core/faf-to-claude.d.ts +0 -18
- package/dist/engines/c-mirror/core/faf-to-claude.d.ts.map +0 -1
- package/dist/engines/c-mirror/core/faf-to-claude.js +0 -162
- package/dist/engines/c-mirror/core/faf-to-claude.js.map +0 -1
- package/dist/engines/c-mirror/core/interfaces.d.ts +0 -153
- package/dist/engines/c-mirror/core/interfaces.d.ts.map +0 -1
- package/dist/engines/c-mirror/core/interfaces.js +0 -8
- package/dist/engines/c-mirror/core/interfaces.js.map +0 -1
- package/dist/engines/c-mirror/core/mirror-engine.d.ts +0 -49
- package/dist/engines/c-mirror/core/mirror-engine.d.ts.map +0 -1
- package/dist/engines/c-mirror/core/mirror-engine.js +0 -315
- package/dist/engines/c-mirror/core/mirror-engine.js.map +0 -1
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.d.ts +0 -33
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.d.ts.map +0 -1
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.js +0 -115
- package/dist/engines/c-mirror/faf-extensions/faf-mirror.js.map +0 -1
- package/dist/engines/c-mirror/strategies/atomic-write.d.ts +0 -34
- package/dist/engines/c-mirror/strategies/atomic-write.d.ts.map +0 -1
- package/dist/engines/c-mirror/strategies/atomic-write.js +0 -132
- package/dist/engines/c-mirror/strategies/atomic-write.js.map +0 -1
- package/dist/engines/claude-todo-engine.d.ts +0 -115
- package/dist/engines/claude-todo-engine.d.ts.map +0 -1
- package/dist/engines/claude-todo-engine.js +0 -346
- package/dist/engines/claude-todo-engine.js.map +0 -1
- package/dist/engines/dependency-tsa.d.ts +0 -89
- package/dist/engines/dependency-tsa.d.ts.map +0 -1
- package/dist/engines/dependency-tsa.js +0 -365
- package/dist/engines/dependency-tsa.js.map +0 -1
- package/dist/engines/drop-coach.d.ts +0 -64
- package/dist/engines/drop-coach.d.ts.map +0 -1
- package/dist/engines/drop-coach.js +0 -222
- package/dist/engines/drop-coach.js.map +0 -1
- package/dist/engines/execution-context.d.ts +0 -75
- package/dist/engines/execution-context.d.ts.map +0 -1
- package/dist/engines/execution-context.js +0 -308
- package/dist/engines/execution-context.js.map +0 -1
- package/dist/engines/fab-formats-processor.d.ts +0 -179
- package/dist/engines/fab-formats-processor.d.ts.map +0 -1
- package/dist/engines/fab-formats-processor.js +0 -1524
- package/dist/engines/fab-formats-processor.js.map +0 -1
- package/dist/engines/faf-dna.d.ts +0 -160
- package/dist/engines/faf-dna.d.ts.map +0 -1
- package/dist/engines/faf-dna.js +0 -547
- package/dist/engines/faf-dna.js.map +0 -1
- package/dist/engines/relentless-context-extractor.d.ts +0 -105
- package/dist/engines/relentless-context-extractor.d.ts.map +0 -1
- package/dist/engines/relentless-context-extractor.js +0 -698
- package/dist/engines/relentless-context-extractor.js.map +0 -1
- package/dist/engines/v252-hybrid-engine.d.ts +0 -60
- package/dist/engines/v252-hybrid-engine.d.ts.map +0 -1
- package/dist/engines/v252-hybrid-engine.js +0 -290
- package/dist/engines/v252-hybrid-engine.js.map +0 -1
- package/dist/family/detectors/n8n.d.ts +0 -10
- package/dist/family/detectors/n8n.d.ts.map +0 -1
- package/dist/family/detectors/n8n.js +0 -102
- package/dist/family/detectors/n8n.js.map +0 -1
- package/dist/family/detectors/next.d.ts +0 -8
- package/dist/family/detectors/next.d.ts.map +0 -1
- package/dist/family/detectors/next.js +0 -106
- package/dist/family/detectors/next.js.map +0 -1
- package/dist/family/detectors/react.d.ts +0 -8
- package/dist/family/detectors/react.d.ts.map +0 -1
- package/dist/family/detectors/react.js +0 -85
- package/dist/family/detectors/react.js.map +0 -1
- package/dist/family/detectors/svelte.d.ts +0 -8
- package/dist/family/detectors/svelte.d.ts.map +0 -1
- package/dist/family/detectors/svelte.js +0 -102
- package/dist/family/detectors/svelte.js.map +0 -1
- package/dist/family/detectors/typescript.d.ts +0 -8
- package/dist/family/detectors/typescript.d.ts.map +0 -1
- package/dist/family/detectors/typescript.js +0 -112
- package/dist/family/detectors/typescript.js.map +0 -1
- package/dist/family/detectors/vite.d.ts +0 -8
- package/dist/family/detectors/vite.d.ts.map +0 -1
- package/dist/family/detectors/vite.js +0 -97
- package/dist/family/detectors/vite.js.map +0 -1
- package/dist/family/index.d.ts +0 -21
- package/dist/family/index.d.ts.map +0 -1
- package/dist/family/index.js +0 -73
- package/dist/family/index.js.map +0 -1
- package/dist/family/registry.d.ts +0 -57
- package/dist/family/registry.d.ts.map +0 -1
- package/dist/family/registry.js +0 -156
- package/dist/family/registry.js.map +0 -1
- package/dist/family/types.d.ts +0 -102
- package/dist/family/types.d.ts.map +0 -1
- package/dist/family/types.js +0 -8
- package/dist/family/types.js.map +0 -1
- package/dist/fix-once/colors.d.ts +0 -105
- package/dist/fix-once/colors.d.ts.map +0 -1
- package/dist/fix-once/colors.js +0 -248
- package/dist/fix-once/colors.js.map +0 -1
- package/dist/fix-once/commander.d.ts +0 -18
- package/dist/fix-once/commander.d.ts.map +0 -1
- package/dist/fix-once/commander.js +0 -25
- package/dist/fix-once/commander.js.map +0 -1
- package/dist/fix-once/types.d.ts +0 -258
- package/dist/fix-once/types.d.ts.map +0 -1
- package/dist/fix-once/types.js +0 -26
- package/dist/fix-once/types.js.map +0 -1
- package/dist/fix-once/yaml.d.ts +0 -58
- package/dist/fix-once/yaml.d.ts.map +0 -1
- package/dist/fix-once/yaml.js +0 -172
- package/dist/fix-once/yaml.js.map +0 -1
- package/dist/framework-detector.d.ts +0 -307
- package/dist/framework-detector.d.ts.map +0 -1
- package/dist/framework-detector.js +0 -951
- package/dist/framework-detector.js.map +0 -1
- package/dist/generators/faf-generator-championship.d.ts +0 -17
- package/dist/generators/faf-generator-championship.d.ts.map +0 -1
- package/dist/generators/faf-generator-championship.js +0 -612
- package/dist/generators/faf-generator-championship.js.map +0 -1
- package/dist/github/current-score-calculator.d.ts +0 -15
- package/dist/github/current-score-calculator.d.ts.map +0 -1
- package/dist/github/current-score-calculator.js +0 -125
- package/dist/github/current-score-calculator.js.map +0 -1
- package/dist/github/faf-git-generator.d.ts +0 -52
- package/dist/github/faf-git-generator.d.ts.map +0 -1
- package/dist/github/faf-git-generator.js +0 -527
- package/dist/github/faf-git-generator.js.map +0 -1
- package/dist/github/github-extractor.d.ts +0 -60
- package/dist/github/github-extractor.d.ts.map +0 -1
- package/dist/github/github-extractor.js +0 -381
- package/dist/github/github-extractor.js.map +0 -1
- package/dist/github/popular-repos.d.ts +0 -43
- package/dist/github/popular-repos.d.ts.map +0 -1
- package/dist/github/popular-repos.js +0 -205
- package/dist/github/popular-repos.js.map +0 -1
- package/dist/github/repo-selector.d.ts +0 -48
- package/dist/github/repo-selector.d.ts.map +0 -1
- package/dist/github/repo-selector.js +0 -297
- package/dist/github/repo-selector.js.map +0 -1
- package/dist/index.d.ts +0 -20
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/licensing/license-messages.d.ts +0 -20
- package/dist/licensing/license-messages.d.ts.map +0 -1
- package/dist/licensing/license-messages.js +0 -77
- package/dist/licensing/license-messages.js.map +0 -1
- package/dist/licensing/pro-gate.d.ts +0 -54
- package/dist/licensing/pro-gate.d.ts.map +0 -1
- package/dist/licensing/pro-gate.js +0 -243
- package/dist/licensing/pro-gate.js.map +0 -1
- package/dist/output/experience-manager.d.ts +0 -58
- package/dist/output/experience-manager.d.ts.map +0 -1
- package/dist/output/experience-manager.js +0 -215
- package/dist/output/experience-manager.js.map +0 -1
- package/dist/schema/faf-schema.d.ts +0 -97
- package/dist/schema/faf-schema.d.ts.map +0 -1
- package/dist/schema/faf-schema.js +0 -173
- package/dist/schema/faf-schema.js.map +0 -1
- package/dist/smart-faf.d.ts +0 -68
- package/dist/smart-faf.d.ts.map +0 -1
- package/dist/smart-faf.js +0 -400
- package/dist/smart-faf.js.map +0 -1
- package/dist/systems/question-system.d.ts +0 -122
- package/dist/systems/question-system.d.ts.map +0 -1
- package/dist/systems/question-system.js +0 -413
- package/dist/systems/question-system.js.map +0 -1
- package/dist/taf/index.d.ts +0 -21
- package/dist/taf/index.d.ts.map +0 -1
- package/dist/taf/index.js +0 -72
- package/dist/taf/index.js.map +0 -1
- package/dist/taf/logger.d.ts +0 -88
- package/dist/taf/logger.d.ts.map +0 -1
- package/dist/taf/logger.js +0 -137
- package/dist/taf/logger.js.map +0 -1
- package/dist/taf/parser.d.ts +0 -32
- package/dist/taf/parser.d.ts.map +0 -1
- package/dist/taf/parser.js +0 -161
- package/dist/taf/parser.js.map +0 -1
- package/dist/taf/star-badge.d.ts +0 -32
- package/dist/taf/star-badge.d.ts.map +0 -1
- package/dist/taf/star-badge.js +0 -158
- package/dist/taf/star-badge.js.map +0 -1
- package/dist/taf/star-rating.d.ts +0 -30
- package/dist/taf/star-rating.d.ts.map +0 -1
- package/dist/taf/star-rating.js +0 -79
- package/dist/taf/star-rating.js.map +0 -1
- package/dist/taf/stats.d.ts +0 -31
- package/dist/taf/stats.d.ts.map +0 -1
- package/dist/taf/stats.js +0 -190
- package/dist/taf/stats.js.map +0 -1
- package/dist/taf/test-output-parser.d.ts +0 -42
- package/dist/taf/test-output-parser.d.ts.map +0 -1
- package/dist/taf/test-output-parser.js +0 -127
- package/dist/taf/test-output-parser.js.map +0 -1
- package/dist/taf/types.d.ts +0 -77
- package/dist/taf/types.d.ts.map +0 -1
- package/dist/taf/types.js +0 -9
- package/dist/taf/types.js.map +0 -1
- package/dist/taf/validator.d.ts +0 -18
- package/dist/taf/validator.d.ts.map +0 -1
- package/dist/taf/validator.js +0 -148
- package/dist/taf/validator.js.map +0 -1
- package/dist/telemetry/analytics.d.ts +0 -74
- package/dist/telemetry/analytics.d.ts.map +0 -1
- package/dist/telemetry/analytics.js +0 -370
- package/dist/telemetry/analytics.js.map +0 -1
- package/dist/tests/test-chrome-fuzzy.d.ts +0 -5
- package/dist/tests/test-chrome-fuzzy.d.ts.map +0 -1
- package/dist/tests/test-chrome-fuzzy.js +0 -68
- package/dist/tests/test-chrome-fuzzy.js.map +0 -1
- package/dist/types/faf-types.d.ts +0 -144
- package/dist/types/faf-types.d.ts.map +0 -1
- package/dist/types/faf-types.js +0 -21
- package/dist/types/faf-types.js.map +0 -1
- package/dist/types/index.d.ts +0 -36
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js +0 -7
- package/dist/types/index.js.map +0 -1
- package/dist/utils/agents-parser.d.ts +0 -60
- package/dist/utils/agents-parser.d.ts.map +0 -1
- package/dist/utils/agents-parser.js +0 -339
- package/dist/utils/agents-parser.js.map +0 -1
- package/dist/utils/announcements.d.ts +0 -16
- package/dist/utils/announcements.d.ts.map +0 -1
- package/dist/utils/announcements.js +0 -131
- package/dist/utils/announcements.js.map +0 -1
- package/dist/utils/balance-visualizer.d.ts +0 -38
- package/dist/utils/balance-visualizer.d.ts.map +0 -1
- package/dist/utils/balance-visualizer.js +0 -190
- package/dist/utils/balance-visualizer.js.map +0 -1
- package/dist/utils/championship-core.d.ts +0 -127
- package/dist/utils/championship-core.d.ts.map +0 -1
- package/dist/utils/championship-core.js +0 -212
- package/dist/utils/championship-core.js.map +0 -1
- package/dist/utils/championship-style.d.ts +0 -110
- package/dist/utils/championship-style.d.ts.map +0 -1
- package/dist/utils/championship-style.js +0 -219
- package/dist/utils/championship-style.js.map +0 -1
- package/dist/utils/chrome-extension-confirmer.d.ts +0 -41
- package/dist/utils/chrome-extension-confirmer.d.ts.map +0 -1
- package/dist/utils/chrome-extension-confirmer.js +0 -203
- package/dist/utils/chrome-extension-confirmer.js.map +0 -1
- package/dist/utils/chrome-extension-detector.d.ts +0 -74
- package/dist/utils/chrome-extension-detector.d.ts.map +0 -1
- package/dist/utils/chrome-extension-detector.js +0 -268
- package/dist/utils/chrome-extension-detector.js.map +0 -1
- package/dist/utils/color-utils.d.ts +0 -17
- package/dist/utils/color-utils.d.ts.map +0 -1
- package/dist/utils/color-utils.js +0 -112
- package/dist/utils/color-utils.js.map +0 -1
- package/dist/utils/conductor-parser.d.ts +0 -86
- package/dist/utils/conductor-parser.d.ts.map +0 -1
- package/dist/utils/conductor-parser.js +0 -293
- package/dist/utils/conductor-parser.js.map +0 -1
- package/dist/utils/cursorrules-parser.d.ts +0 -56
- package/dist/utils/cursorrules-parser.d.ts.map +0 -1
- package/dist/utils/cursorrules-parser.js +0 -327
- package/dist/utils/cursorrules-parser.js.map +0 -1
- package/dist/utils/email-opt-in.d.ts +0 -31
- package/dist/utils/email-opt-in.d.ts.map +0 -1
- package/dist/utils/email-opt-in.js +0 -199
- package/dist/utils/email-opt-in.js.map +0 -1
- package/dist/utils/fab-formats-engine.d.ts +0 -83
- package/dist/utils/fab-formats-engine.d.ts.map +0 -1
- package/dist/utils/fab-formats-engine.js +0 -502
- package/dist/utils/fab-formats-engine.js.map +0 -1
- package/dist/utils/fafb-compiler.d.ts +0 -62
- package/dist/utils/fafb-compiler.d.ts.map +0 -1
- package/dist/utils/fafb-compiler.js +0 -225
- package/dist/utils/fafb-compiler.js.map +0 -1
- package/dist/utils/fafb-detector.d.ts +0 -26
- package/dist/utils/fafb-detector.d.ts.map +0 -1
- package/dist/utils/fafb-detector.js +0 -180
- package/dist/utils/fafb-detector.js.map +0 -1
- package/dist/utils/fafignore-parser.d.ts +0 -21
- package/dist/utils/fafignore-parser.d.ts.map +0 -1
- package/dist/utils/fafignore-parser.js +0 -178
- package/dist/utils/fafignore-parser.js.map +0 -1
- package/dist/utils/feedback-messages.d.ts +0 -13
- package/dist/utils/feedback-messages.d.ts.map +0 -1
- package/dist/utils/feedback-messages.js +0 -118
- package/dist/utils/feedback-messages.js.map +0 -1
- package/dist/utils/file-utils.d.ts +0 -113
- package/dist/utils/file-utils.d.ts.map +0 -1
- package/dist/utils/file-utils.js +0 -949
- package/dist/utils/file-utils.js.map +0 -1
- package/dist/utils/gemini-parser.d.ts +0 -58
- package/dist/utils/gemini-parser.d.ts.map +0 -1
- package/dist/utils/gemini-parser.js +0 -263
- package/dist/utils/gemini-parser.js.map +0 -1
- package/dist/utils/markdown-to-context.d.ts +0 -28
- package/dist/utils/markdown-to-context.d.ts.map +0 -1
- package/dist/utils/markdown-to-context.js +0 -206
- package/dist/utils/markdown-to-context.js.map +0 -1
- package/dist/utils/memory-parser.d.ts +0 -95
- package/dist/utils/memory-parser.d.ts.map +0 -1
- package/dist/utils/memory-parser.js +0 -408
- package/dist/utils/memory-parser.js.map +0 -1
- package/dist/utils/memory-topic-writer.d.ts +0 -52
- package/dist/utils/memory-topic-writer.d.ts.map +0 -1
- package/dist/utils/memory-topic-writer.js +0 -415
- package/dist/utils/memory-topic-writer.js.map +0 -1
- package/dist/utils/native-cli-parser.d.ts +0 -152
- package/dist/utils/native-cli-parser.d.ts.map +0 -1
- package/dist/utils/native-cli-parser.js +0 -466
- package/dist/utils/native-cli-parser.js.map +0 -1
- package/dist/utils/native-file-finder.d.ts +0 -116
- package/dist/utils/native-file-finder.d.ts.map +0 -1
- package/dist/utils/native-file-finder.js +0 -211
- package/dist/utils/native-file-finder.js.map +0 -1
- package/dist/utils/platform-detector.d.ts +0 -31
- package/dist/utils/platform-detector.d.ts.map +0 -1
- package/dist/utils/platform-detector.js +0 -220
- package/dist/utils/platform-detector.js.map +0 -1
- package/dist/utils/score-header.d.ts +0 -22
- package/dist/utils/score-header.d.ts.map +0 -1
- package/dist/utils/score-header.js +0 -88
- package/dist/utils/score-header.js.map +0 -1
- package/dist/utils/slot-counter.d.ts +0 -56
- package/dist/utils/slot-counter.d.ts.map +0 -1
- package/dist/utils/slot-counter.js +0 -100
- package/dist/utils/slot-counter.js.map +0 -1
- package/dist/utils/technical-credit.d.ts +0 -36
- package/dist/utils/technical-credit.d.ts.map +0 -1
- package/dist/utils/technical-credit.js +0 -286
- package/dist/utils/technical-credit.js.map +0 -1
- package/dist/utils/trust-cache.d.ts +0 -29
- package/dist/utils/trust-cache.d.ts.map +0 -1
- package/dist/utils/trust-cache.js +0 -122
- package/dist/utils/trust-cache.js.map +0 -1
- package/dist/utils/turbo-cat-knowledge.d.ts +0 -105
- package/dist/utils/turbo-cat-knowledge.d.ts.map +0 -1
- package/dist/utils/turbo-cat-knowledge.js +0 -1941
- package/dist/utils/turbo-cat-knowledge.js.map +0 -1
- package/dist/utils/turbo-cat-pyramid.d.ts +0 -48
- package/dist/utils/turbo-cat-pyramid.d.ts.map +0 -1
- package/dist/utils/turbo-cat-pyramid.js +0 -380
- package/dist/utils/turbo-cat-pyramid.js.map +0 -1
- package/dist/utils/turbo-cat.d.ts +0 -99
- package/dist/utils/turbo-cat.d.ts.map +0 -1
- package/dist/utils/turbo-cat.js +0 -456
- package/dist/utils/turbo-cat.js.map +0 -1
- package/dist/utils/universal-fuzzy-detector.d.ts +0 -64
- package/dist/utils/universal-fuzzy-detector.d.ts.map +0 -1
- package/dist/utils/universal-fuzzy-detector.js +0 -386
- package/dist/utils/universal-fuzzy-detector.js.map +0 -1
- package/dist/utils/update-checker.d.ts +0 -15
- package/dist/utils/update-checker.d.ts.map +0 -1
- package/dist/utils/update-checker.js +0 -200
- package/dist/utils/update-checker.js.map +0 -1
- package/dist/utils/vibe-sync.d.ts +0 -25
- package/dist/utils/vibe-sync.d.ts.map +0 -1
- package/dist/utils/vibe-sync.js +0 -175
- package/dist/utils/vibe-sync.js.map +0 -1
- package/dist/utils/yaml-generator.d.ts +0 -52
- package/dist/utils/yaml-generator.d.ts.map +0 -1
- package/dist/utils/yaml-generator.js +0 -432
- package/dist/utils/yaml-generator.js.map +0 -1
- package/faf-banner.png +0 -0
- package/scripts/ANTHROPIC-DEMO.sh +0 -203
- package/scripts/boris-ready.sh +0 -169
- package/scripts/bundle-yaml.js +0 -87
- package/scripts/check-version.js +0 -88
- package/scripts/clean-build.js +0 -34
- package/scripts/cleanup-unused.sh +0 -54
- package/scripts/debug-django.txt +0 -9
- package/scripts/debug-mongo.txt +0 -9
- package/scripts/debug-react.txt +0 -9
- package/scripts/debug-rust.txt +0 -9
- package/scripts/debug-whisper.cpp.txt +0 -9
- package/scripts/evaluate-family-member.ts +0 -300
- package/scripts/generate-docs.ts +0 -358
- package/scripts/generate-drift-reports.sh +0 -111
- package/scripts/industry-showcase.json +0 -122
- package/scripts/mcp-ecosystem-research.sh +0 -58
- package/scripts/migrate-yaml-imports.sh +0 -55
- package/scripts/migrate-yaml.ts +0 -132
- package/scripts/performance-validation.ts +0 -460
- package/scripts/postinstall.js +0 -30
- package/scripts/prepare-release.ts +0 -421
- package/scripts/run-industry-showcase.ts +0 -237
- package/scripts/run-test-showcase.ts +0 -244
- package/scripts/setup-github-watch.sh +0 -43
- package/scripts/sync-version.js +0 -35
- package/scripts/test-integration-detection.ts +0 -93
- package/scripts/test-integration-simple.js +0 -93
- package/scripts/test-medal-progression.sh +0 -143
- package/scripts/test-showcase-results.json +0 -109
- package/scripts/test-showcase.json +0 -32
- package/scripts/update-version.js +0 -148
- package/scripts/verify-build.js +0 -343
- package/scripts/version-check.js +0 -78
- package/scripts/watch-discussions.sh +0 -86
|
@@ -1,1587 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* 🏎️ FAF Scoring Compiler
|
|
4
|
-
* Deterministic, multi-pass compiler for .faf scoring
|
|
5
|
-
*
|
|
6
|
-
* Philosophy: Like Svelte, we compile away the complexity
|
|
7
|
-
* Result: Pure, traceable, reproducible scores
|
|
8
|
-
*/
|
|
9
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
-
}
|
|
15
|
-
Object.defineProperty(o, k2, desc);
|
|
16
|
-
}) : (function(o, m, k, k2) {
|
|
17
|
-
if (k2 === undefined) k2 = k;
|
|
18
|
-
o[k2] = m[k];
|
|
19
|
-
}));
|
|
20
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
-
}) : function(o, v) {
|
|
23
|
-
o["default"] = v;
|
|
24
|
-
});
|
|
25
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
-
var ownKeys = function(o) {
|
|
27
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
-
var ar = [];
|
|
29
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
-
return ar;
|
|
31
|
-
};
|
|
32
|
-
return ownKeys(o);
|
|
33
|
-
};
|
|
34
|
-
return function (mod) {
|
|
35
|
-
if (mod && mod.__esModule) return mod;
|
|
36
|
-
var result = {};
|
|
37
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
-
__setModuleDefault(result, mod);
|
|
39
|
-
return result;
|
|
40
|
-
};
|
|
41
|
-
})();
|
|
42
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
-
exports.FafCompiler = exports.SLOT_ALIASES_REVERSE = exports.SLOT_ALIASES = void 0;
|
|
44
|
-
exports.getSlotsForType = getSlotsForType;
|
|
45
|
-
exports.getSlotCountForType = getSlotCountForType;
|
|
46
|
-
exports.compile = compile;
|
|
47
|
-
exports.compileWithTrace = compileWithTrace;
|
|
48
|
-
exports.verify = verify;
|
|
49
|
-
const yaml_1 = require("../fix-once/yaml");
|
|
50
|
-
const crypto = __importStar(require("crypto"));
|
|
51
|
-
const chrome_extension_detector_1 = require("../utils/chrome-extension-detector");
|
|
52
|
-
const fab_formats_processor_1 = require("../engines/fab-formats-processor");
|
|
53
|
-
const path = __importStar(require("path"));
|
|
54
|
-
// ============================================================================
|
|
55
|
-
// TYPE_DEFINITIONS - Single Source of Truth for Project Types
|
|
56
|
-
// ============================================================================
|
|
57
|
-
// Design: 21 slots always exist. Types define which slots COUNT toward scoring.
|
|
58
|
-
// slot_ignore in .faf file overrides type defaults for edge cases.
|
|
59
|
-
/**
|
|
60
|
-
* Mk4 Slot Alias Map — Single Source of Truth
|
|
61
|
-
*
|
|
62
|
-
* Maps old slot field names to new Mk4 canonical names.
|
|
63
|
-
* Used throughout the codebase to accept both old and new names on read,
|
|
64
|
-
* while always generating new names on write.
|
|
65
|
-
*
|
|
66
|
-
* Old .faf files (36k+ downloads) use old names — they must still score correctly.
|
|
67
|
-
*/
|
|
68
|
-
exports.SLOT_ALIASES = {
|
|
69
|
-
// old → new (Mk4 canonical)
|
|
70
|
-
frontend: 'framework',
|
|
71
|
-
css_framework: 'css',
|
|
72
|
-
state_management: 'state',
|
|
73
|
-
api_type: 'api',
|
|
74
|
-
database: 'db',
|
|
75
|
-
package_manager: 'pkg_manager',
|
|
76
|
-
};
|
|
77
|
-
/**
|
|
78
|
-
* Reverse alias map: new → old (for reading old .faf files)
|
|
79
|
-
*/
|
|
80
|
-
exports.SLOT_ALIASES_REVERSE = Object.fromEntries(Object.entries(exports.SLOT_ALIASES).map(([old, mk4]) => [mk4, old]));
|
|
81
|
-
/**
|
|
82
|
-
* All 21 slots in the FAF system (Mk4 canonical names)
|
|
83
|
-
*/
|
|
84
|
-
const ALL_SLOTS = {
|
|
85
|
-
// Project slots (3)
|
|
86
|
-
project: ['project.name', 'project.goal', 'project.main_language'],
|
|
87
|
-
// Frontend slots (4)
|
|
88
|
-
frontend: ['stack.framework', 'stack.css', 'stack.ui_library', 'stack.state'],
|
|
89
|
-
// Backend slots (5)
|
|
90
|
-
backend: ['stack.backend', 'stack.api', 'stack.runtime', 'stack.db', 'stack.connection'],
|
|
91
|
-
// Universal slots (3)
|
|
92
|
-
universal: ['stack.hosting', 'stack.build', 'stack.cicd'],
|
|
93
|
-
// Human context slots (6)
|
|
94
|
-
human: ['human.who', 'human.what', 'human.why', 'human.where', 'human.when', 'human.how']
|
|
95
|
-
};
|
|
96
|
-
/**
|
|
97
|
-
* TYPE_DEFINITIONS - Maps project types to their applicable slots
|
|
98
|
-
*
|
|
99
|
-
* Each type specifies which slot categories count toward scoring.
|
|
100
|
-
* slot_ignore in .faf can override these for edge cases.
|
|
101
|
-
*/
|
|
102
|
-
const TYPE_DEFINITIONS = {
|
|
103
|
-
// ============================================================================
|
|
104
|
-
// CLI/Tool Types (9 slots: project + human)
|
|
105
|
-
// ============================================================================
|
|
106
|
-
'cli': {
|
|
107
|
-
description: 'Command-line interface tool',
|
|
108
|
-
categories: ['project', 'human'],
|
|
109
|
-
aliases: ['cli-tool', 'command-line', 'cli-ts', 'cli-js']
|
|
110
|
-
},
|
|
111
|
-
'cli-tool': {
|
|
112
|
-
description: 'Command-line interface tool',
|
|
113
|
-
categories: ['project', 'human']
|
|
114
|
-
},
|
|
115
|
-
// ============================================================================
|
|
116
|
-
// Library/Package Types (9 slots: project + human)
|
|
117
|
-
// ============================================================================
|
|
118
|
-
'library': {
|
|
119
|
-
description: 'Reusable code library/package',
|
|
120
|
-
categories: ['project', 'human'],
|
|
121
|
-
aliases: ['lib', 'package', 'typescript', 'pure_typescript']
|
|
122
|
-
},
|
|
123
|
-
'npm-package': {
|
|
124
|
-
description: 'NPM package',
|
|
125
|
-
categories: ['project', 'human']
|
|
126
|
-
},
|
|
127
|
-
'pip-package': {
|
|
128
|
-
description: 'Python pip package',
|
|
129
|
-
categories: ['project', 'human'],
|
|
130
|
-
aliases: ['pypi']
|
|
131
|
-
},
|
|
132
|
-
'crate': {
|
|
133
|
-
description: 'Rust crate',
|
|
134
|
-
categories: ['project', 'human'],
|
|
135
|
-
aliases: ['rust-crate', 'zig']
|
|
136
|
-
},
|
|
137
|
-
'gem': {
|
|
138
|
-
description: 'Ruby gem',
|
|
139
|
-
categories: ['project', 'human'],
|
|
140
|
-
aliases: ['ruby-gem']
|
|
141
|
-
},
|
|
142
|
-
// ============================================================================
|
|
143
|
-
// AI/ML Types
|
|
144
|
-
// ============================================================================
|
|
145
|
-
'mcp-server': {
|
|
146
|
-
description: 'Model Context Protocol server',
|
|
147
|
-
categories: ['project', 'backend', 'human']
|
|
148
|
-
},
|
|
149
|
-
'mcpaas': {
|
|
150
|
-
description: 'Context-on-demand platform — SSR, payments, email, MCP protocol',
|
|
151
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
152
|
-
aliases: ['context-on-demand']
|
|
153
|
-
},
|
|
154
|
-
'data-science': {
|
|
155
|
-
description: 'Data science/analysis project',
|
|
156
|
-
categories: ['project', 'backend', 'human'],
|
|
157
|
-
aliases: ['data-analysis', 'analytics']
|
|
158
|
-
},
|
|
159
|
-
'ml-model': {
|
|
160
|
-
description: 'Machine learning model',
|
|
161
|
-
categories: ['project', 'backend', 'human'],
|
|
162
|
-
aliases: ['ai-model', 'ml', 'machine-learning', 'ml-research']
|
|
163
|
-
},
|
|
164
|
-
'jupyter': {
|
|
165
|
-
description: 'Jupyter notebook project',
|
|
166
|
-
categories: ['project', 'human'],
|
|
167
|
-
aliases: ['notebook', 'ipynb']
|
|
168
|
-
},
|
|
169
|
-
'data-pipeline': {
|
|
170
|
-
description: 'Data pipeline/ETL',
|
|
171
|
-
categories: ['project', 'backend', 'human'],
|
|
172
|
-
aliases: ['etl', 'pipeline']
|
|
173
|
-
},
|
|
174
|
-
'voice-ai-agent': {
|
|
175
|
-
description: 'Voice AI agent (LiveKit/xAI/WebRTC)',
|
|
176
|
-
categories: ['project', 'backend', 'human'],
|
|
177
|
-
aliases: ['voice-agent', 'livekit-agent', 'realtime-voice', 'grok-voice']
|
|
178
|
-
},
|
|
179
|
-
// ============================================================================
|
|
180
|
-
// API/Backend Types
|
|
181
|
-
// ============================================================================
|
|
182
|
-
'backend-api': {
|
|
183
|
-
description: 'Backend API service',
|
|
184
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
185
|
-
aliases: ['api', 'backend', 'rest-api']
|
|
186
|
-
},
|
|
187
|
-
'node-api': {
|
|
188
|
-
description: 'Node.js API service',
|
|
189
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
190
|
-
aliases: ['express', 'fastify', 'nest', 'nodejs_native', 'nodejs_esm_native']
|
|
191
|
-
},
|
|
192
|
-
'python-api': {
|
|
193
|
-
description: 'Python API service',
|
|
194
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
195
|
-
aliases: ['flask', 'fastapi', 'django-api', 'python-flask', 'python-fastapi', 'python-starlette']
|
|
196
|
-
},
|
|
197
|
-
'python-app': {
|
|
198
|
-
description: 'Python application',
|
|
199
|
-
categories: ['project', 'backend', 'human'],
|
|
200
|
-
aliases: ['python-generic']
|
|
201
|
-
},
|
|
202
|
-
'go-api': {
|
|
203
|
-
description: 'Go API service',
|
|
204
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
205
|
-
aliases: ['golang', 'gin', 'fiber', 'go']
|
|
206
|
-
},
|
|
207
|
-
'rust-api': {
|
|
208
|
-
description: 'Rust API service',
|
|
209
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
210
|
-
aliases: ['actix', 'axum', 'rocket', 'rust']
|
|
211
|
-
},
|
|
212
|
-
'graphql': {
|
|
213
|
-
description: 'GraphQL API service',
|
|
214
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
215
|
-
aliases: ['graphql-api']
|
|
216
|
-
},
|
|
217
|
-
'microservice': {
|
|
218
|
-
description: 'Microservice',
|
|
219
|
-
categories: ['project', 'backend', 'universal', 'human'],
|
|
220
|
-
aliases: ['service']
|
|
221
|
-
},
|
|
222
|
-
// ============================================================================
|
|
223
|
-
// Frontend Types
|
|
224
|
-
// ============================================================================
|
|
225
|
-
'frontend': {
|
|
226
|
-
description: 'Frontend-only web application',
|
|
227
|
-
categories: ['project', 'frontend', 'universal', 'human']
|
|
228
|
-
},
|
|
229
|
-
'svelte': {
|
|
230
|
-
description: 'Svelte web application',
|
|
231
|
-
categories: ['project', 'frontend', 'universal', 'human'],
|
|
232
|
-
aliases: ['sveltekit', 'svelte_native', 'svelte_5_runes_native']
|
|
233
|
-
},
|
|
234
|
-
'react': {
|
|
235
|
-
description: 'React web application',
|
|
236
|
-
categories: ['project', 'frontend', 'universal', 'human'],
|
|
237
|
-
aliases: ['reactjs', 'react_native', 'react_17_native']
|
|
238
|
-
},
|
|
239
|
-
'vue': {
|
|
240
|
-
description: 'Vue.js web application',
|
|
241
|
-
categories: ['project', 'frontend', 'universal', 'human'],
|
|
242
|
-
aliases: ['vuejs', 'nuxt', 'vue_native']
|
|
243
|
-
},
|
|
244
|
-
'angular': {
|
|
245
|
-
description: 'Angular web application',
|
|
246
|
-
categories: ['project', 'frontend', 'universal', 'human']
|
|
247
|
-
},
|
|
248
|
-
'nextjs': {
|
|
249
|
-
description: 'Next.js application',
|
|
250
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
251
|
-
aliases: ['next', 'nextjs_native']
|
|
252
|
-
},
|
|
253
|
-
'remix': {
|
|
254
|
-
description: 'Remix application',
|
|
255
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
256
|
-
},
|
|
257
|
-
'astro': {
|
|
258
|
-
description: 'Astro static site',
|
|
259
|
-
categories: ['project', 'frontend', 'universal', 'human']
|
|
260
|
-
},
|
|
261
|
-
'solid': {
|
|
262
|
-
description: 'SolidJS application',
|
|
263
|
-
categories: ['project', 'frontend', 'universal', 'human'],
|
|
264
|
-
aliases: ['solidjs']
|
|
265
|
-
},
|
|
266
|
-
'qwik': {
|
|
267
|
-
description: 'Qwik application',
|
|
268
|
-
categories: ['project', 'frontend', 'universal', 'human']
|
|
269
|
-
},
|
|
270
|
-
// ============================================================================
|
|
271
|
-
// Fullstack Types
|
|
272
|
-
// ============================================================================
|
|
273
|
-
'fullstack': {
|
|
274
|
-
description: 'Full-stack web application',
|
|
275
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
276
|
-
},
|
|
277
|
-
't3': {
|
|
278
|
-
description: 'T3 Stack (Next.js + tRPC + Prisma)',
|
|
279
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
280
|
-
aliases: ['t3-stack', 'create-t3-app']
|
|
281
|
-
},
|
|
282
|
-
'mern': {
|
|
283
|
-
description: 'MERN Stack (MongoDB + Express + React + Node)',
|
|
284
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
285
|
-
},
|
|
286
|
-
'mean': {
|
|
287
|
-
description: 'MEAN Stack (MongoDB + Express + Angular + Node)',
|
|
288
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
289
|
-
},
|
|
290
|
-
'lamp': {
|
|
291
|
-
description: 'LAMP Stack (Linux + Apache + MySQL + PHP)',
|
|
292
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
293
|
-
},
|
|
294
|
-
'django': {
|
|
295
|
-
description: 'Django web application',
|
|
296
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
297
|
-
aliases: ['python-django']
|
|
298
|
-
},
|
|
299
|
-
'rails': {
|
|
300
|
-
description: 'Ruby on Rails application',
|
|
301
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
302
|
-
aliases: ['ruby-on-rails', 'ror']
|
|
303
|
-
},
|
|
304
|
-
'laravel': {
|
|
305
|
-
description: 'Laravel PHP application',
|
|
306
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
307
|
-
},
|
|
308
|
-
// ============================================================================
|
|
309
|
-
// Mobile Types
|
|
310
|
-
// ============================================================================
|
|
311
|
-
'mobile': {
|
|
312
|
-
description: 'Mobile application',
|
|
313
|
-
categories: ['project', 'frontend', 'human'],
|
|
314
|
-
aliases: ['mobile-app']
|
|
315
|
-
},
|
|
316
|
-
'react-native': {
|
|
317
|
-
description: 'React Native mobile app',
|
|
318
|
-
categories: ['project', 'frontend', 'human'],
|
|
319
|
-
aliases: ['rn', 'expo']
|
|
320
|
-
},
|
|
321
|
-
'flutter': {
|
|
322
|
-
description: 'Flutter mobile app',
|
|
323
|
-
categories: ['project', 'frontend', 'human'],
|
|
324
|
-
aliases: ['dart']
|
|
325
|
-
},
|
|
326
|
-
'ios': {
|
|
327
|
-
description: 'iOS native app',
|
|
328
|
-
categories: ['project', 'frontend', 'human'],
|
|
329
|
-
aliases: ['swift', 'swiftui']
|
|
330
|
-
},
|
|
331
|
-
'android': {
|
|
332
|
-
description: 'Android native app',
|
|
333
|
-
categories: ['project', 'frontend', 'human'],
|
|
334
|
-
aliases: ['kotlin', 'kotlin-android']
|
|
335
|
-
},
|
|
336
|
-
'ionic': {
|
|
337
|
-
description: 'Ionic mobile app',
|
|
338
|
-
categories: ['project', 'frontend', 'human'],
|
|
339
|
-
aliases: ['capacitor']
|
|
340
|
-
},
|
|
341
|
-
// ============================================================================
|
|
342
|
-
// Desktop Types
|
|
343
|
-
// ============================================================================
|
|
344
|
-
'desktop': {
|
|
345
|
-
description: 'Desktop application',
|
|
346
|
-
categories: ['project', 'frontend', 'human'],
|
|
347
|
-
aliases: ['desktop-app']
|
|
348
|
-
},
|
|
349
|
-
'electron': {
|
|
350
|
-
description: 'Electron desktop app',
|
|
351
|
-
categories: ['project', 'frontend', 'human']
|
|
352
|
-
},
|
|
353
|
-
'tauri': {
|
|
354
|
-
description: 'Tauri desktop app',
|
|
355
|
-
categories: ['project', 'frontend', 'human']
|
|
356
|
-
},
|
|
357
|
-
'qt': {
|
|
358
|
-
description: 'Qt desktop application',
|
|
359
|
-
categories: ['project', 'frontend', 'human'],
|
|
360
|
-
aliases: ['pyqt', 'pyside']
|
|
361
|
-
},
|
|
362
|
-
'gtk': {
|
|
363
|
-
description: 'GTK desktop application',
|
|
364
|
-
categories: ['project', 'frontend', 'human']
|
|
365
|
-
},
|
|
366
|
-
// ============================================================================
|
|
367
|
-
// Browser Extensions
|
|
368
|
-
// ============================================================================
|
|
369
|
-
'chrome-extension': {
|
|
370
|
-
description: 'Chrome browser extension',
|
|
371
|
-
categories: ['project', 'human'],
|
|
372
|
-
aliases: ['browser-extension', 'extension']
|
|
373
|
-
},
|
|
374
|
-
'firefox-extension': {
|
|
375
|
-
description: 'Firefox browser extension',
|
|
376
|
-
categories: ['project', 'human'],
|
|
377
|
-
aliases: ['firefox-addon']
|
|
378
|
-
},
|
|
379
|
-
'safari-extension': {
|
|
380
|
-
description: 'Safari browser extension',
|
|
381
|
-
categories: ['project', 'human']
|
|
382
|
-
},
|
|
383
|
-
// ============================================================================
|
|
384
|
-
// Automation/Workflow Types
|
|
385
|
-
// ============================================================================
|
|
386
|
-
'n8n-workflow': {
|
|
387
|
-
description: 'n8n automation workflow',
|
|
388
|
-
categories: ['project', 'backend', 'human'],
|
|
389
|
-
aliases: ['n8n']
|
|
390
|
-
},
|
|
391
|
-
'zapier': {
|
|
392
|
-
description: 'Zapier integration',
|
|
393
|
-
categories: ['project', 'human']
|
|
394
|
-
},
|
|
395
|
-
'github-action': {
|
|
396
|
-
description: 'GitHub Action',
|
|
397
|
-
categories: ['project', 'human'],
|
|
398
|
-
aliases: ['gha', 'action']
|
|
399
|
-
},
|
|
400
|
-
// ============================================================================
|
|
401
|
-
// DevOps/Infrastructure Types
|
|
402
|
-
// ============================================================================
|
|
403
|
-
'terraform': {
|
|
404
|
-
description: 'Terraform infrastructure',
|
|
405
|
-
categories: ['project', 'human'],
|
|
406
|
-
aliases: ['tf', 'iac']
|
|
407
|
-
},
|
|
408
|
-
'kubernetes': {
|
|
409
|
-
description: 'Kubernetes configuration',
|
|
410
|
-
categories: ['project', 'human'],
|
|
411
|
-
aliases: ['k8s', 'helm']
|
|
412
|
-
},
|
|
413
|
-
'docker': {
|
|
414
|
-
description: 'Docker/container configuration',
|
|
415
|
-
categories: ['project', 'human'],
|
|
416
|
-
aliases: ['dockerfile', 'container']
|
|
417
|
-
},
|
|
418
|
-
'ansible': {
|
|
419
|
-
description: 'Ansible playbooks',
|
|
420
|
-
categories: ['project', 'human']
|
|
421
|
-
},
|
|
422
|
-
'pulumi': {
|
|
423
|
-
description: 'Pulumi infrastructure',
|
|
424
|
-
categories: ['project', 'human']
|
|
425
|
-
},
|
|
426
|
-
'infrastructure': {
|
|
427
|
-
description: 'Infrastructure as code',
|
|
428
|
-
categories: ['project', 'human'],
|
|
429
|
-
aliases: ['infra', 'devops']
|
|
430
|
-
},
|
|
431
|
-
// ============================================================================
|
|
432
|
-
// Static Sites / Documentation
|
|
433
|
-
// ============================================================================
|
|
434
|
-
'static-html': {
|
|
435
|
-
description: 'Static HTML website',
|
|
436
|
-
categories: ['project', 'frontend', 'human'],
|
|
437
|
-
aliases: ['static-site', 'html']
|
|
438
|
-
},
|
|
439
|
-
'landing-page': {
|
|
440
|
-
description: 'Landing page website',
|
|
441
|
-
categories: ['project', 'frontend', 'human'],
|
|
442
|
-
aliases: ['landing']
|
|
443
|
-
},
|
|
444
|
-
'documentation': {
|
|
445
|
-
description: 'Documentation site',
|
|
446
|
-
categories: ['project', 'frontend', 'human'],
|
|
447
|
-
aliases: ['docs']
|
|
448
|
-
},
|
|
449
|
-
'docusaurus': {
|
|
450
|
-
description: 'Docusaurus documentation site',
|
|
451
|
-
categories: ['project', 'frontend', 'human']
|
|
452
|
-
},
|
|
453
|
-
'mkdocs': {
|
|
454
|
-
description: 'MkDocs documentation site',
|
|
455
|
-
categories: ['project', 'human']
|
|
456
|
-
},
|
|
457
|
-
'cookbook': {
|
|
458
|
-
description: 'Example-driven developer onboarding hub with notebooks, scripts, configs, and progressive demos',
|
|
459
|
-
categories: ['project', 'human'],
|
|
460
|
-
aliases: ['examples', 'tutorials', 'demos', 'samples']
|
|
461
|
-
},
|
|
462
|
-
'vitepress': {
|
|
463
|
-
description: 'VitePress documentation site',
|
|
464
|
-
categories: ['project', 'frontend', 'human']
|
|
465
|
-
},
|
|
466
|
-
'storybook': {
|
|
467
|
-
description: 'Storybook component library',
|
|
468
|
-
categories: ['project', 'frontend', 'human']
|
|
469
|
-
},
|
|
470
|
-
// ============================================================================
|
|
471
|
-
// CMS Types
|
|
472
|
-
// ============================================================================
|
|
473
|
-
'wordpress': {
|
|
474
|
-
description: 'WordPress site/plugin/theme',
|
|
475
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
476
|
-
aliases: ['wp']
|
|
477
|
-
},
|
|
478
|
-
'cms': {
|
|
479
|
-
description: 'Content management system',
|
|
480
|
-
categories: ['project', 'frontend', 'backend', 'human']
|
|
481
|
-
},
|
|
482
|
-
'strapi': {
|
|
483
|
-
description: 'Strapi headless CMS',
|
|
484
|
-
categories: ['project', 'backend', 'universal', 'human']
|
|
485
|
-
},
|
|
486
|
-
'sanity': {
|
|
487
|
-
description: 'Sanity.io CMS',
|
|
488
|
-
categories: ['project', 'backend', 'human']
|
|
489
|
-
},
|
|
490
|
-
'contentful': {
|
|
491
|
-
description: 'Contentful CMS integration',
|
|
492
|
-
categories: ['project', 'human']
|
|
493
|
-
},
|
|
494
|
-
// ============================================================================
|
|
495
|
-
// Game Development Types
|
|
496
|
-
// ============================================================================
|
|
497
|
-
'game': {
|
|
498
|
-
description: 'Game project',
|
|
499
|
-
categories: ['project', 'frontend', 'human'],
|
|
500
|
-
aliases: ['gamedev']
|
|
501
|
-
},
|
|
502
|
-
'unity': {
|
|
503
|
-
description: 'Unity game',
|
|
504
|
-
categories: ['project', 'frontend', 'human'],
|
|
505
|
-
aliases: ['unity3d']
|
|
506
|
-
},
|
|
507
|
-
'godot': {
|
|
508
|
-
description: 'Godot game',
|
|
509
|
-
categories: ['project', 'frontend', 'human']
|
|
510
|
-
},
|
|
511
|
-
'unreal': {
|
|
512
|
-
description: 'Unreal Engine game',
|
|
513
|
-
categories: ['project', 'frontend', 'human'],
|
|
514
|
-
aliases: ['ue4', 'ue5']
|
|
515
|
-
},
|
|
516
|
-
'phaser': {
|
|
517
|
-
description: 'Phaser.js game',
|
|
518
|
-
categories: ['project', 'frontend', 'human']
|
|
519
|
-
},
|
|
520
|
-
'threejs': {
|
|
521
|
-
description: 'Three.js 3D project',
|
|
522
|
-
categories: ['project', 'frontend', 'human'],
|
|
523
|
-
aliases: ['three', '3d', 'webgl']
|
|
524
|
-
},
|
|
525
|
-
// ============================================================================
|
|
526
|
-
// Blockchain/Web3 Types
|
|
527
|
-
// ============================================================================
|
|
528
|
-
'smart-contract': {
|
|
529
|
-
description: 'Smart contract',
|
|
530
|
-
categories: ['project', 'human'],
|
|
531
|
-
aliases: ['solidity', 'contract']
|
|
532
|
-
},
|
|
533
|
-
'dapp': {
|
|
534
|
-
description: 'Decentralized application',
|
|
535
|
-
categories: ['project', 'frontend', 'human'],
|
|
536
|
-
aliases: ['web3', 'blockchain']
|
|
537
|
-
},
|
|
538
|
-
'hardhat': {
|
|
539
|
-
description: 'Hardhat Ethereum project',
|
|
540
|
-
categories: ['project', 'human']
|
|
541
|
-
},
|
|
542
|
-
'foundry': {
|
|
543
|
-
description: 'Foundry Ethereum project',
|
|
544
|
-
categories: ['project', 'human'],
|
|
545
|
-
aliases: ['forge']
|
|
546
|
-
},
|
|
547
|
-
// ============================================================================
|
|
548
|
-
// Monorepo Types
|
|
549
|
-
// Monorepos are CONTAINERS - they need ALL slots because they can contain
|
|
550
|
-
// any combination of frontend, backend, libraries, etc.
|
|
551
|
-
// The monorepo root .faf describes the overall architecture.
|
|
552
|
-
// Individual packages can have their own .faf files with specific types.
|
|
553
|
-
// ============================================================================
|
|
554
|
-
'monorepo': {
|
|
555
|
-
description: 'Monorepo - multi-package repository',
|
|
556
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
557
|
-
aliases: ['mono', 'workspace']
|
|
558
|
-
},
|
|
559
|
-
'turborepo': {
|
|
560
|
-
description: 'Turborepo monorepo',
|
|
561
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
562
|
-
aliases: ['turbo']
|
|
563
|
-
},
|
|
564
|
-
'nx': {
|
|
565
|
-
description: 'Nx monorepo',
|
|
566
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
567
|
-
},
|
|
568
|
-
'lerna': {
|
|
569
|
-
description: 'Lerna monorepo',
|
|
570
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human']
|
|
571
|
-
},
|
|
572
|
-
'pnpm-workspace': {
|
|
573
|
-
description: 'pnpm workspace monorepo',
|
|
574
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
575
|
-
aliases: ['pnpm-mono']
|
|
576
|
-
},
|
|
577
|
-
'yarn-workspace': {
|
|
578
|
-
description: 'Yarn workspace monorepo',
|
|
579
|
-
categories: ['project', 'frontend', 'backend', 'universal', 'human'],
|
|
580
|
-
aliases: ['yarn-mono']
|
|
581
|
-
},
|
|
582
|
-
// ============================================================================
|
|
583
|
-
// Embedded/Systems Types
|
|
584
|
-
// ============================================================================
|
|
585
|
-
'embedded': {
|
|
586
|
-
description: 'Embedded systems',
|
|
587
|
-
categories: ['project', 'human'],
|
|
588
|
-
aliases: ['firmware', 'iot']
|
|
589
|
-
},
|
|
590
|
-
'arduino': {
|
|
591
|
-
description: 'Arduino project',
|
|
592
|
-
categories: ['project', 'human']
|
|
593
|
-
},
|
|
594
|
-
'raspberry-pi': {
|
|
595
|
-
description: 'Raspberry Pi project',
|
|
596
|
-
categories: ['project', 'human'],
|
|
597
|
-
aliases: ['rpi']
|
|
598
|
-
},
|
|
599
|
-
'wasm': {
|
|
600
|
-
description: 'WebAssembly module',
|
|
601
|
-
categories: ['project', 'human'],
|
|
602
|
-
aliases: ['webassembly']
|
|
603
|
-
},
|
|
604
|
-
// ============================================================================
|
|
605
|
-
// Testing Types
|
|
606
|
-
// ============================================================================
|
|
607
|
-
'test-suite': {
|
|
608
|
-
description: 'Test suite/framework',
|
|
609
|
-
categories: ['project', 'human'],
|
|
610
|
-
aliases: ['testing', 'tests']
|
|
611
|
-
},
|
|
612
|
-
'e2e-tests': {
|
|
613
|
-
description: 'End-to-end test suite',
|
|
614
|
-
categories: ['project', 'human'],
|
|
615
|
-
aliases: ['e2e', 'playwright', 'cypress']
|
|
616
|
-
},
|
|
617
|
-
// ============================================================================
|
|
618
|
-
// Default
|
|
619
|
-
// ============================================================================
|
|
620
|
-
'generic': {
|
|
621
|
-
description: 'Generic project (fallback)',
|
|
622
|
-
categories: ['project', 'universal', 'human'],
|
|
623
|
-
aliases: ['latest-idea']
|
|
624
|
-
}
|
|
625
|
-
};
|
|
626
|
-
/**
|
|
627
|
-
* Get applicable slots for a project type
|
|
628
|
-
*/
|
|
629
|
-
function getSlotsForType(projectType) {
|
|
630
|
-
// Check for aliases first
|
|
631
|
-
for (const [type, def] of Object.entries(TYPE_DEFINITIONS)) {
|
|
632
|
-
if (def.aliases?.includes(projectType)) {
|
|
633
|
-
projectType = type;
|
|
634
|
-
break;
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
const typeDef = TYPE_DEFINITIONS[projectType] || TYPE_DEFINITIONS['generic'];
|
|
638
|
-
const slots = [];
|
|
639
|
-
for (const category of typeDef.categories) {
|
|
640
|
-
slots.push(...ALL_SLOTS[category]);
|
|
641
|
-
}
|
|
642
|
-
return slots;
|
|
643
|
-
}
|
|
644
|
-
/**
|
|
645
|
-
* Get the number of applicable slots for a project type
|
|
646
|
-
* Used by yaml-generator to calculate correct slot_based_percentage
|
|
647
|
-
*/
|
|
648
|
-
function getSlotCountForType(projectType) {
|
|
649
|
-
return getSlotsForType(projectType).length;
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Parse slot_ignore from .faf content
|
|
653
|
-
* Accepts: slot_ignore: [hosting, cicd] or slot_ignore: hosting, cicd
|
|
654
|
-
*/
|
|
655
|
-
function parseSlotIgnore(ast) {
|
|
656
|
-
const slotIgnore = ast.slot_ignore || ast.slotIgnore || ast.ignore_slots;
|
|
657
|
-
if (!slotIgnore) {
|
|
658
|
-
return [];
|
|
659
|
-
}
|
|
660
|
-
// Handle array format
|
|
661
|
-
if (Array.isArray(slotIgnore)) {
|
|
662
|
-
return slotIgnore.map((s) => normalizeSlotName(s));
|
|
663
|
-
}
|
|
664
|
-
// Handle string format (comma-separated)
|
|
665
|
-
if (typeof slotIgnore === 'string') {
|
|
666
|
-
return slotIgnore.split(',').map((s) => normalizeSlotName(s.trim()));
|
|
667
|
-
}
|
|
668
|
-
return [];
|
|
669
|
-
}
|
|
670
|
-
/**
|
|
671
|
-
* Normalize slot names to full path (Mk4 canonical)
|
|
672
|
-
* Examples: "hosting" -> "stack.hosting", "who" -> "human.who"
|
|
673
|
-
* Also resolves old aliases: "frontend" -> "stack.framework", "database" -> "stack.db"
|
|
674
|
-
*/
|
|
675
|
-
function normalizeSlotName(slot) {
|
|
676
|
-
// Already has prefix — check for old aliased paths like "stack.frontend"
|
|
677
|
-
if (slot.includes('.')) {
|
|
678
|
-
const [prefix, field] = slot.split('.');
|
|
679
|
-
if (prefix === 'stack' && exports.SLOT_ALIASES[field]) {
|
|
680
|
-
return `stack.${exports.SLOT_ALIASES[field]}`;
|
|
681
|
-
}
|
|
682
|
-
return slot;
|
|
683
|
-
}
|
|
684
|
-
// Resolve old name to new name first
|
|
685
|
-
const canonicalField = exports.SLOT_ALIASES[slot] || slot;
|
|
686
|
-
// Check each category for the slot
|
|
687
|
-
for (const [_category, slots] of Object.entries(ALL_SLOTS)) {
|
|
688
|
-
const fullSlot = slots.find(s => s.endsWith(`.${canonicalField}`));
|
|
689
|
-
if (fullSlot) {
|
|
690
|
-
return fullSlot;
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
// Return as-is if not found (will be ignored)
|
|
694
|
-
return slot;
|
|
695
|
-
}
|
|
696
|
-
// ============================================================================
|
|
697
|
-
// Main Compiler Class
|
|
698
|
-
// ============================================================================
|
|
699
|
-
class FafCompiler {
|
|
700
|
-
static VERSION = '3.0.0-compiler';
|
|
701
|
-
static COMPILER_ID = 'faf-compiler-v3';
|
|
702
|
-
diagnostics = [];
|
|
703
|
-
trace;
|
|
704
|
-
ir;
|
|
705
|
-
constructor() {
|
|
706
|
-
this.trace = {
|
|
707
|
-
version: FafCompiler.VERSION,
|
|
708
|
-
timestamp: new Date().toISOString(),
|
|
709
|
-
inputHash: '',
|
|
710
|
-
passes: []
|
|
711
|
-
};
|
|
712
|
-
this.ir = {
|
|
713
|
-
version: FafCompiler.VERSION,
|
|
714
|
-
slots: [],
|
|
715
|
-
metadata: {}
|
|
716
|
-
};
|
|
717
|
-
}
|
|
718
|
-
/**
|
|
719
|
-
* Main compilation pipeline
|
|
720
|
-
*/
|
|
721
|
-
async compile(fafPath) {
|
|
722
|
-
// Reset state for new compilation
|
|
723
|
-
this.diagnostics = [];
|
|
724
|
-
this.trace.passes = [];
|
|
725
|
-
this.ir.slots = [];
|
|
726
|
-
try {
|
|
727
|
-
// PASS 1: Parse
|
|
728
|
-
const source = await this.readSource(fafPath);
|
|
729
|
-
const ast = this.parse(source);
|
|
730
|
-
// PASS 2: Analyze
|
|
731
|
-
const analyzed = this.analyze(ast);
|
|
732
|
-
// PASS 3: Optimize (with discovery)
|
|
733
|
-
const optimized = await this.optimize(analyzed, fafPath);
|
|
734
|
-
// PASS 4: Generate
|
|
735
|
-
const result = this.generate(optimized);
|
|
736
|
-
// Add final checksum
|
|
737
|
-
const checksum = this.calculateChecksum(result);
|
|
738
|
-
return {
|
|
739
|
-
...result,
|
|
740
|
-
trace: this.trace,
|
|
741
|
-
diagnostics: this.diagnostics,
|
|
742
|
-
ir: this.ir,
|
|
743
|
-
checksum
|
|
744
|
-
};
|
|
745
|
-
}
|
|
746
|
-
catch (error) {
|
|
747
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
748
|
-
this.addDiagnostic('error', `Compilation failed: ${message}`);
|
|
749
|
-
throw error;
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
// ============================================================================
|
|
753
|
-
// PASS 1: Parser
|
|
754
|
-
// ============================================================================
|
|
755
|
-
async readSource(fafPath) {
|
|
756
|
-
const start = Date.now();
|
|
757
|
-
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
758
|
-
try {
|
|
759
|
-
const source = await fs.readFile(fafPath, 'utf-8');
|
|
760
|
-
this.trace.inputHash = crypto.createHash('md5').update(source).digest('hex');
|
|
761
|
-
this.recordPass('read', start, fafPath, source.length, [
|
|
762
|
-
`Read ${source.length} bytes from ${fafPath}`
|
|
763
|
-
]);
|
|
764
|
-
return source;
|
|
765
|
-
}
|
|
766
|
-
catch (error) {
|
|
767
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
768
|
-
this.addDiagnostic('error', `Cannot read file: ${fafPath}`, undefined, message);
|
|
769
|
-
throw error;
|
|
770
|
-
}
|
|
771
|
-
}
|
|
772
|
-
parse(source) {
|
|
773
|
-
const start = Date.now();
|
|
774
|
-
try {
|
|
775
|
-
const ast = (0, yaml_1.parse)(source);
|
|
776
|
-
if (!ast || typeof ast !== 'object') {
|
|
777
|
-
this.addDiagnostic('error', 'Invalid YAML: must be an object');
|
|
778
|
-
return {};
|
|
779
|
-
}
|
|
780
|
-
this.recordPass('parse', start, source.length, ast, [
|
|
781
|
-
`Parsed YAML into AST with ${Object.keys(ast).length} top-level keys`
|
|
782
|
-
]);
|
|
783
|
-
return ast;
|
|
784
|
-
}
|
|
785
|
-
catch (error) {
|
|
786
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
787
|
-
this.addDiagnostic('error', `Parse error: ${message}`);
|
|
788
|
-
return {};
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
// ============================================================================
|
|
792
|
-
// PASS 2: Analyzer
|
|
793
|
-
// ============================================================================
|
|
794
|
-
analyze(ast) {
|
|
795
|
-
const start = Date.now();
|
|
796
|
-
const analyzed = { ...ast };
|
|
797
|
-
const changes = [];
|
|
798
|
-
// Validate and normalize structure
|
|
799
|
-
if (!analyzed.project) {
|
|
800
|
-
analyzed.project = {};
|
|
801
|
-
changes.push('Added missing project section');
|
|
802
|
-
}
|
|
803
|
-
if (!analyzed.stack) {
|
|
804
|
-
analyzed.stack = {};
|
|
805
|
-
changes.push('Added missing stack section');
|
|
806
|
-
}
|
|
807
|
-
if (!analyzed.human_context) {
|
|
808
|
-
analyzed.human_context = {};
|
|
809
|
-
changes.push('Added missing human_context section');
|
|
810
|
-
}
|
|
811
|
-
// Type validation
|
|
812
|
-
this.validateTypes(analyzed);
|
|
813
|
-
// Check for deprecated fields
|
|
814
|
-
if (analyzed.ai_score !== undefined) {
|
|
815
|
-
this.addDiagnostic('warning', 'Embedded ai_score is deprecated and will be ignored');
|
|
816
|
-
delete analyzed.ai_score;
|
|
817
|
-
changes.push('Removed deprecated ai_score');
|
|
818
|
-
}
|
|
819
|
-
this.recordPass('analyze', start, ast, analyzed, changes);
|
|
820
|
-
return analyzed;
|
|
821
|
-
}
|
|
822
|
-
validateTypes(data) {
|
|
823
|
-
// Project validation
|
|
824
|
-
if (data.project?.name && typeof data.project.name !== 'string') {
|
|
825
|
-
this.addDiagnostic('error', 'project.name must be a string', {
|
|
826
|
-
line: 0, column: 0, field: 'project.name'
|
|
827
|
-
});
|
|
828
|
-
}
|
|
829
|
-
// Stack validation
|
|
830
|
-
const stackFields = ['framework', 'frontend', 'backend', 'db', 'database', 'hosting'];
|
|
831
|
-
for (const field of stackFields) {
|
|
832
|
-
if (data.stack?.[field] && typeof data.stack[field] !== 'string') {
|
|
833
|
-
this.addDiagnostic('error', `stack.${field} must be a string`, {
|
|
834
|
-
line: 0, column: 0, field: `stack.${field}`
|
|
835
|
-
});
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
// Human context validation
|
|
839
|
-
const humanFields = ['who', 'what', 'why', 'where', 'when', 'how'];
|
|
840
|
-
for (const field of humanFields) {
|
|
841
|
-
const value = data.human_context?.[field];
|
|
842
|
-
if (value && typeof value !== 'string' && typeof value !== 'object') {
|
|
843
|
-
this.addDiagnostic('warning', `human_context.${field} should be a string or object`);
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
// ============================================================================
|
|
848
|
-
// PASS 3: Optimizer (with Discovery)
|
|
849
|
-
// ============================================================================
|
|
850
|
-
async optimize(ast, fafPath) {
|
|
851
|
-
const start = Date.now();
|
|
852
|
-
const optimized = { ...ast };
|
|
853
|
-
const changes = [];
|
|
854
|
-
// Discovery phase
|
|
855
|
-
if (fafPath) {
|
|
856
|
-
try {
|
|
857
|
-
const projectDir = path.dirname(fafPath);
|
|
858
|
-
const discovered = await this.discover(projectDir);
|
|
859
|
-
// Apply discovered values WITHOUT mutation
|
|
860
|
-
optimized._discovered = discovered;
|
|
861
|
-
changes.push(`Discovered ${Object.keys(discovered).length} items`);
|
|
862
|
-
}
|
|
863
|
-
catch (error) {
|
|
864
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
865
|
-
this.addDiagnostic('warning', `Discovery failed: ${message}`);
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
// Remove None/Unknown values (optimization)
|
|
869
|
-
this.removeDefaults(optimized, changes);
|
|
870
|
-
this.recordPass('optimize', start, ast, optimized, changes);
|
|
871
|
-
return optimized;
|
|
872
|
-
}
|
|
873
|
-
async discover(projectDir) {
|
|
874
|
-
const processor = new fab_formats_processor_1.FabFormatsProcessor();
|
|
875
|
-
const analysis = await processor.processFiles(projectDir);
|
|
876
|
-
const discovered = {};
|
|
877
|
-
if (analysis.context) {
|
|
878
|
-
const ctx = analysis.context;
|
|
879
|
-
// Map discovered items (WITHOUT modifying original)
|
|
880
|
-
if (ctx.projectName) {
|
|
881
|
-
discovered.projectName = ctx.projectName;
|
|
882
|
-
}
|
|
883
|
-
if (ctx.mainLanguage) {
|
|
884
|
-
discovered.mainLanguage = ctx.mainLanguage;
|
|
885
|
-
}
|
|
886
|
-
if (ctx.framework) {
|
|
887
|
-
discovered.framework = ctx.framework;
|
|
888
|
-
}
|
|
889
|
-
if (ctx.database) {
|
|
890
|
-
discovered.database = ctx.database;
|
|
891
|
-
}
|
|
892
|
-
if (ctx.backend) {
|
|
893
|
-
discovered.backend = ctx.backend;
|
|
894
|
-
}
|
|
895
|
-
if (ctx.hosting) {
|
|
896
|
-
discovered.hosting = ctx.hosting;
|
|
897
|
-
}
|
|
898
|
-
if (ctx.buildTool) {
|
|
899
|
-
discovered.buildTool = ctx.buildTool;
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
return discovered;
|
|
903
|
-
}
|
|
904
|
-
/**
|
|
905
|
-
* 🎯 SLOT-IGNORE: Remove slot-ignore values during optimization
|
|
906
|
-
*
|
|
907
|
-
* Slot-ignore values like 'None' are kept in the .faf file for scoring,
|
|
908
|
-
* but removed during compilation for cleaner output.
|
|
909
|
-
*
|
|
910
|
-
* Like .gitignore: These values mark slots as "not applicable"
|
|
911
|
-
* - During generation: Set to 'None' (slot-ignore)
|
|
912
|
-
* - During scoring: Counted as filled (not missing)
|
|
913
|
-
* - During compilation: Removed (optimization)
|
|
914
|
-
*
|
|
915
|
-
* See docs/SLOT-IGNORE.md for specification
|
|
916
|
-
*/
|
|
917
|
-
removeDefaults(data, changes) {
|
|
918
|
-
// Slot-ignore values: Mark slots as "not applicable"
|
|
919
|
-
const defaults = ['None', 'Unknown', 'Not specified', 'N/A'];
|
|
920
|
-
const removeFromObject = (obj, path) => {
|
|
921
|
-
for (const key in obj) {
|
|
922
|
-
const value = obj[key];
|
|
923
|
-
const fullPath = path ? `${path}.${key}` : key;
|
|
924
|
-
if (defaults.includes(value)) {
|
|
925
|
-
delete obj[key];
|
|
926
|
-
changes.push(`Removed slot-ignore value at ${fullPath}`);
|
|
927
|
-
}
|
|
928
|
-
else if (typeof value === 'object' && value !== null) {
|
|
929
|
-
removeFromObject(value, fullPath);
|
|
930
|
-
}
|
|
931
|
-
}
|
|
932
|
-
};
|
|
933
|
-
removeFromObject(data, '');
|
|
934
|
-
}
|
|
935
|
-
// ============================================================================
|
|
936
|
-
// PASS 4: Generator
|
|
937
|
-
// ============================================================================
|
|
938
|
-
generate(ast) {
|
|
939
|
-
const start = Date.now();
|
|
940
|
-
// Build IR first (still needed for breakdown/trace)
|
|
941
|
-
const ir = this.buildIR(ast);
|
|
942
|
-
this.ir = {
|
|
943
|
-
version: FafCompiler.VERSION,
|
|
944
|
-
slots: ir,
|
|
945
|
-
metadata: { compiled: new Date().toISOString() }
|
|
946
|
-
};
|
|
947
|
-
// --- Mk4 Kernel Scoring (WASM) ---
|
|
948
|
-
// The Bouncer: type detection → applicable slots → slotignored for the rest
|
|
949
|
-
// Then kernel.score_faf() gets the canonical Mk4 score
|
|
950
|
-
let mk4Score = null;
|
|
951
|
-
let mk4Filled = null;
|
|
952
|
-
let mk4Total = null;
|
|
953
|
-
try {
|
|
954
|
-
const kernel = require('faf-scoring-kernel');
|
|
955
|
-
const { stringify } = require('yaml');
|
|
956
|
-
// Detect project type and get applicable slots
|
|
957
|
-
const projectType = this.detectProjectTypeFromContext(ast);
|
|
958
|
-
const applicableSlots = getSlotsForType(projectType);
|
|
959
|
-
// All 21 slot paths
|
|
960
|
-
const allSlotPaths = [
|
|
961
|
-
...ALL_SLOTS.project,
|
|
962
|
-
...ALL_SLOTS.frontend,
|
|
963
|
-
...ALL_SLOTS.backend,
|
|
964
|
-
...ALL_SLOTS.universal,
|
|
965
|
-
...ALL_SLOTS.human
|
|
966
|
-
];
|
|
967
|
-
// Bouncer: inject slotignored for inapplicable slots AND user slot_ignore
|
|
968
|
-
const normalizedAst = JSON.parse(JSON.stringify(ast));
|
|
969
|
-
// Remove internal fields
|
|
970
|
-
delete normalizedAst._discovered;
|
|
971
|
-
// Also parse user's slot_ignore from the .faf file
|
|
972
|
-
const userIgnored = parseSlotIgnore(ast);
|
|
973
|
-
const setSlotIgnored = (slotPath) => {
|
|
974
|
-
const parts = slotPath.split('.');
|
|
975
|
-
if (parts[0] === 'project') {
|
|
976
|
-
if (!normalizedAst.project) {
|
|
977
|
-
normalizedAst.project = {};
|
|
978
|
-
}
|
|
979
|
-
normalizedAst.project[parts[1]] = 'slotignored';
|
|
980
|
-
}
|
|
981
|
-
else if (parts[0] === 'stack') {
|
|
982
|
-
if (!normalizedAst.stack) {
|
|
983
|
-
normalizedAst.stack = {};
|
|
984
|
-
}
|
|
985
|
-
// Kernel expects old slot names — translate Mk4 back to old
|
|
986
|
-
const kernelField = exports.SLOT_ALIASES_REVERSE[parts[1]] || parts[1];
|
|
987
|
-
normalizedAst.stack[kernelField] = 'slotignored';
|
|
988
|
-
}
|
|
989
|
-
else if (parts[0] === 'human') {
|
|
990
|
-
if (!normalizedAst.human_context) {
|
|
991
|
-
normalizedAst.human_context = {};
|
|
992
|
-
}
|
|
993
|
-
normalizedAst.human_context[parts[1]] = 'slotignored';
|
|
994
|
-
}
|
|
995
|
-
};
|
|
996
|
-
for (const slotPath of allSlotPaths) {
|
|
997
|
-
if (!applicableSlots.includes(slotPath) || userIgnored.includes(slotPath)) {
|
|
998
|
-
setSlotIgnored(slotPath);
|
|
999
|
-
}
|
|
1000
|
-
}
|
|
1001
|
-
// Translate Mk4 stack field names to old names for kernel compatibility
|
|
1002
|
-
if (normalizedAst.stack) {
|
|
1003
|
-
for (const [mk4Name, oldName] of Object.entries(exports.SLOT_ALIASES_REVERSE)) {
|
|
1004
|
-
if (normalizedAst.stack[mk4Name] !== undefined && normalizedAst.stack[oldName] === undefined) {
|
|
1005
|
-
normalizedAst.stack[oldName] = normalizedAst.stack[mk4Name];
|
|
1006
|
-
delete normalizedAst.stack[mk4Name];
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
}
|
|
1010
|
-
const normalizedYaml = stringify(normalizedAst);
|
|
1011
|
-
const kernelResult = JSON.parse(kernel.score_faf(normalizedYaml));
|
|
1012
|
-
mk4Score = kernelResult.score;
|
|
1013
|
-
mk4Filled = kernelResult.populated;
|
|
1014
|
-
mk4Total = kernelResult.active;
|
|
1015
|
-
if (process.env.FAF_DEBUG) {
|
|
1016
|
-
console.log(`[DEBUG] Mk4 kernel score: ${mk4Score}% (${mk4Filled}/${mk4Total})`);
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
catch (err) {
|
|
1020
|
-
// Kernel not available — fall back to Mk3.1 TS scoring
|
|
1021
|
-
if (process.env.FAF_DEBUG) {
|
|
1022
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1023
|
-
console.log(`[DEBUG] Mk4 kernel unavailable, using Mk3.1: ${message}`);
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
// Use Mk4 score if available, otherwise fall back to Mk3.1
|
|
1027
|
-
const slots = this.calculateSlots(ir);
|
|
1028
|
-
const fallbackScore = this.calculateScore(slots);
|
|
1029
|
-
const score = mk4Score !== null ? mk4Score : Math.round(fallbackScore);
|
|
1030
|
-
const filled = mk4Filled !== null ? mk4Filled : slots.filled;
|
|
1031
|
-
const total = mk4Total !== null ? mk4Total : slots.total;
|
|
1032
|
-
const result = {
|
|
1033
|
-
score,
|
|
1034
|
-
filled,
|
|
1035
|
-
total,
|
|
1036
|
-
breakdown: slots.breakdown
|
|
1037
|
-
};
|
|
1038
|
-
const engine = mk4Score !== null ? 'Mk4 (WASM)' : 'Mk3.1 (TS fallback)';
|
|
1039
|
-
this.recordPass('generate', start, ast, result, [
|
|
1040
|
-
`Generated score: ${result.score}% (${result.filled}/${result.total} slots) [${engine}]`
|
|
1041
|
-
]);
|
|
1042
|
-
return result;
|
|
1043
|
-
}
|
|
1044
|
-
buildIR(ast) {
|
|
1045
|
-
const slots = [];
|
|
1046
|
-
// Detect project type to determine applicable slots
|
|
1047
|
-
const projectType = this.detectProjectTypeFromContext(ast);
|
|
1048
|
-
if (process.env.FAF_DEBUG) {
|
|
1049
|
-
console.log(`\n[DEBUG] Project type detected: ${projectType}`);
|
|
1050
|
-
}
|
|
1051
|
-
// Parse slot_ignore from the .faf file
|
|
1052
|
-
const ignoredSlots = parseSlotIgnore(ast);
|
|
1053
|
-
if (process.env.FAF_DEBUG && ignoredSlots.length > 0) {
|
|
1054
|
-
console.log(`[DEBUG] slot_ignore: ${ignoredSlots.join(', ')}`);
|
|
1055
|
-
}
|
|
1056
|
-
// Get applicable slots for this project type
|
|
1057
|
-
const applicableSlots = getSlotsForType(projectType);
|
|
1058
|
-
if (process.env.FAF_DEBUG) {
|
|
1059
|
-
console.log(`[DEBUG] Applicable slots (${applicableSlots.length}): ${applicableSlots.join(', ')}`);
|
|
1060
|
-
}
|
|
1061
|
-
// Filter out ignored slots
|
|
1062
|
-
const activeSlots = applicableSlots.filter(slot => !ignoredSlots.includes(slot));
|
|
1063
|
-
if (process.env.FAF_DEBUG && ignoredSlots.length > 0) {
|
|
1064
|
-
console.log(`[DEBUG] Active slots after ignore (${activeSlots.length}): ${activeSlots.join(', ')}`);
|
|
1065
|
-
}
|
|
1066
|
-
// Helper to get value from ast based on slot path
|
|
1067
|
-
// Checks both nested structure (project.goal) AND flat structure (projectGoal)
|
|
1068
|
-
// to handle inconsistency between init (nested) and sync (flat)
|
|
1069
|
-
// Alternate field names: compact format uses different keys
|
|
1070
|
-
const FIELD_ALIASES = {
|
|
1071
|
-
'goal': ['description'],
|
|
1072
|
-
'main_language': ['language'],
|
|
1073
|
-
};
|
|
1074
|
-
const getSlotValue = (slotPath) => {
|
|
1075
|
-
const parts = slotPath.split('.');
|
|
1076
|
-
if (parts[0] === 'project') {
|
|
1077
|
-
// Check nested first
|
|
1078
|
-
const nested = ast.project?.[parts[1]];
|
|
1079
|
-
if (nested !== undefined && nested !== null) {
|
|
1080
|
-
return nested;
|
|
1081
|
-
}
|
|
1082
|
-
// Check aliases (e.g. goal -> description, main_language -> language)
|
|
1083
|
-
const aliases = FIELD_ALIASES[parts[1]];
|
|
1084
|
-
if (aliases) {
|
|
1085
|
-
for (const alias of aliases) {
|
|
1086
|
-
const aliasVal = ast.project?.[alias];
|
|
1087
|
-
if (aliasVal !== undefined && aliasVal !== null) {
|
|
1088
|
-
return aliasVal;
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
}
|
|
1092
|
-
// Flat fallback: project.goal -> projectGoal, project.name -> projectName
|
|
1093
|
-
const flatKey = `project${parts[1].charAt(0).toUpperCase()}${parts[1].slice(1)}`;
|
|
1094
|
-
return ast[flatKey];
|
|
1095
|
-
}
|
|
1096
|
-
else if (parts[0] === 'stack') {
|
|
1097
|
-
const field = parts[1];
|
|
1098
|
-
// Check Mk4 canonical name first
|
|
1099
|
-
const val = ast.stack?.[field];
|
|
1100
|
-
if (val !== undefined && val !== null) {
|
|
1101
|
-
return val;
|
|
1102
|
-
}
|
|
1103
|
-
// Fall back to old name (e.g. "framework" -> check "frontend")
|
|
1104
|
-
const oldName = exports.SLOT_ALIASES_REVERSE[field];
|
|
1105
|
-
if (oldName) {
|
|
1106
|
-
return ast.stack?.[oldName];
|
|
1107
|
-
}
|
|
1108
|
-
return undefined;
|
|
1109
|
-
}
|
|
1110
|
-
else if (parts[0] === 'human') {
|
|
1111
|
-
// Check human_context first (old format), then context (compact format)
|
|
1112
|
-
return ast.human_context?.[parts[1]] ?? ast.context?.[parts[1]];
|
|
1113
|
-
}
|
|
1114
|
-
return undefined;
|
|
1115
|
-
};
|
|
1116
|
-
// Add all active slots to the IR
|
|
1117
|
-
// Compact format rule: absent fields = slotignored (not penalized)
|
|
1118
|
-
for (const slotPath of activeSlots) {
|
|
1119
|
-
const value = getSlotValue(slotPath);
|
|
1120
|
-
// If value is completely absent (undefined), skip the slot entirely
|
|
1121
|
-
// This implements "absent = ignored" for compact .faf files
|
|
1122
|
-
if (value === undefined) {
|
|
1123
|
-
continue;
|
|
1124
|
-
}
|
|
1125
|
-
this.addSlot(slots, slotPath, value, 'string', 'original', 1);
|
|
1126
|
-
}
|
|
1127
|
-
// Special handling for certain project types (auto-fill missing values)
|
|
1128
|
-
// Chrome Extension: auto-fill technical context
|
|
1129
|
-
if (projectType === 'chrome-extension') {
|
|
1130
|
-
if (!ast.stack) {
|
|
1131
|
-
ast.stack = {};
|
|
1132
|
-
}
|
|
1133
|
-
if (!ast.stack.runtime) {
|
|
1134
|
-
ast.stack.runtime = 'Chrome/Browser';
|
|
1135
|
-
}
|
|
1136
|
-
if (!ast.stack.hosting) {
|
|
1137
|
-
ast.stack.hosting = 'Chrome Web Store';
|
|
1138
|
-
}
|
|
1139
|
-
if (!ast.stack.api && !ast.stack.api_type) {
|
|
1140
|
-
ast.stack.api = 'Chrome Extension APIs';
|
|
1141
|
-
}
|
|
1142
|
-
if (!ast.stack.backend) {
|
|
1143
|
-
ast.stack.backend = 'Service Worker';
|
|
1144
|
-
}
|
|
1145
|
-
if (!ast.stack.db && !ast.stack.database) {
|
|
1146
|
-
ast.stack.db = 'chrome.storage API';
|
|
1147
|
-
}
|
|
1148
|
-
// Add auto-filled slots (only if they're in the active slots list)
|
|
1149
|
-
const chromeSlots = ['stack.runtime', 'stack.hosting', 'stack.api', 'stack.backend', 'stack.db'];
|
|
1150
|
-
for (const slot of chromeSlots) {
|
|
1151
|
-
if (activeSlots.includes(slot) && !slots.find(s => s.path === slot)) {
|
|
1152
|
-
this.addSlot(slots, slot, getSlotValue(slot), 'string', 'discovered', 1);
|
|
1153
|
-
}
|
|
1154
|
-
}
|
|
1155
|
-
}
|
|
1156
|
-
// Static HTML: auto-fill technical context
|
|
1157
|
-
if (projectType === 'static-html' || projectType === 'landing-page') {
|
|
1158
|
-
if (!ast.stack) {
|
|
1159
|
-
ast.stack = {};
|
|
1160
|
-
}
|
|
1161
|
-
if (!ast.stack.framework && !ast.stack.frontend) {
|
|
1162
|
-
ast.stack.framework = 'HTML/CSS/JavaScript';
|
|
1163
|
-
}
|
|
1164
|
-
if (!ast.stack.runtime) {
|
|
1165
|
-
ast.stack.runtime = 'Browser';
|
|
1166
|
-
}
|
|
1167
|
-
if (!ast.stack.hosting) {
|
|
1168
|
-
ast.stack.hosting = 'Static Hosting';
|
|
1169
|
-
}
|
|
1170
|
-
if (!ast.stack.build) {
|
|
1171
|
-
ast.stack.build = 'Direct HTML (no build step)';
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
// n8n Workflow: auto-fill technical context
|
|
1175
|
-
if (projectType === 'n8n-workflow') {
|
|
1176
|
-
if (!ast.project) {
|
|
1177
|
-
ast.project = {};
|
|
1178
|
-
}
|
|
1179
|
-
if (!ast.project.main_language) {
|
|
1180
|
-
ast.project.main_language = ast.tech_stack?.primary_language || 'JSON (workflow definition)';
|
|
1181
|
-
}
|
|
1182
|
-
if (!ast.stack) {
|
|
1183
|
-
ast.stack = {};
|
|
1184
|
-
}
|
|
1185
|
-
if (!ast.stack.runtime) {
|
|
1186
|
-
ast.stack.runtime = ast.tech_stack?.workflow_engine || 'n8n';
|
|
1187
|
-
}
|
|
1188
|
-
if (!ast.stack.backend) {
|
|
1189
|
-
ast.stack.backend = 'Node.js (n8n server)';
|
|
1190
|
-
}
|
|
1191
|
-
if (!ast.stack.api && !ast.stack.api_type) {
|
|
1192
|
-
ast.stack.api = 'Webhooks + HTTP';
|
|
1193
|
-
}
|
|
1194
|
-
if (!ast.stack.db && !ast.stack.database) {
|
|
1195
|
-
ast.stack.db = ast.tech_stack?.infrastructure?.vector_db || 'Workflow State';
|
|
1196
|
-
}
|
|
1197
|
-
if (!ast.stack.hosting) {
|
|
1198
|
-
ast.stack.hosting = 'n8n Cloud';
|
|
1199
|
-
}
|
|
1200
|
-
if (!ast.stack.build) {
|
|
1201
|
-
ast.stack.build = 'n8n Visual Editor';
|
|
1202
|
-
}
|
|
1203
|
-
}
|
|
1204
|
-
// Discovered slots (if any) - only add if slot is active and not already filled
|
|
1205
|
-
if (ast._discovered) {
|
|
1206
|
-
const discovered = ast._discovered;
|
|
1207
|
-
const mapping = {
|
|
1208
|
-
'projectName': 'project.name',
|
|
1209
|
-
'mainLanguage': 'project.main_language',
|
|
1210
|
-
'framework': 'stack.framework',
|
|
1211
|
-
'database': 'stack.db',
|
|
1212
|
-
'backend': 'stack.backend',
|
|
1213
|
-
'hosting': 'stack.hosting',
|
|
1214
|
-
'buildTool': 'stack.build'
|
|
1215
|
-
};
|
|
1216
|
-
for (const [key, slotPath] of Object.entries(mapping)) {
|
|
1217
|
-
if (discovered[key] && activeSlots.includes(slotPath) && !this.hasValue(ast, slotPath)) {
|
|
1218
|
-
// Only add to discovery if not already in slots
|
|
1219
|
-
if (!slots.find(s => s.path === slotPath)) {
|
|
1220
|
-
this.addSlot(slots, `discovery.${slotPath}`, discovered[key], 'string', 'discovered', 1);
|
|
1221
|
-
}
|
|
1222
|
-
}
|
|
1223
|
-
}
|
|
1224
|
-
}
|
|
1225
|
-
return slots;
|
|
1226
|
-
}
|
|
1227
|
-
addSlot(slots, path, value, type, source, weight) {
|
|
1228
|
-
// Deduplication: Check if slot path already exists
|
|
1229
|
-
const exists = slots.some(slot => slot.path === path);
|
|
1230
|
-
if (exists) {
|
|
1231
|
-
if (process.env.FAF_DEBUG) {
|
|
1232
|
-
console.log(`[DEBUG] Skipped duplicate slot: ${path}`);
|
|
1233
|
-
}
|
|
1234
|
-
return; // Skip duplicate slot
|
|
1235
|
-
}
|
|
1236
|
-
const filled = this.isSlotFilled(value);
|
|
1237
|
-
if (process.env.FAF_DEBUG) {
|
|
1238
|
-
const valueStr = JSON.stringify(value) || '';
|
|
1239
|
-
console.log(`[DEBUG] Added slot: ${path} | filled: ${filled} | value: ${valueStr.substring(0, 50)}`);
|
|
1240
|
-
}
|
|
1241
|
-
slots.push({
|
|
1242
|
-
id: `slot_${slots.length + 1}`,
|
|
1243
|
-
path,
|
|
1244
|
-
value,
|
|
1245
|
-
type,
|
|
1246
|
-
source,
|
|
1247
|
-
weight,
|
|
1248
|
-
filled
|
|
1249
|
-
});
|
|
1250
|
-
}
|
|
1251
|
-
isSlotFilled(value) {
|
|
1252
|
-
// Handle null, undefined, false explicitly
|
|
1253
|
-
if (value === null || value === undefined || value === false) {
|
|
1254
|
-
return false;
|
|
1255
|
-
}
|
|
1256
|
-
if (typeof value === 'string') {
|
|
1257
|
-
// Also treat string representations of null/undefined as empty
|
|
1258
|
-
const empty = ['', 'None', 'Unknown', 'Not specified', 'N/A', 'null', 'undefined', '~'];
|
|
1259
|
-
// Also reject generic placeholders that provide no real context
|
|
1260
|
-
const genericPlaceholders = [
|
|
1261
|
-
'Development teams',
|
|
1262
|
-
'Software development solution',
|
|
1263
|
-
'Improve development efficiency',
|
|
1264
|
-
'Cloud platform',
|
|
1265
|
-
'Ongoing development',
|
|
1266
|
-
'Modern development practices',
|
|
1267
|
-
'Development teams building next-generation software',
|
|
1268
|
-
'AI-powered development infrastructure with trust-driven workflows'
|
|
1269
|
-
];
|
|
1270
|
-
const trimmed = value.trim();
|
|
1271
|
-
return !empty.includes(trimmed) && !genericPlaceholders.includes(trimmed);
|
|
1272
|
-
}
|
|
1273
|
-
if (typeof value === 'number') {
|
|
1274
|
-
// Numbers are valid unless they're NaN or Infinity
|
|
1275
|
-
return !isNaN(value) && isFinite(value);
|
|
1276
|
-
}
|
|
1277
|
-
if (typeof value === 'object') {
|
|
1278
|
-
// Arrays and objects need content
|
|
1279
|
-
if (Array.isArray(value)) {
|
|
1280
|
-
return value.length > 0;
|
|
1281
|
-
}
|
|
1282
|
-
return Object.keys(value).length > 0;
|
|
1283
|
-
}
|
|
1284
|
-
return true;
|
|
1285
|
-
}
|
|
1286
|
-
hasValue(ast, path) {
|
|
1287
|
-
const parts = path.split('.');
|
|
1288
|
-
let current = ast;
|
|
1289
|
-
for (const part of parts) {
|
|
1290
|
-
if (!current || !current[part]) {
|
|
1291
|
-
return false;
|
|
1292
|
-
}
|
|
1293
|
-
current = current[part];
|
|
1294
|
-
}
|
|
1295
|
-
return this.isSlotFilled(current);
|
|
1296
|
-
}
|
|
1297
|
-
detectProjectTypeFromContext(ast) {
|
|
1298
|
-
// Check for explicit project type first
|
|
1299
|
-
if (ast.project?.type) {
|
|
1300
|
-
const explicitType = ast.project.type.toLowerCase();
|
|
1301
|
-
// Resolve aliases to canonical type
|
|
1302
|
-
for (const [type, def] of Object.entries(TYPE_DEFINITIONS)) {
|
|
1303
|
-
if (type === explicitType || def.aliases?.includes(explicitType)) {
|
|
1304
|
-
return type;
|
|
1305
|
-
}
|
|
1306
|
-
}
|
|
1307
|
-
// If the explicit type is in TYPE_DEFINITIONS, use it directly
|
|
1308
|
-
if (TYPE_DEFINITIONS[explicitType]) {
|
|
1309
|
-
return explicitType;
|
|
1310
|
-
}
|
|
1311
|
-
// Unknown explicit type - use as-is (will fall to generic in getSlotsForType)
|
|
1312
|
-
return explicitType;
|
|
1313
|
-
}
|
|
1314
|
-
// Infer from goal and context
|
|
1315
|
-
const goal = (ast.project?.goal || '').toLowerCase();
|
|
1316
|
-
const what = (ast.human_context?.what || '').toLowerCase();
|
|
1317
|
-
const mainLanguage = (ast.project?.main_language || '').toLowerCase();
|
|
1318
|
-
// CLI tool indicators (check BEFORE Chrome Extension to avoid false positives)
|
|
1319
|
-
if (goal.includes('cli') || what.includes('cli') ||
|
|
1320
|
-
goal.includes('command line') || what.includes('command line')) {
|
|
1321
|
-
return 'cli';
|
|
1322
|
-
}
|
|
1323
|
-
// MCP Server indicators
|
|
1324
|
-
if (goal.includes('mcp') || what.includes('mcp server') ||
|
|
1325
|
-
goal.includes('model context protocol')) {
|
|
1326
|
-
return 'mcp-server';
|
|
1327
|
-
}
|
|
1328
|
-
// Chrome Extension detection with fuzzy matching (only if not CLI)
|
|
1329
|
-
const goalDetection = chrome_extension_detector_1.ChromeExtensionDetector.detect(goal);
|
|
1330
|
-
const whatDetection = chrome_extension_detector_1.ChromeExtensionDetector.detect(what);
|
|
1331
|
-
if (goalDetection.detected || whatDetection.detected ||
|
|
1332
|
-
ast.stack?.framework === 'Chrome Extension') {
|
|
1333
|
-
return 'chrome-extension';
|
|
1334
|
-
}
|
|
1335
|
-
// Library indicators
|
|
1336
|
-
if (goal.includes('library') || what.includes('library') ||
|
|
1337
|
-
goal.includes('package') || what.includes('npm package')) {
|
|
1338
|
-
return 'library';
|
|
1339
|
-
}
|
|
1340
|
-
// API/Backend indicators
|
|
1341
|
-
if (goal.includes('api') || what.includes('api') ||
|
|
1342
|
-
goal.includes('backend') || what.includes('backend') ||
|
|
1343
|
-
ast.stack?.backend && !ast.stack?.frontend) {
|
|
1344
|
-
return 'backend-api';
|
|
1345
|
-
}
|
|
1346
|
-
// Frontend indicators (check both Mk4 and old names)
|
|
1347
|
-
if (ast.stack?.framework || ast.stack?.frontend || ast.stack?.css || ast.stack?.css_framework || ast.stack?.ui_library) {
|
|
1348
|
-
return ast.stack?.backend ? 'fullstack' : 'frontend';
|
|
1349
|
-
}
|
|
1350
|
-
// Language-based defaults
|
|
1351
|
-
if (mainLanguage === 'python') {
|
|
1352
|
-
if (ast.stack?.framework || ast.stack?.frontend) {
|
|
1353
|
-
return 'fullstack';
|
|
1354
|
-
}
|
|
1355
|
-
return 'python-app'; // Could be CLI, API, or data science
|
|
1356
|
-
}
|
|
1357
|
-
return 'generic';
|
|
1358
|
-
}
|
|
1359
|
-
requiresFrontendStack(projectType) {
|
|
1360
|
-
const frontendTypes = ['frontend', 'fullstack', 'svelte', 'react', 'vue', 'angular'];
|
|
1361
|
-
// Chrome extensions don't need traditional frontend stack
|
|
1362
|
-
return frontendTypes.includes(projectType) && projectType !== 'chrome-extension';
|
|
1363
|
-
}
|
|
1364
|
-
requiresBackendStack(projectType) {
|
|
1365
|
-
const backendTypes = ['backend-api', 'fullstack', 'cli-tool', 'library', 'python-app', 'node-api'];
|
|
1366
|
-
// Chrome extensions don't need traditional backend stack
|
|
1367
|
-
return backendTypes.includes(projectType) && projectType !== 'chrome-extension';
|
|
1368
|
-
}
|
|
1369
|
-
calculateSlots(ir) {
|
|
1370
|
-
const sections = {
|
|
1371
|
-
project: { filled: 0, total: 0, slots: [] },
|
|
1372
|
-
stack: { filled: 0, total: 0, slots: [] },
|
|
1373
|
-
human: { filled: 0, total: 0, slots: [] },
|
|
1374
|
-
discovery: { filled: 0, total: 0, slots: [] }
|
|
1375
|
-
};
|
|
1376
|
-
for (const slot of ir) {
|
|
1377
|
-
const [section] = slot.path.split('.');
|
|
1378
|
-
const sectionKey = section === 'human' ? 'human' :
|
|
1379
|
-
section === 'discovery' ? 'discovery' :
|
|
1380
|
-
section === 'project' ? 'project' : 'stack';
|
|
1381
|
-
const sec = sections[sectionKey];
|
|
1382
|
-
sec.total++;
|
|
1383
|
-
if (slot.filled) {
|
|
1384
|
-
sec.filled++;
|
|
1385
|
-
}
|
|
1386
|
-
sec.slots.push({
|
|
1387
|
-
id: slot.id,
|
|
1388
|
-
value: slot.value,
|
|
1389
|
-
filled: slot.filled,
|
|
1390
|
-
source: slot.source,
|
|
1391
|
-
points: slot.filled ? slot.weight : 0
|
|
1392
|
-
});
|
|
1393
|
-
}
|
|
1394
|
-
// Calculate percentages
|
|
1395
|
-
const breakdown = {
|
|
1396
|
-
project: {
|
|
1397
|
-
...sections.project,
|
|
1398
|
-
percentage: sections.project.total > 0
|
|
1399
|
-
? Math.round((sections.project.filled / sections.project.total) * 100)
|
|
1400
|
-
: 0
|
|
1401
|
-
},
|
|
1402
|
-
stack: {
|
|
1403
|
-
...sections.stack,
|
|
1404
|
-
percentage: sections.stack.total > 0
|
|
1405
|
-
? Math.round((sections.stack.filled / sections.stack.total) * 100)
|
|
1406
|
-
: 0
|
|
1407
|
-
},
|
|
1408
|
-
human: {
|
|
1409
|
-
...sections.human,
|
|
1410
|
-
percentage: sections.human.total > 0
|
|
1411
|
-
? Math.round((sections.human.filled / sections.human.total) * 100)
|
|
1412
|
-
: 0
|
|
1413
|
-
},
|
|
1414
|
-
discovery: {
|
|
1415
|
-
...sections.discovery,
|
|
1416
|
-
percentage: sections.discovery.total > 0
|
|
1417
|
-
? Math.round((sections.discovery.filled / sections.discovery.total) * 100)
|
|
1418
|
-
: 0
|
|
1419
|
-
}
|
|
1420
|
-
};
|
|
1421
|
-
const filled = Object.values(sections).reduce((sum, sec) => sum + sec.filled, 0);
|
|
1422
|
-
const total = Object.values(sections).reduce((sum, sec) => sum + sec.total, 0);
|
|
1423
|
-
return { filled, total, breakdown };
|
|
1424
|
-
}
|
|
1425
|
-
calculateScore(slots) {
|
|
1426
|
-
if (slots.total === 0) {
|
|
1427
|
-
return 0;
|
|
1428
|
-
}
|
|
1429
|
-
return (slots.filled / slots.total) * 100;
|
|
1430
|
-
}
|
|
1431
|
-
// ============================================================================
|
|
1432
|
-
// Utilities
|
|
1433
|
-
// ============================================================================
|
|
1434
|
-
calculateChecksum(result) {
|
|
1435
|
-
const data = JSON.stringify({
|
|
1436
|
-
score: result.score,
|
|
1437
|
-
filled: result.filled,
|
|
1438
|
-
total: result.total,
|
|
1439
|
-
version: FafCompiler.VERSION
|
|
1440
|
-
});
|
|
1441
|
-
return crypto.createHash('md5').update(data).digest('hex').slice(0, 8);
|
|
1442
|
-
}
|
|
1443
|
-
recordPass(name, startTime, input, output, changes) {
|
|
1444
|
-
this.trace.passes.push({
|
|
1445
|
-
name,
|
|
1446
|
-
duration: Date.now() - startTime,
|
|
1447
|
-
input: this.sanitize(input),
|
|
1448
|
-
output: this.sanitize(output),
|
|
1449
|
-
changes
|
|
1450
|
-
});
|
|
1451
|
-
}
|
|
1452
|
-
sanitize(data) {
|
|
1453
|
-
// Limit size for trace
|
|
1454
|
-
const str = JSON.stringify(data);
|
|
1455
|
-
if (str.length > 1000) {
|
|
1456
|
-
return { _truncated: true, size: str.length };
|
|
1457
|
-
}
|
|
1458
|
-
return data;
|
|
1459
|
-
}
|
|
1460
|
-
addDiagnostic(severity, message, location, suggestion) {
|
|
1461
|
-
this.diagnostics.push({ severity, message, location, suggestion });
|
|
1462
|
-
}
|
|
1463
|
-
// ============================================================================
|
|
1464
|
-
// Public API
|
|
1465
|
-
// ============================================================================
|
|
1466
|
-
/**
|
|
1467
|
-
* Compile with trace output
|
|
1468
|
-
*/
|
|
1469
|
-
async compileWithTrace(fafPath) {
|
|
1470
|
-
const result = await this.compile(fafPath);
|
|
1471
|
-
this.printTrace(result);
|
|
1472
|
-
return result;
|
|
1473
|
-
}
|
|
1474
|
-
/**
|
|
1475
|
-
* Verify a checksum
|
|
1476
|
-
*/
|
|
1477
|
-
async verify(fafPath, checksum) {
|
|
1478
|
-
const result = await this.compile(fafPath);
|
|
1479
|
-
return result.checksum === checksum;
|
|
1480
|
-
}
|
|
1481
|
-
/**
|
|
1482
|
-
* Get intermediate representation
|
|
1483
|
-
*/
|
|
1484
|
-
async getIR(fafPath) {
|
|
1485
|
-
const result = await this.compile(fafPath);
|
|
1486
|
-
return result.ir;
|
|
1487
|
-
}
|
|
1488
|
-
/**
|
|
1489
|
-
* Print diagnostic report
|
|
1490
|
-
*/
|
|
1491
|
-
printDiagnostics() {
|
|
1492
|
-
if (this.diagnostics.length === 0) {
|
|
1493
|
-
console.log('✓ No issues found');
|
|
1494
|
-
return;
|
|
1495
|
-
}
|
|
1496
|
-
const byType = {
|
|
1497
|
-
error: this.diagnostics.filter(d => d.severity === 'error'),
|
|
1498
|
-
warning: this.diagnostics.filter(d => d.severity === 'warning'),
|
|
1499
|
-
info: this.diagnostics.filter(d => d.severity === 'info')
|
|
1500
|
-
};
|
|
1501
|
-
if (byType.error.length > 0) {
|
|
1502
|
-
console.log(`\n❌ ${byType.error.length} Errors:`);
|
|
1503
|
-
byType.error.forEach(d => {
|
|
1504
|
-
console.log(` ${d.message}`);
|
|
1505
|
-
if (d.suggestion) {
|
|
1506
|
-
console.log(` → ${d.suggestion}`);
|
|
1507
|
-
}
|
|
1508
|
-
});
|
|
1509
|
-
}
|
|
1510
|
-
if (byType.warning.length > 0) {
|
|
1511
|
-
console.log(`\n⚠️ ${byType.warning.length} Warnings:`);
|
|
1512
|
-
byType.warning.forEach(d => {
|
|
1513
|
-
console.log(` ${d.message}`);
|
|
1514
|
-
if (d.suggestion) {
|
|
1515
|
-
console.log(` → ${d.suggestion}`);
|
|
1516
|
-
}
|
|
1517
|
-
});
|
|
1518
|
-
}
|
|
1519
|
-
if (byType.info.length > 0) {
|
|
1520
|
-
console.log(`\nℹ️ ${byType.info.length} Info:`);
|
|
1521
|
-
byType.info.forEach(d => {
|
|
1522
|
-
console.log(` ${d.message}`);
|
|
1523
|
-
});
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
/**
|
|
1527
|
-
* Print compilation trace
|
|
1528
|
-
*/
|
|
1529
|
-
printTrace(result) {
|
|
1530
|
-
console.log('\n📊 FAF Compilation Trace');
|
|
1531
|
-
console.log('═'.repeat(60));
|
|
1532
|
-
console.log(`Version: ${result.trace.version}`);
|
|
1533
|
-
console.log(`Input Hash: ${result.trace.inputHash}`);
|
|
1534
|
-
console.log(`Checksum: ${result.checksum}`);
|
|
1535
|
-
console.log();
|
|
1536
|
-
console.log('Compilation Passes:');
|
|
1537
|
-
result.trace.passes.forEach((pass, i) => {
|
|
1538
|
-
console.log(` ${i + 1}. ${pass.name.toUpperCase()} (${pass.duration}ms)`);
|
|
1539
|
-
pass.changes.forEach(change => {
|
|
1540
|
-
console.log(` → ${change}`);
|
|
1541
|
-
});
|
|
1542
|
-
});
|
|
1543
|
-
console.log();
|
|
1544
|
-
console.log('Result:');
|
|
1545
|
-
console.log(` Score: ${result.score}%`);
|
|
1546
|
-
console.log(` Filled: ${result.filled}/${result.total} slots`);
|
|
1547
|
-
console.log();
|
|
1548
|
-
console.log('Breakdown:');
|
|
1549
|
-
console.log(` Project: ${result.breakdown.project.filled}/${result.breakdown.project.total} (${result.breakdown.project.percentage}%)`);
|
|
1550
|
-
console.log(` Stack: ${result.breakdown.stack.filled}/${result.breakdown.stack.total} (${result.breakdown.stack.percentage}%)`);
|
|
1551
|
-
console.log(` Human: ${result.breakdown.human.filled}/${result.breakdown.human.total} (${result.breakdown.human.percentage}%)`);
|
|
1552
|
-
if (result.breakdown.discovery.total > 0) {
|
|
1553
|
-
console.log(` Discovery: ${result.breakdown.discovery.filled}/${result.breakdown.discovery.total} (${result.breakdown.discovery.percentage}%)`);
|
|
1554
|
-
}
|
|
1555
|
-
if (result.diagnostics.length > 0) {
|
|
1556
|
-
console.log();
|
|
1557
|
-
this.printDiagnostics();
|
|
1558
|
-
}
|
|
1559
|
-
console.log('═'.repeat(60));
|
|
1560
|
-
}
|
|
1561
|
-
}
|
|
1562
|
-
exports.FafCompiler = FafCompiler;
|
|
1563
|
-
// ============================================================================
|
|
1564
|
-
// Export convenience functions
|
|
1565
|
-
// ============================================================================
|
|
1566
|
-
/**
|
|
1567
|
-
* Compile a .faf file
|
|
1568
|
-
*/
|
|
1569
|
-
async function compile(fafPath) {
|
|
1570
|
-
const compiler = new FafCompiler();
|
|
1571
|
-
return compiler.compile(fafPath);
|
|
1572
|
-
}
|
|
1573
|
-
/**
|
|
1574
|
-
* Compile with trace output
|
|
1575
|
-
*/
|
|
1576
|
-
async function compileWithTrace(fafPath) {
|
|
1577
|
-
const compiler = new FafCompiler();
|
|
1578
|
-
return compiler.compileWithTrace(fafPath);
|
|
1579
|
-
}
|
|
1580
|
-
/**
|
|
1581
|
-
* Verify a checksum
|
|
1582
|
-
*/
|
|
1583
|
-
async function verify(fafPath, checksum) {
|
|
1584
|
-
const compiler = new FafCompiler();
|
|
1585
|
-
return compiler.verify(fafPath, checksum);
|
|
1586
|
-
}
|
|
1587
|
-
//# sourceMappingURL=faf-compiler.js.map
|