@gobing-ai/knowledge-kit 0.0.13 → 0.0.15

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 (125) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/dist/index.js +20 -0
  3. package/package.json +1 -1
  4. package/plugins/generations/content-gen/dist/index.js +20 -0
  5. package/plugins/generations/core-facts-gen/dist/index.js +20 -0
  6. package/plugins/generations/daily-article-gen/dist/index.js +29 -1
  7. package/plugins/generations/daily-article-gen/src/index.ts +13 -1
  8. package/plugins/generations/dailynews-gen/dist/index.js +20 -0
  9. package/plugins/generations/episode-plan-gen/dist/index.js +24 -0
  10. package/plugins/generations/episode-plan-gen/src/index.ts +11 -0
  11. package/plugins/generations/image-gen/dist/index.js +2296 -53
  12. package/plugins/generations/image-gen/src/providers/agnes.ts +110 -0
  13. package/plugins/generations/image-gen/src/providers/azure.ts +153 -0
  14. package/plugins/generations/image-gen/src/providers/codex-cli.ts +170 -0
  15. package/plugins/generations/image-gen/src/providers/dashscope.ts +485 -0
  16. package/plugins/generations/image-gen/src/providers/google.ts +268 -0
  17. package/plugins/generations/image-gen/src/providers/huggingface.ts +59 -0
  18. package/plugins/generations/image-gen/src/providers/jimeng.ts +259 -0
  19. package/plugins/generations/image-gen/src/providers/minimax.ts +171 -0
  20. package/plugins/generations/image-gen/src/providers/openai.ts +319 -0
  21. package/plugins/generations/image-gen/src/providers/openrouter.ts +257 -0
  22. package/plugins/generations/image-gen/src/providers/refs.ts +24 -0
  23. package/plugins/generations/image-gen/src/providers/replicate.ts +279 -0
  24. package/plugins/generations/image-gen/src/providers/seedream.ts +1 -1
  25. package/plugins/generations/image-gen/src/providers/types.ts +52 -51
  26. package/plugins/generations/image-gen/src/providers/zai.ts +237 -0
  27. package/plugins/generations/news-report-gen/dist/index.js +22193 -0
  28. package/plugins/generations/news-report-gen/package.json +17 -0
  29. package/plugins/generations/news-report-gen/plugin.json +7 -0
  30. package/plugins/generations/news-report-gen/src/index.ts +308 -0
  31. package/plugins/generations/news-report-gen/tsconfig.json +4 -0
  32. package/plugins/generations/omni-voice-gen/Makefile +14 -0
  33. package/plugins/generations/omni-voice-gen/README.md +118 -0
  34. package/plugins/generations/omni-voice-gen/bin/omni-voice-gen +2 -0
  35. package/plugins/generations/omni-voice-gen/dist/omni-voice-gen-prr8skpb. +2 -0
  36. package/plugins/generations/omni-voice-gen/dist/omni-voice-gen.js +6 -0
  37. package/plugins/generations/omni-voice-gen/plugin.json +6 -0
  38. package/plugins/generations/omni-voice-gen/profiles.json +16 -0
  39. package/plugins/generations/omni-voice-gen/pyproject.toml +25 -0
  40. package/plugins/generations/omni-voice-gen/scripts/coverage_gate.py +74 -0
  41. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/__init__.py +1 -0
  42. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/__main__.py +39 -0
  43. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/audio.py +190 -0
  44. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/backend.py +161 -0
  45. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/contract.py +76 -0
  46. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/mp3.py +60 -0
  47. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/pipeline.py +305 -0
  48. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/profiles.py +108 -0
  49. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/qc.py +234 -0
  50. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/voicescript.py +340 -0
  51. package/plugins/generations/omni-voice-gen/uv.lock +3510 -0
  52. package/plugins/generations/omni-voice-gen/voices/robin-news.wav +0 -0
  53. package/plugins/generations/voice-gen/dist/index.js +30 -2
  54. package/plugins/generations/voice-gen/src/index.ts +16 -1
  55. package/plugins/generations/voice-gen/src/voicebox-client.ts +3 -1
  56. package/plugins/ingestions/aihot-ingest/dist/index.js +20 -0
  57. package/plugins/ingestions/horizon-ingest/dist/index.js +20 -0
  58. package/plugins/ingestions/last30days-ingest/dist/index.js +20 -0
  59. package/plugins/ingestions/web-search/dist/index.js +20 -0
  60. package/plugins/kk/commands/image-extract.md +40 -0
  61. package/plugins/kk/commands/image-generate.md +18 -1
  62. package/plugins/kk/commands/workflow-run.md +54 -22
  63. package/plugins/kk/config.example.yaml +5 -0
  64. package/plugins/kk/plugin.json +1 -1
  65. package/plugins/kk/scripts/kk-workflow-stages.ts +1226 -0
  66. package/plugins/kk/{workflows → scripts}/validate-voicescript.ts +4 -4
  67. package/plugins/kk/{workflows → scripts}/wrap-voicescript-doc.ts +7 -6
  68. package/plugins/kk/skills/audio-authoring/SKILL.md +11 -12
  69. package/plugins/kk/skills/image-authoring/SKILL.md +10 -3
  70. package/plugins/kk/skills/image-authoring/references/format-drafting.md +57 -0
  71. package/plugins/kk/skills/image-authoring/references/style-extraction.md +14 -9
  72. package/plugins/kk/skills/itc-generating/SKILL.md +2 -2
  73. package/plugins/kk/skills/itc-generating/references/generic-craft.md +1 -1
  74. package/plugins/kk/skills/itc-generating/references/platform-english.md +1 -1
  75. package/plugins/kk/skills/itc-generating/references/platform-wechat.md +1 -1
  76. package/plugins/kk/skills/storm-research/SKILL.md +5 -5
  77. package/plugins/kk/skills/topic/SKILL.md +7 -7
  78. package/plugins/kk/workflows/kk-daily-ai-voice.yaml +219 -133
  79. package/plugins/kk/workflows/kk-itc.yaml +12 -29
  80. package/plugins/kk/workflows/kk-solo-podcast.yaml +72 -131
  81. package/plugins/kk/workflows/kk-storm-research.yaml +12 -62
  82. package/plugins/publishings/emdash-pub/dist/index.js +20 -0
  83. package/plugins/publishings/podcast-pub/dist/index.js +57 -3
  84. package/plugins/publishings/podcast-pub/src/index.ts +18 -2
  85. package/plugins/publishings/podcast-pub/src/show-notes.ts +56 -9
  86. package/plugins/publishings/qiita-pub/dist/index.js +20 -0
  87. package/plugins/publishings/surfdash-pub/dist/index.js +96 -6
  88. package/plugins/publishings/surfdash-pub/src/index.ts +109 -9
  89. package/plugins/publishings/zenn-pub/dist/index.js +20 -0
  90. package/plugins/sp/scripts/batch-preflight.mjs +346 -0
  91. package/plugins/sp/scripts/batch-preflight.ts +459 -0
  92. package/plugins/sp/scripts/daily-summary/daily-summary.mjs +615 -0
  93. package/plugins/sp/scripts/daily-summary/daily-summary.ts +846 -0
  94. package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
  95. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +223 -0
  96. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +367 -0
  97. package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +132 -0
  98. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +169 -0
  99. package/plugins/sp/scripts/feature-dev-precheck.mjs +171 -0
  100. package/plugins/sp/scripts/feature-dev-precheck.ts +238 -0
  101. package/plugins/sp/scripts/feature-sync-bounded.mjs +285 -0
  102. package/plugins/sp/scripts/feature-sync-bounded.ts +478 -0
  103. package/plugins/sp/scripts/history-anatomy-cache.mjs +902 -0
  104. package/plugins/sp/scripts/history-anatomy-cache.ts +1028 -0
  105. package/plugins/sp/scripts/idea-handoff.mjs +22 -0
  106. package/plugins/sp/scripts/idea-handoff.ts +44 -0
  107. package/plugins/sp/scripts/inline-pipeline-parity-check.ts +185 -0
  108. package/plugins/sp/scripts/inline-run-setup.ts +198 -0
  109. package/plugins/sp/scripts/pr-reviewing.mjs +769 -0
  110. package/plugins/sp/scripts/pr-reviewing.ts +925 -0
  111. package/plugins/sp/scripts/quality-gate.mjs +179 -0
  112. package/plugins/sp/scripts/quality-gate.ts +217 -0
  113. package/plugins/sp/scripts/script-contract-check.ts +319 -0
  114. package/plugins/sp/scripts/stage-registry-adapter.ts +1533 -0
  115. package/plugins/sp/scripts/surface-drift-inventory.ts +929 -0
  116. package/plugins/sp/scripts/task-evidence-precheck.ts +181 -0
  117. package/plugins/sp/scripts/task-size-precheck.ts +175 -0
  118. package/plugins/sp/scripts/transition-shim-check.ts +238 -0
  119. package/plugins/sp/scripts/validate-commands.ts +689 -0
  120. package/plugins/sp/scripts/validate-flag-contracts.ts +878 -0
  121. package/plugins/sp/scripts/verify-answer-lint.ts +530 -0
  122. package/plugins/sp/scripts/workflow-step-profile.mjs +316 -0
  123. package/plugins/sp/scripts/workflow-step-profile.ts +456 -0
  124. package/plugins/sp/scripts/wrapup-steps.mjs +373 -0
  125. package/plugins/sp/scripts/wrapup-steps.ts +466 -0
