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.
Files changed (128) hide show
  1. {selfdoc-0.4.1 → selfdoc-0.4.2}/.gitignore +0 -1
  2. selfdoc-0.4.2/.rlsbl/changes/.validated +1 -0
  3. selfdoc-0.4.2/.rlsbl/changes/0.4.2.jsonl +7 -0
  4. selfdoc-0.4.2/.rlsbl/changes/0.4.2.md +5 -0
  5. selfdoc-0.4.2/.rlsbl/version +1 -0
  6. selfdoc-0.4.2/.selfdoc/hashes/hashes.json +6 -0
  7. {selfdoc-0.4.1 → selfdoc-0.4.2}/CHANGELOG.md +6 -0
  8. {selfdoc-0.4.1 → selfdoc-0.4.2}/PKG-INFO +1 -1
  9. {selfdoc-0.4.1 → selfdoc-0.4.2}/docs/index.md +4 -0
  10. selfdoc-0.4.2/package-lock.json +19 -0
  11. {selfdoc-0.4.1 → selfdoc-0.4.2}/package.json +1 -1
  12. {selfdoc-0.4.1 → selfdoc-0.4.2}/pyproject.toml +1 -1
  13. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/git.py +19 -2
  14. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_git.py +37 -9
  15. selfdoc-0.4.2/todo/generate-claude-readme.md +90 -0
  16. selfdoc-0.4.1/.rlsbl/version +0 -1
  17. selfdoc-0.4.1/.selfdoc/hashes/hashes.json +0 -1
  18. {selfdoc-0.4.1 → selfdoc-0.4.2}/.claude/settings.json +0 -0
  19. {selfdoc-0.4.1 → selfdoc-0.4.2}/.github/workflows/ci.yml +0 -0
  20. {selfdoc-0.4.1 → selfdoc-0.4.2}/.github/workflows/publish.yml +0 -0
  21. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.claude/settings.json +0 -0
  22. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.github/workflows/ci.yml +0 -0
  23. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.github/workflows/publish.yml +0 -0
  24. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.gitignore +0 -0
  25. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/changes/unreleased.jsonl +0 -0
  26. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/hooks/post-release.sh +0 -0
  27. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/hooks/pre-checks.sh +0 -0
  28. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/hooks/pre-release.sh +0 -0
  29. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/lint/go.toml +0 -0
  30. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/lint/npm.toml +0 -0
  31. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/.rlsbl/lint/python.toml +0 -0
  32. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/bases/CLAUDE.md +0 -0
  33. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.1.0.jsonl +0 -0
  34. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.1.0.md +0 -0
  35. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.2.0.jsonl +0 -0
  36. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.2.0.md +0 -0
  37. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.0.jsonl +0 -0
  38. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.0.md +0 -0
  39. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.1.jsonl +0 -0
  40. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.3.1.md +0 -0
  41. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.0.jsonl +0 -0
  42. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.0.md +0 -0
  43. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.1.jsonl +0 -0
  44. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/0.4.1.md +0 -0
  45. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/changes/unreleased.jsonl +0 -0
  46. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/config.json +0 -0
  47. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hashes.json +0 -0
  48. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hooks/post-release.sh +0 -0
  49. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hooks/pre-checks.sh +0 -0
  50. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/hooks/pre-release.sh +0 -0
  51. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/lint/go.toml +0 -0
  52. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/lint/npm.toml +0 -0
  53. {selfdoc-0.4.1 → selfdoc-0.4.2}/.rlsbl/lint/python.toml +0 -0
  54. {selfdoc-0.4.1 → selfdoc-0.4.2}/CLAUDE.md +0 -0
  55. {selfdoc-0.4.1 → selfdoc-0.4.2}/LICENSE +0 -0
  56. {selfdoc-0.4.1 → selfdoc-0.4.2}/README.md +0 -0
  57. {selfdoc-0.4.1 → selfdoc-0.4.2}/bin/cli.js +0 -0
  58. {selfdoc-0.4.1 → selfdoc-0.4.2}/demo/index.html +0 -0
  59. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/__init__.py +0 -0
  60. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/__main__.py +0 -0
  61. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/build.py +0 -0
  62. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/catalog.py +0 -0
  63. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/check.py +0 -0
  64. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/cli.py +0 -0
  65. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/config.py +0 -0
  66. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/content.py +0 -0
  67. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/deploy.py +0 -0
  68. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/directives.py +0 -0
  69. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/__init__.py +0 -0
  70. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/base.py +0 -0
  71. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/go.py +0 -0
  72. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/protocol.py +0 -0
  73. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/python.py +0 -0
  74. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/extractors/typescript.py +0 -0
  75. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/gen.py +0 -0
  76. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/gendata.py +0 -0
  77. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/html.py +0 -0
  78. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/resolver.py +0 -0
  79. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/staleness.py +0 -0
  80. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/strictcli_support.py +0 -0
  81. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/__init__.py +0 -0
  82. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/clean.css +0 -0
  83. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/clean.json +0 -0
  84. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/minimal.css +0 -0
  85. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/themes/minimal.json +0 -0
  86. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc/tokenizer.py +0 -0
  87. {selfdoc-0.4.1 → selfdoc-0.4.2}/selfdoc.json +0 -0
  88. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_build.py +0 -0
  89. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_catalog.py +0 -0
  90. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_check.py +0 -0
  91. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_cli.py +0 -0
  92. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_config.py +0 -0
  93. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_content.py +0 -0
  94. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_contrast.py +0 -0
  95. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_custom_directives.py +0 -0
  96. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_demo_panel.py +0 -0
  97. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_directives.py +0 -0
  98. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_extractors_protocol.py +0 -0
  99. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_gen.py +0 -0
  100. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_gendata.py +0 -0
  101. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_go_extractor.py +0 -0
  102. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_h1.py +0 -0
  103. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_python_extractor.py +0 -0
  104. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_search.py +0 -0
  105. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_staleness.py +0 -0
  106. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_strictcli_support.py +0 -0
  107. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_token_migration.py +0 -0
  108. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_tokenizer.py +0 -0
  109. {selfdoc-0.4.1 → selfdoc-0.4.2}/tests/test_ts_extractor.py +0 -0
  110. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/auto-commit-hashes.md +0 -0
  111. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/auto-generated-glossary.md +0 -0
  112. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/auto-generation-gaps.md +0 -0
  113. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/changelog-page.md +0 -0
  114. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/coverage-go-typescript.md +0 -0
  115. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/cross-page-term-linking.md +0 -0
  116. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/lint-ignores-code-blocks.md +0 -0
  117. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/reading-progress.md +0 -0
  118. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/seo-geo-audit.md +0 -0
  119. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/seo-linting-gaps.md +0 -0
  120. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/sticky-table-column.md +0 -0
  121. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/.done/styling-and-release.md +0 -0
  122. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/atom-feed-filtering.md +0 -0
  123. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/brotli-dependency.md +0 -0
  124. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/css-redesign.md +0 -0
  125. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/gen-cli-descriptions.md +0 -0
  126. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/glossary-config-opt-in.md +0 -0
  127. {selfdoc-0.4.1 → selfdoc-0.4.2}/todo/sticky-column-striped-rows.md +0 -0
  128. {selfdoc-0.4.1 → selfdoc-0.4.2}/uv.lock +0 -0
