@gobing-ai/knowledge-kit 0.1.7 → 0.1.9
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/board/collect/index.js +744 -1107
- package/dist/board/daily-voice/index.js +741 -107
- package/dist/board/itc/index.js +32 -6
- package/dist/index.js +1793 -103
- package/package.json +1 -1
- package/plugins/ingestions/horizon-ingest/dist/index.js +24 -1
- package/plugins/ingestions/horizon-ingest/src/index.ts +34 -0
- package/plugins/kk/config.example.yaml +8 -0
- package/plugins/kk/decisions/extract/ai-news.yaml +7 -1
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/publish-presets/daily-ai-voice.json +123 -0
- package/plugins/kk/schedules/kk-daily-publish3-cn-peak.cron.tmpl +20 -0
- package/plugins/kk/schedules/kk-daily-publish3-overseas.cron.tmpl +17 -0
- package/plugins/kk/scripts/daily-stages.ts +664 -83
- package/plugins/kk/scripts/kk-workflow-stages.ts +11 -1
- package/plugins/kk/scripts/topic-boundary.json +18 -83
- package/plugins/kk/workflows/kk-collect.yaml +2 -0
- package/plugins/kk/workflows/kk-daily-ai-voice2.yaml +82 -8
- package/plugins/kk/workflows/kk-daily-ai-voice3.yaml +842 -0
- package/plugins/kk/workflows/kk-daily-publish3.yaml +282 -0
- package/plugins/publishings/podcast-pub/README.md +65 -0
- package/plugins/publishings/podcast-pub/dist/index.js +1709 -274
- package/plugins/publishings/podcast-pub/plugin.json +1 -1
- package/plugins/publishings/podcast-pub/src/backfill.ts +465 -0
- package/plugins/publishings/podcast-pub/src/index.ts +211 -34
- package/plugins/publishings/podcast-pub/src/microfeed-client.ts +32 -3
- package/plugins/publishings/podcast-pub/src/seo.ts +1081 -0
- package/plugins/publishings/podcast-pub/src/show-notes.ts +71 -6
- package/plugins/publishings/surfdash-pub/dist/index.js +66 -5
- package/plugins/publishings/surfdash-pub/src/index.ts +94 -10
- package/plugins/publishings/wechatmp-pub/dist/index.js +54 -30
- package/plugins/publishings/wechatmp-pub/dist/profile-check.js +8 -3
- package/plugins/publishings/wechatmp-pub/src/enrich.ts +58 -38
- package/plugins/publishings/wechatmp-pub/src/flow.ts +18 -1
- package/plugins/publishings/wechatmp-pub/src/profile-check.ts +7 -1
|
@@ -1426,7 +1426,12 @@ function dailyPatchSurfdash(args: string[]): void {
|
|
|
1426
1426
|
const pod = targetOf(podcastResult);
|
|
1427
1427
|
const postPath = (sd.metadata as Record<string, unknown> | undefined)?.postPath;
|
|
1428
1428
|
if (typeof postPath !== 'string' || postPath === '') {
|
|
1429
|
-
|
|
1429
|
+
// A surfdash publish that never landed (2026-10-21: its `git push` was rejected with
|
|
1430
|
+
// `fetch first`) leaves no postPath to patch. `publish-classify` has already recorded the
|
|
1431
|
+
// run as `partial`, and failing here turned a published podcast episode into a `failed`
|
|
1432
|
+
// run — the folded tail must not escalate what the classifier already routed.
|
|
1433
|
+
console.error('patch-surfdash: surfdash result carries no postPath — nothing to patch, skip');
|
|
1434
|
+
return;
|
|
1430
1435
|
}
|
|
1431
1436
|
const resultPath = join(workDir, '31-publish', `${runDate}_23_patch-surfdash_sync-result.json`);
|
|
1432
1437
|
if (process.env.KK_SURFDASH_PATCH_OFFLINE === '1') {
|
|
@@ -1742,6 +1747,11 @@ if (import.meta.main)
|
|
|
1742
1747
|
dailyPublishWechat(rest);
|
|
1743
1748
|
break;
|
|
1744
1749
|
}
|
|
1750
|
+
case 'daily-bundle-variants': {
|
|
1751
|
+
const { dailyBundleVariants } = await loadDailyStages();
|
|
1752
|
+
dailyBundleVariants(rest);
|
|
1753
|
+
break;
|
|
1754
|
+
}
|
|
1745
1755
|
case 'daily-publish-classify':
|
|
1746
1756
|
dailyPublishClassify(rest);
|
|
1747
1757
|
break;
|
|
@@ -1,92 +1,27 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version":
|
|
3
|
-
"note": "Task 0189 R2 topic admission for the AI 乱炖 column, with the 2026-10-02 operator scope correction: the political-diplomatic rule is China-only (中国政治/外交主线). Foreign public-affairs items are NOT floor-excluded — they flow to the plan and are handled by the article-write/script-write/cover 选题边界 prompts (skip + note / plan `excluded`) and the content-safety review. Excluded items are recorded with id, rule, reason and the matched keyword. Sources are never deleted or modified. Scan covers the title plus the first scanChars chars of the body. Precision first: these keywords are a floor, not a sieve — a rare false negative is caught by the prompt-layer boundaries and the content-safety skill review, and a suspected false positive is restored by hand with a recorded reason (manual review), never silently.",
|
|
2
|
+
"version": 2,
|
|
4
3
|
"scanChars": 200,
|
|
5
4
|
"rules": [
|
|
6
5
|
{
|
|
7
|
-
"id": "
|
|
8
|
-
"reason": "
|
|
6
|
+
"id": "prc-leadership",
|
|
7
|
+
"reason": "中国最高领导人敏感线:现任及历任国家最高领导人属平台审核红线,不论条目是否与 AI 相关一律排除(2026-10-22 操作者裁定,取代 0189 R2 的五条规则——诉讼、出口管制、监管博弈、军事技术、社会事件本身都是 AI 产业新闻的主线,整类排除过严)。",
|
|
9
8
|
"keywords": [
|
|
10
|
-
"
|
|
11
|
-
"
|
|
9
|
+
"习近平",
|
|
10
|
+
"毛泽东",
|
|
11
|
+
"邓小平",
|
|
12
|
+
"江泽民",
|
|
13
|
+
"胡锦涛",
|
|
14
|
+
"华国锋",
|
|
15
|
+
"赵紫阳",
|
|
16
|
+
"xi jinping",
|
|
17
|
+
"jiang zemin",
|
|
18
|
+
"deng xiaoping",
|
|
19
|
+
"hu jintao",
|
|
20
|
+
"mao zedong",
|
|
21
|
+
"国家主席",
|
|
12
22
|
"总书记",
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"大使馆",
|
|
16
|
-
"国事访问",
|
|
17
|
-
"政治局",
|
|
18
|
-
"中南海",
|
|
19
|
-
"台海",
|
|
20
|
-
"两岸关系",
|
|
21
|
-
"中美关系"
|
|
22
|
-
]
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"id": "trade-controls",
|
|
26
|
-
"reason": "外交/贸易管制主线:制裁、关税、出口管制、实体清单等政府间管制动作属于公共事务,不是技术实践(0189 R2;涉管制的技术影响可在人工复审后改写为纯技术内容)。",
|
|
27
|
-
"keywords": [
|
|
28
|
-
"制裁",
|
|
29
|
-
"关税",
|
|
30
|
-
"出口管制",
|
|
31
|
-
"实体清单",
|
|
32
|
-
"贸易战",
|
|
33
|
-
"禁令",
|
|
34
|
-
"制裁清单",
|
|
35
|
-
"sanctions",
|
|
36
|
-
"tariff",
|
|
37
|
-
"export control",
|
|
38
|
-
"trade war",
|
|
39
|
-
"entity list"
|
|
40
|
-
]
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
"id": "military",
|
|
44
|
-
"reason": "军事主线:军队、武器、作战相关的条目一律排除(0189 R2)。",
|
|
45
|
-
"keywords": [
|
|
46
|
-
"军队",
|
|
47
|
-
"军事",
|
|
48
|
-
"解放军",
|
|
49
|
-
"武器",
|
|
50
|
-
"导弹",
|
|
51
|
-
"无人机袭击",
|
|
52
|
-
"战场",
|
|
53
|
-
"military",
|
|
54
|
-
"pentagon",
|
|
55
|
-
"missile"
|
|
56
|
-
]
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"id": "policy-dispute",
|
|
60
|
-
"reason": "公共政策争议主线:立法、听证、反垄断等政策博弈是公共事务主线,不是技术内容(0189 R2;纯技术子话题需人工复审并重写后才可使用)。",
|
|
61
|
-
"keywords": [
|
|
62
|
-
"立法",
|
|
63
|
-
"听证",
|
|
64
|
-
"政策争议",
|
|
65
|
-
"反垄断",
|
|
66
|
-
"监管机构",
|
|
67
|
-
"监管新规",
|
|
68
|
-
"法案",
|
|
69
|
-
"regulation",
|
|
70
|
-
"antitrust",
|
|
71
|
-
"legislation",
|
|
72
|
-
"lawsuit"
|
|
73
|
-
]
|
|
74
|
-
},
|
|
75
|
-
{
|
|
76
|
-
"id": "social-event",
|
|
77
|
-
"reason": "社会公共事件主线:事故、灾害、冲突现场等社会事件的报道不属于技术分享(0189 R2)。",
|
|
78
|
-
"keywords": [
|
|
79
|
-
"社会事件",
|
|
80
|
-
"踩踏",
|
|
81
|
-
"骚乱",
|
|
82
|
-
"抗议",
|
|
83
|
-
"示威",
|
|
84
|
-
"罢工",
|
|
85
|
-
"遇难",
|
|
86
|
-
"伤亡",
|
|
87
|
-
"protest",
|
|
88
|
-
"riot",
|
|
89
|
-
"casualties"
|
|
23
|
+
"政治局常委",
|
|
24
|
+
"中南海"
|
|
90
25
|
]
|
|
91
26
|
}
|
|
92
27
|
],
|
|
@@ -110,6 +110,8 @@ states:
|
|
|
110
110
|
# the same 45m leash the daily workflow pins. Writes <work_dir>/10-ingest/<stamp>_02_collect_blended.json.
|
|
111
111
|
# A single failed source degrades to an error entry in the merge (exit 0, surviving docs kept);
|
|
112
112
|
# only an all-sources failure exits 1 and leaves the file unwritten.
|
|
113
|
+
# Empty 6h windows exit 0 with no digest; the plugin falls back to the newest digest ≤26h old
|
|
114
|
+
# (2026-10-23: Oct 21 contributed zero docs when every tick hit an empty window).
|
|
113
115
|
command: >-
|
|
114
116
|
kk executor fan-in
|
|
115
117
|
--source "aihot-ingest:${vars.work_dir}/10-ingest/source.json"
|
|
@@ -48,7 +48,12 @@ vars:
|
|
|
48
48
|
cover_fallback: ""
|
|
49
49
|
# 0219 R3: image-gen vendor fallback for the XHS render; "" restores strict fail-fast.
|
|
50
50
|
xhs_fallback: "true"
|
|
51
|
-
|
|
51
|
+
# 2026-10-21 operator decision: OFF for now (was on since 2026-09-29). The plugin reported today's
|
|
52
|
+
# draft as saved (`草稿箱` 12 -> 13 plus a scoped `保存成功` toast) while the console showed the
|
|
53
|
+
# operator no draft, so the channel's success evidence is not trustworthy until that is resolved.
|
|
54
|
+
# Flip back to "true" to resume the card plan/render/draft series; `xhs_live` stays a separate
|
|
55
|
+
# launch-time switch and nothing else in the run depends on this target.
|
|
56
|
+
xhs_enabled: "false"
|
|
52
57
|
xhs_cards: "4"
|
|
53
58
|
xhs_style: "xhs-knowledge"
|
|
54
59
|
xhs_provider: "minimax"
|
|
@@ -86,9 +91,35 @@ vars:
|
|
|
86
91
|
episode_min_minutes: "15"
|
|
87
92
|
# 2026-10-09 operator decision: ingest bodies are spoken in full and today's pools render 22-46
|
|
88
93
|
# minutes at the current item counts, so the 20-minute ceiling refused real episodes before any
|
|
89
|
-
# TTS request. The pair drives
|
|
90
|
-
# gate
|
|
94
|
+
# TTS request. The pair drives the pre-spend estimates (`daily-qc-content`'s pool gate, and
|
|
95
|
+
# `daily-generate`'s script gate, which measures the authored VoiceScript) and the measured gate
|
|
96
|
+
# in `daily-episode-duration`.
|
|
91
97
|
episode_max_minutes: "25"
|
|
98
|
+
# podcast-pub per-episode SEO (D9). Defaults match the plugin. Legacy publish output:
|
|
99
|
+
# podcast_seo=false, podcast_summary_paragraph=false, podcast_timeline_inline_style=before,
|
|
100
|
+
# podcast_auto_episode_number=false, podcast_link_field=url, podcast_slug=auto,
|
|
101
|
+
# podcast_round_duration=false. Title keywords stay in podcast-pub; ID3 keeps the date-only title.
|
|
102
|
+
podcast_seo: "true"
|
|
103
|
+
podcast_episode_title_mode: "as-is"
|
|
104
|
+
podcast_episode_title_pattern: "{series} · {date}:{keywords}"
|
|
105
|
+
podcast_series_name: "每日AI乱炖"
|
|
106
|
+
podcast_show_name: "咸话咸说"
|
|
107
|
+
podcast_title_max: "55"
|
|
108
|
+
podcast_title_max_keywords: "2"
|
|
109
|
+
podcast_seo_title_suffix: "|咸话咸说"
|
|
110
|
+
podcast_seo_title_max: "60"
|
|
111
|
+
podcast_seo_description_min: "120"
|
|
112
|
+
podcast_seo_description_max: "155"
|
|
113
|
+
podcast_seo_description_source: "plan"
|
|
114
|
+
podcast_summary_paragraph: "true"
|
|
115
|
+
podcast_timeline_inline_style: "after"
|
|
116
|
+
podcast_auto_episode_number: "true"
|
|
117
|
+
podcast_title_sanitize: "normalize"
|
|
118
|
+
podcast_link_field: "none"
|
|
119
|
+
podcast_slug: "pattern"
|
|
120
|
+
podcast_slug_pattern: "daily-ai-{date}"
|
|
121
|
+
podcast_social_image: "false"
|
|
122
|
+
podcast_round_duration: "true"
|
|
92
123
|
# Run id, injected by spur at launch (0674 R5/R8) — the selections / ledger / mark-published
|
|
93
124
|
# identity. A shell command may only reference declared vars.
|
|
94
125
|
__runId: ""
|
|
@@ -185,7 +216,7 @@ nodes:
|
|
|
185
216
|
options:
|
|
186
217
|
onError: continue
|
|
187
218
|
command: >-
|
|
188
|
-
kk plugin check wechatmp-pub xhs-pub
|
|
219
|
+
kk plugin check wechatmp-pub xhs-pub --timeout 60000
|
|
189
220
|
|| echo "session-preflight: a publish channel's saved session was refused — fix it before this run's publish step with: bun plugins/publishings/<channel>-pub/src/profile-check.ts login (wechatmp or xhs)"
|
|
190
221
|
|
|
191
222
|
- id: extract
|
|
@@ -195,7 +226,8 @@ nodes:
|
|
|
195
226
|
store's `selections` ledger, written by the `select` node below). Writes
|
|
196
227
|
<work_dir>/10-collect/pool.json (the fan-in blended.json shape) and prints {count}. An empty
|
|
197
228
|
pool writes [] and exits 0 — the run's no-content path, not a failure. The `daily-extract`
|
|
198
|
-
stage widens the window (×2, ×3, capped at
|
|
229
|
+
stage widens the window (×2, ×3, ×7, capped at 168h — extended 2026-10-23 when the 72h
|
|
230
|
+
ceiling closed a supply-collapsed day as no-content) only when the configured window's pool cannot
|
|
199
231
|
reach `episode_min_minutes` (2026-10-19): a published episode consumes more stories than a day
|
|
200
232
|
of collection supplies, so the tight window alone closed 2026-10-18/19 as no-content while
|
|
201
233
|
older unselected items sat in the store.
|
|
@@ -575,7 +607,7 @@ nodes:
|
|
|
575
607
|
options:
|
|
576
608
|
onError: continue
|
|
577
609
|
command: >-
|
|
578
|
-
OMNIVOICE_SPEED=1.06 kk stage daily-generate "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.transcode_mp3}" "${vars.vdriver}" "1" "${vars.episode_max_minutes}"
|
|
610
|
+
OMNIVOICE_SPEED=1.06 kk stage daily-generate "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.transcode_mp3}" "${vars.vdriver}" "1" "${vars.episode_max_minutes}" "${vars.episode_min_minutes}"
|
|
579
611
|
|
|
580
612
|
# Driver fallback chain (2026-10-15, operator decision): voxcpm -> gemini -> omni. Each sibling
|
|
581
613
|
# runs the same stage with a pinned driver; its condition re-checks the pool AND that NO upstream
|
|
@@ -596,7 +628,7 @@ nodes:
|
|
|
596
628
|
options:
|
|
597
629
|
onError: continue
|
|
598
630
|
command: >-
|
|
599
|
-
kk stage daily-generate "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.transcode_mp3}" "gemini" "1" "${vars.episode_max_minutes}"
|
|
631
|
+
kk stage daily-generate "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.transcode_mp3}" "gemini" "1" "${vars.episode_max_minutes}" "${vars.episode_min_minutes}"
|
|
600
632
|
|
|
601
633
|
- id: generate-fallback2
|
|
602
634
|
description: "Voice tier fallback 2 (last, loud): omni-voice-gen when neither voxcpm nor gemini delivered"
|
|
@@ -611,7 +643,7 @@ nodes:
|
|
|
611
643
|
kind: shell
|
|
612
644
|
options:
|
|
613
645
|
command: >-
|
|
614
|
-
OMNIVOICE_SPEED=1.06 kk stage daily-generate "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.transcode_mp3}" "ominivoice" "1" "${vars.episode_max_minutes}"
|
|
646
|
+
OMNIVOICE_SPEED=1.06 kk stage daily-generate "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.transcode_mp3}" "ominivoice" "1" "${vars.episode_max_minutes}" "${vars.episode_min_minutes}"
|
|
615
647
|
|
|
616
648
|
- id: intro
|
|
617
649
|
description: "Prepend the 8s intro sting (intro_music var; empty = skip), update duration/audioPath"
|
|
@@ -713,6 +745,27 @@ nodes:
|
|
|
713
745
|
kind: shell
|
|
714
746
|
options:
|
|
715
747
|
command: >-
|
|
748
|
+
PODCAST_PUB_SEO="${vars.podcast_seo}"
|
|
749
|
+
PODCAST_PUB_EPISODE_TITLE_MODE="${vars.podcast_episode_title_mode}"
|
|
750
|
+
PODCAST_PUB_EPISODE_TITLE_PATTERN="${vars.podcast_episode_title_pattern}"
|
|
751
|
+
PODCAST_PUB_SERIES_NAME="${vars.podcast_series_name}"
|
|
752
|
+
PODCAST_PUB_SHOW_NAME="${vars.podcast_show_name}"
|
|
753
|
+
PODCAST_PUB_TITLE_MAX="${vars.podcast_title_max}"
|
|
754
|
+
PODCAST_PUB_TITLE_MAX_KEYWORDS="${vars.podcast_title_max_keywords}"
|
|
755
|
+
PODCAST_PUB_SEO_TITLE_SUFFIX="${vars.podcast_seo_title_suffix}"
|
|
756
|
+
PODCAST_PUB_SEO_TITLE_MAX="${vars.podcast_seo_title_max}"
|
|
757
|
+
PODCAST_PUB_SEO_DESCRIPTION_MIN="${vars.podcast_seo_description_min}"
|
|
758
|
+
PODCAST_PUB_SEO_DESCRIPTION_MAX="${vars.podcast_seo_description_max}"
|
|
759
|
+
PODCAST_PUB_SEO_DESCRIPTION_SOURCE="${vars.podcast_seo_description_source}"
|
|
760
|
+
PODCAST_PUB_SUMMARY_PARAGRAPH="${vars.podcast_summary_paragraph}"
|
|
761
|
+
PODCAST_PUB_TIMELINE_INLINE_STYLE="${vars.podcast_timeline_inline_style}"
|
|
762
|
+
PODCAST_PUB_AUTO_EPISODE_NUMBER="${vars.podcast_auto_episode_number}"
|
|
763
|
+
PODCAST_PUB_TITLE_SANITIZE="${vars.podcast_title_sanitize}"
|
|
764
|
+
PODCAST_PUB_LINK_FIELD="${vars.podcast_link_field}"
|
|
765
|
+
PODCAST_PUB_SLUG="${vars.podcast_slug}"
|
|
766
|
+
PODCAST_PUB_SLUG_PATTERN="${vars.podcast_slug_pattern}"
|
|
767
|
+
PODCAST_PUB_SOCIAL_IMAGE="${vars.podcast_social_image}"
|
|
768
|
+
PODCAST_PUB_ROUND_DURATION="${vars.podcast_round_duration}"
|
|
716
769
|
kk stage daily-show-notes "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}" "${vars.title}"
|
|
717
770
|
|
|
718
771
|
- id: publish-podcast
|
|
@@ -726,6 +779,27 @@ nodes:
|
|
|
726
779
|
kind: shell
|
|
727
780
|
options:
|
|
728
781
|
command: >-
|
|
782
|
+
PODCAST_PUB_SEO="${vars.podcast_seo}"
|
|
783
|
+
PODCAST_PUB_EPISODE_TITLE_MODE="${vars.podcast_episode_title_mode}"
|
|
784
|
+
PODCAST_PUB_EPISODE_TITLE_PATTERN="${vars.podcast_episode_title_pattern}"
|
|
785
|
+
PODCAST_PUB_SERIES_NAME="${vars.podcast_series_name}"
|
|
786
|
+
PODCAST_PUB_SHOW_NAME="${vars.podcast_show_name}"
|
|
787
|
+
PODCAST_PUB_TITLE_MAX="${vars.podcast_title_max}"
|
|
788
|
+
PODCAST_PUB_TITLE_MAX_KEYWORDS="${vars.podcast_title_max_keywords}"
|
|
789
|
+
PODCAST_PUB_SEO_TITLE_SUFFIX="${vars.podcast_seo_title_suffix}"
|
|
790
|
+
PODCAST_PUB_SEO_TITLE_MAX="${vars.podcast_seo_title_max}"
|
|
791
|
+
PODCAST_PUB_SEO_DESCRIPTION_MIN="${vars.podcast_seo_description_min}"
|
|
792
|
+
PODCAST_PUB_SEO_DESCRIPTION_MAX="${vars.podcast_seo_description_max}"
|
|
793
|
+
PODCAST_PUB_SEO_DESCRIPTION_SOURCE="${vars.podcast_seo_description_source}"
|
|
794
|
+
PODCAST_PUB_SUMMARY_PARAGRAPH="${vars.podcast_summary_paragraph}"
|
|
795
|
+
PODCAST_PUB_TIMELINE_INLINE_STYLE="${vars.podcast_timeline_inline_style}"
|
|
796
|
+
PODCAST_PUB_AUTO_EPISODE_NUMBER="${vars.podcast_auto_episode_number}"
|
|
797
|
+
PODCAST_PUB_TITLE_SANITIZE="${vars.podcast_title_sanitize}"
|
|
798
|
+
PODCAST_PUB_LINK_FIELD="${vars.podcast_link_field}"
|
|
799
|
+
PODCAST_PUB_SLUG="${vars.podcast_slug}"
|
|
800
|
+
PODCAST_PUB_SLUG_PATTERN="${vars.podcast_slug_pattern}"
|
|
801
|
+
PODCAST_PUB_SOCIAL_IMAGE="${vars.podcast_social_image}"
|
|
802
|
+
PODCAST_PUB_ROUND_DURATION="${vars.podcast_round_duration}"
|
|
729
803
|
kk stage daily-publish-podcast "${vars.work_dir}" "${vars.run_date}" "${vars.plugins_path}"
|
|
730
804
|
|
|
731
805
|
# ---- independent soft channels: xhs, wechat, locales (exit 0 on soft failure; fail-fast DAG) ----
|