@gobing-ai/knowledge-kit 0.0.17 → 0.0.19

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 (76) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/README.md +74 -0
  3. package/dist/index.js +108 -107
  4. package/package.json +19 -1
  5. package/plugins/generations/content-gen/dist/index.js +42 -94
  6. package/plugins/generations/core-facts-gen/dist/index.js +51 -100
  7. package/plugins/generations/daily-article-gen/dist/index.js +57 -99
  8. package/plugins/generations/daily-article-gen/src/index.ts +12 -4
  9. package/plugins/generations/dailynews-gen/dist/index.js +57 -102
  10. package/plugins/generations/dailynews-gen/src/script-builder.ts +9 -1
  11. package/plugins/generations/episode-plan-gen/dist/index.js +120 -113
  12. package/plugins/generations/episode-plan-gen/src/index.ts +102 -22
  13. package/plugins/generations/image-gen/dist/index.js +63 -115
  14. package/plugins/generations/news-report-gen/dist/index.js +117 -99
  15. package/plugins/generations/news-report-gen/src/index.ts +117 -1
  16. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/pipeline.py +1 -1
  17. package/plugins/generations/omni-voice-gen/src/omni_voice_gen/voicescript.py +8 -0
  18. package/plugins/generations/voice-gen/dist/index.js +161 -120
  19. package/plugins/generations/voice-gen/src/concat.ts +34 -0
  20. package/plugins/generations/voice-gen/src/index.ts +14 -4
  21. package/plugins/generations/voice-gen/src/voicebox-server.ts +91 -0
  22. package/plugins/generations/voice-gen/src/voicescript.ts +8 -0
  23. package/plugins/ingestions/aihot-ingest/dist/index.js +47 -97
  24. package/plugins/ingestions/horizon-ingest/dist/index.js +47 -96
  25. package/plugins/ingestions/karakeep-local/dist/index.js +217 -266
  26. package/plugins/ingestions/last30days-ingest/dist/index.js +42 -91
  27. package/plugins/ingestions/web-search/dist/index.js +68 -117
  28. package/plugins/kk/commands/workflow-run.md +10 -6
  29. package/plugins/kk/plugin.json +1 -1
  30. package/plugins/kk/scripts/kk-workflow-stages.ts +376 -70
  31. package/plugins/kk/skills/publish/SKILL.md +80 -0
  32. package/plugins/kk/workflows/kk-daily-ai-voice.yaml +136 -224
  33. package/plugins/kk/workflows/leftover-publish-fanout-example.yaml +53 -0
  34. package/plugins/publishings/emdash-pub/dist/index.js +42 -91
  35. package/plugins/publishings/infoq-pub/dist/index.js +21994 -0
  36. package/plugins/publishings/infoq-pub/package.json +17 -0
  37. package/plugins/publishings/infoq-pub/plugin.json +7 -0
  38. package/plugins/publishings/infoq-pub/src/index.ts +123 -0
  39. package/plugins/publishings/infoq-pub/tsconfig.json +4 -0
  40. package/plugins/publishings/juejin-pub/dist/index.js +21994 -0
  41. package/plugins/publishings/juejin-pub/package.json +17 -0
  42. package/plugins/publishings/juejin-pub/plugin.json +7 -0
  43. package/plugins/publishings/juejin-pub/src/index.ts +123 -0
  44. package/plugins/publishings/juejin-pub/tsconfig.json +4 -0
  45. package/plugins/publishings/medium-pub/dist/index.js +22041 -0
  46. package/plugins/publishings/medium-pub/package.json +17 -0
  47. package/plugins/publishings/medium-pub/plugin.json +7 -0
  48. package/plugins/publishings/medium-pub/src/index.ts +215 -0
  49. package/plugins/publishings/medium-pub/tsconfig.json +4 -0
  50. package/plugins/publishings/podcast-pub/dist/index.js +183 -123
  51. package/plugins/publishings/podcast-pub/src/index.ts +47 -3
  52. package/plugins/publishings/podcast-pub/src/show-notes.ts +153 -34
  53. package/plugins/publishings/qiita-pub/dist/index.js +42 -91
  54. package/plugins/publishings/substack-pub/dist/index.js +21994 -0
  55. package/plugins/publishings/substack-pub/package.json +17 -0
  56. package/plugins/publishings/substack-pub/plugin.json +7 -0
  57. package/plugins/publishings/substack-pub/src/index.ts +123 -0
  58. package/plugins/publishings/substack-pub/tsconfig.json +4 -0
  59. package/plugins/publishings/surfdash-pub/dist/index.js +172 -103
  60. package/plugins/publishings/surfdash-pub/src/index.ts +32 -2
  61. package/plugins/publishings/wechatmp-pub/dist/index.js +22119 -0
  62. package/plugins/publishings/wechatmp-pub/package.json +17 -0
  63. package/plugins/publishings/wechatmp-pub/plugin.json +7 -0
  64. package/plugins/publishings/wechatmp-pub/src/index.ts +304 -0
  65. package/plugins/publishings/wechatmp-pub/tsconfig.json +4 -0
  66. package/plugins/publishings/x-pub/dist/index.js +22110 -0
  67. package/plugins/publishings/x-pub/package.json +17 -0
  68. package/plugins/publishings/x-pub/plugin.json +7 -0
  69. package/plugins/publishings/x-pub/src/index.ts +222 -0
  70. package/plugins/publishings/x-pub/tsconfig.json +4 -0
  71. package/plugins/publishings/xhs-pub/dist/index.js +21994 -0
  72. package/plugins/publishings/xhs-pub/package.json +17 -0
  73. package/plugins/publishings/xhs-pub/plugin.json +7 -0
  74. package/plugins/publishings/xhs-pub/src/index.ts +123 -0
  75. package/plugins/publishings/xhs-pub/tsconfig.json +4 -0
  76. package/plugins/publishings/zenn-pub/dist/index.js +42 -91
