@gobing-ai/knowledge-kit 0.0.25 → 0.0.27
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/package.json +1 -1
- package/plugins/generations/gemini-tts/dist/index.js +3 -3
- package/plugins/generations/news-report-gen/src/index.ts +5 -5
- package/plugins/generations/voice-gen/dist/index.js +3 -3
- package/plugins/generations/voice-gen/src/mp3.ts +4 -3
- package/plugins/generations/voice-gen/src/voicescript.ts +5 -2
- package/plugins/kk/commands/workflow-run.md +4 -4
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/scripts/kk-workflow-stages.ts +146 -99
- package/plugins/kk/scripts/validate-voicescript.ts +5 -2
- package/plugins/kk/workflows/kk-daily-ai-voice.yaml +73 -39
- package/plugins/publishings/wechatmp-pub/dist/index.js +8449 -307
- package/plugins/publishings/wechatmp-pub/package.json +3 -1
- package/plugins/publishings/wechatmp-pub/plugin.json +1 -1
- package/plugins/publishings/wechatmp-pub/src/index.ts +212 -167
- package/plugins/publishings/wechatmp-pub/src/profile-check.ts +34 -0
- package/plugins/publishings/xhs-pub/package.json +2 -1
|
@@ -20,10 +20,12 @@ vars:
|
|
|
20
20
|
limit: "10"
|
|
21
21
|
language: "zh"
|
|
22
22
|
voice_profile: "robin-news"
|
|
23
|
-
#
|
|
24
|
-
# 20260920
|
|
25
|
-
#
|
|
26
|
-
|
|
23
|
+
# Voice driver switch — voicebox (voice-gen) | ominivoice (omni-voice-gen) | gemini (gemini-tts).
|
|
24
|
+
# 20260917 introduced the switch; 20260920 flipped default to voicebox after an operator A/B;
|
|
25
|
+
# 20260929 operator override: gemini-tts is the default again (verified live on this machine —
|
|
26
|
+
# robin-news replicated profile, GEMINI_API_KEY + GEMINI_TTS_MODEL via ~/.config/kk/config.yaml
|
|
27
|
+
# env block; smoke render 6.8s). Flip back with vdriver="voicebox".
|
|
28
|
+
vdriver: "gemini"
|
|
27
29
|
# 20260917 review #7: 8s intro sting prepended to every daily output; empty = skip.
|
|
28
30
|
intro_music: ".works/kk-daily-ai-voice/AI每日资讯_8秒播客片头.mp3"
|
|
29
31
|
# 20260917 review #4/#6: surfdash checkout the patch stage commits to.
|
|
@@ -50,21 +52,30 @@ vars:
|
|
|
50
52
|
# default keeps F614's pinned look the default; availability trades against it only on opt-in.
|
|
51
53
|
cover_fallback: ""
|
|
52
54
|
# 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
|
|
54
|
-
#
|
|
55
|
-
#
|
|
56
|
-
# `xhs-pub` always launches a headed browser and drives the creator console
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
# run
|
|
60
|
-
xhs_enabled: "
|
|
55
|
+
# cover uses) and rendered through the pinned xhs-card/xhs-knowledge presets, then the xhs-pub
|
|
56
|
+
# headed browser saves them into the creator draft box.
|
|
57
|
+
# 2026-09-28 default OFF: XHS had warned the operator about automated login/publish activity,
|
|
58
|
+
# because `xhs-pub` always launches a headed browser and drives the creator console.
|
|
59
|
+
# 2026-09-29 operator decision: default ON — daily runs fill the draft box (best-practice
|
|
60
|
+
# default). The safety rail is `xhs_live: "false"` below: an unattended run drafts and never
|
|
61
|
+
# posts live. To post live, run ad-hoc with xhs_live="true" — deliberately, by hand.
|
|
62
|
+
xhs_enabled: "true"
|
|
61
63
|
xhs_cards: "4"
|
|
62
64
|
xhs_style: "xhs-knowledge"
|
|
63
65
|
# Same credential surface as the cover pin: the provider/model must be one this machine can
|
|
64
66
|
# actually reach, and each provider renders its own look.
|
|
65
67
|
xhs_provider: "minimax"
|
|
66
68
|
xhs_model: "image-01"
|
|
69
|
+
# ADR-022 rail: draft-box only. "true" posts live and stays a launch-time opt-in.
|
|
67
70
|
xhs_live: "false"
|
|
71
|
+
|
|
72
|
+
# WeChat MP (公众号): the daily article is pasted into the MP console editor and saved to the
|
|
73
|
+
# draft box (草稿箱) through wechatmp-pub's persistent-profile browser transport. The plugin
|
|
74
|
+
# runs a headless session preflight first: a sessionless run refuses fast (ok:false) and the
|
|
75
|
+
# stage stays non-blocking. The rail mirrors xhs: an unattended run drafts and never posts
|
|
76
|
+
# live — 发表 only on an ad-hoc wechat_live="true" run, deliberately, by hand.
|
|
77
|
+
wechat_enabled: "true"
|
|
78
|
+
wechat_live: "false"
|
|
68
79
|
plan_max_items: "20"
|
|
69
80
|
plan_translate_enabled: "true"
|
|
70
81
|
article_write_enabled: "true"
|
|
@@ -72,7 +83,7 @@ vars:
|
|
|
72
83
|
# article/cover straight to script (template build, no plan file is written).
|
|
73
84
|
script_write_enabled: "true"
|
|
74
85
|
plugins_path: ""
|
|
75
|
-
# Projected by the publish state from
|
|
86
|
+
# Projected by the publish state from 31-publish/<run_date>_17_publish_publish-status.txt;
|
|
76
87
|
# guards test this var instead of cat-ing the file (state at decision time).
|
|
77
88
|
publish_status: ""
|
|
78
89
|
last30days_topic: "AI news"
|
|
@@ -129,8 +140,8 @@ states:
|
|
|
129
140
|
# 45m leash; aihot/last30days keep the default.
|
|
130
141
|
command: >-
|
|
131
142
|
__STAMP_T0="$(date -u +%FT%TZ)"; trap '[ -n "${vars.work_dir}" ] && printf "{\"step\":\"collect\",\"startedAt\":\"%s\",\"endedAt\":\"%s\"}\n" "$__STAMP_T0" "$(date -u +%FT%TZ)" >> "${vars.work_dir}/step-timing.json"' EXIT;
|
|
132
|
-
if [ -f "${vars.work_dir}/
|
|
133
|
-
kk executor fan-in --source "aihot-ingest:${vars.work_dir}/
|
|
143
|
+
if [ -f "${vars.work_dir}/10-ingest/${vars.run_date}_02_collect_blended.json" ]; then echo "collect cached: ${vars.work_dir}/10-ingest/${vars.run_date}_02_collect_blended.json"; exit 0; fi;
|
|
144
|
+
kk executor fan-in --source "aihot-ingest:${vars.work_dir}/10-ingest/source.json" --source "last30days-ingest:${vars.work_dir}/10-ingest/last30days.json" --source "horizon-ingest:${vars.work_dir}/10-ingest/horizon.json" --source-timeout-override "horizon-ingest:2700000" --out "${vars.work_dir}/10-ingest/${vars.run_date}_02_collect_blended.json"
|
|
134
145
|
- kind: shell
|
|
135
146
|
options:
|
|
136
147
|
command: >-
|
|
@@ -161,13 +172,13 @@ states:
|
|
|
161
172
|
agent: ${vars.agent}
|
|
162
173
|
# ADR-115 error tier: keep this prompt <= 1000 chars (0133 R3; 0138 R4a adds the copy discipline).
|
|
163
174
|
input: |
|
|
164
|
-
Read ${vars.work_dir}/
|
|
175
|
+
Read ${vars.work_dir}/21-plan/${vars.run_date}_04_quality-control-content_candidates.json — metadata.docs (Doc[]) is the plan; don't edit it.
|
|
165
176
|
For items with needsTranslation, translate "title", "body", and "metadata.brief" (when present) into natural simplified Chinese.
|
|
166
177
|
Titles read as a news event (subject + action + object) — e.g. "OpenAI 发布 Sora 应用,集成 Sora 2 模型". Keep product/model/company names verbatim, preserve body URLs, use 「」 not ASCII double quotes.
|
|
167
178
|
Copy discipline: reader-facing news copy — no scaffold labels (「可做角度」「为什么现在值得注意」「社区讨论」「背景」「潜在影响」「影响」), no duplicated labels or hedging (「读者宜另行核实」「仍待验证」) — merge their substance into prose or drop.
|
|
168
179
|
Keep other fields (id, sourceUri, mediaType, metadata), technical terms as-is; no trailing commas or comments.
|
|
169
|
-
Output strictly valid JSON — a same-length, same-order array with the same ids — to ${vars.work_dir}/
|
|
170
|
-
expectFile: ${vars.work_dir}/
|
|
180
|
+
Output strictly valid JSON — a same-length, same-order array with the same ids — to ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json.
|
|
181
|
+
expectFile: ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json
|
|
171
182
|
allowAppend: false
|
|
172
183
|
|
|
173
184
|
- id: article-write
|
|
@@ -179,11 +190,11 @@ states:
|
|
|
179
190
|
agent: ${vars.agent}
|
|
180
191
|
# ADR-115 error tier: keep this prompt <= 1000 chars (0133 R3).
|
|
181
192
|
input: |
|
|
182
|
-
Read ${vars.work_dir}/
|
|
193
|
+
Read ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json — metadata.docs (Doc[]) is the translated plan; don't edit it.
|
|
183
194
|
Write a morning-news prose article in natural simplified Chinese: title line "# 每日 AI 资讯 — ${vars.run_date}", an intro paragraph (2–3 sentences), then one section per item (## numbered title, 2–4 sentences of flowing prose, source link [来源:<label>](<sourceUri>) inline), a closing paragraph tying items together.
|
|
184
195
|
Narrative register — smooth transitions between items, no list-like bulleting, no scaffold labels (「可做角度」「背景」「潜在影响」), no hedging (「读者宜另行核实」「仍待验证」). Keep facts/URLs from the plan verbatim; product/model names as-is; 「」 quotes.
|
|
185
|
-
Output the markdown to ${vars.work_dir}/
|
|
186
|
-
expectFile: ${vars.work_dir}/
|
|
196
|
+
Output the markdown to ${vars.work_dir}/22-article/${vars.run_date}_06_article-write_body.md.
|
|
197
|
+
expectFile: ${vars.work_dir}/22-article/${vars.run_date}_06_article-write_body.md
|
|
187
198
|
allowAppend: false
|
|
188
199
|
|
|
189
200
|
- id: article
|
|
@@ -206,12 +217,12 @@ states:
|
|
|
206
217
|
agent: ${vars.agent}
|
|
207
218
|
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
208
219
|
input: |
|
|
209
|
-
Read ${vars.work_dir}/
|
|
220
|
+
Read ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json — a JSON array of news docs; don't edit it.
|
|
210
221
|
Take item 1 only (its "title" and "metadata.brief") — the episode's lead story.
|
|
211
222
|
Write one concrete visual scene in English, ≤240 characters, that a viewer would connect to that story: objects, settings, symbols, metaphor.
|
|
212
223
|
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}/
|
|
214
|
-
expectFile: ${vars.work_dir}/
|
|
224
|
+
Output strictly valid JSON {"subject": "..."} to ${vars.work_dir}/23-cover/${vars.run_date}_07_cover-brief.json.
|
|
225
|
+
expectFile: ${vars.work_dir}/23-cover/${vars.run_date}_07_cover-brief.json
|
|
215
226
|
allowAppend: false
|
|
216
227
|
- kind: shell
|
|
217
228
|
options:
|
|
@@ -242,11 +253,11 @@ states:
|
|
|
242
253
|
agent: ${vars.agent}
|
|
243
254
|
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
244
255
|
input: |
|
|
245
|
-
Read ${vars.work_dir}/
|
|
256
|
+
Read ${vars.work_dir}/21-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}/24-script/${vars.run_date}_08_script-write_style.md and obey its char caps and banned phrases.
|
|
246
257
|
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
258
|
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}/
|
|
249
|
-
expectFile: ${vars.work_dir}/
|
|
259
|
+
Output only the JSON object {"version":1,"intro":"…","outro":"…","items":[{"id":"…","lead":"…","insight":"…"}]} with one item per doc id to ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json.
|
|
260
|
+
expectFile: ${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json
|
|
250
261
|
allowAppend: false
|
|
251
262
|
|
|
252
263
|
- id: script
|
|
@@ -263,7 +274,7 @@ states:
|
|
|
263
274
|
onEnter:
|
|
264
275
|
- kind: hitl.confirm
|
|
265
276
|
options:
|
|
266
|
-
prompt: "Review daily AI news VoiceScript at ${vars.work_dir}/
|
|
277
|
+
prompt: "Review daily AI news VoiceScript at ${vars.work_dir}/24-script/${vars.run_date}_08_script_voicescript.yaml. Proceed to voice generation?"
|
|
267
278
|
var: __hitlAnswer
|
|
268
279
|
|
|
269
280
|
- id: wrap-docs
|
|
@@ -342,13 +353,13 @@ states:
|
|
|
342
353
|
agent: ${vars.agent}
|
|
343
354
|
# ADR-115 error tier: keep this prompt <= 1000 chars.
|
|
344
355
|
input: |
|
|
345
|
-
Read ${vars.work_dir}/
|
|
356
|
+
Read ${vars.work_dir}/21-plan/${vars.run_date}_03_plan_plan.json — a JSON array of news docs; don't edit it.
|
|
346
357
|
Take item 1 only (its "title" and "metadata.brief") — the lead story.
|
|
347
358
|
Write a Xiaohongshu note: "title" (≤20 chars) and "body" (Chinese note ≤1000 chars, ending with 3-5 hashtags).
|
|
348
359
|
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
360
|
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}/
|
|
351
|
-
expectFile: ${vars.work_dir}/
|
|
361
|
+
Output strictly valid JSON {"title": "...", "body": "...", "cards": [...]} to ${vars.work_dir}/25-xhs/${vars.run_date}_18_xhs_plan.json.
|
|
362
|
+
expectFile: ${vars.work_dir}/25-xhs/${vars.run_date}_18_xhs_plan.json
|
|
352
363
|
allowAppend: false
|
|
353
364
|
- kind: shell
|
|
354
365
|
onError: continue
|
|
@@ -365,6 +376,15 @@ states:
|
|
|
365
376
|
command: >-
|
|
366
377
|
kk stage daily-publish-xhs "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.xhs_live}"
|
|
367
378
|
|
|
379
|
+
- id: wechat-publish
|
|
380
|
+
description: "Publish the daily article to the WeChat MP draft box via wechatmp-pub (console browser transport) — draft, or live only when wechat_live=true; independent and non-blocking: its outcome never enters publish_status; a sessionless profile refuses fast (headless preflight) and the run continues"
|
|
381
|
+
onEnter:
|
|
382
|
+
- kind: shell
|
|
383
|
+
onError: continue
|
|
384
|
+
options:
|
|
385
|
+
command: >-
|
|
386
|
+
kk stage daily-publish-wechat "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.wechat_live}"
|
|
387
|
+
|
|
368
388
|
- id: publish
|
|
369
389
|
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)"
|
|
370
390
|
onEnter:
|
|
@@ -374,7 +394,7 @@ states:
|
|
|
374
394
|
kk stage daily-publish-classify "${vars.work_dir}" "${vars.run_date}"
|
|
375
395
|
- kind: file.read.into-var
|
|
376
396
|
options:
|
|
377
|
-
path: ${vars.work_dir}/
|
|
397
|
+
path: ${vars.work_dir}/31-publish/${vars.run_date}_17_publish_publish-status.txt
|
|
378
398
|
var: publish_status
|
|
379
399
|
|
|
380
400
|
- id: patch-surfdash
|
|
@@ -410,11 +430,11 @@ states:
|
|
|
410
430
|
kk stage daily-translate-localize "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}"
|
|
411
431
|
- kind: file.read.into-var
|
|
412
432
|
options:
|
|
413
|
-
path: ${vars.work_dir}/
|
|
433
|
+
path: ${vars.work_dir}/31-publish/${vars.run_date}_20_translate-localize_en-post-path.txt
|
|
414
434
|
var: surfdash_en_post_path
|
|
415
435
|
- kind: file.read.into-var
|
|
416
436
|
options:
|
|
417
|
-
path: ${vars.work_dir}/
|
|
437
|
+
path: ${vars.work_dir}/31-publish/${vars.run_date}_20_translate-localize_ja-post-path.txt
|
|
418
438
|
var: surfdash_ja_post_path
|
|
419
439
|
- kind: agent.run
|
|
420
440
|
options:
|
|
@@ -430,7 +450,7 @@ states:
|
|
|
430
450
|
- kind: shell
|
|
431
451
|
options:
|
|
432
452
|
command: >-
|
|
433
|
-
kk stage daily-translate-sync "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.work_dir}/
|
|
453
|
+
kk stage daily-translate-sync "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.work_dir}/31-publish/${vars.run_date}_20_translate-localize_zh-post-path.txt"
|
|
434
454
|
|
|
435
455
|
- id: done
|
|
436
456
|
description: "Terminal — Daily AI news pipeline completed (collect → QC'd plan → article/cover/script/voice → publish/locales)"
|
|
@@ -466,7 +486,7 @@ transitions:
|
|
|
466
486
|
guard:
|
|
467
487
|
kind: shell
|
|
468
488
|
options:
|
|
469
|
-
command: 'test "$(jq ''.metadata.docs | length == 0'' "${vars.work_dir}/
|
|
489
|
+
command: 'test "$(jq ''.metadata.docs | length == 0'' "${vars.work_dir}/21-plan/${vars.run_date}_04_quality-control-content_candidates.json")" = "true"'
|
|
470
490
|
|
|
471
491
|
- from: quality-control-content
|
|
472
492
|
to: plan-translate
|
|
@@ -520,7 +540,7 @@ transitions:
|
|
|
520
540
|
guard:
|
|
521
541
|
kind: shell
|
|
522
542
|
options:
|
|
523
|
-
command: 'test "${vars.cover_enabled}" = "true" && test ! -f "${vars.work_dir}/
|
|
543
|
+
command: 'test "${vars.cover_enabled}" = "true" && test ! -f "${vars.work_dir}/23-cover/${vars.run_date}_07_cover_cover.png"'
|
|
524
544
|
|
|
525
545
|
# F613 R3: first match wins — the cover edge stays above script-write so the cover still
|
|
526
546
|
# generates before the plan is authored; script-write sits above the always `-> script` edges
|
|
@@ -531,7 +551,7 @@ transitions:
|
|
|
531
551
|
guard:
|
|
532
552
|
kind: shell
|
|
533
553
|
options:
|
|
534
|
-
command: 'test "${vars.script_write_enabled}" = "true" && test "${vars.language}" = "zh" && test ! -f "${vars.work_dir}/
|
|
554
|
+
command: 'test "${vars.script_write_enabled}" = "true" && test "${vars.language}" = "zh" && test ! -f "${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json" && test ! -f "${vars.work_dir}/24-script/${vars.run_date}_08_script_voicescript.yaml"'
|
|
535
555
|
|
|
536
556
|
- from: article
|
|
537
557
|
to: script
|
|
@@ -545,7 +565,7 @@ transitions:
|
|
|
545
565
|
guard:
|
|
546
566
|
kind: shell
|
|
547
567
|
options:
|
|
548
|
-
command: 'test "${vars.script_write_enabled}" = "true" && test "${vars.language}" = "zh" && test ! -f "${vars.work_dir}/
|
|
568
|
+
command: 'test "${vars.script_write_enabled}" = "true" && test "${vars.language}" = "zh" && test ! -f "${vars.work_dir}/24-script/${vars.run_date}_08_script-write_plan.json" && test ! -f "${vars.work_dir}/24-script/${vars.run_date}_08_script_voicescript.yaml"'
|
|
549
569
|
|
|
550
570
|
- from: cover
|
|
551
571
|
to: script
|
|
@@ -670,6 +690,20 @@ transitions:
|
|
|
670
690
|
guard:
|
|
671
691
|
kind: always
|
|
672
692
|
|
|
693
|
+
- from: publish-podcast
|
|
694
|
+
to: wechat-publish
|
|
695
|
+
description: "wechat_enabled -> paste the daily article into the WeChat MP console and save it to the draft box; first-match-wins, so this sits above the classification edge (WeChat is independent and never gates publish_status)"
|
|
696
|
+
guard:
|
|
697
|
+
kind: shell
|
|
698
|
+
options:
|
|
699
|
+
command: 'test "${vars.wechat_enabled}" = "true"'
|
|
700
|
+
|
|
701
|
+
- from: wechat-publish
|
|
702
|
+
to: publish
|
|
703
|
+
description: "WeChat draft dispatched (or skipped: onError continue) -> classify the surfdash/podcast outcomes; WeChat contributes no target to the classification"
|
|
704
|
+
guard:
|
|
705
|
+
kind: always
|
|
706
|
+
|
|
673
707
|
- from: publish-podcast
|
|
674
708
|
to: publish
|
|
675
709
|
description: "Podcast dispatched -> classify the per-target outcomes full|partial|none"
|