Skip to content

Commit 61e4b42

Browse files
committed
docs: privatize maintainer guidance
1 parent 64dc14b commit 61e4b42

8 files changed

Lines changed: 72 additions & 19 deletions

File tree

‎.gitignore‎

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,9 @@ ENV/
110110
env.bak/
111111
venv.bak/
112112

113-
# removed-provider CLI and Testing artifacts
114-
.removed-provider/*
115-
!.removed-provider/.env.example
116-
!.removed-provider/commands/
117-
!.removed-provider/commands/**
118-
!.removed-provider/policies/
119-
!.removed-provider/policies/**
113+
# Private maintainer configuration
114+
removed-provider.md
115+
docs/removed-provider-removed-provider.md
120116
tmp_pytest/
121117

122118
# Spyder project settings

‎CHANGELOG.md‎

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,9 @@
77
- Preserve absolute and home-relative local Markdown image paths during upload,
88
retain existing root-relative asset fallback, and report missing files or
99
failed uploads instead of saving broken image sources.
10-
11-
## Unreleased
12-
13-
### Fixed
14-
15-
- Return draft records from the Substack drafts response envelope so `drafts list` works with the current API response.
10+
11+
- Return draft records from the Substack drafts response envelope so
12+
`drafts list` works with the current API response.
1613

1714
## 0.8.0
1815

‎README.md‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Substack result:
5858
- Set audience, comment permissions, SEO metadata, slug, sections, and tags.
5959
- List and inspect publications and drafts.
6060
- Export drafts to loss-aware Markdown backups without server writes.
61+
- Safely update drafts from Markdown, preserving unsupported editor widgets by default.
6162
- Schedule, unschedule, publish, and delete drafts with explicit safeguards.
6263
- Use stable JSON envelopes in scripts and automation.
6364
- Authenticate with browser cookies or email and password.
@@ -109,6 +110,7 @@ substack publications list
109110
substack drafts list --limit 10
110111
substack drafts get 12345
111112
substack drafts export 12345 --output backup.md
113+
substack drafts update 12345 revised-post.md --dry-run --yes
112114
substack --publication-url https://example.substack.com drafts list
113115
```
114116

@@ -181,6 +183,17 @@ print(backup["markdown"])
181183
print(backup["unsupported_nodes"])
182184
```
183185

186+
Review a Markdown update before writing it, then update deliberately:
187+
188+
```python
189+
result = api.update_draft_from_markdown(12345, "# Revised draft", dry_run=True)
190+
result = api.update_draft_from_markdown(12345, "# Revised draft")
191+
```
192+
193+
Unsupported editor widgets exported as `python-substack-node:v1` markers are
194+
preserved by default. An update refuses to remove or alter them unless
195+
`allow_unsupported_change=True` is explicitly passed.
196+
184197
For direct ProseMirror node construction, see the
185198
[low-level Python API](docs/low-level-api.md). YAML workflows are documented in
186199
[YAML drafts](docs/yaml.md).
@@ -233,11 +246,11 @@ See [MCP server](docs/mcp.md) for the tool list and safety notes.
233246
- [Python SDK](docs/python-sdk.md)
234247
- [Authentication](docs/authentication.md)
235248
- [Markdown reference](docs/markdown.md)
249+
- [Draft backup and safe updates](docs/cli.md)
236250
- [Legacy CLI commands](docs/legacy-cli.md)
237251
- [Low-level Python API](docs/low-level-api.md)
238252
- [YAML drafts](docs/yaml.md)
239253
- [MCP server](docs/mcp.md)
240-
- [removed-provider CLI with removed-provider](docs/removed-provider-removed-provider.md)
241254
- [Safety and publishing behavior](docs/safety.md)
242255
- [Troubleshooting](docs/troubleshooting.md)
243256
- [Compatibility policy](docs/compatibility.md)

‎docs/cli.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,26 @@ It fetches the draft but performs no server writes. Content without a supported
3636
Markdown representation is emitted as a versioned opaque HTML comment instead
3737
of being silently discarded.
3838

39+
## Update a draft from Markdown
40+
41+
Preview the generated update without writing to Substack:
42+
43+
```bash
44+
substack drafts update 12345 revised-post.md --dry-run --yes
45+
```
46+
47+
Apply it after review:
48+
49+
```bash
50+
substack drafts update 12345 revised-post.md --yes
51+
```
52+
53+
Updates preserve unsupported editor nodes exported as
54+
`python-substack-node:v1` markers. The command refuses to remove or alter
55+
those nodes by default. `--allow-unsupported-change` is available only with
56+
`--yes` for an intentional destructive change. The CLI uses its authenticated
57+
API client while rendering, so local images can upload even during a dry run.
58+
3959
## Select a publication
4060

4161
List every publication available to the authenticated account:

‎docs/markdown.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,12 @@ their document position as:
197197

198198
The payload is UTF-8 JSON encoded with URL-safe base64 and no padding. This
199199
makes unsupported content visible and recoverable instead of silently dropping
200-
it. Version 0.6 does not import these markers into a draft; safe updates that
201-
preserve them are planned for 0.8.
200+
it. `Api.update_draft_from_markdown` and `substack drafts update` recognize
201+
valid markers and preserve the corresponding nodes. They refuse updates that
202+
remove, duplicate, or alter remote unsupported nodes unless the caller
203+
explicitly authorizes that change with `allow_unsupported_change=True` or
204+
`--allow-unsupported-change --yes`.
202205

203206
Export preserves the Markdown meaning of supported images: source, alt text,
204207
link, and plain-text caption. Substack-only image layout attributes are not a
205-
Markdown contract in 0.6.
208+
Markdown contract.

‎docs/python-sdk.md‎

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,21 @@ decodable markers.
5353

5454
For supported syntax, see the [Markdown reference](markdown.md). For direct
5555
editor-node construction, see the [low-level Python API](low-level-api.md).
56+
57+
## Update a draft safely
58+
59+
Preview an update before writing it:
60+
61+
```python
62+
preview = api.update_draft_from_markdown(
63+
12345,
64+
"# Revised title\n\nUpdated body.",
65+
dry_run=True,
66+
)
67+
print(preview["payload"])
68+
```
69+
70+
Run the same call without `dry_run=True` to write the update. Unsupported
71+
editor nodes exported as `python-substack-node:v1` markers are preserved by
72+
default. Removing or changing them raises `ValueError` unless
73+
`allow_unsupported_change=True` is deliberately supplied.

‎docs/safety.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Creating, scheduling, publishing, and deleting are separate operations.
1111
|---|---|---|
1212
| `drafts export` | Reads a draft and produces Markdown | None |
1313
| `drafts create` | Creates an unpublished draft | None |
14+
| `drafts update` | Updates a draft from Markdown | Interactive or `--yes` |
1415
| `drafts schedule` | Adds a future release time | None |
1516
| `drafts unschedule` | Removes a future release time | None |
1617
| `drafts publish` | Publishes after a prepublish check | Interactive or `--yes` |
@@ -30,4 +31,6 @@ important source Markdown and verify the selected publication with
3031

3132
Export never writes to Substack and never overwrites a local file unless
3233
`--force` is supplied. Unsupported editor content is preserved as an opaque
33-
marker and listed in JSON output so it cannot disappear unnoticed.
34+
marker and listed in JSON output so it cannot disappear unnoticed. Updates
35+
refuse to remove or alter those markers unless
36+
`--allow-unsupported-change --yes` explicitly authorizes it.

‎docs/troubleshooting.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ checking the draft ID.
4545

4646
Pass the authenticated `Api` instance to `Post.from_markdown(..., api=api)` or
4747
use `Api.create_draft_from_markdown`, which does this automatically. Relative
48-
image paths resolve from the current working directory.
48+
image paths resolve from the current working directory; absolute paths are
49+
preserved and `~` expands to the current user's home directory. HTTP(S) and
50+
protocol-relative image URLs are not uploaded. Missing files and failed
51+
uploads name the affected path instead of silently retaining a broken source.
4952

5053
If the problem persists, open an issue using the repository's
5154
[authentication bug form](https://github.com/ma2za/python-substack/issues/new?template=auth_bug.yml)

0 commit comments

Comments
 (0)