lark-doc-exporter 0.1.0__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 (29) hide show
  1. lark_doc_exporter-0.1.0/PKG-INFO +134 -0
  2. lark_doc_exporter-0.1.0/README.md +125 -0
  3. lark_doc_exporter-0.1.0/pyproject.toml +41 -0
  4. lark_doc_exporter-0.1.0/setup.cfg +4 -0
  5. lark_doc_exporter-0.1.0/src/lark_doc_exporter.egg-info/PKG-INFO +134 -0
  6. lark_doc_exporter-0.1.0/src/lark_doc_exporter.egg-info/SOURCES.txt +27 -0
  7. lark_doc_exporter-0.1.0/src/lark_doc_exporter.egg-info/dependency_links.txt +1 -0
  8. lark_doc_exporter-0.1.0/src/lark_doc_exporter.egg-info/entry_points.txt +2 -0
  9. lark_doc_exporter-0.1.0/src/lark_doc_exporter.egg-info/requires.txt +2 -0
  10. lark_doc_exporter-0.1.0/src/lark_doc_exporter.egg-info/top_level.txt +1 -0
  11. lark_doc_exporter-0.1.0/src/lark_synced_export/__init__.py +5 -0
  12. lark_doc_exporter-0.1.0/src/lark_synced_export/__main__.py +5 -0
  13. lark_doc_exporter-0.1.0/src/lark_synced_export/cli.py +146 -0
  14. lark_doc_exporter-0.1.0/src/lark_synced_export/doctor.py +56 -0
  15. lark_doc_exporter-0.1.0/src/lark_synced_export/exporter.py +550 -0
  16. lark_doc_exporter-0.1.0/src/lark_synced_export/markdown_runtime.py +42 -0
  17. lark_doc_exporter-0.1.0/src/lark_synced_export/pdf_runtime.py +76 -0
  18. lark_doc_exporter-0.1.0/src/lark_synced_export/release_version.py +97 -0
  19. lark_doc_exporter-0.1.0/src/lark_synced_export/skill_assets/lark-doc-exporter/SKILL.md +61 -0
  20. lark_doc_exporter-0.1.0/src/lark_synced_export/skill_install.py +288 -0
  21. lark_doc_exporter-0.1.0/src/lark_synced_export/themes/company.css +31 -0
  22. lark_doc_exporter-0.1.0/src/lark_synced_export/themes/default.css +16 -0
  23. lark_doc_exporter-0.1.0/tests/test_doctor.py +54 -0
  24. lark_doc_exporter-0.1.0/tests/test_exporter.py +111 -0
  25. lark_doc_exporter-0.1.0/tests/test_markdown_runtime.py +61 -0
  26. lark_doc_exporter-0.1.0/tests/test_pdf_runtime.py +112 -0
  27. lark_doc_exporter-0.1.0/tests/test_release_version.py +65 -0
  28. lark_doc_exporter-0.1.0/tests/test_skill_install.py +314 -0
  29. lark_doc_exporter-0.1.0/tests/test_theme_resolution.py +7 -0
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: lark-doc-exporter
3
+ Version: 0.1.0
4
+ Summary: Export Feishu/Lark docs with synced blocks to Markdown and themeable PDF
5
+ Requires-Python: >=3.14
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: markdown<4,>=3.7
8
+ Requires-Dist: playwright<2,>=1.54
9
+
10
+ # lark-doc-exporter
11
+
12
+ Export Feishu/Lark docs with synced blocks expanded into:
13
+
14
+ - Markdown with localized images
15
+ - Themeable locally rendered PDF
16
+
17
+ The PDF path deliberately avoids the Feishu `docs_ai -> export pdf` route so the
18
+ final file does not include the AI disclaimer injected by that server-side path.
19
+
20
+ ## Requirements
21
+
22
+ - `lark-cli` configured with a user session
23
+ - Python 3.14
24
+ - A working Chrome/Chromium runtime, or the ability to install one with `uvx --from playwright playwright install chromium`
25
+
26
+ If you use `uvx` / `uv tool install`, `uv` can provision the required Python for
27
+ the tool environment automatically.
28
+
29
+ ## Quick Start
30
+
31
+ ```bash
32
+ uv tool install lark-doc-exporter
33
+ lark-doc-exporter doctor
34
+ ```
35
+
36
+ If Chromium is missing, prepare it once:
37
+
38
+ ```bash
39
+ uvx --from playwright playwright install chromium
40
+ ```
41
+
42
+ Then run an export:
43
+
44
+ ```bash
45
+ lark-doc-exporter \
46
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
47
+ --output-dir exports/demo \
48
+ --formats markdown,pdf \
49
+ --theme default
50
+ ```
51
+
52
+ ## One-off Run
53
+
54
+ If you do not want a persistent tool install:
55
+
56
+ ```bash
57
+ uvx lark-doc-exporter \
58
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
59
+ --output-dir exports/demo \
60
+ --formats markdown,pdf \
61
+ --theme default
62
+ ```
63
+
64
+ ## Install As A Tool
65
+
66
+ After installing the released package, companion-skill operations stay the same:
67
+
68
+ ```bash
69
+ lark-doc-exporter skill install --dry-run
70
+ lark-doc-exporter skill install
71
+ ```
72
+
73
+ Auto mode installs the companion skill into every detected supported host:
74
+
75
+ - Codex: `~/.agents/skills/lark-doc-exporter`
76
+ - Claude Code: `~/.claude/skills/lark-doc-exporter`
77
+
78
+ Use `--host codex`, `--host claude`, or `--host all` to target specific hosts. `--dry-run` previews the install plan and target directories without writing files. Use `--force` only when you intentionally want to replace an existing unmanaged target directory.
79
+
80
+ ## Chromium Setup
81
+
82
+ - `doctor` reports whether both `lark-cli` and Chromium are ready.
83
+ - If you already have a browser binary, you can point the exporter at it with `LARK_DOC_EXPORTER_CHROMIUM=/path/to/chromium`.
84
+ - If `LARK_DOC_EXPORTER_CHROMIUM` is set to a missing path, the command fails explicitly instead of silently falling back.
85
+
86
+ ## Output
87
+
88
+ - `markdown` keeps the localized Markdown file in the output directory.
89
+ - `pdf` is rendered locally from the localized Markdown via HTML/CSS + Chromium.
90
+ - `images/` contains same-run localized image assets used by the Markdown/PDF.
91
+
92
+ ## Themes
93
+
94
+ Built-in themes:
95
+
96
+ - `default`
97
+ - `company`
98
+
99
+ You can also layer custom CSS on top:
100
+
101
+ ```bash
102
+ lark-doc-exporter \
103
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
104
+ --output-dir exports/company \
105
+ --formats pdf \
106
+ --theme company \
107
+ --css /path/to/your-company-print.css
108
+ ```
109
+
110
+ ## Development / Unreleased
111
+
112
+ Use the Git URL or a local checkout only when you intentionally need unreleased code:
113
+
114
+ ```bash
115
+ uvx --from git+https://github.com/spencercjh/lark-doc-exporter lark-doc-exporter doctor
116
+
117
+ git clone https://github.com/spencercjh/lark-doc-exporter
118
+ cd lark-doc-exporter
119
+ uv sync --python 3.14 --group dev
120
+ make fmt
121
+ make ci
122
+
123
+ # Optional runtime/environment check (not part of required CI)
124
+ uv run lark-doc-exporter doctor
125
+ ```
126
+
127
+ ## Notes
128
+
129
+ - The current implementation still uses a temporary Feishu doc to translate the
130
+ expanded XML into fresh Markdown.
131
+ - The temporary doc is deleted by default after the Markdown export step. Use
132
+ `--keep-temp-doc` only when you need to inspect that intermediate document.
133
+ - Feishu image `authcode` URLs expire quickly, so image localization happens in
134
+ the same run as the Markdown export.
@@ -0,0 +1,125 @@
1
+ # lark-doc-exporter
2
+
3
+ Export Feishu/Lark docs with synced blocks expanded into:
4
+
5
+ - Markdown with localized images
6
+ - Themeable locally rendered PDF
7
+
8
+ The PDF path deliberately avoids the Feishu `docs_ai -> export pdf` route so the
9
+ final file does not include the AI disclaimer injected by that server-side path.
10
+
11
+ ## Requirements
12
+
13
+ - `lark-cli` configured with a user session
14
+ - Python 3.14
15
+ - A working Chrome/Chromium runtime, or the ability to install one with `uvx --from playwright playwright install chromium`
16
+
17
+ If you use `uvx` / `uv tool install`, `uv` can provision the required Python for
18
+ the tool environment automatically.
19
+
20
+ ## Quick Start
21
+
22
+ ```bash
23
+ uv tool install lark-doc-exporter
24
+ lark-doc-exporter doctor
25
+ ```
26
+
27
+ If Chromium is missing, prepare it once:
28
+
29
+ ```bash
30
+ uvx --from playwright playwright install chromium
31
+ ```
32
+
33
+ Then run an export:
34
+
35
+ ```bash
36
+ lark-doc-exporter \
37
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
38
+ --output-dir exports/demo \
39
+ --formats markdown,pdf \
40
+ --theme default
41
+ ```
42
+
43
+ ## One-off Run
44
+
45
+ If you do not want a persistent tool install:
46
+
47
+ ```bash
48
+ uvx lark-doc-exporter \
49
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
50
+ --output-dir exports/demo \
51
+ --formats markdown,pdf \
52
+ --theme default
53
+ ```
54
+
55
+ ## Install As A Tool
56
+
57
+ After installing the released package, companion-skill operations stay the same:
58
+
59
+ ```bash
60
+ lark-doc-exporter skill install --dry-run
61
+ lark-doc-exporter skill install
62
+ ```
63
+
64
+ Auto mode installs the companion skill into every detected supported host:
65
+
66
+ - Codex: `~/.agents/skills/lark-doc-exporter`
67
+ - Claude Code: `~/.claude/skills/lark-doc-exporter`
68
+
69
+ Use `--host codex`, `--host claude`, or `--host all` to target specific hosts. `--dry-run` previews the install plan and target directories without writing files. Use `--force` only when you intentionally want to replace an existing unmanaged target directory.
70
+
71
+ ## Chromium Setup
72
+
73
+ - `doctor` reports whether both `lark-cli` and Chromium are ready.
74
+ - If you already have a browser binary, you can point the exporter at it with `LARK_DOC_EXPORTER_CHROMIUM=/path/to/chromium`.
75
+ - If `LARK_DOC_EXPORTER_CHROMIUM` is set to a missing path, the command fails explicitly instead of silently falling back.
76
+
77
+ ## Output
78
+
79
+ - `markdown` keeps the localized Markdown file in the output directory.
80
+ - `pdf` is rendered locally from the localized Markdown via HTML/CSS + Chromium.
81
+ - `images/` contains same-run localized image assets used by the Markdown/PDF.
82
+
83
+ ## Themes
84
+
85
+ Built-in themes:
86
+
87
+ - `default`
88
+ - `company`
89
+
90
+ You can also layer custom CSS on top:
91
+
92
+ ```bash
93
+ lark-doc-exporter \
94
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
95
+ --output-dir exports/company \
96
+ --formats pdf \
97
+ --theme company \
98
+ --css /path/to/your-company-print.css
99
+ ```
100
+
101
+ ## Development / Unreleased
102
+
103
+ Use the Git URL or a local checkout only when you intentionally need unreleased code:
104
+
105
+ ```bash
106
+ uvx --from git+https://github.com/spencercjh/lark-doc-exporter lark-doc-exporter doctor
107
+
108
+ git clone https://github.com/spencercjh/lark-doc-exporter
109
+ cd lark-doc-exporter
110
+ uv sync --python 3.14 --group dev
111
+ make fmt
112
+ make ci
113
+
114
+ # Optional runtime/environment check (not part of required CI)
115
+ uv run lark-doc-exporter doctor
116
+ ```
117
+
118
+ ## Notes
119
+
120
+ - The current implementation still uses a temporary Feishu doc to translate the
121
+ expanded XML into fresh Markdown.
122
+ - The temporary doc is deleted by default after the Markdown export step. Use
123
+ `--keep-temp-doc` only when you need to inspect that intermediate document.
124
+ - Feishu image `authcode` URLs expire quickly, so image localization happens in
125
+ the same run as the Markdown export.
@@ -0,0 +1,41 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "lark-doc-exporter"
7
+ version = "0.1.0"
8
+ description = "Export Feishu/Lark docs with synced blocks to Markdown and themeable PDF"
9
+ readme = "README.md"
10
+ requires-python = ">=3.14"
11
+ dependencies = [
12
+ "markdown>=3.7,<4",
13
+ "playwright>=1.54,<2",
14
+ ]
15
+
16
+ [project.scripts]
17
+ lark-doc-exporter = "lark_synced_export.cli:main"
18
+
19
+ [dependency-groups]
20
+ dev = [
21
+ "pytest>=9,<10",
22
+ "ruff>=0.12,<1",
23
+ ]
24
+
25
+ [tool.ruff]
26
+ target-version = "py314"
27
+
28
+ [tool.setuptools]
29
+ package-dir = {"" = "src"}
30
+
31
+ [tool.setuptools.packages.find]
32
+ where = ["src"]
33
+
34
+ [tool.setuptools.package-data]
35
+ lark_synced_export = [
36
+ "themes/*.css",
37
+ "skill_assets/lark-doc-exporter/SKILL.md",
38
+ ]
39
+
40
+ [tool.pytest.ini_options]
41
+ pythonpath = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,134 @@
1
+ Metadata-Version: 2.4
2
+ Name: lark-doc-exporter
3
+ Version: 0.1.0
4
+ Summary: Export Feishu/Lark docs with synced blocks to Markdown and themeable PDF
5
+ Requires-Python: >=3.14
6
+ Description-Content-Type: text/markdown
7
+ Requires-Dist: markdown<4,>=3.7
8
+ Requires-Dist: playwright<2,>=1.54
9
+
10
+ # lark-doc-exporter
11
+
12
+ Export Feishu/Lark docs with synced blocks expanded into:
13
+
14
+ - Markdown with localized images
15
+ - Themeable locally rendered PDF
16
+
17
+ The PDF path deliberately avoids the Feishu `docs_ai -> export pdf` route so the
18
+ final file does not include the AI disclaimer injected by that server-side path.
19
+
20
+ ## Requirements
21
+
22
+ - `lark-cli` configured with a user session
23
+ - Python 3.14
24
+ - A working Chrome/Chromium runtime, or the ability to install one with `uvx --from playwright playwright install chromium`
25
+
26
+ If you use `uvx` / `uv tool install`, `uv` can provision the required Python for
27
+ the tool environment automatically.
28
+
29
+ ## Quick Start
30
+
31
+ ```bash
32
+ uv tool install lark-doc-exporter
33
+ lark-doc-exporter doctor
34
+ ```
35
+
36
+ If Chromium is missing, prepare it once:
37
+
38
+ ```bash
39
+ uvx --from playwright playwright install chromium
40
+ ```
41
+
42
+ Then run an export:
43
+
44
+ ```bash
45
+ lark-doc-exporter \
46
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
47
+ --output-dir exports/demo \
48
+ --formats markdown,pdf \
49
+ --theme default
50
+ ```
51
+
52
+ ## One-off Run
53
+
54
+ If you do not want a persistent tool install:
55
+
56
+ ```bash
57
+ uvx lark-doc-exporter \
58
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
59
+ --output-dir exports/demo \
60
+ --formats markdown,pdf \
61
+ --theme default
62
+ ```
63
+
64
+ ## Install As A Tool
65
+
66
+ After installing the released package, companion-skill operations stay the same:
67
+
68
+ ```bash
69
+ lark-doc-exporter skill install --dry-run
70
+ lark-doc-exporter skill install
71
+ ```
72
+
73
+ Auto mode installs the companion skill into every detected supported host:
74
+
75
+ - Codex: `~/.agents/skills/lark-doc-exporter`
76
+ - Claude Code: `~/.claude/skills/lark-doc-exporter`
77
+
78
+ Use `--host codex`, `--host claude`, or `--host all` to target specific hosts. `--dry-run` previews the install plan and target directories without writing files. Use `--force` only when you intentionally want to replace an existing unmanaged target directory.
79
+
80
+ ## Chromium Setup
81
+
82
+ - `doctor` reports whether both `lark-cli` and Chromium are ready.
83
+ - If you already have a browser binary, you can point the exporter at it with `LARK_DOC_EXPORTER_CHROMIUM=/path/to/chromium`.
84
+ - If `LARK_DOC_EXPORTER_CHROMIUM` is set to a missing path, the command fails explicitly instead of silently falling back.
85
+
86
+ ## Output
87
+
88
+ - `markdown` keeps the localized Markdown file in the output directory.
89
+ - `pdf` is rendered locally from the localized Markdown via HTML/CSS + Chromium.
90
+ - `images/` contains same-run localized image assets used by the Markdown/PDF.
91
+
92
+ ## Themes
93
+
94
+ Built-in themes:
95
+
96
+ - `default`
97
+ - `company`
98
+
99
+ You can also layer custom CSS on top:
100
+
101
+ ```bash
102
+ lark-doc-exporter \
103
+ --doc "https://dynamia-ai.feishu.cn/wiki/WEgBwqGYOiBoQikRzjncvJDonAg" \
104
+ --output-dir exports/company \
105
+ --formats pdf \
106
+ --theme company \
107
+ --css /path/to/your-company-print.css
108
+ ```
109
+
110
+ ## Development / Unreleased
111
+
112
+ Use the Git URL or a local checkout only when you intentionally need unreleased code:
113
+
114
+ ```bash
115
+ uvx --from git+https://github.com/spencercjh/lark-doc-exporter lark-doc-exporter doctor
116
+
117
+ git clone https://github.com/spencercjh/lark-doc-exporter
118
+ cd lark-doc-exporter
119
+ uv sync --python 3.14 --group dev
120
+ make fmt
121
+ make ci
122
+
123
+ # Optional runtime/environment check (not part of required CI)
124
+ uv run lark-doc-exporter doctor
125
+ ```
126
+
127
+ ## Notes
128
+
129
+ - The current implementation still uses a temporary Feishu doc to translate the
130
+ expanded XML into fresh Markdown.
131
+ - The temporary doc is deleted by default after the Markdown export step. Use
132
+ `--keep-temp-doc` only when you need to inspect that intermediate document.
133
+ - Feishu image `authcode` URLs expire quickly, so image localization happens in
134
+ the same run as the Markdown export.
@@ -0,0 +1,27 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/lark_doc_exporter.egg-info/PKG-INFO
4
+ src/lark_doc_exporter.egg-info/SOURCES.txt
5
+ src/lark_doc_exporter.egg-info/dependency_links.txt
6
+ src/lark_doc_exporter.egg-info/entry_points.txt
7
+ src/lark_doc_exporter.egg-info/requires.txt
8
+ src/lark_doc_exporter.egg-info/top_level.txt
9
+ src/lark_synced_export/__init__.py
10
+ src/lark_synced_export/__main__.py
11
+ src/lark_synced_export/cli.py
12
+ src/lark_synced_export/doctor.py
13
+ src/lark_synced_export/exporter.py
14
+ src/lark_synced_export/markdown_runtime.py
15
+ src/lark_synced_export/pdf_runtime.py
16
+ src/lark_synced_export/release_version.py
17
+ src/lark_synced_export/skill_install.py
18
+ src/lark_synced_export/skill_assets/lark-doc-exporter/SKILL.md
19
+ src/lark_synced_export/themes/company.css
20
+ src/lark_synced_export/themes/default.css
21
+ tests/test_doctor.py
22
+ tests/test_exporter.py
23
+ tests/test_markdown_runtime.py
24
+ tests/test_pdf_runtime.py
25
+ tests/test_release_version.py
26
+ tests/test_skill_install.py
27
+ tests/test_theme_resolution.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ lark-doc-exporter = lark_synced_export.cli:main
@@ -0,0 +1,2 @@
1
+ markdown<4,>=3.7
2
+ playwright<2,>=1.54
@@ -0,0 +1 @@
1
+ lark_synced_export
@@ -0,0 +1,5 @@
1
+ """Standalone exporter for Feishu/Lark docs with synced blocks."""
2
+
3
+ __all__ = ["__version__"]
4
+
5
+ __version__ = "0.1.0"
@@ -0,0 +1,5 @@
1
+ from .cli import run_main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ raise SystemExit(run_main())
@@ -0,0 +1,146 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+ import json
5
+ import sys
6
+ from pathlib import Path
7
+
8
+ from .doctor import run_doctor
9
+ from .exporter import export_document
10
+ from .skill_install import run_skill_install
11
+
12
+
13
+ def parse_export_args(argv: list[str]) -> argparse.Namespace:
14
+ parser = argparse.ArgumentParser(
15
+ description="Expand Feishu/Lark synced blocks, export Markdown, and render local PDF.",
16
+ epilog=(
17
+ "Other commands:\n"
18
+ " doctor\n"
19
+ " skill install [--host {auto,codex,claude,all}] [--force] [--dry-run]"
20
+ ),
21
+ formatter_class=argparse.RawDescriptionHelpFormatter,
22
+ )
23
+ parser.add_argument(
24
+ "--doc",
25
+ required=True,
26
+ help="Original docx/wiki URL or token accepted by `lark-cli docs +fetch`.",
27
+ )
28
+ parser.add_argument(
29
+ "--output-dir", required=True, help="Directory for output artifacts."
30
+ )
31
+ parser.add_argument(
32
+ "--formats",
33
+ default="markdown,pdf",
34
+ help="Comma-separated export formats. Supported: markdown,pdf",
35
+ )
36
+ parser.add_argument(
37
+ "--title-suffix",
38
+ default="(同步块展开导出)",
39
+ help="Suffix appended to the temporary expanded doc title.",
40
+ )
41
+ parser.add_argument(
42
+ "--file-stem",
43
+ default="",
44
+ help="Optional output filename stem. Defaults to the expanded doc title slug.",
45
+ )
46
+ parser.add_argument(
47
+ "--keep-temp-doc",
48
+ action="store_true",
49
+ help="Keep the temporary expanded doc instead of deleting it after the Markdown export step.",
50
+ )
51
+ parser.add_argument(
52
+ "--theme",
53
+ default="default",
54
+ help="Built-in PDF theme name. Supported: default, company.",
55
+ )
56
+ parser.add_argument(
57
+ "--css",
58
+ default="",
59
+ help="Optional extra CSS file layered on top of the selected theme for PDF output.",
60
+ )
61
+ return parser.parse_args(argv)
62
+
63
+
64
+ def parse_skill_install_args(argv: list[str]) -> argparse.Namespace:
65
+ parser = argparse.ArgumentParser(
66
+ prog="lark-doc-exporter skill install",
67
+ description="Install the bundled companion skill into Codex and/or Claude Code.",
68
+ )
69
+ parser.add_argument(
70
+ "--host",
71
+ choices=["auto", "codex", "claude", "all"],
72
+ default="auto",
73
+ help="Install target selection. Auto mode uses only already-detected hosts.",
74
+ )
75
+ parser.add_argument(
76
+ "--force",
77
+ action="store_true",
78
+ help="Overwrite an existing unmanaged target directory.",
79
+ )
80
+ parser.add_argument(
81
+ "--dry-run",
82
+ action="store_true",
83
+ help="Show planned target paths without writing files.",
84
+ )
85
+ return parser.parse_args(argv)
86
+
87
+
88
+ def run_main(argv: list[str] | None = None) -> int:
89
+ argv = list(argv if argv is not None else sys.argv[1:])
90
+ if argv and argv[0] == "doctor":
91
+ print(json.dumps(run_doctor(), ensure_ascii=False, indent=2))
92
+ return 0
93
+
94
+ if argv[:2] == ["skill", "install"]:
95
+ args = parse_skill_install_args(argv[2:])
96
+ print(
97
+ json.dumps(
98
+ run_skill_install(
99
+ host=args.host,
100
+ force=args.force,
101
+ dry_run=args.dry_run,
102
+ ),
103
+ ensure_ascii=False,
104
+ indent=2,
105
+ )
106
+ )
107
+ return 0
108
+
109
+ if argv and argv[0] == "skill":
110
+ raise SystemExit(
111
+ "unsupported skill command; expected `lark-doc-exporter skill install`"
112
+ )
113
+
114
+ args = parse_export_args(argv)
115
+ formats = [item.strip() for item in args.formats.split(",") if item.strip()]
116
+ allowed = {"markdown", "pdf"}
117
+ invalid = [fmt for fmt in formats if fmt not in allowed]
118
+ if invalid:
119
+ raise SystemExit(f"unsupported formats: {', '.join(invalid)}")
120
+
121
+ result = export_document(
122
+ doc_ref=args.doc,
123
+ output_dir=Path(args.output_dir).expanduser().resolve(),
124
+ formats=formats,
125
+ title_suffix=args.title_suffix,
126
+ file_stem=args.file_stem,
127
+ keep_temp_doc=args.keep_temp_doc,
128
+ theme_name=args.theme,
129
+ override_css=Path(args.css).expanduser().resolve() if args.css else None,
130
+ )
131
+ print(json.dumps(result, ensure_ascii=False, indent=2))
132
+ return 0
133
+
134
+
135
+ def main() -> None:
136
+ try:
137
+ raise SystemExit(run_main())
138
+ except KeyboardInterrupt:
139
+ raise SystemExit(130) from None
140
+ except Exception as exc: # pragma: no cover - CLI boundary
141
+ sys.stderr.write(f"{exc}\n")
142
+ raise SystemExit(1) from exc
143
+
144
+
145
+ if __name__ == "__main__":
146
+ main()
@@ -0,0 +1,56 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import asdict, dataclass
4
+ import shutil
5
+ import subprocess
6
+
7
+ from .pdf_runtime import check_chromium_ready
8
+
9
+
10
+ @dataclass
11
+ class DoctorCheck:
12
+ name: str
13
+ ok: bool
14
+ detail: str
15
+
16
+
17
+ def check_lark_cli() -> DoctorCheck:
18
+ binary = shutil.which("lark-cli")
19
+ if not binary:
20
+ return DoctorCheck(
21
+ name="lark-cli",
22
+ ok=False,
23
+ detail="`lark-cli` is not on PATH. Install/configure it before running exports.",
24
+ )
25
+
26
+ try:
27
+ subprocess.run(
28
+ [binary, "--help"],
29
+ capture_output=True,
30
+ text=True,
31
+ check=True,
32
+ timeout=10,
33
+ )
34
+ except (OSError, subprocess.CalledProcessError, subprocess.TimeoutExpired) as exc:
35
+ return DoctorCheck(
36
+ name="lark-cli",
37
+ ok=False,
38
+ detail=f"`lark-cli` was found but is not runnable: {exc}",
39
+ )
40
+
41
+ return DoctorCheck(
42
+ name="lark-cli", ok=True, detail=f"`lark-cli` is available at {binary}."
43
+ )
44
+
45
+
46
+ def check_pdf_runtime() -> DoctorCheck:
47
+ ok, detail = check_chromium_ready()
48
+ return DoctorCheck(name="chromium", ok=ok, detail=detail)
49
+
50
+
51
+ def run_doctor() -> dict:
52
+ checks = [check_lark_cli(), check_pdf_runtime()]
53
+ return {
54
+ "ok": all(check.ok for check in checks),
55
+ "checks": [asdict(check) for check in checks],
56
+ }