Scripts reference
Both shipped scripts, with every flag they accept. Generated from each script’s own
--help, so this page cannot describe an option the script does not have.
Most readers never need this: the skills drive both scripts themselves. It exists for running them directly, and for reviewing what the skill is doing on your behalf.
recommend.py
Section titled “recommend.py”Scores the admitted (non-draft) catalog against a described situation, per axis. This is a deterministic pre-filter, not the recommendation itself: the pick-and-justify judgment happens in the skill reasoning, using this output as candidate data.
Source: skills/entry-recommender/scripts/recommend.py
usage: recommend.py [-h] [--ephemeral-input-file EPHEMERAL_INPUT_FILE] [--input-file INPUT_FILE] [--stdin] [--situation SITUATION] [--topic TOPIC] [--audience AUDIENCE] [--voice VOICE] [--tone TONE] [--style STYLE] [--format FMT] [--short-list-size SHORT_LIST_SIZE] [--threshold THRESHOLD] [--fetch AXIS ID] [--fetch-many AXIS_OR_ID [AXIS_OR_ID ...]] [--list] [--response-format {concise,detailed}] [--debug] [--verbose] [--pretty] [--json]
Score the admitted catalog against a described writing situation, per axis.
options: -h, --help show this help message and exit --ephemeral-input-file EPHEMERAL_INPUT_FILE Same JSON payload as --input-file, but this process deletes the file itself immediately after reading it (in a finally block, so cleanup happens even if the JSON is malformed or scoring later raises) - THE PREFERRED way for an agent to pass real situation text, which can be sensitive (HR, incident, customer detail). Cleanup does not depend on a separate agent- followed instruction step; it is guaranteed by this process's own control flow. This deletes whatever path you pass, so three conditions are enforced first, all required: the path must NOT be inside this repo, MUST be inside the system temp directory, and its filename MUST end in '.entry-recommender-input.json' - anything else raises instead of reading or deleting anything (a caller path mistake must fail loudly, not silently destroy the wrong file). Write the file with a file- write tool (never a shell command) to a temp/scratchpad location outside the project directory, with a filename ending in '.entry- recommender-input.json'; the situation text must be properly JSON-string-escaped first (backslash, quote, newline, etc.) - see SKILL.md Step 1. --input-file INPUT_FILE Same JSON payload, but this process does NOT delete the file - for a deliberately-kept test fixture reused across runs, not day-to-day use with real (possibly sensitive) situation text. Prefer --ephemeral-input- file for that. --situation below is a convenience for direct manual/terminal use, where the caller controls their own shell escaping - a caller assembling this command from untrusted text (an agent following SKILL.md, for example) MUST use --ephemeral-input-file instead. --stdin Read the same JSON payload --input-file takes from stdin instead of a file. NOT recommended for untrusted situation text piped via a shell heredoc: a heredoc's closing delimiter is plain text matched against the body, so situation text containing that exact line terminates it early and whatever follows is executed as a new shell command - a real risk if the delimiter is fixed and predictable (for example, one written into this file's own history). Safe only when the JSON is supplied by a mechanism with no delimiter-collision risk, such as another process's stdout piped directly in. Prefer --input-file for an agent workflow. --situation SITUATION Free-text description of the writing situation (manual/terminal use only - see --input-file) --topic TOPIC Optional topic, folded into the situation tokens --audience AUDIENCE Optional audience, folded into the situation tokens --voice VOICE Fixed voice entry id (skip scoring this axis) --tone TONE Fixed tone entry id (skip scoring this axis) --style STYLE Fixed style entry id (skip scoring this axis) --format FMT Fixed format entry id (skip scoring this axis) --short-list-size SHORT_LIST_SIZE Floor for how many non-qualifying candidates pad the short list when there are fewer qualifying ones than this - never a cap on genuinely qualifying candidates. Must be a non-negative integer. --threshold THRESHOLD --fetch AXIS ID Fetch one candidate's full fields --fetch-many AXIS_OR_ID [AXIS_OR_ID ...] Fetch multiple candidates' full fields in one call: --fetch-many AXIS ID [ID ...]. Each id passes through the same stable-membership gate as --fetch (list- derived whitelist, no path construction from caller strings). Returns a JSON array with one result per id, in the order given. Use for triage-tier lean rows (those with "fields": "fetch") when one_liner or matched_tokens suggest a candidate may be competitive with the read tier. --list List all admitted (non-draft) ids per axis --response-format {concise,detailed} Output contract for the recommend path. "concise" (default): tiered short_list - read tier (first short_list_size above_threshold rows) carries full when_to_use/tells/when_not_to_use; all other rows are lean (qualifying triage rows AND non-qualifying padding rows) and carry \"fields\": \"fetch\" marker; full_ranked omitted unless --debug. "detailed": legacy full-fields-for-all-short_list-entries behavior, full_ranked always emitted. --debug Include full_ranked in the output (omitted by default in concise mode). full_ranked contains only non- qualifying entries in concise mode, since every qualifying candidate is already in short_list. Use for diagnosing scores, not as part of the documented Step 2 workflow. --verbose Print a per-candidate score trace to STDERR: the IDF weight of every situation token, each candidate's per- field matches with their weighted contribution, and for a rejected candidate which gate it failed (score below threshold, too few distinct matches, or both). stdout stays clean JSON. Unlike --debug, which adds the ranked pool to the payload, this explains how each score was arrived at. --pretty Pretty-print JSON output with indent=2. Default is compact JSON (no whitespace). The model never needed the whitespace; this flag is for human inspection. --json Output as JSON (for --list and --fetch; the recommend path always outputs JSON)build-instruction.py
Section titled “build-instruction.py”Composes selected entries into a ready-to-paste prompt prefix, applying the conflict-aware composition rules from ADR 0016.
Source: skills/writing-instruction-builder/scripts/build-instruction.py
usage: build-instruction.py [-h] [--voice VOICE] [--tone TONE] [--style STYLE] [--format FMT] [--topic TOPIC] [--audience AUDIENCE] [--list] [--json]
Compose a writing instruction from taxonomy entry IDs.
options: -h, --help show this help message and exit --voice VOICE Voice entry ID --tone TONE Tone entry ID --style STYLE Style entry ID --format FMT Format entry ID --topic TOPIC Topic to write about --audience AUDIENCE Intended audience --list List all available entries --json Output as JSONA note on --ephemeral-input-file
Section titled “A note on --ephemeral-input-file”recommend.py accepts a situation on stdin or in a file. The ephemeral variant reads
the file and then deletes it, which is why it refuses any path not ending in the
required suffix: a delete-after-read flag pointed at an arbitrary path is a destructive
primitive. The guard is deliberate and should not be relaxed to make a call site more
convenient.