faf 7.16.2 → 8.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 +21 -9
- package/dist/cli.js +282 -269
- package/dist/cli.js.map +13 -12
- package/dist/core/faf-dna.d.ts +20 -0
- package/dist/core/slots.d.ts +1 -1
- package/dist/index.js +143 -143
- package/dist/index.js.map +11 -10
- package/dist/interop/command-note.d.ts +43 -0
- package/dist/interop/inject.d.ts +8 -1
- package/dist/wasm/kernel.d.ts +1 -1
- package/package.json +1 -1
- package/project.faf +24 -21
- package/vendor/faf-scoring-kernel/README.md +82 -8
- package/vendor/faf-scoring-kernel/faf_wasm_sdk.d.ts +5 -2
- package/vendor/faf-scoring-kernel/faf_wasm_sdk.js +5 -2
- package/vendor/faf-scoring-kernel/faf_wasm_sdk_bg.wasm +0 -0
- package/vendor/faf-scoring-kernel/package.json +4 -3
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A command value may carry its own note: `cmd — note`.
|
|
3
|
+
*
|
|
4
|
+
* `key_files` already works this way (`path — role`), and the authors turn
|
|
5
|
+
* that into a `| Path | Role |` table. Commands get the same convention, so a
|
|
6
|
+
* `.faf` can say what a script actually does:
|
|
7
|
+
*
|
|
8
|
+
* ```yaml
|
|
9
|
+
* commands:
|
|
10
|
+
* build: bun run build — clean, bundle cli+index, then tsc
|
|
11
|
+
* ```
|
|
12
|
+
*
|
|
13
|
+
* authors as:
|
|
14
|
+
*
|
|
15
|
+
* ```bash
|
|
16
|
+
* bun run build # clean, bundle cli+index, then tsc
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Without a note the behaviour is unchanged — the key is the comment, exactly
|
|
20
|
+
* as before. The separator is the em dash with spaces around it, matching
|
|
21
|
+
* `key_files`; a bare hyphen is left alone, because shell commands are full of
|
|
22
|
+
* them (`--force`, `-rf`).
|
|
23
|
+
*
|
|
24
|
+
* Every consumer of `data.commands` must split before it renders, or the note
|
|
25
|
+
* leaks into the command itself — an authored `bun run build — clean…` that a
|
|
26
|
+
* reader would try to run.
|
|
27
|
+
*/
|
|
28
|
+
/** The separator a command value uses to carry its note. */
|
|
29
|
+
export declare const NOTE_SEPARATOR = " \u2014 ";
|
|
30
|
+
export interface CommandAndNote {
|
|
31
|
+
/** The command to run, with any note removed. */
|
|
32
|
+
cmd: string;
|
|
33
|
+
/** The note the value carried, or null when it carried none. */
|
|
34
|
+
note: string | null;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Split a command value into the command and its note.
|
|
38
|
+
*
|
|
39
|
+
* @param value a `commands` value, e.g. `bun run build` or `bun run build — clean, then tsc`
|
|
40
|
+
*/
|
|
41
|
+
export declare function splitCommandNote(value: unknown): CommandAndNote;
|
|
42
|
+
/** The command alone — for prose and for authors that show no comments. */
|
|
43
|
+
export declare function commandOnly(value: unknown): string;
|
package/dist/interop/inject.d.ts
CHANGED
|
@@ -123,7 +123,14 @@ export declare function injectFafBlock(path: string, block: string, start?: stri
|
|
|
123
123
|
* older block there is an example to faf, and stays below the new one;
|
|
124
124
|
* - a whole-line START marker sits past more than MAX_OPEN_CONTAINERS
|
|
125
125
|
* nested lists or quotes: faf did not read that far, and the older block
|
|
126
|
-
* stays below the new one
|
|
126
|
+
* stays below the new one;
|
|
127
|
+
* - a whole-line START or END marker is shown as text with no matching pair
|
|
128
|
+
* — a block an older faf truncated, or a pair the two readings read
|
|
129
|
+
* differently. faf cannot prove where that block ended, so it is left
|
|
130
|
+
* exactly as it is and the new block goes on top. Without this line the
|
|
131
|
+
* file is the one case in this family that is prefixed in silence: it
|
|
132
|
+
* carries faf's own marker text, so it looks most like faf's to a reader
|
|
133
|
+
* and least like it to faf.
|
|
127
134
|
* `label` names the file (`CLAUDE.md`). `existing` is the file's text before
|
|
128
135
|
* the write (null when there was none). faf-mcp and claude-faf-mcp print the
|
|
129
136
|
* same line through this export.
|
package/dist/wasm/kernel.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { KernelScoreResult, FafbInfo } from '../core/types.js';
|
|
2
2
|
export declare function score(yaml: string): KernelScoreResult;
|
|
3
|
-
/**
|
|
3
|
+
/** Same as {@link score} (always 33) — kept for existing callers (a leading BOM is not scored). */
|
|
4
4
|
export declare function scoreEnterprise(yaml: string): KernelScoreResult;
|
|
5
5
|
/** Validate .faf YAML (a leading BOM is left out, as in {@link score}: `faf check` reads a BOM file). */
|
|
6
6
|
export declare function validate(yaml: string): boolean;
|
package/package.json
CHANGED
package/project.faf
CHANGED
|
@@ -1,29 +1,32 @@
|
|
|
1
1
|
faf_version: "3.0"
|
|
2
2
|
project:
|
|
3
3
|
name: faf-cli
|
|
4
|
-
version: "
|
|
5
|
-
goal: "CLI for IANA-registered `.faf` + `.fafm` — context DNA and portable agent memory. TypeScript, Bun-native since v6. package faf-cli
|
|
4
|
+
version: "8.0.0"
|
|
5
|
+
goal: "CLI for IANA-registered `.faf` + `.fafm` — context DNA and portable agent memory. TypeScript, Bun-native since v6. package faf-cli v8.0.0 The Always33 Edition — scored by the always-33 engine."
|
|
6
6
|
main_language: TypeScript
|
|
7
7
|
type: cli # found: package.json bin
|
|
8
8
|
# Commands + key_files feed `faf export --agents` (hand values win over detection).
|
|
9
9
|
commands:
|
|
10
10
|
install: bun install
|
|
11
|
-
build: bun run build
|
|
12
|
-
dev: bun run dev
|
|
13
|
-
test: bun run test
|
|
14
|
-
lint: bun run lint
|
|
11
|
+
build: bun run build — clean, bundle src/cli.ts to dist, then tsc
|
|
12
|
+
dev: bun run dev — run the CLI from source, no build
|
|
13
|
+
test: bun run test — must pass before a change is done
|
|
14
|
+
lint: bun run lint — eslint over src
|
|
15
|
+
check:no-hardcode: bun run check:no-hardcode — fail if a build-machine path leaked into dist
|
|
15
16
|
key_files:
|
|
16
|
-
- src/cli.ts
|
|
17
|
-
- src/index.ts
|
|
18
|
-
- src/commands/
|
|
19
|
-
- src/commands/memory.ts
|
|
20
|
-
- src/core/
|
|
21
|
-
- src/detect/
|
|
22
|
-
- src/fafm/
|
|
23
|
-
- src/interop/
|
|
24
|
-
- src/
|
|
25
|
-
-
|
|
26
|
-
-
|
|
17
|
+
- src/cli.ts — CLI entry (Commander); builds to the `faf` / `faf-cli` bin
|
|
18
|
+
- src/index.ts — library entry; builds to `main`, plus the `./pack` export
|
|
19
|
+
- src/commands/ — one file per faf subcommand (39)
|
|
20
|
+
- src/commands/memory.ts — `faf memory`, the `.fafm` surface
|
|
21
|
+
- src/core/ — domain engines (drift, faf-dna, faf-source, cwd-guard)
|
|
22
|
+
- src/detect/ — stack and project detection, per language
|
|
23
|
+
- src/fafm/ — the `.fafm` library (soul, from-claude-dir, types)
|
|
24
|
+
- src/interop/ — the context authors (agents, claude, gemini, cards, copilot)
|
|
25
|
+
- src/interrogate/ — extractors that read a repo's own files for facts (readme, cargo, compose, env)
|
|
26
|
+
- src/ui/ — terminal output (colors, display, progress, star-nudge)
|
|
27
|
+
- src/wasm/ — bridge to faf-scoring-kernel; scoring lives there, not in TS
|
|
28
|
+
- package.json — scripts, and the bin that maps `faf` to dist/cli.js
|
|
29
|
+
- project.faf — this file; the DNA every author reads from
|
|
27
30
|
instant_context:
|
|
28
31
|
what_building: CLI for IANA-registered .faf context + .fafm memory
|
|
29
32
|
tech_stack: TypeScript · Bun-native since v6
|
|
@@ -43,9 +46,9 @@ stack:
|
|
|
43
46
|
runtime: slotignored
|
|
44
47
|
database: slotignored
|
|
45
48
|
connection: slotignored
|
|
46
|
-
hosting:
|
|
47
|
-
build:
|
|
48
|
-
cicd:
|
|
49
|
+
hosting: npm + Homebrew
|
|
50
|
+
build: Bun (bun build) + tsc
|
|
51
|
+
cicd: GitHub Actions
|
|
49
52
|
monorepo_tool: slotignored
|
|
50
53
|
package_manager: slotignored
|
|
51
54
|
workspaces: slotignored
|
|
@@ -58,7 +61,7 @@ human_context:
|
|
|
58
61
|
what: Persistent AI Context Standard — project DNA for AI. IANA-registered. Anthropic-merged.
|
|
59
62
|
why: Eliminates 91% context re-discovery tax — define once, AI remembers forever
|
|
60
63
|
where: npm registry, Homebrew, GitHub
|
|
61
|
-
when: Production since September 2025; Bun-native since v6; current package
|
|
64
|
+
when: Production since September 2025; Bun-native since v6; current package 8.0.0 (always-33 engine)
|
|
62
65
|
how: bunx faf-cli auto, then project.faf versions with your code — faf show renders it human-visible
|
|
63
66
|
monorepo:
|
|
64
67
|
packages_count: slotignored
|
|
@@ -1,14 +1,88 @@
|
|
|
1
|
-
# faf-scoring-kernel
|
|
1
|
+
# faf-scoring-kernel
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**faf-scoring-kernel v3.0.0 — The Always33 Edition**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
- `score_faf` is 21-slot base; `score_faf_enterprise` is 33-slot Mk4
|
|
5
|
+
One engine, one number: `score_faf` is always-33, so a repo scores the same in every FAF app.
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
WASM from the FAF Rust workspace. Scores `.faf` against all 33 slots and compiles `.fafb`. `.faf` is IANA-registered as `application/vnd.faf+yaml`.
|
|
8
|
+
|
|
9
|
+
## What's New — v3.0.0
|
|
10
|
+
|
|
11
|
+
One engine, one number: `score_faf` is always-33, so a repo scores the same in every FAF app.
|
|
12
|
+
|
|
13
|
+
- `score_faf` → always-33 — the same score as faf-kernel, the Rust SDK and the MCP servers
|
|
14
|
+
- `score_faf_enterprise` → alias of `score_faf` (existing callers keep working)
|
|
15
|
+
- `score_fafb` → agrees with `score_faf`
|
|
16
|
+
- `tbd` / `todo` count as empty (placeholders)
|
|
17
|
+
- Engine `sdk_version()` is **3.1.0** (the `faf-wasm-sdk` crate this WASM was built from)
|
|
18
|
+
|
|
19
|
+
**Upgrading from 2.x:** a `.faf` without its 12 enterprise `slotignored` markers now scores against all 33 slots, so its number can drop (100 → 64). Mark the slots that don't apply as `slotignored` — a 21-slot project carries the 12 enterprise slots that way — and the score returns.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
9
22
|
|
|
10
23
|
```bash
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
24
|
+
npm install faf-scoring-kernel
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Node.js 16+ and Bun.
|
|
28
|
+
|
|
29
|
+
## Usage
|
|
30
|
+
|
|
31
|
+
```javascript
|
|
32
|
+
const kernel = require('faf-scoring-kernel');
|
|
33
|
+
|
|
34
|
+
const yaml = `faf_version: 2.5.0
|
|
35
|
+
project:
|
|
36
|
+
name: my-app
|
|
37
|
+
goal: Ship a fast CLI
|
|
38
|
+
main_language: Rust
|
|
39
|
+
`;
|
|
40
|
+
|
|
41
|
+
const result = JSON.parse(kernel.score_faf(yaml));
|
|
42
|
+
console.log(result.score, result.populated, '/', result.active); // active = 33 minus slotignored
|
|
43
|
+
|
|
44
|
+
const bytes = kernel.compile_fafb(yaml);
|
|
45
|
+
console.log(String.fromCharCode(bytes[0], bytes[1], bytes[2], bytes[3])); // FAFB
|
|
46
|
+
console.log(JSON.parse(kernel.decompile_fafb(bytes)).version); // 2.0
|
|
14
47
|
```
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
51
|
+
8 pure-function exports. No classes. No state.
|
|
52
|
+
|
|
53
|
+
| Function | Input | Output |
|
|
54
|
+
|----------|-------|--------|
|
|
55
|
+
| `sdk_version()` | — | engine version string (`3.1.0`) |
|
|
56
|
+
| `score_faf(yaml)` | YAML string | JSON — always-33 |
|
|
57
|
+
| `score_faf_enterprise(yaml)` | YAML string | JSON — same as `score_faf` |
|
|
58
|
+
| `validate_faf(yaml)` | YAML string | `boolean` |
|
|
59
|
+
| `compile_fafb(yaml)` | YAML string | `Uint8Array` — FAFb v2 |
|
|
60
|
+
| `decompile_fafb(bytes)` | `Uint8Array` | JSON string |
|
|
61
|
+
| `score_fafb(bytes)` | `Uint8Array` | JSON string — same score as `score_faf` |
|
|
62
|
+
| `fafb_info(bytes)` | `Uint8Array` | JSON — header + section table |
|
|
63
|
+
|
|
64
|
+
## Tiers
|
|
65
|
+
|
|
66
|
+
| Score | Tier |
|
|
67
|
+
|-------|------|
|
|
68
|
+
| 100% | ✪ Trophy |
|
|
69
|
+
| 99% | ★ Gold |
|
|
70
|
+
| 95% | ◆ Silver |
|
|
71
|
+
| 85% | ◇ Bronze |
|
|
72
|
+
| 70% | ● Green |
|
|
73
|
+
| 55% | ● Yellow |
|
|
74
|
+
| 1% | ○ Red |
|
|
75
|
+
| 0% | ♡ White |
|
|
76
|
+
|
|
77
|
+
✪ is the work glyph for 100%. Same score as 🏆 on social surfaces.
|
|
78
|
+
|
|
79
|
+
## Links
|
|
80
|
+
|
|
81
|
+
- [faf.one](https://faf.one) · [the format spec](https://faf.one/spec)
|
|
82
|
+
- [Source](https://github.com/Wolfe-Jam/faf-rust) — `crates/faf-wasm-sdk` (engine) · `npm/faf-scoring-kernel` (this package)
|
|
83
|
+
- [IANA](https://www.iana.org/assignments/media-types/application/vnd.faf+yaml) — `application/vnd.faf+yaml`
|
|
84
|
+
- [faf-cli](https://www.npmjs.com/package/faf-cli) vendors this WASM
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
|
@@ -17,12 +17,15 @@ export function decompile_fafb(bytes: Uint8Array): string;
|
|
|
17
17
|
export function fafb_info(bytes: Uint8Array): string;
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* Score FAF YAML content
|
|
20
|
+
* Score FAF YAML content with the Mk4 kernel (always-33) — returns JSON.
|
|
21
|
+
*
|
|
22
|
+
* Always 33 slots. A 21-slot file carries the 12 enterprise slots as
|
|
23
|
+
* `slotignored`, so it scores the same here as in every other FAF app.
|
|
21
24
|
*/
|
|
22
25
|
export function score_faf(yaml: string): string;
|
|
23
26
|
|
|
24
27
|
/**
|
|
25
|
-
*
|
|
28
|
+
* Same as [`score_faf`] (always-33). Kept so existing callers keep working.
|
|
26
29
|
*/
|
|
27
30
|
export function score_faf_enterprise(yaml: string): string;
|
|
28
31
|
|
|
@@ -94,7 +94,10 @@ function fafb_info(bytes) {
|
|
|
94
94
|
exports.fafb_info = fafb_info;
|
|
95
95
|
|
|
96
96
|
/**
|
|
97
|
-
* Score FAF YAML content
|
|
97
|
+
* Score FAF YAML content with the Mk4 kernel (always-33) — returns JSON.
|
|
98
|
+
*
|
|
99
|
+
* Always 33 slots. A 21-slot file carries the 12 enterprise slots as
|
|
100
|
+
* `slotignored`, so it scores the same here as in every other FAF app.
|
|
98
101
|
* @param {string} yaml
|
|
99
102
|
* @returns {string}
|
|
100
103
|
*/
|
|
@@ -127,7 +130,7 @@ function score_faf(yaml) {
|
|
|
127
130
|
exports.score_faf = score_faf;
|
|
128
131
|
|
|
129
132
|
/**
|
|
130
|
-
*
|
|
133
|
+
* Same as [`score_faf`] (always-33). Kept so existing callers keep working.
|
|
131
134
|
* @param {string} yaml
|
|
132
135
|
* @returns {string}
|
|
133
136
|
*/
|
|
Binary file
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "faf-scoring-kernel",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "FAF Mk4 Scoring Kernel
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "FAF Mk4 Scoring Kernel — WASM from faf-rust. Scores .faf always-33 and compiles FAFb v2.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "wolfejam <wolfejam@faf.one>",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
9
|
-
"url": "https://github.com/Wolfe-Jam/faf-rust"
|
|
9
|
+
"url": "git+https://github.com/Wolfe-Jam/faf-rust.git",
|
|
10
|
+
"directory": "npm/faf-scoring-kernel"
|
|
10
11
|
},
|
|
11
12
|
"homepage": "https://faf.one",
|
|
12
13
|
"files": [
|