selfdoc 0.4.1__tar.gz → 0.4.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.
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.gitignore +0 -1
- selfdoc-0.4.2/.rlsbl/changes/.validated +1 -0
- selfdoc-0.4.2/.rlsbl/changes/0.4.2.jsonl +7 -0
- selfdoc-0.4.2/.rlsbl/changes/0.4.2.md +5 -0
- selfdoc-0.4.2/.rlsbl/version +1 -0
- selfdoc-0.4.2/.selfdoc/hashes/hashes.json +6 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/CHANGELOG.md +6 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/PKG-INFO +1 -1
- {selfdoc-0.4.1 → selfdoc-0.4.2}/docs/index.md +4 -0
- selfdoc-0.4.2/package-lock.json +19 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/package.json +1 -1
- {selfdoc-0.4.1 → selfdoc-0.4.2}/pyproject.toml +1 -1
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/git.py +19 -2
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_git.py +37 -9
- selfdoc-0.4.2/todo/generate-claude-readme.md +90 -0
- selfdoc-0.4.1/.rlsbl/version +0 -1
- selfdoc-0.4.1/.selfdoc/hashes/hashes.json +0 -1
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.claude/settings.json +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.github/workflows/ci.yml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.github/workflows/publish.yml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.claude/settings.json +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.github/workflows/publish.yml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.gitignore +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/changes/unreleased.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/hooks/post-release.sh +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/lint/go.toml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/lint/npm.toml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/lint/python.toml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/CLAUDE.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.1.0.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.1.0.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.2.0.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.2.0.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.0.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.0.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.1.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.1.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.0.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.0.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.1.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.1.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/unreleased.jsonl +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/config.json +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hashes.json +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hooks/post-release.sh +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hooks/pre-checks.sh +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hooks/pre-release.sh +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/lint/go.toml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/lint/npm.toml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/lint/python.toml +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/CLAUDE.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/LICENSE +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/README.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/bin/cli.js +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/demo/index.html +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/__init__.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/__main__.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/build.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/catalog.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/check.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/cli.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/config.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/content.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/deploy.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/directives.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/__init__.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/base.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/go.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/protocol.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/python.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/typescript.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/gen.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/gendata.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/html.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/resolver.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/staleness.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/strictcli_support.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/__init__.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/clean.css +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/clean.json +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/minimal.css +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/minimal.json +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/tokenizer.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc.json +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_build.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_catalog.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_check.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_cli.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_config.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_content.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_contrast.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_custom_directives.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_demo_panel.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_directives.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_extractors_protocol.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_gen.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_gendata.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_go_extractor.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_h1.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_python_extractor.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_search.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_staleness.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_strictcli_support.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_token_migration.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_tokenizer.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_ts_extractor.py +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/auto-commit-hashes.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/auto-generated-glossary.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/auto-generation-gaps.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/changelog-page.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/coverage-go-typescript.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/cross-page-term-linking.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/lint-ignores-code-blocks.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/reading-progress.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/seo-geo-audit.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/seo-linting-gaps.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/sticky-table-column.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/styling-and-release.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/atom-feed-filtering.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/brotli-dependency.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/css-redesign.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/gen-cli-descriptions.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/glossary-config-opt-in.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/sticky-column-striped-rows.md +0 -0
- {selfdoc-0.4.1 → selfdoc-0.4.2}/uv.lock +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
13feaaa6579b99403184ebbc22dae7a207a0075d
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{"commits":["c49c0921c49011c8644a6bc7ddd6b71a0f660060"],"user_facing":false}
|
|
2
|
+
{"commits":["c5501cdc68770602dee65bf78614a6cb0262ab55"],"user_facing":false}
|
|
3
|
+
{"commits":["a32257fd22f1531003ec60ee9c4f00cf0a521c9b"],"user_facing":false}
|
|
4
|
+
{"commits":["1928ad226a3657c089941e017025ea49b846574e","bd31871260c794b8069521c1b8282c8648d2ecc1","f62fd7ba0ae9bb6d74e34222e00be481f6f86caf"],"user_facing":false}
|
|
5
|
+
{"commits":["23795ad5b0a0460a9fd800cbaa01b352654bb5d7"],"user_facing":false}
|
|
6
|
+
{"commits":["583c7fcfae40623860c9b3cdcfa32226fe30be3d"],"user_facing":true,"description":"Auto-commit prefers rlsbl commit when available, marking commits with Autogenerated trailer for changelog coverage exemption","type":"feature"}
|
|
7
|
+
{"commits":["6de2021cc4e20bb17450a37412740a76332e701a"],"user_facing":false}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.31.0
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "selfdocumenting",
|
|
3
|
+
"version": "0.4.1",
|
|
4
|
+
"lockfileVersion": 3,
|
|
5
|
+
"requires": true,
|
|
6
|
+
"packages": {
|
|
7
|
+
"": {
|
|
8
|
+
"name": "selfdocumenting",
|
|
9
|
+
"version": "0.4.1",
|
|
10
|
+
"license": "MIT",
|
|
11
|
+
"bin": {
|
|
12
|
+
"selfdoc": "bin/cli.js"
|
|
13
|
+
},
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -104,8 +104,25 @@ def auto_commit(files: list[str], message: str, cwd: str) -> bool:
|
|
|
104
104
|
env = os.environ.copy()
|
|
105
105
|
env["SELFDOC_AUTO_COMMIT"] = "1"
|
|
106
106
|
|
|
107
|
-
# Try
|
|
108
|
-
if shutil.which("
|
|
107
|
+
# Try rlsbl first, then safegit, fall back to plain git
|
|
108
|
+
if shutil.which("rlsbl"):
|
|
109
|
+
cmd = ["rlsbl", "commit", "-m", message, "--"] + committable
|
|
110
|
+
try:
|
|
111
|
+
result = subprocess.run(
|
|
112
|
+
cmd,
|
|
113
|
+
cwd=cwd,
|
|
114
|
+
capture_output=True,
|
|
115
|
+
env=env,
|
|
116
|
+
timeout=30,
|
|
117
|
+
)
|
|
118
|
+
return result.returncode == 0
|
|
119
|
+
except (OSError, subprocess.TimeoutExpired) as exc:
|
|
120
|
+
print(
|
|
121
|
+
f"selfdoc: auto-commit failed (rlsbl): {exc}",
|
|
122
|
+
file=sys.stderr,
|
|
123
|
+
)
|
|
124
|
+
return False
|
|
125
|
+
elif shutil.which("safegit"):
|
|
109
126
|
cmd = ["safegit", "commit", "-m", message, "--"] + committable
|
|
110
127
|
try:
|
|
111
128
|
result = subprocess.run(
|
|
@@ -101,16 +101,43 @@ def test_auto_commit_loop_guard(tmp_path, monkeypatch):
|
|
|
101
101
|
assert result is False
|
|
102
102
|
|
|
103
103
|
|
|
104
|
+
def test_auto_commit_uses_rlsbl_when_available(tmp_path):
|
|
105
|
+
"""auto_commit calls rlsbl commit when it is on PATH."""
|
|
106
|
+
_init_git_repo(tmp_path)
|
|
107
|
+
(tmp_path / "file.txt").write_text("data")
|
|
108
|
+
|
|
109
|
+
with mock.patch("shutil.which", return_value="/usr/bin/rlsbl"):
|
|
110
|
+
with mock.patch("subprocess.run") as mock_run:
|
|
111
|
+
mock_run.side_effect = [
|
|
112
|
+
mock.Mock(returncode=0), # git rev-parse --git-dir
|
|
113
|
+
mock.Mock(returncode=1), # git check-ignore (not ignored)
|
|
114
|
+
mock.Mock(returncode=0, stdout=""), # git ls-files (untracked)
|
|
115
|
+
mock.Mock(returncode=0), # rlsbl commit
|
|
116
|
+
]
|
|
117
|
+
|
|
118
|
+
result = auto_commit(["file.txt"], "msg", str(tmp_path))
|
|
119
|
+
|
|
120
|
+
# Verify rlsbl was called
|
|
121
|
+
last_call = mock_run.call_args_list[-1]
|
|
122
|
+
assert last_call[0][0][0] == "rlsbl"
|
|
123
|
+
assert last_call[0][0][1] == "commit"
|
|
124
|
+
assert result is True
|
|
125
|
+
|
|
126
|
+
|
|
104
127
|
def test_auto_commit_uses_safegit_when_available(tmp_path):
|
|
105
|
-
"""auto_commit calls safegit when
|
|
128
|
+
"""auto_commit calls safegit when rlsbl is not available."""
|
|
106
129
|
_init_git_repo(tmp_path)
|
|
107
130
|
(tmp_path / "file.txt").write_text("data")
|
|
108
131
|
|
|
109
|
-
|
|
132
|
+
def which_side_effect(cmd):
|
|
133
|
+
if cmd == "rlsbl":
|
|
134
|
+
return None
|
|
135
|
+
if cmd == "safegit":
|
|
136
|
+
return "/usr/bin/safegit"
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
with mock.patch("shutil.which", side_effect=which_side_effect):
|
|
110
140
|
with mock.patch("subprocess.run") as mock_run:
|
|
111
|
-
# First two calls: git rev-parse, git check-ignore
|
|
112
|
-
# Then: git ls-files, git diff (for untracked: ls-files returns empty)
|
|
113
|
-
# Then: safegit commit
|
|
114
141
|
mock_run.side_effect = [
|
|
115
142
|
mock.Mock(returncode=0), # git rev-parse --git-dir
|
|
116
143
|
mock.Mock(returncode=1), # git check-ignore (not ignored)
|
|
@@ -120,14 +147,15 @@ def test_auto_commit_uses_safegit_when_available(tmp_path):
|
|
|
120
147
|
|
|
121
148
|
result = auto_commit(["file.txt"], "msg", str(tmp_path))
|
|
122
149
|
|
|
123
|
-
# Verify safegit was called
|
|
150
|
+
# Verify safegit was called (not rlsbl)
|
|
124
151
|
last_call = mock_run.call_args_list[-1]
|
|
125
|
-
assert
|
|
152
|
+
assert last_call[0][0][0] == "safegit"
|
|
153
|
+
assert last_call[0][0][1] == "commit"
|
|
126
154
|
assert result is True
|
|
127
155
|
|
|
128
156
|
|
|
129
157
|
def test_auto_commit_falls_back_to_git(tmp_path):
|
|
130
|
-
"""auto_commit uses plain git when safegit is
|
|
158
|
+
"""auto_commit uses plain git when neither rlsbl nor safegit is available."""
|
|
131
159
|
_init_git_repo(tmp_path)
|
|
132
160
|
(tmp_path / "file.txt").write_text("data")
|
|
133
161
|
|
|
@@ -143,7 +171,7 @@ def test_auto_commit_falls_back_to_git(tmp_path):
|
|
|
143
171
|
|
|
144
172
|
result = auto_commit(["file.txt"], "msg", str(tmp_path))
|
|
145
173
|
|
|
146
|
-
# Verify git add and git commit were called (not safegit)
|
|
174
|
+
# Verify git add and git commit were called (not rlsbl or safegit)
|
|
147
175
|
add_call = mock_run.call_args_list[-2]
|
|
148
176
|
assert add_call[0][0][0] == "git"
|
|
149
177
|
assert add_call[0][0][1] == "add"
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Generate CLAUDE.md and README.md
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
|
|
5
|
+
selfdoc generates full HTML documentation sites, but many projects also need:
|
|
6
|
+
|
|
7
|
+
- **CLAUDE.md** -- instructions and architecture reference for AI coding agents (Claude Code, Cursor, etc.)
|
|
8
|
+
- **README.md** -- user-facing project overview, setup, and usage
|
|
9
|
+
|
|
10
|
+
These files currently must be written and maintained by hand, which causes them to drift from the actual codebase. selfdoc already has the machinery to extract structured information from source code (AST parsing, directive resolution, config reading). Extending it to produce these Markdown files would keep them in sync with the codebase automatically.
|
|
11
|
+
|
|
12
|
+
## Proposed feature
|
|
13
|
+
|
|
14
|
+
Add optional CLAUDE.md and README.md generation to `selfdoc build` (and possibly a dedicated `selfdoc gen-docs` subcommand).
|
|
15
|
+
|
|
16
|
+
### Configuration
|
|
17
|
+
|
|
18
|
+
In `selfdoc.json`:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"generate": {
|
|
23
|
+
"claude_md": true,
|
|
24
|
+
"readme_md": true
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Both default to `true` (on by default). Set to `false` to opt out.
|
|
30
|
+
|
|
31
|
+
### CLAUDE.md generation
|
|
32
|
+
|
|
33
|
+
The generated CLAUDE.md should include:
|
|
34
|
+
|
|
35
|
+
- Project name, description, and language
|
|
36
|
+
- Directory structure (from `source` paths)
|
|
37
|
+
- Key modules, classes, and functions (from existing AST extractors)
|
|
38
|
+
- Architecture patterns (inferred from import graph, inheritance, protocol usage)
|
|
39
|
+
- Entry points and CLI commands (from existing `code-help` directive machinery)
|
|
40
|
+
- Configuration files and their schema (from existing `table-config` directive)
|
|
41
|
+
- Dependencies and their purpose
|
|
42
|
+
- Any content from `docs/claude.md` template if it exists (allowing projects to add custom sections like constraints, conventions, dangerous operations)
|
|
43
|
+
|
|
44
|
+
The output should be a single flat Markdown file (no HTML, no directives) suitable for inclusion in `.claude/` or project root.
|
|
45
|
+
|
|
46
|
+
### README.md generation
|
|
47
|
+
|
|
48
|
+
The generated README.md should include:
|
|
49
|
+
|
|
50
|
+
- Project name, description, badges
|
|
51
|
+
- Installation / setup instructions
|
|
52
|
+
- Usage examples (from docstrings, test files, or a `docs/readme.md` template)
|
|
53
|
+
- API overview (from extracted symbols)
|
|
54
|
+
- Configuration reference
|
|
55
|
+
- License
|
|
56
|
+
|
|
57
|
+
### Template override
|
|
58
|
+
|
|
59
|
+
Projects can provide `docs/claude.md` and `docs/readme.md` as templates. These would support the same directive syntax as regular selfdoc pages, but the output would be plain Markdown (directives resolved, but no HTML conversion). This lets projects mix auto-extracted content with hand-written sections.
|
|
60
|
+
|
|
61
|
+
### Monorepo support
|
|
62
|
+
|
|
63
|
+
For monorepo workspaces (detected by `pyproject.toml` `[tool.uv.workspace]`, `pnpm-workspace.yaml`, or Go `go.work`):
|
|
64
|
+
|
|
65
|
+
- Generate a root CLAUDE.md and README.md for the workspace
|
|
66
|
+
- Optionally generate per-package CLAUDE.md and README.md if the package has its own `selfdoc.json` or is listed in a workspace-level config
|
|
67
|
+
|
|
68
|
+
## Affected files
|
|
69
|
+
|
|
70
|
+
- `selfdoc/config.py` -- new `generate` config fields
|
|
71
|
+
- `selfdoc/build.py` -- hook generation into build pipeline
|
|
72
|
+
- `selfdoc/gen.py` or new `selfdoc/gen_docs.py` -- generation logic
|
|
73
|
+
- `selfdoc/resolver.py` -- Markdown-output mode (resolve directives but skip HTML conversion)
|
|
74
|
+
- `selfdoc/extractors/*.py` -- may need to expose higher-level summaries (not just per-symbol details)
|
|
75
|
+
|
|
76
|
+
## Effort estimate
|
|
77
|
+
|
|
78
|
+
Medium-large. The extraction machinery exists; the main work is:
|
|
79
|
+
|
|
80
|
+
1. Designing the Markdown output format for each section
|
|
81
|
+
2. Adding a "resolve directives to Markdown" mode (currently directives resolve to HTML)
|
|
82
|
+
3. Architecture inference heuristics (import graph analysis, pattern detection)
|
|
83
|
+
4. Monorepo workspace detection and per-package orchestration
|
|
84
|
+
5. Template override support with directive resolution
|
|
85
|
+
|
|
86
|
+
## Alternatives considered
|
|
87
|
+
|
|
88
|
+
- **Keep manual**: Works but drifts. Every project with a CLAUDE.md has this problem.
|
|
89
|
+
- **Separate tool**: Could build a standalone `claudegen` tool, but it would duplicate selfdoc's extraction machinery.
|
|
90
|
+
- **AI-based generation**: Use an LLM to read the codebase and generate docs. Nondeterministic, expensive, and hard to keep in sync. selfdoc's deterministic extraction is a better foundation.
|
selfdoc-0.4.1/.rlsbl/version
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.27.0
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{}
|
|
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
|
|
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
|
|
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
|
|
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
|