katvan 0.2.4__tar.gz → 0.2.6__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.
- {katvan-0.2.4 → katvan-0.2.6}/.github/workflows/reference-sync.yml +12 -2
- {katvan-0.2.4 → katvan-0.2.6}/CHANGELOG.md +34 -0
- {katvan-0.2.4 → katvan-0.2.6}/PKG-INFO +1 -1
- katvan-0.2.6/docs/superpowers/specs/2026-05-18-agex-docs-absorption-design.md +113 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_commands/doctor.py +22 -6
- {katvan-0.2.4 → katvan-0.2.6}/katvan/repos.py +1 -1
- {katvan-0.2.4 → katvan-0.2.6}/pyproject.toml +1 -1
- katvan-0.2.6/scripts/sync_agex_skills.py +133 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_data/agentculture_repos.yml +6 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_layouts/home.html +2 -1
- katvan-0.2.6/site/agex/commands/doctor.md +43 -0
- katvan-0.2.6/site/agex/commands/explain.md +28 -0
- katvan-0.2.6/site/agex/commands/gamify.md +33 -0
- katvan-0.2.6/site/agex/commands/hook.md +33 -0
- katvan-0.2.6/site/agex/commands/index.md +11 -0
- katvan-0.2.6/site/agex/commands/learn.md +23 -0
- katvan-0.2.6/site/agex/commands/overview.md +33 -0
- katvan-0.2.6/site/agex/commands/pr.md +53 -0
- katvan-0.2.6/site/agex/getting-started.md +41 -0
- katvan-0.2.6/site/agex/index.md +27 -0
- katvan-0.2.6/site/agex/skill-sources.md +42 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/antoine/index.md +1 -1
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/architecture/subsites.md +1 -1
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/categories/workspace-experience.md +2 -2
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/ecosystem.md +2 -2
- {katvan-0.2.4 → katvan-0.2.6}/site/sitemap-main.html +0 -1
- {katvan-0.2.4 → katvan-0.2.6}/site/sitemap.html +0 -1
- katvan-0.2.6/tests/conftest.py +8 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_doctor.py +47 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_repos.py +3 -1
- katvan-0.2.6/tests/unit/test_sync_agex_skills.py +145 -0
- {katvan-0.2.4 → katvan-0.2.6}/uv.lock +1 -1
- katvan-0.2.4/site/docs/agex-cli/index.md +0 -23
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/cicd/SKILL.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/cicd/scripts/_resolve-nick.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/cicd/scripts/portability-lint.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/cicd/scripts/pr-reply.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/cicd/scripts/pr-status.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/cicd/scripts/workflow.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/communicate/SKILL.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/communicate/scripts/fetch-issues.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/communicate/scripts/mesh-message.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/communicate/scripts/post-comment.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/communicate/scripts/post-issue.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/communicate/scripts/templates/skill-update-brief.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/librarian/SKILL.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/librarian/scripts/_frontmatter.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/librarian/scripts/_repos.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/librarian/scripts/doctor.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/librarian/scripts/overview.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.claude/skills/librarian/scripts/pull.sh +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.flake8 +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.github/workflows/docs-check.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.github/workflows/publish.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.github/workflows/tests.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/.gitignore +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/LICENSE +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/README.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/culture.yaml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/docs/skill-sources.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/docs/superpowers/audits/2026-05-17-existing-site-docs-audit.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/docs/superpowers/audits/2026-05-18-sitemap-robots-verification.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/docs/superpowers/plans/2026-05-14-culture-site-migration.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/docs/superpowers/plans/2026-05-17-culture-dev-marketing-rebuild.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/docs/superpowers/specs/2026-05-14-culture-site-migration-design.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/docs/superpowers/specs/2026-05-17-culture-dev-marketing-rebuild-design.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/__main__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_commands/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_commands/explain.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_commands/learn.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_commands/overview.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_commands/pull.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_errors.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/cli/_output.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/explain/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/explain/catalog.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/katvan/frontmatter.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/Gemfile +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/Gemfile.lock +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_config.base.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_config.culture.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_data/culture_subcommands.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_data/landing.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_data/sites.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_data/style.yml +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_includes/analytics.html +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_includes/head_custom.html +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_includes/repo_table.html +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_includes/subcommand_table.html +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_sass/color_schemes/anthropic.scss +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_sass/color_schemes/dark-terminal.scss +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/_sass/custom/custom.scss +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/assets/images/IMG_3183.png +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/assets/images/apple-touch-icon.png +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/assets/images/favicon-16x16.png +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/assets/images/favicon-32x32.png +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/assets/images/favicon.ico +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/assets/images/og-agentirc.png +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/assets/images/og-culture.png +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/afi-cli/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/afi-cli/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/afi-cli/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/agentirc/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/agtag/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/agtag/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/agtag/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/appsec/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/architecture/agent-harness-spec.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/architecture/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/architecture/layers.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/architecture/shared-vs-cited.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/architecture/threads.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/attention.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/auntiepypi/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/auntiepypi/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/auntiepypi/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/categories/core-runtime.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/categories/identity-secrets.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/categories/org-site.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/categories/resident-culture.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/categories/resident-domain.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/code-lens-cli/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/code-lens-cli/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/code-lens-cli/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/coverage-baseline.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/culture/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/cultureagent/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/cultureagent/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/cultureagent/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/cultureflare/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/ghafi/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/ghafi/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/ghafi/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/irc-lens/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/irc-lens/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/irc-lens/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/katvan/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/katvan/reference/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/katvan/reference/learn.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/landing-page/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/office-agent/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/quickstart.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/shushu/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/steward/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/telek/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/tipalti/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/why.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/docs/zehut/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/favicon.ico +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/index.md +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/robots.txt +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/site/sitemap-agentirc.html +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/sonar-project.properties +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/cli/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/cli/test_doctor.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/cli/test_overview.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/cli/test_pull.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/fixtures/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/fixtures/fake_afi_bin.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/test_cli.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/__init__.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_explain.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_frontmatter.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_learn.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_output.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_overview.py +0 -0
- {katvan-0.2.4 → katvan-0.2.6}/tests/unit/test_pull.py +0 -0
|
@@ -34,11 +34,21 @@ jobs:
|
|
|
34
34
|
- name: Pull reference
|
|
35
35
|
run: katvan pull --all --json | tee /tmp/pull.json
|
|
36
36
|
|
|
37
|
+
- name: Clone agex-cli for SKILL.md sync
|
|
38
|
+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
|
|
39
|
+
with:
|
|
40
|
+
repository: agentculture/agex-cli
|
|
41
|
+
ref: main
|
|
42
|
+
path: _agex-cli-src
|
|
43
|
+
|
|
44
|
+
- name: Render agex commands from SKILL.md
|
|
45
|
+
run: python3 scripts/sync_agex_skills.py _agex-cli-src
|
|
46
|
+
|
|
37
47
|
- name: Open PR if anything changed
|
|
38
48
|
env:
|
|
39
49
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
40
50
|
run: |
|
|
41
|
-
if [ -z "$(git status --porcelain site/
|
|
51
|
+
if [ -z "$(git status --porcelain site/)" ]; then
|
|
42
52
|
echo "No reference changes."
|
|
43
53
|
exit 0
|
|
44
54
|
fi
|
|
@@ -46,7 +56,7 @@ jobs:
|
|
|
46
56
|
git checkout -b "$BRANCH"
|
|
47
57
|
git config user.name "katvan-bot"
|
|
48
58
|
git config user.email "katvan-bot@users.noreply.github.com"
|
|
49
|
-
git add site/
|
|
59
|
+
git add site/
|
|
50
60
|
git commit -m "chore(reference): nightly sync $(date -u +%Y-%m-%d)"
|
|
51
61
|
git push origin "$BRANCH"
|
|
52
62
|
gh pr create \
|
|
@@ -9,6 +9,40 @@ artifacts.
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
## [0.2.6] — 2026-05-18
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- `katvan/cli/_commands/doctor.py`: extract `"index.md"` literal into a
|
|
17
|
+
module-level `_INDEX_MD` constant. Resolves SonarCloud's
|
|
18
|
+
duplicate-literal finding on the `_check_index` + `_check_reference`
|
|
19
|
+
pair landed in 0.2.5.
|
|
20
|
+
|
|
21
|
+
## [0.2.5] — 2026-05-18
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
- Site: absorbed `agex-cli`'s standalone Jekyll docs site into
|
|
26
|
+
katvan. `culture.dev/agex/` is now served from katvan's main
|
|
27
|
+
build as plain paths inside the same site — no separate
|
|
28
|
+
`_config.agex.yml`, no separate Cloudflare project, no path-
|
|
29
|
+
routing rule. Prose pages (`/agex/`, `/agex/getting-started/`,
|
|
30
|
+
`/agex/skill-sources/`) are hand-imported; per-command pages
|
|
31
|
+
under `/agex/commands/<verb>/` are rendered from
|
|
32
|
+
`agex-cli/src/agent_experience/commands/*/SKILL.md` by
|
|
33
|
+
`scripts/sync_agex_skills.py`, refreshed by the nightly
|
|
34
|
+
`reference-sync.yml` cron.
|
|
35
|
+
- `scripts/sync_agex_skills.py` + `tests/unit/test_sync_agex_skills.py`
|
|
36
|
+
(11 tests, stdlib-only renderer).
|
|
37
|
+
- `tests/conftest.py` adds `scripts/` to `sys.path` so non-package
|
|
38
|
+
script modules are importable from unit tests.
|
|
39
|
+
|
|
40
|
+
### Removed
|
|
41
|
+
|
|
42
|
+
- `site/docs/agex-cli/index.md` (the marketing-rebuild placeholder
|
|
43
|
+
overview); inbound internal links repointed to `/agex/`. No
|
|
44
|
+
redirect — this is a renovation, not a migration.
|
|
45
|
+
|
|
12
46
|
## [0.2.4] — 2026-05-18
|
|
13
47
|
|
|
14
48
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: katvan
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: Maintain sibling-repo docs under one roof on the culture.dev site.
|
|
5
5
|
Project-URL: Homepage, https://github.com/agentculture/katvan
|
|
6
6
|
Project-URL: Issues, https://github.com/agentculture/katvan/issues
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# agex docs absorption — design
|
|
2
|
+
|
|
3
|
+
> Status: design (2026-05-18). Implementation plan follows in a separate doc under `docs/superpowers/plans/`.
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
`agentculture/agex-cli` ships a small Jekyll docs site that publishes to `culture.dev/agex/` from its own `docs/` folder via a standalone Cloudflare Pages project (`agex.pages.dev`) routed under `culture.dev`. Issue [#13](https://github.com/agentculture/katvan/issues/13) asked katvan to absorb that site so culture.dev is served end-to-end from a single source.
|
|
8
|
+
|
|
9
|
+
The absorption advances the **operating model** for culture.dev. The repo name comes from Hebrew *katvan* — "writer / scribe". katvan owns the customer-facing site for the AgentCulture mesh:
|
|
10
|
+
|
|
11
|
+
- **Sibling repos and their PMs / agents** know *what* changed in their product: the new verb, the shipped feature, the API rename, the deprecation. They file issues against katvan describing the substance.
|
|
12
|
+
- **katvan** knows *how* that change should sit on a public site: where it goes in the IA, how the framing reads, what links in, what gets retired. katvan iterates `culture.dev`.
|
|
13
|
+
|
|
14
|
+
Sibling repos do not run their own Jekyll deploys. They write the substance; katvan writes the page. This split is what makes a unified marketing/docs surface possible without each product team needing to think about navigation or voice.
|
|
15
|
+
|
|
16
|
+
## Goal
|
|
17
|
+
|
|
18
|
+
After this PR ships:
|
|
19
|
+
|
|
20
|
+
- `culture.dev/agex/` and all subpaths are served from katvan's existing Cloudflare deployment as plain paths inside the main Jekyll build. No subsite scaffolding, no per-project Cloudflare project, no path-routing rule, no redirects.
|
|
21
|
+
- The published per-command pages stay in sync with the canonical `SKILL.md` files inside agex-cli (the CLI ships those, and they are the same files `agex learn --json` / `agex explain --json` serve to agents). Drift between site and CLI is impossible by construction (rendering is automated; no hand-authored copy).
|
|
22
|
+
- agex-cli no longer needs `docs/`, the docs deploy workflow, or its render script. (Phase 2, separate PR; see Cutover.)
|
|
23
|
+
|
|
24
|
+
## Non-goals
|
|
25
|
+
|
|
26
|
+
- Visual / design uplift for `/agex/` pages. Folded into katvan's existing dark overlay; richer treatment parked in [#14](https://github.com/agentculture/katvan/issues/14).
|
|
27
|
+
- Migrating other subsites (`/afi/`, `/agentirc/`, `/citation-cli/`). Each gets its own absorption PR when a sibling-repo issue requests it.
|
|
28
|
+
- Rewriting `docs/architecture/subsites.md`. The doc still describes the (now-receding) "separate Cloudflare project per subsite" pattern. One link inside it is fixed in this PR; the broader rewrite is a follow-up.
|
|
29
|
+
- Parity verification against the existing agex.pages.dev rendering. This is a renovation, not a faithful migration; modest content / style drift is acceptable.
|
|
30
|
+
|
|
31
|
+
## URL structure
|
|
32
|
+
|
|
33
|
+
Single-build, single-deployment. `/agex/` is a path node inside `culture.dev`, with sub-pages.
|
|
34
|
+
|
|
35
|
+
| URL | Source file in katvan | Origin |
|
|
36
|
+
|---|---|---|
|
|
37
|
+
| `/agex/` | `site/agex/index.md` | wholesale from `agex-cli/docs/index.md` |
|
|
38
|
+
| `/agex/getting-started/` | `site/agex/getting-started.md` | wholesale from `agex-cli/docs/getting-started.md` |
|
|
39
|
+
| `/agex/skill-sources/` | `site/agex/skill-sources.md` | wholesale from `agex-cli/docs/skill-sources.md` |
|
|
40
|
+
| `/agex/commands/` | `site/agex/commands/index.md` | generated by sync script |
|
|
41
|
+
| `/agex/commands/<verb>/` | `site/agex/commands/<verb>.md` × 7 | generated from `agex-cli/src/agent_experience/commands/<verb>/SKILL.md` |
|
|
42
|
+
| `/agex-cli/` | (deleted) | replaced by content under `/agex/` |
|
|
43
|
+
|
|
44
|
+
`site/docs/agex-cli/index.md` is removed. Its two internal inbound links (`site/docs/antoine/index.md:21`, `site/docs/architecture/subsites.md:108`) are rewritten to `/agex/`.
|
|
45
|
+
|
|
46
|
+
## SKILL.md sync mechanism
|
|
47
|
+
|
|
48
|
+
**Script:** new `scripts/sync_agex_skills.py` in katvan. Reads SKILL.md files from a given agex-cli checkout path, strips each SKILL.md's own YAML frontmatter, prepends a Jekyll-friendly frontmatter (`title`, `parent: Commands`, `nav_order: order*10`), and writes the result into `site/agex/commands/<verb>.md`. Maintains the `_clear_stale_pages` invariant (removed-upstream commands disappear locally too). Stdlib only — no dependency on the `agent_experience` Python package.
|
|
49
|
+
|
|
50
|
+
The script is owned by katvan (single source of truth for the render shape). agex-cli's existing `scripts/sync_skill_md.py` is retired in Phase 2.
|
|
51
|
+
|
|
52
|
+
**Invocation:** `python3 scripts/sync_agex_skills.py <agex-cli-checkout-path>`. The reference-sync workflow passes the path of a freshly-cloned `agentculture/agex-cli@main`.
|
|
53
|
+
|
|
54
|
+
## Reference-sync workflow integration
|
|
55
|
+
|
|
56
|
+
The existing `.github/workflows/reference-sync.yml` (nightly cron + manual `workflow_dispatch`) currently runs `katvan pull --all` for AFI references and opens a PR if `site/docs` changed. Extend it:
|
|
57
|
+
|
|
58
|
+
1. After the `katvan pull --all` step, check out `agentculture/agex-cli@main` into `_agex-cli-src/`.
|
|
59
|
+
2. Run `python3 scripts/sync_agex_skills.py _agex-cli-src`.
|
|
60
|
+
3. Broaden the "Open PR if anything changed" trigger from `site/docs` to `site/`.
|
|
61
|
+
|
|
62
|
+
PR title and body wording stay the same (`chore(reference): nightly sync YYYY-MM-DD`); the diff itself reveals whether AFI refs, agex commands, or both moved.
|
|
63
|
+
|
|
64
|
+
Rendered output is **committed in katvan**. PR builds are deterministic from the committed state. Drift between agex-cli `SKILL.md` and the site is bounded at 24 hours (cron cadence). A maintainer can fire the workflow on demand after a notable agex-cli change to shrink that window.
|
|
65
|
+
|
|
66
|
+
## Cutover
|
|
67
|
+
|
|
68
|
+
**Phase 1 — this PR.** Add `site/agex/*` content (including a one-time hand-run of `sync_agex_skills.py` so `commands/*.md` is populated immediately, not deferred to the first cron). Delete `site/docs/agex-cli/index.md` and update its two inbound links. Add the agex render steps to `reference-sync.yml`. Drop the `/agex/`-exclusion from `site/sitemap-main.html` and the `/agex/sitemap.xml` entry from `site/sitemap.html`. Version bump + CHANGELOG. htmlproofer hard-gate (live from PR #28) catches link regressions on its own — no new CI step needed.
|
|
69
|
+
|
|
70
|
+
On merge, katvan's existing deployment starts serving `culture.dev/agex/*`. The standalone `agex.pages.dev` deployment still builds on agex-cli pushes but its content is no longer reached.
|
|
71
|
+
|
|
72
|
+
**Phase 2 — follow-up PR on `agentculture/agex-cli`.** Delete `docs/`, `.github/workflows/docs.yml`, `scripts/sync_skill_md.py`. Keep `src/agent_experience/commands/*/SKILL.md` — that's the source of truth katvan now pulls from. The `agex` Cloudflare Pages project becomes dead weight; the cloudflare team retires it at their convenience.
|
|
73
|
+
|
|
74
|
+
katvan files one follow-up issue on `agentculture/agex-cli` (via `agtag`) immediately after Phase 1 merges, referencing this PR. No rollback plan — fix-forward.
|
|
75
|
+
|
|
76
|
+
## Files touched in katvan
|
|
77
|
+
|
|
78
|
+
**Add (12 files)**
|
|
79
|
+
- `scripts/sync_agex_skills.py`
|
|
80
|
+
- `site/agex/index.md`, `site/agex/getting-started.md`, `site/agex/skill-sources.md`
|
|
81
|
+
- `site/agex/commands/index.md`
|
|
82
|
+
- `site/agex/commands/{doctor,explain,gamify,hook,learn,overview,pr}.md` (7)
|
|
83
|
+
|
|
84
|
+
**Modify**
|
|
85
|
+
- `site/sitemap-main.html` — drop the `if page.url contains "/agex/"` skip
|
|
86
|
+
- `site/sitemap.html` — drop the `<sitemap><loc>{{ '/agex/sitemap.xml' | absolute_url }}</loc></sitemap>` line
|
|
87
|
+
- `site/docs/antoine/index.md` — rewrite `[agex-cli](/agex-cli/)` → `[agex](/agex/)` at line 21
|
|
88
|
+
- `site/docs/architecture/subsites.md` — rewrite `[`agex-cli`](/agex-cli/)` at line 108 to point at `/agex/`
|
|
89
|
+
- `.github/workflows/reference-sync.yml` — add the agex-cli checkout + render steps; broaden the PR trigger from `site/docs` to `site/`
|
|
90
|
+
- `pyproject.toml` — version bump
|
|
91
|
+
- `CHANGELOG.md` — entry under Unreleased
|
|
92
|
+
|
|
93
|
+
**Delete**
|
|
94
|
+
- `site/docs/agex-cli/index.md`
|
|
95
|
+
|
|
96
|
+
## Verification
|
|
97
|
+
|
|
98
|
+
**Local pre-PR**
|
|
99
|
+
1. `python3 scripts/sync_agex_skills.py /home/spark/git/agex-cli` — confirm 8 files written under `site/agex/commands/` (7 verbs + 1 `index.md`).
|
|
100
|
+
2. `bundle exec jekyll build --config _config.base.yml,_config.culture.yml -d _site_culture --strict_front_matter` — clean.
|
|
101
|
+
3. `htmlproofer _site_culture --disable-external --allow-hash-href` — 0 failures.
|
|
102
|
+
4. Spot-check `_site_culture/agex/index.html`, `_site_culture/agex/getting-started/index.html`, `_site_culture/agex/commands/pr/index.html`. Confirm: page titles render, sidebar shows the command list, internal links resolve, no `404`s on `/agex/*`.
|
|
103
|
+
5. Spot-check `_site_culture/sitemap-main.xml` includes `/agex/`, `/agex/getting-started/`, `/agex/commands/pr/` entries. `_site_culture/sitemap.xml` no longer references `/agex/sitemap.xml`.
|
|
104
|
+
|
|
105
|
+
**CI gates (existing)**
|
|
106
|
+
- `build-docs` workflow: Jekyll `--strict_front_matter` + htmlproofer hard-fail
|
|
107
|
+
- `version-check`
|
|
108
|
+
- `SonarCloud Code Analysis`
|
|
109
|
+
- Cloudflare Pages preview deploys for visual review
|
|
110
|
+
|
|
111
|
+
**Post-merge**
|
|
112
|
+
- Manual trigger of `reference-sync.yml` confirms the cron path works end-to-end (clones agex-cli, renders, opens PR only if content moved).
|
|
113
|
+
- Follow-up issue filed against `agentculture/agex-cli` for Phase 2 (Jekyll teardown).
|
|
@@ -15,6 +15,8 @@ from pathlib import Path
|
|
|
15
15
|
from katvan import repos
|
|
16
16
|
from katvan.cli._output import emit_result
|
|
17
17
|
|
|
18
|
+
_INDEX_MD = "index.md"
|
|
19
|
+
|
|
18
20
|
|
|
19
21
|
def register(sub: argparse._SubParsersAction) -> None:
|
|
20
22
|
parser = sub.add_parser("doctor", help="check culture.dev IA health")
|
|
@@ -23,20 +25,30 @@ def register(sub: argparse._SubParsersAction) -> None:
|
|
|
23
25
|
|
|
24
26
|
|
|
25
27
|
def _check_index(site_root: Path, entry: dict) -> str | None:
|
|
26
|
-
|
|
28
|
+
site_path = entry.get("site_path")
|
|
29
|
+
if site_path:
|
|
30
|
+
rel = site_path.strip("/")
|
|
31
|
+
page = site_root / rel / _INDEX_MD
|
|
32
|
+
rel_display = f"site/{rel}/{_INDEX_MD}"
|
|
33
|
+
else:
|
|
34
|
+
page = site_root / "docs" / entry["id"] / _INDEX_MD
|
|
35
|
+
rel_display = f"site/docs/{entry['id']}/{_INDEX_MD}"
|
|
27
36
|
if not page.is_file():
|
|
28
|
-
return f"missing
|
|
37
|
+
return f"missing {rel_display} (hand-authored page)"
|
|
29
38
|
if not page.read_text().strip():
|
|
30
|
-
return f"
|
|
39
|
+
return f"{rel_display} is empty"
|
|
31
40
|
return None
|
|
32
41
|
|
|
33
42
|
|
|
34
43
|
def _check_reference(site_root: Path, entry: dict) -> str | None:
|
|
35
44
|
if entry.get("docs_mode") != "pull-reference":
|
|
36
45
|
return None
|
|
37
|
-
ref = site_root / "docs" / entry["id"] / "reference" /
|
|
46
|
+
ref = site_root / "docs" / entry["id"] / "reference" / _INDEX_MD
|
|
38
47
|
if not ref.is_file():
|
|
39
|
-
return
|
|
48
|
+
return (
|
|
49
|
+
f"missing site/docs/{entry['id']}/reference/{_INDEX_MD} "
|
|
50
|
+
f"(run `katvan pull {entry['id']}`)"
|
|
51
|
+
)
|
|
40
52
|
return None
|
|
41
53
|
|
|
42
54
|
|
|
@@ -45,7 +57,11 @@ def _check_readme_link(entry: dict) -> str | None:
|
|
|
45
57
|
readme = sibling / "README.md"
|
|
46
58
|
if not readme.is_file():
|
|
47
59
|
return None
|
|
48
|
-
|
|
60
|
+
site_path = entry.get("site_path")
|
|
61
|
+
if site_path:
|
|
62
|
+
expected = f"https://culture.dev{site_path}"
|
|
63
|
+
else:
|
|
64
|
+
expected = f"https://culture.dev/{entry['id']}/"
|
|
49
65
|
if expected not in readme.read_text():
|
|
50
66
|
return f"warning: {sibling}/README.md missing link to {expected}"
|
|
51
67
|
return None
|
|
@@ -184,7 +184,7 @@ def repos() -> Iterator[tuple[str, str, str]]:
|
|
|
184
184
|
# and the overview verb does not need them.
|
|
185
185
|
_SCALAR_FIELDS: tuple[str, ...] = (
|
|
186
186
|
"category", "maturity", "docs_mode", "description",
|
|
187
|
-
"package", "binary", "docs", "install", "caveat",
|
|
187
|
+
"package", "binary", "docs", "site_path", "install", "caveat",
|
|
188
188
|
)
|
|
189
189
|
|
|
190
190
|
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""sync_agex_skills.py — render agex-cli SKILL.md files into katvan site pages.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python3 scripts/sync_agex_skills.py <path-to-agex-cli-checkout>
|
|
6
|
+
|
|
7
|
+
Reads ``<agex-cli>/src/agent_experience/commands/*/SKILL.md``, strips each
|
|
8
|
+
SKILL.md's own YAML frontmatter, prepends a Jekyll-friendly frontmatter
|
|
9
|
+
pointing at the ``Commands`` parent page, and writes the result to
|
|
10
|
+
``site/agex/commands/<verb>.md``. Also writes the ``Commands`` index page.
|
|
11
|
+
|
|
12
|
+
Deterministic by construction:
|
|
13
|
+
* Inputs are sorted alphabetically (so nav order is stable).
|
|
14
|
+
* Removed-upstream commands are deleted locally on re-run
|
|
15
|
+
(``_clear_stale_pages``).
|
|
16
|
+
* Re-running on unchanged input produces byte-identical output (CI relies
|
|
17
|
+
on this so bot-PR diffs stay minimal).
|
|
18
|
+
|
|
19
|
+
stdlib only — no dependency on the ``agent_experience`` Python package or
|
|
20
|
+
PyYAML. The frontmatter shape we read is small enough for a hand parse.
|
|
21
|
+
"""
|
|
22
|
+
from __future__ import annotations
|
|
23
|
+
|
|
24
|
+
import re
|
|
25
|
+
import sys
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
29
|
+
DEFAULT_OUT_DIR = REPO_ROOT / "site" / "agex" / "commands"
|
|
30
|
+
|
|
31
|
+
_JEKYLL_FRONTMATTER = (
|
|
32
|
+
"---\n"
|
|
33
|
+
"title: {title}\n"
|
|
34
|
+
"parent: Commands\n"
|
|
35
|
+
"nav_order: {order}\n"
|
|
36
|
+
"sites: [culture]\n"
|
|
37
|
+
"permalink: /agex/commands/{name}/\n"
|
|
38
|
+
"---\n\n"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
_INDEX_PAGE = (
|
|
42
|
+
"---\n"
|
|
43
|
+
"title: Commands\n"
|
|
44
|
+
"has_children: true\n"
|
|
45
|
+
"nav_order: 3\n"
|
|
46
|
+
"sites: [culture]\n"
|
|
47
|
+
"permalink: /agex/commands/\n"
|
|
48
|
+
"---\n\n"
|
|
49
|
+
"# Commands\n\n"
|
|
50
|
+
"Auto-imported from `agex-cli/src/agent_experience/commands/*/SKILL.md`"
|
|
51
|
+
" by `scripts/sync_agex_skills.py`. Re-run via the nightly"
|
|
52
|
+
" `reference-sync.yml` workflow or fire `workflow_dispatch` manually"
|
|
53
|
+
" after a notable agex-cli change.\n"
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
_NAME_RE = re.compile(r"^name:\s*(.+?)\s*$", re.MULTILINE)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def parse_skill_md(text: str) -> tuple[str, str]:
|
|
60
|
+
"""Return (name, body) from a SKILL.md file.
|
|
61
|
+
|
|
62
|
+
SKILL.md format: ``---\\n<yaml>\\n---\\n\\n<body>``. We extract the
|
|
63
|
+
``name:`` field from the YAML block and return everything after the
|
|
64
|
+
closing fence (byte-for-byte).
|
|
65
|
+
"""
|
|
66
|
+
if not text.startswith("---\n"):
|
|
67
|
+
raise ValueError("SKILL.md missing opening frontmatter fence")
|
|
68
|
+
end = text.find("\n---\n", 4)
|
|
69
|
+
if end == -1:
|
|
70
|
+
raise ValueError("SKILL.md missing closing frontmatter fence")
|
|
71
|
+
frontmatter = text[4:end]
|
|
72
|
+
body = text[end + 5:]
|
|
73
|
+
if body.startswith("\n"):
|
|
74
|
+
body = body[1:]
|
|
75
|
+
match = _NAME_RE.search(frontmatter)
|
|
76
|
+
if not match:
|
|
77
|
+
raise ValueError("SKILL.md frontmatter missing `name:` field")
|
|
78
|
+
return match.group(1), body
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _commands_dir(agex_root: Path) -> Path:
|
|
82
|
+
return agex_root / "src" / "agent_experience" / "commands"
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _top_level_skill_md(agex_root: Path) -> list[Path]:
|
|
86
|
+
"""Return alphabetical SKILL.md paths for the top-level command dirs."""
|
|
87
|
+
cmds = _commands_dir(agex_root)
|
|
88
|
+
return sorted(
|
|
89
|
+
cmd_dir / "SKILL.md"
|
|
90
|
+
for cmd_dir in cmds.iterdir()
|
|
91
|
+
if cmd_dir.is_dir() and (cmd_dir / "SKILL.md").is_file()
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _clear_stale_pages(out_dir: Path, expected: set[str]) -> None:
|
|
96
|
+
"""Remove out_dir/*.md not in ``expected``. Always re-writes index.md."""
|
|
97
|
+
if not out_dir.exists():
|
|
98
|
+
return
|
|
99
|
+
for path in sorted(out_dir.glob("*.md")):
|
|
100
|
+
if path.name in expected:
|
|
101
|
+
continue
|
|
102
|
+
path.unlink()
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def render(agex_root: Path, out_dir: Path = DEFAULT_OUT_DIR) -> int:
|
|
106
|
+
"""Render all top-level SKILL.md files under agex_root into out_dir."""
|
|
107
|
+
out_dir.mkdir(parents=True, exist_ok=True)
|
|
108
|
+
skills = _top_level_skill_md(agex_root)
|
|
109
|
+
expected = {f"{p.parent.name}.md" for p in skills} | {"index.md"}
|
|
110
|
+
_clear_stale_pages(out_dir, expected)
|
|
111
|
+
for order, skill_md in enumerate(skills, start=1):
|
|
112
|
+
slug = skill_md.parent.name
|
|
113
|
+
title, body = parse_skill_md(skill_md.read_text(encoding="utf-8"))
|
|
114
|
+
page = _JEKYLL_FRONTMATTER.format(
|
|
115
|
+
title=title, order=order * 10, name=slug
|
|
116
|
+
) + body
|
|
117
|
+
(out_dir / f"{slug}.md").write_text(page, encoding="utf-8")
|
|
118
|
+
(out_dir / "index.md").write_text(_INDEX_PAGE, encoding="utf-8")
|
|
119
|
+
return 0
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
def main(argv: list[str]) -> int:
|
|
123
|
+
if len(argv) != 2:
|
|
124
|
+
print(
|
|
125
|
+
"usage: sync_agex_skills.py <agex-cli-checkout-path>",
|
|
126
|
+
file=sys.stderr,
|
|
127
|
+
)
|
|
128
|
+
return 2
|
|
129
|
+
return render(Path(argv[1]).resolve())
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
if __name__ == "__main__":
|
|
133
|
+
raise SystemExit(main(sys.argv))
|
|
@@ -20,6 +20,11 @@
|
|
|
20
20
|
# package (optional) PyPI package name if applicable
|
|
21
21
|
# binary (optional) CLI binary name if applicable
|
|
22
22
|
# docs (optional) absolute URL — culture.dev page or repo README
|
|
23
|
+
# site_path (optional) the canonical katvan-site path for this repo,
|
|
24
|
+
# if it differs from `/<id>/`. Set this when a repo's
|
|
25
|
+
# docs live under a different slug (e.g. `agex-cli`'s
|
|
26
|
+
# docs live at `/agex/`). Templates fall back to
|
|
27
|
+
# `/<id>/` when this is unset.
|
|
23
28
|
# install (optional) one-line install command
|
|
24
29
|
# caveat (optional) one short sentence — a current public-facing
|
|
25
30
|
# limitation a reader should know about
|
|
@@ -77,6 +82,7 @@
|
|
|
77
82
|
description: Improve an agent's developer experience; powers `culture devex`.
|
|
78
83
|
binary: agex
|
|
79
84
|
docs: https://culture.dev/agex/
|
|
85
|
+
site_path: /agex/
|
|
80
86
|
caveat: "Reference sync deferred — `agex learn` does not yet support `--json`."
|
|
81
87
|
related: [culture]
|
|
82
88
|
|
|
@@ -30,7 +30,8 @@ layout: default
|
|
|
30
30
|
<h3>{{ cat | replace: "-", " " | capitalize }}</h3>
|
|
31
31
|
<ul>
|
|
32
32
|
{% for r in repos_in_cat %}
|
|
33
|
-
|
|
33
|
+
{% if r.site_path %}{% assign r_path = r.site_path %}{% else %}{% assign r_path = r.id | prepend: "/" | append: "/" %}{% endif %}
|
|
34
|
+
<li><a href="{{ r_path }}">{{ r.id }}</a> — {{ r.description }}</li>
|
|
34
35
|
{% endfor %}
|
|
35
36
|
</ul>
|
|
36
37
|
</article>
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: doctor
|
|
3
|
+
parent: Commands
|
|
4
|
+
nav_order: 10
|
|
5
|
+
sites: [culture]
|
|
6
|
+
permalink: /agex/commands/doctor/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# `agex doctor`
|
|
10
|
+
|
|
11
|
+
Run a zero-argument health check across:
|
|
12
|
+
|
|
13
|
+
1. **Install** — `agex` version, Python version, package resources are reachable.
|
|
14
|
+
2. **Project state** — whether `.agex/` exists in the current directory; if it does, that `config.toml` parses, `.gitignore` matches the managed content, and `data/` is writable.
|
|
15
|
+
3. **Internal consistency** — every shipped `commands/*/SKILL.md` parses with the required frontmatter, every per-backend capability YAML loads.
|
|
16
|
+
4. **Operator verification** — a short markdown checklist of things `doctor` cannot verify automatically (network reach, git-tracking of `.agex/config.toml`, agent shell-tool wiring).
|
|
17
|
+
|
|
18
|
+
`doctor` is strictly read-only. It will never create `.agex/` or write anywhere on disk — if the directory is missing, that is reported as info and the command keeps going.
|
|
19
|
+
|
|
20
|
+
## Exit codes
|
|
21
|
+
|
|
22
|
+
| Code | Meaning |
|
|
23
|
+
|---|---|
|
|
24
|
+
| `0` | All checks `ok`, possibly with `warn` rows. |
|
|
25
|
+
| `1` | At least one `fail` row. Stderr carries a one-line summary. |
|
|
26
|
+
| `2` | CLI usage error (e.g., unknown role passed via `--role`). |
|
|
27
|
+
|
|
28
|
+
## From your shell tool
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
agex doctor # base health check
|
|
32
|
+
agex doctor --role pr-review # base + role-specific checks (when a role file ships)
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Role-specific checks
|
|
36
|
+
|
|
37
|
+
`doctor` has an extension hook: a role file at `commands/doctor/assets/roles/<role>.md.j2` (slug-validated, `^[a-z][a-z0-9-]*$`) is rendered as an extra section when the user passes `--role <role>`. The current release ships zero role files — the contract exists so role-specific diagnostics can be added without touching `doctor` itself.
|
|
38
|
+
|
|
39
|
+
## What `doctor` does *not* do
|
|
40
|
+
|
|
41
|
+
- It does not run backend probes — that's `agex overview --agent X`.
|
|
42
|
+
- It does not perform any auto-fix. Recovery instructions are emitted as markdown for the operator (agent or human) to act on.
|
|
43
|
+
- It does not touch the network.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: explain
|
|
3
|
+
parent: Commands
|
|
4
|
+
nav_order: 20
|
|
5
|
+
sites: [culture]
|
|
6
|
+
permalink: /agex/commands/explain/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# `agex explain <topic>`
|
|
10
|
+
|
|
11
|
+
Use this to get authoritative, deterministic documentation on an agex command, lesson, or concept without invoking a lesson or running a probe.
|
|
12
|
+
|
|
13
|
+
## How it resolves
|
|
14
|
+
|
|
15
|
+
1. `commands/<topic>/SKILL.md` (command-level, wins if present)
|
|
16
|
+
2. `commands/learn/assets/topics/<topic>/SKILL.md` (lesson-level)
|
|
17
|
+
3. `commands/explain/assets/topics/<topic>.md` (concept-level override)
|
|
18
|
+
|
|
19
|
+
First match wins.
|
|
20
|
+
|
|
21
|
+
## From your shell tool
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
agex explain overview
|
|
25
|
+
agex explain gamify
|
|
26
|
+
agex explain levelup
|
|
27
|
+
agex explain agex # self-describing page
|
|
28
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: gamify
|
|
3
|
+
parent: Commands
|
|
4
|
+
nav_order: 30
|
|
5
|
+
sites: [culture]
|
|
6
|
+
permalink: /agex/commands/gamify/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# `agex gamify --agent <backend>` / `agex gamify --uninstall --agent <backend>`
|
|
10
|
+
|
|
11
|
+
## What it does
|
|
12
|
+
|
|
13
|
+
Writes backend-native hook fragments (each tagged with a stable `agex:*` ID) that call `agex hook write <event>` on PostToolUse, UserPromptSubmit, and Stop events. Agent-authored skills (e.g., `levelup`) read the accumulated data via `agex hook read`.
|
|
14
|
+
|
|
15
|
+
## Why it's safe
|
|
16
|
+
|
|
17
|
+
- Idempotent: re-running is a no-op.
|
|
18
|
+
- Reversible: `--uninstall` removes exactly the `agex:*` fragments; user-authored hooks are untouched.
|
|
19
|
+
- Calling `agex gamify` explicitly is the confirmation — no separate prompt.
|
|
20
|
+
|
|
21
|
+
## Unsupported backends
|
|
22
|
+
|
|
23
|
+
If your backend doesn't support hooks, you get a markdown notice + issue link instead.
|
|
24
|
+
|
|
25
|
+
## From your shell tool
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
agex gamify --agent claude-code
|
|
29
|
+
# ... use your runtime for a while ...
|
|
30
|
+
agex hook read --agent claude-code
|
|
31
|
+
# ... later, to undo:
|
|
32
|
+
agex gamify --uninstall --agent claude-code
|
|
33
|
+
```
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: hook
|
|
3
|
+
parent: Commands
|
|
4
|
+
nav_order: 40
|
|
5
|
+
sites: [culture]
|
|
6
|
+
permalink: /agex/commands/hook/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# `agex hook write <event> [key=value ...]` / `agex hook read --agent <backend>`
|
|
10
|
+
|
|
11
|
+
## `write`
|
|
12
|
+
|
|
13
|
+
Called by installed hooks (see `agex gamify`, Phase 7). Appends a JSON line to `.agex/data/<event>.json`. Silent. Safe for concurrent invocation (file locking via `portalocker`).
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
agex hook write post-tool-use tool=Read
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## `read`
|
|
20
|
+
|
|
21
|
+
Renders tracked events as a markdown table. Prints the source JSON path for deeper inspection.
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
agex hook read --agent claude-code
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Notes
|
|
28
|
+
|
|
29
|
+
- Event names are free-form; conventional names: `post-tool-use`, `user-prompt`, `stop`, `sessions`.
|
|
30
|
+
- Extra positional `key=value` pairs are captured into the payload. Empty keys (e.g., `=foo`) are dropped.
|
|
31
|
+
- Timestamp (`ts`) is attached automatically; a positional `ts=<value>` overrides it (useful for replays).
|
|
32
|
+
- The positional `<event>` name is authoritative — it always wins over any `event=...` pair in args.
|
|
33
|
+
- Malformed JSON lines in `.agex/data/*.json` (e.g., from a partial write) are skipped with a warning on `hook read`, not raised.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Commands
|
|
3
|
+
has_children: true
|
|
4
|
+
nav_order: 3
|
|
5
|
+
sites: [culture]
|
|
6
|
+
permalink: /agex/commands/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Commands
|
|
10
|
+
|
|
11
|
+
Auto-imported from `agex-cli/src/agent_experience/commands/*/SKILL.md` by `scripts/sync_agex_skills.py`. Re-run via the nightly `reference-sync.yml` workflow or fire `workflow_dispatch` manually after a notable agex-cli change.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: learn
|
|
3
|
+
parent: Commands
|
|
4
|
+
nav_order: 50
|
|
5
|
+
sites: [culture]
|
|
6
|
+
permalink: /agex/commands/learn/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# `agex learn [topic] --agent <backend>`
|
|
10
|
+
|
|
11
|
+
Without a topic, lists the lessons available for your backend. With a topic, teaches it — emits a markdown lesson body plus inline skill-template code blocks you can write into your project.
|
|
12
|
+
|
|
13
|
+
## From your shell tool
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
agex learn --agent claude-code
|
|
17
|
+
agex learn introspect --agent claude-code
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Notes
|
|
21
|
+
|
|
22
|
+
- Lessons gated on a backend feature (e.g., `gamify` needs hooks) may still appear in the list, but they are not currently annotated as unsupported in the menu — Phase 8 adds that capability-based routing.
|
|
23
|
+
- v0.1 emits inline code blocks only. A future `--write` flag is tracked as an open issue.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: overview
|
|
3
|
+
parent: Commands
|
|
4
|
+
nav_order: 60
|
|
5
|
+
sites: [culture]
|
|
6
|
+
permalink: /agex/commands/overview/
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# `agex overview --agent <backend>`
|
|
10
|
+
|
|
11
|
+
Call this to get a read-only markdown snapshot of what's configured in the
|
|
12
|
+
current project for a given backend — skills, hooks, agents, MCP servers,
|
|
13
|
+
and relevant config files. Descriptive, not diagnostic. Read it before you
|
|
14
|
+
act.
|
|
15
|
+
|
|
16
|
+
## From your shell tool
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
agex overview --agent claude-code
|
|
20
|
+
agex overview --agent codex
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## What you get
|
|
24
|
+
|
|
25
|
+
Markdown sections: Project root, `CLAUDE.md`/`AGENTS.md` presence, Skills,
|
|
26
|
+
Hooks, MCP servers, Settings.
|
|
27
|
+
|
|
28
|
+
## Notes
|
|
29
|
+
|
|
30
|
+
- Malformed files are skipped with a `> ⚠️` inline warning.
|
|
31
|
+
- Read-only except first-run `.agex/` init.
|
|
32
|
+
- Build diagnostic logic (gaps, recommendations) into an agent-authored skill:
|
|
33
|
+
`agex learn introspect --agent <backend>`.
|