@@ -38,4 +38,3 @@ docs/_build/
38
38
  .env
39
39
  .env.local
40
40
  *.local-only
41
- .rlsbl/changes/.validated
@@ -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,5 @@
1
+ ## 0.4.2
2
+
3
+ ### Features
4
+
5
+ - Auto-commit prefers rlsbl commit when available, marking commits with Autogenerated trailer for changelog coverage exemption
@@ -0,0 +1 @@
1
+ 0.31.0
@@ -0,0 +1,6 @@
1
+ {
2
+ "index.md": {
3
+ "content": "bceb3fbd27e158d132823cb8543c6fb4f3bf94d1bbe26a9429b3dec40181218e",
4
+ "description": "38b00bed9f2aee5284aee36a1e9d04a60a04edd8e8bcc5f17df5aa856544799f"
5
+ }
6
+ }
@@ -2,6 +2,12 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## 0.4.2
6
+
7
+ ### Features
8
+
9
+ - Auto-commit prefers rlsbl commit when available, marking commits with Autogenerated trailer for changelog coverage exemption
10
+
5
11
  ## 0.4.1
6
12
 
7
13
  - No user-facing changes.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: selfdoc
3
- Version: 0.4.1
3
+ Version: 0.4.2
4
4
  Summary: Code-aware static site generator with directive-based content extraction
5
5
  Project-URL: Repository, https://github.com/smm-h/selfdoc
6
6
  Author: smm-h
@@ -1,3 +1,7 @@
1
+ ---
2
+ description: "selfdoc auto-generates API documentation from source code using inline directives. Supports Python, Go, and TypeScript extractors."
3
+ ---
4
+
1
5
  # selfdoc
2
6
 
3
7
  Auto-generate API documentation from source code using inline directives
@@ -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
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selfdocumenting",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "Code-aware static site generator with directive-based content extraction",
5
5
  "bin": {
6
6
  "selfdoc": "bin/cli.js"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "selfdoc"
3
- version = "0.4.1"
3
+ version = "0.4.2"
4
4
  description = "Code-aware static site generator with directive-based content extraction"
5
5
  license = "MIT"
6
6
  authors = [{ name = "smm-h" }]
@@ -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 safegit first, fall back to plain git
108
- if shutil.which("safegit"):
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 it is on PATH."""
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
- with mock.patch("shutil.which", return_value="/usr/bin/safegit"):
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 "safegit" in last_call[0][0][0]
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 not available."""
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.
@@ -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