Skip to content

Commit d7082f8

Browse files
release: v0.9.0 — manifest/staleness + multi-doc + top-level _docs bucket
Extracts manifest + staleness from attune-author into attune-help so attune-author and attune-ai share one implementation. Adds multi-doc support via doc_paths and a top-level _docs bucket for narrative docs that don't belong to any single feature. New schema: - Feature.doc_paths: list[str] — multiple docs per feature - FeatureManifest.docs: list[str] — top-level narrative bucket - Feature.__post_init__ coalesces doc_path <-> doc_paths for backward compat Loader accepts both legacy doc_path (scalar) and new doc_paths (list); writer always emits doc_paths. check_staleness iterates the full list so multi-doc features produce one DocStaleness entry per path. Tests: 225 passing (62 new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9c53520 commit d7082f8

8 files changed

Lines changed: 2018 additions & 3 deletions

File tree

CHANGELOG.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,71 @@
22

33
All notable changes to `attune-help` are documented here.
44

5+
## 0.9.0 — 2026-04-24
6+
7+
Supersedes the unreleased 0.8.0 draft. Combines the manifest +
8+
staleness extraction from that draft with multi-doc support and
9+
a top-level narrative-docs bucket.
10+
11+
### Added
12+
13+
- **`manifest.py`** — Feature manifest parser with project-doc field
14+
support. Extends the `Feature` dataclass with `doc_kinds`,
15+
`doc_paths` (list), `arch_path`, and `doc_nav_section` fields so
16+
`features.yaml` can register generated `docs/` output paths
17+
alongside existing `.help/` template mappings. Exports
18+
`load_manifest`, `save_manifest`, `match_files_to_features`,
19+
`resolve_topic`, `is_safe_feature_name`, and `slugify`.
20+
21+
- **`Feature.doc_paths: list[str]`** — A feature may now register
22+
multiple docs. Single-file features (e.g. `cli`
23+
`cli-reference.md`) set one entry; multi-file features (e.g.
24+
`memory` with four how-to guides) set the full list.
25+
`Feature.__post_init__` coalesces between `doc_path` (scalar,
26+
deprecated) and `doc_paths` (list) so callers can read either
27+
attribute without a None mismatch. Loader accepts both forms;
28+
writer always emits `doc_paths`.
29+
30+
- **Top-level `_docs:` bucket** — Hand-written narrative docs that
31+
don't belong to any single feature (FAQ, glossary, installation,
32+
etc.) can be registered in the manifest via a `_docs:` list at
33+
the top level. Exposed as `FeatureManifest.docs: list[str]`.
34+
Tracked for discovery and mkdocs nav; never regenerated from
35+
source.
36+
37+
- **`staleness.py`** — Dual-format staleness detection covering both
38+
`.help/` templates and project `docs/` files in one
39+
`check_staleness()` call. Iterates `doc_paths` so a feature with
40+
multiple registered docs produces one `DocStaleness` entry per
41+
path.
42+
43+
- Help templates: reads `source_hash` from YAML frontmatter in
44+
`concept.md` (unchanged behaviour).
45+
- Project docs: reads `source_hash` from an HTML comment footer
46+
appended by `attune-author`'s doc generator:
47+
`<!-- attune-generated: source_hash=... feature=... kind=... generated_at=... -->`.
48+
Reports a doc as stale when the hash mismatches or the file is
49+
absent entirely.
50+
51+
New data classes: `DocStaleness`, updated `StalenessReport` with
52+
`help_entries` / `doc_entries` split and `stale_docs` property.
53+
New helpers: `parse_doc_footer`, `build_doc_footer`,
54+
`compute_source_hash`.
55+
56+
- **Public API exports** — all new symbols are exported from
57+
`attune_help.__init__` so `attune-author` can import them without
58+
reaching into submodules.
59+
60+
### Migration
61+
62+
- Legacy manifests using `doc_path: <scalar>` continue to load —
63+
the loader coalesces the scalar into a single-entry `doc_paths`
64+
list. No YAML changes required for consumers still on the
65+
scalar form.
66+
- Consumers reading attributes should prefer `feature.doc_paths`
67+
going forward. `feature.doc_path` remains populated as
68+
`doc_paths[0]` for backward compatibility.
69+
570
## 0.7.0 — Unreleased
671

772
### Added

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "attune-help"
7-
version = "0.7.0"
7+
version = "0.9.0"
88
description = "Lightweight help runtime with progressive depth and audience adaptation."
99
readme = {file = "README.md", content-type = "text/markdown"}
1010
requires-python = ">=3.10"

src/attune_help/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,31 @@
1414
PopulatedTemplate,
1515
TemplateContext,
1616
)
17+
from attune_help.manifest import (
18+
Feature,
19+
FeatureManifest,
20+
Manifest,
21+
is_safe_feature_name,
22+
load_manifest,
23+
match_files_to_features,
24+
resolve_topic,
25+
save_manifest,
26+
slugify,
27+
)
1728
from attune_help.preamble import get_preamble # noqa: F401
29+
from attune_help.staleness import (
30+
DocStaleness,
31+
FeatureStaleness,
32+
StalenessReport,
33+
build_doc_footer,
34+
check_staleness,
35+
compute_source_hash,
36+
parse_doc_footer,
37+
)
1838
from attune_help.storage import LocalFileStorage, SessionStorage
1939

2040
__all__ = [
41+
# Engine
2142
"AudienceProfile",
2243
"HelpEngine",
2344
"LocalFileStorage",
@@ -26,6 +47,24 @@
2647
"TemplateContext",
2748
"get_demo_path",
2849
"get_preamble",
50+
# Manifest
51+
"Feature",
52+
"FeatureManifest",
53+
"Manifest",
54+
"is_safe_feature_name",
55+
"load_manifest",
56+
"match_files_to_features",
57+
"resolve_topic",
58+
"save_manifest",
59+
"slugify",
60+
# Staleness
61+
"DocStaleness",
62+
"FeatureStaleness",
63+
"StalenessReport",
64+
"build_doc_footer",
65+
"check_staleness",
66+
"compute_source_hash",
67+
"parse_doc_footer",
2968
]
3069

3170
try:

0 commit comments

Comments
 (0)