@@ -29,34 +29,17 @@ vars:
29
29
 
30
30
  states:
31
31
  - id: prepare
32
- description: "mkdir work_dir, 2-outline, 3-draft; validate XOR topic/input_file; write brief.md"
32
+ description: "mkdir work_dir, 2-outline; validate XOR topic/input_file; write brief.md"
33
33
  onEnter:
34
34
  - kind: shell
35
35
  options:
36
36
  command: >-
37
- set -e;
38
- if [ -z "${vars.work_dir}" ]; then
39
- echo "missing work_dir" >&2; exit 1;
40
- fi;
41
- mkdir -p "${vars.work_dir}" "${vars.work_dir}/2-outline" "${vars.work_dir}/3-draft";
42
- echo 0 > "${vars.work_dir}/.revise-count";
43
- if [ -n "${vars.topic}" ] && [ -n "${vars.input_file}" ]; then
44
- echo "XOR violation: both topic and input_file set" >&2; exit 1;
45
- fi;
46
- if [ -z "${vars.topic}" ] && [ -z "${vars.input_file}" ]; then
47
- echo "XOR violation: neither topic nor input_file set" >&2; exit 1;
48
- fi;
49
- if [ -f "${vars.work_dir}/brief.md" ] && [ "${vars.force}" != "true" ]; then
50
- echo "initialization target already exists at ${vars.work_dir}/brief.md; pass force=true to replace" >&2; exit 1;
51
- fi;
52
- if [ -n "${vars.topic}" ]; then
53
- printf '%s\n' "${vars.topic}" > "${vars.work_dir}/brief.md";
54
- else
55
- if [ ! -f "${vars.input_file}" ]; then
56
- echo "input file not found: ${vars.input_file}" >&2; exit 1;
57
- fi;
58
- cp "${vars.input_file}" "${vars.work_dir}/brief.md";
59
- fi;
37
+ kbin="$(command -v kk 2>/dev/null)";
38
+ pkg="$(dirname "$(dirname "$(realpath "$kbin" 2>/dev/null)")")";
39
+ st="$pkg/plugins/kk/scripts/kk-workflow-stages.ts";
40
+ [ -f "$st" ] || st="plugins/kk/scripts/kk-workflow-stages.ts";
41
+ [ -f "$st" ] || echo "kk-workflow-stages.ts not found at $st — install or refresh the kk package (bun link in a checkout)" >&2;
42
+ bun "$st" prepare-itc "${vars.work_dir}" "${vars.topic}" "${vars.input_file}" "${vars.force}"
60
43
 
61
44
  - id: research
62
45
  description: "Conduct preliminary topic research via storm-research (agent.run)"
@@ -123,9 +106,9 @@ states:
123
106
  agent: ${vars.agent}
124
107
  input: |
125
108
  Invoke the kk:${vars.writer} skill.
126
- Author the technical draft at ${vars.work_dir}/3-draft/draft-article.md based on approved outline ${vars.work_dir}/2-outline/outline-approved.md and brief ${vars.work_dir}/brief.md using playbook ${vars.playbook}.
109
+ Author the technical draft at ${vars.work_dir}/3-draft-draft-article.md based on approved outline ${vars.work_dir}/2-outline/outline-approved.md and brief ${vars.work_dir}/brief.md using playbook ${vars.playbook}.
127
110
  Revision feedback: ${vars.__hitlInput}
