faf-python-sdk 1.3.0__py3-none-any.whl → 1.4.0__py3-none-any.whl
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.
- {faf_python_sdk-1.3.0.dist-info → faf_python_sdk-1.4.0.dist-info}/METADATA +10 -8
- {faf_python_sdk-1.3.0.dist-info → faf_python_sdk-1.4.0.dist-info}/RECORD +6 -6
- faf_sdk/__init__.py +13 -5
- faf_sdk/interop.py +55 -11
- {faf_python_sdk-1.3.0.dist-info → faf_python_sdk-1.4.0.dist-info}/WHEEL +0 -0
- {faf_python_sdk-1.3.0.dist-info → faf_python_sdk-1.4.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: faf-python-sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: Persistent project context for Python — parse, validate, and score `.faf` files. The foundation other Python FAF tools (gemini-faf-mcp, custom MCP servers, CI validators) build on. IANA-registered application/vnd.faf+yaml.
|
|
5
5
|
Project-URL: Homepage, https://faf.one
|
|
6
6
|
Project-URL: Documentation, https://github.com/Wolfe-Jam/faf-python-sdk
|
|
@@ -41,25 +41,27 @@ The foundation other Python FAF tools build on. If you're building MCP servers,
|
|
|
41
41
|
[](https://builder.faf.one)
|
|
42
42
|
[](https://pypi.org/project/faf-python-sdk/)
|
|
43
43
|
[](https://pypi.org/project/faf-python-sdk/)
|
|
44
|
-
[](https://github.com/Wolfe-Jam/faf-python-sdk)
|
|
45
45
|
[](https://www.iana.org/assignments/media-types/application/vnd.faf+yaml)
|
|
46
46
|
|
|
47
47
|
**Media Type:** `application/vnd.faf+yaml` (IANA registered)
|
|
48
48
|
|
|
49
|
-
## What's New in v1.
|
|
49
|
+
## What's New in v1.4.0 — The Interop Edition
|
|
50
50
|
|
|
51
|
-
The
|
|
51
|
+
The interop functions get their real names: `author_agents_md` / `author_gemini_md` are public, `render_*` is the impl, `generate_*` is deprecated (removed in 2.0).
|
|
52
52
|
|
|
53
|
-
|
|
53
|
+
Output is byte-identical — a naming change, not a behaviour change. Existing `from faf_sdk import generate_agents_md` keeps working, now with a `DeprecationWarning`.
|
|
54
|
+
|
|
55
|
+
`faf_sdk.interop` — `author_agents_md(faf)` and `author_gemini_md(faf)`, Python ports of faf-cli's `src/interop/agents.ts` + `gemini.ts`, in parity with the canonical TypeScript. Deterministic BETTER-shaped projection: setup (install→build→dev ordered) · tests · layout · conventions · three-tier guardrails · definition of done · security · commit · stack. Human Context (who/why marketing) is intentionally omitted from AGENTS.md — it belongs in the README / .faf DNA, not agent ops.
|
|
54
56
|
|
|
55
57
|
```python
|
|
56
|
-
from faf_sdk import parse_file,
|
|
58
|
+
from faf_sdk import parse_file, author_agents_md
|
|
57
59
|
|
|
58
60
|
faf = parse_file("project.faf")
|
|
59
|
-
print(
|
|
61
|
+
print(author_agents_md(faf.data.raw)) # takes the raw dict — carries top-level commands / key_files / security
|
|
60
62
|
```
|
|
61
63
|
|
|
62
|
-
Any Python FAF tool that authors an AI-context file wraps this now — never hand-roll
|
|
64
|
+
Any Python FAF tool that authors an AI-context file wraps this now — never hand-roll one. `gemini-faf-mcp` 2.7.0's `faf_agents` / `faf_gemini` are the reference wrappers.
|
|
63
65
|
|
|
64
66
|
## What's New in v1.2.0 — The Dart Edition
|
|
65
67
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
faf_sdk/__init__.py,sha256=
|
|
1
|
+
faf_sdk/__init__.py,sha256=D7XMrdOQ2LwwBVErSosZrnMCbGLppBrTT1f9BcR8dsY,2020
|
|
2
2
|
faf_sdk/dart_detection.json,sha256=jFtKnyyMVVFsunizteFZ2pLhYC1qC2nCIWQB9SdOqKE,1195
|
|
3
3
|
faf_sdk/detect.py,sha256=GothQNKChKSEwke74MRy63VyBYLqOzN1j3yzjsSVpJA,6310
|
|
4
4
|
faf_sdk/discovery.py,sha256=3Jj3lSzPAj9l0_VjJneLAwo1dMXvhneFhcVN4m2ejOw,8643
|
|
5
|
-
faf_sdk/interop.py,sha256=
|
|
5
|
+
faf_sdk/interop.py,sha256=GWGjBEMAYhoDs7lUpZ6sqtE-I5qCcSwQ2QYLJcjXgvA,14776
|
|
6
6
|
faf_sdk/mk4.py,sha256=dA8o3YB0W19Mt_bqcR67HAw4S08zxj6IzEmubTy-pQY,5708
|
|
7
7
|
faf_sdk/parser.py,sha256=lJJysj52X0Q_aGhl4PMXY2PuMqASFHdVRiSZFDdampk,4925
|
|
8
8
|
faf_sdk/types.py,sha256=sm1ezSzCc-93bszr4ite31_xZRKjwqf2utlqN6_0QuM,6615
|
|
9
9
|
faf_sdk/validator.py,sha256=6uneOwar4GYUF52BnAQTu159kE4mh4RWRgG6onVbiG4,5730
|
|
10
10
|
faf_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
-
faf_python_sdk-1.
|
|
12
|
-
faf_python_sdk-1.
|
|
13
|
-
faf_python_sdk-1.
|
|
14
|
-
faf_python_sdk-1.
|
|
11
|
+
faf_python_sdk-1.4.0.dist-info/METADATA,sha256=n7nME8V10mhLGXYYvt7lVeEp21V_CMpOAzAbcBT3X6M,9021
|
|
12
|
+
faf_python_sdk-1.4.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
13
|
+
faf_python_sdk-1.4.0.dist-info/licenses/LICENSE,sha256=ARScF5tFhbQnYO2V5QAuCwhDHcxKdOWTOV81Pxx_j7U,1065
|
|
14
|
+
faf_python_sdk-1.4.0.dist-info/RECORD,,
|
faf_sdk/__init__.py
CHANGED
|
@@ -25,7 +25,15 @@ from .validator import validate, ValidationResult
|
|
|
25
25
|
from .mk4 import score_faf, Mk4Result, SlotState, LicenseTier
|
|
26
26
|
from .discovery import find_faf_file, find_project_root, load_fafignore
|
|
27
27
|
from .detect import detect_dart_project, DartProject
|
|
28
|
-
from .interop import
|
|
28
|
+
from .interop import (
|
|
29
|
+
author_agents_md,
|
|
30
|
+
author_gemini_md,
|
|
31
|
+
render_agents_md,
|
|
32
|
+
render_gemini_md,
|
|
33
|
+
generate_agents_md, # deprecated alias — removed in 2.0
|
|
34
|
+
generate_gemini_md, # deprecated alias — removed in 2.0
|
|
35
|
+
faf_meta_tag,
|
|
36
|
+
)
|
|
29
37
|
from .types import (
|
|
30
38
|
FafData,
|
|
31
39
|
ProjectInfo,
|
|
@@ -36,7 +44,7 @@ from .types import (
|
|
|
36
44
|
AIScoring
|
|
37
45
|
)
|
|
38
46
|
|
|
39
|
-
__version__ = "1.
|
|
47
|
+
__version__ = "1.4.0"
|
|
40
48
|
__all__ = [
|
|
41
49
|
# Parser
|
|
42
50
|
"parse",
|
|
@@ -58,9 +66,9 @@ __all__ = [
|
|
|
58
66
|
# Detection (Dart/Flutter — A+B hybrid, parity with faf-cli)
|
|
59
67
|
"detect_dart_project",
|
|
60
68
|
"DartProject",
|
|
61
|
-
# Interop — AGENTS.md / GEMINI.md
|
|
62
|
-
"
|
|
63
|
-
"
|
|
69
|
+
# Interop — AGENTS.md / GEMINI.md authoring (parity with faf-cli src/interop)
|
|
70
|
+
"author_agents_md",
|
|
71
|
+
"author_gemini_md",
|
|
64
72
|
"faf_meta_tag",
|
|
65
73
|
# Types
|
|
66
74
|
"FafData",
|
faf_sdk/interop.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""
|
|
2
|
-
AI-context file
|
|
2
|
+
AI-context file authoring — AGENTS.md and GEMINI.md from .faf data.
|
|
3
3
|
|
|
4
4
|
Python port of faf-cli's `src/interop/agents.ts` + `gemini.ts`, kept in
|
|
5
5
|
parity with the canonical TypeScript. Deterministic projection from curated
|
|
@@ -10,13 +10,23 @@ not agent ops.
|
|
|
10
10
|
Both take the raw parsed .faf dict (`FafFile.data.raw`) — the .faf format
|
|
11
11
|
carries top-level `commands` / `key_files` / `security` that the typed model
|
|
12
12
|
doesn't surface.
|
|
13
|
+
|
|
14
|
+
Naming: the impl functions are ``render_agents_md`` / ``render_gemini_md``
|
|
15
|
+
(pure ``dict -> str`` projection, pairs with the writers). The public API
|
|
16
|
+
name is ``author_agents_md`` / ``author_gemini_md`` — the surface consumers
|
|
17
|
+
import, in the "faf authors" voice used on every documented surface.
|
|
18
|
+
``generate_*`` is a deprecated alias, removed in 2.0.
|
|
13
19
|
"""
|
|
14
20
|
|
|
15
21
|
from __future__ import annotations
|
|
16
22
|
|
|
23
|
+
import warnings
|
|
17
24
|
from typing import Any
|
|
18
25
|
|
|
19
|
-
__all__ = [
|
|
26
|
+
__all__ = [
|
|
27
|
+
"author_agents_md", "author_gemini_md",
|
|
28
|
+
"faf_meta_tag", "title_label", "slot_label",
|
|
29
|
+
]
|
|
20
30
|
|
|
21
31
|
# --- shared helpers ----------------------------------------------------------
|
|
22
32
|
|
|
@@ -90,7 +100,7 @@ def slot_label(path: str) -> str:
|
|
|
90
100
|
|
|
91
101
|
|
|
92
102
|
def faf_meta_tag(faf: dict) -> str:
|
|
93
|
-
"""The two-line `<!-- faf: ... -->` metastamp every faf-
|
|
103
|
+
"""The two-line `<!-- faf: ... -->` metastamp every faf-authored file opens with."""
|
|
94
104
|
proj = faf.get("project") or {}
|
|
95
105
|
name = str(proj.get("name") or "").strip()
|
|
96
106
|
lang = str(proj.get("main_language") or "").strip()
|
|
@@ -102,7 +112,7 @@ def faf_meta_tag(faf: dict) -> str:
|
|
|
102
112
|
return f"{line1}\n{line2}"
|
|
103
113
|
|
|
104
114
|
|
|
105
|
-
# --- command classification (shared by both
|
|
115
|
+
# --- command classification (shared by both) --------------------------------
|
|
106
116
|
|
|
107
117
|
def _classify_commands(faf: dict) -> dict:
|
|
108
118
|
commands = faf.get("commands") or {}
|
|
@@ -146,8 +156,11 @@ def _key_files(faf: dict) -> list:
|
|
|
146
156
|
|
|
147
157
|
# --- AGENTS.md -------------------------------------------------------------
|
|
148
158
|
|
|
149
|
-
def
|
|
150
|
-
"""Author a BETTER-shaped AGENTS.md from raw .faf data. Deterministic.
|
|
159
|
+
def render_agents_md(faf: dict) -> str:
|
|
160
|
+
"""Author a BETTER-shaped AGENTS.md from raw .faf data. Deterministic.
|
|
161
|
+
|
|
162
|
+
Public alias: :func:`author_agents_md`.
|
|
163
|
+
"""
|
|
151
164
|
lines: list[str] = []
|
|
152
165
|
|
|
153
166
|
def push(s: str = "") -> None:
|
|
@@ -187,9 +200,9 @@ def generate_agents_md(faf: dict) -> str:
|
|
|
187
200
|
push(orientation)
|
|
188
201
|
push()
|
|
189
202
|
push(
|
|
190
|
-
"> Authored by faf —
|
|
191
|
-
"`faf_agents` MCP tool.
|
|
192
|
-
"
|
|
203
|
+
"> Authored by faf — do not edit the managed block; refresh with "
|
|
204
|
+
"`faf export --agents` or the `faf_agents` MCP tool. Hand-written "
|
|
205
|
+
"content outside it is preserved."
|
|
193
206
|
)
|
|
194
207
|
push()
|
|
195
208
|
|
|
@@ -344,8 +357,11 @@ def generate_agents_md(faf: dict) -> str:
|
|
|
344
357
|
|
|
345
358
|
# --- GEMINI.md ------------------------------------------------------------
|
|
346
359
|
|
|
347
|
-
def
|
|
348
|
-
"""GEMINI.md — Gemini CLI's own convention (hierarchical, @file-importable).
|
|
360
|
+
def render_gemini_md(faf: dict) -> str:
|
|
361
|
+
"""GEMINI.md — Gemini CLI's own convention (hierarchical, @file-importable).
|
|
362
|
+
|
|
363
|
+
Public alias: :func:`author_gemini_md`.
|
|
364
|
+
"""
|
|
349
365
|
lines: list[str] = []
|
|
350
366
|
proj = faf.get("project") or {}
|
|
351
367
|
cmds = _classify_commands(faf)
|
|
@@ -401,3 +417,31 @@ def generate_gemini_md(faf: dict) -> str:
|
|
|
401
417
|
"",
|
|
402
418
|
]
|
|
403
419
|
return "\n".join(lines)
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
# --- public + deprecated names --------------------------------------------
|
|
423
|
+
|
|
424
|
+
#: Public API name for :func:`render_agents_md` — "faf authors" voice.
|
|
425
|
+
author_agents_md = render_agents_md
|
|
426
|
+
#: Public API name for :func:`render_gemini_md`.
|
|
427
|
+
author_gemini_md = render_gemini_md
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
def generate_agents_md(faf: dict) -> str:
|
|
431
|
+
"""Deprecated alias for :func:`author_agents_md`. Removed in 2.0."""
|
|
432
|
+
warnings.warn(
|
|
433
|
+
"generate_agents_md is deprecated; use author_agents_md",
|
|
434
|
+
DeprecationWarning,
|
|
435
|
+
stacklevel=2,
|
|
436
|
+
)
|
|
437
|
+
return render_agents_md(faf)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def generate_gemini_md(faf: dict) -> str:
|
|
441
|
+
"""Deprecated alias for :func:`author_gemini_md`. Removed in 2.0."""
|
|
442
|
+
warnings.warn(
|
|
443
|
+
"generate_gemini_md is deprecated; use author_gemini_md",
|
|
444
|
+
DeprecationWarning,
|
|
445
|
+
stacklevel=2,
|
|
446
|
+
)
|
|
447
|
+
return render_gemini_md(faf)
|
|
File without changes
|
|
File without changes
|