@gobing-ai/knowledge-kit 0.0.28 → 0.0.30

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 (97) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/dist/index.js +114 -38
  3. package/package.json +1 -1
  4. package/plugins/generations/daily-article-gen/dist/index.js +45 -5
  5. package/plugins/generations/daily-article-gen/src/index.ts +59 -4
  6. package/plugins/generations/dailynews-gen/dist/index.js +46 -9
  7. package/plugins/generations/dailynews-gen/src/index.ts +36 -1
  8. package/plugins/generations/dailynews-gen/src/script-builder.ts +15 -12
  9. package/plugins/generations/dailynews-gen/src/script-plan.ts +21 -3
  10. package/plugins/generations/episode-plan-gen/dist/index.js +55 -4
  11. package/plugins/generations/episode-plan-gen/src/index.ts +80 -2
  12. package/plugins/generations/image-gen/assets/fonts/NotoSansSC-Bold.otf +0 -0
  13. package/plugins/generations/image-gen/assets/fonts/NotoSansSC-Regular.otf +0 -0
  14. package/plugins/generations/image-gen/assets/fonts/OFL.txt +92 -0
  15. package/plugins/generations/image-gen/assets/fonts/SOURCE.md +15 -0
  16. package/plugins/generations/image-gen/dist/index.js +700 -22
  17. package/plugins/generations/image-gen/package.json +1 -0
  18. package/plugins/generations/image-gen/presets/formats/daily-news-cover.yaml +2 -2
  19. package/plugins/generations/image-gen/presets/formats/xhs-card.yaml +19 -11
  20. package/plugins/generations/image-gen/presets/styles/xhs-knowledge.yaml +2 -1
  21. package/plugins/generations/image-gen/scripts/compose-e2e-artifact.ts +135 -0
  22. package/plugins/generations/image-gen/src/bytes.ts +116 -0
  23. package/plugins/generations/image-gen/src/compose/card.ts +294 -0
  24. package/plugins/generations/image-gen/src/compose/chromium.ts +147 -0
  25. package/plugins/generations/image-gen/src/compose/cmap.ts +177 -0
  26. package/plugins/generations/image-gen/src/index.ts +211 -13
  27. package/plugins/generations/image-gen/src/job.ts +12 -0
  28. package/plugins/generations/image-gen/src/presets.ts +53 -13
  29. package/plugins/generations/image-gen/src/providers/minimax.ts +12 -4
  30. package/plugins/generations/image-gen/src/providers/types.ts +12 -1
  31. package/plugins/kk/plugin.json +1 -1
  32. package/plugins/kk/scripts/daily-voice-style.zh.md +27 -14
  33. package/plugins/kk/scripts/itc-stages.ts +21 -3
  34. package/plugins/kk/scripts/kk-workflow-stages.ts +461 -10
  35. package/plugins/kk/scripts/topic-boundary.json +96 -0
  36. package/plugins/kk/scripts/validate-voicescript.ts +15 -0
  37. package/plugins/kk/skills/content-judge/SKILL.md +30 -0
  38. package/plugins/kk/skills/content-judge/references/workflow-integration.md +9 -2
  39. package/plugins/kk/skills/content-safety/SKILL.md +163 -0
  40. package/plugins/kk/skills/content-safety/references/platforms/apple-podcasts.md +36 -0
  41. package/plugins/kk/skills/content-safety/references/platforms/netease-music.md +31 -0
  42. package/plugins/kk/skills/content-safety/references/platforms/wechatmp.md +32 -0
  43. package/plugins/kk/skills/content-safety/references/platforms/xiaoyuzhou.md +35 -0
  44. package/plugins/kk/skills/publish/SKILL.md +1 -1
  45. package/plugins/kk/skills/xhs-images/SKILL.md +11 -7
  46. package/plugins/kk/skills/xhs-images/references/card-layouts.md +4 -4
  47. package/plugins/kk/workflows/judge-gated-publish-example.yaml +18 -10
  48. package/plugins/kk/workflows/kk-daily-ai-voice.yaml +139 -24
  49. package/plugins/kk/workflows/kk-itc.yaml +21 -8
  50. package/plugins/publishings/podcast-pub/dist/index.js +4 -0
  51. package/plugins/publishings/podcast-pub/src/index.ts +2 -0
  52. package/plugins/publishings/podcast-pub/src/show-notes.ts +6 -0
  53. package/plugins/publishings/xhs-pub/dist/index.js +1 -1
  54. package/plugins/publishings/xhs-pub/src/automation-guard.ts +2 -2
  55. package/plugins/publishings/xhs-pub/src/index.ts +1 -1
  56. package/plugins/publishings/xhs-pub/src/profile-check.ts +2 -2
  57. package/plugins/sp/lib/env.ts +0 -46
  58. package/plugins/sp/lib/inline-run.generated.mjs +0 -1489
  59. package/plugins/sp/scripts/batch-preflight.mjs +0 -346
  60. package/plugins/sp/scripts/batch-preflight.ts +0 -459
  61. package/plugins/sp/scripts/daily-summary/daily-summary.mjs +0 -615
  62. package/plugins/sp/scripts/daily-summary/daily-summary.ts +0 -846
  63. package/plugins/sp/scripts/daily-summary/logger.ts +0 -28
  64. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +0 -223
  65. package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +0 -367
  66. package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +0 -132
  67. package/plugins/sp/scripts/dogfood-testing/validate-report.ts +0 -169
  68. package/plugins/sp/scripts/feature-dev-precheck.mjs +0 -171
  69. package/plugins/sp/scripts/feature-dev-precheck.ts +0 -238
  70. package/plugins/sp/scripts/feature-sync-bounded.mjs +0 -285
  71. package/plugins/sp/scripts/feature-sync-bounded.ts +0 -478
  72. package/plugins/sp/scripts/feature-verification-steps.ts +0 -275
  73. package/plugins/sp/scripts/history-anatomy-cache.mjs +0 -902
  74. package/plugins/sp/scripts/history-anatomy-cache.ts +0 -1028
  75. package/plugins/sp/scripts/idea-handoff.mjs +0 -22
  76. package/plugins/sp/scripts/idea-handoff.ts +0 -44
  77. package/plugins/sp/scripts/inline-pipeline-parity-check.ts +0 -185
  78. package/plugins/sp/scripts/inline-run-setup.ts +0 -722
  79. package/plugins/sp/scripts/pr-reviewing.mjs +0 -769
  80. package/plugins/sp/scripts/pr-reviewing.ts +0 -925
  81. package/plugins/sp/scripts/quality-gate.mjs +0 -179
  82. package/plugins/sp/scripts/quality-gate.ts +0 -217
  83. package/plugins/sp/scripts/script-contract-check.ts +0 -319
  84. package/plugins/sp/scripts/stage-registry-adapter.ts +0 -1533
  85. package/plugins/sp/scripts/surface-drift-inventory.ts +0 -929
  86. package/plugins/sp/scripts/task-evidence-precheck.ts +0 -181
  87. package/plugins/sp/scripts/task-size-precheck.ts +0 -175
  88. package/plugins/sp/scripts/transition-shim-check.ts +0 -238
  89. package/plugins/sp/scripts/validate-commands.ts +0 -689
  90. package/plugins/sp/scripts/validate-flag-contracts.ts +0 -878
  91. package/plugins/sp/scripts/verify-answer-lint.ts +0 -530
  92. package/plugins/sp/scripts/workflow-step-profile.mjs +0 -316
  93. package/plugins/sp/scripts/workflow-step-profile.ts +0 -456
  94. package/plugins/sp/scripts/wrapup-drift-probe.mjs +0 -190
  95. package/plugins/sp/scripts/wrapup-drift-probe.ts +0 -258
  96. package/plugins/sp/scripts/wrapup-steps.mjs +0 -444
  97. package/plugins/sp/scripts/wrapup-steps.ts +0 -552