128
- expectFile: ${vars.work_dir}/3-draft/draft-article.md
111
+ expectFile: ${vars.work_dir}/3-draft-draft-article.md
129
112
 
130
113
  - id: draft-review
131
114
  description: "Operator reviews and approves or requests revision on draft-article.md"
@@ -133,7 +116,7 @@ states:
133
116
  onEnter:
134
117
  - kind: hitl.confirm
135
118
  options:
136
- prompt: "Review draft at ${vars.work_dir}/3-draft/draft-article.md. Approve?"
119
+ prompt: "Review draft at ${vars.work_dir}/3-draft-draft-article.md. Approve?"
137
120
  var: __hitlAnswer
138
121
 
139
122
  - id: draft-revise
@@ -147,7 +130,7 @@ states:
147
130
  echo $((n + 1)) > "${vars.work_dir}/.revise-count";
148
131
  - kind: hitl.input
149
132
  options:
150
- prompt: "Provide specific revision feedback for ${vars.work_dir}/3-draft/draft-article.md:"
133
+ prompt: "Provide specific revision feedback for ${vars.work_dir}/3-draft-draft-article.md:"
151
134
  var: __hitlInput
152
135
 
153
136
  - id: judge
@@ -159,7 +142,7 @@ states:
159
142
  agent: ${vars.agent}
160
143
  input: |
161
144
  Invoke the kk:content-judge skill.
162
- Evaluate the draft at ${vars.work_dir}/3-draft/draft-article.md against the ${vars.rubric} rubric.
145
+ Evaluate the draft at ${vars.work_dir}/3-draft-draft-article.md against the ${vars.rubric} rubric.
163
146
  Write the verdict JSON to ${vars.work_dir}/.itc-verdict.json per the skill's verdict contract.
164
147
  Print the verdict path as the last line of stdout.
165
148
  expectFile: ${vars.work_dir}/.itc-verdict.json
@@ -37,33 +37,16 @@ states:
37
37
  onEnter:
38
38
  - kind: shell
39
39
  options:
40
- command: >-
41
- set -e;
42
- if [ -z "${vars.work_dir}" ]; then
43
- echo "missing work_dir" >&2; exit 1;
44
- fi;
45
- mkdir -p "${vars.work_dir}" "${vars.work_dir}/1-briefing" "${vars.work_dir}/2-outline" "${vars.work_dir}/3-script" "${vars.work_dir}/4-audio";
46
- if [ -n "${vars.topic}" ] && [ -n "${vars.input_file}" ]; then
47
- echo "XOR violation: both topic and input_file set" >&2; exit 1;
48
- fi;
49
- if [ -z "${vars.topic}" ] && [ -z "${vars.input_file}" ]; then
50
- echo "XOR violation: neither topic nor input_file set" >&2; exit 1;
51
- fi;
52
- if [ -z "${vars.voice_profile}" ] && [ -z "$VOICEBOX_DEFAULT_PROFILE" ]; then
53
- echo "missing voice_profile (set vars.voice_profile or VOICEBOX_DEFAULT_PROFILE)" >&2; exit 1;
54
- fi;
55
- if [ -f "${vars.work_dir}/brief.md" ] && [ "${vars.force}" != "true" ]; then
56
- echo "initialization target already exists at ${vars.work_dir}/brief.md; pass force=true to replace" >&2; exit 1;
57
- fi;
58
- if [ -n "${vars.topic}" ]; then
59
- printf '%s\n' "${vars.topic}" > "${vars.work_dir}/brief.md";
60
- else
61
- if [ ! -f "${vars.input_file}" ]; then
62
- echo "input file not found: ${vars.input_file}" >&2; exit 1;
63
- fi;
64
- cp "${vars.input_file}" "${vars.work_dir}/brief.md";
65
- fi;
66
- echo 0 > "${vars.work_dir}/.revise-count";
40
+ # ADR-115: the XOR / voice_profile / overwrite / brief logic lives in the
41
+ # solo-podcast stage runner; this action only resolves the package root and
42
+ # delegates (one logical call).
43
+ command: >-
44
+ kbin="$(command -v kk 2>/dev/null)";
45
+ pkg="$(dirname "$(dirname "$(realpath "$kbin" 2>/dev/null)")")";
46
+ st="$pkg/plugins/kk/scripts/kk-workflow-stages.ts";
47
+ [ -f "$st" ] || st="plugins/kk/scripts/kk-workflow-stages.ts";
48
+ [ -f "$st" ] || echo "kk-workflow-stages.ts not found at $st — install or refresh the kk package (bun link in a checkout)" >&2;
49
+ bun "$st" prepare-solo "${vars.work_dir}" "${vars.topic}" "${vars.input_file}" "${vars.voice_profile}" "${vars.force}"
67
50
 
68
51
  - id: understand
69
52
  description: "Analyze brief and generate podcast briefing (agent.run)"
@@ -75,10 +58,10 @@ states:
75
58
  input: |
76
59
  Invoke the kk:audio-authoring skill: operation `briefing`, mode `solo`.
77
60
  Read the source brief at ${vars.work_dir}/brief.md.
78
- Write a concise podcast briefing at ${vars.work_dir}/1-briefing/briefing.md.
61
+ Write a concise podcast briefing at ${vars.work_dir}/1-briefing-briefing.md.
79
62
  Identify core thesis, key listener takeaways, audience profile, target spoken duration (${vars.target_duration_min} minutes), tone, and what material from the brief to emphasize or cut.
80
63
  Flags: --dir ${vars.work_dir} --duration ${vars.target_duration_min}
81
- expectFile: ${vars.work_dir}/1-briefing/briefing.md
64
+ expectFile: ${vars.work_dir}/1-briefing-briefing.md
82
65
 
83
66
  - id: outline-write
84
67
  description: "Generate spoken podcast outline options (agent.run)"
@@ -89,7 +72,7 @@ states:
89
72
  agent: ${vars.agent}
90
73
  input: |
91
74
  Invoke the kk:audio-authoring skill: operation `outline`, mode `solo`.
92
- Read the briefing at ${vars.work_dir}/1-briefing/briefing.md and brief at ${vars.work_dir}/brief.md.
75
+ Read the briefing at ${vars.work_dir}/1-briefing-briefing.md and brief at ${vars.work_dir}/brief.md.
93
76
  Generate spoken podcast outline options in ${vars.work_dir}/2-outline/:
94
77
  - outline-option-a.md (e.g. narrative / storytelling arc)
95
78
  - outline-option-b.md (e.g. analytical / explainer breakdown)
