@gobing-ai/knowledge-kit 0.0.13 → 0.0.15
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 +20 -0
- package/package.json +1 -1
- package/plugins/generations/content-gen/dist/index.js +20 -0
- package/plugins/generations/core-facts-gen/dist/index.js +20 -0
- package/plugins/generations/daily-article-gen/dist/index.js +29 -1
- package/plugins/generations/daily-article-gen/src/index.ts +13 -1
- package/plugins/generations/dailynews-gen/dist/index.js +20 -0
- package/plugins/generations/episode-plan-gen/dist/index.js +24 -0
- package/plugins/generations/episode-plan-gen/src/index.ts +11 -0
- package/plugins/generations/image-gen/dist/index.js +2296 -53
- package/plugins/generations/image-gen/src/providers/agnes.ts +110 -0
- package/plugins/generations/image-gen/src/providers/azure.ts +153 -0
- package/plugins/generations/image-gen/src/providers/codex-cli.ts +170 -0
- package/plugins/generations/image-gen/src/providers/dashscope.ts +485 -0
- package/plugins/generations/image-gen/src/providers/google.ts +268 -0
- package/plugins/generations/image-gen/src/providers/huggingface.ts +59 -0
- package/plugins/generations/image-gen/src/providers/jimeng.ts +259 -0
- package/plugins/generations/image-gen/src/providers/minimax.ts +171 -0
- package/plugins/generations/image-gen/src/providers/openai.ts +319 -0
- package/plugins/generations/image-gen/src/providers/openrouter.ts +257 -0
- package/plugins/generations/image-gen/src/providers/refs.ts +24 -0
- package/plugins/generations/image-gen/src/providers/replicate.ts +279 -0
- package/plugins/generations/image-gen/src/providers/seedream.ts +1 -1
- package/plugins/generations/image-gen/src/providers/types.ts +52 -51
- package/plugins/generations/image-gen/src/providers/zai.ts +237 -0
- package/plugins/generations/news-report-gen/dist/index.js +22193 -0
- package/plugins/generations/news-report-gen/package.json +17 -0
- package/plugins/generations/news-report-gen/plugin.json +7 -0
- package/plugins/generations/news-report-gen/src/index.ts +308 -0
- package/plugins/generations/news-report-gen/tsconfig.json +4 -0
- package/plugins/generations/omni-voice-gen/Makefile +14 -0
- package/plugins/generations/omni-voice-gen/README.md +118 -0
- package/plugins/generations/omni-voice-gen/bin/omni-voice-gen +2 -0
- package/plugins/generations/omni-voice-gen/dist/omni-voice-gen-prr8skpb. +2 -0
- package/plugins/generations/omni-voice-gen/dist/omni-voice-gen.js +6 -0
- package/plugins/generations/omni-voice-gen/plugin.json +6 -0
- package/plugins/generations/omni-voice-gen/profiles.json +16 -0
- package/plugins/generations/omni-voice-gen/pyproject.toml +25 -0
- package/plugins/generations/omni-voice-gen/scripts/coverage_gate.py +74 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/__init__.py +1 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/__main__.py +39 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/audio.py +190 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/backend.py +161 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/contract.py +76 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/mp3.py +60 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/pipeline.py +305 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/profiles.py +108 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/qc.py +234 -0
- package/plugins/generations/omni-voice-gen/src/omni_voice_gen/voicescript.py +340 -0
- package/plugins/generations/omni-voice-gen/uv.lock +3510 -0
- package/plugins/generations/omni-voice-gen/voices/robin-news.wav +0 -0
- package/plugins/generations/voice-gen/dist/index.js +30 -2
- package/plugins/generations/voice-gen/src/index.ts +16 -1
- package/plugins/generations/voice-gen/src/voicebox-client.ts +3 -1
- package/plugins/ingestions/aihot-ingest/dist/index.js +20 -0
- package/plugins/ingestions/horizon-ingest/dist/index.js +20 -0
- package/plugins/ingestions/last30days-ingest/dist/index.js +20 -0
- package/plugins/ingestions/web-search/dist/index.js +20 -0
- package/plugins/kk/commands/image-extract.md +40 -0
- package/plugins/kk/commands/image-generate.md +18 -1
- package/plugins/kk/commands/workflow-run.md +54 -22
- package/plugins/kk/config.example.yaml +5 -0
- package/plugins/kk/plugin.json +1 -1
- package/plugins/kk/scripts/kk-workflow-stages.ts +1226 -0
- package/plugins/kk/{workflows → scripts}/validate-voicescript.ts +4 -4
- package/plugins/kk/{workflows → scripts}/wrap-voicescript-doc.ts +7 -6
- package/plugins/kk/skills/audio-authoring/SKILL.md +11 -12
- package/plugins/kk/skills/image-authoring/SKILL.md +10 -3
- package/plugins/kk/skills/image-authoring/references/format-drafting.md +57 -0
- package/plugins/kk/skills/image-authoring/references/style-extraction.md +14 -9
- package/plugins/kk/skills/itc-generating/SKILL.md +2 -2
- package/plugins/kk/skills/itc-generating/references/generic-craft.md +1 -1
- package/plugins/kk/skills/itc-generating/references/platform-english.md +1 -1
- package/plugins/kk/skills/itc-generating/references/platform-wechat.md +1 -1
- package/plugins/kk/skills/storm-research/SKILL.md +5 -5
- package/plugins/kk/skills/topic/SKILL.md +7 -7
- package/plugins/kk/workflows/kk-daily-ai-voice.yaml +219 -133
- package/plugins/kk/workflows/kk-itc.yaml +12 -29
- package/plugins/kk/workflows/kk-solo-podcast.yaml +72 -131
- package/plugins/kk/workflows/kk-storm-research.yaml +12 -62
- package/plugins/publishings/emdash-pub/dist/index.js +20 -0
- package/plugins/publishings/podcast-pub/dist/index.js +57 -3
- package/plugins/publishings/podcast-pub/src/index.ts +18 -2
- package/plugins/publishings/podcast-pub/src/show-notes.ts +56 -9
- package/plugins/publishings/qiita-pub/dist/index.js +20 -0
- package/plugins/publishings/surfdash-pub/dist/index.js +96 -6
- package/plugins/publishings/surfdash-pub/src/index.ts +109 -9
- package/plugins/publishings/zenn-pub/dist/index.js +20 -0
- package/plugins/sp/scripts/batch-preflight.mjs +346 -0
- package/plugins/sp/scripts/batch-preflight.ts +459 -0
- package/plugins/sp/scripts/daily-summary/daily-summary.mjs +615 -0
- package/plugins/sp/scripts/daily-summary/daily-summary.ts +846 -0
- package/plugins/sp/scripts/daily-summary/logger.ts +28 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.mjs +223 -0
- package/plugins/sp/scripts/dogfood-testing/detect-pipeline-driving.ts +367 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.mjs +132 -0
- package/plugins/sp/scripts/dogfood-testing/validate-report.ts +169 -0
- package/plugins/sp/scripts/feature-dev-precheck.mjs +171 -0
- package/plugins/sp/scripts/feature-dev-precheck.ts +238 -0
- package/plugins/sp/scripts/feature-sync-bounded.mjs +285 -0
- package/plugins/sp/scripts/feature-sync-bounded.ts +478 -0
- package/plugins/sp/scripts/history-anatomy-cache.mjs +902 -0
- package/plugins/sp/scripts/history-anatomy-cache.ts +1028 -0
- package/plugins/sp/scripts/idea-handoff.mjs +22 -0
- package/plugins/sp/scripts/idea-handoff.ts +44 -0
- package/plugins/sp/scripts/inline-pipeline-parity-check.ts +185 -0
- package/plugins/sp/scripts/inline-run-setup.ts +198 -0
- package/plugins/sp/scripts/pr-reviewing.mjs +769 -0
- package/plugins/sp/scripts/pr-reviewing.ts +925 -0
- package/plugins/sp/scripts/quality-gate.mjs +179 -0
- package/plugins/sp/scripts/quality-gate.ts +217 -0
- package/plugins/sp/scripts/script-contract-check.ts +319 -0
- package/plugins/sp/scripts/stage-registry-adapter.ts +1533 -0
- package/plugins/sp/scripts/surface-drift-inventory.ts +929 -0
- package/plugins/sp/scripts/task-evidence-precheck.ts +181 -0
- package/plugins/sp/scripts/task-size-precheck.ts +175 -0
- package/plugins/sp/scripts/transition-shim-check.ts +238 -0
- package/plugins/sp/scripts/validate-commands.ts +689 -0
- package/plugins/sp/scripts/validate-flag-contracts.ts +878 -0
- package/plugins/sp/scripts/verify-answer-lint.ts +530 -0
- package/plugins/sp/scripts/workflow-step-profile.mjs +316 -0
- package/plugins/sp/scripts/workflow-step-profile.ts +456 -0
- package/plugins/sp/scripts/wrapup-steps.mjs +373 -0
- package/plugins/sp/scripts/wrapup-steps.ts +466 -0
|
Binary file
|
|
@@ -21848,6 +21848,26 @@ var ResultSchema = exports_external.object({
|
|
|
21848
21848
|
metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21849
21849
|
});
|
|
21850
21850
|
var DocListSchema = exports_external.array(DocSchema);
|
|
21851
|
+
var omniVoiceGenContentSchema = ContentSchema.extend({
|
|
21852
|
+
format: exports_external.literal("audio"),
|
|
21853
|
+
metadata: exports_external.looseObject({
|
|
21854
|
+
generator: exports_external.literal("kk:omni-voice-gen"),
|
|
21855
|
+
audioPath: exports_external.string(),
|
|
21856
|
+
duration: exports_external.number(),
|
|
21857
|
+
segments: exports_external.array(exports_external.looseObject({
|
|
21858
|
+
generationId: exports_external.string(),
|
|
21859
|
+
profile: exports_external.string(),
|
|
21860
|
+
speaker: exports_external.string().optional(),
|
|
21861
|
+
emotion: exports_external.string().optional(),
|
|
21862
|
+
duration: exports_external.number(),
|
|
21863
|
+
verifyRetries: exports_external.number(),
|
|
21864
|
+
transcription: exports_external.string().optional(),
|
|
21865
|
+
loudnessDip: exports_external.boolean().optional()
|
|
21866
|
+
})),
|
|
21867
|
+
mp3Path: exports_external.string().optional(),
|
|
21868
|
+
qc: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21869
|
+
})
|
|
21870
|
+
});
|
|
21851
21871
|
|
|
21852
21872
|
// ../../packages/kk-core/src/kinds.ts
|
|
21853
21873
|
var PLUGIN_KINDS = ["ingestion", "generator", "publish"];
|
|
@@ -22268,7 +22288,7 @@ function createVoiceboxClient(options = {}) {
|
|
|
22268
22288
|
}
|
|
22269
22289
|
} catch (err) {
|
|
22270
22290
|
const reason = err instanceof Error ? err.message : String(err);
|
|
22271
|
-
throw new Error(`Voicebox health check failed at ${url2}: ${reason}`);
|
|
22291
|
+
throw new Error(`Voicebox health check failed at ${url2}: ${reason} \u2014 is Voicebox.app running with its REST server enabled? (restart the app or fix VOICEBOX_URL)`);
|
|
22272
22292
|
}
|
|
22273
22293
|
},
|
|
22274
22294
|
async resolveProfile(nameOrId) {
|
|
@@ -22810,11 +22830,18 @@ async function processGeneratorIO(inputPath, outputPath, clientOverride, transco
|
|
|
22810
22830
|
const scripts = docs.map((doc2) => parseDocToVoiceScript(doc2, envDefaultProfile));
|
|
22811
22831
|
const combinedScript = mergeVoiceScripts(scripts, docs, envDefaultProfile);
|
|
22812
22832
|
validateVoiceScript(combinedScript);
|
|
22833
|
+
const renderStartedAt = Date.now();
|
|
22834
|
+
const maxRunMs = process.env.VOICE_GEN_MAX_RUN_MS ? parseInt(process.env.VOICE_GEN_MAX_RUN_MS, 10) : 0;
|
|
22835
|
+
echoError(`voice-gen: ${combinedScript.segments.length} segments queued for local render`);
|
|
22813
22836
|
const segmentWavs = [];
|
|
22814
22837
|
const segmentGaps = [];
|
|
22815
22838
|
const segmentMetadata = [];
|
|
22816
22839
|
let totalDuration = 0;
|
|
22817
|
-
for (const segment of combinedScript.segments) {
|
|
22840
|
+
for (const [segIndex, segment] of combinedScript.segments.entries()) {
|
|
22841
|
+
if (maxRunMs > 0 && Date.now() - renderStartedAt > maxRunMs) {
|
|
22842
|
+
throw new Error(`voice-gen: render budget ${maxRunMs}ms exceeded after ${segIndex}/${combinedScript.segments.length} segments \u2014 Voicebox may be wedged; raise VOICE_GEN_MAX_RUN_MS if the render is legitimately long`);
|
|
22843
|
+
}
|
|
22844
|
+
const segStartedAt = Date.now();
|
|
22818
22845
|
const speakerConfig = segment.speaker ? combinedScript.speakers?.[segment.speaker] : undefined;
|
|
22819
22846
|
const profileTarget = segment.profile_id ?? segment.profile ?? speakerConfig?.profile_id ?? speakerConfig?.profile ?? combinedScript.default_profile_id ?? combinedScript.default_profile ?? envDefaultProfile ?? (typeof docs[0]?.metadata?.voiceProfile === "string" ? docs[0].metadata.voiceProfile : undefined);
|
|
22820
22847
|
if (!profileTarget) {
|
|
@@ -22930,6 +22957,7 @@ async function processGeneratorIO(inputPath, outputPath, clientOverride, transco
|
|
|
22930
22957
|
transcription,
|
|
22931
22958
|
loudnessDip
|
|
22932
22959
|
});
|
|
22960
|
+
echoError(`voice-gen: segment ${segIndex + 1}/${combinedScript.segments.length} done in ${((Date.now() - segStartedAt) / 1000).toFixed(1)}s${verifyRetries ? ` (${verifyRetries} verify ${verifyRetries === 1 ? "retry" : "retries"})` : ""}`);
|
|
22933
22961
|
}
|
|
22934
22962
|
const concatenatedWav = concatWavs(segmentWavs, segmentGaps);
|
|
22935
22963
|
await fs.ensureDir(outDir);
|
|
@@ -83,6 +83,12 @@ export async function processGeneratorIO(
|
|
|
83
83
|
// 3. Validate VoiceScript
|
|
84
84
|
validateVoiceScript(combinedScript);
|
|
85
85
|
|
|
86
|
+
// Local render can take hours; per-segment progress + an optional total budget keep
|
|
87
|
+
// long renders observable and bounded (dogfood 2026-09-12: healthy 72-min render read as a hang).
|
|
88
|
+
const renderStartedAt = Date.now();
|
|
89
|
+
const maxRunMs = process.env.VOICE_GEN_MAX_RUN_MS ? parseInt(process.env.VOICE_GEN_MAX_RUN_MS, 10) : 0;
|
|
90
|
+
echoError(`voice-gen: ${combinedScript.segments.length} segments queued for local render`);
|
|
91
|
+
|
|
86
92
|
// 4. Generate each segment
|
|
87
93
|
const segmentWavs: Uint8Array[] = [];
|
|
88
94
|
const segmentGaps: number[] = [];
|
|
@@ -98,7 +104,13 @@ export async function processGeneratorIO(
|
|
|
98
104
|
}> = [];
|
|
99
105
|
let totalDuration = 0;
|
|
100
106
|
|
|
101
|
-
for (const segment of combinedScript.segments) {
|
|
107
|
+
for (const [segIndex, segment] of combinedScript.segments.entries()) {
|
|
108
|
+
if (maxRunMs > 0 && Date.now() - renderStartedAt > maxRunMs) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
`voice-gen: render budget ${maxRunMs}ms exceeded after ${segIndex}/${combinedScript.segments.length} segments — Voicebox may be wedged; raise VOICE_GEN_MAX_RUN_MS if the render is legitimately long`,
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
const segStartedAt = Date.now();
|
|
102
114
|
const speakerConfig = segment.speaker ? combinedScript.speakers?.[segment.speaker] : undefined;
|
|
103
115
|
const profileTarget =
|
|
104
116
|
segment.profile_id ??
|
|
@@ -284,6 +296,9 @@ export async function processGeneratorIO(
|
|
|
284
296
|
transcription,
|
|
285
297
|
loudnessDip,
|
|
286
298
|
});
|
|
299
|
+
echoError(
|
|
300
|
+
`voice-gen: segment ${segIndex + 1}/${combinedScript.segments.length} done in ${((Date.now() - segStartedAt) / 1000).toFixed(1)}s${verifyRetries ? ` (${verifyRetries} verify ${verifyRetries === 1 ? 'retry' : 'retries'})` : ''}`,
|
|
301
|
+
);
|
|
287
302
|
}
|
|
288
303
|
|
|
289
304
|
// 5. Concatenate audio
|
|
@@ -73,7 +73,9 @@ export function createVoiceboxClient(options: VoiceboxClientOptions = {}): Voice
|
|
|
73
73
|
}
|
|
74
74
|
} catch (err: unknown) {
|
|
75
75
|
const reason = err instanceof Error ? err.message : String(err);
|
|
76
|
-
throw new Error(
|
|
76
|
+
throw new Error(
|
|
77
|
+
`Voicebox health check failed at ${url}: ${reason} — is Voicebox.app running with its REST server enabled? (restart the app or fix VOICEBOX_URL)`,
|
|
78
|
+
);
|
|
77
79
|
}
|
|
78
80
|
},
|
|
79
81
|
|
|
@@ -21848,6 +21848,26 @@ var ResultSchema = exports_external.object({
|
|
|
21848
21848
|
metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21849
21849
|
});
|
|
21850
21850
|
var DocListSchema = exports_external.array(DocSchema);
|
|
21851
|
+
var omniVoiceGenContentSchema = ContentSchema.extend({
|
|
21852
|
+
format: exports_external.literal("audio"),
|
|
21853
|
+
metadata: exports_external.looseObject({
|
|
21854
|
+
generator: exports_external.literal("kk:omni-voice-gen"),
|
|
21855
|
+
audioPath: exports_external.string(),
|
|
21856
|
+
duration: exports_external.number(),
|
|
21857
|
+
segments: exports_external.array(exports_external.looseObject({
|
|
21858
|
+
generationId: exports_external.string(),
|
|
21859
|
+
profile: exports_external.string(),
|
|
21860
|
+
speaker: exports_external.string().optional(),
|
|
21861
|
+
emotion: exports_external.string().optional(),
|
|
21862
|
+
duration: exports_external.number(),
|
|
21863
|
+
verifyRetries: exports_external.number(),
|
|
21864
|
+
transcription: exports_external.string().optional(),
|
|
21865
|
+
loudnessDip: exports_external.boolean().optional()
|
|
21866
|
+
})),
|
|
21867
|
+
mp3Path: exports_external.string().optional(),
|
|
21868
|
+
qc: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21869
|
+
})
|
|
21870
|
+
});
|
|
21851
21871
|
|
|
21852
21872
|
// ../../packages/kk-core/src/kinds.ts
|
|
21853
21873
|
var PLUGIN_KINDS = ["ingestion", "generator", "publish"];
|
|
@@ -21849,6 +21849,26 @@ var ResultSchema = exports_external.object({
|
|
|
21849
21849
|
metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21850
21850
|
});
|
|
21851
21851
|
var DocListSchema = exports_external.array(DocSchema);
|
|
21852
|
+
var omniVoiceGenContentSchema = ContentSchema.extend({
|
|
21853
|
+
format: exports_external.literal("audio"),
|
|
21854
|
+
metadata: exports_external.looseObject({
|
|
21855
|
+
generator: exports_external.literal("kk:omni-voice-gen"),
|
|
21856
|
+
audioPath: exports_external.string(),
|
|
21857
|
+
duration: exports_external.number(),
|
|
21858
|
+
segments: exports_external.array(exports_external.looseObject({
|
|
21859
|
+
generationId: exports_external.string(),
|
|
21860
|
+
profile: exports_external.string(),
|
|
21861
|
+
speaker: exports_external.string().optional(),
|
|
21862
|
+
emotion: exports_external.string().optional(),
|
|
21863
|
+
duration: exports_external.number(),
|
|
21864
|
+
verifyRetries: exports_external.number(),
|
|
21865
|
+
transcription: exports_external.string().optional(),
|
|
21866
|
+
loudnessDip: exports_external.boolean().optional()
|
|
21867
|
+
})),
|
|
21868
|
+
mp3Path: exports_external.string().optional(),
|
|
21869
|
+
qc: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21870
|
+
})
|
|
21871
|
+
});
|
|
21852
21872
|
|
|
21853
21873
|
// ../../packages/kk-core/src/kinds.ts
|
|
21854
21874
|
var PLUGIN_KINDS = ["ingestion", "generator", "publish"];
|
|
@@ -21850,6 +21850,26 @@ var ResultSchema = exports_external.object({
|
|
|
21850
21850
|
metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21851
21851
|
});
|
|
21852
21852
|
var DocListSchema = exports_external.array(DocSchema);
|
|
21853
|
+
var omniVoiceGenContentSchema = ContentSchema.extend({
|
|
21854
|
+
format: exports_external.literal("audio"),
|
|
21855
|
+
metadata: exports_external.looseObject({
|
|
21856
|
+
generator: exports_external.literal("kk:omni-voice-gen"),
|
|
21857
|
+
audioPath: exports_external.string(),
|
|
21858
|
+
duration: exports_external.number(),
|
|
21859
|
+
segments: exports_external.array(exports_external.looseObject({
|
|
21860
|
+
generationId: exports_external.string(),
|
|
21861
|
+
profile: exports_external.string(),
|
|
21862
|
+
speaker: exports_external.string().optional(),
|
|
21863
|
+
emotion: exports_external.string().optional(),
|
|
21864
|
+
duration: exports_external.number(),
|
|
21865
|
+
verifyRetries: exports_external.number(),
|
|
21866
|
+
transcription: exports_external.string().optional(),
|
|
21867
|
+
loudnessDip: exports_external.boolean().optional()
|
|
21868
|
+
})),
|
|
21869
|
+
mp3Path: exports_external.string().optional(),
|
|
21870
|
+
qc: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21871
|
+
})
|
|
21872
|
+
});
|
|
21853
21873
|
|
|
21854
21874
|
// ../../packages/kk-core/src/kinds.ts
|
|
21855
21875
|
var PLUGIN_KINDS = ["ingestion", "generator", "publish"];
|
|
@@ -21849,6 +21849,26 @@ var ResultSchema = exports_external.object({
|
|
|
21849
21849
|
metadata: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21850
21850
|
});
|
|
21851
21851
|
var DocListSchema = exports_external.array(DocSchema);
|
|
21852
|
+
var omniVoiceGenContentSchema = ContentSchema.extend({
|
|
21853
|
+
format: exports_external.literal("audio"),
|
|
21854
|
+
metadata: exports_external.looseObject({
|
|
21855
|
+
generator: exports_external.literal("kk:omni-voice-gen"),
|
|
21856
|
+
audioPath: exports_external.string(),
|
|
21857
|
+
duration: exports_external.number(),
|
|
21858
|
+
segments: exports_external.array(exports_external.looseObject({
|
|
21859
|
+
generationId: exports_external.string(),
|
|
21860
|
+
profile: exports_external.string(),
|
|
21861
|
+
speaker: exports_external.string().optional(),
|
|
21862
|
+
emotion: exports_external.string().optional(),
|
|
21863
|
+
duration: exports_external.number(),
|
|
21864
|
+
verifyRetries: exports_external.number(),
|
|
21865
|
+
transcription: exports_external.string().optional(),
|
|
21866
|
+
loudnessDip: exports_external.boolean().optional()
|
|
21867
|
+
})),
|
|
21868
|
+
mp3Path: exports_external.string().optional(),
|
|
21869
|
+
qc: exports_external.record(exports_external.string(), exports_external.unknown()).optional()
|
|
21870
|
+
})
|
|
21871
|
+
});
|
|
21852
21872
|
|
|
21853
21873
|
// ../../packages/kk-core/src/kinds.ts
|
|
21854
21874
|
var PLUGIN_KINDS = ["ingestion", "generator", "publish"];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: image-extract
|
|
3
|
+
description: Extract a reusable style preset (and optionally draft a format preset) from 1-5 reference images, saved to ~/.config/kk/image-presets/ after confirmation.
|
|
4
|
+
argument-hint: "--name <style-name> --ref <img> [--ref <img>…] [--emit-format <name> --job free|cover|illustration] (max 5 refs)"
|
|
5
|
+
allowed-tools: ["Skill"]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# image-extract
|
|
9
|
+
|
|
10
|
+
Thin wrapper for the `image-authoring` skill's `extract-style` operation — all vision
|
|
11
|
+
analysis, schema-fill, merge, and validation logic lives in the skill. Forward
|
|
12
|
+
`$ARGUMENTS` with one substitution: this command's `--name <style-name>` is the skill's
|
|
13
|
+
`--extract-style <name>` (the flag doubles as the operation selector there — rewrite it,
|
|
14
|
+
do not pass `--name` through). `--ref`, `--emit-format`, and `--job` pass through unchanged.
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
Skill(skill="kk:image-authoring", args="$ARGUMENTS with --name rewritten to --extract-style")
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## What it does
|
|
21
|
+
|
|
22
|
+
- Reads 1–5 reference images (`--ref`, repeatable; more than 5 is refused), analyses
|
|
23
|
+
the look, and shows you the composed `StylePreset` YAML for `--name <style-name>`.
|
|
24
|
+
- **Confirms with you before writing**, then saves to the user root
|
|
25
|
+
`~/.config/kk/image-presets/styles/<name>.yaml` — usable immediately via
|
|
26
|
+
`/kk:image-generate --style <name>`, shadowing any shipped preset of the same name.
|
|
27
|
+
- With `--emit-format <name> --job <job>`, additionally **drafts** a format preset from
|
|
28
|
+
the same images: measured dimensions + declared job + visual defaults authored from
|
|
29
|
+
the analysis, skeleton (variables, template grammar) reused from the shipped format
|
|
30
|
+
of the same job. Shown for confirmation and fine-tuning, then written to
|
|
31
|
+
`~/.config/kk/image-presets/formats/<name>.yaml` with `defaultStyle` set to the
|
|
32
|
+
style just extracted.
|
|
33
|
+
- Validates each new preset with a dry-run generation (`KK_IMAGE_DRY_RUN=1`).
|
|
34
|
+
|
|
35
|
+
Examples:
|
|
36
|
+
|
|
37
|
+
```text
|
|
38
|
+
/kk:image-extract --name flat-retro --ref a.png --ref b.png
|
|
39
|
+
/kk:image-extract --name flat-retro --ref a.png --emit-format retro-cover --job cover
|
|
40
|
+
```
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: image-generate
|
|
3
3
|
description: Generate images from a prompt or an article — covers, illustrations, or free-form — using named format and style presets.
|
|
4
|
-
argument-hint: "[prompt] [--format
|
|
4
|
+
argument-hint: "[prompt] [--format free|cover|illustration] [--style vibrant|minimalist|photorealistic|technical-diagram|editorial|fresh|warm|cute|sketch|clean-webapp-ui|<custom>] [--content <file>] [--ref <img>…] [--var K=V] [--dry-run] [--list-presets]"
|
|
5
5
|
allowed-tools: ["Skill"]
|
|
6
6
|
---
|
|
7
7
|
|
|
@@ -13,3 +13,20 @@ confirmation and delegation logic lives in the skill. Forward `$ARGUMENTS` uncha
|
|
|
13
13
|
```text
|
|
14
14
|
Skill(skill="kk:image-authoring", args="$ARGUMENTS")
|
|
15
15
|
```
|
|
16
|
+
|
|
17
|
+
## Built-in presets (user presets under `~/.config/kk/image-presets/` shadow these)
|
|
18
|
+
|
|
19
|
+
**Formats** (`--format`; default `free`):
|
|
20
|
+
|
|
21
|
+
| Format | Job | Aspect | Default style |
|
|
22
|
+
| ------ | --- | ------ | ------------- |
|
|
23
|
+
| `free` | free-form image from the positional prompt | 1:1 | vibrant |
|
|
24
|
+
| `cover` | article cover; requires `--content <file>` | 21:9 | vibrant |
|
|
25
|
+
| `illustration` | auto-insert illustrations into `--content <file>` | 4:3 | technical-diagram |
|
|
26
|
+
|
|
27
|
+
**Styles** (`--style`): `vibrant` · `minimalist` · `photorealistic` · `technical-diagram` ·
|
|
28
|
+
`editorial` · `fresh` · `warm` · `cute` · `sketch` · `clean-webapp-ui` — or any custom style
|
|
29
|
+
preset name. Omit to use the preference `image.style` or the format's default.
|
|
30
|
+
|
|
31
|
+
Run `--list-presets` for the live list with origins and shadows. Create new presets from
|
|
32
|
+
reference images with `/kk:image-extract`.
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: workflow-run
|
|
3
3
|
description: >-
|
|
4
4
|
Run STORM daily research, IT content authoring, or solo-podcast end to end.
|
|
5
|
-
Resolves the workflow YAML from the user override, KK_WORKFLOWS_SOURCE,
|
|
6
|
-
|
|
5
|
+
Resolves the workflow YAML from the user override, KK_WORKFLOWS_SOURCE, bun/npm
|
|
6
|
+
global installs, the kk package root, or a repo checkout — runs in place from any cwd;
|
|
7
7
|
creates the config with defaults if missing; computes the workspace; shells
|
|
8
8
|
spur workflow run against the resolved YAML.
|
|
9
9
|
argument-hint: "[name] <topic|--in file> [--dir <path>] [--playbook generic|english|wechat] [--research] [--judge] [--outline <a|b|c>] [--writer itc-generating|topic] [--duration <min>] [--language <code>] [--script-approved] [--fixture] [--force]"
|
|
@@ -13,8 +13,9 @@ Thin runner around the **storm-research**, **itc-generating** / **topic**, and *
|
|
|
13
13
|
capabilities. Read `plugins/kk/skills/storm-research/SKILL.md` or
|
|
14
14
|
`plugins/kk/skills/itc-generating/SKILL.md` for craft; solo-podcast craft lives in the
|
|
15
15
|
`audio-authoring` skill. This command owns the run procedure: config create,
|
|
16
|
-
workflow YAML resolution (user override → `$KK_WORKFLOWS_SOURCE` → **
|
|
17
|
-
root** → repo checkout, runs in place from any cwd), workspace
|
|
16
|
+
workflow YAML resolution (user override → `$KK_WORKFLOWS_SOURCE` → **bun/npm global
|
|
17
|
+
install** → **installed package root** → repo checkout, runs in place from any cwd), workspace
|
|
18
|
+
computation, and the
|
|
18
19
|
`spur workflow run` of the resolved YAML. Design-time SSOT remains
|
|
19
20
|
`plugins/kk/workflows/` in the package/repo. No new `kk` CLI noun (ADR-011) — everything here
|
|
20
21
|
is shell + the workflow.
|
|
@@ -30,12 +31,13 @@ Parse per the frozen rule:
|
|
|
30
31
|
`kk-storm-research` (default), `kk-itc`, `kk-solo-podcast`. Any other name after successful copy → exit 1 listing
|
|
31
32
|
`kk-storm-research`, `kk-itc`, `kk-solo-podcast`.
|
|
32
33
|
- `--in <file>` → file mode. `--force` → overwrite an existing dest YAML / existing `brief.md`.
|
|
33
|
-
- Profile `kk-storm-research`: `--
|
|
34
|
-
|
|
34
|
+
- Profile `kk-storm-research`: `--dir <path>` (default `$works_dir/kk-storm-research/<topic-id>`),
|
|
35
|
+
`--fixture` → force `fixture: "true"`.
|
|
36
|
+
- Profile `kk-itc`: `--dir <path>` (default `$works_dir/kk-itc/<kebab>`), `--playbook generic|english|wechat` (default `generic`),
|
|
35
37
|
`--research` (`true`|`false`, default `false`), `--judge` (`true`|`false`, default `false`),
|
|
36
38
|
`--outline <a|b|c>` (default empty), `--writer itc-generating|topic` (default `itc-generating`).
|
|
37
39
|
`--fixture` passed with `kk-itc` or `kk-solo-podcast` → exit 1 (`fixture is storm-only`).
|
|
38
|
-
- Profile `kk-solo-podcast`: `--dir <path>` (default `$works_dir/<
|
|
40
|
+
- Profile `kk-solo-podcast`: `--dir <path>` (default `$works_dir/kk-solo-podcast/<date>`), `--outline <a|b|c>`
|
|
39
41
|
(default empty), `--duration <min>` (default `8`), `--language <code>` (default `en`),
|
|
40
42
|
`--script-approved` (sets `script_approved=true`; default off). `--fixture` is storm-only.
|
|
41
43
|
- **XOR:** exactly one of `<topic>` / `--in <file>`. Both set or both empty → exit 1, stderr
|
|
@@ -90,6 +92,19 @@ while [ -L "$kbin" ]; do
|
|
|
90
92
|
case "$link" in /*) kbin="$link";; *) kbin="$(dirname "$kbin")/$link";; esac
|
|
91
93
|
done
|
|
92
94
|
pkg=""; [ -n "$kbin" ] && pkg="$(cd "$(dirname "$kbin")/.." 2>/dev/null && pwd || true)"
|
|
95
|
+
# Global-install roots — the common no-config case (package installed with `bun install -g`
|
|
96
|
+
# or `npm i -g` and no `workflows_dir` written yet). Each probe is guarded, so a missing
|
|
97
|
+
# package manager never breaks the chain.
|
|
98
|
+
bun_global_workflows=""
|
|
99
|
+
if command -v bun >/dev/null 2>&1; then
|
|
100
|
+
bg="$(dirname "$(bun pm bin -g 2>/dev/null)")/install/global/node_modules/@gobing-ai/knowledge-kit/plugins/kk/workflows"
|
|
101
|
+
[ -d "$bg" ] && bun_global_workflows="$bg"
|
|
102
|
+
fi
|
|
103
|
+
npm_global_workflows=""
|
|
104
|
+
if command -v npm >/dev/null 2>&1; then
|
|
105
|
+
ng="$(dirname "$(npm root -g 2>/dev/null)")/node_modules/@gobing-ai/knowledge-kit/plugins/kk/workflows"
|
|
106
|
+
[ -d "$ng" ] && npm_global_workflows="$ng"
|
|
107
|
+
fi
|
|
93
108
|
```
|
|
94
109
|
|
|
95
110
|
Resolution order — first hit wins:
|
|
@@ -97,26 +112,31 @@ Resolution order — first hit wins:
|
|
|
97
112
|
1. **User override** `$workflows_dir/$NAME.yaml` (default `~/.config/kk/workflows/`) —
|
|
98
113
|
when it exists it always wins, and nothing is copied.
|
|
99
114
|
2. `$KK_WORKFLOWS_SOURCE/$NAME.yaml`
|
|
100
|
-
3. `$
|
|
101
|
-
4.
|
|
115
|
+
3. **bun global install** — `$(dirname $(bun pm bin -g))/install/global/node_modules/@gobing-ai/knowledge-kit/plugins/kk/workflows/$NAME.yaml`
|
|
116
|
+
4. **npm global install** — `$(dirname $(npm root -g))/node_modules/@gobing-ai/knowledge-kit/plugins/kk/workflows/$NAME.yaml`
|
|
117
|
+
5. `$pkg/plugins/kk/workflows/$NAME.yaml` — the installed package copy (resolved from the `kk` binary)
|
|
118
|
+
6. `plugins/kk/workflows/$NAME.yaml` — repo checkout (development)
|
|
119
|
+
|
|
120
|
+
A corrupt `config.yaml` already exited 1 in step 2; none of these probes runs before that check,
|
|
121
|
+
so no fallback masks a config error.
|
|
102
122
|
|
|
103
123
|
```bash
|
|
104
124
|
dest=""
|
|
105
125
|
if [ -f "$workflows_dir/$NAME.yaml" ]; then
|
|
106
126
|
dest="$workflows_dir/$NAME.yaml"
|
|
107
127
|
else
|
|
108
|
-
for d in "$KK_WORKFLOWS_SOURCE" ${pkg:+"$pkg/plugins/kk/workflows"} "plugins/kk/workflows"; do
|
|
128
|
+
for d in "$KK_WORKFLOWS_SOURCE" "$bun_global_workflows" "$npm_global_workflows" ${pkg:+"$pkg/plugins/kk/workflows"} "plugins/kk/workflows"; do
|
|
109
129
|
[ -n "$d" ] && [ -f "$d/$NAME.yaml" ] && { dest="$d/$NAME.yaml"; break; }
|
|
110
130
|
done
|
|
111
|
-
[ -z "$dest" ] && { echo "no source workflow for $NAME (searched $workflows_dir, KK_WORKFLOWS_SOURCE, kk package root, plugins/kk/workflows)" >&2; exit 1; }
|
|
131
|
+
[ -z "$dest" ] && { echo "no source workflow for $NAME (searched $workflows_dir, KK_WORKFLOWS_SOURCE, bun/npm global installs, kk package root, plugins/kk/workflows)" >&2; exit 1; }
|
|
112
132
|
fi
|
|
113
133
|
# --force: refresh the user override from the best available source, then run the override.
|
|
114
134
|
if [ "$FORCE" = true ]; then
|
|
115
135
|
src=""
|
|
116
|
-
for d in "$KK_WORKFLOWS_SOURCE" ${pkg:+"$pkg/plugins/kk/workflows"} "plugins/kk/workflows"; do
|
|
136
|
+
for d in "$KK_WORKFLOWS_SOURCE" "$bun_global_workflows" "$npm_global_workflows" ${pkg:+"$pkg/plugins/kk/workflows"} "plugins/kk/workflows"; do
|
|
117
137
|
[ -n "$d" ] && [ -f "$d/$NAME.yaml" ] && { src="$d/$NAME.yaml"; break; }
|
|
118
138
|
done
|
|
119
|
-
[ -z "$src" ] && { echo "no source workflow for $NAME to force-install (searched KK_WORKFLOWS_SOURCE, kk package root, plugins/kk/workflows)" >&2; exit 1; }
|
|
139
|
+
[ -z "$src" ] && { echo "no source workflow for $NAME to force-install (searched KK_WORKFLOWS_SOURCE, bun/npm global installs, kk package root, plugins/kk/workflows)" >&2; exit 1; }
|
|
120
140
|
install -d "$workflows_dir" && cp "$src" "$workflows_dir/$NAME.yaml"
|
|
121
141
|
dest="$workflows_dir/$NAME.yaml"
|
|
122
142
|
fi
|
|
@@ -126,9 +146,11 @@ fi
|
|
|
126
146
|
`--force` to place a fresh copy there) — that override wins on every later run.
|
|
127
147
|
- No auto-copy, no drift warnings: the package copy is versioned with the CLI and
|
|
128
148
|
never goes stale; overrides are explicit.
|
|
129
|
-
- Sidecars (`
|
|
130
|
-
|
|
131
|
-
root,
|
|
149
|
+
- Sidecars (`plugins/kk/scripts/kk-workflow-stages.ts`, plus the
|
|
150
|
+
`validate-voicescript.ts` / `wrap-voicescript-doc.ts` it delegates to) are **not copied** —
|
|
151
|
+
the workflow resolves the stage runner from the package root, and the runner resolves each
|
|
152
|
+
sidecar via the explicit var, `$KK_WORKFLOWS_DIR`, the package copy, then
|
|
153
|
+
`$HOME/.config/kk/workflows`.
|
|
132
154
|
|
|
133
155
|
## 4. Compute workspace
|
|
134
156
|
|
|
@@ -143,7 +165,7 @@ slug=$(printf '%s' "$normalized" | tr -cs 'a-z0-9' '-' | sed 's/^-*//; s/-*$//'
|
|
|
143
165
|
[ -z "$slug" ] && slug="topic"
|
|
144
166
|
hash=$(printf '%s' "$normalized" | shasum -a 256 | cut -c1-8)
|
|
145
167
|
topic_id="${slug}-${hash}"
|
|
146
|
-
work_dir="$works_dir/$topic_id"
|
|
168
|
+
work_dir="${DIR:-$works_dir/kk-storm-research/$topic_id}"
|
|
147
169
|
```
|
|
148
170
|
|
|
149
171
|
- `raw` derives empty (no H1 and empty basename) → exit 1 with the derived value.
|
|
@@ -157,15 +179,24 @@ mkdir -p "$work_dir"
|
|
|
157
179
|
|
|
158
180
|
`raw` = `TOPIC` or file-mode first ATX H1 else basename without extension.
|
|
159
181
|
`kebab` = lower-case, `[^a-z0-9]+` → `-`, trimmed dashes (no length cap, no sha256 hash).
|
|
160
|
-
`work_dir="${DIR
|
|
182
|
+
`work_dir="${DIR:-$works_dir/kk-itc/$kebab}"`. Empty derived `kebab` → exit 1. An explicit
|
|
183
|
+
`--dir` still wins, and the default never writes into the caller's cwd.
|
|
161
184
|
|
|
162
|
-
### Profile `kk-solo-podcast`
|
|
185
|
+
### Profile `kk-solo-podcast`
|
|
163
186
|
|
|
164
187
|
`date` = today's date in `YYYY-MM-DD` (`$(date +%Y-%m-%d)`).
|
|
165
188
|
`raw` = `TOPIC` or file-mode first ATX H1 else basename without extension.
|
|
166
189
|
`kebab` = lower-case, `[^a-z0-9]+` → `-`, trimmed dashes (no length cap, no sha256 hash).
|
|
167
190
|
`work_dir="${DIR:-$works_dir/kk-solo-podcast/$date}"`.
|
|
168
191
|
|
|
192
|
+
### Profile `kk-daily-ai-voice`
|
|
193
|
+
|
|
194
|
+
Same `date` / `raw` / `kebab` derivation as `kk-solo-podcast`.
|
|
195
|
+
`work_dir="${DIR:-$works_dir/kk-daily-ai-voice/$date}"`.
|
|
196
|
+
|
|
197
|
+
Every profile's default puts its workspace in **its own** `$works_dir/<workflow-name>/` namespace;
|
|
198
|
+
an explicit `--dir` overrides all four defaults.
|
|
199
|
+
|
|
169
200
|
## 5. Run the workflow
|
|
170
201
|
|
|
171
202
|
All values are strings.
|
|
@@ -216,9 +247,10 @@ spur workflow run "$dest" --vars \
|
|
|
216
247
|
and `$work_dir/content.json` (machine contract). Skim `content.md` citations against `docs.json`
|
|
217
248
|
ids before presenting.
|
|
218
249
|
- **`kk-itc`**: print resolved `work_dir`, then `$work_dir/brief.md`, `$work_dir/2-outline/outline-approved.md`,
|
|
219
|
-
and `$work_dir/3-draft
|
|
220
|
-
- **`kk-solo-podcast`**: print resolved `work_dir`, then `$work_dir/
|
|
221
|
-
`$work_dir/
|
|
250
|
+
and `$work_dir/3-draft-draft-article.md`. If `judge=true`, also print the verdict path.
|
|
251
|
+
- **`kk-solo-podcast`**: print resolved `work_dir`, then `$work_dir/1-briefing-briefing.md`,
|
|
252
|
+
`$work_dir/3-script-voicescript.yaml`, `$work_dir/4-audio/content.json`, and
|
|
253
|
+
`$work_dir/4-audio/content.wav`.
|
|
222
254
|
|
|
223
255
|
If the run ended `failed`, show the failing state (`spur workflow trace <run-id> --json`) and the
|
|
224
256
|
fail-loud recovery line.
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
# kk operator config. `works_dir` is the run-workspace root — each workflow run defaults
|
|
2
|
+
# to <works_dir>/<workflow-name>/<run-id> unless --dir is given (existing `.works/`-era
|
|
3
|
+
# trees are not migrated). `workflows_dir` is the user-override root for workflow YAMLs;
|
|
4
|
+
# when a workflow is not found there, /workflow-run falls back to KK_WORKFLOWS_SOURCE,
|
|
5
|
+
# bun/npm global installs, the kk package root, then the repo checkout.
|
|
1
6
|
works_dir: "~/.config/kk/works"
|
|
2
7
|
workflows_dir: "~/.config/kk/workflows"
|
|
3
8
|
defaults:
|
package/plugins/kk/plugin.json
CHANGED