Add json/csv support to the posting script (issue #012)

TEXT_KINDS and TEXT_SUFFIXES now include json/csv, with matching
sniff_text_kind branches so both explicit --kind and positional auto-mode
work. Added validate_payload's JSON shape check mirroring the server.
Updated SKILL.md/docs/llm_posting_helper.md with real usage examples,
replacing the stale --as-markdown workaround guidance (kept only for
genuinely unstructured code, which still has no dedicated kind). Also
fixed an unrelated stale doc line found in the same table: html_full's
validation was documented as requiring <!doctype AND <html, but only
<html is actually required.

Verified via dry-run (explicit --kind, auto-mode, invalid-JSON rejection)
and one real end-to-end post through the script against the live dev
instance.

Added tests/scripts/test_daybook_post.py - 17 tests, plain unittest, zero
new dependencies, loaded via importlib since the script isn't a package.
Closes the test-coverage question the issue raised.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
peter 2026-09-02 15:38:47 +01:00
parent 532b4bd4eb
commit e137725cab
6 changed files with 177 additions and 8 deletions

View file

@ -18,8 +18,8 @@ from urllib.parse import urljoin
from urllib.request import Request, urlopen
TEXT_KINDS = {"markdown", "html_fragment", "html_full", "deck"}
TEXT_SUFFIXES = {".md", ".markdown", ".txt", ".html", ".htm"}
TEXT_KINDS = {"markdown", "html_fragment", "html_full", "deck", "json", "csv"}
TEXT_SUFFIXES = {".md", ".markdown", ".txt", ".html", ".htm", ".json", ".csv"}
DEFAULT_URL = "http://127.0.0.1:8001"
DEFAULT_SOURCE = "agent"
@ -156,6 +156,10 @@ def resolve_auto_path(args):
def sniff_text_kind(suffix, text):
if suffix in (".md", ".markdown", ".txt"):
return "markdown"
if suffix == ".json":
return "json"
if suffix == ".csv":
return "csv"
lower = text.lower()
if "<!doctype" in lower or "<html" in lower:
return "html_full"
@ -301,6 +305,11 @@ def validate_payload(payload, args):
raise ValueError("html_full must be a complete HTML document with <html> (and ideally <!doctype html>)")
if kind == "markdown" and not payload["content"].strip():
raise ValueError("markdown content cannot be blank")
if kind == "json":
try:
json.loads(payload["content"])
except json.JSONDecodeError as exc:
raise ValueError(f"json content must be valid JSON: {exc}") from exc
def print_dry_run(base_url, token, payload, args):