@@ -100,8 +83,8 @@ states:
100
83
  expectFile: ${vars.work_dir}/2-outline/outline-option-a.md
101
84
  - kind: shell
102
85
  options:
103
- command: >-
104
- test -f "${vars.work_dir}/2-outline/outline-option-b.md" || { echo "missing required outline-option-b.md" >&2; exit 1; }
86
+ command: >-
87
+ test -f "${vars.work_dir}/2-outline/outline-option-b.md" || { echo "missing required outline-option-b.md" >&2; exit 1; }
105
88
 
106
89
  - id: outline-select
107
90
  description: "Operator selects preferred outline option"
@@ -121,15 +104,15 @@ states:
121
104
  onEnter:
122
105
  - kind: shell
123
106
  options:
124
- command: >-
125
- sel="${vars.outline}";
126
- if [ -z "$sel" ]; then sel="${vars.__hitlAnswer}"; fi;
127
- if [ -z "$sel" ]; then sel="a"; fi;
128
- src="${vars.work_dir}/2-outline/outline-option-$sel.md";
129
- if [ ! -f "$src" ]; then
130
- echo "selected outline file not found: $src" >&2; exit 1;
131
- fi;
132
- cp "$src" "${vars.work_dir}/2-outline/outline-approved.md";
107
+ command: >-
108
+ sel="${vars.outline}";
109
+ if [ -z "$sel" ]; then sel="${vars.__hitlAnswer}"; fi;
110
+ if [ -z "$sel" ]; then sel="a"; fi;
111
+ src="${vars.work_dir}/2-outline/outline-option-$sel.md";
112
+ if [ ! -f "$src" ]; then
113
+ echo "selected outline file not found: $src" >&2; exit 1;
114
+ fi;
115
+ cp "$src" "${vars.work_dir}/2-outline/outline-approved.md";
133
116
 
134
117
  - id: script-write
135
118
  description: "Author complete VoiceScript YAML from approved outline (agent.run)"
@@ -138,51 +121,32 @@ states:
138
121
  options:
139
122
  role: scribe
140
123
  agent: ${vars.agent}
124
+ # ADR-115 (R3): the VoiceScript field contract is the skill's own
125
+ # templates/voicescript.solo.yaml (task 0081) — not duplicated here. The prompt
126
+ # stays a bounded skill invocation: operation + inputs + output path + budget.
141
127
  input: |
142
128
  Invoke the kk:audio-authoring skill: operation `script`, mode `solo`.
143
- Read the approved outline at ${vars.work_dir}/2-outline/outline-approved.md and briefing at ${vars.work_dir}/1-briefing/briefing.md.
144
- Target duration is ${vars.target_duration_min} minutes.
145
- Spoken budget: if language (${vars.language}) is zh, ja, or ko, target characters = ${vars.target_duration_min} * ${vars.cjk_chars_per_min}; otherwise target words = ${vars.target_duration_min} * ${vars.words_per_min}. Land inside ±20%, spoken prose, one speaker.
146
- Author the complete solo-podcast VoiceScript YAML at ${vars.work_dir}/3-script/voicescript.yaml.
147
- Emit ONLY valid YAML (no markdown fences, no repo/docs paths). Contract:
148
- title: string
149
- language: "${vars.language}"
150
- default_profile: "${vars.voice_profile}"
151
- default_engine: qwen|qwen_custom_voice|luxtts|chatterbox|chatterbox_turbo|tada|kokoro # optional
152
- segments:
153
- - text: "spoken sentence" # required, 1..50000 characters
154
- gap_ms: 400 # optional, >= 0, silence before next clip
155
- instruct: "warm" # optional, <= 500 characters
156
- Do not invent fields. Revision feedback: ${vars.__hitlInput}
157
- Duration retries: if ${vars.work_dir}/.duration-feedback exists, invoke with `--force` (authorized rewrite) and treat its contents as the revision feedback.
158
- Flags: --dir ${vars.work_dir} --duration ${vars.target_duration_min} --language ${vars.language} --profile ${vars.voice_profile} --revise "${vars.__hitlInput}"
159
- expectFile: ${vars.work_dir}/3-script/voicescript.yaml
129
+ Inputs: briefing ${vars.work_dir}/1-briefing-briefing.md; approved outline ${vars.work_dir}/2-outline/outline-approved.md; revision feedback ${vars.__hitlInput}.
130
+ Contract: the skill's templates/voicescript.solo.yaml — `language: "${vars.language}"`, `segments` of spoken text; no `default_profile`, no `title`, no invented fields.
131
+ Budget: ${vars.target_duration_min} min — zh/ja/ko ${vars.cjk_chars_per_min} chars/min, else ${vars.words_per_min} words/min; within ±20%, one speaker.
132
+ Write ONLY the YAML (no fences, no repo paths) to ${vars.work_dir}/3-script-voicescript.yaml.
133
+ Flags: --dir ${vars.work_dir} --duration ${vars.target_duration_min} --language ${vars.language} --profile ${vars.voice_profile} --revise "${vars.__hitlInput}"; add --force when ${vars.work_dir}/.duration-feedback exists (its contents are the revision feedback).
134
+ expectFile: ${vars.work_dir}/3-script-voicescript.yaml
160
135
 
161
136
  - id: script-validate
162
137
  description: "Validate authored VoiceScript YAML structure and constraints"
163
138
  onEnter:
164
139
  - kind: shell
165
140
  options:
