Use when the user wants a draft from a writing content repository pushed to a private Google Doc for human review, or wants the reviewers' comments and edits pulled back as a working list.
Install
npx skillscat add platypeeps/sd-ai-command-pack/sd-draft-review Install via the SkillsCat registry.
sd-draft-review
Two modes on one private review copy per piece:
pushwrites the draft and its research to Google Docs in the private drafts folder.pullreads comments and edits back. It writes nothing anywhere.
Run from the root of a content repository (it holds content/, profile/ and templates/). This skill also needs sd-writing's scripts/pack.py. pack below means python3 scripts/pack.py.
The piece comes from the arguments; with none, ask which piece, or offer the ones at review (push) or with a recorded review URL (pull).
Always pull before a push that replaces a document: a replace overwrites reviewer edits in the body, and no tool here recovers them.
It has no bin/ command: the steps below are the procedure, and scripts/pack.py and the workspace-mcp tools do the work.
Settings
sd config get sdw.google_account
sd config get sdw.drive_writing_folderAn unset value exits 1 and prints the config set command that fixes it. Stop and show the user that line. Never guess an address or a folder.
This skill writes only the drafts folder. It never writes the publishing folder: a draft there is published unreviewed. sd-publish-drive owns that folder.
push
sd writing get --piece <year>/<slug> --json; useitem.pathandwriting.stage.reviewis the intended stage.draftingandreadyare allowed; name the stage in the report.ideaandresearchingrefuse (suggestsd-draft);publishedrefuses.- An empty or placeholder
## Draftstops the push.
- Read
writing.metadata.review_urls.gdocs. A recorded URL means replace in place: one review doc per piece, one URL that never changes. Never create a second copy.
If the piece has noreview_urlsblock, runpack pieces backfill-urls --piece <year>/<slug>. - Confirm the push with the user every time. It writes to their Drive.
- Build both documents with
pack review build-html --piece <year>/<slug> --out <scratch dir>. It writesdraft.html(the## Draftprose only, neverNotes / angleorOutline) andresearch.html(all ofresearch.md, marked internal), with images inlined. Do not hand-roll a converter.
Check the printedimages=count against the piece'simages/folder. AWARNING: missing image(s)line is a stop. - Confirm the folder:
get_drive_shareable_linkondrive_writing_foldermust return the drafts folder's name, not the publishing folder's. If it returns the publishing folder, the two keys are swapped: stop and tell the user. - Copy both files into the
workspace-mcpattachments folder (~/.workspace-mcp/attachmentsby default; the server's refusal names it). Always passfile_path, nevercontent. - Each piece gets
<drafts>/<year>/<slug>/. Search for the year and slug folders before creating them.- First push:
import_to_google_docper document withuser_google_email,folder_id,file_name(the title, orResearch — <title>),file_path, andsource_format: "html". - Re-push:
update_drive_filewith the recordedfile_id, the newfile_path, andsource_format: "html". Say in the report that comment anchors detach, and that revision history keeps the old body. - A result that is not
application/vnd.google-apps.documentis a failure to report.
- First push:
- Read the doc back with
get_doc_as_markdown(comment_mode: "none"). Check the header word count and push date, that images came back asgoogleusercontentURLs, and that headings arrived as##. pack pieces set-review-url --piece <year>/<slug> --target gdocs --url <draft URL>. It also stampsreview_urls.gdocs_digest. It changes no stage.- If the piece has
obsidian_source, merge the links into its idea note'sDrive docssection:sd store get sdw.blog-idea "<idea title>" --section 'Drive docs', merge, thensd store set sdw.blog-idea "<idea title>" --section-file 'Drive docs=<file>'.
The section is replaced whole, so carry the old lines over. One- <label>: <url>line per document:Draft review copy,Research notes,Published copy. Withoutobsidian_source, say so.
Push report: the URL, word count, stage, and how comments come back (/sd-draft-review pull; nothing watches for them). A failed push leaves review_urls.gdocs unchanged.
pull
sd writing get --piece <year>/<slug> --json; takewriting.metadata.review_urls.gdocs. A null, empty or missing value means the piece was not pushed: say so and suggestpush. Take the document ID from that URL only; do not search Drive for a likely title.pack review status --piece <year>/<slug>. Areview=staleorunstampedcopy may quote sentences that no longer exist: say so at the top of the report.- Comments:
list_document_commentswithuser_google_emailanddocument_id. "No comments" and "could not read" are different results; on an error, report it and stop.get_doc_as_markdownshows comments against their anchors when an anchor is thin. - Suggestion-mode edits:
get_doc_as_markdownwithsuggestions_view_mode=SUGGESTIONS_INLINE. - Direct edits: rebuild with
pack review build-html, confirm its digest matchesreview_urls.gdocs_digest(if not, report that instead of a mixed diff), then diff the## Draftmarkdown against the doc's markdown, whitespace-insensitive. Drop what the transport adds:- the header block;
- image lines: compare image count and order only, not URLs or alt text;
- an italic line under an image that matches that image's alt text. An italic line that differs is a reviewer's caption edit: report it.
Pull report, grouped by what the user must do:
- Open comments: quoted anchor, author, comment verbatim, replies in order.
- Resolved comments, briefly.
- Edits, both kinds. An edit is an opinion; it reaches the repository through an
sd-draftpass the user approves. - Factual challenges, called out on their own as work for the fact-check gate in
sd-draft. Do not run that gate from here.
Then say what did not happen: nothing was applied, comments are still open, and no reviewer got a reply.
Safety rules
pullmakes no writes: no reply, resolution or edit in the doc; no change to prose, stage,review_urlsorupdated.pushwrites only the drafts folder tree and only after the user confirms.- Never reconstruct a document ID or a folder ID.
- Never edit the draft from a review comment; offer
sd-draftinstead.