@@ -31,6 +31,28 @@ export interface FormatVariable {
31
31
  default: string;
32
32
  }
33
33
 
34
+ /**
35
+ * Optional compose block in a format preset (task 0180, F616).
36
+ * When present, image-gen typesets the on-card copy from Noto Sans SC via
37
+ * headless Chromium instead of generating text as pixels. Requires `width`
38
+ * and `height` on the format (enforced by FormatPresetSchema refine).
39
+ */
40
+ export interface ComposeConfig {
41
+ /** The only v1 engine value; zod literal enforces it. */
42
+ engine: 'text-card';
43
+ /** Safe-area inset in px on all sides. */
44
+ safeArea: number;
45
+ /** Headline minimum font size in px. */
46
+ headlineMinPx: number;
47
+ /** Body/bullets minimum font size in px. */
48
+ bodyMinPx: number;
49
+ /** Height in px of the illustration band (top); text panel takes the rest. */
50
+ illustrationHeight: number;
51
+ palette: { background: string; text: string; accent: string };
52
+ /** Font filenames under `assets/fonts/`. */
53
+ fonts: { headline: string; body: string };
54
+ }
55
+
34
56
  /** R1 — `formats/<name>.yaml`: the job skeleton (template, keywords, variables). */
35
57
  export interface FormatPreset {
36
58
  /** Filename stem must equal this. */
@@ -51,6 +73,8 @@ export interface FormatPreset {
51
73
  variables: Record<string, FormatVariable>;
52
74
  /** Prompt body; YAML block scalar, embedded newlines preserved. */
53
75
  template: string;
76
+ /** Optional compose block (0180): when present, image-gen typesets card copy from a real font. */
77
+ compose?: ComposeConfig;
54
78
  }
55
79
 
56
80
  /** R1 — `styles/<name>.yaml`; `modifiers` is the only required prompt field. */
@@ -76,21 +100,37 @@ const PresetSourceSchema = z.object({
76
100
  confidence: z.enum(['high', 'medium', 'low']).optional(),
77
101
  });
78
102
 
79
- /** Parse gate for `formats/<name>.yaml`. */
80
- export const FormatPresetSchema = z.object({
81
- name: z.string(),
82
- description: z.string(),
83
- job: z.enum(['free', 'cover', 'illustration']),
84
- aspectRatio: z.string(),
85
- width: z.number().optional(),
86
- height: z.number().optional(),
87
- defaultStyle: z.string(),
88
- keywords: z.array(z.string()),
89
- outputFilename: z.string(),
90
- variables: z.record(z.string(), z.object({ description: z.string(), default: z.string() })),
91
- template: z.string(),
103
+ /** The zod schema for the optional compose block (0180). */
104
+ const ComposeConfigSchema = z.object({
105
+ engine: z.literal('text-card'),
106
+ safeArea: z.number(),
107
+ headlineMinPx: z.number(),
108
+ bodyMinPx: z.number(),
109
+ illustrationHeight: z.number(),
110
+ palette: z.object({ background: z.string(), text: z.string(), accent: z.string() }),
111
+ fonts: z.object({ headline: z.string(), body: z.string() }),
92
112
  });
93
113
 
114
+ /** Parse gate for `formats/<name>.yaml`. */
115
+ export const FormatPresetSchema = z
116
+ .object({
117
+ name: z.string(),
118
+ description: z.string(),
119
+ job: z.enum(['free', 'cover', 'illustration']),
120
+ aspectRatio: z.string(),
121
+ width: z.number().optional(),
122
+ height: z.number().optional(),
123
+ defaultStyle: z.string(),
124
+ keywords: z.array(z.string()),
125
+ outputFilename: z.string(),
126
+ variables: z.record(z.string(), z.object({ description: z.string(), default: z.string() })),
127
+ template: z.string(),
128
+ compose: ComposeConfigSchema.optional(),
129
+ })
130
+ .refine((data) => data.compose === undefined || (data.width !== undefined && data.height !== undefined), {
131
+ message: 'A format preset with a compose block requires both width and height to be declared',
132
+ });
133
+
94
134
  /** Parse gate for `styles/<name>.yaml`. */
95
135
  export const StylePresetSchema = z.object({
96
136
  name: z.string(),
@@ -50,11 +50,17 @@ export function parsePixelSize(size: string): { width: number; height: number }
50
50
  return { width, height };
51
51
  }
52
52
 
53
+ /** 0182 R4: image-01 accepts an exact canvas of 512..2048 per edge, divisible by 8. */
54
+ function isAcceptablePixelSize(width: number, height: number): boolean {
55
+ return width >= 512 && width <= 2048 && height >= 512 && height <= 2048 && width % 8 === 0 && height % 8 === 0;
56
+ }
57
+
58
+ /** Throwing twin of {@link isAcceptablePixelSize} for the request-body path; messages are frozen (tests pin them). */
53
59
  function validatePixelSize(width: number, height: number): void {
54
- if (width < 512 || width > 2048 || height < 512 || height > 2048) {
55
- throw new Error('MiniMax custom size must keep width and height between 512 and 2048.');
56
- }
57
- if (width % 8 !== 0 || height % 8 !== 0) {
60
+ if (!isAcceptablePixelSize(width, height)) {
61
+ if (width < 512 || width > 2048 || height < 512 || height > 2048) {
62
+ throw new Error('MiniMax custom size must keep width and height between 512 and 2048.');
63
+ }
58
64
  throw new Error('MiniMax custom size requires width and height divisible by 8.');
59
65
  }
60
66
  }
@@ -146,6 +152,8 @@ export const createMinimax: ProviderFactory = (options?: ProviderOptions): Image
146
152
  defaultModel: () => DEFAULT_MODEL,
147
153
  isAvailable: () => readEnv('MINIMAX_API_KEY') !== '',
148
154
  supportsReferenceImages: () => true,
155
+ exactSize: (model: string, width: number, height: number): boolean =>
156
+ model === 'image-01' && isAcceptablePixelSize(width, height),
149
157
  validate(req: ImageRequest): void {
150
158
  requestBody(req.prompt, req.model, req);
151
159
  },
@@ -32,7 +32,11 @@ export interface ImageRequest {
32
32
  model: string;
33
33
  /** e.g. '21:9' — from FormatPreset.aspectRatio (0102). */
34
34
  aspectRatio?: string;
35
- /** Optional exact pixels; providers that only take an aspect ratio ignore them. */
35
+ /**
36
+ * Declared preset canvas (0182 R1). Sent only when the resolved provider's
37
+ * `exactSize(model, width, height)` returns true — with `aspectRatio` omitted;
38
+ * every other provider receives the aspect-only request shape and never sees them.
39
+ */
36
40
  width?: number;
37
41
  height?: number;
38
42
  quality?: ImageQuality;
@@ -64,6 +68,13 @@ export interface ImageProvider {
64
68
  isAvailable(): boolean;
65
69
  /** Queryable ref-image capability; 0105 routes `--ref` work on this fact. */
66
70
  supportsReferenceImages(model: string): boolean;
71
+ /**
72
+ * Exact-size capability (0182 R1/R4): can this adapter deliver the exact pixel canvas
73
+ * for this model? Absent = aspect-only — `processGeneratorIO` then sends only
74
+ * `aspectRatio`, byte-for-byte as before 0182. Adapters opt in one at a time, on
75
+ * measured evidence (task 0182 Q&A, closed).
76
+ */
77
+ exactSize?(model: string, width: number, height: number): boolean;
67
78
  /** Throw on an impossible combination (e.g. Imagen + referenceImages) before spending money. */
68
79
  validate?(req: ImageRequest): void;
69
80
  generate(req: ImageRequest): Promise<ImageResult>;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "kk",
3
- "version": "0.0.28",
3
+ "version": "0.0.30",
4
4
  "description": "knowledge-kit Claude Code plugin: skills, commands, subagents, hooks, and rules"
5
5
  }
@@ -1,37 +1,45 @@
1
- # 每日AI科技漫谈 · 主持风格契约(zh)
1
+ # AI 乱炖 · 主持风格契约(zh)
2
2
 
3
- `kk-daily-ai-voice` 的每一句口播都受这份契约约束(F613 R1)。`script-write` 提示词与
4
- `dailynews-gen` 的校验器读取同一份机器可读块,因此提示词与校验永远一致。
3
+ `kk-daily-ai-voice` 的每一句口播都受这份契约约束(F613 R1;0189 R1 改定位)。`script-write`
4
+ 提示词与 `dailynews-gen` 的校验器读取同一份机器可读块,因此提示词与校验永远一致。
5
+
6
+ ## 栏目定位(0189 R1)
7
+
8
+ 「AI 乱炖」是「咸话咸说」下的 AI 技术分享栏目,副题「工具、论文与实践随聊」。口播是开发者
9
+ 视角的技术分享,不是新闻通报:不播报时事,不以任何代称、绰号或「闲聊」包装政治、外交、
10
+ 军事、公共政策争议或社会公共事件主线的内容——这类条目在选题/QC 阶段就应被排除(0189 R2)。
11
+ 身份与经历必须真实:只讲真实做过的实测与实践,AI 配音参与按真实程度说明。
5
12
 
6
13
  ## 人设与语域
7
14
 
8
- - 口语化普通话,第一人称「我」,像一位冷静、有依据的科技播客主播。
15
+ - 口语化普通话,第一人称「我」,像一位冷静、有依据的 AI 技术分享主播。
9
16
  - 平实、克制、不炒作:不夸大单一消息的意义,不使用惊叹式渲染或营销话术。
10
- - 面向普通听众说明「这件事为什么重要」,而不是堆砌术语。
17
+ - 面向普通听众说明「这件事为什么重要」或「怎么用得上」,而不是堆砌术语。
11
18
 
12
19
  ## 固定开场与收尾
13
20
 
14
21
  开场问候与收尾致谢由 builder 固定输出,计划文本只填充两者之间的内容,节目身份永不漂移:
15
22
 
16
- - 开场:`大家好,今天是<日期>,欢迎收听由<主持人>为您带来的今日AI科技漫谈。`
23
+ - 开场:`大家好,今天是<日期>,欢迎收听「咸话咸说」的「AI 乱炖」栏目,我是<主持人>。`
17
24
  - 收尾:`感谢您的收听,我是<主持人>,祝您拥有充实高效的一天,我们下期节目不见不散!`
18
25
 
19
26
  ## 段落角色
20
27
 
21
- - `intro`:开场导语,串起今天几条主题,接在固定问候之后,不超过 120 字。
22
- - `lead`:一句话口语桥段,引出下一条新闻的【标题】;只做铺垫,不得复述标题本身,不超过 60 字。
23
- - `insight`:只基于这条新闻自身事实的 1–2 句点评,说明它为什么重要;不得挪用其他新闻的话题,不超过 160 字。
24
- - `outro`:简短收束语,接在固定致谢之前,不超过 120 字。
28
+ - `intro`:开场导语,串起今天几个主题,接在固定问候之后,不超过 150 字。
29
+ - `lead`:一句话口语桥段,引出下一个主题的【标题】;只做铺垫,不得复述标题本身,不超过 80 字。
30
+ - `insight`:只基于这一条自身可核事实的点评(3–6 句),展开这一条自身的机制→意义→实用角度;不得挪用其他条目的话题,不超过 380 字。时长契约:全片按 15–20 分钟口播设计,insight 应写到接近上限——宁可深挖这一条的事实,也不要浅尝辄止。字数按配音驱动折算:gemini ≈3.3 字/秒(正文约 4300–5800 字);Voicebox robin-news ≈6.3 字/秒(正文约 5700–7600 字,或增加条目数)。
31
+ - `outro`:简短收束语,接在固定致谢之前,不超过 150 字。
25
32
 
26
33
  ## 机器可读契约
27
34
 
28
35
  `caps` 是各字段的字数上限;`banned` 是任何计划字段都不得出现的短语——包括旧模板的全部罐头
29
- 点评、旧模板的 首先/接着/最后 开头,以及 0133 的研究脚手架标签与对冲语(校验规则
30
- `banned:<短语>`)。
36
+ 点评、旧模板的 首先/接着/最后 开头、0133 的研究脚手架标签与对冲语(校验规则
37
+ `banned:<短语>`),以及 0189 R4 退役的旧栏目名(「每日 AI 资讯」「AI科技漫谈」
38
+ 「AI Daily Briefing」):任何路径都不得让旧新闻定位复活。
31
39
 
32
40
  ```json
33
41
  {
34
- "caps": { "intro": 120, "outro": 120, "lead": 60, "insight": 160 },
42
+ "caps": { "intro": 150, "outro": 150, "lead": 80, "insight": 380 },
35
43
  "banned": [
36
44
  "在各种技术光环背后,正是这样专注而不知疲倦的底层攻坚者,为今天整个大模型生态奠定了最坚实的技术基石。",
37
45
  "这其实释放了一个非常明确的信号:AI竞争的下半场,已经不再只是单纯拼模型参数,更是电力、能源和全栈工业基础设施的硬核较量。",
@@ -46,7 +54,12 @@
46
54
  "背景",
47
55
  "潜在影响",
48
56
  "读者宜另行核实",
49
- "仍待验证"
57
+ "仍待验证",
58
+ "每日AI资讯",
59
+ "每日 AI 资讯",
60
+ "今日AI科技漫谈",
61
+ "AI科技漫谈",
62
+ "AI Daily Briefing"
50
63
  ]
51
64
  }
52
65
  ```
@@ -131,7 +131,18 @@ export function itcReport(args: string[]): void {
131
131
  const [workDir = '', maxRevisions = ''] = args;
132
132
  if (!workDir) fail('usage: itc-report <work_dir> [max_revisions]');
133
133
  const verdictPath = join(workDir, '.itc-verdict.json');
134
- const verdict = existsSync(verdictPath) ? ((readJson(verdictPath) as { verdict?: unknown }).verdict ?? '') : '';
134
+ const verdictJson = existsSync(verdictPath)
135
+ ? (readJson(verdictPath) as { verdict?: unknown; confidence?: unknown })
136
+ : {};
137
+ const verdict = verdictJson.verdict ?? '';
138
+ // Same enum as the workflow guards and `daily-safety-gate`: a PASS without a HIGH/MEDIUM/LOW
139
+ // confidence never cleared the judge gate, so the report must not claim a publish-ready draft.
140
+ // An absent verdict file stays the dry-run PASS convention (verdict '').
141
+ const unusablePass =
142
+ verdict === 'PASS' &&
143
+ verdictJson.confidence !== 'HIGH' &&
144
+ verdictJson.confidence !== 'MEDIUM' &&
145
+ verdictJson.confidence !== 'LOW';
135
146
  // Auto runs count on .auto-revise-count; interactive runs keep the existing .revise-count.
136
147
  const revisions = readCount(join(workDir, '.auto-revise-count')) ?? readCount(join(workDir, '.revise-count')) ?? 0;
137
148
  // Exhaustion only fails the run when the last verdict still asks for another revision —
@@ -186,7 +197,8 @@ export function itcReport(args: string[]): void {
186
197
  }
187
198
 
188
199
  const publishFailed = targets.some((t) => !t.ok);
189
- const outcome = verdict === 'FAIL' || exhausted || publishFailed ? 'failed' : declined ? 'declined' : 'done';
200
+ const outcome =
201
+ verdict === 'FAIL' || unusablePass || exhausted || publishFailed ? 'failed' : declined ? 'declined' : 'done';
190
202
  const reportDir = join(workDir, '5-report');
191
203
  const jsonPath = join(reportDir, 'report.json');
192
204
  const publish = hasPlan ? { targets, retryCommands } : undefined;
@@ -198,7 +210,13 @@ export function itcReport(args: string[]): void {
198
210
  );
199
211
  writeFileSync(
200
212
  join(reportDir, 'report.md'),
201
- `# kk-itc run report\n\n- Outcome: ${outcome}\n- Verdict: ${verdict === '' ? 'PASS (empty)' : verdict}\n- Revisions: ${revisions}\n` +
213
+ `# kk-itc run report\n\n- Outcome: ${outcome}\n- Verdict: ${
214
+ verdict === ''
215
+ ? 'PASS (empty)'
216
+ : unusablePass
217
+ ? 'PASS (no HIGH/MEDIUM/LOW confidence — the judge gate never cleared)'
218
+ : verdict
219
+ }\n- Revisions: ${revisions}\n` +
202
220
  (declined
203
221
  ? '\n## Publish\n\n- Declined by the operator — nothing was sent.\n'
204
222
  : targets.length > 0