166
- command: >-
167
- set -e;
168
- vs="${vars.validate_script}";
169
- if [ ! -f "$vs" ]; then
170
- kbin="$(command -v kk 2>/dev/null || true)";
171
- while [ -L "$kbin" ]; do
172
- link="$(readlink "$kbin")";
173
- case "$link" in /*) kbin="$link";; *) kbin="$(dirname "$kbin")/$link";; esac;
174
- done;
175
- pkg=""; [ -n "$kbin" ] && pkg="$(cd "$(dirname "$kbin")/.." 2>/dev/null && pwd || true)";
176
- vs="";
177
- if [ -n "$KK_WORKFLOWS_DIR" ] && [ -f "$KK_WORKFLOWS_DIR/validate-voicescript.ts" ]; then vs="$KK_WORKFLOWS_DIR/validate-voicescript.ts";
178
- elif [ -n "$pkg" ] && [ -f "$pkg/plugins/kk/workflows/validate-voicescript.ts" ]; then vs="$pkg/plugins/kk/workflows/validate-voicescript.ts";
179
- elif [ -f "$HOME/.config/kk/workflows/validate-voicescript.ts" ]; then vs="$HOME/.config/kk/workflows/validate-voicescript.ts"; fi;
180
- fi;
181
- if [ -z "$vs" ]; then
182
- echo "validate_script not found (searched: \$KK_WORKFLOWS_DIR, kk package root via \`command -v kk\`, \$HOME/.config/kk/workflows) — install the kk package or place an override with /workflow-run kk-solo-podcast --force" >&2;
183
- exit 1;
184
- fi;
185
- bun "$vs" --in "${vars.work_dir}/3-script/voicescript.yaml"
141
+ # ADR-115: package-root resolution + delegation to validate-voicescript.ts
142
+ # (override chain preserved inside the stage runner).
143
+ command: >-
144
+ kbin="$(command -v kk 2>/dev/null)";
145
+ pkg="$(dirname "$(dirname "$(realpath "$kbin" 2>/dev/null)")")";
146
+ st="$pkg/plugins/kk/scripts/kk-workflow-stages.ts";
147
+ [ -f "$st" ] || st="plugins/kk/scripts/kk-workflow-stages.ts";
148
+ [ -f "$st" ] || echo "kk-workflow-stages.ts not found at $st — install or refresh the kk package (bun link in a checkout)" >&2;
149
+ bun "$st" validate "${vars.validate_script}" --in "${vars.work_dir}/3-script-voicescript.yaml"
186
150
 
187
151
  - id: script-review
188
152
  description: "Operator reviews and approves VoiceScript before live TTS generation"
@@ -190,7 +154,7 @@ states:
190
154
  onEnter:
191
155
  - kind: hitl.confirm
192
156
  options:
193
- prompt: "Review VoiceScript at ${vars.work_dir}/3-script/voicescript.yaml. Approve for voice generation?"
157
+ prompt: "Review VoiceScript at ${vars.work_dir}/3-script-voicescript.yaml. Approve for voice generation?"
194
158
  var: __hitlAnswer
195
159
 
196
160
  - id: script-revise
@@ -199,13 +163,13 @@ states:
199
163
  onEnter:
200
164
  - kind: shell
201
165
  options:
202
- command: >-
203
- rm -f "${vars.work_dir}/.duration-feedback";
204
- n=$(cat "${vars.work_dir}/.revise-count" 2>/dev/null || echo 0);
205
- echo $((n + 1)) > "${vars.work_dir}/.revise-count";
166
+ command: >-
167
+ rm -f "${vars.work_dir}/.duration-feedback";
168
+ n=$(cat "${vars.work_dir}/.revise-count" 2>/dev/null || echo 0);
169
+ echo $((n + 1)) > "${vars.work_dir}/.revise-count";
206
170
  - kind: hitl.input
207
171
  options:
208
- prompt: "Provide specific revision feedback for ${vars.work_dir}/3-script/voicescript.yaml:"
172
+ prompt: "Provide specific revision feedback for ${vars.work_dir}/3-script-voicescript.yaml:"
209
173
  var: __hitlInput
210
174
 
211
175
  - id: wrap-docs
@@ -213,65 +177,42 @@ states:
213
177
  onEnter:
214
178
  - kind: shell
215
179
  options:
216
- command: >-
217
- set -e;
218
- ws="${vars.wrap_script}";
219
- if [ ! -f "$ws" ]; then
220
- kbin="$(command -v kk 2>/dev/null || true)";
221
- while [ -L "$kbin" ]; do
222
- link="$(readlink "$kbin")";
223
- case "$link" in /*) kbin="$link";; *) kbin="$(dirname "$kbin")/$link";; esac;
224
- done;
225
- pkg=""; [ -n "$kbin" ] && pkg="$(cd "$(dirname "$kbin")/.." 2>/dev/null && pwd || true)";
226
- ws="";
227
- if [ -n "$KK_WORKFLOWS_DIR" ] && [ -f "$KK_WORKFLOWS_DIR/wrap-voicescript-doc.ts" ]; then ws="$KK_WORKFLOWS_DIR/wrap-voicescript-doc.ts";
228
- elif [ -n "$pkg" ] && [ -f "$pkg/plugins/kk/workflows/wrap-voicescript-doc.ts" ]; then ws="$pkg/plugins/kk/workflows/wrap-voicescript-doc.ts";
229
- elif [ -f "$HOME/.config/kk/workflows/wrap-voicescript-doc.ts" ]; then ws="$HOME/.config/kk/workflows/wrap-voicescript-doc.ts"; fi;
230
- fi;
231
- if [ -z "$ws" ]; then
232
- echo "wrap_script not found (searched: \$KK_WORKFLOWS_DIR, kk package root via \`command -v kk\`, \$HOME/.config/kk/workflows) — install the kk package or place an override with /workflow-run kk-solo-podcast --force" >&2;
233
- exit 1;
234
- fi;
235
- bun "$ws" "${vars.work_dir}/3-script/voicescript.yaml" "${vars.work_dir}/4-audio/docs.json" "${vars.voice_profile}"
180
+ # ADR-115: package-root resolution + delegation to wrap-voicescript-doc.ts
181
+ # (override chain preserved inside the stage runner).
182
+ command: >-
183
+ kbin="$(command -v kk 2>/dev/null)";
184
+ pkg="$(dirname "$(dirname "$(realpath "$kbin" 2>/dev/null)")")";
185
+ st="$pkg/plugins/kk/scripts/kk-workflow-stages.ts";
186
+ [ -f "$st" ] || st="plugins/kk/scripts/kk-workflow-stages.ts";
187
+ [ -f "$st" ] || echo "kk-workflow-stages.ts not found at $st — install or refresh the kk package (bun link in a checkout)" >&2;
188
+ bun "$st" wrap "${vars.wrap_script}" --in "${vars.work_dir}/3-script-voicescript.yaml" --out "${vars.work_dir}/4-audio/docs.json" --profile "${vars.voice_profile}"
236
189
 
237
190
  - id: generate
238
191
  description: "Invoke voice-gen generator plugin to generate audio"
239
192
  onEnter:
240
193
  - kind: shell
241
194
  options:
242
- command: >-
243
- set -e;
244
- extra="";
245
- if [ -n "${vars.plugins_path}" ]; then extra="--plugins-path ${vars.plugins_path}"; fi;
246
- kk executor run voice-gen --in "${vars.work_dir}/4-audio/docs.json" --out "${vars.work_dir}/4-audio/content.json" $extra
195
+ command: >-
196
+ set -e;
197
+ extra="";
198
+ if [ -n "${vars.plugins_path}" ]; then extra="--plugins-path ${vars.plugins_path}"; fi;
199
+ kk executor run voice-gen --in "${vars.work_dir}/4-audio/docs.json" --out "${vars.work_dir}/4-audio/content.json" $extra
247
200
 
248
201
  - id: duration-check
249
202
  description: "Validate generated audio duration against target budget; miss writes .duration-feedback for the retry edge"
250
203
  onEnter:
251
204
  - kind: shell
252
205
  options:
253
- command: >-
254
- rm -f "${vars.work_dir}/4-audio/.duration-ok";
255
- if [ ! -f "${vars.work_dir}/4-audio/content.json" ]; then
256
- exit 0;
257
- fi;
258
- dur=$(jq -r '.metadata.duration // empty' "${vars.work_dir}/4-audio/content.json" 2>/dev/null);
259
- if [ -z "$dur" ]; then
260
- printf 'Regenerate: audio metadata.duration missing or not a number.\n' > "${vars.work_dir}/.duration-feedback";
261
- n=$(cat "${vars.work_dir}/.revise-count" 2>/dev/null || echo 0);
262
- echo $((n+1)) > "${vars.work_dir}/.revise-count";
263
- exit 0;
264
- fi;
265
- target_s=$((${vars.target_duration_min} * 60));
266
- min_s=$(awk -v t="$target_s" 'BEGIN {print t * 0.5}');
267
- max_s=$(awk -v t="$target_s" 'BEGIN {print t * 2.0}');
268
- if awk -v d="$dur" -v min="$min_s" -v max="$max_s" 'BEGIN { exit !(d >= min && d <= max) }'; then
269
- touch "${vars.work_dir}/4-audio/.duration-ok";
270
- else
271
- printf 'Regenerate: last audio duration %ss outside 0.5x–2x of %ss; adjust segment lengths toward the target.\n' "$dur" "$target_s" > "${vars.work_dir}/.duration-feedback";
272
- n=$(cat "${vars.work_dir}/.revise-count" 2>/dev/null || echo 0);
273
- echo $((n+1)) > "${vars.work_dir}/.revise-count";
274
- fi
206
+ # ADR-115: the band math, .duration-feedback, and .revise-count bump live in
207
+ # the solo-podcast stage runner; the transition guards below still branch on
208
+ # .duration-ok.
209
+ command: >-
210
+ kbin="$(command -v kk 2>/dev/null)";
211
+ pkg="$(dirname "$(dirname "$(realpath "$kbin" 2>/dev/null)")")";
212
+ st="$pkg/plugins/kk/scripts/kk-workflow-stages.ts";
213
+ [ -f "$st" ] || st="plugins/kk/scripts/kk-workflow-stages.ts";
214
+ [ -f "$st" ] || echo "kk-workflow-stages.ts not found at $st — install or refresh the kk package (bun link in a checkout)" >&2;
215
+ bun "$st" duration "${vars.work_dir}" "${vars.target_duration_min}"
275
216
 
276
217
  - id: done
277
218
  description: "Terminal — Solo podcast VoiceScript and audio generated successfully"
@@ -52,49 +52,12 @@ states:
52
52
  - kind: shell
53
53
  options:
54
54
  command: >-
55
- set -e;
56
- mkdir -p "${vars.work_dir}";
57
- if [ -n "${vars.topic}" ] && [ -n "${vars.input_file}" ]; then
58
- echo "XOR violation: both topic and input_file set" >&2; exit 1;
59
- fi;
60
- if [ -z "${vars.topic}" ] && [ -z "${vars.input_file}" ]; then
61
- echo "XOR violation: neither topic nor input_file set" >&2;
62
- exit 1;
63
- fi;
64
- if [ -n "${vars.topic}" ]; then
65
- jq -n --arg topic "${vars.topic}" --arg maxResults
66
- "${vars.maxResults}" --arg fixture "${vars.fixture}"
67
- '{topic: $topic, maxResults: ($maxResults | tonumber),
68
- fixture: ($fixture == "true")}' > "${vars.work_dir}/topic.json";
69
- exit 0;
70
- fi;
71
- if [ -f "${vars.input_file}" ]; then
72
- cp "${vars.input_file}" "${vars.work_dir}/input.md";
73
- ABS=$(cd "$(dirname "${vars.input_file}")" && pwd)/$(basename
74
- "${vars.input_file}");
75
- QUERY=$(grep -m1 '^# ' "${vars.input_file}" | sed 's/^# *//'
76
- || true);
77
- if [ -z "$QUERY" ]; then
78
- QUERY=$(basename "${vars.input_file}" | sed 's/\.[^.]*$//');
79
- fi;
80
- if [ -z "$QUERY" ]; then
81
- echo "no query derivable (no H1 and empty basename)" >&2;
82
- exit 1;
83
- fi;
84
- ID=$(printf 'file://%s' "$ABS" | shasum -a 256 | cut -c1-16);
85
- jq -n --arg id "$ID" --arg body "$(cat "${vars.input_file}")"
86
- --arg title "$QUERY" --arg sourceUri "file://$ABS" --arg query
87
- "$QUERY" '{id: $id, body: $body, title: $title, sourceUri:
88
- $sourceUri, mediaType: "text/markdown",
89
- metadata: {query: $query, rank: -1, position: 0}}'
90
- > "${vars.work_dir}/local-doc.json";
91
- jq -n --arg topic "$QUERY" --arg maxResults
92
- "${vars.maxResults}" --arg fixture "${vars.fixture}"
93
- '{topic: $topic, maxResults: ($maxResults | tonumber),
94
- fixture: ($fixture == "true")}' > "${vars.work_dir}/topic.json";
95
- else
96
- echo "input_file not readable: ${vars.input_file}" >&2; exit 1;
97
- fi
55
+ kbin="$(command -v kk 2>/dev/null)";
56
+ pkg="$(dirname "$(dirname "$(realpath "$kbin" 2>/dev/null)")")";
57
+ st="$pkg/plugins/kk/scripts/kk-workflow-stages.ts";
58
+ [ -f "$st" ] || st="plugins/kk/scripts/kk-workflow-stages.ts";
59
+ [ -f "$st" ] || echo "kk-workflow-stages.ts not found at $st — install or refresh the kk package (bun link in a checkout)" >&2;
60
+ bun "$st" prepare-storm "${vars.work_dir}" "${vars.topic}" "${vars.input_file}" "${vars.maxResults}" "${vars.fixture}"
98
61
 
