steward-cli 0.3.0__tar.gz → 0.3.2__tar.gz
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.
- {steward_cli-0.3.0 → steward_cli-0.3.2}/CHANGELOG.md +17 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/PKG-INFO +25 -1
- steward_cli-0.3.2/README.md +64 -0
- steward_cli-0.3.2/docs/perfect-patient.md +48 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/pyproject.toml +1 -1
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/cli/_commands/_corpus.py +78 -3
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/cli/_commands/doctor.py +1 -1
- {steward_cli-0.3.0 → steward_cli-0.3.2}/tests/test_corpus.py +37 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/uv.lock +1 -1
- steward_cli-0.3.0/README.md +0 -40
- steward_cli-0.3.0/docs/perfect-patient.md +0 -35
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/agent-config/SKILL.md +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/agent-config/scripts/show.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/doc-test-alignment/SKILL.md +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/doc-test-alignment/scripts/check.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/SKILL.md +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/scripts/portability-lint.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/scripts/pr-batch.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/scripts/pr-comments.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/scripts/pr-reply.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/scripts/pr-status.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/scripts/workflow.sh +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/version-bump/SKILL.md +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/version-bump/scripts/bump.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills.local.yaml.example +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.flake8 +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.github/workflows/publish.yml +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.github/workflows/tests.yml +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.gitignore +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/.markdownlint-cli2.yaml +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/CLAUDE.md +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/LICENSE +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/docs/sibling-pattern.md +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/docs/skill-sources.md +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/__init__.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/__main__.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/cli/__init__.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/cli/_commands/__init__.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/cli/_commands/show.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/cli/_errors.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/steward/cli/_output.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/tests/__init__.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/tests/test_cli.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/tests/test_cli_doctor.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/tests/test_cli_doctor_siblings.py +0 -0
- {steward_cli-0.3.0 → steward_cli-0.3.2}/tests/test_skills_convention.py +0 -0
|
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
Format follows [Keep a Changelog](https://keepachangelog.com/). This project
|
|
6
6
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.2] - 2026-04-26
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- `README.md` — document `steward doctor`. The previous Usage section listed only `steward show`, leaving the second verb (added in 0.2.0 as `verify`, renamed in 0.3.0, refined in 0.3.1) invisible to anyone who only reads the README. Adds both scopes (`--scope self` default, `--scope siblings`), the `--json` / `--check` flags, the `--apply` roadmap caveat, and cross-links to `docs/sibling-pattern.md` (the contract `doctor` honors) and `docs/perfect-patient.md` (the auto-generated corpus baseline).
|
|
13
|
+
|
|
14
|
+
## [0.3.1] - 2026-04-26
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- `docs/perfect-patient.md` — first real corpus snapshot, generated by running `steward doctor --scope siblings` against the `agentculture` workspace (8 agents across 6 sibling repos: agex, culture, culture-sonar-cli, daria, reachy_nova, shushu). Replaces the placeholder shipped in 0.3.0. Required `culture.yaml` fields settle at `backend` + `suffix`; `acp_command` and `model` fall in the recommended band; common skills baseline is empty so far while `pr-review` and `run-tests` show up as recommended.
|
|
19
|
+
- Skill bullets in the synthesized `perfect-patient.md` now carry a high-level one-liner per skill, sourced from each `SKILL.md`'s frontmatter `description:` (first-wins across the corpus, trimmed to the first sentence or 200 chars). Adds `Baseline.skill_descriptions: dict[str, str]` and a new `_skill_bullets` renderer; bare-bullet fallback when no description can be parsed. Reader can now scan the baseline and see what each skill ideally does without opening the upstream repo.
|
|
20
|
+
|
|
21
|
+
### Fixed
|
|
22
|
+
|
|
23
|
+
- `render_perfect_patient` no longer emits markdown that fails `markdownlint`. The empty-set placeholder switched from `_(none)_` (tripped MD036 emphasis-as-heading) to plain `None yet.`, and `_refresh_perfect_patient` no longer appends an extra trailing newline on top of the one the renderer already produces (which previously left a blank EOF line and tripped MD012).
|
|
24
|
+
|
|
8
25
|
## [0.3.0] - 2026-04-26
|
|
9
26
|
|
|
10
27
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: steward-cli
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.2
|
|
4
4
|
Summary: Steward — aligns and maintains resident agents across Culture projects.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentculture/steward
|
|
6
6
|
Project-URL: Issues, https://github.com/agentculture/steward/issues
|
|
@@ -50,6 +50,30 @@ steward show ../daria
|
|
|
50
50
|
`.claude/skills/agent-config/scripts/show.sh`. The skill remains the canonical
|
|
51
51
|
implementation; the CLI is the typed entry point.
|
|
52
52
|
|
|
53
|
+
```bash
|
|
54
|
+
# Diagnose a single sibling repo against the AgentCulture sibling pattern
|
|
55
|
+
# (portability + skills-convention checks). Exits non-zero on findings.
|
|
56
|
+
steward doctor ../culture
|
|
57
|
+
steward doctor ../culture --json --check portability
|
|
58
|
+
|
|
59
|
+
# Walk every culture.yaml in the workspace, score each declared agent
|
|
60
|
+
# against the corpus baseline, and write per-repo feedback into
|
|
61
|
+
# <target>/docs/steward/steward-suggestions.md. Diagnostic-only.
|
|
62
|
+
steward doctor --scope siblings
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
`steward doctor` is read-only diagnosis. `--scope self` (default) runs the
|
|
66
|
+
single-repo invariant checks against `TARGET`. `--scope siblings` walks every
|
|
67
|
+
`culture.yaml` in the workspace, refreshes
|
|
68
|
+
[`docs/perfect-patient.md`](docs/perfect-patient.md) from the corpus, and
|
|
69
|
+
writes per-target feedback into each sibling's
|
|
70
|
+
`docs/steward/steward-suggestions.md`. The repair mode (`--apply`) is on the
|
|
71
|
+
roadmap but not implemented yet.
|
|
72
|
+
|
|
73
|
+
See [`docs/sibling-pattern.md`](docs/sibling-pattern.md) for the contract
|
|
74
|
+
`doctor` honors and [`docs/perfect-patient.md`](docs/perfect-patient.md) for
|
|
75
|
+
the auto-generated corpus baseline.
|
|
76
|
+
|
|
53
77
|
See [`CLAUDE.md`](CLAUDE.md) for project-shape, build/test/publish details, and
|
|
54
78
|
the skills convention.
|
|
55
79
|
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# steward
|
|
2
|
+
|
|
3
|
+
Steward aligns and maintains resident agents across Culture projects.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install steward-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or, with [uv](https://github.com/astral-sh/uv):
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
uv tool install steward-cli
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
steward --version
|
|
21
|
+
steward --help
|
|
22
|
+
|
|
23
|
+
# Show a Culture agent's full configuration in one view
|
|
24
|
+
# (CLAUDE.md + the parallel culture.yaml + .claude/skills/ index).
|
|
25
|
+
# Run from inside a Steward checkout — the command finds the agent-config
|
|
26
|
+
# skill script via a walk-up from the current working directory.
|
|
27
|
+
steward show ../culture
|
|
28
|
+
steward show ../daria
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
`steward show` is a thin wrapper over the `agent-config` skill at
|
|
32
|
+
`.claude/skills/agent-config/scripts/show.sh`. The skill remains the canonical
|
|
33
|
+
implementation; the CLI is the typed entry point.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Diagnose a single sibling repo against the AgentCulture sibling pattern
|
|
37
|
+
# (portability + skills-convention checks). Exits non-zero on findings.
|
|
38
|
+
steward doctor ../culture
|
|
39
|
+
steward doctor ../culture --json --check portability
|
|
40
|
+
|
|
41
|
+
# Walk every culture.yaml in the workspace, score each declared agent
|
|
42
|
+
# against the corpus baseline, and write per-repo feedback into
|
|
43
|
+
# <target>/docs/steward/steward-suggestions.md. Diagnostic-only.
|
|
44
|
+
steward doctor --scope siblings
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`steward doctor` is read-only diagnosis. `--scope self` (default) runs the
|
|
48
|
+
single-repo invariant checks against `TARGET`. `--scope siblings` walks every
|
|
49
|
+
`culture.yaml` in the workspace, refreshes
|
|
50
|
+
[`docs/perfect-patient.md`](docs/perfect-patient.md) from the corpus, and
|
|
51
|
+
writes per-target feedback into each sibling's
|
|
52
|
+
`docs/steward/steward-suggestions.md`. The repair mode (`--apply`) is on the
|
|
53
|
+
roadmap but not implemented yet.
|
|
54
|
+
|
|
55
|
+
See [`docs/sibling-pattern.md`](docs/sibling-pattern.md) for the contract
|
|
56
|
+
`doctor` honors and [`docs/perfect-patient.md`](docs/perfect-patient.md) for
|
|
57
|
+
the auto-generated corpus baseline.
|
|
58
|
+
|
|
59
|
+
See [`CLAUDE.md`](CLAUDE.md) for project-shape, build/test/publish details, and
|
|
60
|
+
the skills convention.
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Perfect patient
|
|
2
|
+
|
|
3
|
+
> Auto-generated by `steward doctor` on 2026-04-26.
|
|
4
|
+
> Synthesized from 8 agents across 6 repos.
|
|
5
|
+
>
|
|
6
|
+
> The baseline is descriptive, not prescriptive: it describes what
|
|
7
|
+
> a typical healthy agent looks like in the current corpus, so
|
|
8
|
+
> drift can be spotted. Edit by hand only if you intend to ratchet
|
|
9
|
+
> the bar — `steward doctor --scope siblings` overwrites this file.
|
|
10
|
+
|
|
11
|
+
## Required `culture.yaml` fields
|
|
12
|
+
|
|
13
|
+
Present in ≥80% of agents.
|
|
14
|
+
|
|
15
|
+
- `backend`
|
|
16
|
+
- `suffix`
|
|
17
|
+
|
|
18
|
+
## Recommended `culture.yaml` fields
|
|
19
|
+
|
|
20
|
+
Present in 30–80% of agents.
|
|
21
|
+
|
|
22
|
+
- `acp_command`
|
|
23
|
+
- `model`
|
|
24
|
+
|
|
25
|
+
## Common skills baseline
|
|
26
|
+
|
|
27
|
+
Skills present in ≥80% of agent repos.
|
|
28
|
+
|
|
29
|
+
None yet.
|
|
30
|
+
|
|
31
|
+
## Recommended skills
|
|
32
|
+
|
|
33
|
+
Skills present in 30–80% of agent repos.
|
|
34
|
+
|
|
35
|
+
- `pr-review` — Full PR workflow for culture: branch, commit, push, create PR, wait for automated reviewers, fetch comments, fix or pushback, reply, resolve threads.
|
|
36
|
+
- `run-tests` — Run pytest with parallel execution and coverage.
|
|
37
|
+
|
|
38
|
+
## Common `CLAUDE.md` sections
|
|
39
|
+
|
|
40
|
+
Top-level `## …` headings present in ≥80% of agent repos.
|
|
41
|
+
|
|
42
|
+
None yet.
|
|
43
|
+
|
|
44
|
+
## Corpus stats
|
|
45
|
+
|
|
46
|
+
- Agents counted: 8
|
|
47
|
+
- Repos counted: 6
|
|
48
|
+
- Generated on: 2026-04-26
|
|
@@ -42,7 +42,7 @@ RECOMMENDED_THRESHOLD = 0.30
|
|
|
42
42
|
|
|
43
43
|
# Placeholder used in baseline sections when no items are present. Kept
|
|
44
44
|
# as a constant so the surface is single-sourced and matches in tests.
|
|
45
|
-
NONE_PLACEHOLDER = "
|
|
45
|
+
NONE_PLACEHOLDER = "None yet."
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
@dataclass
|
|
@@ -119,6 +119,7 @@ class Baseline:
|
|
|
119
119
|
recommended_skills: set[str] = field(default_factory=set)
|
|
120
120
|
required_claude_md_sections: set[str] = field(default_factory=set)
|
|
121
121
|
recommended_claude_md_sections: set[str] = field(default_factory=set)
|
|
122
|
+
skill_descriptions: dict[str, str] = field(default_factory=dict)
|
|
122
123
|
agent_count: int = 0
|
|
123
124
|
repo_count: int = 0
|
|
124
125
|
|
|
@@ -244,6 +245,68 @@ def _agent_skills(agent: Agent) -> set[str]:
|
|
|
244
245
|
return {p.name for p in skills_dir.iterdir() if p.is_dir()}
|
|
245
246
|
|
|
246
247
|
|
|
248
|
+
def _read_skill_description(skill_md: Path) -> str:
|
|
249
|
+
"""Pull a one-line summary out of a SKILL.md frontmatter `description:`.
|
|
250
|
+
|
|
251
|
+
Frontmatter is the leading ``---``-delimited YAML block. Many skills
|
|
252
|
+
use a folded scalar (``description: >\\n ...``) so we hand the block
|
|
253
|
+
to ``yaml.safe_load`` rather than line-grepping. The returned string
|
|
254
|
+
is whitespace-collapsed and trimmed to the first sentence (or 200
|
|
255
|
+
chars, whichever is shorter) so the rendered baseline stays compact.
|
|
256
|
+
Returns ``""`` when the file is missing, has no frontmatter, or
|
|
257
|
+
can't be parsed — the caller renders a bare bullet in that case.
|
|
258
|
+
"""
|
|
259
|
+
try:
|
|
260
|
+
text = skill_md.read_text()
|
|
261
|
+
except OSError:
|
|
262
|
+
return ""
|
|
263
|
+
lines = text.splitlines()
|
|
264
|
+
if not lines or lines[0].strip() != "---":
|
|
265
|
+
return ""
|
|
266
|
+
end = next((i for i in range(1, len(lines)) if lines[i].strip() == "---"), -1)
|
|
267
|
+
if end == -1:
|
|
268
|
+
return ""
|
|
269
|
+
try:
|
|
270
|
+
meta = yaml.safe_load("\n".join(lines[1:end])) or {}
|
|
271
|
+
except yaml.YAMLError:
|
|
272
|
+
return ""
|
|
273
|
+
desc = meta.get("description") if isinstance(meta, dict) else None
|
|
274
|
+
if not isinstance(desc, str):
|
|
275
|
+
return ""
|
|
276
|
+
desc = " ".join(desc.split())
|
|
277
|
+
if not desc:
|
|
278
|
+
return ""
|
|
279
|
+
cut = desc.find(". ")
|
|
280
|
+
if 0 < cut < 200:
|
|
281
|
+
desc = desc[: cut + 1]
|
|
282
|
+
elif len(desc) > 200:
|
|
283
|
+
desc = desc[:197].rstrip() + "…"
|
|
284
|
+
return desc
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _corpus_skill_descriptions(agents: list[Agent]) -> dict[str, str]:
|
|
288
|
+
"""Best one-liner per skill name, sourced from SKILL.md frontmatter.
|
|
289
|
+
|
|
290
|
+
Walks each repo (deterministic by name), takes the first non-empty
|
|
291
|
+
description we encounter for each skill. "First-wins" rather than
|
|
292
|
+
"longest-wins" so the output is stable across re-runs even when a
|
|
293
|
+
downstream copy of a skill has tweaked its description.
|
|
294
|
+
"""
|
|
295
|
+
out: dict[str, str] = {}
|
|
296
|
+
repos = sorted({a.repo_path for a in agents}, key=lambda p: p.name)
|
|
297
|
+
for repo in repos:
|
|
298
|
+
skills_dir = repo / ".claude" / "skills"
|
|
299
|
+
if not skills_dir.is_dir():
|
|
300
|
+
continue
|
|
301
|
+
for skill_dir in sorted(skills_dir.iterdir(), key=lambda p: p.name):
|
|
302
|
+
if not skill_dir.is_dir() or skill_dir.name in out:
|
|
303
|
+
continue
|
|
304
|
+
desc = _read_skill_description(skill_dir / "SKILL.md")
|
|
305
|
+
if desc:
|
|
306
|
+
out[skill_dir.name] = desc
|
|
307
|
+
return out
|
|
308
|
+
|
|
309
|
+
|
|
247
310
|
def _agent_claude_md_sections(agent: Agent) -> set[str]:
|
|
248
311
|
"""Extract level-2 (`## ...`) heading titles from the agent's CLAUDE.md.
|
|
249
312
|
|
|
@@ -301,6 +364,7 @@ def synthesize_baseline(agents: list[Agent]) -> Baseline:
|
|
|
301
364
|
recommended_skills=rec_skills,
|
|
302
365
|
required_claude_md_sections=req_sec,
|
|
303
366
|
recommended_claude_md_sections=rec_sec,
|
|
367
|
+
skill_descriptions=_corpus_skill_descriptions(agents),
|
|
304
368
|
agent_count=len(agents),
|
|
305
369
|
repo_count=len(repos),
|
|
306
370
|
)
|
|
@@ -342,7 +406,7 @@ def render_perfect_patient(baseline: Baseline) -> str:
|
|
|
342
406
|
"Skills present in ≥80% of agent repos.",
|
|
343
407
|
"",
|
|
344
408
|
]
|
|
345
|
-
lines.extend(
|
|
409
|
+
lines.extend(_skill_bullets(baseline.required_skills, baseline.skill_descriptions))
|
|
346
410
|
lines += [
|
|
347
411
|
"",
|
|
348
412
|
"## Recommended skills",
|
|
@@ -350,7 +414,7 @@ def render_perfect_patient(baseline: Baseline) -> str:
|
|
|
350
414
|
"Skills present in 30–80% of agent repos.",
|
|
351
415
|
"",
|
|
352
416
|
]
|
|
353
|
-
lines.extend(
|
|
417
|
+
lines.extend(_skill_bullets(baseline.recommended_skills, baseline.skill_descriptions))
|
|
354
418
|
lines += [
|
|
355
419
|
"",
|
|
356
420
|
"## Common `CLAUDE.md` sections",
|
|
@@ -377,6 +441,17 @@ def _bullets(items: set[str]) -> list[str]:
|
|
|
377
441
|
return [f"- `{item}`" for item in sorted(items)]
|
|
378
442
|
|
|
379
443
|
|
|
444
|
+
def _skill_bullets(items: set[str], descriptions: dict[str, str]) -> list[str]:
|
|
445
|
+
"""Render skill bullets with frontmatter-sourced one-liners when available."""
|
|
446
|
+
if not items:
|
|
447
|
+
return [NONE_PLACEHOLDER]
|
|
448
|
+
out: list[str] = []
|
|
449
|
+
for name in sorted(items):
|
|
450
|
+
desc = descriptions.get(name, "")
|
|
451
|
+
out.append(f"- `{name}` — {desc}" if desc else f"- `{name}`")
|
|
452
|
+
return out
|
|
453
|
+
|
|
454
|
+
|
|
380
455
|
def synthesize_perfect_patient(agents: list[Agent]) -> str:
|
|
381
456
|
"""Convenience: discover → render in one call (used by doctor)."""
|
|
382
457
|
return render_perfect_patient(synthesize_baseline(agents))
|
|
@@ -330,7 +330,7 @@ def _resolve_perfect_patient_path(args: argparse.Namespace, steward_root: Path)
|
|
|
330
330
|
|
|
331
331
|
def _refresh_perfect_patient(baseline: _corpus.Baseline, pp_path: Path) -> None:
|
|
332
332
|
pp_path.parent.mkdir(parents=True, exist_ok=True)
|
|
333
|
-
pp_path.write_text(_corpus.render_perfect_patient(baseline)
|
|
333
|
+
pp_path.write_text(_corpus.render_perfect_patient(baseline))
|
|
334
334
|
|
|
335
335
|
|
|
336
336
|
def _run_repo_checks(repo_path: Path, selected_repo_checks: list[str]) -> list[Finding]:
|
|
@@ -203,6 +203,43 @@ def test_render_perfect_patient_has_expected_sections(tmp_path: Path) -> None:
|
|
|
203
203
|
assert "Corpus stats" in body
|
|
204
204
|
|
|
205
205
|
|
|
206
|
+
def test_skill_bullets_carry_frontmatter_descriptions(tmp_path: Path) -> None:
|
|
207
|
+
"""Skills in the rendered baseline get a one-liner pulled from
|
|
208
|
+
their SKILL.md frontmatter `description:`. First-encountered repo
|
|
209
|
+
wins so the output is stable across runs."""
|
|
210
|
+
repo = tmp_path / "alpha"
|
|
211
|
+
repo.mkdir()
|
|
212
|
+
(repo / "culture.yaml").write_text(
|
|
213
|
+
yaml.safe_dump({"agents": [{"suffix": "a", "backend": "claude"}]})
|
|
214
|
+
)
|
|
215
|
+
(repo / ".claude" / "skills" / "run-tests" / "scripts").mkdir(parents=True)
|
|
216
|
+
(repo / ".claude" / "skills" / "run-tests" / "SKILL.md").write_text(
|
|
217
|
+
"---\nname: run-tests\n"
|
|
218
|
+
"description: Run pytest with parallel execution and coverage. "
|
|
219
|
+
"Use when running tests.\n---\n"
|
|
220
|
+
)
|
|
221
|
+
(repo / ".claude" / "skills" / "no-meta" / "scripts").mkdir(parents=True)
|
|
222
|
+
(repo / ".claude" / "skills" / "no-meta" / "SKILL.md").write_text("# no frontmatter\n")
|
|
223
|
+
|
|
224
|
+
agents, _errors = _corpus.discover_agents(tmp_path)
|
|
225
|
+
baseline = _corpus.synthesize_baseline(agents)
|
|
226
|
+
# 1-of-1 repo carries each skill, so both are required.
|
|
227
|
+
assert {"run-tests", "no-meta"} <= baseline.required_skills
|
|
228
|
+
# Description is collected for the skill that has frontmatter and trimmed
|
|
229
|
+
# to the first sentence (the trailing "Use when..." is dropped).
|
|
230
|
+
assert baseline.skill_descriptions["run-tests"].startswith(
|
|
231
|
+
"Run pytest with parallel execution and coverage."
|
|
232
|
+
)
|
|
233
|
+
assert "Use when" not in baseline.skill_descriptions["run-tests"]
|
|
234
|
+
# Skills without a parseable description are absent from the dict, not
|
|
235
|
+
# mapped to an empty string — render falls back to a bare bullet.
|
|
236
|
+
assert "no-meta" not in baseline.skill_descriptions
|
|
237
|
+
|
|
238
|
+
body = _corpus.render_perfect_patient(baseline)
|
|
239
|
+
assert "- `run-tests` — Run pytest with parallel execution and coverage." in body
|
|
240
|
+
assert "- `no-meta`\n" in body
|
|
241
|
+
|
|
242
|
+
|
|
206
243
|
def test_write_repo_report_writes_marked_file(tmp_path: Path) -> None:
|
|
207
244
|
repo = tmp_path / "alpha"
|
|
208
245
|
repo.mkdir()
|
steward_cli-0.3.0/README.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# steward
|
|
2
|
-
|
|
3
|
-
Steward aligns and maintains resident agents across Culture projects.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
pip install steward-cli
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Or, with [uv](https://github.com/astral-sh/uv):
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
uv tool install steward-cli
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Usage
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
steward --version
|
|
21
|
-
steward --help
|
|
22
|
-
|
|
23
|
-
# Show a Culture agent's full configuration in one view
|
|
24
|
-
# (CLAUDE.md + the parallel culture.yaml + .claude/skills/ index).
|
|
25
|
-
# Run from inside a Steward checkout — the command finds the agent-config
|
|
26
|
-
# skill script via a walk-up from the current working directory.
|
|
27
|
-
steward show ../culture
|
|
28
|
-
steward show ../daria
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
`steward show` is a thin wrapper over the `agent-config` skill at
|
|
32
|
-
`.claude/skills/agent-config/scripts/show.sh`. The skill remains the canonical
|
|
33
|
-
implementation; the CLI is the typed entry point.
|
|
34
|
-
|
|
35
|
-
See [`CLAUDE.md`](CLAUDE.md) for project-shape, build/test/publish details, and
|
|
36
|
-
the skills convention.
|
|
37
|
-
|
|
38
|
-
## License
|
|
39
|
-
|
|
40
|
-
MIT — see [`LICENSE`](LICENSE).
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
# Perfect patient
|
|
2
|
-
|
|
3
|
-
> This file is auto-generated by `steward doctor --scope siblings`. The
|
|
4
|
-
> committed copy is a placeholder; run the command locally to populate it
|
|
5
|
-
> with real corpus statistics from the `culture.yaml` files in your
|
|
6
|
-
> workspace.
|
|
7
|
-
>
|
|
8
|
-
> The baseline is descriptive, not prescriptive: it describes what a
|
|
9
|
-
> typical healthy agent looks like in the current corpus, so drift can
|
|
10
|
-
> be spotted. Edit by hand only if you intend to ratchet the bar —
|
|
11
|
-
> `steward doctor --scope siblings` overwrites this file.
|
|
12
|
-
|
|
13
|
-
## Required `culture.yaml` fields
|
|
14
|
-
|
|
15
|
-
Populated on first `steward doctor --scope siblings` run.
|
|
16
|
-
|
|
17
|
-
## Recommended `culture.yaml` fields
|
|
18
|
-
|
|
19
|
-
Populated on first `steward doctor --scope siblings` run.
|
|
20
|
-
|
|
21
|
-
## Common skills baseline
|
|
22
|
-
|
|
23
|
-
Populated on first `steward doctor --scope siblings` run.
|
|
24
|
-
|
|
25
|
-
## Recommended skills
|
|
26
|
-
|
|
27
|
-
Populated on first `steward doctor --scope siblings` run.
|
|
28
|
-
|
|
29
|
-
## Common `CLAUDE.md` sections
|
|
30
|
-
|
|
31
|
-
Populated on first `steward doctor --scope siblings` run.
|
|
32
|
-
|
|
33
|
-
## Corpus stats
|
|
34
|
-
|
|
35
|
-
Populated on first `steward doctor --scope siblings` run.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steward_cli-0.3.0 → steward_cli-0.3.2}/.claude/skills/pr-review/scripts/portability-lint.sh
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|