autodoc-docs 0.3.1__py3-none-any.whl

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 (43) hide show
  1. autodoc/__init__.py +20 -0
  2. autodoc/__main__.py +5 -0
  3. autodoc/cli.py +282 -0
  4. autodoc_docs-0.3.1.data/data/share/autodoc/CATALOG-A/INDEX.yaml +6687 -0
  5. autodoc_docs-0.3.1.data/data/share/autodoc/CATALOG-B/INDEX.yaml +1886 -0
  6. autodoc_docs-0.3.1.data/data/share/autodoc/CATALOG-C/INDEX.yaml +36 -0
  7. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/BASELINE-SCHEMA.json +30 -0
  8. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/CATALOG-RULES.json +956 -0
  9. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/CATALOG-SCHEMA.json +246 -0
  10. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/CONTEXT-MODEL.json +422 -0
  11. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/CONTEXT-SCHEMA.json +145 -0
  12. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/FRONT-MATTER-SCHEMA.json +29 -0
  13. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/MASTER-INDEX.json +565 -0
  14. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/OWNERSHIP-MATRIX.yaml +11 -0
  15. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/PROFILES.json +1 -0
  16. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/RELATIONSHIP-GRAPH.yaml +112 -0
  17. autodoc_docs-0.3.1.data/data/share/autodoc/CONTROL/metadata/TRIGGERS.json +190 -0
  18. autodoc_docs-0.3.1.data/data/share/autodoc/engine/__init__.py +1 -0
  19. autodoc_docs-0.3.1.data/data/share/autodoc/engine/extractors/__init__.py +1 -0
  20. autodoc_docs-0.3.1.data/data/share/autodoc/engine/extractors/env_alerts.py +60 -0
  21. autodoc_docs-0.3.1.data/data/share/autodoc/engine/extractors/facts.py +178 -0
  22. autodoc_docs-0.3.1.data/data/share/autodoc/engine/extractors/local_policy.py +17 -0
  23. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/add-document.py +175 -0
  24. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/adopt.py +49 -0
  25. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/doc-control/check_catalog.py +511 -0
  26. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/doc-control/guards.py +89 -0
  27. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/doc-control/library.py +260 -0
  28. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/doc-control/stub_check.py +250 -0
  29. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/doc-sync/engine.py +916 -0
  30. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/doc-sync/languages.py +461 -0
  31. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/init-project.py +109 -0
  32. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/intelligence/context.py +414 -0
  33. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/intelligence/enforce.py +490 -0
  34. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/intelligence/evolve.py +405 -0
  35. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/intelligence/profile.py +592 -0
  36. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/intelligence/promote.py +334 -0
  37. autodoc_docs-0.3.1.data/data/share/autodoc/scripts/intelligence/recommend.py +861 -0
  38. autodoc_docs-0.3.1.dist-info/METADATA +178 -0
  39. autodoc_docs-0.3.1.dist-info/RECORD +43 -0
  40. autodoc_docs-0.3.1.dist-info/WHEEL +5 -0
  41. autodoc_docs-0.3.1.dist-info/entry_points.txt +2 -0
  42. autodoc_docs-0.3.1.dist-info/licenses/LICENSE +202 -0
  43. autodoc_docs-0.3.1.dist-info/top_level.txt +1 -0