99
62
  - id: ingest
100
63
  description: >-
@@ -139,25 +102,12 @@ states:
139
102
  - kind: shell
140
103
  options:
141
104
  command: >-
142
- set -e;
143
- rs="${vars.render_script}";
144
- if [ ! -f "$rs" ]; then
145
- kbin="$(command -v kk 2>/dev/null || true)";
146
- while [ -L "$kbin" ]; do
147
- link="$(readlink "$kbin")";
148
- case "$link" in /*) kbin="$link";; *) kbin="$(dirname "$kbin")/$link";; esac;
149
- done;
150
- pkg=""; [ -n "$kbin" ] && pkg="$(cd "$(dirname "$kbin")/.." 2>/dev/null && pwd || true)";
151
- rs="";
152
- if [ -n "$pkg" ] && [ -f "$pkg/plugins/kk/scripts/render-md.ts" ]; then rs="$pkg/plugins/kk/scripts/render-md.ts";
153
- elif [ -f "plugins/kk/scripts/render-md.ts" ]; then rs="plugins/kk/scripts/render-md.ts"; fi;
154
- fi;
155
- if [ -z "$rs" ]; then
156
- echo "render_script not found (searched: var, kk package root via \`command -v kk\`, ./plugins/kk/scripts)" >&2;
157
- exit 1;
158
- fi;
159
- bun "$rs" --in "${vars.work_dir}/content.json"
160
- --out "${vars.work_dir}/content.md"
105
+ kbin="$(command -v kk 2>/dev/null)";
106
+ pkg="$(dirname "$(dirname "$(realpath "$kbin" 2>/dev/null)")")";
107
+ st="$pkg/plugins/kk/scripts/kk-workflow-stages.ts";
108
+ [ -f "$st" ] || st="plugins/kk/scripts/kk-workflow-stages.ts";
109
+ [ -f "$st" ] || echo "kk-workflow-stages.ts not found at $st — install or refresh the kk package (bun link in a checkout)" >&2;
110
+ bun "$st" render-storm "${vars.render_script}" --in "${vars.work_dir}/content.json" --out "${vars.work_dir}/content.md"
161
111
 
162
112
  - id: done
163
113
  description: >-
@@ -21848,6 +21848,26 @@ var ResultSchema = exports_external.object({
21848
21848
  metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
21849
21849
  });
21850
21850
  var DocListSchema = exports_external.array(DocSchema);
21851
+ var omniVoiceGenContentSchema = ContentSchema.extend({
21852
+ format: exports_external.literal("audio"),
21853
+ metadata: exports_external.looseObject({
21854
+ generator: exports_external.literal("kk:omni-voice-gen"),
21855
+ audioPath: exports_external.string(),
21856
+ duration: exports_external.number(),
21857
+ segments: exports_external.array(exports_external.looseObject({
21858
+ generationId: exports_external.string(),
21859
+ profile: exports_external.string(),
21860
+ speaker: exports_external.string().optional(),
21861
+ emotion: exports_external.string().optional(),
21862
+ duration: exports_external.number(),
21863
+ verifyRetries: exports_external.number(),
21864
+ transcription: exports_external.string().optional(),
21865
+ loudnessDip: exports_external.boolean().optional()
21866
+ })),
21867
+ mp3Path: exports_external.string().optional(),
21868
+ qc: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
21869
+ })
21870
+ });
21851
21871
 
21852
21872
  // ../../packages/kk-core/src/kinds.ts
21853
21873
  var PLUGIN_KINDS = ["ingestion", "generator", "publish"];
@@ -21849,6 +21849,26 @@ var ResultSchema = exports_external.object({
21849
21849
  metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
21850
21850
  });
21851
21851
  var DocListSchema = exports_external.array(DocSchema);
21852
+ var omniVoiceGenContentSchema = ContentSchema.extend({
21853
+ format: exports_external.literal("audio"),
21854
+ metadata: exports_external.looseObject({
21855
+ generator: exports_external.literal("kk:omni-voice-gen"),
21856
+ audioPath: exports_external.string(),
21857
+ duration: exports_external.number(),
21858
+ segments: exports_external.array(exports_external.looseObject({
21859
+ generationId: exports_external.string(),
21860
+ profile: exports_external.string(),
21861
+ speaker: exports_external.string().optional(),
21862
+ emotion: exports_external.string().optional(),
21863
+ duration: exports_external.number(),
21864
+ verifyRetries: exports_external.number(),
21865
+ transcription: exports_external.string().optional(),
21866
+ loudnessDip: exports_external.boolean().optional()
21867
+ })),
21868
+ mp3Path: exports_external.string().optional(),
21869
+ qc: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
21870
+ })
21871
+ });
21852
21872
 
21853
21873
  // ../../packages/kk-core/src/kinds.ts
21854
21874
  var PLUGIN_KINDS = ["ingestion", "generator", "publish"];
@@ -21962,7 +21982,12 @@ function renderShowNotesMarkdown(docs, opts) {
21962
21982
  const s = t.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/[\s_]+/g, "-");
21963
21983
  return s.length > 0 ? s : "post";
21964
21984
  };
21965
- const articleUrl = `${opts.articleBaseUrl ?? "https://surfing.salty.vip"}/zh/posts/${opts.runDate}-${slugify2(opts.title)}`;
21985
+ const baseUrl = opts.articleBaseUrl ?? "https://surfing.salty.vip";
21986
+ const segments = opts.articlePostPath?.split(/[\\/]/).filter((s) => s.length > 0) ?? [];
21987
+ const postSlug = segments.length >= 2 ? segments[segments.length - 2] ?? "" : "";
21988
+ const postLocale = segments.find((s) => ["zh", "en", "ja"].includes(s)) ?? "zh";
21989
+ const articleUrl = postSlug.length > 0 ? `${baseUrl}/${postLocale}/posts/${postSlug}` : `${baseUrl}/zh/posts/${opts.runDate}-${slugify2(opts.title)}`;
21990
+ const briefMode = opts.briefMode === true && postSlug.length > 0;
21966
21991
  const sourceLabel = (d) => {
21967
21992
  const m = d.metadata ?? {};
21968
21993
  if (typeof m.sourceName === "string" && m.sourceName.trim())
@@ -21973,11 +21998,31 @@ function renderShowNotesMarkdown(docs, opts) {
21973
21998
  return "\u6765\u6E90";
21974
21999
  }
21975
22000
  };
22001
+ const itemBrief = (d) => {
22002
+ const meta3 = d.metadata ?? {};
22003
+ if (typeof meta3.brief === "string" && meta3.brief.trim().length > 0)
22004
+ return meta3.brief.trim();
22005
+ return (d.body ?? "").trim().split(/(?<=[\u3002\uFF01\uFF1F])\s*/).slice(0, 2).join("");
22006
+ };
22007
+ const itemTimestamp = (d) => {
22008
+ const meta3 = d.metadata ?? {};
22009
+ const raw = meta3.publishAt;
22010
+ const t = typeof raw === "string" ? Date.parse(raw) : typeof raw === "number" ? raw : Number.NaN;
22011
+ if (!Number.isFinite(t))
22012
+ return "--:--";
22013
+ const at = new Date(t);
22014
+ return `${String(at.getHours()).padStart(2, "0")}:${String(at.getMinutes()).padStart(2, "0")}`;
22015
+ };
21976
22016
  const lines = [`# ${opts.title}`, ""];
