polyptych 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 (168) hide show
  1. polyptych-0.1.0/.claude/agents/prompt-consistency-reviewer.md +66 -0
  2. polyptych-0.1.0/.claude/hooks/block-sensitive-files.sh +22 -0
  3. polyptych-0.1.0/.claude/hooks/ruff-format.sh +17 -0
  4. polyptych-0.1.0/.claude/settings.json +51 -0
  5. polyptych-0.1.0/.claude/skills/check-models/SKILL.md +96 -0
  6. polyptych-0.1.0/.claude/skills/check-status/SKILL.md +101 -0
  7. polyptych-0.1.0/.claude/skills/clean-source/SKILL.md +34 -0
  8. polyptych-0.1.0/.claude/skills/edit-output/SKILL.md +136 -0
  9. polyptych-0.1.0/.claude/skills/infographic/SKILL.md +137 -0
  10. polyptych-0.1.0/.claude/skills/new-style/SKILL.md +131 -0
  11. polyptych-0.1.0/.claude/skills/qa-test/SKILL.md +138 -0
  12. polyptych-0.1.0/.claude/skills/review-regen/SKILL.md +115 -0
  13. polyptych-0.1.0/.claude/skills/run-local-pipeline/SKILL.md +223 -0
  14. polyptych-0.1.0/.claude/skills/run-local-task/SKILL.md +154 -0
  15. polyptych-0.1.0/.claude/skills/run-pipeline/SKILL.md +131 -0
  16. polyptych-0.1.0/.claude/skills/suggest-style/SKILL.md +100 -0
  17. polyptych-0.1.0/.claude/skills/trace-prompt/SKILL.md +138 -0
  18. polyptych-0.1.0/.envrc.example +11 -0
  19. polyptych-0.1.0/.github/workflows/ci.yml +41 -0
  20. polyptych-0.1.0/.gitignore +59 -0
  21. polyptych-0.1.0/CHANGELOG.md +26 -0
  22. polyptych-0.1.0/CLAUDE.md +216 -0
  23. polyptych-0.1.0/CONTRIBUTING.md +58 -0
  24. polyptych-0.1.0/LICENSE +202 -0
  25. polyptych-0.1.0/NOTICE +10 -0
  26. polyptych-0.1.0/PKG-INFO +209 -0
  27. polyptych-0.1.0/README.md +175 -0
  28. polyptych-0.1.0/RELEASE-READINESS.md +131 -0
  29. polyptych-0.1.0/SECURITY.md +25 -0
  30. polyptych-0.1.0/docs/assets/polyptych-studio-explainer.png +0 -0
  31. polyptych-0.1.0/docs/assets/polyptych-studio.png +0 -0
  32. polyptych-0.1.0/docs/explanation/critique-refine-pattern.md +106 -0
  33. polyptych-0.1.0/docs/explanation/multi-agent-patterns.md +232 -0
  34. polyptych-0.1.0/docs/explanation/operating-modes.md +70 -0
  35. polyptych-0.1.0/docs/explanation/pipeline-architectures.md +90 -0
  36. polyptych-0.1.0/docs/explanation/system-overview.md +620 -0
  37. polyptych-0.1.0/docs/explanation/task-decomposition.md +779 -0
  38. polyptych-0.1.0/docs/how-to/resume-pipeline.md +85 -0
  39. polyptych-0.1.0/docs/how-to/write-style-prompts.md +73 -0
  40. polyptych-0.1.0/docs/index.md +38 -0
  41. polyptych-0.1.0/docs/reference/cli-reference.md +220 -0
  42. polyptych-0.1.0/docs/reference/image-prompting-guide.md +148 -0
  43. polyptych-0.1.0/docs/reference/pipeline-tier-optimization.md +48 -0
  44. polyptych-0.1.0/docs/reference/text-client-api.md +267 -0
  45. polyptych-0.1.0/docs/tutorials/first-pipeline.md +156 -0
  46. polyptych-0.1.0/examples/about-polyptych-studio.md +109 -0
  47. polyptych-0.1.0/examples/scene.md +17 -0
  48. polyptych-0.1.0/image-presets.yaml +33 -0
  49. polyptych-0.1.0/image_model_config.yaml +10 -0
  50. polyptych-0.1.0/justfile +140 -0
  51. polyptych-0.1.0/model_config.yaml +58 -0
  52. polyptych-0.1.0/pipeline-presets.yaml +20 -0
  53. polyptych-0.1.0/prompts/providers/gemini-best-practices.md +75 -0
  54. polyptych-0.1.0/prompts/providers/openai-best-practices.md +155 -0
  55. polyptych-0.1.0/prompts/providers/xai-best-practices.md +83 -0
  56. polyptych-0.1.0/prompts/style-transfer/anime/anime-dark.md +33 -0
  57. polyptych-0.1.0/prompts/style-transfer/editorial/scholarly-monograph.md +146 -0
  58. polyptych-0.1.0/prompts/style-transfer/infographic/clean-minimalist.md +116 -0
  59. polyptych-0.1.0/prompts/style-transfer/infographic/semi-flat-vector.md +116 -0
  60. polyptych-0.1.0/prompts/style-transfer/noir/cinematic-illustrative-noir.md +42 -0
  61. polyptych-0.1.0/prompts/style-transfer/period-art/attic-vase-pastoral.md +146 -0
  62. polyptych-0.1.0/prompts/tasks/task-01-genre-classification.md +359 -0
  63. polyptych-0.1.0/prompts/tasks/task-02-source-analysis.md +557 -0
  64. polyptych-0.1.0/prompts/tasks/task-03-structure-planning.md +490 -0
  65. polyptych-0.1.0/prompts/tasks/task-04-content-allocation.md +395 -0
  66. polyptych-0.1.0/prompts/tasks/task-05-visual-design.md +766 -0
  67. polyptych-0.1.0/prompts/tasks/task-06-slide-specification-fiction.md +440 -0
  68. polyptych-0.1.0/prompts/tasks/task-06-slide-specification.md +677 -0
  69. polyptych-0.1.0/prompts/tasks/task-07-image-generation.md +984 -0
  70. polyptych-0.1.0/prompts/tasks/task-critique.md +144 -0
  71. polyptych-0.1.0/prompts/tasks/task-i0-analysis.md +68 -0
  72. polyptych-0.1.0/prompts/tasks/task-i1-design.md +86 -0
  73. polyptych-0.1.0/prompts/tasks/task-i2-critique.md +97 -0
  74. polyptych-0.1.0/prompts/tasks/task-i2-prompts.md +92 -0
  75. polyptych-0.1.0/prompts/tasks/task-i2-refine.md +53 -0
  76. polyptych-0.1.0/pyproject.toml +94 -0
  77. polyptych-0.1.0/scripts/count-paragraphs.py +23 -0
  78. polyptych-0.1.0/src/common/__init__.py +0 -0
  79. polyptych-0.1.0/src/common/compat.py +91 -0
  80. polyptych-0.1.0/src/common/logging_setup.py +96 -0
  81. polyptych-0.1.0/src/common/usage_log.py +32 -0
  82. polyptych-0.1.0/src/polyptych/__init__.py +26 -0
  83. polyptych-0.1.0/src/polyptych/batch_utils.py +85 -0
  84. polyptych-0.1.0/src/polyptych/clean_source.py +316 -0
  85. polyptych-0.1.0/src/polyptych/cli.py +1047 -0
  86. polyptych-0.1.0/src/polyptych/client.py +333 -0
  87. polyptych-0.1.0/src/polyptych/concurrent_engine.py +214 -0
  88. polyptych-0.1.0/src/polyptych/cross_validate.py +319 -0
  89. polyptych-0.1.0/src/polyptych/image_batch.py +452 -0
  90. polyptych-0.1.0/src/polyptych/logging_setup.py +64 -0
  91. polyptych-0.1.0/src/polyptych/model_config.py +186 -0
  92. polyptych-0.1.0/src/polyptych/models/__init__.py +165 -0
  93. polyptych-0.1.0/src/polyptych/models/infographic.py +258 -0
  94. polyptych-0.1.0/src/polyptych/models/slide.py +678 -0
  95. polyptych-0.1.0/src/polyptych/pipeline.py +60 -0
  96. polyptych-0.1.0/src/polyptych/pipeline_base.py +353 -0
  97. polyptych-0.1.0/src/polyptych/pipeline_config.py +161 -0
  98. polyptych-0.1.0/src/polyptych/pipeline_infographic.py +448 -0
  99. polyptych-0.1.0/src/polyptych/pipeline_task.py +1000 -0
  100. polyptych-0.1.0/src/polyptych/presets.py +311 -0
  101. polyptych-0.1.0/src/polyptych/prompt_loader.py +146 -0
  102. polyptych-0.1.0/src/polyptych/providers/__init__.py +86 -0
  103. polyptych-0.1.0/src/polyptych/providers/anthropic.py +215 -0
  104. polyptych-0.1.0/src/polyptych/providers/base.py +349 -0
  105. polyptych-0.1.0/src/polyptych/providers/gemini.py +179 -0
  106. polyptych-0.1.0/src/polyptych/providers/openai.py +158 -0
  107. polyptych-0.1.0/src/polyptych/providers/vertex.py +50 -0
  108. polyptych-0.1.0/src/polyptych/providers/xai.py +193 -0
  109. polyptych-0.1.0/src/polyptych/ref_utils.py +84 -0
  110. polyptych-0.1.0/src/polyptych/run_config.py +204 -0
  111. polyptych-0.1.0/src/polyptych/task_registry.py +217 -0
  112. polyptych-0.1.0/src/polyptych/tasks/__init__.py +32 -0
  113. polyptych-0.1.0/src/polyptych/tasks/task_01_genre.py +68 -0
  114. polyptych-0.1.0/src/polyptych/tasks/task_02_analysis.py +69 -0
  115. polyptych-0.1.0/src/polyptych/tasks/task_03_structure.py +84 -0
  116. polyptych-0.1.0/src/polyptych/tasks/task_04_content.py +112 -0
  117. polyptych-0.1.0/src/polyptych/tasks/task_05_design.py +101 -0
  118. polyptych-0.1.0/src/polyptych/tasks/task_06_slides.py +103 -0
  119. polyptych-0.1.0/src/polyptych/tasks/task_07_prompts.py +580 -0
  120. polyptych-0.1.0/src/polyptych/tasks/task_i0_analysis.py +60 -0
  121. polyptych-0.1.0/src/polyptych/tasks/task_i1_design.py +109 -0
  122. polyptych-0.1.0/src/polyptych/tasks/task_i2_critique.py +207 -0
  123. polyptych-0.1.0/src/polyptych/tasks/task_i2_prompts.py +131 -0
  124. polyptych-0.1.0/src/polyptych/text_utils.py +200 -0
  125. polyptych-0.1.0/src/polyptych/usage_log.py +5 -0
  126. polyptych-0.1.0/tests/__init__.py +0 -0
  127. polyptych-0.1.0/tests/common/__init__.py +0 -0
  128. polyptych-0.1.0/tests/common/test_compat.py +142 -0
  129. polyptych-0.1.0/tests/polyptych/__init__.py +0 -0
  130. polyptych-0.1.0/tests/polyptych/conftest.py +45 -0
  131. polyptych-0.1.0/tests/polyptych/mock_client.py +189 -0
  132. polyptych-0.1.0/tests/polyptych/providers/__init__.py +0 -0
  133. polyptych-0.1.0/tests/polyptych/providers/test_base.py +402 -0
  134. polyptych-0.1.0/tests/polyptych/providers/test_helpers.py +356 -0
  135. polyptych-0.1.0/tests/polyptych/slide/__init__.py +0 -0
  136. polyptych-0.1.0/tests/polyptych/slide/conftest.py +42 -0
  137. polyptych-0.1.0/tests/polyptych/slide/factories.py +372 -0
  138. polyptych-0.1.0/tests/polyptych/slide/test_character_canon.py +199 -0
  139. polyptych-0.1.0/tests/polyptych/slide/test_cross_validate.py +262 -0
  140. polyptych-0.1.0/tests/polyptych/slide/test_local_manifest.py +48 -0
  141. polyptych-0.1.0/tests/polyptych/slide/test_prompt_provider.py +107 -0
  142. polyptych-0.1.0/tests/polyptych/slide/test_schema_ergonomics.py +121 -0
  143. polyptych-0.1.0/tests/polyptych/slide/test_slide_image_paths.py +240 -0
  144. polyptych-0.1.0/tests/polyptych/slide/test_slide_pipeline_flow.py +315 -0
  145. polyptych-0.1.0/tests/polyptych/slide/test_task7_assembly.py +192 -0
  146. polyptych-0.1.0/tests/polyptych/tasks/__init__.py +0 -0
  147. polyptych-0.1.0/tests/polyptych/tasks/test_task_05_design.py +36 -0
  148. polyptych-0.1.0/tests/polyptych/test_clean_source.py +413 -0
  149. polyptych-0.1.0/tests/polyptych/test_cli.py +520 -0
  150. polyptych-0.1.0/tests/polyptych/test_client.py +855 -0
  151. polyptych-0.1.0/tests/polyptych/test_dependency_resolver.py +157 -0
  152. polyptych-0.1.0/tests/polyptych/test_image_batch.py +480 -0
  153. polyptych-0.1.0/tests/polyptych/test_infographic_critique.py +184 -0
  154. polyptych-0.1.0/tests/polyptych/test_logging_setup.py +132 -0
  155. polyptych-0.1.0/tests/polyptych/test_pipeline_base.py +79 -0
  156. polyptych-0.1.0/tests/polyptych/test_pipeline_config.py +56 -0
  157. polyptych-0.1.0/tests/polyptych/test_pipeline_infographic.py +340 -0
  158. polyptych-0.1.0/tests/polyptych/test_pipeline_init.py +307 -0
  159. polyptych-0.1.0/tests/polyptych/test_pipeline_resume.py +169 -0
  160. polyptych-0.1.0/tests/polyptych/test_ref_utils.py +65 -0
  161. polyptych-0.1.0/tests/polyptych/test_run_config.py +161 -0
  162. polyptych-0.1.0/tests/polyptych/test_task_registry.py +236 -0
  163. polyptych-0.1.0/tests/polyptych/test_text_utils.py +81 -0
  164. polyptych-0.1.0/tests/test_concurrent_engine.py +304 -0
  165. polyptych-0.1.0/tests/test_concurrent_engine_ordering.py +228 -0
  166. polyptych-0.1.0/tests/test_model_config.py +72 -0
  167. polyptych-0.1.0/tests/test_presets.py +450 -0
  168. polyptych-0.1.0/uv.lock +1243 -0
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: prompt-consistency-reviewer
3
+ description: Read-only reviewer that detects drift between prompt task templates, provider best-practice docs, style-transfer presets, and the YAML config files (image-presets, pipeline-presets, model configs). Invoke after editing anything under prompts/ or the *-presets.yaml / *_config.yaml files, or when asked to audit prompt/config consistency.
4
+ tools: Read, Grep, Glob
5
+ model: inherit
6
+ ---
7
+
8
+ # Prompt & Config Consistency Reviewer
9
+
10
+ You are a read-only auditor for this essay-to-visuals generation system. You never edit
11
+ files — you report findings so the main agent (or the user) can act on them.
12
+
13
+ ## What you check
14
+
15
+ The project keeps several sources of truth that must agree with each other:
16
+
17
+ - `prompts/tasks/` — per-task prompt templates (task-01 … task-07,
18
+ task-i0 … task-i2, task-critique)
19
+ - `prompts/providers/{gemini,openai,xai}-best-practices.md` — provider guidance
20
+ - `prompts/style-transfer/<category>/*.md` — visual style presets (+ optional sibling
21
+ exemplar image)
22
+ - `image-presets.yaml`, `pipeline-presets.yaml`, `model_config.yaml`,
23
+ `image_model_config.yaml`
24
+ - `CLAUDE.md` and `docs/reference/cli-reference.md` — which document flags, presets,
25
+ pipelines, and task tables
26
+
27
+ ## Drift patterns to hunt for
28
+
29
+ 1. **Flag/option drift** — a flag or option named in a provider best-practices doc or a
30
+ task template that no longer exists in the CLI / config (or vice versa: a flag in
31
+ `CLAUDE.md` / cli-reference not honored by any template).
32
+ 2. **Preset references** — a `--image-preset` / `--pipeline-preset` name referenced in
33
+ docs, task templates, or the justfile that is missing from `image-presets.yaml` /
34
+ `pipeline-presets.yaml`, or a preset defined but referenced nowhere.
35
+ 3. **Style presets** — a style category or preset count claimed in `CLAUDE.md`
36
+ or the docs that disagrees with what's actually on disk under
37
+ `prompts/style-transfer/`. Count the real files.
38
+ 4. **Model/tier references** — task names in `model_config.yaml` that don't correspond to
39
+ a real task template, or templates with no model-tier entry.
40
+ 5. **Pipeline/task-table drift** — the pipeline list and per-task tables in `CLAUDE.md` /
41
+ cli-reference vs. the actual `task-*` templates present.
42
+ 6. **Cross-doc contradictions** — same fact stated two ways in CLAUDE.md vs.
43
+ cli-reference vs. a provider doc.
44
+
45
+ ## Method
46
+
47
+ - Use `Glob`/`Grep` to enumerate the real files first, then compare against what the docs
48
+ and configs claim. **Verify counts and names against disk** — never trust a number
49
+ asserted in prose without checking it (this is a known failure mode in this repo).
50
+ - Be specific: cite `file:line` for every finding and quote both sides of a mismatch.
51
+ - Distinguish severity: `MISMATCH` (a concrete contradiction with disk/config) vs.
52
+ `STALE?` (likely outdated, needs human judgment) vs. `NOTE` (minor).
53
+
54
+ ## Output
55
+
56
+ Return a compact report grouped by drift pattern. For each finding:
57
+
58
+ ```
59
+ [MISMATCH] <one-line summary>
60
+ claim: <file:line> — "<quoted text>"
61
+ reality: <file:line or disk fact> — "<quoted text / count>"
62
+ fix: <smallest change that reconciles them>
63
+ ```
64
+
65
+ End with a one-line verdict: `CONSISTENT` or `N findings (X mismatch, Y stale)`.
66
+ If you found nothing, say so plainly — don't invent issues.
@@ -0,0 +1,22 @@
1
+ #!/bin/bash
2
+ # PreToolUse hook: block Edit/Write to secrets-bearing files (.env, .envrc, ...).
3
+ # Receives the tool-call JSON on stdin; denies via exit code 2 + JSON decision.
4
+ set -euo pipefail
5
+
6
+ input=$(cat)
7
+ file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
8
+ filename=$(basename "$file_path")
9
+
10
+ # Block .env, .env.local, .envrc, etc. Allow .env.example templates through.
11
+ if [[ "$filename" == .env* && "$filename" != ".env.example" ]]; then
12
+ jq -n --arg f "$filename" '{
13
+ hookSpecificOutput: {
14
+ hookEventName: "PreToolUse",
15
+ permissionDecision: "deny",
16
+ permissionDecisionReason: ("Refusing to edit secrets-bearing file: " + $f + ". Edit it manually if intended.")
17
+ }
18
+ }'
19
+ exit 2
20
+ fi
21
+
22
+ exit 0
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+ # PostToolUse hook: auto-format + lint-fix Python files after Claude edits them.
3
+ # Receives the tool-call JSON on stdin; acts only on .py files.
4
+ set -euo pipefail
5
+
6
+ input=$(cat)
7
+ file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
8
+
9
+ [[ "$file_path" == *.py ]] || exit 0
10
+ [[ -f "$file_path" ]] || exit 0
11
+
12
+ # Format only — idempotent, no semantic changes. Lint-fixing (e.g. removing
13
+ # "unused" imports) is intentionally left to `just lint`, since on a per-edit
14
+ # hook it would strip imports added in one edit before they're used in the next.
15
+ uv run ruff format "$file_path" >/dev/null 2>&1 || true
16
+
17
+ exit 0
@@ -0,0 +1,51 @@
1
+ {
2
+ "permissions": {
3
+ "allow": [
4
+ "Bash(uv sync:*)",
5
+ "Bash(uv run:*)",
6
+ "Bash(just:*)",
7
+ "Bash(python3:*)",
8
+ "Bash(python:*)",
9
+ "Bash(git add:*)",
10
+ "Bash(git commit:*)",
11
+ "Bash(git stash:*)",
12
+ "Bash(ffmpeg:*)",
13
+ "Bash(ffprobe:*)",
14
+ "Bash(ls:*)",
15
+ "Bash(wc:*)",
16
+ "WebSearch",
17
+ "WebFetch(domain:ai.google.dev)",
18
+ "WebFetch(domain:docs.cloud.google.com)",
19
+ "WebFetch(domain:docs.x.ai)",
20
+ "WebFetch(domain:github.com)",
21
+ "mcp__plugin_context7_context7__resolve-library-id",
22
+ "mcp__plugin_context7_context7__query-docs"
23
+ ]
24
+ },
25
+ "hooks": {
26
+ "PreToolUse": [
27
+ {
28
+ "matcher": "Edit|Write",
29
+ "hooks": [
30
+ {
31
+ "type": "command",
32
+ "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-sensitive-files.sh",
33
+ "timeout": 5
34
+ }
35
+ ]
36
+ }
37
+ ],
38
+ "PostToolUse": [
39
+ {
40
+ "matcher": "Edit|Write",
41
+ "hooks": [
42
+ {
43
+ "type": "command",
44
+ "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/ruff-format.sh",
45
+ "timeout": 30
46
+ }
47
+ ]
48
+ }
49
+ ]
50
+ }
51
+ }
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: check-models
3
+ description: Search the web for the latest AI model names and identifiers for a provider, then compare with model_config.yaml and image_model_config.yaml
4
+ user-invocable: true
5
+ args:
6
+ - name: provider
7
+ description: "Provider to check: gemini, openai, xai/grok, anthropic/claude, vertex, or 'all' to check every provider. Optional — defaults to 'all' when omitted."
8
+ ---
9
+
10
+ # Check Latest AI Models for a Provider
11
+
12
+ You are given a `provider` argument identifying which AI provider's models to look up. **If no argument is provided, default to `all`** (check every provider) rather than stopping to ask.
13
+
14
+ ## Provider Mapping
15
+
16
+ Map the argument to a search scope. Each provider may appear in `model_config.yaml` (text/LLM tiers) and/or `image_model_config.yaml` (image model). Cover both.
17
+
18
+ | Argument | Text entries (`model_config.yaml`) | Image entries (`image_model_config.yaml`) | Search hints |
19
+ |---------------------|------------------------------------|-------------------------------------------|--------------------------------------------------|
20
+ | `gemini` | `providers.gemini` | `providers.gemini`, `providers.x_gemini` | `site:ai.google.dev` Gemini models, API ids |
21
+ | `openai` / `gpt` | `providers.openai` | `providers.openai` | `site:developers.openai.com` models, gpt-image (NOT `platform.openai.com` — that host blocks WebFetch with 403) |
22
+ | `xai` / `grok` | `providers.xai` | `providers.xai` | `site:docs.x.ai` Grok / grok-imagine models — pages are often skeletal; lean on WebSearch result snippets, not WebFetch |
23
+ | `anthropic` / `claude` | `providers.anthropic` | (none — no image gen) | `site:platform.claude.com` models (the old `docs.anthropic.com` URL 301-redirects to `platform.claude.com/docs/en/...`) |
24
+ | `vertex` | `providers.vertex` | `providers.vertex` | Vertex AI model garden — Gemini ids on Vertex |
25
+ | `all` | all of the above | all of the above | run each provider in sequence |
26
+
27
+ If no argument is given, treat it as `all`. If a non-empty argument doesn't match any of the above, tell the user the valid options and stop.
28
+
29
+ ## Steps
30
+
31
+ 1. **Read both config files** from the repository root:
32
+ - `model_config.yaml` — display the `fast` and `thinking` model ids for the matched provider(s) under `providers:`.
33
+ - `image_model_config.yaml` — display the matched provider's image model id (and `x_gemini` if relevant).
34
+
35
+ Show the current values so the user can see what's about to be compared.
36
+
37
+ 2. **Search the web** for the latest available models from that provider. Use targeted queries:
38
+ - Provider docs first: `site:ai.google.dev`, `site:developers.openai.com`, `site:platform.claude.com`, `site:docs.x.ai`, `site:cloud.google.com vertex ai`
39
+ - General fallback: `<provider> latest AI models 2026 API model id`
40
+ - For image entries, search specifically for image-generation model ids (e.g. `gpt-image-2 successor`, `gemini image preview latest`, `grok-imagine model id`).
41
+
42
+ 3. **Fetch the relevant documentation page(s)** with WebFetch to extract actual model identifiers — not marketing names. Look for:
43
+ - Stable model id strings (e.g. `gemini-3.1-pro`, `gpt-5.5`, `claude-opus-4-7`, `grok-4.20-reasoning`)
44
+ - Stable vs preview/experimental distinction (entries currently using `-preview` ids should stay on previews unless a stable replacement exists)
45
+ - Recommended / current vs deprecated status
46
+ - For Anthropic: prefer the current Sonnet/Opus/Haiku tier ids; verify whether dated suffixes are required.
47
+
48
+ **Known WebFetch-incompatible hosts — do not WebFetch these, use the alternative:**
49
+
50
+ | Don't fetch | Use instead | Why |
51
+ |---------------------------------------|----------------------------------------------------------|------------------------------------------------|
52
+ | `platform.openai.com/docs/...` | `developers.openai.com/api/docs/models/<id>` | `platform.openai.com` returns 403 to WebFetch |
53
+ | `docs.anthropic.com/en/docs/...` | `platform.claude.com/docs/en/docs/...` (after redirect) | `docs.anthropic.com` 301s to `platform.claude.com`; fetch the redirect URL directly to save a round-trip |
54
+ | `docs.x.ai/developers/models` | WebSearch result snippets + secondary sources (Vercel AI Gateway listings, OpenRouter, release-note aggregators) | The official models page often omits exact API ids in the rendered HTML WebFetch sees |
55
+
56
+ If a WebFetch returns 4xx, do **not** retry the same URL — switch to the alternative above (or fall back to WebSearch snippets) instead of burning more requests.
57
+
58
+ 4. **Compare** fetched ids against the config files. For each entry, determine:
59
+ - Is the current id still listed by the provider?
60
+ - Is there a newer stable or preview successor?
61
+ - Are there new tiers worth adding (e.g. a new "mini" / "nano" / "reasoning" model that fits `fast` or `thinking`)?
62
+
63
+ 5. **Present a summary table** to the user, separated by config file. Example:
64
+
65
+ ```
66
+ Provider: gemini
67
+
68
+ model_config.yaml
69
+ Tier Current Identifier Latest Available Status
70
+ ──── ────────────────── ──────────────── ──────
71
+ fast gemini-3-flash-preview gemini-3-flash ⚠ stable available
72
+ thinking gemini-3.1-pro-preview gemini-3.1-pro-preview ✓ up to date
73
+
74
+ image_model_config.yaml
75
+ Entry Current Identifier Latest Available Status
76
+ ───── ────────────────── ──────────────── ──────
77
+ gemini gemini-3-pro-image-preview gemini-3-pro-image-preview ✓ up to date
78
+ x_gemini gemini-3.1-flash-image-preview gemini-3.1-flash-image-preview ✓ up to date
79
+ ```
80
+
81
+ Status indicators:
82
+ - `✓ up to date` — current id is the latest recommended
83
+ - `⚠ update available` — a newer id exists (note: stable replacing preview is also `⚠`)
84
+ - `✗ deprecated` — current id is deprecated or removed
85
+ - `? unknown` — couldn't determine status
86
+
87
+ 6. **If updates are available**, show the exact YAML changes needed for the affected file(s) as a diff, but **do NOT apply them automatically**. Ask the user whether to apply.
88
+
89
+ ## Important Notes
90
+
91
+ - `model_config.yaml` model ids are bare provider-native ids (no `provider:` prefix). Preserve that format when suggesting updates — don't introduce a routing prefix that doesn't exist in this repo.
92
+ - The `vertex` provider in this repo runs Gemini models — its ids should match what Vertex AI exposes (which sometimes lags `ai.google.dev`). Don't blindly copy ai.google.dev ids into `vertex`; verify Vertex availability.
93
+ - `x_gemini` is an experimental/secondary slot under image providers — treat it as the "next preview" line. If the main `gemini` image entry catches up, the `x_gemini` slot should point one step ahead (next preview), not the same id.
94
+ - When uncertain whether a model is newer or just differently positioned (e.g. a "mini" sibling), flag it as `? check manually` rather than recommending a change.
95
+ - The repo's resolution order is `--model` flag > `$POLYPTYCH_MODEL` env (deprecated alias `$SLIDE_GEN_MODEL`) > config tiers — config changes affect every task that didn't override, so call out high-impact swaps (especially `thinking`-tier moves) before applying.
96
+ - Prefer stable/GA models over preview when one exists. If the current entry is on a `-preview` id and a stable successor has shipped, recommend the stable id but call out behaviour differences (preview models sometimes have different output formats / token limits).
@@ -0,0 +1,101 @@
1
+ ---
2
+ name: check-status
3
+ description: Check the current state of a pipeline output directory — which tasks are done, what's next, and key summary info
4
+ argument-hint: <output-directory>
5
+ ---
6
+
7
+ # Pipeline Status — Situational Awareness
8
+
9
+ ## Role
10
+
11
+ You are inspecting a pipeline output directory to understand its current state. Report what exists, what's valid, what's next, and key summary information.
12
+
13
+ ## Arguments
14
+
15
+ - `$ARGUMENTS` = path to the output directory (e.g., `generated/my-project`)
16
+
17
+ If no directory is provided, ask the user which output directory to check.
18
+
19
+ ## Process
20
+
21
+ ### Step 1: Run Schema Validation
22
+
23
+ Run the validate command to check all task outputs:
24
+
25
+ ```bash
26
+ uv run polyptych validate $ARGUMENTS --json
27
+ ```
28
+
29
+ This will:
30
+ - Auto-detect the pipeline type from files present
31
+ - Validate each task YAML against its Pydantic schema
32
+ - Run cross-task referential checks when 2+ task files exist (slide pipeline: dangling scene_beat_ids, slide-count mismatches across task3/4/6/7, out-of-range paragraph references, unknown source_sections, arc peaks at nonexistent slides; headline/quote word limits as warnings) — findings appear under `cross_task` in the JSON
33
+ - Report the next step to run
34
+
35
+ Surface any `cross_task` errors prominently in the status report — they indicate broken references between task files even when every file is schema-valid.
36
+
37
+ If the directory doesn't exist or is empty, report that and stop.
38
+
39
+ ### Step 2: Read the Manifest
40
+
41
+ If `$ARGUMENTS/manifest.yaml` exists, read it to extract:
42
+ - Source file path
43
+ - Style preset used
44
+ - Image provider and model
45
+ - Timestamp
46
+ - `mode: local` — the directory was produced by a local skill run (`/run-local-pipeline`, `/run-local-task`, `/infographic`): text-task YAMLs were Claude-generated (`models: claude-local`), image settings are absent until a CLI image run overwrites the manifest, and `tasks_completed` lists the finished text tasks
47
+
48
+ ### Step 3: Detect Pipeline Type and Count Outputs
49
+
50
+ Determine the pipeline type from which files are present:
51
+
52
+ | Pipeline | Detection Signal | Image Pattern |
53
+ |----------|-----------------|---------------|
54
+ | **Slide** | `task1-genre.yaml` or `task4-content.yaml` | `slide-NN.{jpg,png}` |
55
+ | **Infographic** | `task-i0-analysis.yaml` or `task-i1-design.yaml` | `infographic-vN.{jpg,png}` |
56
+
57
+ Count images in `$ARGUMENTS/images/` and prompt files in `$ARGUMENTS/prompts/`.
58
+
59
+ ### Step 4: Summarize Key Outputs
60
+
61
+ Read task YAML files to extract headline information. Be selective — only read what's present:
62
+
63
+ | Task File | Key Info to Extract |
64
+ |-----------|-------------------|
65
+ | `task1-genre.yaml` | Genre classification, essay type |
66
+ | `task3-structure.yaml` | Number of slides, structure type |
67
+ | `task-i0-analysis.yaml` | Content analysis summary |
68
+
69
+ Don't read entire files — use `yaml.safe_load()` and extract just the top-level keys.
70
+
71
+ ### Step 5: Report
72
+
73
+ Present a concise status report:
74
+
75
+ ```
76
+ Pipeline: infographic
77
+ Source: essays/my-essay.md
78
+ Style: semi-flat-vector
79
+ Provider: gemini
80
+
81
+ Tasks:
82
+ [OK] i0 task-i0-analysis.yaml
83
+ [OK] i1 task-i1-design.yaml
84
+ [---] i2 task-i2-prompts.yaml
85
+
86
+ Next step: i2
87
+ Images: 0 / 3 variants
88
+
89
+ Key info:
90
+ - Content type: analytical essay
91
+ - Sections: 5
92
+ ```
93
+
94
+ ### Step 6: Suggest Next Action
95
+
96
+ Based on the state, suggest what to do next:
97
+
98
+ - If no outputs exist: "Run the full pipeline with `/run-pipeline` or start a local task with `/run-local-task`"
99
+ - If partially complete: "Resume from `{next_step}` — run `/run-pipeline {pipeline} {source} {dir} --from {next_step}` or `/run-local-task {next_step} {dir}`"
100
+ - If all text tasks done but no images: "Text pipeline complete. Run image generation with `/run-pipeline {pipeline} {source} {dir} --from images`"
101
+ - If everything done: "Pipeline complete. Review images with `/review-regen {dir}`"
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: clean-source
3
+ description: Clean PDF-converted markdown files by removing page numbers, footnotes, TOC, broken images, and escaped characters
4
+ argument-hint: <input-file> [--output <file>] [--keep-footnotes] [--keep-toc]
5
+ ---
6
+
7
+ # Clean Source — PDF Markdown Cleanup
8
+
9
+ ## Role
10
+
11
+ You clean PDF-to-markdown conversion artifacts from source files before they are fed into pipelines.
12
+
13
+ ## Arguments
14
+
15
+ Parse from `$ARGUMENTS`:
16
+ - **input-file** (required): Path to the markdown file to clean
17
+ - Optional flags: `--output`, `--keep-toc`, `--keep-images`, `--keep-footnotes`, `--keep-page-numbers`, `--keep-escapes`, `--dry-run`
18
+
19
+ If the input file is missing, ask the user.
20
+
21
+ ## Process
22
+
23
+ 1. **Verify file exists** — check the input file path
24
+ 2. **Run cleaning** — execute `uv run polyptych clean-source <file> [flags]`
25
+ 3. **Report results** — show the cleaning statistics (lines removed, artifacts found)
26
+ 4. **Suggest next step** — recommend running a pipeline with the cleaned file, e.g.:
27
+ - `/run-local-pipeline slide <cleaned-file>`
28
+ - `/run-pipeline slide <cleaned-file> <output-dir>`
29
+
30
+ ## Tips
31
+
32
+ - Use `--dry-run` first to preview what will be removed without writing
33
+ - Use `--keep-footnotes` if the source uses inline citations that should be preserved
34
+ - The default output is `<stem>-clean.md` in the same directory as the input
@@ -0,0 +1,136 @@
1
+ ---
2
+ name: edit-output
3
+ description: Modify a pipeline task YAML output, validate it, and identify downstream tasks that need re-running
4
+ argument-hint: <output-dir> <task-name> <change-description>
5
+ ---
6
+
7
+ # Edit Pipeline Output — Modify and Resume
8
+
9
+ ## Role
10
+
11
+ You modify intermediate pipeline task outputs (YAML files), validate the changes against the Pydantic schema, and identify which downstream tasks need to be re-run.
12
+
13
+ ## Arguments
14
+
15
+ Parse from `$ARGUMENTS`:
16
+ - **output-dir**: Path to the output directory
17
+ - **task-name**: Which task output to edit (e.g., `task1`, `i0`, `i2`)
18
+ - **change-description**: Natural language description of what to change (e.g., "change slide 3's headline to...", "tighten the i1 color palette", "drop section 4 from the infographic")
19
+
20
+ If arguments are missing, ask the user.
21
+
22
+ ## Task Output Files
23
+
24
+ | Task | Output File | Model Class |
25
+ |------|-------------|-------------|
26
+ | task1 | `task1-genre.yaml` | `Task1Output` |
27
+ | task2 | `task2-analysis.yaml` | `Task2Output` |
28
+ | task3 | `task3-structure.yaml` | `Task3Output` |
29
+ | task4 | `task4-content.yaml` | `Task4Output` |
30
+ | task5 | `task5-design.yaml` | `Task5Output` |
31
+ | task6 | `task6-slides.yaml` | `Task6Output` |
32
+ | task7 | `task7-prompts.yaml` | `Task7Output` |
33
+ | i0 | `task-i0-analysis.yaml` | `TaskI0Output` |
34
+ | i1 | `task-i1-design.yaml` | `TaskI1Output` |
35
+ | i2 | `task-i2-prompts.yaml` | `TaskI2Output` |
36
+
37
+ ## Dependency Graph
38
+
39
+ Tasks that depend on the edited task will need re-running. Here are the downstream dependencies:
40
+
41
+ ### Slide Pipeline
42
+ ```
43
+ task1 → task2, task3, task4, task5, task6, task7
44
+ task2 → task3, task4, task5, task6
45
+ task3 → task4, task6
46
+ task4 → task5, task6
47
+ task5 → task6, task7
48
+ task6 → task7
49
+ task7 → images
50
+ ```
51
+
52
+ ### Infographic Pipeline
53
+ ```
54
+ i0 → i1, i2, images
55
+ i1 → i2, images
56
+ i2 → images
57
+ ```
58
+
59
+ ## Process
60
+
61
+ ### Step 1: Read Current Output
62
+
63
+ Read the task YAML file from `$OUTPUT_DIR/<output-file>`.
64
+
65
+ If the file doesn't exist, report it and stop.
66
+
67
+ ### Step 2: Read the Pydantic Model
68
+
69
+ Read the model class definition from `src/polyptych/models.py` to understand the schema constraints:
70
+ - Required fields and types
71
+ - Nested model structures
72
+ - Value constraints (min/max, enums, list lengths)
73
+
74
+ ### Step 3: Apply Changes
75
+
76
+ Based on the change description, modify the YAML data. Common edit patterns:
77
+
78
+ - **Change a field value**: Update the specific field
79
+ - **Add an item to a list**: Append with all required fields filled
80
+ - **Remove an item**: Delete from the list (may need to renumber)
81
+ - **Modify nested data**: Navigate to the correct nesting level
82
+ - **Bulk changes**: Apply the same change across multiple items
83
+
84
+ Preserve all fields that aren't being changed. Don't reformat or restructure unchanged data.
85
+
86
+ ### Step 4: Validate
87
+
88
+ Run schema validation:
89
+
90
+ ```bash
91
+ uv run polyptych validate $OUTPUT_DIR $TASK_NAME
92
+ ```
93
+
94
+ If validation fails:
95
+ - Read the error message
96
+ - Fix the issue (missing required field, wrong type, constraint violation)
97
+ - Re-validate
98
+
99
+ After saving, also run directory-level validation (`uv run polyptych validate $OUTPUT_DIR --json`): with 2+ task files present it performs cross-task checks (dangling scene_beat_ids, slide-set mismatches, out-of-range paragraph references, ...), which catch edits that broke references *between* files — e.g. removing a scene beat that a task4 allocation still cites.
100
+
101
+ ### Step 5: Save
102
+
103
+ Write the modified YAML back to the output file, overwriting the original.
104
+
105
+ ### Step 6: Identify Downstream Impact
106
+
107
+ Using the dependency graph above, list all downstream tasks that may need re-running because they depend on the edited task.
108
+
109
+ Categorize them:
110
+ - **Direct dependents**: Tasks that directly read this task's output
111
+ - **Transitive dependents**: Tasks that depend on direct dependents
112
+
113
+ ### Step 7: Suggest Resume Command
114
+
115
+ Build the command to re-run downstream tasks. The earliest downstream step is where to resume:
116
+
117
+ ```
118
+ To re-run affected downstream tasks:
119
+ just <target> SOURCE OUTPUT STYLE --from <earliest-affected-step>
120
+
121
+ Or selectively re-run specific tasks:
122
+ /run-local-task <task-name> <output-dir>
123
+ /run-pipeline <pipeline> <source> <output-dir> --from <step> --to <step>
124
+ ```
125
+
126
+ If only the images step is affected (e.g., editing image prompts in task7/i2), suggest:
127
+ ```
128
+ /run-pipeline <pipeline> <source> <output-dir> --from images
129
+ ```
130
+
131
+ ## Notes
132
+
133
+ - Always back up the original file mentally — if the edit goes wrong, the user can recover from git
134
+ - For large edits (e.g., restructuring all slides), consider whether `/run-local-task` to regenerate the entire task would be faster than manual editing
135
+ - When editing list items (slides, scenes, beats), be careful about maintaining consistent numbering and cross-references
136
+ - If the change affects counts (e.g., adding slides), downstream tasks that reference the count may produce inconsistent output — flag this