autodoc/__init__.py ADDED
@@ -0,0 +1,20 @@
1
+ """AutoDOC's installable command-line interface."""
2
+
3
+ from importlib.metadata import PackageNotFoundError, version
4
+ from pathlib import Path
5
+ import tomllib
6
+
7
+ try:
8
+ try:
9
+ __version__ = version("autodoc-docs")
10
+ except PackageNotFoundError:
11
+ __version__ = version("autodoc")
12
+ except PackageNotFoundError: # source checkout without installed distribution metadata
13
+ try:
14
+ project_file = Path(__file__).resolve().parents[1] / "pyproject.toml"
15
+ with project_file.open("rb") as stream:
16
+ __version__ = tomllib.load(stream)["project"]["version"]
17
+ except (OSError, KeyError, tomllib.TOMLDecodeError):
18
+ __version__ = "0+unknown"
19
+
20
+ __all__ = ["__version__"]
autodoc/__main__.py ADDED
@@ -0,0 +1,5 @@
1
+ """Run AutoDOC with ``python -m autodoc``."""
2
+
3
+ from .cli import main
4
+
5
+ raise SystemExit(main())
autodoc/cli.py ADDED
@@ -0,0 +1,282 @@
1
+ """Small dependency-free CLI over AutoDOC's existing repository scripts.
2
+
3
+ The installed Python package is kept separate from the user project. The policy/data scripts live
4
+ under the distribution's ``share/autodoc`` data directory; ``--repo`` and ``--root`` always name
5
+ the project being inspected or generated.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import site
12
+ import subprocess
13
+ import sys
14
+ import sysconfig
15
+ from pathlib import Path
16
+ from typing import Sequence
17
+
18
+ from . import __version__
19
+
20
+
21
+ def runtime_root() -> Path:
22
+ """Locate the bundled AutoDOC scripts and policy data, never the target project.
23
+
24
+ An editable/source checkout is useful for development. Normal installs place data files under
25
+ ``sysconfig.get_path('data')/share/autodoc``; ``site.USER_BASE`` covers ``pip install --user``.
26
+ """
27
+ candidates: list[Path] = [Path(__file__).resolve().parents[1]]
28
+ data_directory = sysconfig.get_path("data")
29
+ if data_directory:
30
+ candidates.append(Path(data_directory) / "share" / "autodoc")
31
+ if site.USER_BASE:
32
+ candidates.append(Path(site.USER_BASE) / "share" / "autodoc")
33
+
34
+ required = (
35
+ "scripts/intelligence/enforce.py",
36
+ "scripts/intelligence/evolve.py",
37
+ "scripts/intelligence/promote.py",
38
+ "scripts/doc-sync/engine.py",
39
+ "scripts/doc-control/library.py",
40
+ "scripts/add-document.py",
41
+ "scripts/init-project.py",
42
+ "scripts/adopt.py",
43
+ "engine/extractors/facts.py",
44
+ "CONTROL/metadata/CONTEXT-MODEL.json",
45
+ "CATALOG-A/INDEX.yaml",
46
+ "CATALOG-B/INDEX.yaml",
47
+ )
48
+ checked: set[Path] = set()
49
+ for candidate in candidates:
50
+ candidate = candidate.resolve()
51
+ if candidate in checked:
52
+ continue
53
+ checked.add(candidate)
54
+ if all((candidate / relative).is_file() for relative in required):
55
+ return candidate
56
+
57
+ raise RuntimeError(
58
+ "AutoDOC runtime files are missing. Reinstall the complete AutoDOC distribution; "
59
+ "the target project is not a substitute for the installed tool assets."
60
+ )
61
+
62
+
63
+ def _add_check_arguments(parser: argparse.ArgumentParser) -> None:
64
+ parser.add_argument(
65
+ "--repo", type=Path, default=Path.cwd(),
66
+ help="project to inspect (default: current directory)",
67
+ )
68
+ parser.add_argument("--config", type=Path, help="context TOML (default: <repo>/autodoc.toml)")
69
+ parser.add_argument("--baseline", type=Path, help="baseline JSON (default: <repo>/autodoc-baseline.json)")
70
+ parser.add_argument("--write-baseline", action="store_true", help="record current findings as a baseline")
71
+ parser.add_argument("--fail-on-stale", action="store_true", help="fail when old baseline entries no longer match")
72
+ parser.add_argument("--json", action="store_true", help="print a machine-readable JSON report")
73
+ parser.add_argument("--output", type=Path, help="write the report to this file instead of stdout")
74
+
75
+
76
+ def build_parser() -> argparse.ArgumentParser:
77
+ parser = argparse.ArgumentParser(
78
+ prog="autodoc",
79
+ description="Installable CLI for AutoDOC's bounded documentation checks and generators.",
80
+ )
81
+ parser.add_argument("--version", action="version", version=f"%(prog)s {__version__}")
82
+ commands = parser.add_subparsers(dest="command", required=True)
83
+
84
+ check = commands.add_parser("check", help="check a project using its declared context and baseline")
85
+ _add_check_arguments(check)
86
+
87
+ generate = commands.add_parser("generate", help="generate mapped factual documents for a project")
88
+ generate.add_argument(
89
+ "--root", type=Path, default=Path.cwd(),
90
+ help="project containing docs/.doc-sync-map.yaml (default: current directory)",
91
+ )
92
+ generate.add_argument("--check", action="store_true", help="check for drift without writing files")
93
+ generate.add_argument("--only", help="run one generator ID from the project's sync map")
94
+
95
+ adopt = commands.add_parser("adopt", help="read-only heuristic scan for potentially relevant catalog domains")
96
+ adopt.add_argument("--project-path", type=Path, default=Path.cwd(), help="project to scan (default: current directory)")
97
+
98
+ init = commands.add_parser("init", help="scaffold starter documents in an existing project")
99
+ init.add_argument("--name", required=True, help="project name")
100
+ init.add_argument(
101
+ "--type", default="generic", choices=["generic", "web-api", "cli", "library", "ai-agent"],
102
+ help="project type recorded in scaffold prompts (default: generic)",
103
+ )
104
+ init.add_argument("--output", type=Path, default=Path.cwd(), help="existing project directory (default: current directory)")
105
+ init.add_argument("--phase", help="declare the initial phase in autodoc.toml")
106
+ init.add_argument("--profile", help="declare the catalog profile in autodoc.toml")
107
+
108
+ add = commands.add_parser("add", help="instantiate one catalog document in a project")
109
+ add.add_argument("document", help="catalog type id, for example DOC-A03-001")
110
+ add.add_argument(
111
+ "--root", type=Path, default=Path.cwd(),
112
+ help="project receiving the document (default: current directory)",
113
+ )
114
+ add.add_argument("--output", type=Path, help="exact file, relative to --root unless absolute")
115
+ add.add_argument(
116
+ "--variant", choices=["canonical", "blank", "example"], default="canonical",
117
+ help="template variant to instantiate (default: canonical)",
118
+ )
119
+ add.add_argument("--instance", dest="instance_id", help="frontmatter instance id")
120
+ add.add_argument("--write", action="store_true", help="write the file instead of previewing")
121
+ add.add_argument("--force", action="store_true", help="allow replacing an existing file")
122
+ add.add_argument("--json", action="store_true", help="print a machine-readable result")
123
+
124
+ promote = commands.add_parser("promote", help="preview or apply a declared phase promotion")
125
+ promote.add_argument("--repo", type=Path, default=Path.cwd(),
126
+ help="repository whose facts are evaluated (default: current directory)")
127
+ promote.add_argument("--config", type=Path, help="context TOML (default: <repo>/autodoc.toml)")
128
+ promote.add_argument("--to", required=True, help="target phase id")
129
+ promote.add_argument("--date", help="declaration date in YYYY-MM-DD (default: today)")
130
+ promote.add_argument("--write", action="store_true", help="apply the promotion instead of previewing")
131
+ promote.add_argument("--force", action="store_true",
132
+ help="allow a demotion, backdate or write with missing required documents")
133
+ promote.add_argument("--json", action="store_true", help="print a machine-readable result")
134
+
135
+ evolve = commands.add_parser("evolve", help="plan safe documentation updates for a project")
136
+ evolve.add_argument("--repo", type=Path, default=Path.cwd(),
137
+ help="project to evolve (default: current directory)")
138
+ evolve.add_argument("--config", type=Path, help="context TOML (default: <repo>/autodoc.toml)")
139
+ evolve.add_argument("--baseline", type=Path,
140
+ help="baseline JSON (default: <repo>/autodoc-baseline.json)")
141
+ evolve.add_argument("--write", action="store_true",
142
+ help="apply safe actions (generated refresh, and drafts with --allow-add)")
143
+ evolve.add_argument("--allow-add", action="store_true",
144
+ help="with --write, create missing required documents as drafts")
145
+ evolve.add_argument("--check", action="store_true",
146
+ help="exit 1 when an action is pending, without writing")
147
+ evolve.add_argument("--json", action="store_true", help="print a machine-readable plan")
148
+
149
+ templates = commands.add_parser("templates", help="render catalog templates on demand into a project build directory")
150
+ templates.add_argument(
151
+ "--root", type=Path, default=Path.cwd(),
152
+ help="project receiving rendered files (default: current directory)",
153
+ )
154
+ templates.add_argument(
155
+ "--output", type=Path,
156
+ help="output tree root (default: <root>/build/TEMPLATES)",
157
+ )
158
+ templates.add_argument(
159
+ "--variant", choices=["all", "canonical", "blank", "example"], default="all",
160
+ help="variant to render (default: all three)",
161
+ )
162
+ return parser
163
+
164
+
165
+ def _absolute_directory(parser: argparse.ArgumentParser, value: Path, option: str) -> Path:
166
+ directory = value.expanduser().resolve()
167
+ if not directory.is_dir():
168
+ parser.error(f"{option} must be an existing directory: {directory}")
169
+ return directory
170
+
171
+
172
+ def _absolute_file(value: Path) -> Path:
173
+ return value.expanduser().resolve()
174
+
175
+
176
+ def _run_script(script: Path, arguments: Sequence[str]) -> int:
177
+ """Execute an existing script with the same interpreter and preserve its exit code."""
178
+ try:
179
+ return subprocess.run(
180
+ [sys.executable, str(script), *arguments],
181
+ check=False,
182
+ ).returncode
183
+ except OSError as error:
184
+ print(f"AutoDOC could not start {script.name}: {error}", file=sys.stderr)
185
+ return 2
186
+
187
+
188
+ def main(argv: Sequence[str] | None = None) -> int:
189
+ parser = build_parser()
190
+ args = parser.parse_args(argv)
191
+ try:
192
+ tool_root = runtime_root()
193
+ except RuntimeError as error:
194
+ print(f"AutoDOC error: {error}", file=sys.stderr)
195
+ return 2
196
+
197
+ if args.command == "check":
198
+ project = _absolute_directory(parser, args.repo, "--repo")
199
+ command = ["--repo", str(project)]
200
+ for option in ("config", "baseline", "output"):
201
+ value = getattr(args, option)
202
+ if value is not None:
203
+ command.extend(("--" + option, str(_absolute_file(value))))
204
+ for option in ("write_baseline", "fail_on_stale", "json"):
205
+ if getattr(args, option):
206
+ command.append("--" + option.replace("_", "-"))
207
+ return _run_script(tool_root / "scripts/intelligence/enforce.py", command)
208
+
209
+ if args.command == "generate":
210
+ project = _absolute_directory(parser, args.root, "--root")
211
+ command = ["generate", "--root", str(project)]
212
+ if args.check:
213
+ command.append("--check")
214
+ if args.only:
215
+ command.extend(("--only", args.only))
216
+ return _run_script(tool_root / "scripts/doc-sync/engine.py", command)
217
+
218
+ if args.command == "adopt":
219
+ project = _absolute_directory(parser, args.project_path, "--project-path")
220
+ return _run_script(tool_root / "scripts/adopt.py", ["--project-path", str(project)])
221
+
222
+ if args.command == "init":
223
+ project = _absolute_directory(parser, args.output, "--output")
224
+ command = ["--name", args.name, "--type", args.type, "--output", str(project)]
225
+ if args.phase:
226
+ command.extend(("--phase", args.phase))
227
+ if args.profile:
228
+ command.extend(("--profile", args.profile))
229
+ return _run_script(tool_root / "scripts/init-project.py", command)
230
+
231
+ if args.command == "add":
232
+ project = _absolute_directory(parser, args.root, "--root")
233
+ command = [args.document, "--root", str(project), "--variant", args.variant]
234
+ if args.output is not None:
235
+ command.extend(("--output", str(args.output)))
236
+ if args.instance_id:
237
+ command.extend(("--instance", args.instance_id))
238
+ for option in ("write", "force", "json"):
239
+ if getattr(args, option):
240
+ command.append("--" + option)
241
+ return _run_script(tool_root / "scripts/add-document.py", command)
242
+
243
+ if args.command == "promote":
244
+ project = _absolute_directory(parser, args.repo, "--repo")
245
+ command = ["--repo", str(project), "--to", args.to]
246
+ if args.config is not None:
247
+ command.extend(("--config", str(_absolute_file(args.config))))
248
+ if args.date:
249
+ command.extend(("--date", args.date))
250
+ for option in ("write", "force", "json"):
251
+ if getattr(args, option):
252
+ command.append("--" + option)
253
+ return _run_script(tool_root / "scripts/intelligence/promote.py", command)
254
+
255
+ if args.command == "evolve":
256
+ project = _absolute_directory(parser, args.repo, "--repo")
257
+ command = ["--repo", str(project)]
258
+ for option in ("config", "baseline"):
259
+ value = getattr(args, option)
260
+ if value is not None:
261
+ command.extend(("--" + option, str(_absolute_file(value))))
262
+ for option in ("write", "allow_add", "check", "json"):
263
+ if getattr(args, option):
264
+ command.append("--" + option.replace("_", "-"))
265
+ return _run_script(tool_root / "scripts/intelligence/evolve.py", command)
266
+
267
+ if args.command == "templates":
268
+ project = _absolute_directory(parser, args.root, "--root")
269
+ if args.output is None:
270
+ destination = project / "build" / "TEMPLATES"
271
+ else:
272
+ destination = args.output.expanduser()
273
+ if not destination.is_absolute():
274
+ destination = project / destination
275
+ destination = destination.resolve()
276
+ return _run_script(
277
+ tool_root / "scripts/doc-control/library.py",
278
+ ["--variant", args.variant, "--output-dir", str(destination)],
279
+ )
280
+
281
+ parser.error(f"unknown command: {args.command}")
282
+ return 2