21977
22017
  docs.forEach((d, i) => {
21978
22018
  const body = (d.body ?? "").trim();
21979
22019
  const sentences = body.split(/(?<=[\u3002\uFF01\uFF1F])\s*/).slice(0, 2).join("");
21980
- lines.push(`## ${i + 1}. ${d.title ?? `\u6761\u76EE ${i + 1}`}`, "", sentences, "", `[\u6765\u6E90\uFF1A${sourceLabel(d)}](${d.sourceUri ?? ""})`, "");
22020
+ lines.push(`## ${i + 1}. ${d.title ?? `\u6761\u76EE ${i + 1}`}`, "");
22021
+ if (briefMode) {
22022
+ lines.push(`${itemTimestamp(d)} \xB7 ${itemBrief(d)}`, "", `[\u6765\u6E90\uFF1A${sourceLabel(d)}](${d.sourceUri ?? ""}) \xB7 [\u6587\u7AE0](${articleUrl})`, "");
22023
+ } else {
22024
+ lines.push(sentences, "", `[\u6765\u6E90\uFF1A${sourceLabel(d)}](${d.sourceUri ?? ""})`, "");
22025
+ }
21981
22026
  });
21982
22027
  lines.push(`\u8BE6\u60C5\u89C1\u672C\u671F\u5B8C\u6574\u6587\u7AE0\uFF1A[ ${opts.title} ](${articleUrl})`, "");