@@ -97,26 +97,29 @@ const TAG_CATEGORY: Record<string, Category> = {
97
97
  const NON_AI_SOURCES = new Set(['polymarket']);
98
98
 
99
99
  /**
100
- * Title/body keyword signals, scanned in array order (junk → technical → news → industry);
101
- * first hit wins. The junk group is the 0099 audit: ingest template artifacts — error logs,
102
- * checklist boilerplate — used to absorb AI keywords riding along in the boilerplate (0098
103
- * dogfood r7: a yt-dlp HTTP-403 error post classified INTO ai-industry via the word "policy"
104
- * in its "NO AI / NO LLM POLICY" checklist), so they now land `non-ai` instead.
100
+ * Curated AI sources: after the junk-phrase deny, everything from them defaults to `ai-news`
101
+ * even when the title carries no keyword signal (20260917 dogfood: aihot items with clean but
102
+ * signal-free titles fell to `non-ai`). Junk still wins — the deny is checked first.
103
+ */
104
+ const AI_DEFAULT_SOURCES = new Set(['aihot']);
105
+
106
+ /** Ingest junk phrases (error logs, template checklists) — deny before any AI default or signal. */
107
+ const JUNK_KEYWORDS = ['error:', 'http error', 'unable to download'];
108
+
109
+ /**
110
+ * Title/body keyword signals, scanned in array order (technical → news → industry);
111
+ * first hit wins (after the junk deny and the AI_DEFAULT_SOURCES fallback).
105
112
  */
106
113
  const CATEGORY_KEYWORDS: ReadonlyArray<{ category: Category; words: string[] }> = [
107
- {
108
- // Ingest junk: error-log titles and template checklists. Phrases are tight enough
109
- // to never fire on genuine coverage (verified against the r6/r7 blended corpora).
110
- category: 'non-ai',
111
- words: ['error:', 'http error', 'unable to download'],
112
- },
113
114
  {
114
115
  // Technical vocabulary: APIs, tutorials, benchmarks, architecture, inference.
115
116
  category: 'ai-technical',
116
117
  words: ['api', 'tutorial', 'benchmark', 'architecture', 'sdk', 'cli', 'quantization', 'inference', 'fine-tun'],
117
118
  },
118
119
  {
119
- // Launch/release/announce verbs + product names.
120
+ // Launch/release/announce verbs + product names + the generic "ai" token and CJK
121
+ // equivalents + the vendor/lab tokens the 20260917 funnel showed dying uncategorized
122
+ // (vllm/glm/deepseek/qwen/mistral, 华为/英伟达 chip stories).
120
123
  category: 'ai-news',
121
124
  words: [
122
125
  'launch',
@@ -129,13 +132,28 @@ const CATEGORY_KEYWORDS: ReadonlyArray<{ category: Category; words: string[] }>
129
132
  '上线',
130
133
  '推出',
131
134
  '开源',
135
+ 'ai',
136
+ '人工智能',
137
+ '大模型',
132
138
  'sora',
133
139
  'gpt',
140
+ 'chatgpt',
134
141
  'claude',
135
142
  'gemini',
136
143
  'llama',
137
144
  'grok',
138
145
  'copilot',
146
+ 'openai',
147
+ 'anthropic',
148
+ 'deepseek',
149
+ 'qwen',
150
+ 'vllm',
151
+ 'glm',
152
+ 'mistral',
153
+ 'nvidia',
154
+ '英伟达',
155
+ 'huawei',
156
+ '华为',
139
157
  ],
140
158
  },
141
159
  {
@@ -166,6 +184,29 @@ const DEFAULT_IMPORTANCE = 2;
166
184
  export interface PlanOptions {
167
185
  maxItems: number;
168
186
  date?: string; // episode date (YYYY-MM-DD); freshness is judged against it, default today
187
+ /** Out-collector: when provided, receives one audit row per input doc (input order via rowsOf). */
188
+ audit?: PlanAuditRow[];
189
+ }
190
+
191
+ /** Per-doc selection trail (20260917 funnel: why did only 2 of 57 survive?). Disposition is the
192
+ * LAST pipeline stage that touched the doc: gate (rejected) → url-merge (lost a URL collision)
193
+ * → title-merge (absorbed by title similarity) → cap (per-source cap) → topN (rank beyond max)
194
+ * → selected. */
195
+ export interface PlanAuditRow {
196
+ id: string;
197
+ source: string;
198
+ title: string;
199
+ category: Category;
200
+ scores: DimensionScores;
201
+ planScore: number | null;
202
+ disposition: 'gate' | 'url-merge' | 'title-merge' | 'cap' | 'topN' | 'selected';
203
+ }
204
+
205
+ /** Sibling plan-audit path: `<out>.json` → `<out>.audit.json`. */
206
+ export function planAuditOutPath(outputPath: string): string {
207
+ return outputPath.endsWith('.json')
208
+ ? `${outputPath.slice(0, -'.json'.length)}.audit.json`
209
+ : `${outputPath}.audit.json`;
169
210
  }
170
211
 
171
212
  /** Best-effort publication timestamp from mixed source metadata (aihot: publishedAt/discoveredAt; horizon: date). */
@@ -283,8 +324,8 @@ function matchesKeyword(haystack: string, word: string): boolean {
283
324
 
284
325
  /**
285
326
  * MECE category of a doc (v1 — tune later), first match wins: tag map →
286
- * non-AI source deny → title + body-head keyword scan → `non-ai`.
287
- * Deterministic, no LLM.
327
+ * non-AI source deny → junk-phrase deny → AI_DEFAULT_SOURCES fallback →
328
+ * title + body-head keyword scan → `non-ai`. Deterministic, no LLM.
288
329
  */
289
330
  export function classifyCategory(doc: Doc): Category {
290
331
  const meta = asRecord(doc.metadata);
@@ -293,9 +334,12 @@ export function classifyCategory(doc: Doc): Category {
293
334
  const hit = TAG_CATEGORY[tag.toLowerCase()];
294
335
  if (hit) return hit;
295
336
  }
296
- if (NON_AI_SOURCES.has(typeof meta.source === 'string' ? meta.source : '')) return 'non-ai';
337
+ const source = typeof meta.source === 'string' ? meta.source : '';
338
+ if (NON_AI_SOURCES.has(source)) return 'non-ai';
297
339
  const title = (doc.title ?? '').toLowerCase();
298
340
  const bodyHead = (doc.body ?? '').slice(0, 200).toLowerCase();
341
+ if (JUNK_KEYWORDS.some((w) => matchesKeyword(title, w) || matchesKeyword(bodyHead, w))) return 'non-ai';
342
+ if (AI_DEFAULT_SOURCES.has(source)) return 'ai-news';
299
343
  for (const { category, words } of CATEGORY_KEYWORDS) {
300
344
  if (words.some((w) => matchesKeyword(title, w) || matchesKeyword(bodyHead, w))) return category;
301
345
  }
@@ -370,6 +414,7 @@ interface ScoredDoc {
370
414
  /** Full plan pipeline: clean → annotate (category + 4-dim QC scores) → gate (freshness/non-news) → score → URL-dedup → title-dedup → per-source cap → top N. */
371
415
  export function planEpisode(docs: Doc[], options: PlanOptions): Doc[] {
372
416
  const planDate = options.date ?? new Date().toISOString().slice(0, 10);
417
+ const rows = options.audit ? new Map<Doc, PlanAuditRow>() : null;
373
418
  // URL dedup happens on the original sourceUri (first occurrence wins ties,
374
419
  // resolved below by score after the map).
375
420
  const byUrl = new Map<string, ScoredDoc>();
@@ -385,8 +430,26 @@ export function planEpisode(docs: Doc[], options: PlanOptions): Doc[] {
385
430
  scores: scoreDimensions(doc, planDate),
386
431
  },
387
432
  };
433
+ const meta = asRecord(cleaned.metadata);
434
+ // Keyed by the `cleaned` object — later stages hold cleaned docs. Map insertion order
435
+ // == input order, so [...rows.values()] is the audit table layout.
436
+ rows?.set(cleaned, {
437
+ id: doc.id,
438
+ source: sourceOf(doc),
439
+ title: doc.title ?? '',
440
+ category: meta.category as Category,
441
+ scores: meta.scores as DimensionScores,
442
+ planScore: null,
443
+ disposition: 'gate',
444
+ });
388
445
  if (!passesGates(cleaned, planDate)) continue;
389
- const record = { doc: cleaned, score: planScore(cleaned), mergedFrom: [] as MergedFrom[] };
446
+ const score = planScore(cleaned);
447
+ const row = rows?.get(cleaned);
448
+ if (row) {
449
+ row.planScore = score;
450
+ row.disposition = 'topN'; // provisional: overwritten by every later stage
451
+ }
452
+ const record = { doc: cleaned, score, mergedFrom: [] as MergedFrom[] };
390
453
  const urlKey = normalizeUrl(doc.sourceUri);
391
454
  if (urlKey) {
392
455
  const existing = byUrl.get(urlKey);
@@ -399,6 +462,8 @@ export function planEpisode(docs: Doc[], options: PlanOptions): Doc[] {
399
462
  title: loser.doc.title ?? '',
400
463
  url: loser.doc.sourceUri ?? null,
401
464
  });
465
+ const loserRow = rows?.get(loser.doc);
466
+ if (loserRow) loserRow.disposition = 'url-merge';
402
467
  if (winner !== existing) {
403
468
  existing.doc = winner.doc;
404
469
  existing.score = winner.score;
@@ -429,6 +494,8 @@ export function planEpisode(docs: Doc[], options: PlanOptions): Doc[] {
429
494
  title: loser.doc.title ?? '',
430
495
  url: loser.doc.sourceUri ?? null,
431
496
  });
497
+ const loserRow = rows?.get(loser.doc);
498
+ if (loserRow) loserRow.disposition = 'title-merge';
432
499
  absorbed.add(loser);
433
500
  }
434
501
  }
@@ -440,12 +507,19 @@ export function planEpisode(docs: Doc[], options: PlanOptions): Doc[] {
440
507
  for (const record of candidates) {
441
508
  const source = sourceOf(record.doc);
442
509
  const count = perSource.get(source) ?? 0;
443
- if (count >= PER_SOURCE_CAP) continue;
510
+ if (count >= PER_SOURCE_CAP) {
511
+ const row = rows?.get(record.doc);
512
+ if (row) row.disposition = 'cap';
513
+ continue;
514
+ }
444
515
  perSource.set(source, count + 1);
445
516
  selected.push(record);
517
+ const row = rows?.get(record.doc);
518
+ if (row) row.disposition = 'selected';
446
519
  if (selected.length >= Math.max(1, options.maxItems)) break;
447
520
  }
448
521
 
522
+ if (rows) options.audit?.push(...rows.values());
449
523
  return selected.map((r) => {
450
524
  const meta = asRecord(r.doc.metadata);
451
525
  const ascii = asciiRatio(r.doc.title ?? '');
@@ -493,8 +567,8 @@ export function renderPlanMarkdown(docs: Doc[], date: string): string {
493
567
  }
494
568
 
495
569
  /** Build the plan Content; `metadata.docs` is the contract with the workflow. */
496
- export function docsToContent(docs: Doc[], date: string): Content {
497
- const planned = planEpisode(docs, { maxItems: maxItemsFromEnv(), date });
570
+ export function docsToContent(docs: Doc[], date: string, audit?: PlanAuditRow[]): Content {
571
+ const planned = planEpisode(docs, { maxItems: maxItemsFromEnv(), date, audit });
498
572
  return planContent(planned, date);
499
573
  }
500
574
 
@@ -559,7 +633,11 @@ export interface RejectedDoc {
559
633
 
560
634
  /** Single source of filter defaults — standalone CLI and workflow stay in lockstep (no divergence). */
561
635
  export const DEFAULT_FILTER_CONFIG: FilterConfig = {
562
- categories: ['ai-news', 'ai-industry'],
636
+ // 20260917 funnel: genuine AI stories died on `category:not-in-allowlist` while carrying
637
+ // technical/research annotations — widen the default allowlist to the whole AI taxonomy;
638
+ // `non-ai` stays excluded (that is the point of the gate). Moves in lockstep with the
639
+ // workflow's qc_categories pin (kk-daily-ai-voice.yaml).
640
+ categories: ['ai-news', 'ai-technical', 'ai-research', 'ai-industry'],
563
641
  // 0098 dogfood calibration (r7, owner-approved 0099): the shipped 3/3/2/2 rejected 20/20
564
642
  // live candidates — the two strongest ai-news items died solely on `impact:1<2`, and
565
643
  // discussion-tier last30days content scores quality 2. quality 3→2, impact 2→1
@@ -682,11 +760,13 @@ export async function processGeneratorIO(
682
760
  return mode === 'filter' ? processFilterIO(inputPath, outputPath) : processPlanIO(inputPath, outputPath);
683
761
  }
684
762
 
685
- /** Plan mode (default, behavior unchanged): blended `Doc[]` → gated/annotated plan Content. */
763
+ /** Plan mode (default, behavior unchanged): blended `Doc[]` → gated/annotated plan Content + `<out>.audit.json` selection trail. */
686
764
  async function processPlanIO(inputPath: string, outputPath: string): Promise<Content> {
687
765
  const docs = DocListSchema.parse(await readJsonFile(inputPath));
688
- const content = docsToContent(docs, resolvePlanDate());
766
+ const audit: PlanAuditRow[] = [];
767
+ const content = docsToContent(docs, resolvePlanDate(), audit);
689
768
  await atomicWrite(outputPath, content);
769
+ await atomicWrite(planAuditOutPath(outputPath), { date: resolvePlanDate(), total: docs.length, rows: audit });
690
770
  return content;
691
771
  }
692
772
 
@@ -14642,72 +14642,6 @@ var init_zod = __esm(() => {
14642
14642
  init_external();
14643
14643
  });
14644
14644
 
14645
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.39/node_modules/@gobing-ai/ts-utils/dist/errors.js
14646
- var ErrorCode;
14647
- var init_errors3 = __esm(() => {
14648
- ErrorCode = {
14649
- NotFound: "NOT_FOUND",
14650
- Validation: "VALIDATION",
14651
- Conflict: "CONFLICT",
14652
- Internal: "INTERNAL"
14653
- };
14654
- });
14655
-
14656
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.39/node_modules/@gobing-ai/ts-utils/dist/api-response.js
14657
- var API_ERROR_CODES, ERROR_CODE_TO_HTTP, CLIENT_SAFE_CODES;
14658
- var init_api_response = __esm(() => {
14659
- init_errors3();
14660
- API_ERROR_CODES = {
14661
- SUCCESS: 0,
14662
- NOT_FOUND: 404,
14663
- VALIDATION_ERROR: 422,
14664
- BAD_REQUEST: 400,
14665
- UNAUTHORIZED: 401,
14666
- FORBIDDEN: 403,
14667
- CONFLICT: 409,
14668
- INTERNAL_ERROR: 500
14669
- };
14670
- ERROR_CODE_TO_HTTP = {
14671
- [ErrorCode.NotFound]: API_ERROR_CODES.NOT_FOUND,
14672
- [ErrorCode.Validation]: API_ERROR_CODES.VALIDATION_ERROR,
14673
- [ErrorCode.Conflict]: API_ERROR_CODES.CONFLICT,
14674
- [ErrorCode.Internal]: API_ERROR_CODES.INTERNAL_ERROR
14675
- };
14676
- CLIENT_SAFE_CODES = new Set([ErrorCode.NotFound, ErrorCode.Validation, ErrorCode.Conflict]);
14677
- });
14678
-
14679
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.39/node_modules/@gobing-ai/ts-utils/dist/cursor.js
14680
- var init_cursor = () => {};
14681
-
14682
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.39/node_modules/@gobing-ai/ts-utils/dist/event-severity.js
14683
- var init_event_severity = () => {};
14684
-
14685
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.39/node_modules/@gobing-ai/ts-utils/dist/output.js
14686
- function processStream(name) {
14687
- const proc = globalThis.process;
14688
- const stream = proc?.[name];
14689
- if (stream === undefined) {
14690
- throw new Error(`No ${name} target available: set one via setDefaultOutputTargets or pass an explicit target`);
14691
- }
14692
- return stream;
14693
- }
14694
- function writeLine(message, target) {
14695
- target.write(`${message}
14696
- `);
14697
- }
14698
- function echoError(message, target = defaultStderrTarget ?? processStream("stderr")) {
14699
- writeLine(message, target);
14700
- }
14701
- var defaultStderrTarget;
14702
-
14703
- // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.39/node_modules/@gobing-ai/ts-utils/dist/index.js
14704
- var init_dist = __esm(() => {
14705
- init_api_response();
14706
- init_cursor();
14707
- init_errors3();
14708
- init_event_severity();
14709
- });
14710
-
14711
14645
  // ../../node_modules/.bun/yaml@2.9.0/node_modules/yaml/dist/nodes/identity.js
14712
14646
  var require_identity = __commonJS((exports) => {
14713
14647
  var ALIAS = Symbol.for("yaml.alias");
@@ -17612,15 +17546,15 @@ var require_timestamp = __commonJS((exports) => {
17612
17546
  throw new Error("!!timestamp expects a date, starting with yyyy-mm-dd");
17613
17547
  const [, year, month, day, hour, minute, second] = match.map(Number);
17614
17548
  const millisec = match[7] ? Number((match[7] + "00").substr(1, 3)) : 0;
17615
- let date6 = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
17549
+ let date5 = Date.UTC(year, month - 1, day, hour || 0, minute || 0, second || 0, millisec);
17616
17550
  const tz = match[8];
17617
17551
  if (tz && tz !== "Z") {
17618
17552
  let d = parseSexagesimal(tz, false);
17619
17553
  if (Math.abs(d) < 30)
17620
17554
  d *= 60;
17621
- date6 -= 60000 * d;
17555
+ date5 -= 60000 * d;
17622
17556
  }
17623
- return new Date(date6);
17557
+ return new Date(date5);
17624
17558
  },
17625
17559
  stringify: ({ value }) => value?.toISOString().replace(/(T00:00:00)?\.000Z$/, "") ?? ""
17626
17560
  };
@@ -19480,7 +19414,7 @@ var require_composer = __commonJS((exports) => {
19480
19414
  var node_process = __require("process");
19481
19415
  var directives = require_directives();
19482
19416
  var Document = require_Document();
19483
- var errors4 = require_errors();
19417
+ var errors3 = require_errors();
19484
19418
  var identity = require_identity();
19485
19419
  var composeDoc = require_compose_doc();
19486
19420
  var resolveEnd = require_resolve_end();
@@ -19531,9 +19465,9 @@ var require_composer = __commonJS((exports) => {
19531
19465
  this.onError = (source, code, message, warning) => {
19532
19466
  const pos = getErrorPos(source);
19533
19467
  if (warning)
19534
- this.warnings.push(new errors4.YAMLWarning(pos, code, message));
19468
+ this.warnings.push(new errors3.YAMLWarning(pos, code, message));
19535
19469
  else
19536
- this.errors.push(new errors4.YAMLParseError(pos, code, message));
19470
+ this.errors.push(new errors3.YAMLParseError(pos, code, message));
19537
19471
  };
19538
19472
  this.directives = new directives.Directives({ version: options.version || "1.2" });
19539
19473
  this.options = options;
@@ -19619,7 +19553,7 @@ ${cb}` : comment;
19619
19553
  break;
19620
19554
  case "error": {
19621
19555
  const msg = token.source ? `${token.message}: ${JSON.stringify(token.source)}` : token.message;
19622
- const error51 = new errors4.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg);
19556
+ const error51 = new errors3.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg);
19623
19557
  if (this.atDirectives || !this.doc)
19624
19558
  this.errors.push(error51);
19625
19559
  else
@@ -19629,7 +19563,7 @@ ${cb}` : comment;
19629
19563
  case "doc-end": {
19630
19564
  if (!this.doc) {
19631
19565
  const msg = "Unexpected doc-end without preceding document";
19632
- this.errors.push(new errors4.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg));
19566
+ this.errors.push(new errors3.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", msg));
19633
19567
  break;
19634
19568
  }
19635
19569
  this.doc.directives.docEnd = true;
@@ -19644,7 +19578,7 @@ ${end.comment}` : end.comment;
19644
19578
  break;
19645
19579
  }
19646
19580
  default:
19647
- this.errors.push(new errors4.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", `Unsupported token ${token.type}`));
19581
+ this.errors.push(new errors3.YAMLParseError(getErrorPos(token), "UNEXPECTED_TOKEN", `Unsupported token ${token.type}`));
19648
19582
  }
19649
19583
  }
19650
19584
  *end(forceDoc = false, endOffset = -1) {
@@ -19670,7 +19604,7 @@ ${end.comment}` : end.comment;
19670
19604
  var require_cst_scalar = __commonJS((exports) => {
19671
19605
  var resolveBlockScalar = require_resolve_block_scalar();
19672
19606
  var resolveFlowScalar = require_resolve_flow_scalar();
19673
- var errors4 = require_errors();
19607
+ var errors3 = require_errors();
19674
19608
  var stringifyString = require_stringifyString();
19675
19609
  function resolveAsScalar(token, strict = true, onError) {
19676
19610
  if (token) {
@@ -19679,7 +19613,7 @@ var require_cst_scalar = __commonJS((exports) => {
19679
19613
  if (onError)
19680
19614
  onError(offset, code, message);
19681
19615
  else
19682
- throw new errors4.YAMLParseError([offset, offset + 1], code, message);
19616
+ throw new errors3.YAMLParseError([offset, offset + 1], code, message);
19683
19617
  };
19684
19618
  switch (token.type) {
19685
19619
  case "scalar":
@@ -21559,7 +21493,7 @@ var require_parser = __commonJS((exports) => {
21559
21493
  var require_public_api = __commonJS((exports) => {
21560
21494
  var composer = require_composer();
21561
21495
  var Document = require_Document();
21562
- var errors4 = require_errors();
21496
+ var errors3 = require_errors();
21563
21497
  var log = require_log();
21564
21498
  var identity = require_identity();
21565
21499
  var lineCounter = require_line_counter();
@@ -21576,8 +21510,8 @@ var require_public_api = __commonJS((exports) => {
21576
21510
  const docs = Array.from(composer$1.compose(parser$1.parse(source)));
21577
21511
  if (prettyErrors && lineCounter2)
21578
21512
  for (const doc2 of docs) {
21579
- doc2.errors.forEach(errors4.prettifyError(source, lineCounter2));
21580
- doc2.warnings.forEach(errors4.prettifyError(source, lineCounter2));
21513
+ doc2.errors.forEach(errors3.prettifyError(source, lineCounter2));
21514
+ doc2.warnings.forEach(errors3.prettifyError(source, lineCounter2));
21581
21515
  }
21582
21516
  if (docs.length > 0)
21583
21517
  return docs;
@@ -21592,13 +21526,13 @@ var require_public_api = __commonJS((exports) => {
21592
21526
  if (!doc2)
21593
21527
  doc2 = _doc;
21594
21528
  else if (doc2.options.logLevel !== "silent") {
21595
- doc2.errors.push(new errors4.YAMLParseError(_doc.range.slice(0, 2), "MULTIPLE_DOCS", "Source contains multiple documents; please use YAML.parseAllDocuments()"));
21529
+ doc2.errors.push(new errors3.YAMLParseError(_doc.range.slice(0, 2), "MULTIPLE_DOCS", "Source contains multiple documents; please use YAML.parseAllDocuments()"));
21596
21530
  break;
21597
21531
  }
21598
21532
  }
21599
21533
  if (prettyErrors && lineCounter2) {
21600
- doc2.errors.forEach(errors4.prettifyError(source, lineCounter2));
21601
- doc2.warnings.forEach(errors4.prettifyError(source, lineCounter2));
21534
+ doc2.errors.forEach(errors3.prettifyError(source, lineCounter2));
21535
+ doc2.warnings.forEach(errors3.prettifyError(source, lineCounter2));
21602
21536
  }
21603
21537
  return doc2;
21604
21538
  }
@@ -21650,12 +21584,12 @@ var require_public_api = __commonJS((exports) => {
21650
21584
  });
21651
21585
 
21652
21586
  // ../../node_modules/.bun/yaml@2.9.0/node_modules/yaml/dist/index.js
21653
- var composer, Document, Schema, errors4, Alias, identity, Pair, Scalar, YAMLMap, YAMLSeq, cst, lexer, lineCounter, parser, publicApi, visit, $Composer, $Document, $Schema, $YAMLError, $YAMLParseError, $YAMLWarning, $Alias, $isAlias, $isCollection, $isDocument, $isMap, $isNode, $isPair, $isScalar, $isSeq, $Pair, $Scalar, $YAMLMap, $YAMLSeq, $Lexer, $LineCounter, $Parser, $parse, $parseAllDocuments, $parseDocument, $stringify, $visit, $visitAsync;
21654
- var init_dist2 = __esm(() => {
21587
+ var composer, Document, Schema, errors3, Alias, identity, Pair, Scalar, YAMLMap, YAMLSeq, cst, lexer, lineCounter, parser, publicApi, visit, $Composer, $Document, $Schema, $YAMLError, $YAMLParseError, $YAMLWarning, $Alias, $isAlias, $isCollection, $isDocument, $isMap, $isNode, $isPair, $isScalar, $isSeq, $Pair, $Scalar, $YAMLMap, $YAMLSeq, $Lexer, $LineCounter, $Parser, $parse, $parseAllDocuments, $parseDocument, $stringify, $visit, $visitAsync;
21588
+ var init_dist = __esm(() => {
21655
21589
  composer = require_composer();
21656
21590
  Document = require_Document();
21657
21591
  Schema = require_Schema();
21658
- errors4 = require_errors();
21592
+ errors3 = require_errors();
21659
21593
  Alias = require_Alias();
21660
21594
  identity = require_identity();
21661
21595
  Pair = require_Pair();
@@ -21671,9 +21605,9 @@ var init_dist2 = __esm(() => {
21671
21605
  $Composer = composer.Composer;
21672
21606
  $Document = Document.Document;
21673
21607
  $Schema = Schema.Schema;
21674
- $YAMLError = errors4.YAMLError;
21675
- $YAMLParseError = errors4.YAMLParseError;
21676
- $YAMLWarning = errors4.YAMLWarning;
21608
+ $YAMLError = errors3.YAMLError;
21609
+ $YAMLParseError = errors3.YAMLParseError;
21610
+ $YAMLWarning = errors3.YAMLWarning;
21677
21611
  $Alias = Alias.Alias;
21678
21612
  $isAlias = identity.isAlias;
21679
21613
  $isCollection = identity.isCollection;
@@ -21701,7 +21635,7 @@ var init_dist2 = __esm(() => {
21701
21635
  // ../../node_modules/.bun/@gobing-ai+ts-runtime@0.4.39/node_modules/@gobing-ai/ts-runtime/dist/config.js
21702
21636
  var configSchema;
21703
21637
  var init_config = __esm(() => {
21704
- init_dist2();
21638
+ init_dist();
21705
21639
  init_zod();
21706
21640
  configSchema = exports_external.object({
21707
21641
  app: exports_external.object({
@@ -21887,11 +21821,26 @@ var PluginManifestSchema = exports_external.object({
21887
21821
  init_file_system_node();
21888
21822
  init_config();
21889
21823
 
21824
+ // ../../node_modules/.bun/@gobing-ai+ts-utils@0.4.67/node_modules/@gobing-ai/ts-utils/dist/output.js
21825
+ var defaultStderrTarget;
21826
+ function processStream(name) {
21827
+ const proc = globalThis.process;
21828
+ const stream = proc?.[name];
21829
+ if (stream === undefined) {
21830
+ throw new Error(`No ${name} target available: set one via setDefaultOutputTargets or pass an explicit target`);
21831
+ }
21832
+ return stream;
21833
+ }
21834
+ function writeLine(message, target) {
21835
+ target.write(`${message}
21836
+ `);
21837
+ }
21838
+ function echoError(message, target = defaultStderrTarget ?? processStream("stderr")) {
21839
+ writeLine(message, target);
21840
+ }
21841
+
21890
21842
  // ../../packages/kk-core/src/render-md.ts
21891
21843
  if (false) {}
21892
- // ../../plugins/generations/image-gen/src/index.ts
21893
- init_dist();
21894
-
21895
21844
  // ../../plugins/generations/image-gen/src/bytes.ts
21896
21845
  import { readFile, writeFile } from "fs/promises";
21897
21846
  async function writeBytes(path2, bytes) {
@@ -22045,22 +21994,22 @@ function resolvePlaceholder(expr, vars, formatName) {
22045
21994
  }
22046
21995
  function renderTemplate(template, vars, formatName) {
22047
21996
  let rendered = "";
22048
- let cursor2 = 0;
22049
- while (cursor2 < template.length) {
22050
- const start = template.indexOf("{{", cursor2);
21997
+ let cursor = 0;
21998
+ while (cursor < template.length) {
21999
+ const start = template.indexOf("{{", cursor);
22051
22000
  if (start === -1) {
22052
- rendered += template.slice(cursor2);
22001
+ rendered += template.slice(cursor);
22053
22002
  break;
22054
22003
  }
22055
22004
  const match = matchPlaceholder(template, start);
22056
22005
  if (match === undefined) {
22057
- rendered += template.slice(cursor2, start + 2);
22058
- cursor2 = start + 2;
22006
+ rendered += template.slice(cursor, start + 2);
22007
+ cursor = start + 2;
22059
22008
  continue;
22060
22009
  }
22061
- rendered += template.slice(cursor2, start);
22010
+ rendered += template.slice(cursor, start);
22062
22011
  rendered += resolvePlaceholder(match.expr, vars, formatName);
22063
- cursor2 = match.end;
22012
+ cursor = match.end;
22064
22013
  }
22065
22014
  return rendered;
22066
22015
  }
@@ -22756,13 +22705,13 @@ var createAzure = (options) => {
22756
22705
  // ../../plugins/generations/image-gen/src/providers/codex-cli.ts
22757
22706
  import { spawn } from "child_process";
22758
22707
  import { randomBytes } from "crypto";
22759
- import { access as access2, mkdir, rm, writeFile as writeFile2 } from "fs/promises";
22708
+ import { access, mkdir, rm, writeFile as writeFile2 } from "fs/promises";
22760
22709
  import { tmpdir } from "os";
22761
22710
  import { resolve as resolve2 } from "path";
22762
22711
  var DEFAULT_MODEL4 = "codex-image-gen";
22763
22712
  async function exists(filePath) {
22764
22713
  try {
22765
- await access2(filePath);
22714
+ await access(filePath);
22766
22715
  return true;
22767
22716
  } catch {
22768
22717
  return false;
@@ -22877,7 +22826,6 @@ var createCodexCli = (options) => {
22877
22826
  };
22878
22827
 
22879
22828
  // ../../plugins/generations/image-gen/src/providers/dashscope.ts
22880
- init_dist();
22881
22829
  import { Buffer as Buffer5 } from "buffer";
22882
22830
  var DEFAULT_MODEL5 = "qwen-image-2.0-pro";
22883
22831
  var MIN_QWEN_2_TOTAL_PIXELS = 512 * 512;
@@ -24177,23 +24125,23 @@ function buildInput(req) {
24177
24125
  return { prompt: req.prompt };
24178
24126
  }
24179
24127
  function extractOutputUrl(prediction) {
24180
- const output2 = prediction.output;
24181
- if (typeof output2 === "string")
24182
- return output2;
24183
- if (Array.isArray(output2)) {
24184
- if (output2.length !== 1) {
24185
- throw new Error(`Replicate returned ${output2.length} outputs, but kk image-gen currently supports saving exactly one image per request.`);
24186
- }
24187
- const first = output2[0];
24128
+ const output = prediction.output;
24129
+ if (typeof output === "string")
24130
+ return output;
24131
+ if (Array.isArray(output)) {
24132
+ if (output.length !== 1) {
24133
+ throw new Error(`Replicate returned ${output.length} outputs, but kk image-gen currently supports saving exactly one image per request.`);
24134
+ }
24135
+ const first = output[0];
24188
24136
  if (typeof first === "string")
24189
24137
  return first;
24190
24138
  }
24191
- if (output2 !== null && typeof output2 === "object" && "url" in output2) {
24192
- const url2 = output2.url;
24139
+ if (output !== null && typeof output === "object" && "url" in output) {
24140
+ const url2 = output.url;
24193
24141
  if (typeof url2 === "string")
24194
24142
  return url2;
24195
24143
  }
24196
- throw new Error(`Unexpected Replicate output format: ${JSON.stringify(output2)}`);
24144
+ throw new Error(`Unexpected Replicate output format: ${JSON.stringify(output)}`);
24197
24145
  }
24198
24146
  var createReplicate = (options) => {
24199
24147
  const fetchFn = options?.fetch ?? fetch;