@gobing-ai/knowledge-kit 0.0.30 → 0.0.31
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/dailynews-gen/dist/index.js +1 -1
- package/plugins/generations/dailynews-gen/src/script-builder.ts +4 -2
- package/plugins/generations/episode-plan-gen/dist/index.js +11 -1
- package/plugins/generations/episode-plan-gen/src/index.ts +23 -2
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/skills/content-judge/SKILL.md +4 -2
- package/plugins/kk/skills/content-judge/references/workflow-integration.md +2 -1
package/package.json
CHANGED
|
@@ -21994,7 +21994,7 @@ function normalizeBroadcastText(raw, isZh) {
|
|
|
21994
21994
|
text = text.replace(/\s+/g, " ");
|
|
21995
21995
|
if (isZh) {
|
|
21996
21996
|
text = text.replace(/[''\u2018\u2019]/g, "");
|
|
21997
|
-
text = text.replace(/[:\uFF1A]/g, "\uFF0C");
|
|
21997
|
+
text = text.replace(/[:\uFF1A](?!\/\/)/g, "\uFF0C");
|
|
21998
21998
|
text = text.replace(/[;\uFF1B]/g, "\u3002");
|
|
21999
21999
|
text = text.replace(/--+/g, "\uFF0C");
|
|
22000
22000
|
text = text.replace(/\.{2,}/g, "\u3002");
|
|
@@ -119,8 +119,10 @@ export function normalizeBroadcastText(raw: string, isZh: boolean): string {
|
|
|
119
119
|
|
|
120
120
|
if (isZh) {
|
|
121
121
|
text = text.replace(/[''‘’]/g, '');
|
|
122
|
-
// Replace English punctuation with Chinese pauses
|
|
123
|
-
|
|
122
|
+
// Replace English punctuation with Chinese pauses. A URL scheme's colon (`https://`,
|
|
123
|
+
// `wss://`) is the exception: spoken as `,//` the URL is mangled, and the content gate
|
|
124
|
+
// (`validate-voicescript.ts` CONTENT_URL_MANGLE_RE) rejects the whole run over it.
|
|
125
|
+
text = text.replace(/[::](?!\/\/)/g, ',');
|
|
124
126
|
text = text.replace(/[;;]/g, '。');
|
|
125
127
|
text = text.replace(/--+/g, ',');
|
|
126
128
|
text = text.replace(/\.{2,}/g, '。');
|
|
@@ -22118,8 +22118,18 @@ function passesGates(doc2, planDate) {
|
|
|
22118
22118
|
return true;
|
|
22119
22119
|
return published >= Date.parse(planDate) - FRESHNESS_DAYS * 86400000;
|
|
22120
22120
|
}
|
|
22121
|
+
var SCAFFOLD_HEADING_RE = /^\s*\*\*\s*[\u300C\u300E][^\u300D\u300F\n]{1,80}[\u300D\u300F]\s*\*\*\s*[\uFF1A:]?(?:\s+|$)/;
|
|
22121
22122
|
function cleanBody(body) {
|
|
22122
|
-
|
|
22123
|
+
const kept = [];
|
|
22124
|
+
for (const line of body.split(`
|
|
22125
|
+
`)) {
|
|
22126
|
+
const stripped = line.replace(SCAFFOLD_HEADING_RE, "");
|
|
22127
|
+
if (stripped.trim() === "" && line.trim() !== "")
|
|
22128
|
+
continue;
|
|
22129
|
+
kept.push(stripped);
|
|
22130
|
+
}
|
|
22131
|
+
return kept.join(`
|
|
22132
|
+
`).replace(/\u2B50\uFE0F\s*[\d.]+\s*\/\s*10/g, "").replace(/^#{1,6}\s*\[[^\]]*\]\([^)]*\)\s*$/gm, "").replace(/\n{3,}/g, `
|
|
22123
22133
|
|
|
22124
22134
|
`).trim();
|
|
22125
22135
|
}
|
|
@@ -248,9 +248,30 @@ function passesGates(doc: Doc, planDate: string): boolean {
|
|
|
248
248
|
return published >= Date.parse(planDate) - FRESHNESS_DAYS * 86_400_000;
|
|
249
249
|
}
|
|
250
250
|
|
|
251
|
-
/**
|
|
251
|
+
/**
|
|
252
|
+
* Research-note section headings: the horizon/last30days note format labels its sections with a
|
|
253
|
+
* bold corner-bracket heading (`**「社区讨论」** 评论区…`, `**「背景」**`, `**「背景:GCN 架构」**`,
|
|
254
|
+
* `**「方案」**`, …). Spoken from a VoiceScript segment they read as scaffolding, and the content
|
|
255
|
+
* gates reject a segment that opens with one (`voice-gen`'s `voicescript.ts`, the
|
|
256
|
+
* `validate-voicescript.ts` sidecar) — which fails the whole unattended daily run at the `script`
|
|
257
|
+
* state (2026-10-03 「背景」/「社区讨论」, 2026-10-04 「社区讨论」). The bold corner-bracket markup is
|
|
258
|
+
* the discriminator: these note bodies never bold-quote conversational prose, so the label list
|
|
259
|
+
* stays open-ended.
|
|
260
|
+
*/
|
|
261
|
+
const SCAFFOLD_HEADING_RE = /^\s*\*\*\s*[「『][^」』\n]{1,80}[」』]\s*\*\*\s*[::]?(?:\s+|$)/;
|
|
262
|
+
|
|
263
|
+
/** Strip `⭐️ x.y/10` ratings, `### [title](url)` heading copies and `**「label」**` research-note
|
|
264
|
+
* section headings from a body. A heading ahead of prose keeps the prose; a heading alone on its
|
|
265
|
+
* line disappears with it. */
|
|
252
266
|
export function cleanBody(body: string): string {
|
|
253
|
-
|
|
267
|
+
const kept: string[] = [];
|
|
268
|
+
for (const line of body.split('\n')) {
|
|
269
|
+
const stripped = line.replace(SCAFFOLD_HEADING_RE, '');
|
|
270
|
+
if (stripped.trim() === '' && line.trim() !== '') continue; // the line held only a heading
|
|
271
|
+
kept.push(stripped);
|
|
272
|
+
}
|
|
273
|
+
return kept
|
|
274
|
+
.join('\n')
|
|
254
275
|
.replace(/⭐️\s*[\d.]+\s*\/\s*10/g, '')
|
|
255
276
|
.replace(/^#{1,6}\s*\[[^\]]*\]\([^)]*\)\s*$/gm, '')
|
|
256
277
|
.replace(/\n{3,}/g, '\n\n')
|
package/plugins/kk/plugin.json
CHANGED
|
@@ -81,8 +81,10 @@ outside `HIGH|MEDIUM|LOW` is not a usable verdict anywhere:
|
|
|
81
81
|
a valid confidence; an absent verdict file keeps the dry-run convention.
|
|
82
82
|
|
|
83
83
|
Add that filter to any new judge gate; `references/workflow-integration.md` carries the pattern and
|
|
84
|
-
`plugins/kk/tests/verdict-confidence.test.ts` fails
|
|
85
|
-
checking the enum
|
|
84
|
+
`plugins/kk/tests/verdict-confidence.test.ts` fails on either half of the contract: a workflow that
|
|
85
|
+
accepts a judge `PASS` without checking the enum, and this skill drifting out of the producer side
|
|
86
|
+
(enum line, per-level definition, or a reference snippet whose filter no longer matches the guards
|
|
87
|
+
the consumer scan collects).
|
|
86
88
|
|
|
87
89
|
The level itself does not change routing — escalation stays owned by the review's `RISK` decisions
|
|
88
90
|
and `escalate` flag; treat `LOW` as a signal to demand human review before publishing.
|
|
@@ -35,7 +35,8 @@ if [ ! -f "$verdict_path" ]; then
|
|
|
35
35
|
fi
|
|
36
36
|
# Confidence-aware read: a PASS without a HIGH|MEDIUM|LOW confidence becomes `PASS!`, which no
|
|
37
37
|
# accept guard matches and the catch-all below rejects. Keep this filter byte-identical wherever a
|
|
38
|
-
# guard reads a judge verdict
|
|
38
|
+
# guard reads a judge verdict — and to this snippet: `plugins/kk/tests/verdict-confidence.test.ts`
|
|
39
|
+
# collects every guard's filter plus this one and fails unless they are byte-identical.
|
|
39
40
|
verdict=$(jq -r 'if (.verdict // "") == "PASS" then (.verdict + (if ((.confidence // "") | test("^(HIGH|MEDIUM|LOW)$")) then "" else "!" end)) else (.verdict // "") end' "$verdict_path")
|
|
40
41
|
case "$verdict" in
|
|
41
42
|
PASS)
|