@gobing-ai/knowledge-kit 0.0.22 → 0.0.24
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.
- package/.claude-plugin/marketplace.json +1 -1
- package/dist/index.js +137 -59
- package/package.json +4 -4
- package/plugins/generations/content-gen/dist/index.js +97 -45
- package/plugins/generations/core-facts-gen/dist/index.js +106 -57
- package/plugins/generations/daily-article-gen/dist/index.js +105 -56
- package/plugins/generations/dailynews-gen/dist/index.js +235 -57
- package/plugins/generations/dailynews-gen/src/index.ts +67 -2
- package/plugins/generations/dailynews-gen/src/script-builder.ts +36 -15
- package/plugins/generations/dailynews-gen/src/script-plan.ts +142 -0
- package/plugins/generations/episode-plan-gen/dist/index.js +115 -66
- package/plugins/generations/gemini-tts/README.md +125 -0
- package/plugins/generations/gemini-tts/dist/index.js +23348 -0
- package/plugins/generations/gemini-tts/package.json +16 -0
- package/plugins/generations/gemini-tts/plugin.json +6 -0
- package/plugins/generations/gemini-tts/profiles.json +3 -0
- package/plugins/generations/gemini-tts/src/gemini-client.ts +220 -0
- package/plugins/generations/gemini-tts/src/index.ts +33 -0
- package/plugins/generations/gemini-tts/src/voice-create.ts +180 -0
- package/plugins/generations/gemini-tts/tsconfig.json +8 -0
- package/plugins/generations/image-gen/dist/index.js +338 -117
- package/plugins/generations/image-gen/presets/formats/daily-news-cover.yaml +19 -0
- package/plugins/generations/image-gen/presets/formats/xhs-card.yaml +55 -0
- package/plugins/generations/image-gen/presets/styles/daily-news.yaml +9 -0
- package/plugins/generations/image-gen/presets/styles/xhs-knowledge.yaml +7 -0
- package/plugins/generations/image-gen/src/index.ts +148 -14
- package/plugins/generations/image-gen/src/job.ts +30 -0
- package/plugins/generations/image-gen/src/providers/errors.ts +91 -0
- package/plugins/generations/image-gen/src/providers/types.ts +79 -0
- package/plugins/generations/news-report-gen/dist/index.js +136 -55
- package/plugins/generations/news-report-gen/src/index.ts +57 -1
- package/plugins/generations/voice-gen/dist/index.js +121 -69
- package/plugins/generations/voice-gen/package.json +3 -0
- package/plugins/generations/voice-gen/src/index.ts +2 -1
- package/plugins/generations/voice-gen/src/voicebox-client.ts +2 -1
- package/plugins/ingestions/aihot-ingest/dist/index.js +103 -53
- package/plugins/ingestions/horizon-ingest/dist/index.js +102 -53
- package/plugins/ingestions/karakeep-local/dist/index.js +273 -224
- package/plugins/ingestions/last30days-ingest/dist/index.js +97 -48
- package/plugins/ingestions/web-search/dist/index.js +121 -72
- package/plugins/kk/config.example.yaml +13 -0
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/scripts/daily-voice-style.zh.md +52 -0
- package/plugins/kk/scripts/kk-workflow-stages.ts +438 -17
- package/plugins/kk/skills/publish/SKILL.md +24 -1
- package/plugins/kk/skills/xhs-images/SKILL.md +89 -0
- package/plugins/kk/skills/xhs-images/references/card-layouts.md +35 -0
- package/plugins/kk/workflows/kk-daily-ai-voice.yaml +164 -13
- package/plugins/publishings/emdash-pub/dist/index.js +94 -45
- package/plugins/publishings/infoq-pub/dist/index.js +94 -45
- package/plugins/publishings/juejin-pub/dist/index.js +94 -45
- package/plugins/publishings/medium-pub/dist/index.js +94 -45
- package/plugins/publishings/podcast-pub/dist/index.js +115 -55
- package/plugins/publishings/podcast-pub/src/map.ts +30 -10
- package/plugins/publishings/podcast-pub/src/show-notes.ts +6 -1
- package/plugins/publishings/qiita-pub/dist/index.js +94 -45
- package/plugins/publishings/substack-pub/dist/index.js +94 -45
- package/plugins/publishings/surfdash-pub/dist/index.js +99 -63
- package/plugins/publishings/surfdash-pub/src/index.ts +10 -1
- package/plugins/publishings/wechatmp-pub/dist/index.js +94 -45
- package/plugins/publishings/x-pub/dist/index.js +94 -45
- package/plugins/publishings/xhs-pub/dist/index.js +8908 -229
- package/plugins/publishings/xhs-pub/package.json +1 -0
- package/plugins/publishings/xhs-pub/plugin.json +1 -1
- package/plugins/publishings/xhs-pub/src/automation-guard.ts +128 -0
- package/plugins/publishings/xhs-pub/src/index.ts +753 -24
- package/plugins/publishings/xhs-pub/src/profile-check.ts +133 -0
- package/plugins/publishings/zenn-pub/dist/index.js +94 -45
- package/plugins/sp/lib/env.ts +46 -0
- package/plugins/sp/lib/inline-run.generated.mjs +1489 -0
- package/plugins/sp/scripts/feature-verification-steps.ts +275 -0
- package/plugins/sp/scripts/inline-run-setup.ts +571 -47
- package/plugins/sp/scripts/wrapup-drift-probe.mjs +190 -0
- package/plugins/sp/scripts/wrapup-drift-probe.ts +258 -0
- package/plugins/sp/scripts/wrapup-steps.mjs +77 -6
- package/plugins/sp/scripts/wrapup-steps.ts +91 -5
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: xhs-images
|
|
3
|
+
description: >-
|
|
4
|
+
Use the xhs-images skill to turn source content into an ordered Xiaohongshu
|
|
5
|
+
card series — "make XHS cards from this article", "generate a card series",
|
|
6
|
+
"turn these notes into 小红书图文卡片". Plans N ordered cards (cover, content,
|
|
7
|
+
closing) grounded in the source, renders them through the image-gen executor
|
|
8
|
+
with the xhs-card/xhs-knowledge presets, packages a publishable Content, and
|
|
9
|
+
hands off to kk:publish channel xhs. Never publishes directly.
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# xhs-images — source-grounded XHS card series (plan → render → package → handoff)
|
|
13
|
+
|
|
14
|
+
Adapted from `baoyu-xhs-images` (MIT © Jim Liu) — layout, typography, and
|
|
15
|
+
consistency guidance only. Not imported: backend selection, batch/parallel
|
|
16
|
+
generation, `EXTEND.md` chain. Layout catalog:
|
|
17
|
+
`references/card-layouts.md`. Presets: `xhs-card` (format) +
|
|
18
|
+
`xhs-knowledge` (style). Rendering always goes through
|
|
19
|
+
`kk executor run image-gen` — this skill holds no transport.
|
|
20
|
+
|
|
21
|
+
## Inputs
|
|
22
|
+
|
|
23
|
+
| Input | Required | Notes |
|
|
24
|
+
| ----- | -------- | ----- |
|
|
25
|
+
| source file (md/txt) | yes | read-only; never written or modified |
|
|
26
|
+
| `--out <dir>` | yes | fresh dir = new plan; existing dir = resume |
|
|
27
|
+
| `--count <n>` | no | 1–10; default: cover + one card per major point, capped at 10 |
|
|
28
|
+
| `--style <name>` | no | default `xhs-knowledge` |
|
|
29
|
+
| `--live` | no | passed through to kk:publish as the operator's live request |
|
|
30
|
+
|
|
31
|
+
`--count` above `min(10, image.max_images)` is refused, naming
|
|
32
|
+
`KK_IMAGE_MAX_IMAGES` / `image.max_images`.
|
|
33
|
+
|
|
34
|
+
## Procedure
|
|
35
|
+
|
|
36
|
+
1. **Plan** — read the source; produce ordered cards: card 01 `role: cover`,
|
|
37
|
+
then `content` cards in source order, then an optional `closing` card. Each
|
|
38
|
+
card records `index`, `role`, `sourcePoint` (verbatim heading or sentence),
|
|
39
|
+
`copy` (short Chinese on-card text), `layout` (from the reference catalog),
|
|
40
|
+
`subject` (visual scene). Write `<out>/cards.json` with
|
|
41
|
+
`{ source, cards: [{ index, role, sourcePoint, copy, layout, promptPath,
|
|
42
|
+
imagePath, status: 'pending' }] }`.
|
|
43
|
+
2. **Envelopes** — for each card write `<out>/cards/NN.in.json`: the `image-gen`
|
|
44
|
+
envelope with `job: free`, `format: xhs-card`, `style`, `vars` (role,
|
|
45
|
+
layout, headline, points, subject, language 简体中文, index), `provider`,
|
|
46
|
+
`model`, `maxImages: 1`, `outputStem: card-NN`. For NN ≥ 02 add
|
|
47
|
+
`referenceImages: [<cover path>]` **only when** `kk:image-authoring`
|
|
48
|
+
`references/providers.md` marks the provider/model reference-capable.
|
|
49
|
+
3. **Dry-run + one confirmation** — run each envelope with `KK_IMAGE_DRY_RUN=1`;
|
|
50
|
+
save the emitted `Content.body` as `<out>/cards/NN.prompt.txt` (the exact
|
|
51
|
+
composed prompt; it must equal `ImageArtifact.prompt` after render). Resolve
|
|
52
|
+
provider/model via `kk:image-authoring`'s preference chain (arguments >
|
|
53
|
+
env > `$KK_CONFIG` > defaults). Show **one** spend preview for the series
|
|
54
|
+
(provider, model, style, N, cover prompt, per-card copy list, plus the
|
|
55
|
+
consistency path: cover-reference chain when the provider is
|
|
56
|
+
reference-capable per `kk:image-authoring` `references/providers.md`, or an
|
|
57
|
+
explicit weaker-consistency disclosure when it is not) and follow the
|
|
58
|
+
`kk:image-authoring` Confirmation policy once before any paid render.
|
|
59
|
+
4. **Render sequentially** — card 01, then 02..N, each via
|
|
60
|
+
`kk executor run image-gen --in cards/NN.in.json --out cards/NN.json`.
|
|
61
|
+
On the first failure: stop spending, mark the card `failed`, later cards
|
|
62
|
+
stay `pending`, report the retry.
|
|
63
|
+
5. **Package** — write `<out>/content.json`: `title` (XHS title, ≤ 20 chars),
|
|
64
|
+
`body` (Chinese note + hashtags, ≤ 1000 chars), `format: 'text'`,
|
|
65
|
+
`metadata.images` = each card's `cards/NN.json` `metadata.images[0]` in
|
|
66
|
+
index order, `metadata.publishStatus: 'draft'`. Packaging refuses while any
|
|
67
|
+
card is not `rendered` or its prompt/image file is missing.
|
|
68
|
+
6. **Handoff** — never spawn `xhs-pub` directly. Hand `content.json` to
|
|
69
|
+
`kk:publish` channel `xhs`; pass `--live` through as the operator's live
|
|
70
|
+
request.
|
|
71
|
+
|
|
72
|
+
## Resume
|
|
73
|
+
|
|
74
|
+
Re-running with the same `--out` reuses the existing `cards.json` and
|
|
75
|
+
`cards/NN.in.json` (no replanning) and renders only cards without an existing
|
|
76
|
+
image file — check existence via the artifact path recorded in the prior run's
|
|
77
|
+
`cards/NN.json` (or a `cards/card-NN-*` glob), since the provider decides the
|
|
78
|
+
extension. Replanning requires a new `--out`.
|
|
79
|
+
|
|
80
|
+
## Checks and limits
|
|
81
|
+
|
|
82
|
+
- N ≤ 10 and ≤ `image.max_images`; refusal names the cap env/key.
|
|
83
|
+
- Source file is never written.
|
|
84
|
+
- One spend confirmation per series; renders strictly sequential.
|
|
85
|
+
- Card text stays minimal (headline ≤ 12 chars, 2–4 short points) — the model
|
|
86
|
+
renders text, so fewer words means fewer rendering defects.
|
|
87
|
+
- Consistency: cover prompt fixes palette/typography wording; per-card prompts
|
|
88
|
+
reuse it verbatim and vary only layout/points/subject. When the provider is
|
|
89
|
+
reference-capable, cards ≥ 02 reference the rendered cover.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# XHS card layouts — adapted from `baoyu-xhs-images`
|
|
2
|
+
|
|
3
|
+
Source: `vendors/baoyu-skills/skills/baoyu-xhs-images/SKILL.md` (MIT © Jim Liu).
|
|
4
|
+
Adapted: layout names, typography rules, consistency guidance. Not imported:
|
|
5
|
+
backend selection, batch/parallel generation, `EXTEND.md` chain.
|
|
6
|
+
|
|
7
|
+
## Layout catalog
|
|
8
|
+
|
|
9
|
+
| Layout | Use when | On-card structure |
|
|
10
|
+
| ------ | -------- | ----------------- |
|
|
11
|
+
| `cover` | Card 01 | Big headline (≤ 12 chars), one-line hook, small series label |
|
|
12
|
+
| `definition` | One concept to explain | Term + one-sentence definition + 2 short points |
|
|
13
|
+
| `list` | 3–4 parallel items | Numbered short lines, uniform phrasing |
|
|
14
|
+
| `comparison` | Two options | Two columns, 2–3 contrast points each |
|
|
15
|
+
| `steps` | Ordered process | 3–4 numbered steps, verb-first |
|
|
16
|
+
| `quote` | Key sentence from source | Large quote text + attribution line |
|
|
17
|
+
| `summary` | Closing card | 3 takeaways + one CTA line |
|
|
18
|
+
|
|
19
|
+
## Typography rules
|
|
20
|
+
|
|
21
|
+
- Headline: extra-large bold; ≤ 12 Chinese characters.
|
|
22
|
+
- Points: short lines, 2–4 per card, generous line spacing.
|
|
23
|
+
- Keep total on-card text minimal — the model renders text, so fewer words
|
|
24
|
+
means fewer rendering defects.
|
|
25
|
+
- Language default: 简体中文 (`xhs-card` format `language` var).
|
|
26
|
+
|
|
27
|
+
## Consistency rules
|
|
28
|
+
|
|
29
|
+
- Compose the cover prompt first; fix palette/typography wording there.
|
|
30
|
+
- Per-card prompts reuse that wording verbatim; vary only
|
|
31
|
+
layout/points/subject (via the `xhs-card` template variables).
|
|
32
|
+
- When the provider/model is reference-capable per `kk:image-authoring`
|
|
33
|
+
`references/providers.md`, cards ≥ 02 set `referenceImages: [<cover path>]`.
|
|
34
|
+
- Renders are strictly sequential (card 01 → N) so the cover reference exists
|
|
35
|
+
before dependents render.
|
|
@@ -5,7 +5,8 @@ kind: state-machine
|
|
|
5
5
|
description: >-
|
|
6
6
|
Daily AI news end-to-end pipeline (F61 destination): collect (fan-in --source: aihot + last30days
|
|
7
7
|
+ Horizon) → core facts → plan → content QC (filter, done-no-content terminal) → article + cover
|
|
8
|
-
+ script + review + voice → publish (surfdash + podcast, full|partial|none routing) →
|
|
8
|
+
+ script + review + voice → publish (surfdash + podcast, full|partial|none routing) → xhs draft
|
|
9
|
+
(independent, non-blocking target) → locales
|
|
9
10
|
initialState: prepare
|
|
10
11
|
terminalStates:
|
|
11
12
|
- done
|
|
@@ -19,7 +20,7 @@ vars:
|
|
|
19
20
|
limit: "10"
|
|
20
21
|
language: "zh"
|
|
21
22
|
voice_profile: "robin-news"
|
|
22
|
-
# 20260917: voice driver switch — voicebox (default, voice-gen) | ominivoice (omni-voice-gen).
|
|
23
|
+
# 20260917: voice driver switch — voicebox (default, voice-gen) | ominivoice (omni-voice-gen) | gemini (gemini-tts).
|
|
23
24
|
# 20260920: default flipped to voicebox — operator A/B at matched speech rate (~5.2 chars/s)
|
|
24
25
|
# judged voicebox clearly better (ominivoice carries ~1min dead air over 16min + ASR-garble class).
|
|
25
26
|
vdriver: "voicebox"
|
|
@@ -31,11 +32,45 @@ vars:
|
|
|
31
32
|
cursor: ""
|
|
32
33
|
state_file: ""
|
|
33
34
|
skip_review: "false"
|
|
34
|
-
|
|
35
|
+
# 0171 R1: podcast-pub publishes metadata.mp3Path, so "false" fell back to the WAV render — an
|
|
36
|
+
# enclosure Apple Podcasts rejects and no ID3 tag can ride.
|
|
37
|
+
transcode_mp3: "true"
|
|
38
|
+
# 0171 R3/R4: ID3 artist/album stamped onto the published MP3 (title comes from the article,
|
|
39
|
+
# date from run_date); an empty var omits that tag.
|
|
40
|
+
podcast_artist: "Robin Min"
|
|
41
|
+
podcast_album: "咸话咸说"
|
|
35
42
|
cover_enabled: "true"
|
|
43
|
+
# F614: the daily cover pins provider+model in vars — each provider has its own look, so the
|
|
44
|
+
# pin is part of the style contract; it stays a var because the right value depends on which
|
|
45
|
+
# credentials the machine has (2026-09-24 run: minimax/image-01).
|
|
46
|
+
cover_provider: "minimax"
|
|
47
|
+
cover_model: "image-01"
|
|
48
|
+
# D6 0166: runtime-fallback opt-in for the cover render — "" (default) keeps strict fail-fast,
|
|
49
|
+
# "true" retries down AUTO_ORDER, anything else is a comma-separated provider list. The empty
|
|
50
|
+
# default keeps F614's pinned look the default; availability trades against it only on opt-in.
|
|
51
|
+
cover_fallback: ""
|
|
52
|
+
# E8: XHS image-card target. Cards are planned from the lead plan item (the same source the
|
|
53
|
+
# cover uses) and rendered through the pinned xhs-card/xhs-knowledge presets. `xhs_live` stays a
|
|
54
|
+
# separate launch-time switch (ADR-022), so an unattended run drafts and never posts live.
|
|
55
|
+
# Default OFF (2026-09-28): XHS warned the operator about automated login/publish activity.
|
|
56
|
+
# `xhs-pub` always launches a headed browser and drives the creator console, and an unattended
|
|
57
|
+
# daily job repeating that is precisely the pattern the platform flags — so the target is
|
|
58
|
+
# operator-opt-in until a reviewed automation policy exists. Do NOT flip this on for a scheduled
|
|
59
|
+
# run; publish XHS deliberately, by hand, and rarely.
|
|
60
|
+
xhs_enabled: "false"
|
|
61
|
+
xhs_cards: "4"
|
|
62
|
+
xhs_style: "xhs-knowledge"
|
|
63
|
+
# Same credential surface as the cover pin: the provider/model must be one this machine can
|
|
64
|
+
# actually reach, and each provider renders its own look.
|
|
65
|
+
xhs_provider: "minimax"
|
|
66
|
+
xhs_model: "image-01"
|
|
67
|
+
xhs_live: "false"
|
|
36
68
|
plan_max_items: "20"
|
|
37
69
|
plan_translate_enabled: "true"
|
|
38
70
|
article_write_enabled: "true"
|
|
71
|
+
# F613 R3: script-write authors the per-item plan the zh builder consumes; "false" routes
|
|
72
|
+
# article/cover straight to script (template build, no plan file is written).
|
|
73
|
+
script_write_enabled: "true"
|
|
39
74
|
plugins_path: ""
|
|
40
75
|
# Projected by the publish state from 3-publish/<run_date>_17_publish_publish-status.txt;
|
|
41
76
|
# guards test this var instead of cat-ing the file (state at decision time).
|
|
@@ -160,24 +195,60 @@ states:
|
|
|
160
195
|
kk stage daily-article "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}"
|
|
161
196
|
|
|
162
197
|
- id: cover
|
|
163
|
-
description: "
|
|
198
|
+
description: "Render the daily cover from the lead plan item through the pinned daily-news presets (brief agent.run -> pinned stage render -> normalize, F614)"
|
|
164
199
|
onEnter:
|
|
165
200
|
- kind: agent.run
|
|
201
|
+
# A bad or failed brief must never halt the run: the stage falls back to the format's
|
|
202
|
+
# default subject (F614 R4) and keeps the same pinned format/style/provider/model.
|
|
203
|
+
onError: continue
|
|
166
204
|
options:
|
|
167
205
|
role: scribe
|
|
168
206
|
agent: ${vars.agent}
|
|
207
|
+
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
169
208
|
input: |
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
expectFile: ${vars.work_dir}/2-cover
|
|
209
|
+
Read ${vars.work_dir}/2-plan/${vars.run_date}_03_plan_plan.json — a JSON array of news docs; don't edit it.
|
|
210
|
+
Take item 1 only (its "title" and "metadata.brief") — the episode's lead story.
|
|
211
|
+
Write one concrete visual scene in English, ≤240 characters, that a viewer would connect to that story: objects, settings, symbols, metaphor.
|
|
212
|
+
No text, letters, numbers, logos, brand marks, flags, or recognizable real people. No style, color, lighting, or composition words — the preset owns those.
|
|
213
|
+
Output strictly valid JSON {"subject": "..."} to ${vars.work_dir}/2-cover/${vars.run_date}_07_cover-brief.json.
|
|
214
|
+
expectFile: ${vars.work_dir}/2-cover/${vars.run_date}_07_cover-brief.json
|
|
215
|
+
allowAppend: false
|
|
216
|
+
- kind: shell
|
|
217
|
+
options:
|
|
218
|
+
command: >-
|
|
219
|
+
kk stage daily-cover "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.cover_provider}" "${vars.cover_model}" "${vars.cover_fallback}"
|
|
176
220
|
- kind: shell
|
|
177
221
|
options:
|
|
178
222
|
command: >-
|
|
179
223
|
kk stage daily-cover-normalize "${vars.work_dir}" "${vars.run_date}"
|
|
180
224
|
|
|
225
|
+
- id: script-write
|
|
226
|
+
description: "Author the per-item script plan (intro/outro + lead/insight per doc id) from the show-notes plan source via agent.run; onError: continue — a failed plan falls back to templates (F613)"
|
|
227
|
+
onEnter:
|
|
228
|
+
- kind: shell
|
|
229
|
+
options:
|
|
230
|
+
# Spur has no workflow-dir var, so the prompt cannot name the shipped sidecar: this
|
|
231
|
+
# stage snapshots it into the work dir (idempotent; a missing sidecar is a broken
|
|
232
|
+
# install and fails loud). The snapshot also freezes the contract the plan was
|
|
233
|
+
# written against, per run, for audit.
|
|
234
|
+
command: >-
|
|
235
|
+
kk stage daily-script-style "${vars.work_dir}" "${vars.run_date}"
|
|
236
|
+
- kind: agent.run
|
|
237
|
+
# A rejected or failed plan must never halt the unattended daily run: the builder
|
|
238
|
+
# decides plan-vs-template from the file itself and falls back to templates.
|
|
239
|
+
onError: continue
|
|
240
|
+
options:
|
|
241
|
+
role: scribe
|
|
242
|
+
agent: ${vars.agent}
|
|
243
|
+
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
244
|
+
input: |
|
|
245
|
+
Read ${vars.work_dir}/2-plan/${vars.run_date}_03_plan_plan.json — a JSON array of docs; use each doc's `id`; don't edit it. Also read the style contract ${vars.work_dir}/2-script/${vars.run_date}_08_script-write_style.md and obey its char caps and banned phrases.
|
|
246
|
+
For each doc write a `lead` (a spoken bridge into the title, not containing it) and an `insight` (why it matters, grounded only in that doc's facts).
|
|
247
|
+
Write an `intro` hooking today's actual themes and an `outro`; no greeting or sign-off — the builder adds both.
|
|
248
|
+
Output only the JSON object {"version":1,"intro":"…","outro":"…","items":[{"id":"…","lead":"…","insight":"…"}]} with one item per doc id to ${vars.work_dir}/2-script/${vars.run_date}_08_script-write_plan.json.
|
|
249
|
+
expectFile: ${vars.work_dir}/2-script/${vars.run_date}_08_script-write_plan.json
|
|
250
|
+
allowAppend: false
|
|
251
|
+
|
|
181
252
|
- id: script
|
|
182
253
|
description: "Compile the episode plan Doc[] into structured broadcast VoiceScript YAML Content"
|
|
183
254
|
onEnter:
|
|
@@ -204,7 +275,7 @@ states:
|
|
|
204
275
|
kk stage daily-wrap-docs "${vars.work_dir}" "${vars.run_date}" "${vars.voice_profile}"
|
|
205
276
|
|
|
206
277
|
- id: generate
|
|
207
|
-
description: "Invoke voice driver plugin (vdriver var: ominivoice -> omni-voice-gen, voicebox -> voice-gen) to generate audio"
|
|
278
|
+
description: "Invoke voice driver plugin (vdriver var: ominivoice -> omni-voice-gen, voicebox -> voice-gen, gemini -> gemini-tts) to generate audio"
|
|
208
279
|
onEnter:
|
|
209
280
|
- kind: shell
|
|
210
281
|
options:
|
|
@@ -228,12 +299,12 @@ states:
|
|
|
228
299
|
kk stage daily-quality-report "${vars.work_dir}" "${vars.run_date}"
|
|
229
300
|
|
|
230
301
|
- id: publish-prep
|
|
231
|
-
description: "Merge article Content with
|
|
302
|
+
description: "Merge article Content with the MP3 (rejects a non-.mp3 enclosure) and stamp its ID3 tags (podcast assembly facts ride the content options channel for podcast-pub's absorbed assembly; runDate kept for surfdash slug)"
|
|
232
303
|
onEnter:
|
|
233
304
|
- kind: shell
|
|
234
305
|
options:
|
|
235
306
|
command: >-
|
|
236
|
-
kk stage daily-publish-prep "${vars.work_dir}" "${vars.run_date}"
|
|
307
|
+
kk stage daily-publish-prep "${vars.work_dir}" "${vars.run_date}" "${vars.podcast_artist}" "${vars.podcast_album}"
|
|
237
308
|
|
|
238
309
|
- id: publish-surfdash
|
|
239
310
|
description: "Publish the merged Content to surfdash (single target); result lands in result.json — surfdash publishes first so show-notes can link the article (task 0118 seam reorder)"
|
|
@@ -259,6 +330,41 @@ states:
|
|
|
259
330
|
command: >-
|
|
260
331
|
kk stage daily-publish-podcast "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}"
|
|
261
332
|
|
|
333
|
+
- id: xhs-write
|
|
334
|
+
description: "Plan the XHS card series from the lead plan item via agent.run (title + note + N ordered cards), then render it through the pinned xhs-card/xhs-knowledge presets (E8); onError: continue — a failed plan or render skips the XHS target, never the run"
|
|
335
|
+
onEnter:
|
|
336
|
+
- kind: agent.run
|
|
337
|
+
# XHS is an independent, non-blocking target: a bad or failed plan must never halt the run.
|
|
338
|
+
# The render stage still fails loud; the publish state then skips naming the missing series.
|
|
339
|
+
onError: continue
|
|
340
|
+
options:
|
|
341
|
+
role: scribe
|
|
342
|
+
agent: ${vars.agent}
|
|
343
|
+
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
344
|
+
input: |
|
|
345
|
+
Read ${vars.work_dir}/2-plan/${vars.run_date}_03_plan_plan.json — a JSON array of news docs; don't edit it.
|
|
346
|
+
Take item 1 only (its "title" and "metadata.brief") — the lead story.
|
|
347
|
+
Write a Xiaohongshu note: "title" (≤20 chars) and "body" (Chinese note ≤1000 chars, ending with 3-5 hashtags).
|
|
348
|
+
Write exactly ${vars.xhs_cards} cards: card 1 role "cover", the rest "content", except a final "closing". Each card carries "role", "copy" (Chinese on-card headline ≤12 chars), "points" (2-4 short Chinese bullets), "layout", "subject" (one concrete English visual scene), "sourcePoint" (the lead-story fact that card uses).
|
|
349
|
+
Ground every "copy", "points" and "sourcePoint" in that story alone — no invented facts. No text, letters, numbers, logos or real people in "subject".
|
|
350
|
+
Output strictly valid JSON {"title": "...", "body": "...", "cards": [...]} to ${vars.work_dir}/2-xhs/${vars.run_date}_18_xhs_plan.json.
|
|
351
|
+
expectFile: ${vars.work_dir}/2-xhs/${vars.run_date}_18_xhs_plan.json
|
|
352
|
+
allowAppend: false
|
|
353
|
+
- kind: shell
|
|
354
|
+
onError: continue
|
|
355
|
+
options:
|
|
356
|
+
command: >-
|
|
357
|
+
kk stage daily-xhs-render "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.xhs_cards}" "${vars.xhs_style}" "${vars.xhs_provider}" "${vars.xhs_model}"
|
|
358
|
+
|
|
359
|
+
- id: xhs-publish
|
|
360
|
+
description: "Publish the packaged card series to XHS — draft, or live only when xhs_live=true (ADR-022); independent and non-blocking: its outcome never enters publish_status. xhs-pub itself enforces a headless session preflight and a 24h publish/check cap (ADR-025), so a sessionless or capped run fails soft with a named reason and the run continues"
|
|
361
|
+
onEnter:
|
|
362
|
+
- kind: shell
|
|
363
|
+
onError: continue
|
|
364
|
+
options:
|
|
365
|
+
command: >-
|
|
366
|
+
kk stage daily-publish-xhs "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.xhs_live}"
|
|
367
|
+
|
|
262
368
|
- id: publish
|
|
263
369
|
description: "Classify the sequenced surfdash → podcast outcomes full|partial|none into publish-status.txt (exit 0 in all three — routing is transition-owned; task 0118: per-target classification over the merged result.json)"
|
|
264
370
|
onEnter:
|
|
@@ -416,18 +522,43 @@ transitions:
|
|
|
416
522
|
options:
|
|
417
523
|
command: 'test "${vars.cover_enabled}" = "true" && test ! -f "${vars.work_dir}/2-cover/${vars.run_date}_07_cover_cover.png"'
|
|
418
524
|
|
|
525
|
+
# F613 R3: first match wins — the cover edge stays above script-write so the cover still
|
|
526
|
+
# generates before the plan is authored; script-write sits above the always `-> script` edges
|
|
527
|
+
# and skips itself when disabled, non-zh, or the plan/YAML already exists (resume cost).
|
|
528
|
+
- from: article
|
|
529
|
+
to: script-write
|
|
530
|
+
description: "script_write_enabled, zh, and neither today's plan nor VoiceScript exists -> author the script plan"
|
|
531
|
+
guard:
|
|
532
|
+
kind: shell
|
|
533
|
+
options:
|
|
534
|
+
command: 'test "${vars.script_write_enabled}" = "true" && test "${vars.language}" = "zh" && test ! -f "${vars.work_dir}/2-script/${vars.run_date}_08_script-write_plan.json" && test ! -f "${vars.work_dir}/2-script/${vars.run_date}_08_script_voicescript.yaml"'
|
|
535
|
+
|
|
419
536
|
- from: article
|
|
420
537
|
to: script
|
|
421
538
|
description: "cover disabled or today's cover cached -> skip to script"
|
|
422
539
|
guard:
|
|
423
540
|
kind: always
|
|
424
541
|
|
|
542
|
+
- from: cover
|
|
543
|
+
to: script-write
|
|
544
|
+
description: "script_write_enabled, zh, and neither today's plan nor VoiceScript exists -> author the script plan"
|
|
545
|
+
guard:
|
|
546
|
+
kind: shell
|
|
547
|
+
options:
|
|
548
|
+
command: 'test "${vars.script_write_enabled}" = "true" && test "${vars.language}" = "zh" && test ! -f "${vars.work_dir}/2-script/${vars.run_date}_08_script-write_plan.json" && test ! -f "${vars.work_dir}/2-script/${vars.run_date}_08_script_voicescript.yaml"'
|
|
549
|
+
|
|
425
550
|
- from: cover
|
|
426
551
|
to: script
|
|
427
552
|
description: "Cover generated -> build broadcast script"
|
|
428
553
|
guard:
|
|
429
554
|
kind: always
|
|
430
555
|
|
|
556
|
+
- from: script-write
|
|
557
|
+
to: script
|
|
558
|
+
description: "Script plan authored (ok or failed: onError continue) -> build the broadcast script"
|
|
559
|
+
guard:
|
|
560
|
+
kind: always
|
|
561
|
+
|
|
431
562
|
- from: script
|
|
432
563
|
to: wrap-docs
|
|
433
564
|
description: "skip_review enabled -> bypass HITL review"
|
|
@@ -519,6 +650,26 @@ transitions:
|
|
|
519
650
|
guard:
|
|
520
651
|
kind: always
|
|
521
652
|
|
|
653
|
+
- from: publish-podcast
|
|
654
|
+
to: xhs-write
|
|
655
|
+
description: "xhs_enabled -> plan and render the XHS card series from the lead plan item; first-match-wins, so this sits above the classification edge (XHS is independent and never gates publish_status)"
|
|
656
|
+
guard:
|
|
657
|
+
kind: shell
|
|
658
|
+
options:
|
|
659
|
+
command: 'test "${vars.xhs_enabled}" = "true"'
|
|
660
|
+
|
|
661
|
+
- from: xhs-write
|
|
662
|
+
to: xhs-publish
|
|
663
|
+
description: "Card series planned and rendered (or failed: onError continue) -> publish the XHS draft"
|
|
664
|
+
guard:
|
|
665
|
+
kind: always
|
|
666
|
+
|
|
667
|
+
- from: xhs-publish
|
|
668
|
+
to: publish
|
|
669
|
+
description: "XHS dispatched (or skipped: onError continue) -> classify the surfdash/podcast outcomes; XHS contributes no target to the classification"
|
|
670
|
+
guard:
|
|
671
|
+
kind: always
|
|
672
|
+
|
|
522
673
|
- from: publish-podcast
|
|
523
674
|
to: publish
|
|
524
675
|
description: "Podcast dispatched -> classify the per-target outcomes full|partial|none"
|