21983
22028
  return lines.join(`
@@ -22262,8 +22307,17 @@ function resolveShowNotesRenderOptions(options) {
22262
22307
  return { error: 'options.runDate (or PODCAST_PUB_RUN_DATE) is required for the "show-notes" operation' };
22263
22308
  }
22264
22309
  const articleBaseUrl = resolveOptionString(options.articleBaseUrl, "PODCAST_PUB_ARTICLE_BASE_URL");
22310
+ const briefModeRaw = options.briefMode ?? process.env.PODCAST_PUB_BRIEF_MODE;
22311
+ const briefMode = briefModeRaw === true || briefModeRaw === "true" || briefModeRaw === "1";
22312
+ const articlePostPath = resolveOptionString(options.articlePostPath, "PODCAST_PUB_ARTICLE_POST_PATH");
22265
22313
  return {
22266
- renderOptions: { title, runDate, ...articleBaseUrl !== undefined ? { articleBaseUrl } : {} }
22314
+ renderOptions: {
22315
+ title,
22316
+ runDate,
22317
+ ...articleBaseUrl !== undefined ? { articleBaseUrl } : {},
22318
+ ...briefMode ? { briefMode: true } : {},
22319
+ ...articlePostPath !== undefined ? { articlePostPath } : {}
22320
+ }
22267
22321
  };
22268
22322
  }
22269
22323
  function renderShowNotesFromOptions(options) {
@@ -28,6 +28,10 @@ interface PodcastPubOptions {
28
28
  title?: unknown;
29
29
  runDate?: unknown;
30
30
  articleBaseUrl?: unknown;
31
+ /** Brief/timeline render flag (task 0118). */
32
+ briefMode?: unknown;
33
+ /** Surfdash publish result `metadata.postPath` (briefMode URL source). */
34
+ articlePostPath?: unknown;
31
35
  /** Episode-assembly options for the `publish` op (absorb publish-prep's merge; additive). */
32
36
  audioFile?: unknown;
33
37
  coverPath?: unknown;
@@ -76,7 +80,10 @@ function resolveItemId(options: PodcastPubOptions): { itemId: string } | { error
76
80
  }
77
81
 
78
82
  /** Options the `show-notes` operation reads on the payload (a subset of {@link PodcastPubOptions}). */
79
- type ShowNotesOpOptions = Pick<PodcastPubOptions, 'docs' | 'title' | 'runDate' | 'articleBaseUrl'>;
83
+ type ShowNotesOpOptions = Pick<
84
+ PodcastPubOptions,
85
+ 'docs' | 'title' | 'runDate' | 'articleBaseUrl' | 'briefMode' | 'articlePostPath'
86
+ >;
80
87
 
81
88
  /**
82
89
  * Option-then-env resolution for the show-notes render options: `kk executor run`
@@ -103,8 +110,17 @@ function resolveShowNotesRenderOptions(
103
110
  return { error: 'options.runDate (or PODCAST_PUB_RUN_DATE) is required for the "show-notes" operation' };
104
111
  }
105
112
  const articleBaseUrl = resolveOptionString(options.articleBaseUrl, 'PODCAST_PUB_ARTICLE_BASE_URL');
113
+ const briefModeRaw = options.briefMode ?? process.env.PODCAST_PUB_BRIEF_MODE;
114
+ const briefMode = briefModeRaw === true || briefModeRaw === 'true' || briefModeRaw === '1';
115
+ const articlePostPath = resolveOptionString(options.articlePostPath, 'PODCAST_PUB_ARTICLE_POST_PATH');
106
116
  return {
107
- renderOptions: { title, runDate, ...(articleBaseUrl !== undefined ? { articleBaseUrl } : {}) },
117
+ renderOptions: {
118
+ title,
119
+ runDate,
120
+ ...(articleBaseUrl !== undefined ? { articleBaseUrl } : {}),
121
+ ...(briefMode ? { briefMode: true } : {}),
122
+ ...(articlePostPath !== undefined ? { articlePostPath } : {}),
123
+ },
108
124
  };
109
125
  }
110
126